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

Reply via email to