(file) Return to SubscriptionTable.cpp CVS log (file) (dir) Up to [Pegasus] / pegasus / src / Pegasus / IndicationService

File: [Pegasus] / pegasus / src / Pegasus / IndicationService / SubscriptionTable.cpp (download)
Revision: 1.30, Thu Feb 2 05:46:18 2012 UTC (12 years, 5 months ago) by venkat.puvvada
Branch: MAIN
Changes since 1.29: +157 -85 lines
BUG#: 9118
TITLE: Add support for CIM_IndicationFilter.SourceNamespaces[] property
DESCRIPTION: Added support for the SourceNamespaces[] property. The values in the SourceNamespaces property and the SourceNamespace property are not additive. If both sourceNamespace and SourceNamespaces are non NULL, the namespace defined in sourceNamespace must also exist in sourceNamespaces.

//%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/Constants.h>
#include <Pegasus/Common/Tracer.h>

#include "IndicationConstants.h"
#include "IndicationService.h"
#include "SubscriptionTable.h"

#ifdef PEGASUS_ENABLE_INDICATION_COUNT
# include "ProviderIndicationCountTable.h"
#endif

PEGASUS_USING_STD;

PEGASUS_NAMESPACE_BEGIN

SubscriptionTable::SubscriptionTable (
    SubscriptionRepository * subscriptionRepository)
    : _subscriptionRepository (subscriptionRepository)
{
}

SubscriptionTable::~SubscriptionTable ()
{
}

Boolean SubscriptionTable::getSubscriptionEntry (
    const CIMObjectPath & subscriptionPath,
    ActiveSubscriptionsTableEntry & tableValue) const
{
    PEG_METHOD_ENTER (TRC_INDICATION_SERVICE,
        "SubscriptionTable::getSubscriptionEntry");

    Boolean succeeded = false;
    String activeSubscriptionsKey = _generateActiveSubscriptionsKey
        (subscriptionPath);
    if (_lockedLookupActiveSubscriptionsEntry
        (activeSubscriptionsKey, tableValue))
    {
        succeeded = true;
    }
    else
    {
        //
        //  Subscription not found in Active Subscriptions table
        //
        PEG_TRACE((TRC_INDICATION_SERVICE, Tracer::LEVEL1,
            "Subscription (%s) not found in ActiveSubscriptionsTable",
            (const char*)activeSubscriptionsKey.getCString()));
    }

    PEG_METHOD_EXIT ();
    return succeeded;
}

Array <SubscriptionWithSrcNamespace>
    SubscriptionTable::getMatchingSubscriptions(
        const CIMName & supportedClass,
        const Array <CIMNamespaceName> nameSpaces,
        const Boolean checkProvider,
        const CIMInstance & provider) const
{
    PEG_METHOD_ENTER (TRC_INDICATION_SERVICE,
        "SubscriptionTable::getMatchingSubscriptions");

    Array <SubscriptionWithSrcNamespace> matchingSubscriptions;
    Array <CIMInstance> subscriptions;

    for (Uint32 i = 0; i < nameSpaces.size (); i++)
    {
        //
        //  Look up the indicationClass-sourceNamespace pair in the
        //  Subscription Classes table
        //
        String subscriptionClassesKey = _generateSubscriptionClassesKey
            (supportedClass, nameSpaces [i]);
        SubscriptionClassesTableEntry scTableValue;
        if (_lockedLookupSubscriptionClassesEntry(
                subscriptionClassesKey, scTableValue))
        {
            subscriptions = scTableValue.subscriptions;
            for (Uint32 j = 0; j < subscriptions.size (); j++)
            {
                Boolean match = true;

                if (checkProvider)
                {
                    //
                    //  Check if the provider who generated this indication
                    //  accepted this subscription
                    //
                    String activeSubscriptionsKey =
                        _generateActiveSubscriptionsKey
                            (subscriptions [j].getPath ());
                    ActiveSubscriptionsTableEntry asTableValue;
                    if (_lockedLookupActiveSubscriptionsEntry(
                            activeSubscriptionsKey, asTableValue))
                    {
                        //
                        //  If provider is not in list, it did not accept the
                        //  subscription
                        //
                        if ((providerInList(provider, asTableValue)) ==
                                PEG_NOT_FOUND)
                        {
                            match = false;
                            break;
                        }
                    }
                }

                if (match)
                {
                    //
                    //  Add current subscription to list
                    //
                    SubscriptionWithSrcNamespace subscriptionWithSrcNamespace;
                    subscriptionWithSrcNamespace.nameSpace = nameSpaces[i];
                    subscriptionWithSrcNamespace.subscription =
                        subscriptions[j];
                    matchingSubscriptions.append (subscriptionWithSrcNamespace);
                }
            }
        }
    }

    PEG_METHOD_EXIT ();
    return matchingSubscriptions;
}

Array <CIMInstance> SubscriptionTable::reflectProviderDisable (
    const CIMInstance & provider)
{
    PEG_METHOD_ENTER (TRC_INDICATION_SERVICE,
        "SubscriptionTable::reflectProviderDisable");

    Array <CIMInstance> providerSubscriptions;

    //
    //  Iterate through the subscription table to find subscriptions served by
    //  the provider
    //  NOTE: updating entries (remove and insert) while iterating through the
    //  table does not work reliably, and it is not clear if that is supposed to
    //  work; for now, the SubscriptionTable first iterates through the
    //  active subscriptions table to find subscriptions served by the
    //  provider, then looks up and updates each affected subscription
    //
    {
        //
        //  Acquire and hold the write lock during the entire
        //  lookup/remove/insert process, allowing competing threads to apply
        //  their logic over a consistent view of the data.
        //  Do not call any other methods that need
        //  _activeSubscriptionsTableLock.
        //
        WriteLock lock (_activeSubscriptionsTableLock);

        for (ActiveSubscriptionsTable::Iterator i =
            _activeSubscriptionsTable.start (); i; i++)
        {
            //
            //  If provider matches, append subscription to the list
            //
            ActiveSubscriptionsTableEntry asTableValue = i.value();
            for (Uint32 j = 0; j < asTableValue.providers.size(); j++)
            {
                if (asTableValue.providers[j].provider.getPath().identical(
                        provider.getPath()))
                {
                    //
                    //  Add the subscription to the list
                    //
                    providerSubscriptions.append(asTableValue.subscription);
                    break;
                }
            }
        }

        //
        //  Look up and update hash table entry for each affected subscription
        //
        for (Uint32 k = 0; k < providerSubscriptions.size (); k++)
        {
            //
            //  Update the entry in the active subscriptions hash table
            //
            String activeSubscriptionsKey =
                _generateActiveSubscriptionsKey
                    (providerSubscriptions [k].getPath ());
            ActiveSubscriptionsTableEntry asTableValue;
            if (_activeSubscriptionsTable.lookup(
                    activeSubscriptionsKey, asTableValue))
            {
                //
                //  Remove the provider from the list of providers serving the
                //  subscription
                //
                Uint32 providerIndex = providerInList(provider, asTableValue);
                if (providerIndex != PEG_NOT_FOUND)
                {
                    asTableValue.providers.remove(providerIndex);

                    _updateSubscriptionProviders(
                        activeSubscriptionsKey,
                        asTableValue.subscription,
                        asTableValue.providers);
                }
                else
                {
                    PEG_TRACE((TRC_INDICATION_SERVICE,Tracer::LEVEL2,
                        "Provider (%s) not found in list for Subscription (%s)"
                        " in ActiveSubscriptionsTable",
                        (const char*)provider.getPath().toString().getCString(),
                        (const char*)activeSubscriptionsKey.getCString()));
                }
            }
            else
            {
                PEG_TRACE((TRC_INDICATION_SERVICE,Tracer::LEVEL2,
                    "Subscription (%s) not found in ActiveSubscriptionsTable",
                    (const char*)activeSubscriptionsKey.getCString()));
                //
                //  The subscription may have been deleted in the mean time
                //  If so, no further update is required
                //
            }
        }
    }

    PEG_METHOD_EXIT ();
    return providerSubscriptions;
}

Array <ActiveSubscriptionsTableEntry>
SubscriptionTable::reflectProviderModuleFailure
    (const String & moduleName,
     const String & userName,
     Boolean authenticationEnabled)
{
    PEG_METHOD_ENTER (TRC_INDICATION_SERVICE,
        "SubscriptionTable::reflectProviderModuleFailure");

    Array <ActiveSubscriptionsTableEntry> providerModuleSubscriptions;

    //
    //  Iterate through the subscription table to find subscriptions served by
    //  a provider in the specified module, with the specified userName as the
    //  subscription creator
    //  NOTE: updating entries (remove and insert) while iterating through the
    //  table is not allowed
    //  The SubscriptionTable first iterates through the active subscriptions
    //  table to find matching subscriptions served by a provider in the
    //  specified module, then looks up and updates each affected subscription
    //
    {
        //
        //  Acquire and hold the write lock during the entire
        //  lookup/remove/insert process, allowing competing threads to apply
        //  their logic over a consistent view of the data.
        //  Do not call any other methods that need
        //  _activeSubscriptionsTableLock.
        //
        WriteLock lock (_activeSubscriptionsTableLock);

        for (ActiveSubscriptionsTable::Iterator i =
            _activeSubscriptionsTable.start (); i; i++)
        {
            ActiveSubscriptionsTableEntry asTableValue;
            //
            //  Get subscription creator
            //
            asTableValue = i.value();
            String creator;
            CIMValue creatorValue = asTableValue.subscription.getProperty(
                asTableValue.subscription.findProperty(
                    PEGASUS_PROPERTYNAME_INDSUB_CREATOR)).getValue();
            creatorValue.get (creator);

            Array <ProviderClassList> failedProviderList;
            for (Uint32 j = 0; j < asTableValue.providers.size(); j++)
            {
                //
                //  Get provider module name
                //
                String providerModuleName;
                CIMValue nameValue =
                    asTableValue.providers[j].providerModule.getProperty(
                        asTableValue.providers[j].providerModule.findProperty(
                            PEGASUS_PROPERTYNAME_NAME)).getValue();
                nameValue.get (providerModuleName);

                //
                //  Get module user context setting
                //
                Uint16 moduleContext = PEGASUS_DEFAULT_PROV_USERCTXT;
                CIMValue contextValue =
                    asTableValue.providers[j].providerModule.getProperty(
                        asTableValue.providers [j].providerModule.findProperty(
                            PEGASUS_PROPERTYNAME_MODULE_USERCONTEXT)).
                    getValue();
                if (!contextValue.isNull ())
                {
                    contextValue.get (moduleContext);
                }

                //
                //  If provider module name matches,
                //  add provider to the list of failed providers
                //
                if (providerModuleName == moduleName)
                {
                    //
                    //  If authentication is enabled, and module was run as
                    //  requestor, subscription creator must also match module
                    //  user context name, to add provider to the list of
                    //  failed providers
                    //
                    if ((moduleContext != PG_PROVMODULE_USERCTXT_REQUESTOR) ||
                        (!authenticationEnabled) || (creator == userName))
                    {
                        //
                        //  Add the provider to the list
                        //
                        failedProviderList.append(asTableValue.providers[j]);
                    }
                }  //  if provider module name matches
            }  //  for each subscription provider

            //
            //  If there were any failed providers, add the subscription
            //  entry to the list of affected subscriptions
            //
            if (failedProviderList.size () > 0)
            {
                ActiveSubscriptionsTableEntry subscription;
                subscription.subscription = asTableValue.subscription;
                subscription.providers = failedProviderList;
                providerModuleSubscriptions.append (subscription);
            }
        }

        //
        //  Look up and update hash table entry for each affected subscription
        //
        for (Uint32 k = 0; k < providerModuleSubscriptions.size (); k++)
        {
            //
            //  Update the entry in the active subscriptions hash table
            //
            String activeSubscriptionsKey =
                _generateActiveSubscriptionsKey
                    (providerModuleSubscriptions [k].subscription.getPath ());
            ActiveSubscriptionsTableEntry asTableValue;
            if (_activeSubscriptionsTable.lookup(
                    activeSubscriptionsKey, asTableValue))
            {
                Array <ProviderClassList> updatedProviderList;
                for (Uint32 l = 0; l < asTableValue.providers.size(); l++)
                {
                    String providerModuleName;
                    CIMValue nameValue =
                        asTableValue.providers[l].providerModule.getProperty(
                            asTableValue.providers[l].providerModule.
                            findProperty(PEGASUS_PROPERTYNAME_NAME)).getValue();
                    nameValue.get (providerModuleName);
                    if (providerModuleName != moduleName)
                    {
                        //
                        //  Provider is not in the failed module
                        //  Append provider to list of providers still serving
                        //  the subscription
                        //
                        updatedProviderList.append(asTableValue.providers[l]);
                    }
                }

                _updateSubscriptionProviders(
                    activeSubscriptionsKey,
                    asTableValue.subscription,
                    updatedProviderList);
            }
        }
    }

    PEG_METHOD_EXIT ();
    return providerModuleSubscriptions;
}

String SubscriptionTable::_generateActiveSubscriptionsKey (
    const CIMObjectPath & subscription) const
{
    //
    //  Get filter and handler object paths from subscription Filter and Handler
    //  reference property values
    //
    Array<CIMKeyBinding> subscriptionKB = subscription.getKeyBindings ();
    String filterPath;
    String handlerPath;
    for (Uint32 i = 0; i < subscriptionKB.size (); i++)
    {
        if ((subscriptionKB [i].getName () == PEGASUS_PROPERTYNAME_FILTER) &&
            (subscriptionKB [i].getType () == CIMKeyBinding::REFERENCE))
        {
            filterPath = subscriptionKB [i].getValue ();
        }
        else
        if ((subscriptionKB [i].getName () == PEGASUS_PROPERTYNAME_HANDLER) &&
            (subscriptionKB [i].getType () == CIMKeyBinding::REFERENCE))
        {
            handlerPath = subscriptionKB [i].getValue ();
        }
    }

    //
    //  Construct subscription key from handler and filter.
    //  To avoid ambiguity, the hostname part is removed, since the
    //  hostname can only point to the local machine anyway.
    //
    const Char16 slash = '/';
    if ((filterPath[0]==slash) && (filterPath[1]==slash))
    {
        Uint32 index = filterPath.find(2,slash);
        filterPath = filterPath.subString(index+1);
    }

    if ((handlerPath[0]==slash) && (handlerPath[1]==slash))
    {
        Uint32 index = handlerPath.find(2,slash);
        handlerPath = handlerPath.subString(index+1);
    }

    //
    //  Assuming that most subscriptions will differ in the filter and handler
    //  names, the namespace and classname of the subscription are added at the
    //  end of the key.
    //
    String activeSubscriptionsKey(filterPath);
    activeSubscriptionsKey.append(handlerPath);
    activeSubscriptionsKey.append(slash);
    activeSubscriptionsKey.append(subscription.getNameSpace().getString());
    activeSubscriptionsKey.append(slash);
    activeSubscriptionsKey.append(subscription.getClassName().getString());

    return activeSubscriptionsKey;
}

Boolean SubscriptionTable::_lockedLookupActiveSubscriptionsEntry (
    const String & key,
    ActiveSubscriptionsTableEntry & tableEntry) const
{
    ReadLock lock(_activeSubscriptionsTableLock);

    return (_activeSubscriptionsTable.lookup (key, tableEntry));
}

void SubscriptionTable::_insertActiveSubscriptionsEntry (
    const CIMInstance & subscription,
    const Array <ProviderClassList> & providers)
{
    PEG_METHOD_ENTER (TRC_INDICATION_SERVICE,
        "SubscriptionTable::_insertActiveSubscriptionsEntry");

    String activeSubscriptionsKey = _generateActiveSubscriptionsKey
        (subscription.getPath ());
    ActiveSubscriptionsTableEntry entry;
    entry.subscription = subscription;
    entry.providers = providers;

    //
    //  Insert returns true on success, false if duplicate key
    //
    Boolean succeeded = _activeSubscriptionsTable.insert
        (activeSubscriptionsKey, entry);
    PEGASUS_ASSERT (succeeded);

#ifdef PEGASUS_INDICATION_HASHTRACE
    String traceString;
    traceString.append (activeSubscriptionsKey);
    traceString.append (" Providers: ");
    for (Uint32 i = 0; i < providers.size (); i++)
    {
        String providerName = providers [i].provider.getProperty
            (providers [i].provider.findProperty
            (PEGASUS_PROPERTYNAME_NAME)).getValue ().toString ();
        traceString.append (providerName);
        traceString.append ("  Classes: ");
        for (Uint32 j = 0; j < providers[i].classList.size (); j++)
        {
             traceString.append (providers[i].classList[j].getString());
             traceString.append ("  ");
        }
    }

    PEG_TRACE((TRC_INDICATION_SERVICE, Tracer::LEVEL4,
        "INSERTED _activeSubscriptionsTable entry: %s",
        (const char*)traceString.getCString()));
#endif

    PEG_METHOD_EXIT ();
}

void SubscriptionTable::_removeActiveSubscriptionsEntry (
    const String & key)
{
    PEG_METHOD_ENTER (TRC_INDICATION_SERVICE,
        "SubscriptionTable::_removeActiveSubscriptionsEntry");

    //
    //  Remove returns true on success, false if not found
    //
    Boolean succeeded = _activeSubscriptionsTable.remove (key);
    PEGASUS_ASSERT (succeeded);

#ifdef PEGASUS_INDICATION_HASHTRACE
    PEG_TRACE((TRC_INDICATION_SERVICE,Tracer::LEVEL4,
         "REMOVED _activeSubscriptionsTable entry: %s",
         (const char*)key.getCString()));
#endif

    PEG_METHOD_EXIT ();
}

String SubscriptionTable::_generateSubscriptionClassesKey (
    const CIMName & indicationClassName,
    const CIMNamespaceName & sourceNamespaceName) const
{
    String subscriptionClassesKey;

    //
    //  Append indication class name to key
    //
    subscriptionClassesKey.append (indicationClassName.getString ());

    //
    //  Append source namespace name to key
    //
    subscriptionClassesKey.append (sourceNamespaceName.getString ());

    return subscriptionClassesKey;
}

Boolean SubscriptionTable::_lockedLookupSubscriptionClassesEntry (
    const String & key,
    SubscriptionClassesTableEntry & tableEntry) const
{
    ReadLock lock(_subscriptionClassesTableLock);

    return (_subscriptionClassesTable.lookup (key, tableEntry));
}

void SubscriptionTable::_insertSubscriptionClassesEntry (
    const CIMName & indicationClassName,
    const CIMNamespaceName & sourceNamespaceName,
    const Array <CIMInstance> & subscriptions)
{
    PEG_METHOD_ENTER (TRC_INDICATION_SERVICE,
        "SubscriptionTable::_insertSubscriptionClassesEntry");

    String subscriptionClassesKey = _generateSubscriptionClassesKey
        (indicationClassName, sourceNamespaceName);
    SubscriptionClassesTableEntry entry;
    entry.indicationClassName = indicationClassName;
    entry.sourceNamespaceName = sourceNamespaceName;
    entry.subscriptions = subscriptions;

    //
    //  Insert returns true on success, false if duplicate key
    //
    Boolean succeeded = _subscriptionClassesTable.insert
        (subscriptionClassesKey, entry);
    PEGASUS_ASSERT (succeeded);

#ifdef PEGASUS_INDICATION_HASHTRACE
    String traceString;
    traceString.append (subscriptionClassesKey);
    traceString.append (" Subscriptions: ");
    for (Uint32 i = 0; i < subscriptions.size (); i++)
    {
        traceString.append (subscriptions [i].getPath ().toString());
        traceString.append ("  ");
    }

    PEG_TRACE((TRC_INDICATION_SERVICE, Tracer::LEVEL4,
        "INSERTED _subscriptionClassesTable entry: %s",
        (const char*)traceString.getCString()));
#endif

    PEG_METHOD_EXIT ();
}

void SubscriptionTable::_removeSubscriptionClassesEntry (
    const String & key)
{
    PEG_METHOD_ENTER (TRC_INDICATION_SERVICE,
        "SubscriptionTable::_removeSubscriptionClassesEntry");

    //
    //  Remove returns true on success, false if not found
    //
    Boolean succeeded = _subscriptionClassesTable.remove (key);
    PEGASUS_ASSERT (succeeded);

#ifdef PEGASUS_INDICATION_HASHTRACE
    PEG_TRACE((TRC_INDICATION_SERVICE, Tracer::LEVEL4,
        "REMOVED _subscriptionClassesTable entry: %s",
        (const char*)key.getCString()));
#endif

    PEG_METHOD_EXIT ();
}

void SubscriptionTable::_updateSubscriptionProviders
    (const String & activeSubscriptionsKey,
     const CIMInstance & subscription,
     const Array <ProviderClassList> & updatedProviderList)
{
    PEG_METHOD_ENTER (TRC_INDICATION_SERVICE,
        "SubscriptionTable::_updateSubscriptionProviders");

    if (updatedProviderList.size () > 0)
    {
        //
        //  At least one provider is still serving the
        //  subscription
        //  Update entry in Active Subscriptions table
        //
        _removeActiveSubscriptionsEntry (activeSubscriptionsKey);
        _insertActiveSubscriptionsEntry (subscription, updatedProviderList);
    }
    else
    {
        //
        //  The disabled or failed provider(s) was (were) the only provider(s)
        //  serving the subscription
        //  Implement the subscription's On Fatal Error Policy
        //
        Boolean removedOrDisabled =
            _subscriptionRepository->reconcileFatalError (subscription);
        _removeActiveSubscriptionsEntry (activeSubscriptionsKey);
        if (!removedOrDisabled)
        {
            //
            //  If subscription was not disabled or deleted
            //  Update entry in Active Subscriptions table
            //  Note that in this case the updatedProviderList is
            //  empty - no providers are serving the subscription
            //  currently
            //
            _insertActiveSubscriptionsEntry (subscription,
                updatedProviderList);
        }
        else
        {
            // Delete subscription entries from SubscriptionClassesTable.
            WriteLock lock(_subscriptionClassesTableLock);
            Array<SubscriptionClassesTableEntry> scTableValues;
            for (SubscriptionClassesTable::Iterator i =
                _subscriptionClassesTable.start(); i; i++)
            {
                SubscriptionClassesTableEntry value = i.value();
                for (Uint32 j = 0, n = value.subscriptions.size(); j < n; ++j)
                {
                    if (value.subscriptions[j].getPath().identical(
                        subscription.getPath()))
                    {
                        value.subscriptions.remove(j);
                        scTableValues.append(value);
                        break;
                    }
                }
            }
            for (Uint32 i = 0, n = scTableValues.size(); i < n; ++i)
            {
                String subscriptionClassesKey = _generateSubscriptionClassesKey(
                    scTableValues[i].indicationClassName,
                    scTableValues[i].sourceNamespaceName);
                // If this is the only subscription for this class-namespace
                // pair delete the entry else update the subscription list
                // for this class-namespace pair.
                if (scTableValues[i].subscriptions.size())
                {
                    SubscriptionClassesTableEntry *entry = 0;
                    _subscriptionClassesTable.lookupReference(
                        subscriptionClassesKey,
                        entry);
                    PEGASUS_ASSERT(entry);
                    entry->subscriptions = scTableValues[i].subscriptions;
                }
                else
                {
                    _removeSubscriptionClassesEntry(subscriptionClassesKey);
                }
            }
        }
    }

    PEG_METHOD_EXIT ();
}

void SubscriptionTable::insertSubscription (
    const CIMInstance & subscription,
    const Array <ProviderClassList> & providers,
    const Array <NamespaceClassList> & indicationSubclassNames)
{
    PEG_METHOD_ENTER (TRC_INDICATION_SERVICE,
        "SubscriptionTable::insertSubscription");

    //
    //  Insert entry into active subscriptions table
    //
    {
        WriteLock lock(_activeSubscriptionsTableLock);

        _insertActiveSubscriptionsEntry(subscription, providers);
    }

    //
    //  Insert or update entries in subscription classes table
    //
    {
        //
        //  Acquire and hold the write lock during the entire
        //  lookup/remove/insert process, allowing competing threads to apply
        //  their logic over a consistent view of the data.
        //  Do not call any other methods that need
        //  _subscriptionClassesTableLock.
        //
        WriteLock lock (_subscriptionClassesTableLock);
        for (Uint32 i = 0; i < indicationSubclassNames.size (); i++)
        {
            for (Uint32 j = 0, n = indicationSubclassNames[i].classList.size();
                j < n; ++j)
            {
                String subscriptionClassesKey = _generateSubscriptionClassesKey(
                    indicationSubclassNames[i].classList[j],
                    indicationSubclassNames[i].nameSpace);

                SubscriptionClassesTableEntry scTableValue;
                if (_subscriptionClassesTable.lookup(
                    subscriptionClassesKey, scTableValue))
                {
                    //
                    //  If entry exists for this IndicationClassName-
                    //  SourceNamespace pair, remove old entry and insert
                    //  new entry
                    //
                    Array<CIMInstance> subscriptions =
                        scTableValue.subscriptions;
                    subscriptions.append (subscription);
                    _removeSubscriptionClassesEntry (subscriptionClassesKey);
                    _insertSubscriptionClassesEntry (
                        indicationSubclassNames[i].classList[j],
                        indicationSubclassNames[i].nameSpace,
                        subscriptions);
                }
                else
                {
                    //
                    //  If no entry exists for this
                    //  IndicationClassName-SourceNamespace pair, insert new
                    //  entry
                    //
                    Array <CIMInstance> subscriptions;
                    subscriptions.append (subscription);
                   _insertSubscriptionClassesEntry (
                       indicationSubclassNames[i].classList[j],
                       indicationSubclassNames[i].nameSpace,
                       subscriptions);
                }
            }
        }
    }

    PEG_METHOD_EXIT ();
}

void SubscriptionTable::updateProviders (
    const CIMObjectPath & subscriptionPath,
    const ProviderClassList & provider,
    Boolean addProvider)
{
    PEG_METHOD_ENTER (TRC_INDICATION_SERVICE,
        "SubscriptionTable::updateProviders");

    String activeSubscriptionsKey = _generateActiveSubscriptionsKey
        (subscriptionPath);
    ActiveSubscriptionsTableEntry asTableValue;
    {
        //
        //  Acquire and hold the write lock during the entire
        //  lookup/remove/insert process, allowing competing threads to apply
        //  their logic over a consistent view of the data.
        //  Do not call any other methods that need
        //  _activeSubscriptionsTableLock.
        //
        WriteLock lock (_activeSubscriptionsTableLock);
        if (_activeSubscriptionsTable.lookup(
                activeSubscriptionsKey, asTableValue))
        {
            Uint32 providerIndex =
                providerInList(provider.provider, asTableValue);
            if (addProvider)
            {
                if (providerIndex == PEG_NOT_FOUND)
                {
                    asTableValue.providers.append(provider);
                    _removeActiveSubscriptionsEntry(activeSubscriptionsKey);
                    _insertActiveSubscriptionsEntry(
                        asTableValue.subscription,
                        asTableValue.providers);
                }
                else
                {
                    CIMInstance p = provider.provider;
                    PEG_TRACE((TRC_INDICATION_SERVICE,Tracer::LEVEL2,
                        "Provider %s already in list for Subscription (%s) "
                        "in ActiveSubscriptionsTable",
                        (const char*)IndicationService::getProviderLogString(p)
                        .getCString(),
                        (const char*)activeSubscriptionsKey.getCString()));
                }
            }
            else
            {
                if (providerIndex != PEG_NOT_FOUND)
                {
                    asTableValue.providers.remove(providerIndex);
                    _removeActiveSubscriptionsEntry(activeSubscriptionsKey);
                    _insertActiveSubscriptionsEntry(
                        asTableValue.subscription,
                        asTableValue.providers);
                }
                else
                {
                    CIMInstance p = provider.provider;
                    PEG_TRACE((TRC_INDICATION_SERVICE,Tracer::LEVEL2,
                        "Provider %s not found in list for Subscription (%s) "
                        "in ActiveSubscriptionsTable",
                        (const char*)IndicationService::getProviderLogString(p)
                        .getCString(),
                        (const char*)activeSubscriptionsKey.getCString()));
                }
            }
        }
        else
        {
            PEG_TRACE((TRC_INDICATION_SERVICE, Tracer::LEVEL2,
                "Subscription (%s) not found in ActiveSubscriptionsTable",
                (const char*)activeSubscriptionsKey.getCString()));

            //
            //  The subscription may have been deleted in the mean time
            //  If so, no further update is required
            //
        }
    }

    PEG_METHOD_EXIT ();
}

void SubscriptionTable::updateClasses (
    const CIMObjectPath & subscriptionPath,
    const CIMInstance & provider,
    const CIMNamespaceName &nameSpace,
    const CIMName & className)
{
    PEG_METHOD_ENTER (TRC_INDICATION_SERVICE,
        "SubscriptionTable::updateClasses");

    String activeSubscriptionsKey = _generateActiveSubscriptionsKey
        (subscriptionPath);
    ActiveSubscriptionsTableEntry asTableValue;

    {
        //
        //  Acquire and hold the write lock during the entire
        //  lookup/remove/insert process, allowing competing threads to apply
        //  their logic over a consistent view of the data.
        //  Do not call any other methods that need
        //  _activeSubscriptionsTableLock.
        //
        WriteLock lock (_activeSubscriptionsTableLock);
        if (_activeSubscriptionsTable.lookup(
                activeSubscriptionsKey, asTableValue))
        {
            Uint32 providerIndex = providerInList(provider, asTableValue);
            if (providerIndex != PEG_NOT_FOUND)
            {
                Uint32 classIndex = classInList(
                    className,
                    nameSpace,
                    asTableValue.providers[providerIndex]);
                if (classIndex == PEG_NOT_FOUND)
                {
                    for (Uint32 i = 0,
                        n = asTableValue.
                            providers[providerIndex].classList.size();
                        i < n; ++i)
                    {
                        if (asTableValue.providers[providerIndex].
                            classList[i].nameSpace == nameSpace)
                        {
                            asTableValue.providers[providerIndex].classList[i].
                                classList.append(className);
                            break;
                        }
                    }
                }
                else //  classIndex != PEG_NOT_FOUND
                {

                    for (Uint32 i = 0,
                        n = asTableValue.
                            providers[providerIndex].classList.size();
                        i < n; ++i)
                    {
                        if (asTableValue.providers[providerIndex].
                            classList[i].nameSpace == nameSpace)
                        {
                            asTableValue.providers[providerIndex].classList[i].
                                classList.remove(classIndex);
                            break;
                        }
                    }
                }

                _removeActiveSubscriptionsEntry(activeSubscriptionsKey);
                _insertActiveSubscriptionsEntry(
                    asTableValue.subscription,
                    asTableValue.providers);
            }
            else
            {
                PEG_TRACE((TRC_INDICATION_SERVICE,Tracer::LEVEL2,
                    "Provider (%s) not found in list for Subscription (%s) in "
                    "ActiveSubscriptionsTable",
                    (const char*)provider.getPath().toString().getCString(),
                    (const char*)activeSubscriptionsKey.getCString()));
            }
        }
        else
        {
            //
            //  Subscription not found in Active Subscriptions table
            //
        }
    }

    PEG_METHOD_EXIT ();
}

void SubscriptionTable::removeSubscription (
    const CIMInstance & subscription,
    const Array <NamespaceClassList> & indicationSubclassNames,
    const Array <ProviderClassList> & providers)
{
    PEG_METHOD_ENTER (TRC_INDICATION_SERVICE,
        "SubscriptionTable::removeSubscription");

    //
    //  Remove entry from active subscriptions table
    //
    {
        WriteLock lock(_activeSubscriptionsTableLock);

        _removeActiveSubscriptionsEntry (
            _generateActiveSubscriptionsKey (subscription.getPath ()));
    }

    //
    //  Remove or update entries in subscription classes table
    //
    {
        //
        //  Acquire and hold the write lock during the entire
        //  lookup/remove/insert process, allowing competing threads to apply
        //  their logic over a consistent view of the data.
        //  Do not call any other methods that need
        //  _subscriptionClassesTableLock.
        //
        WriteLock lock (_subscriptionClassesTableLock);
        for (Uint32 i = 0; i < indicationSubclassNames.size (); i++)
        {
            for (Uint32 k = 0, n = indicationSubclassNames[i].classList.size();
                k < n; ++k)
            {
                String subscriptionClassesKey = _generateSubscriptionClassesKey(
                    indicationSubclassNames[i].classList[k],
                    indicationSubclassNames[i].nameSpace);
                SubscriptionClassesTableEntry scTableValue;
                if (_subscriptionClassesTable.lookup(
                    subscriptionClassesKey, scTableValue))
                {
                    //
                    //  If entry exists for this IndicationClassName-
                    //  -SourceNamespace pair, remove subscription from the list
                    //
                    Array<CIMInstance> subscriptions =
                        scTableValue.subscriptions;
                    for (Uint32 j = 0; j < subscriptions.size (); j++)
                    {
                        if (subscriptions [j].getPath().identical
                           (subscription.getPath()))
                        {
                            subscriptions.remove (j);
                        }
                    }

                    //
                    //  Remove the old entry
                    //
                    _removeSubscriptionClassesEntry (subscriptionClassesKey);

                    //
                    //  If there are still subscriptions in the list, insert the
                    //  new entry
                    //
                    if (subscriptions.size () > 0)
                    {
                        _insertSubscriptionClassesEntry (
                        indicationSubclassNames[i].classList[k],
                        indicationSubclassNames[i].nameSpace,
                        subscriptions);
                    }
                }
                else
                {
                    //
                    //  Entry not found in Subscription Classes table
                    //
                    PEG_TRACE((TRC_INDICATION_SERVICE,Tracer::LEVEL2,
                        "Indication subclass and namespace (%s) not found "
                        "in SubscriptionClassesTable",
                        (const char*)subscriptionClassesKey.getCString()));
                }
            }
        }
    }

    PEG_METHOD_EXIT ();
}

Uint32 SubscriptionTable::providerInList
    (const CIMInstance & provider,
     const ActiveSubscriptionsTableEntry & tableValue,
     const CIMNamespaceName &nameSpace) const
{
    PEG_METHOD_ENTER (TRC_INDICATION_SERVICE,
        "SubscriptionTable::providerInList");

    //
    //  Look for the provider in the list
    //
    for (Uint32 i = 0; i < tableValue.providers.size (); i++)
    {
        if (tableValue.providers [i].provider.getPath ().identical
            (provider.getPath ()))
        {
            if (nameSpace.isNull())
            {
                PEG_METHOD_EXIT ();
                return i;
            }
            for (Uint32 j = 0; j < tableValue.providers[i].classList.size();
                ++j)
            {
                if (tableValue.providers[i].classList[j].nameSpace
                    == nameSpace)
                {
                    PEG_METHOD_EXIT ();
                    return i;
                }
            }
        }
    }

    PEG_METHOD_EXIT ();
    return PEG_NOT_FOUND;
}


Uint32 SubscriptionTable::classInList
    (const CIMName & className,
     const CIMNamespaceName &nameSpace,
     const ProviderClassList & providerClasses) const
{
    PEG_METHOD_ENTER (TRC_INDICATION_SERVICE, "SubscriptionTable::classInList");

    //
    //  Look for the class in the list
    //
    for (Uint32 i = 0; i < providerClasses.classList.size (); i++)
    {
        if (providerClasses.classList[i].nameSpace == nameSpace)
        {
            for (Uint32 j = 0;
                j < providerClasses.classList[i].classList.size(); i++)
            {
                if (providerClasses.classList[i].classList[j].equal(className))
                {
                    PEG_METHOD_EXIT ();
                    return i;
                }
            }
        }
    }

    PEG_METHOD_EXIT ();
    return PEG_NOT_FOUND;
}

void SubscriptionTable::clear ()
{
    PEG_METHOD_ENTER (TRC_INDICATION_SERVICE, "SubscriptionTable::clear");

    {
        WriteLock lock (_activeSubscriptionsTableLock);
        _activeSubscriptionsTable.clear ();
    }
    {
        WriteLock lock (_subscriptionClassesTableLock);
        _subscriptionClassesTable.clear ();
    }

    PEG_METHOD_EXIT ();
}

void SubscriptionTable::getMatchingClassNamespaceSubscriptions(
    const CIMName & supportedClass,
    const CIMNamespaceName & nameSpace,
    const CIMInstance& provider,
    Array<CIMInstance>& matchingSubscriptions,
    Array<String>& matchingSubscriptionKeys)
{
    PEG_METHOD_ENTER (TRC_INDICATION_SERVICE,
        "SubscriptionTable::getMatchingClassNamespaceSubscriptions");

    Array <CIMInstance> subscriptions;
    matchingSubscriptions.clear();
    matchingSubscriptionKeys.clear();

    //
    //  Look up the indicationClass-sourceNamespace pair in the
    //  Subscription Classes table
    //
    String subscriptionClassesKey = _generateSubscriptionClassesKey
        (supportedClass, nameSpace);
    SubscriptionClassesTableEntry scTableValue;
    if (_lockedLookupSubscriptionClassesEntry(
            subscriptionClassesKey, scTableValue))
    {
        subscriptions = scTableValue.subscriptions;
        for (Uint32 j = 0; j < subscriptions.size (); j++)
        {
            //
            //  Check if the provider who generated this indication
            //  accepted this subscription
            //
            String activeSubscriptionsKey =
                _generateActiveSubscriptionsKey
                    (subscriptions [j].getPath ());
            ActiveSubscriptionsTableEntry asTableValue;
            if (_lockedLookupActiveSubscriptionsEntry(
                    activeSubscriptionsKey, asTableValue))
            {
                //
                //  If provider is in list, the subscription is acceptted
                //
                if ((providerInList(provider, asTableValue, nameSpace))
                    != PEG_NOT_FOUND)
                {
                    //
                    //  Add current subscription to list
                    //
                    matchingSubscriptions.append(subscriptions[j]);
                    matchingSubscriptionKeys.append(activeSubscriptionsKey);
                }
            }
        }
    }

    PEGASUS_ASSERT(
        matchingSubscriptions.size() == matchingSubscriptionKeys.size());
    PEG_METHOD_EXIT ();
}

Array<ActiveSubscriptionsTableEntry>
    SubscriptionTable::getAllActiveSubscriptionEntries()
{
    PEG_METHOD_ENTER(TRC_INDICATION_SERVICE,
        "SubscriptionTable::getAllActiveSubscriptionEntries");

    Array <ActiveSubscriptionsTableEntry> subscriptionsEntries;

    //
    // Iterate through the ActiveSubscriptions table to get all active
    // subscriptions table entries
    //

    ReadLock lock(_activeSubscriptionsTableLock);

    for (ActiveSubscriptionsTable::Iterator i =
        _activeSubscriptionsTable.start(); i; i++)
    {
        subscriptionsEntries.append(i.value());
    }

    PEG_METHOD_EXIT();
    return subscriptionsEntries;
}

#ifdef PEGASUS_ENABLE_INDICATION_COUNT

void SubscriptionTable::updateMatchedIndicationCounts(
    const CIMInstance & providerInstance,
    const Array<String>& activeSubscriptionsKeys)
{
    PEG_METHOD_ENTER(TRC_INDICATION_SERVICE,
        "SubscriptionTable::updateMatchedIndicationCounts");

    WriteLock lock(_activeSubscriptionsTableLock);

    for (Uint32 i = 0; i < activeSubscriptionsKeys.size(); i++)
    {
        ActiveSubscriptionsTableEntry* entry = 0;
        if (_activeSubscriptionsTable.lookupReference(
                activeSubscriptionsKeys[i], entry))
        {
            Uint32 providerIndex = providerInList(providerInstance, *entry);
            if (providerIndex != PEG_NOT_FOUND)
            {
                entry->providers[providerIndex].
                    matchedIndCountPerSubscription++;
            }
        }
        else
        {
            // The subscription may have been deleted in the mean time.
            // If so, no further update is required.
            PEG_TRACE((TRC_INDICATION_SERVICE, Tracer::LEVEL2,
                "Subscription %s not found in ActiveSubscriptionsTable",
                (const char *) activeSubscriptionsKeys[i].getCString()));
        }
    }
    PEG_METHOD_EXIT();
}


Array<CIMInstance>
    SubscriptionTable::enumerateSubscriptionIndicationDataInstances()
{
    PEG_METHOD_ENTER(TRC_INDICATION_SERVICE,
        "SubscriptionTable::enumerateSubscriptionIndicationDataInstances");

    Array<CIMInstance> instances;

    //
    // Get all active subscriptions table entries
    //
    Array<ActiveSubscriptionsTableEntry> activeSubscriptionEntries =
        getAllActiveSubscriptionEntries();

    for (Uint32 i = 0; i < activeSubscriptionEntries.size(); i++)
    {
        //
        // Gets filter name and handler name of the subscription
        //
        CIMInstance subscription = activeSubscriptionEntries[i].subscription;
        String sourceNS = subscription.getPath().getNameSpace().getString();

        String filterName;
        String handlerName;
        _getFilterAndHandlerNames(subscription, filterName, handlerName);

        Array<ProviderClassList> providers =
            activeSubscriptionEntries[i].providers;

        for (Uint32 j = 0; j < providers.size(); j++)
        {
            //
            // Gets provider name and provider module name
            //
            String providerName, providerModuleName;
            ProviderIndicationCountTable::getProviderKeys(
                providers[j].provider,
                providerModuleName,
                providerName);

            CIMInstance subscriptionIndDataInstance =
                _buildSubscriptionIndDataInstance(
                    filterName,
                    handlerName,
                    sourceNS,
                    providerModuleName,
                    providerName,
                    providers[j].matchedIndCountPerSubscription);

            instances.append(subscriptionIndDataInstance);
        }
    }

    PEG_METHOD_EXIT();
    return instances;
}

Array<CIMObjectPath>
    SubscriptionTable::enumerateSubscriptionIndicationDataInstanceNames()
{
    PEG_METHOD_ENTER(TRC_INDICATION_SERVICE,
        "SubscriptionTable::enumerateSubscriptionIndicationDataInstanceNames");

    Array<CIMObjectPath> instanceNames;

    //
    // Get all active subscriptions table entries
    //
    Array<ActiveSubscriptionsTableEntry> activeSubscriptionEntries =
        getAllActiveSubscriptionEntries();

    for (Uint32 i = 0; i < activeSubscriptionEntries.size(); i++)
    {
        //
        // Gets filter name and handler name of the subscription
        //
        CIMInstance subscription = activeSubscriptionEntries[i].subscription;
        String sourceNS = subscription.getPath().getNameSpace().getString();

        String filterName;
        String handlerName;
        _getFilterAndHandlerNames(subscription, filterName, handlerName);

        Array<ProviderClassList> providers =
            activeSubscriptionEntries[i].providers;

        for (Uint32 j = 0; j < providers.size(); j++)
        {
            //
            // Gets provider name and provider module name
            //
            String providerName, providerModuleName;
            ProviderIndicationCountTable::getProviderKeys(
                providers[j].provider,
                providerModuleName,
                providerName);

            CIMObjectPath path = _buildSubscriptionIndDataInstanceName(
                filterName,
                handlerName,
                sourceNS,
                providerModuleName,
                providerName);

            instanceNames.append(path);
        }
    }

    PEG_METHOD_EXIT();
    return instanceNames;
}

CIMInstance SubscriptionTable::getSubscriptionIndicationDataInstance(
    const CIMObjectPath& instanceName)
{
    PEG_METHOD_ENTER(TRC_INDICATION_SERVICE,
        "SubscriptionTable::getSubscriptionIndicationDataInstance");

    String filterName;
    String handlerName;
    String sourceNS;
    String specifiedProviderModuleName;
    String specifiedProviderName;

    //
    // Gets handler name, filter name, source namespace, provider module name,
    // and provider name from a PG_SubscriptionIndicationData instanceName
    //
    _getSubscriptionIndicationDataKeys(
        instanceName,
        filterName,
        handlerName,
        sourceNS,
        specifiedProviderModuleName,
        specifiedProviderName);

    // Builds the PG_Provider object path
    CIMObjectPath providerName = _buildProviderPath(
        specifiedProviderModuleName, specifiedProviderName);

    //
    // Builds subscription path by using the specified parameters
    //
    CIMObjectPath subscriptionPath = _buildSubscriptionPath(
        filterName, handlerName, sourceNS);

    //
    // Look up the subscription in the active subscriptions table
    //
    ActiveSubscriptionsTableEntry asTableValue;
    if (getSubscriptionEntry(subscriptionPath, asTableValue))
    {
        Array<ProviderClassList> providers = asTableValue.providers;
        for (Uint32 i = 0; i < providers.size(); i++)
        {
            if (providerName.identical(providers[i].provider.getPath()))
            {
                CIMInstance subIndDataInstance =
                    _buildSubscriptionIndDataInstance(
                        filterName,
                        handlerName,
                        sourceNS,
                        specifiedProviderModuleName,
                        specifiedProviderName,
                        providers[i].matchedIndCountPerSubscription);

                PEG_METHOD_EXIT();
                return subIndDataInstance;
            }
        }
    }

    PEG_METHOD_EXIT();
    throw CIMObjectNotFoundException(instanceName.toString());
}

void SubscriptionTable::_getFilterAndHandlerNames(
    const CIMInstance& subscription,
    String& filterName,
    String& handlerName)
{
    PEG_METHOD_ENTER(TRC_INDICATION_SERVICE,
        "SubscriptionTable::_getFilterAndHandlerNames");

    CIMObjectPath filterPath;
    CIMObjectPath handlerPath;

    subscription.getProperty(subscription.findProperty(
        PEGASUS_PROPERTYNAME_FILTER)).getValue().get(filterPath);
    subscription.getProperty(subscription.findProperty(
        PEGASUS_PROPERTYNAME_HANDLER)).getValue().get(handlerPath);

    //
    //  Get Filter namespace - if not set in Filter reference property
    //  value, namespace is the namespace of the subscription
    //
    CIMNamespaceName filterNS = filterPath.getNameSpace();
    if (filterNS.isNull())
    {
        filterNS = subscription.getPath().getNameSpace();
    }

    //
    // Get filter name
    //
    Array<CIMKeyBinding> filterKeyBindings = filterPath.getKeyBindings();
    for (Uint32 i = 0; i < filterKeyBindings.size(); i++)
    {
        if (filterKeyBindings[i].getName().equal(PEGASUS_PROPERTYNAME_NAME))
        {
            filterName.append(filterNS.getString());
            filterName.append(":");
            filterName.append(filterKeyBindings[i].getValue());
            break;
        }
    }

    //
    //  Get handler namespace - if not set in handler reference property
    //  value, namespace is the namespace of the subscription
    //
    CIMNamespaceName handlerNS = handlerPath.getNameSpace();
    if (handlerNS.isNull())
    {
        handlerNS = subscription.getPath().getNameSpace();
    }

    //
    // Get handler name
    //
    Array<CIMKeyBinding> handlerKeyBindings = handlerPath.getKeyBindings();
    for (Uint32 i = 0; i < handlerKeyBindings.size(); i++)
    {
        if (handlerKeyBindings[i].getName().equal(PEGASUS_PROPERTYNAME_NAME))
        {
            handlerName.append(handlerNS.getString());
            handlerName.append(":");
            handlerName.append(handlerPath.getClassName().getString());
            handlerName.append(".");
            handlerName.append(handlerKeyBindings[i].getValue());
            break;
        }
    }

    PEG_METHOD_EXIT();
}

void SubscriptionTable::_getSubscriptionIndicationDataKeys(
    const CIMObjectPath& instanceName,
    String& filterName,
    String& handlerName,
    String& sourceNS,
    String& providerModuleName,
    String& providerName)
{
    PEG_METHOD_ENTER(TRC_INDICATION_SERVICE,
        "SubscriptionTable::_getSubscriptionIndicationDataKeys");

    Array<CIMKeyBinding> keys = instanceName.getKeyBindings();
    for (Uint32 i = 0; i < keys.size(); i++)
    {
        if (keys[i].getName() == "FilterName")
        {
            filterName = keys[i].getValue();
        }
        else if (keys[i].getName() == "HandlerName")
        {
            handlerName = keys[i].getValue();
        }
        else if (keys[i].getName() == "SourceNamespace")
        {
            sourceNS = keys[i].getValue();
        }
        else if (keys[i].getName() == "ProviderModuleName")
        {
            providerModuleName = keys[i].getValue();
        }
        else if (keys[i].getName() == "ProviderName")
        {
            providerName = keys[i].getValue();
        }
    }

    PEG_METHOD_EXIT();
}


CIMObjectPath SubscriptionTable::_buildFilterPath(const String& filterName)
{
    PEG_METHOD_ENTER(TRC_INDICATION_SERVICE,
        "SubscriptionTable::_buildFilterPath");

    //
    // creates filter object path from input string filterName
    // (namespace:filtername)
    //
    String name;
    Uint32 colonIndex = filterName.find(':');

    if (colonIndex != PEG_NOT_FOUND)
    {
        name = filterName.subString(colonIndex + 1);
    }

    Array<CIMKeyBinding> filterKeys;
    filterKeys.append(CIMKeyBinding(
        "SystemCreationClassName",
        System::getSystemCreationClassName(),
        CIMKeyBinding::STRING));
    filterKeys.append(CIMKeyBinding(
        "SystemName",
        System::getFullyQualifiedHostName(),
        CIMKeyBinding::STRING));
    filterKeys.append(CIMKeyBinding(
        "CreationClassName",
        PEGASUS_CLASSNAME_INDFILTER.getString(),
        CIMKeyBinding::STRING));
    filterKeys.append(CIMKeyBinding(
        PEGASUS_PROPERTYNAME_NAME,
        name,
        CIMKeyBinding::STRING));

    CIMObjectPath filterPath = CIMObjectPath(
        String::EMPTY,
        CIMNamespaceName(),
        PEGASUS_CLASSNAME_INDFILTER,
        filterKeys);

    PEG_METHOD_EXIT();
    return filterPath;
}

CIMObjectPath SubscriptionTable::_buildHandlerPath(const String& handlerName)
{
    PEG_METHOD_ENTER(TRC_INDICATION_SERVICE,
        "SubscriptionTable::_buildHandlerPath");

    //
    // creates handler object path from input string handlerName
    // (namespace:classname.handlername)
    //
    String name;
    String classname;
    Uint32 colonIndex = handlerName.find(':');
    Uint32 dotIndex = handlerName.find('.');

    if (colonIndex != PEG_NOT_FOUND)
    {
        if ((dotIndex != PEG_NOT_FOUND) && (dotIndex > colonIndex))
        {
            classname = handlerName.subString(
                colonIndex + 1, dotIndex - 1 - colonIndex);
            name = handlerName.subString(dotIndex + 1);
        }
    }

    Array<CIMKeyBinding> handlerKeys;
    handlerKeys.append(CIMKeyBinding(
        "SystemCreationClassName",
        System::getSystemCreationClassName(),
        CIMKeyBinding::STRING));
    handlerKeys.append(CIMKeyBinding(
        "SystemName",
        System::getFullyQualifiedHostName(),
        CIMKeyBinding::STRING));
    handlerKeys.append(CIMKeyBinding(
        "CreationClassName",
        classname,
        CIMKeyBinding::STRING));
    handlerKeys.append(CIMKeyBinding(
        PEGASUS_PROPERTYNAME_NAME,
        name,
        CIMKeyBinding::STRING));

    CIMObjectPath handlerPath = CIMObjectPath(
        String::EMPTY,
        CIMNamespaceName(),
        classname,
        handlerKeys);

    PEG_METHOD_EXIT();
    return handlerPath;
}

CIMObjectPath SubscriptionTable::_buildSubscriptionPath(
    const String& filterName,
    const String& handlerName,
    const String& sourceNS)
{
    CIMObjectPath filterPath = _buildFilterPath(filterName);
    CIMObjectPath handlerPath = _buildHandlerPath(handlerName);

    CIMObjectPath subscriptionPath;
    Array<CIMKeyBinding> keyBindings;
    keyBindings.append(CIMKeyBinding(
        PEGASUS_PROPERTYNAME_FILTER,
        filterPath.toString(),
        CIMKeyBinding::REFERENCE));
    keyBindings.append(CIMKeyBinding(
        PEGASUS_PROPERTYNAME_HANDLER,
        handlerPath.toString(),
        CIMKeyBinding::REFERENCE));

    subscriptionPath.setClassName(PEGASUS_CLASSNAME_INDSUBSCRIPTION);
    subscriptionPath.setNameSpace(sourceNS);
    subscriptionPath.setKeyBindings(keyBindings);

    return subscriptionPath;
}

CIMInstance SubscriptionTable::_buildSubscriptionIndDataInstance(
    const String& filterName,
    const String& handlerName,
    const String& sourceNS,
    const String& providerModuleName,
    const String& providerName,
    Uint32 matchedIndicationCount)
{
    CIMInstance subscriptionIndDataInstance(
        PEGASUS_CLASSNAME_SUBSCRIPTIONINDDATA);
    subscriptionIndDataInstance.addProperty(CIMProperty(
        CIMName("FilterName"), filterName));
    subscriptionIndDataInstance.addProperty(CIMProperty(
        CIMName("HandlerName"), handlerName));
    subscriptionIndDataInstance.addProperty(CIMProperty(
        CIMName("SourceNamespace"), sourceNS));
    subscriptionIndDataInstance.addProperty(CIMProperty(
        CIMName("ProviderModuleName"), providerModuleName));
    subscriptionIndDataInstance.addProperty(CIMProperty(
        CIMName("ProviderName"), providerName));
    subscriptionIndDataInstance.addProperty(CIMProperty(
        CIMName("MatchedIndicationCount"),
        matchedIndicationCount));

    CIMObjectPath path = _buildSubscriptionIndDataInstanceName(
        filterName,
        handlerName,
        sourceNS,
        providerModuleName,
        providerName);
    subscriptionIndDataInstance.setPath(path);

    return subscriptionIndDataInstance;
}

CIMObjectPath SubscriptionTable::_buildSubscriptionIndDataInstanceName(
    const String& filterName,
    const String& handlerName,
    const String& sourceNS,
    const String& providerModuleName,
    const String& providerName)
{
    CIMObjectPath path;
    Array<CIMKeyBinding> keyBindings;
    keyBindings.append(CIMKeyBinding(
        "FilterName",
        filterName,
        CIMKeyBinding::STRING));
    keyBindings.append(CIMKeyBinding(
        "HandlerName",
        handlerName,
        CIMKeyBinding::STRING));
    keyBindings.append(CIMKeyBinding(
        "SourceNamespace",
        sourceNS,
        CIMKeyBinding::STRING));
    keyBindings.append(CIMKeyBinding(
        "ProviderModuleName",
        providerModuleName,
        CIMKeyBinding::STRING));
    keyBindings.append(CIMKeyBinding(
        "ProviderName",
        providerName,
        CIMKeyBinding::STRING));

    path.setClassName(PEGASUS_CLASSNAME_SUBSCRIPTIONINDDATA);
    path.setKeyBindings(keyBindings);

    return path;
}

CIMObjectPath SubscriptionTable::_buildProviderPath(
    const String& providerModuleName,
    const String& providerName)
{
    CIMObjectPath path;
    Array<CIMKeyBinding> keyBindings;
    keyBindings.append(CIMKeyBinding(
        _PROPERTY_PROVIDERMODULENAME,
        providerModuleName,
        CIMKeyBinding::STRING));
    keyBindings.append(CIMKeyBinding(
        PEGASUS_PROPERTYNAME_NAME,
        providerName,
        CIMKeyBinding::STRING));

    path.setClassName(PEGASUS_CLASSNAME_PROVIDER);
    path.setKeyBindings(keyBindings);

    return path;
}

#endif

PEGASUS_NAMESPACE_END

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2