BUG#: 8763
authorvenkat.puvvada <venkat.puvvada>
Mon, 26 Apr 2010 05:38:40 +0000 (05:38 +0000)
committervenkat.puvvada <venkat.puvvada>
Mon, 26 Apr 2010 05:38:40 +0000 (05:38 +0000)
TITLE: PEP 356 - Provider module grouping
DESCRIPTION: PEP 356 implementation

35 files changed:
Schemas/Pegasus/InterOp/VER20/PG_ProviderModule20.mof
rpm/manLinux/man1.Z/cimprovider.1
src/Clients/cimprovider/CIMProviderCommand.cpp
src/Pegasus/Common/AuditLogger.h
src/Pegasus/Common/AuditLoggerToLog.cpp
src/Pegasus/Common/AuditLoggerToSMF.cpp
src/Pegasus/Common/Constants.cpp
src/Pegasus/Common/Constants.h
src/Pegasus/ControlProviders/ProviderRegistrationProvider/ProviderRegistrationProvider.cpp
src/Pegasus/ControlProviders/ProviderRegistrationProvider/ProviderRegistrationProvider.h
src/Pegasus/ProviderManagerService/OOPProviderManagerRouter.cpp
src/Pegasus/ProviderManagerService/OOPProviderManagerRouter.h
src/Pegasus/ProviderManagerService/ProviderAgent/ProviderAgent.cpp
src/Pegasus/ProviderManagerService/ProviderManagerService.cpp
src/Pegasus/Server/ProviderRegistrationManager/ProviderRegistrationManager.cpp
src/Pegasus/Server/ProviderRegistrationManager/ProviderRegistrationManager.h
src/Pegasus/msg/CLI/pegasusCLI_en.txt
src/Pegasus/msg/Server/pegasusServer_en.txt
src/Providers/TestProviders/Load/GroupMethodProvider.mof [new file with mode: 0644]
src/Providers/TestProviders/Load/Makefile
src/Providers/TestProviders/Makefile
src/Providers/TestProviders/TestModuleGrouping/GroupProvider1/Makefile [new file with mode: 0644]
src/Providers/TestProviders/TestModuleGrouping/GroupProvider1/TestGroupingProvider.cpp [new file with mode: 0644]
src/Providers/TestProviders/TestModuleGrouping/GroupProvider1/TestGroupingProvider.h [new file with mode: 0644]
src/Providers/TestProviders/TestModuleGrouping/GroupProvider1/TestGroupingProviderMain.cpp [new file with mode: 0644]
src/Providers/TestProviders/TestModuleGrouping/GroupProvider2/Makefile [new file with mode: 0644]
src/Providers/TestProviders/TestModuleGrouping/GroupProvider2/TestGroupingProvider.cpp [new file with mode: 0644]
src/Providers/TestProviders/TestModuleGrouping/GroupProvider2/TestGroupingProvider.h [new file with mode: 0644]
src/Providers/TestProviders/TestModuleGrouping/GroupProvider2/TestGroupingProviderMain.cpp [new file with mode: 0644]
src/Providers/TestProviders/TestModuleGrouping/GroupUtilLib/Makefile [new file with mode: 0644]
src/Providers/TestProviders/TestModuleGrouping/GroupUtilLib/groupUtilLib.cpp [new file with mode: 0644]
src/Providers/TestProviders/TestModuleGrouping/GroupUtilLib/groupUtilLib.h [new file with mode: 0644]
src/Providers/TestProviders/TestModuleGrouping/Makefile [new file with mode: 0644]
src/Providers/TestProviders/TestModuleGrouping/testclient/Makefile [new file with mode: 0644]
src/Providers/TestProviders/TestModuleGrouping/testclient/TestGroupMethodProvider.cpp [new file with mode: 0644]

index 8424dd480a9c6e429c12620b4aa501ce65ead281..80fddd1ada2de4d36c12151299225c06097d0556 100644 (file)
@@ -30,7 +30,7 @@
 // ==================================================================
 // PG_ProviderModule
 // ==================================================================
-        [Version("2.5.0"), Description ( "A ProviderModule contains "
+        [Version("2.11.0"), Description ( "A ProviderModule contains "
          "one or more Providers. ") ]
 class PG_ProviderModule : CIM_LogicalElement {
       [Key, Override("Name"), Description ("A human-readable name that"
@@ -120,6 +120,23 @@ class PG_ProviderModule : CIM_LogicalElement {
         "CIM_ManagedSystemElement.OperationalStatus"} ]
     string OtherStatusDescription;
 
+      [Description(
+        " A string specifying a group name for the provider module."
+        " If the specified value is \"CIMServer\",  provider module"
+        " is loaded into the CIMServer process. Provider modules"
+        " having the same group name other than \"CIMServer\" are"
+        " loaded into a single agent process except when overridden"
+        " by specific UserContext values. If the value is not specified,"
+        " each provider module is loaded into different agent process."
+        " Provider modules having different UserContext values but the"
+        " same group name are loaded according to the UserContext"
+        " information")]
+   string ModuleGroupName;
+
+      [Description(
+        " Sets the module group name")]
+   sint16 setModuleGroupName([IN] string moduleGroupName);
+
       [Description ("")]
    uint32 start();
       [Description ("")]
index bc0d52e89b786ddfb80146ae096196bd5fca529d..da6ee954141551912e713913ef8c00cdf8fb4583 100644 (file)
@@ -1,7 +1,7 @@
 .\" .TA c \" lowercase initial letter of .TH name
 .TH "cimprovider" "1" "" "" ""
 .SH "NAME"
-cimprovider \- disable, enable, remove , list or display status of registered CIM providers or 
+cimprovider \- disable, enable, remove , group, list or display status of registered CIM providers or 
 CIM provider modules
 .SH "SYNOPSIS"
 \fBcimprovider\fP \fB\-d\fP \fB\-m\fP module
@@ -10,7 +10,9 @@ CIM provider modules
 
 \fBcimprovider\fP \fB\-r\fP \fB\-m\fP module [ \fB\-p\fP provider ]
 
-\fBcimprovider\fP \fB\-l\fP  [ \fB\-s\fP | \fB\-m\fP module ]
+\fBcimprovider\fP \fB\-g\fP group \fB\-m\fP module
+
+\fBcimprovider\fP \fB\-l\fP  [ \fB\-s\fP | \fB\-f\fP | \fB\-m\fP module ]
 
 \fBcimprovider\fP \fB\-h\fP
 
@@ -29,8 +31,8 @@ module or CIM provider at a time.
 .SH "DESCRIPTION"
 The 
 .B cimprovider 
-command provides a command line interface to disable, enable, unregister, and
-list registered CIM providers.  If a CIM provider is disabled, the CIM Server 
+command provides a command line interface to disable, enable, unregister, group
+and list registered CIM providers.  If a CIM provider is disabled, the CIM Server 
 rejects any requests to the provider.  If a CIM provider is enabled, the CIM 
 Server forwards requests to the provider.  And if a CIM provider is 
 unregistered, the CIM Server will no longer have any information about the 
@@ -64,6 +66,17 @@ Once removed, a provider or provider module
 must be re\-registered (typically by loading its registration schema via the 
 .B cimmof 
 command).
+.PP
+The fourth form of
+.B cimprovider
+sets the provider module group. If the provider module is  active, provider module is disabled first,
+group is set and enabled again. If group name is 
+.B CIMServer,
+provider module is loaded into 
+.B CIMServer
+process depending on 
+.B UserContext
+value. Specify empty string to remove from grouping.
 .PP 
 The last form of 
 .B cimprovider 
@@ -142,10 +155,41 @@ is specified, removes the specified
 in the specified provider
 .I module
 (not affecting any other providers in that module).
+.TP
+.B \-g
+Sets the CIM provider module
+.I group.
+Specify empty string to remove from 
+.I grouping.
+If the
+.I provider module
+is  active,
+.I provider module
+is disabled first, 
+.I group
+is set and enabled again. All 
+.I provider modules
+with the same
+.I group
+name are loaded into a single agent process except when overridden by specific
+.I UserContext
+values. If
+.I group
+name is
+.I CIMServer
+,
+.I provider module
+is loaded into 
+.I CIMServer process depending on 
+.I UserContext
+value. 
 .TP 
 .B \-s
 Displays the status of provider modules.
 .TP 
+.B \-f
+Displays the full status of provider modules with group name.
+.TP 
 .B \-\-version
 Display CIM Server version number.
 .SH "EXIT STATUS"
@@ -205,6 +249,14 @@ List the registered providers which are contained in the
 "OperatingSystemProvider" provider module.
 .IP 
 .B cimprovider \-l \-m OperatingSystemProvider
+.PP
+Set the group name of the "OperatingSystemProvider" provider module to "CIMServer".
+.IP
+.B cimprovider \-g CIMServer \-m OperatingSystemProvider
+.PP
+Remove "OperatingSystemProvider" provider module from grouping.
+.IP
+.B cimprovider \-g """"""  \-m OperatingSystemProvider
 .SH "SEE ALSO"
 .PP 
 cimmof(1), cimserver(1).
index 7c3c56f25cc4af2589aba00f901170e5cf87ba9d..2281b2872ea287140e794c060e4b580a63602c40 100644 (file)
@@ -127,6 +127,11 @@ static const Uint32 OPERATION_TYPE_HELP    = 5;
 */
 static const Uint32 OPERATION_TYPE_VERSION = 6;
 
+/**
+    This constant represents provider module group set operation.
+*/
+static const Uint32 OPERATION_TYPE_GROUP = 7;
+
 
 /**
     The constants representing the messages.
@@ -271,6 +276,27 @@ static const char ERR_USAGE_KEY[] =
 static const char ERR_USAGE[] =
     "Use '--help' to obtain command syntax.";
 
+static const char SETTING_PROVIDERMODULE_GROUP_KEY[] =
+    "Clients.cimprovider.CIMProviderCommand.SETTING_PROVIDERMODULE_GROUP";
+
+static const char SETTING_PROVIDERMODULE_GROUP[] =
+    "Setting the provider module group...";
+
+static const char SET_PROVIDERMODULE_GROUP_SUCCESS_KEY[] =
+    "Clients.cimprovider.CIMProviderCommand."
+        "SET_PROVIDERMODULE_GROUP_SUCCESS";
+
+static const char SET_PROVIDERMODULE_GROUP_SUCCESS[] =
+    "Provider module group set successfully.";
+
+static const char SET_PROVIDERMODULE_GROUP_FAILURE_KEY[] =
+    "Clients.cimprovider.CIMProviderCommand."
+        "SET_PROVIDERMODULE_GROUP_FAILURE";
+
+static const char SET_PROVIDERMODULE_GROUP_FAILURE[] =
+    "Failed to set the provider module group.";
+
+
 static const char LONG_HELP[] = "help";
 
 static const char LONG_VERSION[] = "version";
@@ -311,6 +337,11 @@ static const char OPTION_LIST        = 'l';
 */
 static const char OPTION_STATUS      = 's';
 
+/**
+    The option character used to specify get full module status.
+*/
+static const char OPTION_FULLSTATUS      = 'f';
+
 /**
     The option character used to display help info.
 */
@@ -321,6 +352,11 @@ static const char OPTION_HELP        = 'h';
 */
 static const char OPTION_VERSION     = 'v';
 
+/**
+    The option character used to specify the module group name.
+*/
+static const char OPTION_GROUP     = 'g';
+
 /**
     The name of the Method that implements stop provider or module
 */
@@ -331,6 +367,16 @@ static const CIMName STOP_METHOD = CIMName("stop");
 */
 static const CIMName START_METHOD = CIMName("start");
 
+/**
+    The name of the Method that implements the provider module group setting.
+*/
+static const CIMName SETMODULEGROUPNAME_METHOD = CIMName("SetModuleGroupName");
+
+/**
+    ModuleGroupName param or property.
+*/
+static const String MODULEGROUPNAME = "ModuleGroupName";
+
 /**
     This is a CLI used to update providers of the CIM Server.  This
     command supports operations to stop, start, list and delete provider
@@ -428,6 +474,21 @@ private:
         ostream& outPrintWriter,
         ostream& errPrintWriter);
 
+    //
+    // Sets the provider module group
+    //
+    // @param outPrintWriter The stream to which command output is written.
+    // @param errPrintWriter The stream to which command errors are written.
+    //
+    // @return Uint32 command result
+    // @exception CIMException  if the setModuleGroupName operation generates
+    // an exception.
+    //
+   Uint32 _setProviderModuleGroupName(
+        ostream& outPrintWriter,
+        ostream& errPrintWriter);
+
+
     //
     // List all the registered providers or modules.
     //
@@ -466,6 +527,11 @@ private:
     //
     String _moduleName;
 
+    //
+    // The name of the provider module group.
+    //
+    String _moduleGroupName;
+
     //
     // The name of the provider.
     //
@@ -491,6 +557,16 @@ private:
     //
     Boolean _statusSet;
 
+    //
+    // The flag to indicate whether the full status is set or not
+    //
+    Boolean _fullStatusSet;
+
+    //
+    // The flag to indicate whether the group is set or not
+    //
+    Boolean _moduleGroupSet;
+
     String usage;
 };
 
@@ -506,6 +582,8 @@ CIMProviderCommand::CIMProviderCommand()
     _moduleSet          = false;
     _providerSet        = false;
     _statusSet          = false;
+    _fullStatusSet          = false;
+    _moduleGroupSet          = false;
 
     /**
         Build the usage string for the config command.
@@ -521,12 +599,16 @@ CIMProviderCommand::CIMProviderCommand()
     usage.append("                   -").append(OPTION_ENABLE);
     usage.append(" -").append(OPTION_MODULE).append(" module \n");
 
+    usage.append("                   -").append(OPTION_GROUP).append(" group");
+    usage.append(" -").append(OPTION_MODULE).append(" module \n");
+
     usage.append("                   -").append(OPTION_REMOVE);
     usage.append(" -").append(OPTION_MODULE).append(" module");
     usage.append(" [ -").append(OPTION_PROVIDER).append(" provider ] \n");
 
     usage.append("                   -").append(OPTION_LIST);
     usage.append(" [ -").append(OPTION_STATUS);
+    usage.append(" | -").append(OPTION_FULLSTATUS);
     usage.append(" | -").append(OPTION_MODULE).append(" module ] \n");
 
     usage.append("                   -").append(OPTION_HELP).append("\n");
@@ -538,6 +620,17 @@ CIMProviderCommand::CIMProviderCommand()
         "Disable the specified CIM provider module\n");
     usage.append("    -e         - "
         "Enable the specified CIM provider module\n");
+    usage.append("    -g         - "
+        "Sets the CIM provider module group. Specify\n"
+        "                 empty string to remove from grouping.\n"
+        "                 If the provider module is  active, provider\n"
+        "                 module is disabled first, group is set and\n"
+        "                 enabled again. All provider modules with the same\n"
+        "                 group name are loaded into a single agent process\n"
+        "                 except when overridden by specific UserContext\n"
+        "                 values. If group name is CIMServer, provider module\n"
+        "                 is loaded into CIMServer process depending on\n"
+        "                 UserContext value\n");
     usage.append("    -h, --help - Display this help message\n");
     usage.append("    -l         - "
         "Display all the registered provider modules\n");
@@ -552,6 +645,9 @@ CIMProviderCommand::CIMProviderCommand()
         "                 it contains\n");
     usage.append("    -s         - "
         "Display the status of registered provider modules\n");
+    usage.append("    -f         - "
+        "Full status, display the status of registered\n"
+        "                 provider modules and module group name\n");
     usage.append("    --version  - Display CIM Server version number\n");
 
 // Localize the usage text
@@ -587,6 +683,8 @@ void CIMProviderCommand::setCommand(
     //
     optString.append(OPTION_DISABLE);
     optString.append(OPTION_ENABLE);
+    optString.append(OPTION_GROUP);
+    optString.append(getoopt::GETOPT_ARGUMENT_DESIGNATOR);
     optString.append(OPTION_HELP);
     optString.append(OPTION_LIST);
     optString.append(OPTION_MODULE);
@@ -595,6 +693,7 @@ void CIMProviderCommand::setCommand(
     optString.append(getoopt::GETOPT_ARGUMENT_DESIGNATOR);
     optString.append(OPTION_REMOVE);
     optString.append(OPTION_STATUS);
+    optString.append(OPTION_FULLSTATUS);
 
     //
     //  Initialize and parse options
@@ -683,6 +782,30 @@ void CIMProviderCommand::setCommand(
 
                     break;
                 }
+                case OPTION_GROUP:
+                {
+                    if (_operationType != OPERATION_TYPE_UNINITIALIZED)
+                    {
+                        //
+                        // More than one operation option was found
+                        //
+                        throw UnexpectedOptionException(OPTION_GROUP);
+                    }
+
+                    if (options.isSet(OPTION_GROUP) > 1)
+                    {
+                        //
+                        // More than one group option was found
+                        //
+                        throw DuplicateOptionException(OPTION_GROUP);
+                    }
+
+                    _operationType = OPERATION_TYPE_GROUP;
+                    _moduleGroupName = options[i].Value();
+                    _moduleGroupSet = true;
+
+                    break;
+                }
                 case OPTION_REMOVE:
                 {
                     if (_operationType != OPERATION_TYPE_UNINITIALIZED)
@@ -795,6 +918,20 @@ void CIMProviderCommand::setCommand(
 
                     break;
                 }
+                case OPTION_FULLSTATUS:
+                {
+                    if (options.isSet(OPTION_FULLSTATUS) > 1)
+                    {
+                        //
+                        // More than one status option was found
+                        //
+                        throw DuplicateOptionException(OPTION_FULLSTATUS);
+                    }
+
+                    _fullStatusSet = true;
+
+                    break;
+                }
 
                 case OPTION_HELP:
                 {
@@ -861,7 +998,9 @@ void CIMProviderCommand::setCommand(
             MSG_PATH, REQUIRED_ARGS_MISSING_KEY, REQUIRED_ARGS_MISSING));
     }
 
-    if (_operationType == OPERATION_TYPE_DISABLE)
+    if (_operationType == OPERATION_TYPE_DISABLE
+        || _operationType == OPERATION_TYPE_ENABLE
+        || _operationType == OPERATION_TYPE_GROUP)
     {
         if (_providerSet)
         {
@@ -876,21 +1015,15 @@ void CIMProviderCommand::setCommand(
         }
     }
 
-    if (_operationType == OPERATION_TYPE_ENABLE)
+    if (_operationType == OPERATION_TYPE_GROUP)
     {
-        if (_providerSet)
-        {
-            throw CommandFormatException(localizeMessage(MSG_PATH,
-                UNEXPECTED_OPTION_KEY,
-                UNEXPECTED_OPTION));
-        }
-
-        if (!_moduleSet)
+        if (!_moduleGroupSet)
         {
-            throw MissingOptionException(OPTION_MODULE);
+            throw MissingOptionException(OPTION_GROUP);
         }
     }
 
+
     if (_operationType == OPERATION_TYPE_REMOVE && !_moduleSet)
     {
         throw MissingOptionException(OPTION_MODULE);
@@ -903,7 +1036,9 @@ void CIMProviderCommand::setCommand(
             UNEXPECTED_OPTION));
     }
 
-    if (_operationType == OPERATION_TYPE_LIST && _statusSet && _moduleSet)
+    if (_operationType == OPERATION_TYPE_LIST &&
+        ( (_statusSet && _moduleSet) || (_fullStatusSet && _moduleSet) ||
+            _fullStatusSet && _statusSet))
     {
         throw CommandFormatException(localizeMessage(MSG_PATH,
             UNEXPECTED_OPTION_KEY,
@@ -1091,6 +1226,44 @@ Uint32 CIMProviderCommand::execute(
             }
             break;
 
+        case OPERATION_TYPE_GROUP:
+            try
+            {
+                return _setProviderModuleGroupName(
+                    outPrintWriter, errPrintWriter);
+            }
+            catch (CIMException& e)
+            {
+                CIMStatusCode code = e.getCode();
+                if (code == CIM_ERR_FAILED)
+                {
+                    outPrintWriter << localizeMessage(MSG_PATH,
+                        SET_PROVIDERMODULE_GROUP_FAILURE_KEY,
+                        SET_PROVIDERMODULE_GROUP_FAILURE) << endl;
+                    errPrintWriter << e.getMessage() << endl;
+                }
+                else if (code == CIM_ERR_INVALID_CLASS)
+                {
+                    outPrintWriter << localizeMessage(MSG_PATH,
+                        SET_PROVIDERMODULE_GROUP_FAILURE_KEY,
+                        SET_PROVIDERMODULE_GROUP_FAILURE) << endl;
+                    outPrintWriter << localizeMessage(MSG_PATH,
+                        PG_PROVIDER_SCHEMA_NOT_LOADED,
+                        PG_PROVIDER_SCHEMA_NOT_LOADED) << endl;
+                }
+                else
+                {
+                    errPrintWriter << e.getMessage() << endl;
+                }
+                return RC_ERROR;
+            }
+            catch (Exception& e)
+            {
+                errPrintWriter << e.getMessage() << endl;
+                return RC_ERROR;
+            }
+            break;
+
         case OPERATION_TYPE_LIST:
             try
             {
@@ -1213,6 +1386,62 @@ void CIMProviderCommand::_deleteProvider(
 }
 
 //
+// Set the  provider module group name
+//
+Uint32 CIMProviderCommand::_setProviderModuleGroupName(
+    ostream& outPrintWriter,
+    ostream& errPrintWriter)
+{
+    PEGASUS_ASSERT(_moduleSet);
+    PEGASUS_ASSERT(_moduleGroupSet);
+
+    // get the module instance
+    CIMInstance moduleInstance = _getModuleInstance();
+
+    CIMObjectPath moduleRef = moduleInstance.getPath();
+    moduleRef.setNameSpace(PEGASUS_NAMESPACENAME_PROVIDERREG);
+    moduleRef.setClassName(PEGASUS_CLASSNAME_PROVIDERMODULE);
+
+    CIMKeyBinding kb1(CIMName("Name"), _moduleName, CIMKeyBinding::STRING);
+    Array<CIMKeyBinding> keys;
+    keys.append(kb1);
+
+    moduleRef.setKeyBindings(keys);
+
+    outPrintWriter << localizeMessage(MSG_PATH,
+        SETTING_PROVIDERMODULE_GROUP_KEY,
+        SETTING_PROVIDERMODULE_GROUP) << endl;
+
+    Array<CIMParamValue> inParams;
+    Array<CIMParamValue> outParams;
+
+    inParams.append(CIMParamValue(MODULEGROUPNAME, _moduleGroupName));
+
+    CIMValue ret_value = _client->invokeMethod(
+        PEGASUS_NAMESPACENAME_PROVIDERREG,
+        moduleRef,
+        SETMODULEGROUPNAME_METHOD,
+        inParams,
+        outParams);
+
+    Sint16 retValue;
+    ret_value.get(retValue);
+    if (retValue == 0)
+    {
+        outPrintWriter << localizeMessage(MSG_PATH,
+            SET_PROVIDERMODULE_GROUP_SUCCESS_KEY,
+            SET_PROVIDERMODULE_GROUP_SUCCESS) << endl;
+        return RC_SUCCESS;
+    }
+    else
+    {
+        outPrintWriter << localizeMessage(MSG_PATH,
+            SET_PROVIDERMODULE_GROUP_FAILURE_KEY,
+            SET_PROVIDERMODULE_GROUP_FAILURE) << endl;
+        return RC_ERROR;
+    }
+}
+
 // Enable the provider module
 //
 Uint32 CIMProviderCommand::_startProvider(
@@ -1521,52 +1750,29 @@ void CIMProviderCommand::_printList(
     ostream& outPrintWriter,
     ostream& errPrintWriter)
 {
-    Uint32 maxLength=0;
+    Uint32 maxModuleLength=0;
+    Uint32 maxStatusLength=0;
+
     Uint32 length=0;
     Array<Uint16> _status;
     String output;
     String statusValue;
 
-    if (_statusSet)
+    Array<String> modulesStatus;
+
+    if (_statusSet || _fullStatusSet)
     {
         // get max length of module name
         for (Uint32 i=0; i < moduleNames.size(); i++)
         {
-            if (maxLength < moduleNames[i].size())
+            if (maxModuleLength < moduleNames[i].size())
             {
-                maxLength = moduleNames[i].size();
+                maxModuleLength = moduleNames[i].size();
             }
         }
 
-        output = "MODULE";
-
-        for (Uint32 i = 0; i < maxLength; i++)
-        {
-            output.append(" ");
-        }
-
-        output.append("STATUS");
-#ifdef PEGASUS_OS_VMS
-        //
-        // When outputing to a file using outPrintWriter,
-        // characters appear one per line.
-        // Use printf instead.
-        //
-        printf("%s\n", (const char *) output.getCString());
-#else
-        outPrintWriter << output << endl;
-#endif
-
         for (Uint32 i =0; i < instances.size(); i++)
         {
-            output = moduleNames[i];
-            length = maxLength +6 - moduleNames[i].size();
-
-            for (Uint32 j = 0; j < length; j++)
-            {
-                output.append(" ");
-            }
-
             Uint32 pos = instances[i].findProperty(_PROPERTY_OPERATIONALSTATUS);
             if (pos == PEG_NOT_FOUND)
             {
@@ -1682,6 +1888,33 @@ void CIMProviderCommand::_printList(
                 output.append(statusValue);
                 output.append(" ");
             }
+            modulesStatus.append(output);
+            if (output.size() > maxStatusLength)
+            {
+                maxStatusLength = output.size();
+            }
+            output.clear();
+        }
+
+        output.clear();
+        output = "MODULE";
+
+        for (Uint32 x =0; x < maxModuleLength; ++x)
+        {
+            output.append(" ");
+        }
+
+        output.append("STATUS");
+
+        if (_fullStatusSet)
+        {
+            for (Uint32 x =0; x < maxStatusLength; ++x)
+            {
+                output.append(" ");
+            }
+            output.append("GROUP");
+        }
+
 #ifdef PEGASUS_OS_VMS
             //
             // When outputing to a file using outPrintWriter,
@@ -1692,8 +1925,50 @@ void CIMProviderCommand::_printList(
 #else
             outPrintWriter << output << endl;
 #endif
-        }
 
+        for (Uint32 i = 0, n = moduleNames.size(); i < n ; ++i)
+        {
+            output.clear();
+            output.append(moduleNames[i]);
+            for (Uint32 x =0,
+                m = maxModuleLength - moduleNames[i].size() + 6;
+                x < m;  ++x)
+            {
+                output.append(" ");
+            }
+
+            output.append(modulesStatus[i]);
+
+            if (_fullStatusSet)
+            {
+
+                String groupName;
+                Uint32 pos = instances[i].findProperty(MODULEGROUPNAME);
+                if (pos != PEG_NOT_FOUND)
+                {
+                    CIMValue value = instances[i].getProperty(pos).getValue();
+                    value.get(groupName);
+                    for (Uint32 x =0,
+                        m = maxStatusLength - modulesStatus[i].size() + 6;
+                        x < m;  ++x)
+                    {
+                        output.append(" ");
+                    }
+                    output.append(groupName);
+                }
+            }
+
+#ifdef PEGASUS_OS_VMS
+            //
+            // When outputing to a file using outPrintWriter,
+            // characters appear one per line.
+            // Use printf instead.
+            //
+            printf("%s\n", (const char *) output.getCString());
+#else
+            outPrintWriter << output << endl;
+#endif
+        }
     }
     else
     {
index 462039d10fc96d141017497a032c75b30582dc05..684e42313283b07a7b5e46dc3d3b26cc6803c7ad 100644 (file)
@@ -227,6 +227,17 @@ public:
         const Array<Uint16> currentModuleStatus,
         const Array<Uint16> newModuleStatus);
 
+    /** Constructs and logs audit message of a provider module group change
+        @param moduleName - The name of the provider module
+        @param oldModuleGroupName - The old group name of the provider module
+        @param newModuleGroupName - The new group name of the provider module
+    */
+    static void logSetProvModuleGroupName(
+        const String & moduleName,
+        const String & oldModuleGroupName,
+        const String & newModuleGroupName);
+
+
     /** Constructs and logs audit message of local authentication
         @param userName - The user name for this operation
         @param successful - True on successful basic authentication,
index 9b93fe46a4072eac45a087f0beeb88d6328ed10c..9bde3b3d450af168c5efa7873d88d65079f1623a 100644 (file)
@@ -347,6 +347,23 @@ void AuditLogger::logInvokeMethodOperation(
     }
 }
 
+void AuditLogger::logSetProvModuleGroupName(
+    const String & moduleName,
+    const String & oldModuleGroupName,
+    const String & newModuleGroupName)
+{
+    MessageLoaderParms msgParms(
+        "Common.AuditLogger.SET_PROVIDER_MODULE_GROUP",
+        "The ModuleGroupName of provider module \"$0\" has changed from \"$1\""
+            " to \"$2\".",
+        moduleName, oldModuleGroupName, newModuleGroupName);
+
+    _writeAuditMessage(TYPE_CONFIGURATION,
+        SUBTYPE_PROVIDER_MODULE_STATUS_CHANGE,
+        EVENT_UPDATE, Logger::INFORMATION, msgParms);
+}
+
+
 void AuditLogger::logUpdateProvModuleStatus(
     const String & moduleName,
     const Array<Uint16> currentModuleStatus,
index 89ee4a8f1c1c12272bbcfec45d53c96e0afab806..433b0e7b5264b0689b449bd2935e937e3272a4d1 100644 (file)
@@ -460,6 +460,14 @@ void AuditLogger::logInvokeMethodOperation(
     }
 }
 
+void AuditLogger::logSetProvModuleGroupName(
+    const String & moduleName,
+    const String & oldModuleGroupName,
+    const String & newModuleGroupName)
+{
+// ATTN: Implement for z/OS.
+}
+
 void AuditLogger::logUpdateProvModuleStatus(
     const String & moduleName,
     const Array<Uint16> currentModuleStatus,
index 2300c8665a6021227f22b2e0b1ee1883e0ea3285..d08c8be8338a801674299dddd89ae7397e0c7306 100644 (file)
@@ -157,6 +157,8 @@ const CIMName PEGASUS_PROPERTYNAME_MODULE_USERCONTEXT =
     CIMNameCast("UserContext");
 const CIMName PEGASUS_PROPERTYNAME_MODULE_DESIGNATEDUSER =
     CIMNameCast("DesignatedUserContext");
+const CIMName PEGASUS_PROPERTYNAME_MODULE_MODULEGROUPNAME =
+    CIMNameCast("ModuleGroupName");
 
 /**
     The name of the Destination property for CIM XML Indication Handler
index a66c349ff68ebc95c13f0030193b3a3061ba4d34..6b7aa169768537fa42d01589dcaac8fd29f72a15 100644 (file)
@@ -653,6 +653,8 @@ PEGASUS_COMMON_LINKAGE
     extern const CIMName PEGASUS_PROPERTYNAME_MODULE_USERCONTEXT;
 PEGASUS_COMMON_LINKAGE
     extern const CIMName PEGASUS_PROPERTYNAME_MODULE_DESIGNATEDUSER;
+PEGASUS_COMMON_LINKAGE
+    extern const CIMName PEGASUS_PROPERTYNAME_MODULE_MODULEGROUPNAME;
 
 /**
     The name of the Destination property for CIM XML Indication Handler
index 99b0edde96a238583efd2fc692b529bca8c44a6d..c388ba1cd2f8302421c76d9b822e1200b4a2b63f 100644 (file)
@@ -60,6 +60,17 @@ static const CIMName _STOP_PROVIDER = CIMNameCast("Stop");
 */
 static const CIMName _START_PROVIDER = CIMNameCast("Start");
 
+/**
+   setting provider module group method
+*/
+static const CIMName _SET_MODULEGROUPNAME = CIMNameCast("SetModuleGroupName");
+
+/**
+   input param for setModuleGroupName name method
+*/
+static const CIMName _PARAM_MODULEGROUPNAME = CIMNameCast("ModuleGroupName");
+
+
 ProviderRegistrationProvider::ProviderRegistrationProvider(
     ProviderRegistrationManager * providerRegistrationManager)
 {
@@ -1067,6 +1078,7 @@ void ProviderRegistrationProvider::invokeMethod(
         }
     }
 
+
     // if _PROPERTY_PROVIDERMODULE_NAME key not found
     if( !moduleFound)
     {
@@ -1091,6 +1103,21 @@ void ProviderRegistrationProvider::invokeMethod(
         // enable module
         ret_value = _enableModule(objectReference, moduleName, al);
     }
+    else if (methodName.equal(_SET_MODULEGROUPNAME))
+    {
+        String paramName;
+        if (!inParameters.size() ||
+            ((paramName = inParameters[0].getParameterName())
+                != _PARAM_MODULEGROUPNAME))
+        {
+            throw PEGASUS_CIM_EXCEPTION(CIM_ERR_INVALID_PARAMETER, paramName);
+        }
+        // set group
+        String moduleGroupName;
+        inParameters[0].getValue().get(moduleGroupName);
+        ret_value = _setModuleGroupName(
+            objectReference, moduleName, moduleGroupName, al);
+    }
     else
     {
         throw PEGASUS_CIM_EXCEPTION(CIM_ERR_METHOD_NOT_AVAILABLE,
@@ -1105,6 +1132,77 @@ void ProviderRegistrationProvider::invokeMethod(
     handler.complete();
 }
 
+Sint16 ProviderRegistrationProvider::_setModuleGroupName(
+    const CIMObjectPath & moduleRef,
+    const String & moduleName,
+    const String & moduleGroupName,
+    const AcceptLanguageList & al)
+{
+    Sint32 disableRC = _disableModule (moduleRef, moduleName, false, al);
+
+    if (disableRC == -1)
+    {
+        throw PEGASUS_CIM_EXCEPTION_L(CIM_ERR_FAILED,
+            MessageLoaderParms(
+                "ControlProviders.ProviderRegistrationProvider."
+                    "ProviderRegistrationProvider."
+                    "DISABLE_PROVIDER_FAILED",
+                "disable the provider failed."));
+    }
+
+    if (disableRC == -2)
+    {
+        throw PEGASUS_CIM_EXCEPTION_L(CIM_ERR_FAILED,
+            MessageLoaderParms(
+                "ControlProviders.ProviderRegistrationProvider."
+                    "ProviderRegistrationProvider."
+                    "DISABLE_PROVIDER_FAILED_PROVIDER_BUSY",
+                "disable the provider failed: Provider is busy."));
+    }
+
+    String errorMsg;
+
+    if (!_providerRegistrationManager->setProviderModuleGroupName(
+        moduleName, moduleGroupName, errorMsg))
+    {
+        throw PEGASUS_CIM_EXCEPTION_L(CIM_ERR_FAILED,
+            MessageLoaderParms(
+                "ControlProviders.ProviderRegistrationProvider."
+                    "ProviderRegistrationProvider."
+                    "SET_PROVIDERMODULEGROUPNAME_FAILED",
+                "Failed to set the ModuleGroupName: $0.",
+                errorMsg));
+    }
+
+    // Enable the module only if it was previously enabled.
+    if (disableRC == 0)
+    {
+        try
+        {
+            _enableModule(moduleRef, moduleName, al);
+        }
+        catch(const Exception &e)
+        {
+            PEG_TRACE((TRC_CONTROLPROVIDER,Tracer::LEVEL1,
+                "Exception caught while enabling the provider module %s : %s",
+                (const char*)moduleName.getCString(),
+                (const char*)e.getMessage().getCString()));
+        }
+        catch(...)
+        {
+            PEG_TRACE((
+                TRC_CONTROLPROVIDER,
+                Tracer::LEVEL1,
+                "Unknown error occurred while"
+                    " enabling the provider modules %s.",
+                (const char*)moduleName.getCString()));
+        }
+    }
+
+    return 0;
+}
+
+
 // get provider manager service
 MessageQueueService * ProviderRegistrationProvider::_getProviderManagerService()
 {
index 26da5532794d5c11c0f68c9f9bc4f78e4a887c89..692a2086aabe183d2df33e402fe85e041123077d 100644 (file)
@@ -164,6 +164,11 @@ protected:
                           Boolean disableProviderOnly,
                       const AcceptLanguageList & al);
 
+    Sint16 _setModuleGroupName(const CIMObjectPath & moduleRef,
+                          const String & moduleName,
+                          const String & moduleGroupName,
+                          const AcceptLanguageList & al);
+
     //
     // If the provider is an indication provider, return true
     // otherwise, return false
index 5819a401d7462f4465e8eddbbf6d2e93d5ae82bf..d48d777b5e747e02aaa0d7654b98d775141ce34f 100644 (file)
@@ -75,6 +75,9 @@ PEGASUS_USING_STD;
 
 PEGASUS_NAMESPACE_BEGIN
 
+static String _GROUP_PREFIX = "grp:";
+static String _MODULE_PREFIX = "mod:";
+
 /////////////////////////////////////////////////////////////////////////////
 // OutstandingRequestTable and OutstandingRequestEntry
 /////////////////////////////////////////////////////////////////////////////
@@ -127,7 +130,7 @@ class ProviderAgentContainer
 {
 public:
     ProviderAgentContainer(
-        const String & moduleName,
+        const String & groupNameWithType,
         const String & userName,
         Uint16 userContext,
         PEGASUS_INDICATION_CALLBACK_T indicationCallback,
@@ -139,7 +142,7 @@ public:
 
     Boolean isInitialized();
 
-    String getModuleName() const;
+    String getGroupNameWithType() const;
 
     CIMResponseMessage* processMessage(CIMRequestMessage* request);
     void unloadIdleProviders();
@@ -223,9 +226,15 @@ private:
     Mutex _agentMutex;
 
     /**
-        Name of the provider module served by this Provider Agent.
+        Name of the provider module or group served by this Provider Agent.
+     */
+    String _moduleOrGroupName;
+
+    /**
+        Name of the group with type(group or module indicator)
+        served by this Provider Agent.
      */
-    String _moduleName;
+    String _groupNameWithType;
 
     /**
         The user context in which this Provider Agent operates.
@@ -326,6 +335,7 @@ private:
         ProviderManagerRouter::_subscriptionInitComplete member variable.
      */
     Boolean _subscriptionInitComplete;
+
 };
 
 Uint32 ProviderAgentContainer::_numProviderProcesses = 0;
@@ -336,7 +346,7 @@ CIMResponseMessage* ProviderAgentContainer::_REQUEST_NOT_PROCESSED =
     static_cast<CIMResponseMessage*>((void*)&_REQUEST_NOT_PROCESSED);
 
 ProviderAgentContainer::ProviderAgentContainer(
-    const String & moduleName,
+    const String & groupName,
     const String & userName,
     Uint16 userContext,
     PEGASUS_INDICATION_CALLBACK_T indicationCallback,
@@ -344,7 +354,7 @@ ProviderAgentContainer::ProviderAgentContainer(
     PEGASUS_PROVIDERMODULEFAIL_CALLBACK_T providerModuleFailCallback,
     Boolean subscriptionInitComplete)
     :
-      _moduleName(moduleName),
+      _groupNameWithType(groupName),
       _userName(userName),
       _userContext(userContext),
       _indicationCallback(indicationCallback),
@@ -353,9 +363,12 @@ ProviderAgentContainer::ProviderAgentContainer(
       _isInitialized(false),
       _subscriptionInitComplete(subscriptionInitComplete)
 {
-
     PEG_METHOD_ENTER(TRC_PROVIDERMANAGER,
         "ProviderAgentContainer::ProviderAgentContainer");
+
+    // Remove prefixes "grp" and "mod" and get actual module or group name.
+    _moduleOrGroupName = _groupNameWithType.subString(4);
+
     PEG_METHOD_EXIT();
 }
 
@@ -406,7 +419,7 @@ void ProviderAgentContainer::_startAgentProcess()
     AnonymousPipe* writePipe;
 
     int status = Executor::startProviderAgent(
-        (const char*)_moduleName.getCString(),
+        (const char*)_moduleOrGroupName.getCString(),
         ConfigManager::getPegasusHome(),
         _userName,
         pid,
@@ -421,7 +434,7 @@ void ProviderAgentContainer::_startAgentProcess()
         throw Exception(MessageLoaderParms(
             "ProviderManager.OOPProviderManagerRouter.CIMPROVAGT_START_FAILED",
             "Failed to start cimprovagt \"$0\".",
-            _moduleName));
+            _moduleOrGroupName));
     }
 
 # if defined(PEGASUS_HAS_SIGNALS)
@@ -486,7 +499,7 @@ void ProviderAgentContainer::_sendInitializationData()
             "ProviderManager.OOPProviderManagerRouter."
                 "CIMPROVAGT_COMMUNICATION_FAILED",
             "Failed to communicate with cimprovagt \"$0\".",
-            _moduleName));
+            _moduleOrGroupName));
     }
 
     // Wait for a null response from the Provider Agent indicating it has
@@ -507,7 +520,7 @@ void ProviderAgentContainer::_sendInitializationData()
             "ProviderManager.OOPProviderManagerRouter."
                 "CIMPROVAGT_COMMUNICATION_FAILED",
             "Failed to communicate with cimprovagt \"$0\".",
-            _moduleName));
+            _moduleOrGroupName));
     }
 
     PEGASUS_ASSERT(message == 0);
@@ -585,7 +598,7 @@ void ProviderAgentContainer::_initialize()
                     "ProviderManager.OOPProviderManagerRouter."
                         "CIMPROVAGT_THREAD_ALLOCATION_FAILED",
                     "Failed to allocate thread for cimprovagt \"$0\".",
-                    _moduleName));
+                    _moduleOrGroupName));
             }
         }
     }
@@ -697,7 +710,26 @@ void ProviderAgentContainer::_uninitialize(Boolean cleanShutdown)
             // the failure to the Provider Manager Service.  The Provider
             // Manager Service will inform the Indication Service.
             //
-            _providerModuleFailCallback(_moduleName, _userName, _userContext);
+            Array<String> moduleNames;
+
+            // If this agent is servicing the group of modules, get all related
+            // provider module names.
+            if (!String::compare(_groupNameWithType, _GROUP_PREFIX, 4))
+            {
+                OOPProviderManagerRouter::getProviderRegistrationManager()->
+                    getProviderModuleNamesForGroup(
+                        _moduleOrGroupName, moduleNames);
+            }
+            else
+            {
+                moduleNames.append(_moduleOrGroupName);
+            }
+
+            for (Uint32 i = 0, n = moduleNames.size(); i < n; i++)
+            {
+                _providerModuleFailCallback(
+                    moduleNames[i], _userName, _userContext);
+            }
         }
     }
     catch (...)
@@ -722,9 +754,9 @@ void ProviderAgentContainer::_uninitialize(Boolean cleanShutdown)
     PEG_METHOD_EXIT();
 }
 
-String ProviderAgentContainer::getModuleName() const
+String ProviderAgentContainer::getGroupNameWithType() const
 {
-    return _moduleName;
+    return _groupNameWithType;
 }
 
 CIMResponseMessage* ProviderAgentContainer::processMessage(
@@ -758,6 +790,7 @@ CIMResponseMessage* ProviderAgentContainer::processMessage(
             }
             else if (request->getType() == CIM_DISABLE_MODULE_REQUEST_MESSAGE)
             {
+                response = request->buildResponse();
                 CIMDisableModuleResponseMessage* dmResponse =
                     dynamic_cast<CIMDisableModuleResponseMessage*>(response);
                 PEGASUS_ASSERT(dmResponse != 0);
@@ -995,7 +1028,7 @@ CIMResponseMessage* ProviderAgentContainer::_processMessage(
                     "ProviderManager.OOPProviderManagerRouter."
                         "CIMPROVAGT_CONNECTION_LOST",
                     "Lost connection with cimprovagt \"$0\".",
-                    _moduleName));
+                    _moduleOrGroupName));
         }
     }
     catch (CIMException& e)
@@ -1257,7 +1290,11 @@ ProviderAgentContainer::_responseProcessor(void* arg)
 // OOPProviderManagerRouter
 /////////////////////////////////////////////////////////////////////////////
 
+ProviderRegistrationManager*
+    OOPProviderManagerRouter::_providerRegistrationManager;
+
 OOPProviderManagerRouter::OOPProviderManagerRouter(
+    ProviderRegistrationManager *providerRegistrationManager,
     PEGASUS_INDICATION_CALLBACK_T indicationCallback,
     PEGASUS_RESPONSE_CHUNK_CALLBACK_T responseChunkCallback,
     PEGASUS_PROVIDERMODULEFAIL_CALLBACK_T providerModuleFailCallback)
@@ -1269,7 +1306,7 @@ OOPProviderManagerRouter::OOPProviderManagerRouter(
     _responseChunkCallback = responseChunkCallback;
     _providerModuleFailCallback = providerModuleFailCallback;
     _subscriptionInitComplete = false;
-
+    _providerRegistrationManager = providerRegistrationManager;
     PEG_METHOD_EXIT();
 }
 
@@ -1293,6 +1330,12 @@ OOPProviderManagerRouter::~OOPProviderManagerRouter()
     PEG_METHOD_EXIT();
 }
 
+ProviderRegistrationManager*
+    OOPProviderManagerRouter::getProviderRegistrationManager()
+{
+    return _providerRegistrationManager;
+}
+
 Message* OOPProviderManagerRouter::processMessage(Message* message)
 {
     PEG_METHOD_ENTER(TRC_PROVIDERMANAGER,
@@ -1404,13 +1447,14 @@ Message* OOPProviderManagerRouter::processMessage(Message* message)
     {
         // Fan out the request to all Provider Agent processes for this module
 
-        // Retrieve the provider module name
-        String moduleName;
-        _getProviderModuleName(providerModule,moduleName);
+        // Retrieve the provider group name.
+        String groupNameWithType;
+        _getGroupNameWithType(providerModule, groupNameWithType);
+
 
         // Look up the Provider Agents for this module
         Array<ProviderAgentContainer*> paArray =
-            _lookupProviderAgents(moduleName);
+            _lookupProviderAgents(groupNameWithType);
 
         for (Uint32 i=0; i<paArray.size(); i++)
         {
@@ -1472,13 +1516,13 @@ Message* OOPProviderManagerRouter::processMessage(Message* message)
     {
         // Fan out the request to all Provider Agent processes for this module
 
-        // Retrieve the provider module name
-        String moduleName;
-        _getProviderModuleName(providerModule,moduleName);
+        // Retrieve the provider module group name.
+        String groupNameWithType;
+        _getGroupNameWithType(providerModule, groupNameWithType);
 
         // Look up the Provider Agents for this module
         Array<ProviderAgentContainer*> paArray =
-            _lookupProviderAgents(moduleName);
+            _lookupProviderAgents(groupNameWithType);
 
         for (Uint32 i=0; i<paArray.size(); i++)
         {
@@ -1556,9 +1600,9 @@ ProviderAgentContainer* OOPProviderManagerRouter::_lookupProviderAgent(
     const CIMInstance& providerModule,
     CIMRequestMessage* request)
 {
-    // Retrieve the provider module name
-    String moduleName;
-    _getProviderModuleName(providerModule,moduleName);
+    // Retrieve the provider module group name
+    String groupNameWithType;
+    _getGroupNameWithType(providerModule, groupNameWithType);
 
 #if defined(PEGASUS_OS_ZOS)
     // For z/OS we don't start an extra provider agent for
@@ -1642,43 +1686,45 @@ ProviderAgentContainer* OOPProviderManagerRouter::_lookupProviderAgent(
     PEG_TRACE((
         TRC_PROVIDERMANAGER,
         Tracer::LEVEL4,
-        "Module name = %s, User context = %hd, User name = %s",
-        (const char*) moduleName.getCString(),
+        "Group name with type = %s, User context = %hd, User name = %s",
+        (const char*) groupNameWithType.getCString(),
         userContext,
         (const char*) userName.getCString()));
 #endif
 
     ProviderAgentContainer* pa = 0;
+
 #ifdef PEGASUS_OS_PASE
     String userUpper = userName;
     userUpper.toUpper();
-    String key = moduleName + ":" + userUpper;
+    String key = groupNameWithType + ":" + userUpper;
 #else
-    String key = moduleName + ":" + userName;
+    String key = groupNameWithType + ":" + userName;
 #endif
 
     AutoMutex lock(_providerAgentTableMutex);
     if (!_providerAgentTable.lookup(key, pa))
     {
         pa = new ProviderAgentContainer(
-            moduleName, userName, userContext,
+            groupNameWithType, userName, userContext,
             _indicationCallback, _responseChunkCallback,
             _providerModuleFailCallback,
             _subscriptionInitComplete);
         _providerAgentTable.insert(key, pa);
     }
+
     return pa;
 }
 
 Array<ProviderAgentContainer*> OOPProviderManagerRouter::_lookupProviderAgents(
-    const String& moduleName)
+    const String& groupNameWithType)
 {
     Array<ProviderAgentContainer*> paArray;
 
     AutoMutex lock(_providerAgentTableMutex);
     for (ProviderAgentTable::Iterator i = _providerAgentTable.start(); i; i++)
     {
-        if (i.value()->getModuleName() == moduleName)
+        if (i.value()->getGroupNameWithType() == groupNameWithType)
         {
             paArray.append(i.value());
         }
@@ -1765,6 +1811,37 @@ void OOPProviderManagerRouter::unloadIdleProviders()
     PEG_METHOD_EXIT();
 }
 
+void OOPProviderManagerRouter::_getGroupNameWithType(
+        const CIMInstance &providerModule,
+        String &groupNameWithType)
+{
+    Uint32 idx = providerModule.findProperty(
+            PEGASUS_PROPERTYNAME_MODULE_MODULEGROUPNAME);
+
+    String moduleName;
+    String groupName;
+
+    if (idx != PEG_NOT_FOUND)
+    {
+        providerModule.getProperty(idx).getValue().get(groupName);
+    }
+
+    // Note: If group name is not found, module name is used as group name.
+    // prefixes "grp" and "mod" is used to distinguish between the provider
+    // modules who have same group and module names.
+    if (groupName.size())
+    {
+        groupNameWithType.assign(_GROUP_PREFIX);
+        groupNameWithType.append(groupName);
+    }
+    else
+    {
+        _getProviderModuleName(providerModule, moduleName);
+        groupNameWithType.assign(_MODULE_PREFIX);
+        groupNameWithType.append(moduleName);
+    }
+}
+
 void OOPProviderManagerRouter::_getProviderModuleName(
         const CIMInstance & providerModule,
         String & moduleName)
index e92863c9ed8af135abb60d345db020c8dac78e6d..28d144984550d84c07898d07d1cbd7431f02f9f3 100644 (file)
@@ -41,6 +41,9 @@
 #include <Pegasus/ProviderManagerService/ProviderManagerRouter.h>
 #include <Pegasus/ProviderManagerService/Linkage.h>
 
+#include \
+    <Pegasus/Server/ProviderRegistrationManager/ProviderRegistrationManager.h>
+
 PEGASUS_NAMESPACE_BEGIN
 
 typedef void (*PEGASUS_PROVIDERMODULEFAIL_CALLBACK_T)(const String &,
@@ -56,6 +59,7 @@ class PEGASUS_PMS_LINKAGE OOPProviderManagerRouter
 {
 public:
     OOPProviderManagerRouter(
+        ProviderRegistrationManager *providerRegistrationManager,
         PEGASUS_INDICATION_CALLBACK_T indicationCallback,
         PEGASUS_RESPONSE_CHUNK_CALLBACK_T responseChunkCallback,
         PEGASUS_PROVIDERMODULEFAIL_CALLBACK_T providerModuleFailCallback);
@@ -66,6 +70,8 @@ public:
 
     virtual void unloadIdleProviders();
 
+    static ProviderRegistrationManager* getProviderRegistrationManager();
+
 private:
     //
     // Private methods
@@ -76,6 +82,17 @@ private:
         const CIMInstance & providerModule,
         String & moduleName);
 
+    /**
+        Determine groupName from the providerModule. Function sets
+        groupName. A type prefix(grp or mod) is added to distinguish
+        between group and module names.
+        If ModuleGroupName property value is not specified, moduleName is set
+        to groupName.
+    */
+    void _getGroupNameWithType(
+        const CIMInstance &providerModule,
+        String &groupNameWithType);
+
     /** Unimplemented */
     OOPProviderManagerRouter();
     /** Unimplemented */
@@ -138,6 +155,9 @@ private:
         _providerAgentTable is accessed.
      */
     Mutex _providerAgentTableMutex;
+
+    static ProviderRegistrationManager *_providerRegistrationManager;
+
 };
 
 PEGASUS_NAMESPACE_END
index af65aa13536f9495ac5e4690eccba03448209f32..61596d874e1961fbeba951f4bed4285b22926617 100644 (file)
@@ -521,10 +521,12 @@ Boolean ProviderAgent::_readAndProcessRequest()
 
         // If StopAllProviders, terminate the agent process.
         // If DisableModule not successful, leave agent process running.
+        // If there are any active providers after DisableModule request
+        // successful, this agent might be servicing the group of
+        // provider modules, leave agent process running.
         if ((request->getType() == CIM_STOP_ALL_PROVIDERS_REQUEST_MESSAGE) ||
             ((request->getType() == CIM_DISABLE_MODULE_REQUEST_MESSAGE) &&
-             (!dynamic_cast<CIMDisableModuleRequestMessage*>(request)->
-                  disableProviderOnly) &&
+             (!_providerManagerRouter.hasActiveProviders()) &&
              (respMsg->cimException.getCode() == CIM_ERR_SUCCESS)))
         {
             // Operation is successful. End the agent process.
index d967f36626bb2981051b5806d2e5e698e857c08c..f4a24dd4932133a7df88d145095d2a78eb7ceae1 100644 (file)
@@ -58,6 +58,8 @@
 
 PEGASUS_NAMESPACE_BEGIN
 
+const String PG_PROVMODULE_GROUPNAME_CIMSERVER = "CIMServer";
+
 ProviderManagerService* ProviderManagerService::providerManagerService=NULL;
 Boolean ProviderManagerService::_allProvidersStopped = false;
 Uint32 ProviderManagerService::_indicationServiceQueueId = PEG_NOT_FOUND;
@@ -75,48 +77,20 @@ ProviderManagerService::ProviderManagerService(
 
     _unloadIdleProvidersBusy = 0;
 
-    _basicProviderManagerRouter = 0;
-    _oopProviderManagerRouter = 0;
-
-    // Determine which ProviderManagerRouter(s) to use
-
     _forceProviderProcesses = ConfigManager::parseBooleanValue(
         ConfigManager::getInstance()->getCurrentValue(
             "forceProviderProcesses"));
 
-#if defined(PEGASUS_DISABLE_PROV_USERCTXT) || defined(PEGASUS_OS_ZOS)
-    if (_forceProviderProcesses)
-    {
-        _oopProviderManagerRouter = new OOPProviderManagerRouter(
-            indicationCallback, responseChunkCallback,
-            providerModuleFailureCallback);
-    }
-    else
-    {
-        _basicProviderManagerRouter = new BasicProviderManagerRouter(
-            indicationCallback, responseChunkCallback,
-            createDefaultProviderManagerCallback);
-    }
-#else
     _oopProviderManagerRouter = new OOPProviderManagerRouter(
-        indicationCallback, responseChunkCallback,
+        providerRegistrationManager,
+        indicationCallback,
+        responseChunkCallback,
         providerModuleFailureCallback);
 
-    if (!_forceProviderProcesses)
-    {
-        _basicProviderManagerRouter = new BasicProviderManagerRouter(
-            indicationCallback, responseChunkCallback,
-            createDefaultProviderManagerCallback);
-    }
-#endif
-#ifdef PEGASUS_ENABLE_REMOTE_CMPI
-   if (!_basicProviderManagerRouter)
-   {
-       _basicProviderManagerRouter = new BasicProviderManagerRouter(
-           indicationCallback, responseChunkCallback,
-           createDefaultProviderManagerCallback);
-   }
-#endif
+    _basicProviderManagerRouter = new BasicProviderManagerRouter(
+        indicationCallback,
+        responseChunkCallback,
+        createDefaultProviderManagerCallback);
 }
 
 ProviderManagerService::~ProviderManagerService(void)
@@ -687,6 +661,14 @@ Message* ProviderManagerService::_processMessage(CIMRequestMessage* request)
             providerModule.getProperty(pos).getValue().get(userContext);
         }
 
+        String moduleGroupName;
+        Uint32 idx = providerModule.findProperty(
+            PEGASUS_PROPERTYNAME_MODULE_MODULEGROUPNAME);
+        if (idx != PEG_NOT_FOUND)
+        {
+            providerModule.getProperty(idx).getValue().get(moduleGroupName);
+        }
+
         // Load proxy-provider into CIMServer, in case of remote namespace
         // requests. (ie through _basicProviderManagerRouter). -V 3913
 #ifdef PEGASUS_ENABLE_REMOTE_CMPI
@@ -707,7 +689,8 @@ Message* ProviderManagerService::_processMessage(CIMRequestMessage* request)
         // Forward the request to the appropriate ProviderManagerRouter, based
         // on the CIM Server configuration and the UserContext setting.
 
-        if (_forceProviderProcesses
+        if ( (_forceProviderProcesses &&
+                   moduleGroupName != PG_PROVMODULE_GROUPNAME_CIMSERVER)
 #if !defined(PEGASUS_DISABLE_PROV_USERCTXT) && !defined(PEGASUS_OS_ZOS)
             || (userContext == PG_PROVMODULE_USERCTXT_REQUESTOR)
             || (userContext == PG_PROVMODULE_USERCTXT_DESIGNATED)
index 7735985887b46b751caa2f6e524c57e801b6c493..b3820c05399eb4c583e7c2375c07d4e3f245aee1 100644 (file)
@@ -67,6 +67,7 @@ const CIMName _PROPERTY_PROVIDERTYPE = CIMNameCast("ProviderType");
 const CIMName _PROPERTY_SUPPORTEDPROPERTIES =CIMNameCast("SupportedProperties");
 const CIMName _PROPERTY_SUPPORTEDMETHODS = CIMNameCast("SupportedMethods");
 const CIMName _PROPERTY_INDICATIONDESTINATIONS = CIMNameCast("Destinations");
+const CIMName _PROPERTY_MODULEGROUPNAME = CIMNameCast("ModuleGroupName");
 
 /**
     ProviderRegistration table is used to keep track of provider registration
@@ -1566,6 +1567,137 @@ Array<Uint16> ProviderRegistrationManager::getProviderModuleStatus(
     return (_providerModuleStatus);
 }
 
+void ProviderRegistrationManager::getProviderModuleNamesForGroup(
+    const String& moduleGroupName,
+    Array<String> &moduleNames)
+{
+    String name;
+
+    ReadLock lock(_registrationTableLock);
+
+    // Retrieve required provider modules from registration hash table
+    // instead of repository. This significantly decreases the time required.
+    for (Table::Iterator i=_registrationTable->table.start(); i; i++)
+    {
+        Array<CIMInstance> instances;
+        instances = i.value()->getInstances();
+        for (Uint32 j = 0; j < instances.size(); j++)
+        {
+            if (instances[j].getClassName().equal(
+                PEGASUS_CLASSNAME_PROVIDERMODULE))
+            {
+                Uint32 pos = instances[j].findProperty(
+                    _PROPERTY_MODULEGROUPNAME);
+                if (pos != PEG_NOT_FOUND)
+                {
+                    instances[j].getProperty(pos).getValue().get(name);
+                    if (String::equalNoCase(moduleGroupName, name))
+                    {
+                        pos = instances[j].findProperty(
+                            _PROPERTY_PROVIDERMODULE_NAME);
+                        if (pos != PEG_NOT_FOUND)
+                        {
+                            instances[j].getProperty(pos).getValue().get(name);
+                            moduleNames.append(name);
+                        }
+                    }
+                }
+            }
+        }
+    }
+}
+
+Boolean ProviderRegistrationManager::setProviderModuleGroupName(
+    const String& providerModuleName,
+    const String& moduleGroupName,
+    String &errorMsg)
+{
+    WriteLock lock(_registrationTableLock);
+
+    String oldModuleGroupName;
+
+    try
+    {
+        Array <CIMKeyBinding> moduleKeyBindings;
+
+        moduleKeyBindings.append (CIMKeyBinding
+            (_PROPERTY_PROVIDERMODULE_NAME,
+             providerModuleName, CIMKeyBinding::STRING));
+        CIMObjectPath reference ("", CIMNamespaceName (),
+            PEGASUS_CLASSNAME_PROVIDERMODULE, moduleKeyBindings);
+
+        //
+        // get the old group value.
+        //
+        CIMValue groupValue =  _repository->getProperty(
+            PEGASUS_NAMESPACENAME_INTEROP,
+            reference, _PROPERTY_MODULEGROUPNAME);
+        groupValue.get(oldModuleGroupName);
+
+        //
+        // update provider module with the new group name
+        //
+        _repository->setProperty(
+            PEGASUS_NAMESPACENAME_INTEROP,
+            reference, _PROPERTY_MODULEGROUPNAME, moduleGroupName);
+
+        //
+        //  get instance from the repository
+        //
+        CIMInstance _instance = _repository->getInstance(
+            PEGASUS_NAMESPACENAME_INTEROP,
+            reference,
+            false,
+            false,
+            CIMPropertyList());
+        //
+        // remove old entry from table
+        //
+        String _moduleKey = _generateKey(providerModuleName, MODULE_KEY);
+        ProviderRegistrationTable* _entry = 0;
+        if (_registrationTable->table.lookup(_moduleKey, _entry))
+        {
+            delete _entry;
+            _registrationTable->table.remove(_moduleKey);
+        }
+
+        //
+        // add the updated instance to the table
+        //
+        Array<CIMInstance> instances;
+        instances.append(_instance);
+        _addInstancesToTable(_moduleKey, instances);
+    }
+    catch (const Exception & e)
+    {
+        errorMsg = e.getMessage();
+        PEG_TRACE((TRC_DISCARDED_DATA, Tracer::LEVEL1,
+            "Group name %s cannot be set to the provider module %s : %s",
+            (const char*)moduleGroupName.getCString(),
+            (const char*)providerModuleName.getCString(),
+            (const char*)errorMsg.getCString()));
+        return false;
+    }
+    catch (...)
+    {
+        errorMsg = "Unknown error";
+        PEG_TRACE((TRC_DISCARDED_DATA, Tracer::LEVEL1,
+            "Unknown error occured while setting the group name %s"
+                " to the provider module : %s",
+            (const char*)moduleGroupName.getCString(),
+            (const char*)providerModuleName.getCString()));
+        return false;
+    }
+
+    PEG_AUDIT_LOG(
+        logSetProvModuleGroupName(
+            providerModuleName,
+            oldModuleGroupName,
+            moduleGroupName));
+
+    return (true);
+}
+
 Boolean ProviderRegistrationManager::updateProviderModuleStatus(
     const String& providerModuleName,
     const Array<Uint16>& removeStatus,
index 5f7f05c162a3a955fabc8b377c4e33b88e339b06..8978e530bfb6b8ce282a6eff254b8b44e45c45f8 100644 (file)
@@ -241,6 +241,38 @@ public:
         const Array<Uint16>& appendStatus,
         Array<Uint16>& outStatus);
 
+    /**
+        Retrieves all the provider module names who have the given
+        moduleGroupName in common.
+
+        @param    moduleGroupName String specifying name of the provider
+                  module group.
+        @param    moduleNames OUTPUT array of string returning the provider
+                  module names for the group
+
+    */
+    void getProviderModuleNamesForGroup(
+        const String& moduleGroupName,
+        Array<String>& moduleNames);
+
+    /**
+        Sets the provider module group name for the specified provider
+        module.
+
+        @param    providerModuleName String specifying name of the provider
+                  module.
+        @param    moduleGroupName  String specifying name of the provider
+                  module group.
+        @param    errorMsg  Output arg, String containing the reason for failure
+
+        @return   True if the ModuleGroupName set successfully,
+                  Otherwise, return false.
+    */
+    Boolean setProviderModuleGroupName(
+        const String& providerModuleName,
+        const String& moduleGroupName,
+        String &errorMsg);
+
     /**
         Determines whether specified provider is an indication provider.
 
index 34a16d8d41a41c6c516d5a8456ad27626f7a7f08..1e427de7c597f02f7998b620da19e7849b39ca39 100755 (executable)
@@ -327,14 +327,25 @@ en:table {
        Clients.cimprovider.CIMProviderCommand.MENU.STANDARD:string {
     "Usage: cimprovider -d -m module\n"
     "                   -e -m module\n"
+    "                   -g group -m module\n"
     "                   -r -m module [ -p provider ]\n"
-    "                   -l [ -s | -m module ]\n"
+    "                   -l [ -s | -f | -m module ]\n"
     "                   -h\n"
     "                   --help\n"
     "                   --version\n"
     "  Options:\n"
     "      -d         - Disable the specified CIM provider module.\n"
     "      -e         - Enable the specified CIM provider module.\n"
+    "      -g         - Sets the CIM provider module group. Specify\n"
+    "                   empty string to remove from grouping.\n"
+    "                   If the provider module is  active, provider\n"
+    "                   module is disabled first, group is set and\n"
+    "                   enabled again. All provider modules with the same\n"
+    "                   group name are loaded into a single agent process\n"
+    "                   except when overridden by specific UserContext\n"
+    "                   values. If group name is CIMServer, provider module\n"
+    "                   is loaded into CIMServer process depending on\n"
+    "                   UserContext value.\n"
     "      -r         - Remove the registration for a provider (if specified)\n"
     "                   or for the specified provider module and all the providers\n"
     "                   it contains.\n"
@@ -342,6 +353,8 @@ en:table {
     "      -m         - Specify the provider module for the operation.\n"
     "      -p         - Specify the provider for the operation.\n"
     "      -s         - Display the status of registered provider modules.\n"
+    "      -f         - Full status, display the status of registered\n"
+    "                   provider modules and module group name.\n"
     "      -h, --help - Display this help message.\n"
     "      --version  - Display CIM Server version number.\n"
     "\n"
@@ -424,6 +437,12 @@ en:table {
 
         Clients.cimprovider.CIMProviderCommand.ERR_USAGE:string {"PGC00628: Use ''--help'' to obtain command syntax."}
 
+        Clients.cimprovider.CIMProviderCommand.SETTING_PROVIDERMODULE_GROUP:string {"PGC00628: Setting the provider module group..."}
+
+        Clients.cimprovider.CIMProviderCommand.SET_PROVIDERMODULE_GROUP_SUCCESS:string {"PGC00629: Provider module group set successfully."}
+
+       Clients.cimprovider.CIMProviderCommand.SET_PROVIDERMODULE_GROUP_FAILURE:string {"PGC00630: Failed to set the provider module group."}
+
 
        // ==========================================================
         // Messages for CIMUserCommand
index bbbf06d3b524679f5397b465e7995765c67e4c72..d33a45e49a14ef0ba3a934b7780574b1ea6fe3a4 100644 (file)
@@ -1323,6 +1323,14 @@ en:table {
         */
         ControlProviders.ProviderRegistrationProvider.ProviderRegistrationProvider.UNSUPPORTED_INTERFACETYPE_VALUE:string {"PGS03034: InterfaceType property value {0} is not supported."}
 
+        /**
+        * @note PGS03035:
+        *     Do not translate the word 'ModuleGroupName' since it is the name of a CIM property.
+        *     Substitution {0} is a string containing reason for the failure
+        *     to set the ModuleGroupName.
+        */
+        ControlProviders.ProviderRegistrationProvider.ProviderRegistrationProvider.SET_PROVIDERMODULEGROUPNAME_FAILED:string {"PGS03035: Failed to set the ModuleGroupName: {0}."}
+
 
         // ==========================================================
         // Messages for UserAuthProvider
@@ -6817,6 +6825,18 @@ CIM server listening on HTTPS port {0}."}
         */
         Common.AuditLogger.CERTIFICATE_BASED_USER_VALIDATION:string {"PGS17817: Certificate based user validation attempt: successful = {0}, from IP address = {5}, user name = {1}, issuer name = {2}, subject name = {3}, serial number = {4}."}
 
+        /**
+        * @note PGS17818:
+        *    Do not translate the word 'ModuleGroupName' since it is the name of a CIM property.
+        *    Substitution {0} is a string containing a provider module name
+        *    Substitution {1} is a string containing a current ModuleGroupName
+        *    value
+        *    Substitution {2} is a string containing a new ModuleGroupName
+        *    value
+        *
+        */
+        Common.AuditLogger.SET_PROVIDER_MODULE_GROUP:string {"PGS17818: The ModuleGroupName of provider module \"{0}\" has changed from \"{1}\" to \"{2}\"."}
+
         // ==========================================================
         // Messages for DynListener.cimlistener
         //  Please use message prefix "PGS18000"
diff --git a/src/Providers/TestProviders/Load/GroupMethodProvider.mof b/src/Providers/TestProviders/Load/GroupMethodProvider.mof
new file mode 100644 (file)
index 0000000..0020335
--- /dev/null
@@ -0,0 +1,46 @@
+//%LICENSE////////////////////////////////////////////////////////////////
+//
+// Licensed to The Open Group (TOG) under one or more contributor license
+// agreements.  Refer to the OpenPegasusNOTICE.txt file distributed with
+// this work for additional information regarding copyright ownership.
+// Each contributor licenses this file to you under the OpenPegasus Open
+// Source License; you may not use this file except in compliance with the
+// License.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//////////////////////////////////////////////////////////////////////////
+
+class Test_GroupingClass : CIM_Indication
+{
+    [key]
+    uint32 id;
+    uint32 getNextIdentifier();
+};
+
+class Test_GroupingClass1 : Test_GroupingClass
+{
+    uint32 resetIdentifier();
+    uint32 testFail();
+};
+
+class Test_GroupingClass2 : Test_GroupingClass
+{
+};
+
index f20e7699cbf32754c5883b0c0bfef51922db9dd9..6b921792b07c36f17c0e055e334e9ec436c0d150 100644 (file)
@@ -101,9 +101,10 @@ repository:
 
        @ $(ECHO) +++++ Loading MethodTestProvider class definitions into $(TESTPROVIDERNS) namespace ...
        @ cimmofl "-R$(REPOSITORY_DIR)" "-N$(REPOSITORY_NAME)" "-M$(REPOSITORY_MODE)" "-n$(TESTPROVIDERNS)" MethodTestProvider.mof
+       @ $(ECHO) +++++ Loading GroupMethodProvider class definitions into $(TESTPROVIDERNS) namespace ...
+       @ cimmofl "-R$(REPOSITORY_DIR)" "-N$(REPOSITORY_NAME)" "-M$(REPOSITORY_MODE)" "-n$(TESTPROVIDERNS)" GroupMethodProvider.mof
        @ $(ECHO) +++++ Registering MethodTestProvider ...
        @ cimmofl "-R$(REPOSITORY_DIR)" "-N$(REPOSITORY_NAME)" "-M$(REPOSITORY_MODE)" "-n$(INTEROPNS)" MethodTestProviderR.mof
-
        @ $(ECHO) +++++ Loading CLITestProvider class definitions into $(TESTPROVIDERNS) namespace ...
        @ cimmofl "-R$(REPOSITORY_DIR)" "-N$(REPOSITORY_NAME)" "-M$(REPOSITORY_MODE)" "-n$(TESTPROVIDERNS)" CLITestProvider.mof
        @ $(ECHO) +++++ Registering CLITestProvider ...
@@ -226,6 +227,8 @@ repositoryServer:
 
        @ $(ECHO) +++++ Loading MethodTestProvider class definitions into $(TESTPROVIDERNS) namespace ...
        @ cimmof "-n$(TESTPROVIDERNS)" MethodTestProvider.mof
+       @ $(ECHO) +++++ Loading GroupMethodProvider class definitions into $(TESTPROVIDERNS) namespace ...
+       @ cimmof "-n$(TESTPROVIDERNS)" GroupMethodProvider.mof
        @ $(ECHO) +++++ Registering MethodTestProvider ...
        @ cimmof "-n$(INTEROPNS)" MethodTestProviderR.mof
 
index f1e8a8f2fcef95e27f4d6bb572642a6e76174664..514f5edd72783b8df5e69b3ad4069b3cdb1eeb4c 100644 (file)
@@ -65,7 +65,8 @@ TEST_DIRS = \
        LocalizedProvider/msg \
        PerformanceTests \
         EmbeddedInstanceProvider \
-        EmbeddedInstanceProvider/testClient
+        EmbeddedInstanceProvider/testClient \
+        TestModuleGrouping
 
 ifeq ($(PEGASUS_ENABLE_INTEROP_PROVIDER),true)
 TEST_DIRS += \
diff --git a/src/Providers/TestProviders/TestModuleGrouping/GroupProvider1/Makefile b/src/Providers/TestProviders/TestModuleGrouping/GroupProvider1/Makefile
new file mode 100644 (file)
index 0000000..048ec31
--- /dev/null
@@ -0,0 +1,47 @@
+#//%LICENSE////////////////////////////////////////////////////////////////
+#//
+#// Licensed to The Open Group (TOG) under one or more contributor license
+#// agreements.  Refer to the OpenPegasusNOTICE.txt file distributed with
+#// this work for additional information regarding copyright ownership.
+#// Each contributor licenses this file to you under the OpenPegasus Open
+#// Source License; you may not use this file except in compliance with the
+#// License.
+#//
+#// Permission is hereby granted, free of charge, to any person obtaining a
+#// copy of this software and associated documentation files (the "Software"),
+#// to deal in the Software without restriction, including without limitation
+#// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+#// and/or sell copies of the Software, and to permit persons to whom the
+#// Software is furnished to do so, subject to the following conditions:
+#//
+#// The above copyright notice and this permission notice shall be included
+#// in all copies or substantial portions of the Software.
+#//
+#// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+#// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+#// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+#// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+#// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+#// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+#// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#//
+#//////////////////////////////////////////////////////////////////////////
+ROOT = ../../../../..
+
+DIR = Providers/TestProviders/TestModuleGrouping/GroupProvider1
+
+include $(ROOT)/mak/config.mak
+
+LIBRARY = TestGroupingProvider1
+
+LIBRARIES = \
+    groupUtilLib \
+    pegprovider \
+    pegclient \
+    pegcommon
+       
+SOURCES = \
+    TestGroupingProviderMain.cpp \
+    TestGroupingProvider.cpp
+
+include $(ROOT)/mak/dynamic-library.mak
diff --git a/src/Providers/TestProviders/TestModuleGrouping/GroupProvider1/TestGroupingProvider.cpp b/src/Providers/TestProviders/TestModuleGrouping/GroupProvider1/TestGroupingProvider.cpp
new file mode 100644 (file)
index 0000000..11ab2fd
--- /dev/null
@@ -0,0 +1,119 @@
+//%LICENSE////////////////////////////////////////////////////////////////
+//
+// Licensed to The Open Group (TOG) under one or more contributor license
+// agreements.  Refer to the OpenPegasusNOTICE.txt file distributed with
+// this work for additional information regarding copyright ownership.
+// Each contributor licenses this file to you under the OpenPegasus Open
+// Source License; you may not use this file except in compliance with the
+// License.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//////////////////////////////////////////////////////////////////////////
+//
+//%/////////////////////////////////////////////////////////////////////////////
+
+#include "TestGroupingProvider.h"
+#include "../GroupUtilLib/groupUtilLib.h"
+
+PEGASUS_NAMESPACE_BEGIN
+
+TestGroupingProvider1::TestGroupingProvider1()
+{
+}
+
+TestGroupingProvider1::~TestGroupingProvider1()
+{
+}
+
+void TestGroupingProvider1::initialize(CIMOMHandle& cimom)
+{
+    _cimom = cimom;
+}
+
+void TestGroupingProvider1::terminate()
+{
+    delete this;
+}
+
+void TestGroupingProvider1::invokeMethod(
+    const OperationContext& context,
+    const CIMObjectPath& objectReference,
+    const CIMName& methodName,
+    const Array<CIMParamValue>& inParameters,
+    MethodResultResponseHandler& handler)
+{
+    if (!objectReference.getClassName().equal("Test_GroupingClass1"))
+    {
+        throw CIMNotSupportedException(
+            objectReference.getClassName().getString());
+    }
+
+    handler.processing();
+    if (methodName.equal("getNextIdentifier"))
+    {
+        handler.deliver(CIMValue(getNextIdentifier()));
+    }
+    else if (methodName.equal("resetIdentifier"))
+    {
+        handler.deliver(CIMValue(resetIdentifier()));
+    }
+    else if (methodName.equal("testFail"))
+    {
+        exit(-1);
+    }
+    handler.complete();
+}
+
+void TestGroupingProvider1::enableIndications (
+    IndicationResponseHandler & handler)
+{
+}
+
+void TestGroupingProvider1::disableIndications ()
+{
+}
+
+void TestGroupingProvider1::createSubscription (
+    const OperationContext & context,
+    const CIMObjectPath & subscriptionName,
+    const Array <CIMObjectPath> & classNames,
+    const CIMPropertyList & propertyList,
+    const Uint16 repeatNotificationPolicy)
+{
+}
+
+void TestGroupingProvider1::modifySubscription (
+    const OperationContext & context,
+    const CIMObjectPath & subscriptionName,
+    const Array <CIMObjectPath> & classNames,
+    const CIMPropertyList & propertyList,
+    const Uint16 repeatNotificationPolicy)
+{
+}
+
+
+void TestGroupingProvider1::deleteSubscription (
+    const OperationContext & context,
+    const CIMObjectPath & subscriptionName,
+    const Array <CIMObjectPath> & classNames)
+{
+}
+
+PEGASUS_NAMESPACE_END
diff --git a/src/Providers/TestProviders/TestModuleGrouping/GroupProvider1/TestGroupingProvider.h b/src/Providers/TestProviders/TestModuleGrouping/GroupProvider1/TestGroupingProvider.h
new file mode 100644 (file)
index 0000000..9452e04
--- /dev/null
@@ -0,0 +1,88 @@
+//%LICENSE////////////////////////////////////////////////////////////////
+//
+// Licensed to The Open Group (TOG) under one or more contributor license
+// agreements.  Refer to the OpenPegasusNOTICE.txt file distributed with
+// this work for additional information regarding copyright ownership.
+// Each contributor licenses this file to you under the OpenPegasus Open
+// Source License; you may not use this file except in compliance with the
+// License.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//////////////////////////////////////////////////////////////////////////
+//
+//%/////////////////////////////////////////////////////////////////////////////
+
+#ifndef Pegasus_TestGroupingProvider1_h
+#define Pegasus_TestGroupingProvider1_h
+
+#include <Pegasus/Common/Config.h>
+#include <Pegasus/Provider/CIMMethodProvider.h>
+#include <Pegasus/Provider/CIMIndicationProvider.h>
+
+PEGASUS_NAMESPACE_BEGIN
+
+class TestGroupingProvider1 : public CIMIndicationProvider,
+    public CIMMethodProvider
+{
+public:
+    TestGroupingProvider1();
+    virtual ~TestGroupingProvider1();
+
+    virtual void initialize(CIMOMHandle& cimom);
+    virtual void terminate();
+
+    virtual void invokeMethod(
+        const OperationContext& context,
+        const CIMObjectPath& objectReference,
+        const CIMName& methodName,
+        const Array<CIMParamValue>& inParameters,
+        MethodResultResponseHandler& handler);
+
+    virtual void enableIndications (
+        IndicationResponseHandler & handler);
+
+    virtual void disableIndications ();
+
+    virtual void createSubscription (
+        const OperationContext & context,
+        const CIMObjectPath & subscriptionName,
+        const Array <CIMObjectPath> & classNames,
+        const CIMPropertyList & propertyList,
+        const Uint16 repeatNotificationPolicy);
+
+    virtual void modifySubscription (
+        const OperationContext & context,
+        const CIMObjectPath & subscriptionName,
+        const Array <CIMObjectPath> & classNames,
+        const CIMPropertyList & propertyList,
+        const Uint16 repeatNotificationPolicy);
+
+    virtual void deleteSubscription (
+        const OperationContext & context,
+        const CIMObjectPath & subscriptionName,
+        const Array <CIMObjectPath> & classNames);
+
+private:
+    CIMOMHandle _cimom;
+};
+
+PEGASUS_NAMESPACE_END
+
+#endif
diff --git a/src/Providers/TestProviders/TestModuleGrouping/GroupProvider1/TestGroupingProviderMain.cpp b/src/Providers/TestProviders/TestModuleGrouping/GroupProvider1/TestGroupingProviderMain.cpp
new file mode 100644 (file)
index 0000000..4508508
--- /dev/null
@@ -0,0 +1,48 @@
+//%LICENSE////////////////////////////////////////////////////////////////
+//
+// Licensed to The Open Group (TOG) under one or more contributor license
+// agreements.  Refer to the OpenPegasusNOTICE.txt file distributed with
+// this work for additional information regarding copyright ownership.
+// Each contributor licenses this file to you under the OpenPegasus Open
+// Source License; you may not use this file except in compliance with the
+// License.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//////////////////////////////////////////////////////////////////////////
+//
+//%/////////////////////////////////////////////////////////////////////////////
+
+#include <Pegasus/Common/Config.h>
+#include <Pegasus/Common/String.h>
+
+#include "TestGroupingProvider.h"
+
+PEGASUS_USING_PEGASUS;
+PEGASUS_USING_STD;
+
+extern "C" PEGASUS_EXPORT CIMProvider* PegasusCreateProvider(
+    const String& providerName)
+{
+    if(String::equalNoCase(providerName, "TestGroupingProvider1"))
+    {
+        return(new TestGroupingProvider1());
+    }
+    return(0);
+}
diff --git a/src/Providers/TestProviders/TestModuleGrouping/GroupProvider2/Makefile b/src/Providers/TestProviders/TestModuleGrouping/GroupProvider2/Makefile
new file mode 100644 (file)
index 0000000..ca291ea
--- /dev/null
@@ -0,0 +1,47 @@
+#//%LICENSE////////////////////////////////////////////////////////////////
+#//
+#// Licensed to The Open Group (TOG) under one or more contributor license
+#// agreements.  Refer to the OpenPegasusNOTICE.txt file distributed with
+#// this work for additional information regarding copyright ownership.
+#// Each contributor licenses this file to you under the OpenPegasus Open
+#// Source License; you may not use this file except in compliance with the
+#// License.
+#//
+#// Permission is hereby granted, free of charge, to any person obtaining a
+#// copy of this software and associated documentation files (the "Software"),
+#// to deal in the Software without restriction, including without limitation
+#// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+#// and/or sell copies of the Software, and to permit persons to whom the
+#// Software is furnished to do so, subject to the following conditions:
+#//
+#// The above copyright notice and this permission notice shall be included
+#// in all copies or substantial portions of the Software.
+#//
+#// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+#// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+#// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+#// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+#// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+#// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+#// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#//
+#//////////////////////////////////////////////////////////////////////////
+ROOT = ../../../../..
+
+DIR = Providers/TestProviders/TestModuleGrouping/GroupProvider2
+
+include $(ROOT)/mak/config.mak
+
+LIBRARY = TestGroupingProvider2
+
+LIBRARIES = \
+    groupUtilLib \
+    pegprovider \
+    pegclient \
+    pegcommon
+       
+SOURCES = \
+    TestGroupingProviderMain.cpp \
+    TestGroupingProvider.cpp
+
+include $(ROOT)/mak/dynamic-library.mak
diff --git a/src/Providers/TestProviders/TestModuleGrouping/GroupProvider2/TestGroupingProvider.cpp b/src/Providers/TestProviders/TestModuleGrouping/GroupProvider2/TestGroupingProvider.cpp
new file mode 100644 (file)
index 0000000..2ddeccf
--- /dev/null
@@ -0,0 +1,112 @@
+//%LICENSE////////////////////////////////////////////////////////////////
+//
+// Licensed to The Open Group (TOG) under one or more contributor license
+// agreements.  Refer to the OpenPegasusNOTICE.txt file distributed with
+// this work for additional information regarding copyright ownership.
+// Each contributor licenses this file to you under the OpenPegasus Open
+// Source License; you may not use this file except in compliance with the
+// License.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//////////////////////////////////////////////////////////////////////////
+//
+//%/////////////////////////////////////////////////////////////////////////////
+
+#include "TestGroupingProvider.h"
+#include "../GroupUtilLib/groupUtilLib.h"
+
+PEGASUS_NAMESPACE_BEGIN
+
+TestGroupingProvider2::TestGroupingProvider2()
+{
+}
+
+TestGroupingProvider2::~TestGroupingProvider2()
+{
+}
+
+void TestGroupingProvider2::initialize(CIMOMHandle& cimom)
+{
+    _cimom = cimom;
+}
+
+void TestGroupingProvider2::terminate()
+{
+    delete this;
+}
+
+void TestGroupingProvider2::invokeMethod(
+    const OperationContext& context,
+    const CIMObjectPath& objectReference,
+    const CIMName& methodName,
+    const Array<CIMParamValue>& inParameters,
+    MethodResultResponseHandler& handler)
+{
+    if (!objectReference.getClassName().equal("Test_GroupingClass2"))
+    {
+        throw CIMNotSupportedException(
+            objectReference.getClassName().getString());
+    }
+
+    handler.processing();
+    if (methodName.equal("getNextIdentifier"))
+    {
+        handler.deliver(CIMValue(getNextIdentifier()));
+    }
+
+    handler.complete();
+}
+
+void TestGroupingProvider2::enableIndications (
+    IndicationResponseHandler & handler)
+{
+}
+
+void TestGroupingProvider2::disableIndications ()
+{
+}
+
+void TestGroupingProvider2::createSubscription (
+    const OperationContext & context,
+    const CIMObjectPath & subscriptionName,
+    const Array <CIMObjectPath> & classNames,
+    const CIMPropertyList & propertyList,
+    const Uint16 repeatNotificationPolicy)
+{
+}
+
+void TestGroupingProvider2::modifySubscription (
+    const OperationContext & context,
+    const CIMObjectPath & subscriptionName,
+    const Array <CIMObjectPath> & classNames,
+    const CIMPropertyList & propertyList,
+    const Uint16 repeatNotificationPolicy)
+{
+}
+
+
+void TestGroupingProvider2::deleteSubscription (
+    const OperationContext & context,
+    const CIMObjectPath & subscriptionName,
+    const Array <CIMObjectPath> & classNames)
+{
+}
+
+PEGASUS_NAMESPACE_END
diff --git a/src/Providers/TestProviders/TestModuleGrouping/GroupProvider2/TestGroupingProvider.h b/src/Providers/TestProviders/TestModuleGrouping/GroupProvider2/TestGroupingProvider.h
new file mode 100644 (file)
index 0000000..04cb1a2
--- /dev/null
@@ -0,0 +1,90 @@
+//%LICENSE////////////////////////////////////////////////////////////////
+//
+// Licensed to The Open Group (TOG) under one or more contributor license
+// agreements.  Refer to the OpenPegasusNOTICE.txt file distributed with
+// this work for additional information regarding copyright ownership.
+// Each contributor licenses this file to you under the OpenPegasus Open
+// Source License; you may not use this file except in compliance with the
+// License.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//////////////////////////////////////////////////////////////////////////
+//
+//%/////////////////////////////////////////////////////////////////////////////
+
+#ifndef Pegasus_TestGroupingProvider2_h
+#define Pegasus_TestGroupingProvider2_h
+
+#include <Pegasus/Common/Config.h>
+#include <Pegasus/Provider/CIMMethodProvider.h>
+#include <Pegasus/Provider/CIMIndicationProvider.h>
+
+PEGASUS_NAMESPACE_BEGIN
+
+class TestGroupingProvider2 : public CIMMethodProvider,
+    public CIMIndicationProvider
+{
+public:
+    TestGroupingProvider2();
+    virtual ~TestGroupingProvider2();
+
+    // CIMProvider interface
+    virtual void initialize(CIMOMHandle& cimom);
+    virtual void terminate();
+
+    // CIMMethodProviderFacade
+    virtual void invokeMethod(
+        const OperationContext& context,
+        const CIMObjectPath& objectReference,
+        const CIMName& methodName,
+        const Array<CIMParamValue>& inParameters,
+        MethodResultResponseHandler& handler);
+
+    virtual void enableIndications (
+        IndicationResponseHandler & handler);
+
+    virtual void disableIndications ();
+
+    virtual void createSubscription (
+        const OperationContext & context,
+        const CIMObjectPath & subscriptionName,
+        const Array <CIMObjectPath> & classNames,
+        const CIMPropertyList & propertyList,
+        const Uint16 repeatNotificationPolicy);
+
+    virtual void modifySubscription (
+        const OperationContext & context,
+        const CIMObjectPath & subscriptionName,
+        const Array <CIMObjectPath> & classNames,
+        const CIMPropertyList & propertyList,
+        const Uint16 repeatNotificationPolicy);
+
+    virtual void deleteSubscription (
+        const OperationContext & context,
+        const CIMObjectPath & subscriptionName,
+        const Array <CIMObjectPath> & classNames);
+
+private:
+    CIMOMHandle _cimom;
+};
+
+PEGASUS_NAMESPACE_END
+
+#endif
diff --git a/src/Providers/TestProviders/TestModuleGrouping/GroupProvider2/TestGroupingProviderMain.cpp b/src/Providers/TestProviders/TestModuleGrouping/GroupProvider2/TestGroupingProviderMain.cpp
new file mode 100644 (file)
index 0000000..da4e9ef
--- /dev/null
@@ -0,0 +1,48 @@
+//%LICENSE////////////////////////////////////////////////////////////////
+//
+// Licensed to The Open Group (TOG) under one or more contributor license
+// agreements.  Refer to the OpenPegasusNOTICE.txt file distributed with
+// this work for additional information regarding copyright ownership.
+// Each contributor licenses this file to you under the OpenPegasus Open
+// Source License; you may not use this file except in compliance with the
+// License.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//////////////////////////////////////////////////////////////////////////
+//
+//%/////////////////////////////////////////////////////////////////////////////
+
+#include <Pegasus/Common/Config.h>
+#include <Pegasus/Common/String.h>
+
+#include "TestGroupingProvider.h"
+
+PEGASUS_USING_PEGASUS;
+
+extern "C" PEGASUS_EXPORT CIMProvider* PegasusCreateProvider(
+    const String& providerName)
+{
+    if(String::equalNoCase(providerName, "TestGroupingProvider2"))
+    {
+        return(new TestGroupingProvider2());
+    }
+
+    return(0);
+}
diff --git a/src/Providers/TestProviders/TestModuleGrouping/GroupUtilLib/Makefile b/src/Providers/TestProviders/TestModuleGrouping/GroupUtilLib/Makefile
new file mode 100644 (file)
index 0000000..374b2b0
--- /dev/null
@@ -0,0 +1,50 @@
+#//%LICENSE////////////////////////////////////////////////////////////////
+#//
+#// Licensed to The Open Group (TOG) under one or more contributor license
+#// agreements.  Refer to the OpenPegasusNOTICE.txt file distributed with
+#// this work for additional information regarding copyright ownership.
+#// Each contributor licenses this file to you under the OpenPegasus Open
+#// Source License; you may not use this file except in compliance with the
+#// License.
+#//
+#// Permission is hereby granted, free of charge, to any person obtaining a
+#// copy of this software and associated documentation files (the "Software"),
+#// to deal in the Software without restriction, including without limitation
+#// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+#// and/or sell copies of the Software, and to permit persons to whom the
+#// Software is furnished to do so, subject to the following conditions:
+#//
+#// The above copyright notice and this permission notice shall be included
+#// in all copies or substantial portions of the Software.
+#//
+#// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+#// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+#// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+#// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+#// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+#// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+#// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#//
+#//////////////////////////////////////////////////////////////////////////
+ROOT = ../../../../..
+
+DIR = Providers/TestProviders/TestModuleGrouping/GroupUtilLib
+
+include $(ROOT)/mak/config.mak
+
+ifeq ($(OS),VMS)
+LOCAL_DEFINES = -DPEGASUS_ROOT="""$(PEGASUS_ROOT)"""
+else
+LOCAL_DEFINES = -DPEGASUS_ROOT=\"$(ROOT)\"
+endif
+
+VMS_HAS_CC = yes
+
+LIBRARY = groupUtilLib
+
+SOURCES = \
+       groupUtilLib.cpp
+
+include $(ROOT)/mak/library.mak
+
+tests:
diff --git a/src/Providers/TestProviders/TestModuleGrouping/GroupUtilLib/groupUtilLib.cpp b/src/Providers/TestProviders/TestModuleGrouping/GroupUtilLib/groupUtilLib.cpp
new file mode 100644 (file)
index 0000000..a4556ab
--- /dev/null
@@ -0,0 +1,45 @@
+//%LICENSE////////////////////////////////////////////////////////////////
+//
+// Licensed to The Open Group (TOG) under one or more contributor license
+// agreements.  Refer to the OpenPegasusNOTICE.txt file distributed with
+// this work for additional information regarding copyright ownership.
+// Each contributor licenses this file to you under the OpenPegasus Open
+// Source License; you may not use this file except in compliance with the
+// License.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//////////////////////////////////////////////////////////////////////////
+//
+//%/////////////////////////////////////////////////////////////////////////////
+
+#include "groupUtilLib.h"
+
+static int nextIdentifier = 0;
+
+int getNextIdentifier()
+{
+    return ++nextIdentifier;
+}
+
+int resetIdentifier()
+{
+    return nextIdentifier = 0;
+}
+
diff --git a/src/Providers/TestProviders/TestModuleGrouping/GroupUtilLib/groupUtilLib.h b/src/Providers/TestProviders/TestModuleGrouping/GroupUtilLib/groupUtilLib.h
new file mode 100644 (file)
index 0000000..b7c68cf
--- /dev/null
@@ -0,0 +1,39 @@
+//%LICENSE////////////////////////////////////////////////////////////////
+//
+// Licensed to The Open Group (TOG) under one or more contributor license
+// agreements.  Refer to the OpenPegasusNOTICE.txt file distributed with
+// this work for additional information regarding copyright ownership.
+// Each contributor licenses this file to you under the OpenPegasus Open
+// Source License; you may not use this file except in compliance with the
+// License.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//////////////////////////////////////////////////////////////////////////
+
+#ifndef Pegasus_GroupUtilLib_h
+#define Pegasus_GroupUtilLib_h
+
+#include <Pegasus/Common/Config.h>
+
+extern "C" PEGASUS_EXPORT int getNextIdentifier();
+extern "C" PEGASUS_EXPORT int resetIdentifier();
+
+#endif
+
diff --git a/src/Providers/TestProviders/TestModuleGrouping/Makefile b/src/Providers/TestProviders/TestModuleGrouping/Makefile
new file mode 100644 (file)
index 0000000..385f825
--- /dev/null
@@ -0,0 +1,40 @@
+#//%LICENSE////////////////////////////////////////////////////////////////
+#//
+#// Licensed to The Open Group (TOG) under one or more contributor license
+#// agreements.  Refer to the OpenPegasusNOTICE.txt file distributed with
+#// this work for additional information regarding copyright ownership.
+#// Each contributor licenses this file to you under the OpenPegasus Open
+#// Source License; you may not use this file except in compliance with the
+#// License.
+#//
+#// Permission is hereby granted, free of charge, to any person obtaining a
+#// copy of this software and associated documentation files (the "Software"),
+#// to deal in the Software without restriction, including without limitation
+#// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+#// and/or sell copies of the Software, and to permit persons to whom the
+#// Software is furnished to do so, subject to the following conditions:
+#//
+#// The above copyright notice and this permission notice shall be included
+#// in all copies or substantial portions of the Software.
+#//
+#// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+#// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+#// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+#// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+#// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+#// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+#// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#//
+#//////////////////////////////////////////////////////////////////////////
+
+ROOT = ../../../..
+
+include $(ROOT)/mak/config.mak
+
+TEST_DIRS = \
+           GroupUtilLib \
+           GroupProvider1 \
+           GroupProvider2 \
+           testclient
+
+include $(ROOT)/mak/recurse.mak
diff --git a/src/Providers/TestProviders/TestModuleGrouping/testclient/Makefile b/src/Providers/TestProviders/TestModuleGrouping/testclient/Makefile
new file mode 100644 (file)
index 0000000..0964322
--- /dev/null
@@ -0,0 +1,83 @@
+#//%LICENSE////////////////////////////////////////////////////////////////
+#//
+#// Licensed to The Open Group (TOG) under one or more contributor license
+#// agreements.  Refer to the OpenPegasusNOTICE.txt file distributed with
+#// this work for additional information regarding copyright ownership.
+#// Each contributor licenses this file to you under the OpenPegasus Open
+#// Source License; you may not use this file except in compliance with the
+#// License.
+#//
+#// Permission is hereby granted, free of charge, to any person obtaining a
+#// copy of this software and associated documentation files (the "Software"),
+#// to deal in the Software without restriction, including without limitation
+#// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+#// and/or sell copies of the Software, and to permit persons to whom the
+#// Software is furnished to do so, subject to the following conditions:
+#//
+#// The above copyright notice and this permission notice shall be included
+#// in all copies or substantial portions of the Software.
+#//
+#// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+#// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+#// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+#// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+#// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+#// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+#// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#//
+#//////////////////////////////////////////////////////////////////////////
+ROOT = ../../../../..
+
+PEGASUS_ZOS_PROGRAM_OBJECT = yes
+
+DIR = Providers/TestProviders/TestModuleGrouping/testclient
+
+include $(ROOT)/mak/config.mak
+
+LOCAL_DEFINES = -DPEGASUS_INTERNALONLY
+
+LIBRARIES = \
+    pegclient \
+    pegcommon
+
+EXTRA_INCLUDES = $(SYS_INCLUDES)
+
+PROGRAM = TestGroupMethodProvider
+
+SOURCES = TestGroupMethodProvider.cpp
+
+include $(ROOT)/mak/program.mak
+
+tests:
+
+poststarttests:
+       @$(ECHO) "Registering the providers ...."
+       @$(PROGRAM) registerProviders
+       @$(ECHO) "Testing the module grouping...."
+       @$(PROGRAM) testGrouping
+       @$(ECHO) "Deregistering the providers ...."
+       @$(PROGRAM) deregisterProviders
+       @$(ECHO) "Registering the providers ...."
+       @$(PROGRAM) registerProviders
+       @$(ECHO) "Testing the module grouping...."
+       @$(PROGRAM) testGrouping
+       @$(ECHO) "Disabling the provider  module TestGroupingProviderModule2 ...."
+       @cimprovider -d -m TestGroupingProviderModule2
+       @$(ECHO) "Testing the module grouping with TestGroupingProviderModule2 disabled...."
+       @$(PROGRAM) testGroupingWithProviderDisabled
+       @$(ECHO) "Enabling the provider  module TestGroupingProviderModule2 ...."
+       @cimprovider -e -m TestGroupingProviderModule2
+       @$(ECHO) "Testing the module grouping...."
+       @$(PROGRAM) testGrouping
+       @$(ECHO) "Setting the TestGroupingProviderModule2 group to none..."
+       @cimprovider -g "" -m TestGroupingProviderModule2
+       @$(ECHO) "Testing the module grouping with TestGroupingProviderModule2 removed from grouping...."
+       @$(PROGRAM) testGroupingWithProviderDisabled
+       @$(ECHO) "Setting the TestGroupingProviderModule2 group to TestGroup1..."
+       @cimprovider -g TestGroup1 -m TestGroupingProviderModule2
+       @$(ECHO) "Testing the module grouping...."
+       @$(PROGRAM) testGrouping
+       @$(ECHO) "Deregistering the providers ...."
+       @$(PROGRAM) deregisterProviders
+       @$(ECHO) "Testing the indication providers with grouping enabled...."
+       @$(PROGRAM) testIndications
diff --git a/src/Providers/TestProviders/TestModuleGrouping/testclient/TestGroupMethodProvider.cpp b/src/Providers/TestProviders/TestModuleGrouping/testclient/TestGroupMethodProvider.cpp
new file mode 100644 (file)
index 0000000..72f0b83
--- /dev/null
@@ -0,0 +1,797 @@
+//%LICENSE////////////////////////////////////////////////////////////////
+//
+// Licensed to The Open Group (TOG) under one or more contributor license
+// agreements.  Refer to the OpenPegasusNOTICE.txt file distributed with
+// this work for additional information regarding copyright ownership.
+// Each contributor licenses this file to you under the OpenPegasus Open
+// Source License; you may not use this file except in compliance with the
+// License.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//////////////////////////////////////////////////////////////////////////
+//
+//%/////////////////////////////////////////////////////////////////////////////
+
+#include <Pegasus/Common/PegasusAssert.h>
+#include <Pegasus/Common/Config.h>
+#include <Pegasus/Client/CIMClient.h>
+#include <Pegasus/Common/Config.h>
+#include <Pegasus/Common/Constants.h>
+#include <Pegasus/Common/FileSystem.h>
+#include <Pegasus/Common/PegasusAssert.h>
+#include <Pegasus/Common/System.h>
+#include <Pegasus/Server/ProviderRegistrationManager/\
+ProviderRegistrationManager.h>
+
+PEGASUS_USING_PEGASUS;
+
+PEGASUS_USING_PEGASUS;
+PEGASUS_USING_STD;
+
+static const CIMNamespaceName NAMESPACE = CIMNamespaceName("test/TestProvider");
+
+static Boolean verbose;
+
+Boolean _validateStatus(
+    CIMClient& client,
+    const String& providerModuleName,
+    Uint16 expectedStatus)
+{
+    Boolean result = false;
+
+    try
+    {
+        //
+        //  Get instance for module
+        //
+        CIMInstance moduleInstance;
+        CIMKeyBinding keyBinding(CIMName("Name"), providerModuleName,
+            CIMKeyBinding::STRING);
+        Array<CIMKeyBinding> kbArray;
+        kbArray.append(keyBinding);
+        CIMObjectPath modulePath("", PEGASUS_NAMESPACENAME_INTEROP,
+            PEGASUS_CLASSNAME_PROVIDERMODULE, kbArray);
+
+        moduleInstance = client.getInstance(PEGASUS_NAMESPACENAME_INTEROP,
+            modulePath);
+
+        //
+        //  Get status from instance
+        //
+        Array<Uint16> operationalStatus;
+        Uint32 index = moduleInstance.findProperty(
+            CIMName("OperationalStatus"));
+        if (index != PEG_NOT_FOUND)
+        {
+            CIMValue statusValue =
+                moduleInstance.getProperty(index).getValue();
+            if (!statusValue.isNull())
+            {
+                statusValue.get(operationalStatus);
+                for (Uint32 i = 0; i < operationalStatus.size(); i++)
+                {
+                    if (operationalStatus [i] == expectedStatus)
+                    {
+                        result = true;
+                        break;
+                    }
+                }
+            }
+        }
+    }
+    catch (...)
+    {
+    }
+
+    return result;
+}
+
+void _checkStatus(
+    CIMClient& client,
+    const String& providerModuleName,
+    Uint16 expectedStatus)
+{
+    Uint32 iteration = 0;
+    Boolean expectedStatusObserved = false;
+    while (iteration < 300)
+    {
+        iteration++;
+        if (_validateStatus(client, providerModuleName, expectedStatus))
+        {
+            expectedStatusObserved = true;
+            break;
+        }
+        else
+        {
+            System::sleep(1);
+        }
+    }
+
+    PEGASUS_TEST_ASSERT(expectedStatusObserved);
+}
+
+void _createModuleInstance(
+    CIMClient& client,
+    const String& name,
+    const String& location,
+    const String& groupName,
+    Uint16 userContext)
+{
+    CIMInstance moduleInstance(PEGASUS_CLASSNAME_PROVIDERMODULE);
+    moduleInstance.addProperty(CIMProperty(CIMName("Name"), name));
+    moduleInstance.addProperty(CIMProperty(CIMName("Vendor"),
+        String("OpenPegasus")));
+    moduleInstance.addProperty(CIMProperty(CIMName("Version"),
+        String("2.0")));
+    moduleInstance.addProperty(CIMProperty(CIMName("InterfaceType"),
+        String("C++Default")));
+    moduleInstance.addProperty(CIMProperty(CIMName("InterfaceVersion"),
+        String("2.5.0")));
+    moduleInstance.addProperty(CIMProperty(CIMName("Location"), location));
+
+    if (groupName.size())
+    {
+        moduleInstance.addProperty(
+            CIMProperty(CIMName("ModuleGroupName"), groupName));
+    }
+
+#ifndef PEGASUS_DISABLE_PROV_USERCTXT
+    if (userContext != 0)
+    {
+        moduleInstance.addProperty(CIMProperty(CIMName("UserContext"),
+            userContext));
+    }
+#endif
+
+    CIMObjectPath path = client.createInstance(PEGASUS_NAMESPACENAME_INTEROP,
+        moduleInstance);
+}
+
+void _createProviderInstance(
+    CIMClient& client,
+    const String& name,
+    const String& providerModuleName)
+{
+    CIMInstance providerInstance(PEGASUS_CLASSNAME_PROVIDER);
+    providerInstance.addProperty(CIMProperty(CIMName("Name"), name));
+    providerInstance.addProperty(CIMProperty(CIMName("ProviderModuleName"),
+        providerModuleName));
+
+    CIMObjectPath path = client.createInstance(PEGASUS_NAMESPACENAME_INTEROP,
+        providerInstance);
+}
+
+void _createCapabilityInstance(
+    CIMClient& client,
+    const String& providerModuleName,
+    const String& providerName,
+    const String& capabilityID,
+    const String& className,
+    const Array<String>& namespaces,
+    const Array<Uint16>& providerType,
+    const CIMPropertyList& supportedProperties,
+    const CIMPropertyList& supportedMethods)
+{
+    CIMInstance capabilityInstance(PEGASUS_CLASSNAME_PROVIDERCAPABILITIES);
+    capabilityInstance.addProperty(CIMProperty(CIMName("ProviderModuleName"),
+        providerModuleName));
+    capabilityInstance.addProperty(CIMProperty(CIMName("ProviderName"),
+        providerName));
+    capabilityInstance.addProperty(CIMProperty(CIMName("CapabilityID"),
+        capabilityID));
+    capabilityInstance.addProperty(CIMProperty(CIMName("ClassName"),
+        className));
+    capabilityInstance.addProperty(CIMProperty(CIMName("Namespaces"),
+        namespaces));
+    capabilityInstance.addProperty(CIMProperty(CIMName("ProviderType"),
+        CIMValue(providerType)));
+    if (!supportedProperties.isNull())
+    {
+        Array<String> propertyNameStrings;
+        for (Uint32 i = 0; i < supportedProperties.size(); i++)
+        {
+            propertyNameStrings.append(supportedProperties [i].getString());
+        }
+        capabilityInstance.addProperty(CIMProperty(
+            CIMName("supportedProperties"), CIMValue(propertyNameStrings)));
+    }
+    if (!supportedMethods.isNull())
+    {
+        Array<String> methodNameStrings;
+        for (Uint32 i = 0; i < supportedMethods.size(); i++)
+        {
+            methodNameStrings.append(supportedMethods [i].getString());
+        }
+        capabilityInstance.addProperty(CIMProperty(
+            CIMName("supportedMethods"), CIMValue(methodNameStrings)));
+    }
+
+    CIMObjectPath path = client.createInstance(PEGASUS_NAMESPACENAME_INTEROP,
+        capabilityInstance);
+}
+
+void _deleteCapabilityInstance(
+    CIMClient& client,
+    const String& providerModuleName,
+    const String& providerName,
+    const String& capabilityID)
+{
+    Array<CIMKeyBinding> keyBindings;
+    keyBindings.append(CIMKeyBinding("ProviderModuleName",
+        providerModuleName, CIMKeyBinding::STRING));
+    keyBindings.append(CIMKeyBinding("ProviderName",
+        providerName, CIMKeyBinding::STRING));
+    keyBindings.append(CIMKeyBinding("CapabilityID",
+        capabilityID, CIMKeyBinding::STRING));
+    CIMObjectPath path("", CIMNamespaceName(),
+        CIMName("PG_ProviderCapabilities"), keyBindings);
+    client.deleteInstance(PEGASUS_NAMESPACENAME_INTEROP, path);
+}
+
+void _deleteProviderInstance(
+    CIMClient& client,
+    const String& name,
+    const String& providerModuleName)
+{
+    Array<CIMKeyBinding> keyBindings;
+    keyBindings.append(CIMKeyBinding("Name",
+        name, CIMKeyBinding::STRING));
+    keyBindings.append(CIMKeyBinding("ProviderModuleName",
+        providerModuleName, CIMKeyBinding::STRING));
+    CIMObjectPath path("", CIMNamespaceName(),
+        CIMName("PG_Provider"), keyBindings);
+    client.deleteInstance(PEGASUS_NAMESPACENAME_INTEROP, path);
+}
+
+void _deleteModuleInstance(
+    CIMClient& client,
+    const String& name)
+{
+    Array<CIMKeyBinding> keyBindings;
+    keyBindings.append(CIMKeyBinding("Name",
+        name, CIMKeyBinding::STRING));
+    CIMObjectPath path("", CIMNamespaceName(),
+        CIMName("PG_ProviderModule"), keyBindings);
+    client.deleteInstance(PEGASUS_NAMESPACENAME_INTEROP, path);
+}
+
+void _createFilterInstance(
+    CIMClient& client,
+    const String& name,
+    const String& query,
+    const String& qlang)
+{
+    CIMInstance filterInstance(PEGASUS_CLASSNAME_INDFILTER);
+    filterInstance.addProperty(CIMProperty(CIMName
+       ("SystemCreationClassName"), System::getSystemCreationClassName()));
+    filterInstance.addProperty(CIMProperty(CIMName("SystemName"),
+        System::getFullyQualifiedHostName()));
+    filterInstance.addProperty(CIMProperty(CIMName("CreationClassName"),
+        PEGASUS_CLASSNAME_INDFILTER.getString()));
+    filterInstance.addProperty(CIMProperty(CIMName("Name"), name));
+    filterInstance.addProperty(CIMProperty(CIMName("Query"), query));
+    filterInstance.addProperty(CIMProperty(CIMName("QueryLanguage"),
+        String(qlang)));
+    filterInstance.addProperty(CIMProperty(CIMName("SourceNamespace"),
+        NAMESPACE.getString()));
+
+    CIMObjectPath path = client.createInstance(PEGASUS_NAMESPACENAME_INTEROP,
+        filterInstance);
+}
+
+void _createHandlerInstance(
+    CIMClient& client,
+    const String& name,
+    const String& destination)
+{
+    CIMInstance handlerInstance(PEGASUS_CLASSNAME_LSTNRDST_CIMXML);
+    handlerInstance.addProperty(CIMProperty(CIMName
+       ("SystemCreationClassName"), System::getSystemCreationClassName()));
+    handlerInstance.addProperty(CIMProperty(CIMName("SystemName"),
+        System::getFullyQualifiedHostName()));
+    handlerInstance.addProperty(CIMProperty(CIMName("CreationClassName"),
+        PEGASUS_CLASSNAME_LSTNRDST_CIMXML.getString()));
+    handlerInstance.addProperty(CIMProperty(CIMName("Name"), name));
+    handlerInstance.addProperty(CIMProperty(CIMName("Destination"),
+        destination));
+
+    CIMObjectPath path = client.createInstance(PEGASUS_NAMESPACENAME_INTEROP,
+        handlerInstance);
+}
+
+CIMObjectPath _buildFilterOrHandlerPath(
+    const CIMName& className,
+    const String& name,
+    const String& host,
+    const CIMNamespaceName& namespaceName = CIMNamespaceName())
+{
+    CIMObjectPath path;
+
+    Array<CIMKeyBinding> keyBindings;
+    keyBindings.append(CIMKeyBinding("SystemCreationClassName",
+        System::getSystemCreationClassName(), CIMKeyBinding::STRING));
+    keyBindings.append(CIMKeyBinding("SystemName",
+        System::getFullyQualifiedHostName(), CIMKeyBinding::STRING));
+    keyBindings.append(CIMKeyBinding("CreationClassName",
+        className.getString(), CIMKeyBinding::STRING));
+    keyBindings.append(CIMKeyBinding("Name", name, CIMKeyBinding::STRING));
+    path.setClassName(className);
+    path.setKeyBindings(keyBindings);
+    path.setNameSpace(namespaceName);
+    path.setHost(host);
+
+    return path;
+}
+
+void _createSubscriptionInstance(
+    CIMClient& client,
+    const CIMObjectPath& filterPath,
+    const CIMObjectPath& handlerPath,
+    Uint16 onFatalErrorPolicy)
+{
+    CIMInstance subscriptionInstance(PEGASUS_CLASSNAME_INDSUBSCRIPTION);
+    subscriptionInstance.addProperty(CIMProperty(CIMName("Filter"),
+        filterPath, 0, PEGASUS_CLASSNAME_INDFILTER));
+    subscriptionInstance.addProperty(CIMProperty(CIMName("Handler"),
+        handlerPath, 0, PEGASUS_CLASSNAME_LSTNRDST_CIMXML));
+    subscriptionInstance.addProperty(CIMProperty(
+        CIMName("SubscriptionState"), CIMValue((Uint16) 2)));
+    subscriptionInstance.addProperty(
+        CIMProperty(
+            CIMName("OnFatalErrorPolicy"),
+            CIMValue((Uint16) onFatalErrorPolicy)));
+    CIMObjectPath path = client.createInstance(PEGASUS_NAMESPACENAME_INTEROP,
+        subscriptionInstance);
+}
+
+void _createSubscription(
+    CIMClient& client,
+    const String& filterName,
+    Uint16 onFatalErrorPolicy = 2)
+{
+    CIMObjectPath filterPath;
+    CIMObjectPath handlerPath;
+    filterPath = _buildFilterOrHandlerPath(
+        PEGASUS_CLASSNAME_INDFILTER, filterName, String::EMPTY,
+        CIMNamespaceName());
+    handlerPath = _buildFilterOrHandlerPath(
+        PEGASUS_CLASSNAME_LSTNRDST_CIMXML, "OOPHandler01", String::EMPTY,
+        CIMNamespaceName());
+    _createSubscriptionInstance(
+        client,
+        filterPath,
+        handlerPath,
+        onFatalErrorPolicy);
+}
+
+CIMObjectPath _getSubscriptionPath(
+    const String& filterName,
+    const String& handlerName)
+{
+    Array<CIMKeyBinding> filterKeyBindings;
+    filterKeyBindings.append(CIMKeyBinding("SystemCreationClassName",
+        System::getSystemCreationClassName(), CIMKeyBinding::STRING));
+    filterKeyBindings.append(CIMKeyBinding("SystemName",
+        System::getFullyQualifiedHostName(), CIMKeyBinding::STRING));
+    filterKeyBindings.append(CIMKeyBinding("CreationClassName",
+        PEGASUS_CLASSNAME_INDFILTER.getString(), CIMKeyBinding::STRING));
+    filterKeyBindings.append(CIMKeyBinding("Name", filterName,
+        CIMKeyBinding::STRING));
+    CIMObjectPath filterPath("", CIMNamespaceName(),
+        PEGASUS_CLASSNAME_INDFILTER, filterKeyBindings);
+
+    Array<CIMKeyBinding> handlerKeyBindings;
+    handlerKeyBindings.append(CIMKeyBinding("SystemCreationClassName",
+        System::getSystemCreationClassName(), CIMKeyBinding::STRING));
+    handlerKeyBindings.append(CIMKeyBinding("SystemName",
+        System::getFullyQualifiedHostName(), CIMKeyBinding::STRING));
+    handlerKeyBindings.append(CIMKeyBinding("CreationClassName",
+        PEGASUS_CLASSNAME_LSTNRDST_CIMXML.getString(),
+        CIMKeyBinding::STRING));
+    handlerKeyBindings.append(CIMKeyBinding("Name", handlerName,
+        CIMKeyBinding::STRING));
+    CIMObjectPath handlerPath("", CIMNamespaceName(),
+        PEGASUS_CLASSNAME_LSTNRDST_CIMXML, handlerKeyBindings);
+
+    Array<CIMKeyBinding> subscriptionKeyBindings;
+    subscriptionKeyBindings.append(CIMKeyBinding("Filter",
+        filterPath.toString(), CIMKeyBinding::REFERENCE));
+    subscriptionKeyBindings.append(CIMKeyBinding("Handler",
+        handlerPath.toString(), CIMKeyBinding::REFERENCE));
+
+    return CIMObjectPath(
+               "",
+               CIMNamespaceName(),
+               PEGASUS_CLASSNAME_INDSUBSCRIPTION,
+               subscriptionKeyBindings);
+}
+
+void _deleteSubscriptionInstance(
+    CIMClient& client,
+    const String& filterName,
+    const String& handlerName)
+{
+    client.deleteInstance(
+        PEGASUS_NAMESPACENAME_INTEROP,
+        _getSubscriptionPath(filterName, handlerName));
+}
+
+void _deleteHandlerInstance(
+    CIMClient& client,
+    const String& name)
+{
+    Array<CIMKeyBinding> keyBindings;
+    keyBindings.append(CIMKeyBinding("SystemCreationClassName",
+        System::getSystemCreationClassName(), CIMKeyBinding::STRING));
+    keyBindings.append(CIMKeyBinding("SystemName",
+        System::getFullyQualifiedHostName(), CIMKeyBinding::STRING));
+    keyBindings.append(CIMKeyBinding("CreationClassName",
+        PEGASUS_CLASSNAME_LSTNRDST_CIMXML.getString(),
+        CIMKeyBinding::STRING));
+    keyBindings.append(CIMKeyBinding("Name", name,
+        CIMKeyBinding::STRING));
+    CIMObjectPath path("", CIMNamespaceName(),
+        PEGASUS_CLASSNAME_LSTNRDST_CIMXML, keyBindings);
+    client.deleteInstance(PEGASUS_NAMESPACENAME_INTEROP, path);
+}
+
+void _deleteFilterInstance(
+    CIMClient& client,
+    const String& name)
+{
+    Array<CIMKeyBinding> keyBindings;
+    keyBindings.append(CIMKeyBinding("SystemCreationClassName",
+        System::getSystemCreationClassName(), CIMKeyBinding::STRING));
+    keyBindings.append(CIMKeyBinding("SystemName",
+        System::getFullyQualifiedHostName(), CIMKeyBinding::STRING));
+    keyBindings.append(CIMKeyBinding("CreationClassName",
+        PEGASUS_CLASSNAME_INDFILTER.getString(), CIMKeyBinding::STRING));
+    keyBindings.append(CIMKeyBinding("Name", name,
+        CIMKeyBinding::STRING));
+    CIMObjectPath path("", CIMNamespaceName(),
+        PEGASUS_CLASSNAME_INDFILTER, keyBindings);
+    client.deleteInstance(PEGASUS_NAMESPACENAME_INTEROP, path);
+}
+
+Sint32 _getValue(
+    CIMClient &client,
+    const String &className,
+    const CIMName &methodName)
+{
+    Array<CIMParamValue> inParams;
+    Array<CIMParamValue> outParams;
+
+    CIMObjectPath instName =
+        CIMObjectPath(className);
+
+    CIMValue returnValue = client.invokeMethod(
+        NAMESPACE,
+        instName,
+        methodName,
+        inParams,
+        outParams);
+    Sint32 rc;
+    returnValue.get(rc);
+
+    return rc;
+}
+
+void _setup(CIMClient& client)
+{
+    //
+    //  Create Filters and Handler for subscriptions
+    //
+    _createFilterInstance(client, String("OOPFilter01"),
+        String("SELECT * FROM Test_GroupingClass1"), "WQL");
+
+    _createFilterInstance(client, String("OOPFilter02"),
+        String("SELECT * FROM Test_GroupingClass2"), "WQL");
+
+    _createHandlerInstance(client, String("OOPHandler01"),
+        String("localhost/CIMListener/Pegasus_SimpleDisplayConsumer"));
+}
+
+void _cleanup(CIMClient& client)
+{
+    //
+    //  Delete Filters and Handler for subscriptions
+    //
+    _deleteHandlerInstance(client, String("OOPHandler01"));
+    _deleteFilterInstance(client, String("OOPFilter01"));
+    _deleteFilterInstance(client, String("OOPFilter02"));
+}
+
+void _register(
+    CIMClient& client,
+    Uint16 userContext,
+    const String& providerModuleName,
+    const String& location,
+    const String& providerName,
+    const String& capabilityID,
+    const String& className,
+    const String& groupName,
+    const Array<String>& namespaces,
+    const Array<Uint16>& providerType,
+    const CIMPropertyList& supportedProperties,
+    const CIMPropertyList& supportedMethods)
+{
+    //
+    //  Create provider module instance
+    //
+    _createModuleInstance(
+        client,
+        providerModuleName,
+        location,
+        groupName,
+        userContext);
+
+    //
+    //  Create the provider and capability instances
+    //
+    _createProviderInstance(
+        client,
+        providerName,
+        providerModuleName);
+
+    _createCapabilityInstance(
+        client,
+        providerModuleName,
+        providerName,
+        capabilityID,
+        className,
+        namespaces,
+        providerType,
+        supportedProperties,
+        supportedMethods);
+}
+
+void _deregister(
+    CIMClient& client,
+    const String& providerModuleName,
+    const String& providerName,
+    const String& capabilityID)
+{
+    _deleteCapabilityInstance(
+        client,
+        providerModuleName,
+        providerName,
+        capabilityID);
+
+    _deleteProviderInstance(
+        client,
+        providerName,
+        providerModuleName);
+
+    _deleteModuleInstance(
+        client,
+        providerModuleName);
+}
+
+static void _registerProviders2(
+    CIMClient &client, const String &id, Uint32 userContext = 0)
+{
+    Array<String> namespaces;
+    namespaces.append("test/TestProvider");
+
+    if (verbose)
+    {
+        cout << "registering the providers..." << endl;
+    }
+
+    Array<Uint16> providerType;
+    providerType.append(_METHOD_PROVIDER);
+    providerType.append(_INDICATION_PROVIDER);
+
+    _register(
+        client, // client
+        userContext, // userContext
+        "TestGroupingProviderModule" + id, //providerModuleName
+        "TestGroupingProvider" + id, // location,
+        "TestGroupingProvider" + id, // providerName
+        "TestGroupingProviderCapability" + id, // capabilityID
+        "Test_GroupingClass" + id , // className
+        "TestGroup1", //groupName
+        namespaces,
+        providerType,
+        CIMPropertyList(),
+        CIMPropertyList());
+}
+
+static void _deregisterProviders2(CIMClient &client, const String &id)
+{
+    if (verbose)
+    {
+        cout << "deregistering the providers..." << endl;
+    }
+
+    _deregister(
+        client,
+        "TestGroupingProviderModule" + id,
+        "TestGroupingProvider" + id,
+        "TestGroupingProviderCapability" + id);
+}
+
+static void _registerProviders(CIMClient &client, Uint32 userContext = 0)
+{
+    _registerProviders2(client, "1", userContext);
+    _registerProviders2(client, "2", userContext);
+}
+
+static void _deregisterProviders(CIMClient &client)
+{
+    _deregisterProviders2(client, "1");
+    _deregisterProviders2(client, "2");
+}
+
+static void _testGrouping(CIMClient &client)
+{
+    try
+    {
+        if (verbose)
+        {
+            cout << "Testing module grouping..." <<  endl;
+        }
+
+        PEGASUS_TEST_ASSERT(
+            _getValue(client, "Test_GroupingClass1", "resetIdentifier") == 0);
+        PEGASUS_TEST_ASSERT(
+            _getValue(client, "Test_GroupingClass1", "getNextIdentifier") == 1);
+        PEGASUS_TEST_ASSERT(
+            _getValue(client, "Test_GroupingClass2", "getNextIdentifier") == 2);
+        PEGASUS_TEST_ASSERT(
+            _getValue(client, "Test_GroupingClass1", "getNextIdentifier") == 3);
+        PEGASUS_TEST_ASSERT(
+            _getValue(client, "Test_GroupingClass2", "getNextIdentifier") == 4);
+        PEGASUS_TEST_ASSERT(
+            _getValue(client, "Test_GroupingClass1", "resetIdentifier") == 0);
+        PEGASUS_TEST_ASSERT(
+            _getValue(client, "Test_GroupingClass2", "getNextIdentifier") == 1);
+
+    }
+    catch (Exception& e)
+    {
+        cerr << "Error: " << e.getMessage() << endl;
+        exit(1);
+    }
+}
+
+static void _testGroupingWithProviderDisabled(CIMClient &client)
+{
+    try
+    {
+        if (verbose)
+        {
+            cout << "Testing module grouping with provider disabled..." << endl;
+        }
+
+        PEGASUS_TEST_ASSERT(
+            _getValue(client, "Test_GroupingClass1", "getNextIdentifier") == 2);
+        PEGASUS_TEST_ASSERT(
+            _getValue(client, "Test_GroupingClass1", "getNextIdentifier") == 3);
+        PEGASUS_TEST_ASSERT(
+            _getValue(client, "Test_GroupingClass1", "resetIdentifier") == 0);
+        PEGASUS_TEST_ASSERT(
+            _getValue(client, "Test_GroupingClass1", "getNextIdentifier") == 1);
+    }
+    catch (Exception& e)
+    {
+        cerr << "Error: " << e.getMessage() << endl;
+        exit(1);
+    }
+}
+
+static void _testIndications(CIMClient &client)
+{
+    try
+    {
+        if (verbose)
+        {
+            cout << "Testing indication provider grouping failure..." << endl;
+        }
+        _setup(client);
+        _registerProviders(client, 2);
+        _createSubscription(client, String("OOPFilter01"));
+        _createSubscription(client, String("OOPFilter02"));
+        try
+        {
+            Array<CIMParamValue> outParams;
+            Array<CIMParamValue> inParams;
+            client.invokeMethod(
+                NAMESPACE,
+                CIMObjectPath("Test_GroupingClass1"),
+                "testFail",
+                inParams,
+                outParams);
+        }
+        catch(...)
+        {
+        }
+
+        _checkStatus(
+            client,
+            "TestGroupingProviderModule1",
+            CIM_MSE_OPSTATUS_VALUE_DEGRADED);
+
+        _checkStatus(
+            client,
+            "TestGroupingProviderModule2",
+            CIM_MSE_OPSTATUS_VALUE_DEGRADED);
+
+        _deleteSubscriptionInstance(client, String("OOPFilter01"),
+            String("OOPHandler01"));
+        _deleteSubscriptionInstance(client, String("OOPFilter02"),
+            String("OOPHandler01"));
+        _cleanup(client);
+        _deregisterProviders(client);
+    }
+    catch (Exception& e)
+    {
+        cerr << "Error: " << e.getMessage() << endl;
+        exit(1);
+    }
+}
+
+int main(int argc, char** argv)
+{
+    verbose = getenv("PEGASUS_TEST_VERBOSE") ? true : false;
+
+    try
+    {
+        CIMClient client;
+        client.connectLocal();
+
+        if (!strcmp(argv[1], "testGrouping"))
+        {
+            _testGrouping(client);
+        }
+        if (!strcmp(argv[1], "testGroupingWithProviderDisabled"))
+        {
+            _testGroupingWithProviderDisabled(client);
+        }
+        else if (!strcmp(argv[1], "registerProviders"))
+        {
+            _registerProviders(client);
+        }
+        else if (!strcmp(argv[1], "deregisterProviders"))
+        {
+            _deregisterProviders(client);
+        }
+        else if (!strcmp(argv[1], "testIndications"))
+        {
+#ifndef PEGASUS_DISABLE_PROV_USERCTXT
+            _testIndications(client);
+#else
+            cout << argv [0] <<
+                ": Grouping indication providers tests skipped because"
+                " PEGASUS_DISABLE_PROV_USERCTXT is defined" << endl;
+#endif
+
+        }
+    }
+    catch (Exception& e)
+    {
+        cerr << "Error: " << e.getMessage() << endl;
+        exit(1);
+    }
+
+    cout << argv[0] << " +++++ passed all tests" << endl;
+
+    return 0;
+}