Heart 1.3.842.34c2ab5
Heart is base back end library for your c++ Qt projects.
abstractnode.h
Go to the documentation of this file.
1/*
2 * Copyright (C) 2018-2024 QuasarApp.
3 * Distributed under the lgplv3 software license, see the accompanying
4 * Everyone is permitted to copy and distribute verbatim copies
5 * of this license document, but changing it is not allowed.
6*/
7
8
9#ifndef ABSTRACTNODE_H
10#define ABSTRACTNODE_H
11
12#include "abstractnodeinfo.h"
13#include "ping.h"
14
15#ifdef USE_HEART_SSL
16#include <QSslConfiguration>
17#include <easyssl/icertificate.h>
18#endif
19
20#include <QAbstractSocket>
21#include <QFutureWatcher>
22#include <QMutex>
23#include <QSharedPointer>
24#include <QTcpServer>
25#include <QThreadPool>
26#include <QTimer>
27#include <softdelete.h>
28#include "abstractdata.h"
29#include "workstate.h"
30#include "package.h"
31#include "heart_global.h"
32#include <iparser.h>
33
34namespace QH {
35
36class DataSender;
37class ReceiveData;
38class SocketFactory;
39class AsyncLauncher;
40class TaskScheduler;
41class AbstractTask;
42class SslSocket;
43class APIVersionParser;
44
45namespace PKG {
46class ErrorData;
47}
48
53enum class SslMode {
55 NoSSL,
56#ifdef USE_HEART_SSL
57
59 InitFromSystem,
61 InitSelfSigned
62#endif
63};
64
79
80#define CRITICAL_ERROOR -50
81#define LOGICK_ERROOR -20
82#define REQUEST_ERROR -5
83#define NOTSUPPORT_ERROR -1
84
85#define BIG_DATA_HASH_ID 0xFFFF
86
87class Abstract;
88
100class HEARTSHARED_EXPORT AbstractNode : public QTcpServer, public SoftDelete
101{
102 Q_OBJECT
103
104public:
105
109 enum NodeType: int {
111 Client = 0,
112
114 Node = 1,
115
117 Server = 2
118 };
119
125 AbstractNode(QObject * ptr = nullptr);
126 ~AbstractNode() override;
127
132 virtual NodeType nodeType() const = 0;
133
141 virtual bool run(const QString& addres, unsigned short port);
142
149 QSharedPointer<QH::iParser> selectParser(unsigned short cmd,
150 AbstractNodeInfo *sender) const;
151
158 QSharedPointer<QH::iParser> selectParser(const QString& type,
159 int version) const;
160
167 QSharedPointer<QH::iParser> selectParser(const QString& type,
168 AbstractNodeInfo *sender) const;
169
173 virtual void stop();
174
181 virtual AbstractNodeInfo* getInfoPtr(const HostAddress &id);
182
188 virtual const AbstractNodeInfo* getInfoPtr(const HostAddress &id) const;
189
194 virtual void ban(const HostAddress& target);
195
200 virtual void unBan(const HostAddress& target);
201
209 virtual unsigned int sendData(const PKG::AbstractData *resp, const HostAddress& address,
210 const Header *req = nullptr);
211
219 virtual unsigned int sendData(const PKG::AbstractData *resp, const AbstractNodeInfo *node,
220 const Header *req = nullptr);
221
229 bool addNode(const HostAddress &address);
230
244 bool addNode(const HostAddress &address,
245 const std::function<void(QH::AbstractNodeInfo *)>& action,
246 NodeCoonectionStatus status = NodeCoonectionStatus::Connected);
247
270 bool addNode(const QString &domain, unsigned short port,
271 const std::function<void(QH::AbstractNodeInfo *)>& action = nullptr,
272 NodeCoonectionStatus status = NodeCoonectionStatus::Connected);
273
279 bool removeNode(const HostAddress& nodeAdderess);
280
286 bool removeNode(AbstractNodeInfo* node);
287
292 HostAddress address() const;
293
294#ifdef USE_HEART_SSL
295
300 QSslConfiguration getSslConfig() const;
301#endif
306 SslMode getMode() const;
307
313 virtual WorkState getWorkState() const;
314
319 int connectionsCount() const;
320
325 int confirmendCount() const;
326
332 bool ping( const HostAddress& address);
333
338 static QThread *mainThreadID();
339
348 bool sheduleTask(const QSharedPointer<AbstractTask>& task);
349
356 void removeTask(int taskId);
357
364 int sheduledTaskCount() const;
365
374 virtual void badRequest(const HostAddress &address, const Header &req,
375 const PKG::ErrorData& err, qint8 diff = REQUEST_ERROR);
376
377#ifdef USE_HEART_SSL
378
384 const QList<QSslError> &ignoreSslErrors() const;
385#endif
386
392 bool addApiParser(const QSharedPointer<iParser>& parser);
393
398 bool fSendBadRequestErrors() const;
399
404 void setSendBadRequestErrors(bool value);
405
410 bool fCloseConnectionAfterBadRequest() const;
411
416 void setCloseConnectionAfterBadRequest(bool value);
417
418signals:
424 void requestError(unsigned char code, QString msg);
425
432 void sigNoLongerSupport(const QString& ApiKey, unsigned short version);
433
434
435protected:
436
437#ifdef USE_HEART_SSL
438
444 void setIgnoreSslErrors(const QList<QSslError> &newIgnoreSslErrors);
445
451 virtual QSslConfiguration selfSignedSslConfiguration( const EasySSL::SslSrtData& data = {});
452#endif
453
461 virtual AbstractNodeInfo* createNodeInfo(QAbstractSocket *socket,
462 const HostAddress *clientAddress = nullptr) const;
463
471 virtual bool registerSocket(QAbstractSocket *socket, const HostAddress* address = nullptr);
472
482 virtual bool sendPackage(const Package &pkg, QAbstractSocket *target) const;
483
488 virtual QString getWorkStateString() const;
489
494 virtual QString connectionState() const;
495
500 QList<HostAddress> banedList() const;
501
502 // TO-DO Need to add new method fo collect banned addresses for exmaple use the mask.
503 // See Task https://github.com/QuasarApp/Heart/issues/13
509 virtual bool isBanned(const AbstractNodeInfo *socket) const;
510
515 void incomingConnection(qintptr handle) override final;
516
523 virtual bool changeTrust(const HostAddress& id, int diff);
524
525
526#ifdef USE_HEART_SSL
527
536 bool useSelfSignedSslConfiguration(const EasySSL::SslSrtData& crtData);
537
545 bool useSystemSslConfiguration(QSslConfiguration config = QSslConfiguration::defaultConfiguration());
546
553 bool disableSSL();
554#endif
555
560 QHash<HostAddress, AbstractNodeInfo *> connections() const;
561
567 virtual void nodeConfirmend(AbstractNodeInfo *node);
568
574 virtual void nodeConnected(AbstractNodeInfo *node);
575
581 virtual void nodeDisconnected(AbstractNodeInfo *node);
582
583 void prepareForDelete() override;
584
592 QSharedPointer<PKG::AbstractData> prepareData(const Package& pkg, AbstractNodeInfo *sender) const;
593
599 QList<HostAddress> connectionsList() const;
600
606 QList<HostAddress> activeConnectionsList() const;
607
615 virtual void addNodeFailed(AddNodeError error);
616
624 virtual void nodeAddedSucessful(AbstractNodeInfo* node);
625
632 template<class ApiType, class ... Args >
633 QSharedPointer<ApiType> addApiParserNative(Args&&... arg) {
634 return addApiParserImpl(QSharedPointer<ApiType>::create(this, std::forward<Args>(arg)...)).template staticCast<ApiType>();
635 }
636
643 template<class ApiType, class ... Args >
644 const QSharedPointer<iParser> & addApiParser(Args&&... arg) {
645 return addApiParserImpl(QSharedPointer<ApiType>::create(this, std::forward<Args>(arg)...));
646 }
647
648protected slots:
653 virtual void receivePing(const QSharedPointer<QH::PKG::Ping>& ping);;
654
662 virtual void nodeErrorOccured(QH::AbstractNodeInfo *nodeInfo,
663 QAbstractSocket::SocketError errorCode,
664 QString errorString);
665
666#ifdef USE_HEART_SSL
667
674 virtual void handleSslErrorOcurred(QH::SslSocket *scket, const QSslError& error);
675#endif
676
677private slots:
678
679 void avelableBytes(QH::AbstractNodeInfo* sender);
680
687 void handleNodeStatusChanged(QH::AbstractNodeInfo* node, QH::NodeCoonectionStatus status);
688
692 void handleWorkerStoped();
693
698 void handleForceRemoveNode(QH::HostAddress node);
699
704 void handleBeginWork(QSharedPointer<QH::AbstractTask> work);
705
706#ifdef USE_HEART_SSL
707
713 void handleSslErrorOcurredPrivate(QH::SslSocket *sender, const QList<QSslError> & errors);
714
718 void handleEncrypted(QH::AbstractNodeInfo *node);
719
720#endif
721
722private:
723
729 const QSharedPointer<iParser> & addApiParserImpl(const QSharedPointer<QH::iParser>& parserObject);
730
731 // iParser interface
732 ParserResult parsePackage(const QSharedPointer<PKG::AbstractData> &pkg,
733 const Header &pkgHeader,
734 AbstractNodeInfo *sender);
735
742 QSharedPointer<PKG::AbstractData>
743 genPackage(unsigned short cmd,
744 AbstractNodeInfo *sender) const;
745
749 bool listen(const HostAddress& address = HostAddress::Any);
750
757 void newWork(const Package &pkg, AbstractNodeInfo *sender, const HostAddress &id);
758
763 void checkConfirmendOfNode(AbstractNodeInfo *node);
764
768 void initThreadId() const;
769
773 void initThreadPool();
774
778 void deinitThreadPool();
779
780
781 SslMode _mode = SslMode::NoSSL;
782#ifdef USE_HEART_SSL
783 bool configureSslSocket(AbstractNodeInfo *node, bool fServer);
784 QSslConfiguration _ssl;
785 QList<QSslError> _ignoreSslErrors;
786#endif
787 QHash<HostAddress, AbstractNodeInfo*> _connections;
788 QHash<HostAddress, ReceiveData*> _receiveData;
789
790 DataSender * _dataSender = nullptr;
791 AsyncLauncher * _socketWorker = nullptr;
792 QThread *_senderThread = nullptr;
793 TaskScheduler *_tasksheduller = nullptr;
794 APIVersionParser *_apiVersionParser = nullptr;
795
797 QHash<HostAddress,
798 std::function<void (QH::AbstractNodeInfo *)>>> _connectActions;
799
800 QSet<QFutureWatcher <bool>*> _workers;
801 bool _sendBadRequestErrors = true;
802 bool _closeConnectionAfterBadRequest = false;
803
804 mutable QMutex _connectionsMutex;
805 mutable QMutex _confirmNodeMutex;
806 mutable QMutex _threadPoolMutex;
807 mutable QMutex _workersMutex;
808
809 QThreadPool *_threadPool = nullptr;
810
811 friend class WebSocketController;
812 friend class SocketFactory;
813 friend class BigDataParser;
814 friend class BigDataParserOld;
815 friend class AbstractNodeParser;
816 friend class AbstractNodeParserOld;
817
818
819};
820
821}
822#endif // ABSTRACTNODE_H
#define REQUEST_ERROR
The APIVersionParser class This is main parser forthe main command. This parsers work only with the A...
The AbstractNodeInfo class contains information about client or server connection and tcp socket of n...
The AbstractNodeParser class is main parser of the abstract level of the hear lib.
The AbstractNode class - Abstract implementation of node. this implementation have a methods for send...
QSharedPointer< ApiType > addApiParserNative(Args &&... arg)
addApiParserNative This is template metod that add sipport of new apiparser ApiType
NodeType
The NodeType enum contains types of the node. By default node contains only 3 types.
const QSharedPointer< iParser > & addApiParser(Args &&... arg)
addApiParser This is template metod that add sipport of new apiparser ApiType
void sigNoLongerSupport(const QString &ApiKey, unsigned short version)
sigNoLongerSupport is some as a APIVersionParser::sigNoLongerSupport. This signal just retronslate th...
void requestError(unsigned char code, QString msg)
requestError This signal emited when client or node received from remoute server or node the BadReque...
virtual NodeType nodeType() const =0
nodeType This method should be return type of the serve.
The AsyncLauncher class is wraper of the Async class for support moving invokes to thread of the curr...
The BigDataParser class is main manager for control big data packages.
The DataSender class this class create a queue for sendet data to network.
Definition datasender.h:23
The Host Address class this is wrapper of QHostAddress. Contains the NetworkAddress and network port.
Definition hostaddress.h:22
The AbstractData class is provide base functions for transport data by network For create you own pac...
The Package struct. This is base structure for transporting data by network between QH nodes....
Definition package.h:23
The SoftDelete class povide the soft delete functionality. All child classes of this class must be de...
Definition softdelete.h:20
The TaskScheduler class This class contains queue of all shedule tasks.
The WorkState class is simple class with data of work state of node.
Definition workstate.h:20
#define HEARTSHARED_EXPORT
The QH namespace - QuasarApp Heart namespace. This namespace contains all classes of the Heart librar...
Definition heart.cpp:13
ParserResult
The ParserResult enum. Error - parser detect a errorob package. NotProcessed - the parser does not kn...
Definition iparser.h:35
NodeCoonectionStatus
The AbstractNodeState enum - This is status of the known nodes or clients.
AddNodeError
The AddNodeError enum contains error code that can be occured after invoke the AbstractNode::addNode ...
@ RegisterSocketFailed
This error ocurred when you try add baned node or server is overrload.
@ UnknownError
unknown error
@ HostNotFound
This error ocurred when DNS server not responce to node or node can't find the server ip address by h...
SslMode
The SslMode enum This enum contatins options for set ssl mode of node (server). For more information ...
@ NoSSL
This is not secure connection without ssl encription. It is default value of new any node see Abstrac...
The Header struct 32 bytes.
Definition header.h:19
The ErrorData struct is simple structure for contains data of the error.
Definition badrequest.h:20