osaf/libs/common/immsv/immpbe_dump.cc | 2 +- osaf/services/saf/immsv/immloadd/imm_loader.cc | 164 ++++++++++++- osaf/services/saf/immsv/immnd/ImmModel.cc | 36 +- osaf/services/saf/immsv/immnd/ImmSearchOp.cc | 2 +- osaf/services/saf/immsv/immnd/ImmSearchOp.hh | 4 +- osaf/services/saf/immsv/schema/SAI-AIS-IMM-XSD-A.02.12.xsd | 14 +- 6 files changed, 196 insertions(+), 26 deletions(-)
diff --git a/osaf/libs/common/immsv/immpbe_dump.cc b/osaf/libs/common/immsv/immpbe_dump.cc --- a/osaf/libs/common/immsv/immpbe_dump.cc +++ b/osaf/libs/common/immsv/immpbe_dump.cc @@ -873,7 +873,7 @@ ClassInfo* classToPBE(std::string classN LOG_ER("Failed to bind attr_type with error code: %d", rc); goto bailout; } - if((rc = sqlite3_bind_int(stmt, 4, (*p)->attrFlags)) != SQLITE_OK) { + if((rc = sqlite3_bind_int64(stmt, 4, (*p)->attrFlags)) != SQLITE_OK) { LOG_ER("Failed to bind attr_flags with error code: %d", rc); goto bailout; } diff --git a/osaf/services/saf/immsv/immloadd/imm_loader.cc b/osaf/services/saf/immsv/immloadd/imm_loader.cc --- a/osaf/services/saf/immsv/immloadd/imm_loader.cc +++ b/osaf/services/saf/immsv/immloadd/imm_loader.cc @@ -18,6 +18,7 @@ #include "imm_loader.hh" #include <iostream> #include <libxml/parser.h> +#include <libxml/xpath.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> @@ -26,6 +27,7 @@ #include <configmake.h> #include <logtrace.h> #include <sys/stat.h> +#include <errno.h> #define MAX_DEPTH 10 #define MAX_CHAR_BUFFER_SIZE 8192 //8k @@ -111,6 +113,22 @@ typedef struct ParserStateStruct SaImmHandleT ccbHandle; } ParserState; +bool isXsdLoaded; +std::string xsddir; +std::string xsd; +typedef std::map<std::string, SaImmAttrFlagsT> AttrFlagMap; +AttrFlagMap attrFlagMap; + +static SaImmAttrFlagsT attrFlagMask = (SA_IMM_ATTR_RUNTIME + | SA_IMM_ATTR_CONFIG + | SA_IMM_ATTR_MULTI_VALUE + | SA_IMM_ATTR_WRITABLE + | SA_IMM_ATTR_INITIALIZED + | SA_IMM_ATTR_PERSISTENT + | SA_IMM_ATTR_CACHED + | SA_IMM_ATTR_NOTIFY + | SA_IMM_ATTR_NO_DUPLICATES); + /* Helper functions */ static void addToAttrTypeCache(ParserState*, SaImmValueTypeT); @@ -874,6 +892,13 @@ static void startElementHandler(void* us else if (strcmp((const char*)name, "imm:IMM-contents") == 0) { state->state[state->depth] = IMM_CONTENTS; + char *schema = (char *)getAttributeValue(attrs, (xmlChar *)"noNamespaceSchemaLocation"); + if(!schema) { + schema = (char *)getAttributeValue(attrs, (xmlChar *)"xsi:noNamespaceSchemaLocation"); + } + if(schema) { + xsd = schema; + } } else { @@ -1424,6 +1449,121 @@ static xmlEntityPtr return xmlGetPredefinedEntity(name); } +static inline char *getAttrValue(xmlAttributePtr attr) { + if(!attr || !attr->children) { + return NULL; + } + + return (char *)attr->children->content; +} + +static bool loadXsd(const char *xsdFile) { + struct stat st; + if(stat(xsdFile, &st)) { + if(errno == ENOENT) { + LOG_ER("%s does not exist", xsdFile); + } else { + LOG_ER("stat of %s return error: %d", xsdFile, errno); + } + + return false; + } + // It should be a file or a directory + if(!S_ISREG(st.st_mode)) { + LOG_ER("%s is not a file", xsdFile); + return false; + } + + xmlNodePtr xsdDocRoot; + xmlDocPtr xsdDoc = xmlParseFile(xsdFile); + if(!xsdDoc) { + return false; + } + + bool rc = true; + xmlXPathContextPtr ctx = xmlXPathNewContext(xsdDoc); + if(!ctx) { + rc = false; + goto freedoc; + } + + // Add namespace of the first element + xsdDocRoot = xmlDocGetRootElement(xsdDoc); + if(xsdDocRoot->ns) { + ctx->namespaces = (xmlNsPtr *)malloc(sizeof(xmlNsPtr)); + ctx->namespaces[0] = xsdDocRoot->ns; + ctx->nsNr = 1; + } + + xmlXPathObjectPtr xpathObj; + xpathObj = xmlXPathEval((const xmlChar*)"/xs:schema/xs:simpleType[@name=\"attr-flags\"]/xs:restriction/xs:enumeration", ctx); + if(!xpathObj || !xpathObj->nodesetval) { + rc = false; + goto freectx; + } + + xmlElementPtr element; + xmlAttributePtr attr; + char *id; + char *value; + int size; + + size = xpathObj->nodesetval->nodeNr; + for(int i=0; i<size; i++) { + id = NULL; + value = NULL; + element = (xmlElementPtr)xpathObj->nodesetval->nodeTab[i]; + attr = element->attributes; + while(attr) { + if(!strcmp((char *)attr->name, "ID")) { + id = getAttrValue(attr); + } else if(!strcmp((char *)attr->name, "value")) { + value = getAttrValue(attr); + } + + if(id && value) { + break; + } + + attr = (xmlAttributePtr)attr->next; + } + + if(value) { + char *end; + SaImmAttrFlagsT attrFlag = 0; + if(id) { + if(!strncmp(id, "0x", 2)) { + attrFlag = strtoull(id, &end, 16); + } else { + attrFlag = strtoull(id, &end, 10); + } + + if(*end) { + LOG_WA("INVALID ID(%s) FOR FLAG %s. Unknown attribute flag is set to 0", id, value); + attrFlag = 0; + } + } + + if((attrFlag & ~attrFlagMask) || (attrFlag == 0)) { + attrFlagMap[value] = attrFlag; + } + } + } + + isXsdLoaded = true; + + xmlXPathFreeObject(xpathObj); +freectx: + if(ctx->nsNr) { + free(ctx->namespaces); + } + xmlXPathFreeContext(ctx); +freedoc: + xmlFreeDoc(xsdDoc); + + return rc; +} + /** * Takes a string and returns the corresponding flag */ @@ -1470,7 +1610,24 @@ static SaImmAttrFlagsT charsToFlagsHelpe return SA_IMM_ATTR_NO_DUPLICATES; } - LOG_ER("UNKNOWN FLAGS, %s", str); + std::string unflag((char *)str, len); + if(!isXsdLoaded) { + std::string xsdPath = xsddir; + if(xsdPath.size() > 0) + xsdPath.append("/"); + xsdPath.append(xsd); + LOG_WA("Found unknown flag (%s). Trying to load a schema %s", unflag.c_str(), xsdPath.c_str()); + loadXsd(xsdPath.c_str()); + } + + if(isXsdLoaded) { + AttrFlagMap::iterator it = attrFlagMap.find(unflag); + if(it != attrFlagMap.end()) { + return it->second; + } + } + + LOG_ER("UNKNOWN FLAGS, %s", unflag.c_str()); exit(1); } @@ -1879,6 +2036,11 @@ int loadImmXML(std::string xmldir, std:: state.adminInit = 0; state.ccbInit = 0; + isXsdLoaded = false; + xsddir = xmldir; + xsd = ""; + attrFlagMap.clear(); + /* Build the filename */ filename = xmldir; filename.append("/"); diff --git a/osaf/services/saf/immsv/immnd/ImmModel.cc b/osaf/services/saf/immsv/immnd/ImmModel.cc --- a/osaf/services/saf/immsv/immnd/ImmModel.cc +++ b/osaf/services/saf/immsv/immnd/ImmModel.cc @@ -70,7 +70,7 @@ struct AttrInfo { AttrInfo():mValueType(0), mFlags(0), mNtfId(0){} SaUint32T mValueType; - SaUint32T mFlags; + SaImmAttrFlagsT mFlags; SaUint32T mNtfId; ImmAttrValue mDefaultValue; }; @@ -2429,6 +2429,7 @@ ImmModel::classCreate(const ImmsvOmClass int illegal=0; bool persistentRt = false; bool persistentRdn = false; + bool useUnknownFlag = false; ClassInfo* classInfo = NULL; ClassInfo* prevClassInfo = NULL; ClassInfo dummyClass(req->classCategory); @@ -2647,7 +2648,10 @@ ImmModel::classCreate(const ImmsvOmClass } } err = attrCreate(classInfo, attr, attrName); - if(err != SA_AIS_OK) { + if(err == SA_AIS_ERR_NOT_SUPPORTED) { + useUnknownFlag = true; + err = SA_AIS_OK; + } else if(err != SA_AIS_OK) { illegal = 1; } list = list->next; @@ -2700,6 +2704,10 @@ ImmModel::classCreate(const ImmsvOmClass goto done; } + if(useUnknownFlag) { + LOG_NO("At least one attribute in class %s has unsupported attribute flag", className.c_str()); + } + /* All checks passed, now install the class def. */ if(!schemaChange) { @@ -3420,18 +3428,18 @@ ImmModel::attrCreate(ClassInfo* classInf SA_IMM_ATTR_NOTIFY); if(unknownFlags) { - LOG_NO("ERR_INVALID_PARAM: invalid search option 0x%llx", - unknownFlags); - err = SA_AIS_ERR_INVALID_PARAM; - goto done; - } - - TRACE_5("create attribute '%s'", attrName.c_str()); - + /* This error means that at least one attribute flag is not supported by OpenSAF, + * but because of forward compatibility, future flags must be supported. + */ + err = SA_AIS_ERR_NOT_SUPPORTED; + TRACE_5("create attribute '%s' with unknown flag(s), attribute flag: %llu", attrName.c_str(), attr->attrFlags); + } else { + TRACE_5("create attribute '%s'", attrName.c_str()); + } + AttrInfo* attrInfo = new AttrInfo; attrInfo->mValueType = attr->attrValueType; - osafassert(attr->attrFlags < 0xffffffff); - attrInfo->mFlags = (SaUint32T) attr->attrFlags; + attrInfo->mFlags = attr->attrFlags; attrInfo->mNtfId = attr->attrNtfId; if(attr->attrDefaultValue) { IMMSV_OCTET_STRING tmpos; //temporary octet string @@ -3514,13 +3522,13 @@ ImmModel::classDescriptionGet(const IMMS struct AttrFlagIncludes { - AttrFlagIncludes(SaUint32T attrFlag) : mFlag(attrFlag) { } + AttrFlagIncludes(SaImmAttrFlagsT attrFlag) : mFlag(attrFlag) { } bool operator() (AttrMap::value_type& item) const { return (item.second->mFlags & mFlag) != 0; } - SaUint32T mFlag; + SaImmAttrFlagsT mFlag; }; struct IdIs diff --git a/osaf/services/saf/immsv/immnd/ImmSearchOp.cc b/osaf/services/saf/immsv/immnd/ImmSearchOp.cc --- a/osaf/services/saf/immsv/immnd/ImmSearchOp.cc +++ b/osaf/services/saf/immsv/immnd/ImmSearchOp.cc @@ -51,7 +51,7 @@ ImmSearchOp::addObject( void ImmSearchOp::addAttribute(const std::string& attributeName, SaUint32T valueType, - SaUint32T flags) + SaImmAttrFlagsT flags) { SearchObject& obj = mResultList.back(); diff --git a/osaf/services/saf/immsv/immnd/ImmSearchOp.hh b/osaf/services/saf/immsv/immnd/ImmSearchOp.hh --- a/osaf/services/saf/immsv/immnd/ImmSearchOp.hh +++ b/osaf/services/saf/immsv/immnd/ImmSearchOp.hh @@ -32,7 +32,7 @@ struct SearchAttribute std::string name; ImmAttrValue* valuep; SaImmValueTypeT valueType; - SaUint32T flags; + SaImmAttrFlagsT flags; ~SearchAttribute(); }; @@ -63,7 +63,7 @@ public: void addAttribute( const std::string& attributeName, SaUint32T valueType, - SaUint32T flags); + SaImmAttrFlagsT flags); void addAttrValue(const ImmAttrValue& value); void setImplementer( SaUint32T conn, diff --git a/osaf/services/saf/immsv/schema/SAI-AIS-IMM-XSD-A.02.12.xsd b/osaf/services/saf/immsv/schema/SAI-AIS-IMM-XSD-A.02.12.xsd --- a/osaf/services/saf/immsv/schema/SAI-AIS-IMM-XSD-A.02.12.xsd +++ b/osaf/services/saf/immsv/schema/SAI-AIS-IMM-XSD-A.02.12.xsd @@ -59,13 +59,13 @@ <xs:documentation>Attribute flags</xs:documentation> </xs:annotation> <xs:restriction base="xs:string"> - <xs:enumeration value="SA_MULTI_VALUE"/> - <xs:enumeration value="SA_WRITABLE"/> - <xs:enumeration value="SA_INITIALIZED"/> - <xs:enumeration value="SA_PERSISTENT"/> - <xs:enumeration value="SA_CACHED"/> - <xs:enumeration value="SA_NO_DUPLICATES"/> - <xs:enumeration value="SA_NOTIFY"/> + <xs:enumeration ID="0x00000001" value="SA_MULTI_VALUE"/> + <xs:enumeration ID="0x00000200" value="SA_WRITABLE"/> + <xs:enumeration ID="0x00000400" value="SA_INITIALIZED"/> + <xs:enumeration ID="0x00020000" value="SA_PERSISTENT"/> + <xs:enumeration ID="0x00040000" value="SA_CACHED"/> + <xs:enumeration ID="0x0000000001000000" value="SA_NO_DUPLICATES"/> + <xs:enumeration ID="0x0000000002000000" value="SA_NOTIFY"/> </xs:restriction> </xs:simpleType> <!-- ------------------------------------------------------------------------------ Managing the Performance of Cloud-Based Applications Take advantage of what the Cloud has to offer - Avoid Common Pitfalls. Read the Whitepaper. http://pubads.g.doubleclick.net/gampad/clk?id=121054471&iu=/4140/ostg.clktrk _______________________________________________ Opensaf-devel mailing list Opensaf-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/opensaf-devel