X-Git-Url: https://git.teslayout.com/public/public/public/?a=blobdiff_plain;f=include%2Fanna%2Fdiameter%2Fcodec%2FEngineImpl.hpp;h=22fb82f4c8b39b2440a79b576e0bd205706b90f7;hb=5a6cba5fde2b2f538a7515f8293cc0a8d9589dfa;hp=bb7c6f56b1f474564cf7e951a11f1501f5ca8410;hpb=129af2a9a7c287843be5bd443c5b1ad9b08438a8;p=anna.git diff --git a/include/anna/diameter/codec/EngineImpl.hpp b/include/anna/diameter/codec/EngineImpl.hpp index bb7c6f5..22fb82f 100644 --- a/include/anna/diameter/codec/EngineImpl.hpp +++ b/include/anna/diameter/codec/EngineImpl.hpp @@ -36,8 +36,6 @@ class Dictionary; namespace codec { -extern const char *MessageDTD; - class Message; class Avp; @@ -50,23 +48,15 @@ class Avp; * A child implementation could manage complex Avp classes with new data-part formats. Grouped ones could * allocate new complex Avps through such engine which knows how to allocate this special Avp's (also for * complex Message classes with application-specific setters and getters as credit-control related avps, - * or some another context items). For example helpers for TME scope stands for a new engine component - * called tme::Engine, allocating tme::Avp and tme::Message classes which support three new Avp formats: + * or some another context items). For example tme::Avp and tme::Message classes support three new Avp formats: * ISDNNumber, ISDNAddress and Unsigned16. Anyway, main Message/Avp and Engine classes stand for all contexts * included in anna::diameter, that is to say, whole contexts (at the time only TME) will be included in future * when needed apart from the independent namespace version. Thank to this, single threaded applications could * use whole engine in a easy way. * - * Usually an engine component is associated to a single diameter stack, although single threaded processes could - * use a common engine alternating different stack dictionaries by mean #setDictionary, depending on which kind of - * messages are being analyzed. Although the application must ensure that a single dictionary is activated during - * the same context operations an Avp could be considered as Unknown if was created with another, and we could - * have validation problems (i.e. if mandatory Avp bit is enabled). In general, managing Unknown data-part format - * don't have to be a problem because it is interpreted as OctetString format. Depending on what setters/getters - * we use, it could reach a RuntimeException at our application. - * - * At multithread processes we must use one heir engine per stack and never switching stacks within same component. - * We will use each engine for each context. + * An engine component is associated to a single diameter stack. It is application responsability to use message + * container initialized with the correct codec engine depending on the context. There are helpers to do this at + * anna::diameter::codec::functions::getApplicationId (from xml document or hexadecimal buffer). * * It is recommended to use Message class to create Avps (adding them through pair identification * prototype), but we could create Avps separately (other program section, i.e) and join them after: @@ -75,7 +65,7 @@ class Avp; * 1. Recommended way: * * // Message creation: - * Message * msg = new Message(helpers::base::COMMANDID__Re_Auth_Answer); + * Message * msg = new Message(helpers::base::COMMANDID__Re_Auth_Answer, codecEngine); * // Adding + creation: * Avp * avp_sid = msg->addAvp(helpers::base::AVPID__Session_Id); * Avp * avp_oh = msg->addAvp(helpers::base::AVPID__Origin_Host); @@ -88,12 +78,12 @@ class Avp; * 2. External Avp creation: * * // Message creation: - * Message * msg = new Message(helpers::base::COMMANDID__Re_Auth_Answer); + * Message * msg = new Message(helpers::base::COMMANDID__Re_Auth_Answer, codecEngine); * // Creation: - * Avp * avp_sid = new Avp(helpers::base::AVPID__Session_Id); - * Avp * avp_oh = new Avp(helpers::base::AVPID__Origin_Host); - * Avp * avp_or = new Avp(helpers::base::AVPID__Origin_Realm); - * Avp * avp_rc = new Avp(helpers::base::AVPID__Result_Code); + * Avp * avp_sid = new Avp(helpers::base::AVPID__Session_Id, codecEngine); + * Avp * avp_oh = new Avp(helpers::base::AVPID__Origin_Host, codecEngine); + * Avp * avp_or = new Avp(helpers::base::AVPID__Origin_Realm, codecEngine); + * Avp * avp_rc = new Avp(helpers::base::AVPID__Result_Code, codecEngine); * // Adding: * msg->addAvp(avp_sid); * msg->addAvp(avp_oh); @@ -120,18 +110,18 @@ class Avp; * anna::Recycler a_avps; * anna::Recycler a_messages; * - * anna::diameter::codec::Avp* allocateAvp () throw () { return a_avps.create (); } + * anna::diameter::codec::Avp* allocateAvp () { return a_avps.create (); } * - * void releaseAvp (anna::diameter::codec::Avp* avp) throw () { + * void releaseAvp (anna::diameter::codec::Avp* avp) { * if (avp == NULL) return; * MyAvp* aux = static_cast (avp); * aux->clear(); // free internal data-part storage specially for grouped avps which will release its childrens * a_avps.release (aux); * } * - * anna::diameter::codec::Message* allocateMessage () throw () { return a_messages.create (); } + * anna::diameter::codec::Message* allocateMessage () { return a_messages.create (); } * - * void releaseMessage (anna::diameter::codec::Message* message) throw () { + * void releaseMessage (anna::diameter::codec::Message* message) { * if (message == NULL) return; * MyMessage* aux = static_cast (message); * aux->clear(); // free internal data-part storage specially for childrens releasing @@ -169,34 +159,38 @@ public: // Creators - Avp* createAvp(const AvpId *id) throw(anna::RuntimeException); - Message* createMessage(const CommandId *id) throw(anna::RuntimeException); + Avp* createAvp(const AvpId *id) noexcept(false); + Message* createMessage(const CommandId *id) noexcept(false); private: - anna::xml::DTDMemory a_dtd; ValidationDepth::_v a_validationDepth; ValidationMode::_v a_validationMode; + bool a_singleFailedAVP; bool a_ignoreFlags; FixMode::_v a_fixMode; - bool a_selectStackWithApplicationId; // default behaviour: let the user switch the stack (false for this boolean) - // Auxiliary const stack::Dictionary * a_dictionary; // helpers - static const char* asText(const ValidationDepth::_v) throw(); - static const char* asText(const ValidationMode::_v) throw(); - static const char* asText(const FixMode::_v) throw(); + static const char* asText(const ValidationDepth::_v) ; + static const char* asText(const ValidationMode::_v) ; + static const char* asText(const FixMode::_v) ; public: /** Constructor @param className Logical name for the class. + @param dictionary Diameter dictionary. At single threaded processes, the same codec engine could be used with + different diameter dictionaries (multi-stack applications). In that case the process must switch the stack for + the whole decoding or enconding operation over a Message depending on the context (normally the message header + Application-Id is used as stack identifier). But the smart way implies inherit from this engine creating a + component for each diameter stack managed in the application. Inheritance is mandatory in multi-threaded processes: + one engine, a unique stack. */ - EngineImpl(const char* className); + EngineImpl(const char* className, const stack::Dictionary * dictionary); /** * Destructor @@ -204,68 +198,19 @@ public: virtual ~EngineImpl() {;} - // setters - /** - Sets diameter dictionary loaded at stack engine. It's recommended to configure a valid dictionary - (if not, or NULL provided at #setDictionary, all avps will be managed as 'Unknown' format and all - items will need to be manually updated, i.e. message and avp flags). - - @param dictionary Diameter dictionary. At single threaded processes, the same codec engine could be used with - different diameter dictionaries (multi-stack applications). In that case the process must switch the stack for - the whole decoding or enconding operation over a Message depending on the context (normally the message header - Application-Id is used as stack identifier). But the smart way implies inherit from this engine creating a - component for each diameter stack managed in the application. Inheritance is mandatory in multi-threaded processes: - one engine, a unique stack. - */ - void setDictionary(const stack::Dictionary * dictionary) throw() { a_dictionary = dictionary; } - - /** - * Sets diameter dictionary loaded at stack engine with the provided identifier. - * - * @param stackId Stack identifier. When missing, NULL will be returned - * @return Returns configured dictionary (NULL if stack id was not found) - */ - const stack::Dictionary *setDictionary(unsigned int stackId) throw(); - - - /** - * By default, the user will select the appropiate stack id depending on the context (see #setDictionary), but - * some applications could consider interesting automatic stack selection based on managed messages (incoming - * decoded ones, or built messages to be encoded). By default, on engine construction, no changes are done. - * Multithreaded processes should have a unique codec engine for each managed stack (then you don't have to - * worry about), but mono processes with multistack implementation over the same-unique engine, should activate - * this to have the commonly recommended way to choose the stack: using the Application-Id value. - * - * @warning do not activate in case of multithreaded applications. - * @param enable Activates/deactivates the stack selection from the Application-Id value within the message header. - * False by default. - */ - void selectStackWithApplicationId (bool enable) throw() { a_selectStackWithApplicationId = enable; } - - // getters - - /** - Gets the currently configured behaviour regarding stack selection for multistack codec engines in mono thread - applications. - - @return True if selection is done with the Application-Id. False (default) if no selection is performed (user responsibility). - */ - bool hasSelectStackWithApplicationId (void) throw() { return a_selectStackWithApplicationId; } - - /** Gets currently configured dictionary. NULL if not configured (manual encode/decode operations). @return Returns currently configured engine dictionary */ - const stack::Dictionary *getDictionary() const throw() { return a_dictionary; } + const stack::Dictionary *getDictionary() const { return a_dictionary; } /** * Sets behaviour on validation procedure. * \param validationDepth Behaviour on validation procedure: complete analysis or stop at first validation error over the message. */ - void setValidationDepth(const ValidationDepth::_v validationDepth) throw() { a_validationDepth = validationDepth; } + void setValidationDepth(const ValidationDepth::_v validationDepth) { a_validationDepth = validationDepth; } /** * Returns behaviour on on validation procedure. @@ -275,7 +220,7 @@ public: * * \return Behaviour on validation procedure: complete analysis or stop at first validation error over the message (by default). */ - ValidationDepth::_v getValidationDepth() const throw() { return a_validationDepth; } + ValidationDepth::_v getValidationDepth() const { return a_validationDepth; } /** * Sets behaviour on validation procedure regarding stack flags. Actually, only AVP flags M & P are affected. The vendor bit is @@ -284,7 +229,7 @@ public: * \param ignoreFlags Validation will ignore flags. */ - void ignoreFlagsOnValidation(bool ignoreFlags) throw() { a_ignoreFlags = ignoreFlags; } + void ignoreFlagsOnValidation(bool ignoreFlags) { a_ignoreFlags = ignoreFlags; } /** * Gets behaviour on validation procedure regarding stack flags. Actually, only AVP flags M & P are affected. The vendor bit is @@ -292,13 +237,13 @@ public: * By default (at engine start), flags are verified. * \return Validation ignore flags indicator. */ - bool ignoreFlagsOnValidation() const throw() { return a_ignoreFlags; } + bool ignoreFlagsOnValidation() const { return a_ignoreFlags; } /** * Sets validation mode. * \param validationMode Validation mode: before encoding, after decoding, always or never. */ - void setValidationMode(const ValidationMode::_v validationMode) throw() { a_validationMode = validationMode; } + void setValidationMode(const ValidationMode::_v validationMode) { a_validationMode = validationMode; } /** * Returns validation mode. @@ -306,7 +251,7 @@ public: * during development phase. * \return Validation mode: before encoding, after decoding (by default), always or never. */ - ValidationMode::_v getValidationMode() const throw() { return a_validationMode; } + ValidationMode::_v getValidationMode() const { return a_validationMode; } @@ -314,20 +259,28 @@ public: * Sets fix mode. * \param fixMode Fix mode: before encoding, after decoding, always or never. */ - void setFixMode(const FixMode::_v fixMode) throw() { a_fixMode = fixMode; } + void setFixMode(const FixMode::_v fixMode) { a_fixMode = fixMode; } /** * Returns fix mode. * \return Fix mode: before encoding (by default), after decoding, always or never. */ - FixMode::_v getFixMode() const throw() { return a_fixMode; } - + FixMode::_v getFixMode() const { return a_fixMode; } + /** + * Sets single FailedAVP. True by default. If false, and more than one wrong avp are found during message + * decoding and or validation, a new Failed-AVP will be added to the dynamic answer provided. The standard + * talks about only one but it is open to do this. + * + * \param single Single Failed-AVP boolean. + */ + void setSingleFailedAVP(bool single = true) { a_singleFailedAVP = single; } /** - DTD document for xml message parsing - */ - const anna::xml::DTDMemory & getDTD() const throw() { return a_dtd; } + * Returns single Failed-AVP boolean. + * \return Failed-AVP could be one (true) or more (false) in answer message. + */ + bool getSingleFailedAVP() const { return a_singleFailedAVP; } /** * Creates a new diameter avp assigning its identifier, using engine resources to allocate memory (recommended @@ -339,7 +292,7 @@ public: * * @return Created avp ready to be used */ - Avp* createAvp(AvpId id) throw(anna::RuntimeException) { return createAvp(&id); } + Avp* createAvp(AvpId id) noexcept(false) { return createAvp(&id); } /** * Creates a new diameter avp, using engine resources to allocate memory (recommended recycler allocation at @@ -347,7 +300,7 @@ public: * * @return Created avp ready to be used */ - Avp* createAvp() throw(anna::RuntimeException) { return createAvp(NULL); } + Avp* createAvp() noexcept(false) { return createAvp(NULL); } /** * Creates a new diameter Message assigning its identifier, using engine resources to allocate memory (recommended @@ -359,7 +312,7 @@ public: * * @return Created message ready to be used */ - Message* createMessage(CommandId id) throw(anna::RuntimeException) { return createMessage(&id); } + Message* createMessage(CommandId id) noexcept(false) { return createMessage(&id); } /** * Creates a new diameter message, using engine resources to allocate memory (recommended recycler allocation @@ -367,28 +320,29 @@ public: * * @return Created message ready to be used */ - Message* createMessage() throw(anna::RuntimeException) { return createMessage(NULL); } + Message* createMessage() noexcept(false) { return createMessage(NULL); } /** - Loads an xml file representing a diameter message base in a DTD document (#getDTD) + Loads an xml file/string representing a diameter message base in a DTD document (#getDTD) - @param xmlPathFile Complete path file to the xml document which represents the diameter message + @param xmlPathFile_or_string Complete path file or string representation for the xml document which represents the diameter message + @param pathfile_or_string boolean about the interpretation of the previous argument */ - Message *createMessage(const std::string & xmlPathFile) throw(anna::RuntimeException); + Message *createMessage(const std::string & xmlPathFile_or_string, bool pathfile_or_string = true) noexcept(false); /** Invoked to free Avps. \see anna::Recycler */ - virtual void releaseAvp(Avp*) throw() = 0; + virtual void releaseAvp(Avp*) = 0; /** Invoked to free Messages. \see anna::Recycler */ - virtual void releaseMessage(Message*) throw() = 0; + virtual void releaseMessage(Message*) = 0; /** @@ -396,14 +350,14 @@ public: * * @return String with class content */ - virtual std::string asString(void) const throw(); + virtual std::string asString(void) const ; /** Class XML representation. \param parent XML node over which we will put instance information. \return XML documentcon with class content. */ - virtual anna::xml::Node* asXML(anna::xml::Node* parent) const throw(); + virtual anna::xml::Node* asXML(anna::xml::Node* parent) const ; /** @@ -413,7 +367,7 @@ public: @return Avp identifier as pair (code,vendor-id) */ - AvpId avpIdForName(const char * name) throw(anna::RuntimeException); + AvpId avpIdForName(const char * name) noexcept(false); /** @@ -423,7 +377,7 @@ public: @return Command identifier as pair (code,request-indicator) */ - CommandId commandIdForName(const char * name) throw(anna::RuntimeException); + CommandId commandIdForName(const char * name) noexcept(false); protected: @@ -435,7 +389,7 @@ protected: \see anna::Recycler */ - virtual Avp* allocateAvp() throw() = 0; + virtual Avp* allocateAvp() = 0; /** @@ -445,7 +399,7 @@ protected: \see anna::Recycler */ - virtual Message* allocateMessage() throw() = 0; + virtual Message* allocateMessage() = 0; /** @@ -457,7 +411,7 @@ protected: @see setValidationDepth @see getValidationDepth */ - void validationAnomaly(const std::string & description) const throw(anna::RuntimeException); + void validationAnomaly(const std::string & description) const noexcept(false); }; }