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

   1 karl  1.11 //%2006////////////////////////////////////////////////////////////////////////
   2 kumpf 1.1  //
   3 karl  1.3  // Copyright (c) 2000, 2001, 2002 BMC Software; Hewlett-Packard Development
   4            // Company, L.P.; IBM Corp.; The Open Group; Tivoli Systems.
   5            // Copyright (c) 2003 BMC Software; Hewlett-Packard Development Company, L.P.;
   6 kumpf 1.1  // IBM Corp.; EMC Corporation, The Open Group.
   7 karl  1.3  // Copyright (c) 2004 BMC Software; Hewlett-Packard Development Company, L.P.;
   8            // IBM Corp.; EMC Corporation; VERITAS Software Corporation; The Open Group.
   9 karl  1.5  // Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.;
  10            // EMC Corporation; VERITAS Software Corporation; The Open Group.
  11 karl  1.11 // Copyright (c) 2006 Hewlett-Packard Development Company, L.P.; IBM Corp.;
  12            // EMC Corporation; Symantec Corporation; The Open Group.
  13 kumpf 1.1  //
  14            // Permission is hereby granted, free of charge, to any person obtaining a copy
  15            // of this software and associated documentation files (the "Software"), to
  16            // deal in the Software without restriction, including without limitation the
  17            // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  18            // sell copies of the Software, and to permit persons to whom the Software is
  19            // furnished to do so, subject to the following conditions:
  20            // 
  21            // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
  22            // ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED
  23            // "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
  24            // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
  25            // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
  26            // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
  27            // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  28            // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  29            //
  30            //==============================================================================
  31            //
  32            // Author: Carol Ann Krug Graves, Hewlett-Packard Company
  33            //             (carolann_graves@hp.com)
  34 kumpf 1.1  //
  35            // Modified By:  
  36 gs.keenan 1.4  //              Sean Keenan, Hewlett-Packard Company (sean.keenan@hp.com)
  37 aruran.ms 1.7  //              Aruran, IBM (ashanmug@in.ibm.com) for Bug# 3603
  38 kumpf     1.1  //
  39                //%/////////////////////////////////////////////////////////////////////////////
  40                
  41                #include <Pegasus/Common/Config.h>
  42                #include <Pegasus/Common/Constants.h>
  43                #include <Pegasus/Common/Tracer.h>
  44                
  45                #include "IndicationConstants.h"
  46                #include "IndicationService.h"
  47                #include "SubscriptionTable.h"
  48                
  49                PEGASUS_USING_STD;
  50                
  51                PEGASUS_NAMESPACE_BEGIN
  52                
  53                SubscriptionTable::SubscriptionTable (
  54                    SubscriptionRepository * subscriptionRepository)
  55                    : _subscriptionRepository (subscriptionRepository)
  56                {
  57                }
  58                
  59 kumpf     1.1  SubscriptionTable::~SubscriptionTable ()
  60                {
  61                }
  62                
  63                Boolean SubscriptionTable::getSubscriptionEntry (
  64                    const CIMObjectPath & subscriptionPath,
  65 carolann.graves 1.9      ActiveSubscriptionsTableEntry & tableValue) const
  66 kumpf           1.1  {
  67                          PEG_METHOD_ENTER (TRC_INDICATION_SERVICE,
  68                              "SubscriptionTable::getSubscriptionEntry");
  69                      
  70                          Boolean succeeded = false;
  71 carolann.graves 1.10     CIMObjectPath activeSubscriptionsKey = _generateActiveSubscriptionsKey
  72 kumpf           1.1          (subscriptionPath);
  73 carolann.graves 1.9      if (_lockedLookupActiveSubscriptionsEntry
  74 kumpf           1.1          (activeSubscriptionsKey, tableValue))
  75                          {
  76                              succeeded = true;
  77                          }
  78                          else
  79                          {
  80                              //
  81                              //  Subscription not found in Active Subscriptions table
  82                              //
  83                              PEG_TRACE_STRING (TRC_INDICATION_SERVICE_INTERNAL, Tracer::LEVEL2,
  84 carolann.graves 1.10             "Subscription (" + activeSubscriptionsKey.toString () +
  85 kumpf           1.1              ") not found in ActiveSubscriptionsTable");
  86                          }
  87                      
  88                          PEG_METHOD_EXIT ();
  89                          return succeeded;
  90                      }
  91                      
  92                      Array <CIMInstance> SubscriptionTable::getMatchingSubscriptions (
  93                          const CIMName & supportedClass,
  94                          const Array <CIMNamespaceName> nameSpaces,
  95                          const Boolean checkProvider,
  96 aruran.ms       1.7      const CIMInstance & provider) const
  97 kumpf           1.1  {
  98                          PEG_METHOD_ENTER (TRC_INDICATION_SERVICE,
  99                              "SubscriptionTable::getMatchingSubscriptions");
 100                      
 101                          Array <CIMInstance> matchingSubscriptions;
 102                          Array <CIMInstance> subscriptions;
 103                      
 104                          for (Uint32 i = 0; i < nameSpaces.size (); i++)
 105                          {
 106                              //
 107 carolann.graves 1.9          //  Look up the indicationClass-sourceNamespace pair in the
 108 kumpf           1.1          //  Subscription Classes table
 109                              //
 110 carolann.graves 1.9          String subscriptionClassesKey = _generateSubscriptionClassesKey
 111 kumpf           1.1              (supportedClass, nameSpaces [i]);
 112                              SubscriptionClassesTableEntry tableValue;
 113 carolann.graves 1.9          if (_lockedLookupSubscriptionClassesEntry (subscriptionClassesKey,
 114 kumpf           1.1              tableValue))
 115                              {
 116                                  subscriptions = tableValue.subscriptions;
 117                                  for (Uint32 j = 0; j < subscriptions.size (); j++)
 118                                  {
 119                                      Boolean match = true;
 120                      
 121                                      if (checkProvider)
 122                                      {
 123                                          //
 124 carolann.graves 1.9                      //  Check if the provider who generated this indication
 125 kumpf           1.1                      //  accepted this subscription
 126                                          //
 127 carolann.graves 1.10                     CIMObjectPath activeSubscriptionsKey =
 128 kumpf           1.1                          _generateActiveSubscriptionsKey
 129 carolann.graves 1.10                             (subscriptions [j].getPath ());
 130 kumpf           1.1                      ActiveSubscriptionsTableEntry tableValue;
 131 carolann.graves 1.9                      if (_lockedLookupActiveSubscriptionsEntry
 132 kumpf           1.1                          (activeSubscriptionsKey, tableValue))
 133                                          {
 134                                              //
 135                                              //  If provider is not in list, it did not accept the
 136                                              //  subscription
 137                                              //
 138 carolann.graves 1.9                          if ((providerInList (provider, tableValue)) ==
 139 kumpf           1.1                              PEG_NOT_FOUND)
 140                                              {
 141                                                  match = false;
 142                                                  break;
 143                                              }
 144                                          }
 145                                      }
 146                      
 147                                      if (match)
 148                                      {
 149                                          //
 150                                          //  Add current subscription to list
 151                                          //
 152                                          matchingSubscriptions.append (subscriptions [j]);
 153                                      }
 154                                  }
 155                              }
 156                          }
 157                      
 158                          PEG_METHOD_EXIT ();
 159                          return matchingSubscriptions;
 160 kumpf           1.1  }
 161                      
 162 carolann.graves 1.12 Array <CIMInstance> SubscriptionTable::reflectProviderDisable (
 163 aruran.ms       1.8      const CIMInstance & provider)
 164 kumpf           1.1  {
 165                          PEG_METHOD_ENTER (TRC_INDICATION_SERVICE,
 166 carolann.graves 1.12         "SubscriptionTable::reflectProviderDisable");
 167 kumpf           1.1  
 168                          Array <CIMInstance> providerSubscriptions;
 169                      
 170                          //
 171                          //  Iterate through the subscription table to find subscriptions served by
 172                          //  the provider
 173 carolann.graves 1.9      //  NOTE: updating entries (remove and insert) while iterating through the
 174 kumpf           1.1      //  table does not work reliably, and it is not clear if that is supposed to
 175 carolann.graves 1.9      //  work; for now, the SubscriptionTable first iterates through the
 176                          //  active subscriptions table to find subscriptions served by the
 177                          //  provider, then looks up and updates each affected subscription
 178 kumpf           1.1      //
 179                          {
 180                              //
 181 carolann.graves 1.9          //  Acquire and hold the write lock during the entire
 182                              //  lookup/remove/insert process, allowing competing threads to apply
 183                              //  their logic over a consistent view of the data.
 184                              //  Do not call any other methods that need 
 185                              //  _activeSubscriptionsTableLock.
 186 kumpf           1.1          //
 187 carolann.graves 1.9          WriteLock lock (_activeSubscriptionsTableLock);
 188 kumpf           1.1  
 189                              for (ActiveSubscriptionsTable::Iterator i =
 190                                  _activeSubscriptionsTable.start (); i; i++)
 191                              {
 192                                  //
 193                                  //  If provider matches, append subscription to the list
 194                                  //
 195                                  ActiveSubscriptionsTableEntry tableValue = i.value ();
 196                                  for (Uint32 j = 0; j < tableValue.providers.size (); j++)
 197                                  {
 198 carolann.graves 1.9                  if (tableValue.providers [j].provider.getPath ().identical
 199 kumpf           1.1                      (provider.getPath ()))
 200                                      {
 201                                          //
 202                                          //  Add the subscription to the list
 203                                          //
 204                                          providerSubscriptions.append (tableValue.subscription);
 205                                          break;
 206                                      }
 207                                  }
 208                              }
 209                      
 210                              //
 211 carolann.graves 1.9          //  Look up and update hash table entry for each affected subscription
 212 kumpf           1.1          //
 213 carolann.graves 1.9          for (Uint32 k = 0; k < providerSubscriptions.size (); k++)
 214 kumpf           1.1          {
 215                                  //
 216 carolann.graves 1.9              //  Update the entry in the active subscriptions hash table
 217 kumpf           1.1              //
 218 carolann.graves 1.10             CIMObjectPath activeSubscriptionsKey =
 219                                      _generateActiveSubscriptionsKey
 220                                          (providerSubscriptions [k].getPath ());
 221 carolann.graves 1.9              ActiveSubscriptionsTableEntry tableValue;
 222                                  if (_activeSubscriptionsTable.lookup (activeSubscriptionsKey,
 223                                      tableValue))
 224 kumpf           1.1              {
 225 carolann.graves 1.9                  //
 226                                      //  Remove the provider from the list of providers serving the
 227                                      //  subscription
 228                                      //
 229                                      Uint32 providerIndex = providerInList (provider, tableValue);
 230                                      if (providerIndex != PEG_NOT_FOUND)
 231 kumpf           1.1                  {
 232 carolann.graves 1.9                      tableValue.providers.remove (providerIndex);
 233 carolann.graves 1.12 
 234                                          _updateSubscriptionProviders (activeSubscriptionsKey,
 235                                              tableValue.subscription, tableValue.providers);
 236 carolann.graves 1.9                  }
 237                                      else
 238                                      {
 239                                          PEG_TRACE_STRING (TRC_INDICATION_SERVICE_INTERNAL,
 240                                              Tracer::LEVEL2,
 241                                              "Provider (" + provider.getPath().toString() +
 242                                              ") not found in list for Subscription (" +
 243 carolann.graves 1.10                         activeSubscriptionsKey.toString () +
 244 carolann.graves 1.9                          ") in ActiveSubscriptionsTable");
 245 kumpf           1.1                  }
 246                                  }
 247                                  else
 248                                  {
 249                                      PEG_TRACE_STRING (TRC_INDICATION_SERVICE_INTERNAL, 
 250 carolann.graves 1.9                      Tracer::LEVEL2,
 251 carolann.graves 1.10                     "Subscription (" + activeSubscriptionsKey.toString () +
 252 carolann.graves 1.9                      ") not found in ActiveSubscriptionsTable");
 253                                      //
 254                                      //  The subscription may have been deleted in the mean time
 255                                      //  If so, no further update is required
 256                                      //
 257 kumpf           1.1              }
 258                              }
 259                          }
 260                      
 261                          PEG_METHOD_EXIT ();
 262                          return providerSubscriptions;
 263                      }
 264                      
 265 carolann.graves 1.12 Array <ActiveSubscriptionsTableEntry>
 266                      SubscriptionTable::reflectProviderModuleFailure
 267                          (const String & moduleName,
 268                           const String & userName,
 269                           Boolean authenticationEnabled)
 270                      {
 271                          PEG_METHOD_ENTER (TRC_INDICATION_SERVICE,
 272                              "SubscriptionTable::reflectProviderModuleFailure");
 273                      
 274                          Array <ActiveSubscriptionsTableEntry> providerModuleSubscriptions;
 275                      
 276                          //
 277                          //  Iterate through the subscription table to find subscriptions served by
 278                          //  a provider in the specified module, with the specified userName as the
 279                          //  subscription creator
 280                          //  NOTE: updating entries (remove and insert) while iterating through the
 281                          //  table is not allowed
 282                          //  The SubscriptionTable first iterates through the active subscriptions
 283                          //  table to find matching subscriptions served by a provider in the
 284                          //  specified module, then looks up and updates each affected subscription
 285                          //
 286 carolann.graves 1.12     {
 287                              //
 288                              //  Acquire and hold the write lock during the entire
 289                              //  lookup/remove/insert process, allowing competing threads to apply
 290                              //  their logic over a consistent view of the data.
 291                              //  Do not call any other methods that need 
 292                              //  _activeSubscriptionsTableLock.
 293                              //
 294                              WriteLock lock (_activeSubscriptionsTableLock);
 295                      
 296                              for (ActiveSubscriptionsTable::Iterator i =
 297                                  _activeSubscriptionsTable.start (); i; i++)
 298                              {
 299                                  ActiveSubscriptionsTableEntry tableValue;
 300                                  //
 301                                  //  Get subscription creator
 302                                  //
 303                                  tableValue = i.value ();
 304                                  String creator;
 305                                  CIMValue creatorValue = tableValue.subscription.getProperty
 306                                      (tableValue.subscription.findProperty
 307 carolann.graves 1.12                 (PEGASUS_PROPERTYNAME_INDSUB_CREATOR)).getValue();
 308                                  creatorValue.get (creator);
 309                      
 310                                  Array <ProviderClassList> failedProviderList;
 311                                  for (Uint32 j = 0; j < tableValue.providers.size (); j++)
 312                                  {
 313                                      //
 314                                      //  Get provider module name
 315                                      //
 316                                      String providerModuleName;
 317                                      CIMValue nameValue =
 318                                          tableValue.providers [j].providerModule.getProperty
 319                                          (tableValue.providers [j].providerModule.findProperty
 320 w.otsuka        1.13                     (PEGASUS_PROPERTYNAME_NAME)).getValue ();
 321 carolann.graves 1.12                 nameValue.get (providerModuleName);
 322                      
 323                                      //
 324                                      //  Get module user context setting
 325                                      //
 326                                      Uint16 moduleContext = PEGASUS_DEFAULT_PROV_USERCTXT;
 327                                      CIMValue contextValue = 
 328                                          tableValue.providers [j].providerModule.getProperty
 329                                          (tableValue.providers [j].providerModule.findProperty
 330                                          (PEGASUS_PROPERTYNAME_MODULE_USERCONTEXT)).getValue ();
 331                                      if (!contextValue.isNull ())
 332                                      {
 333                                          contextValue.get (moduleContext);
 334                                      }
 335                      
 336                                      //
 337                                      //  If provider module name matches, 
 338                                      //  add provider to the list of failed providers
 339                                      //
 340                                      if (providerModuleName == moduleName)
 341                                      {
 342 carolann.graves 1.12                     //
 343                                          //  If authentication is enabled, and module was run as
 344                                          //  requestor, subscription creator must also match module
 345                                          //  user context name, to add provider to the list of
 346                                          //  failed providers
 347                                          //
 348                                          if ((moduleContext != PG_PROVMODULE_USERCTXT_REQUESTOR) ||
 349                                              (!authenticationEnabled) || (creator == userName))
 350                                          {
 351                                              //
 352                                              //  Add the provider to the list
 353                                              //
 354                                              failedProviderList.append
 355                                                  (tableValue.providers [j]);
 356                                          }
 357                                      }  //  if provider module name matches
 358                                  }  //  for each subscription provider
 359                      
 360                                  //
 361                                  //  If there were any failed providers, add the subscription
 362                                  //  entry to the list of affected subscriptions
 363 carolann.graves 1.12             //
 364                                  if (failedProviderList.size () > 0)
 365                                  {
 366                                      ActiveSubscriptionsTableEntry subscription;
 367                                      subscription.subscription = tableValue.subscription;
 368                                      subscription.providers = failedProviderList;
 369                                      providerModuleSubscriptions.append (subscription);
 370                                  }
 371                              }
 372                      
 373                              //
 374                              //  Look up and update hash table entry for each affected subscription
 375                              //
 376                              for (Uint32 k = 0; k < providerModuleSubscriptions.size (); k++)
 377                              {
 378                                  //
 379                                  //  Update the entry in the active subscriptions hash table
 380                                  //
 381                                  CIMObjectPath activeSubscriptionsKey =
 382                                      _generateActiveSubscriptionsKey
 383                                          (providerModuleSubscriptions [k].subscription.getPath ());
 384 carolann.graves 1.12             ActiveSubscriptionsTableEntry tableValue;
 385                                  if (_activeSubscriptionsTable.lookup (activeSubscriptionsKey,
 386                                      tableValue))
 387                                  {
 388                                      Array <ProviderClassList> updatedProviderList;    
 389                                      for (Uint32 l = 0; l < tableValue.providers.size (); l++)
 390                                      {
 391                                          String providerModuleName;
 392                                          CIMValue nameValue =
 393                                              tableValue.providers [l].providerModule.getProperty
 394                                              (tableValue.providers [l].providerModule.findProperty
 395 w.otsuka        1.13                         (PEGASUS_PROPERTYNAME_NAME)).getValue ();
 396 carolann.graves 1.12                     nameValue.get (providerModuleName);
 397                                          if (providerModuleName != moduleName)
 398                                          {
 399                                              //
 400                                              //  Provider is not in the failed module
 401                                              //  Append provider to list of providers still serving
 402                                              //  the subscription
 403                                              //
 404                                              updatedProviderList.append (tableValue.providers [l]);
 405                                          }
 406                                      }
 407                      
 408                                      _updateSubscriptionProviders (activeSubscriptionsKey,
 409                                          tableValue.subscription, updatedProviderList);
 410                                  }
 411                              }
 412                          }
 413                      
 414                          PEG_METHOD_EXIT ();
 415                          return providerModuleSubscriptions;
 416                      }
 417 carolann.graves 1.12 
 418 carolann.graves 1.10 CIMObjectPath SubscriptionTable::_generateActiveSubscriptionsKey (
 419 kumpf           1.1      const CIMObjectPath & subscription) const
 420                      {
 421                          //
 422 carolann.graves 1.10     //  Get filter and handler object paths from subscription Filter and Handler
 423                          //  reference property values
 424 kumpf           1.1      //
 425                          Array<CIMKeyBinding> subscriptionKB = subscription.getKeyBindings ();
 426 carolann.graves 1.10     CIMObjectPath filterPath;
 427                          CIMObjectPath handlerPath;
 428 kumpf           1.1      for (Uint32 i = 0; i < subscriptionKB.size (); i++)
 429                          {
 430 w.otsuka        1.13         if ((subscriptionKB [i].getName () == PEGASUS_PROPERTYNAME_FILTER) &&
 431 kumpf           1.1              (subscriptionKB [i].getType () == CIMKeyBinding::REFERENCE))
 432                              {
 433 carolann.graves 1.10             filterPath = subscriptionKB [i].getValue ();
 434 kumpf           1.1          }
 435 w.otsuka        1.13         if ((subscriptionKB [i].getName () == PEGASUS_PROPERTYNAME_HANDLER) &&
 436 kumpf           1.1              (subscriptionKB [i].getType () == CIMKeyBinding::REFERENCE))
 437                              {
 438 carolann.graves 1.10             handlerPath = subscriptionKB [i].getValue ();
 439 kumpf           1.1          }
 440                          }
 441                      
 442                          //
 443 carolann.graves 1.10     //  Construct subscription object name for key
 444 kumpf           1.1      //
 445 carolann.graves 1.10     filterPath.setHost (String::EMPTY);
 446                          handlerPath.setHost (String::EMPTY);
 447                          Array <CIMKeyBinding> kb;
 448 w.otsuka        1.13     kb.append (CIMKeyBinding (PEGASUS_PROPERTYNAME_FILTER, CIMValue (filterPath)));
 449                          kb.append (CIMKeyBinding (PEGASUS_PROPERTYNAME_HANDLER, CIMValue (handlerPath)));
 450 carolann.graves 1.10     CIMObjectPath activeSubscriptionsKey ("", subscription.getNameSpace (),
 451                              subscription.getClassName (), kb);
 452 kumpf           1.1  
 453                          return activeSubscriptionsKey;
 454                      }
 455                      
 456                      Boolean SubscriptionTable::_lockedLookupActiveSubscriptionsEntry (
 457 carolann.graves 1.10     const CIMObjectPath & key,
 458 aruran.ms       1.7      ActiveSubscriptionsTableEntry & tableEntry) const
 459 kumpf           1.1  {
 460                          ReadLock lock(_activeSubscriptionsTableLock);
 461                      
 462                          return (_activeSubscriptionsTable.lookup (key, tableEntry));
 463                      }
 464                      
 465                      void SubscriptionTable::_insertActiveSubscriptionsEntry (
 466                          const CIMInstance & subscription,
 467 aruran.ms       1.8      const Array <ProviderClassList> & providers)
 468 kumpf           1.1  {
 469                          PEG_METHOD_ENTER (TRC_INDICATION_SERVICE,
 470                              "SubscriptionTable::_insertActiveSubscriptionsEntry");
 471                      
 472 carolann.graves 1.10     CIMObjectPath activeSubscriptionsKey = _generateActiveSubscriptionsKey
 473 kumpf           1.1          (subscription.getPath ());
 474                          ActiveSubscriptionsTableEntry entry;
 475                          entry.subscription = subscription;
 476                          entry.providers = providers;
 477                      
 478 carolann.graves 1.10     //
 479                          //  Insert returns true on success, false if duplicate key
 480                          //
 481                          Boolean succeeded = _activeSubscriptionsTable.insert
 482                              (activeSubscriptionsKey, entry);
 483                          PEGASUS_ASSERT (succeeded);
 484 kumpf           1.1  
 485                      #ifdef PEGASUS_INDICATION_HASHTRACE
 486                          String traceString;
 487                          traceString.append (activeSubscriptionsKey);
 488                          traceString.append (" Providers: ");
 489                          for (Uint32 i = 0; i < providers.size (); i++)
 490                          {
 491 carolann.graves 1.9          String providerName = providers [i].provider.getProperty
 492                                  (providers [i].provider.findProperty
 493 w.otsuka        1.13             (PEGASUS_PROPERTYNAME_NAME)).getValue ().toString ();
 494 kumpf           1.1          traceString.append (providerName);
 495                              traceString.append ("  Classes: ");
 496                              for (Uint32 j = 0; j < providers[i].classList.size (); j++)
 497                              {
 498 carolann.graves 1.9               traceString.append (providers[i].classList[j].getString());
 499 kumpf           1.1               traceString.append ("  ");
 500                              }
 501                          }
 502 carolann.graves 1.9  
 503                          PEG_TRACE_STRING (TRC_INDICATION_SERVICE_INTERNAL, Tracer::LEVEL3,
 504 kumpf           1.1          "INSERTED _activeSubscriptionsTable entry: " + traceString);
 505                      #endif
 506                      
 507                          PEG_METHOD_EXIT ();
 508                      }
 509                      
 510                      void SubscriptionTable::_removeActiveSubscriptionsEntry (
 511 carolann.graves 1.10     const CIMObjectPath & key)
 512 kumpf           1.1  {
 513                          PEG_METHOD_ENTER (TRC_INDICATION_SERVICE,
 514                              "SubscriptionTable::_removeActiveSubscriptionsEntry");
 515                      
 516 carolann.graves 1.10     //
 517                          //  Remove returns true on success, false if not found
 518                          //
 519                          Boolean succeeded = _activeSubscriptionsTable.remove (key);
 520                          PEGASUS_ASSERT (succeeded);
 521                      
 522 kumpf           1.1  #ifdef PEGASUS_INDICATION_HASHTRACE
 523 carolann.graves 1.9      PEG_TRACE_STRING (TRC_INDICATION_SERVICE_INTERNAL,
 524                                            Tracer::LEVEL3,
 525 carolann.graves 1.10                       "REMOVED _activeSubscriptionsTable entry: " +
 526                                            key.toString ());
 527 kumpf           1.1  #endif
 528                      
 529                          PEG_METHOD_EXIT ();
 530                      }
 531                      
 532                      String SubscriptionTable::_generateSubscriptionClassesKey (
 533                          const CIMName & indicationClassName,
 534                          const CIMNamespaceName & sourceNamespaceName) const
 535                      {
 536                          String subscriptionClassesKey;
 537                      
 538                          //
 539                          //  Append indication class name to key
 540                          //
 541                          subscriptionClassesKey.append (indicationClassName.getString ());
 542                      
 543                          //
 544                          //  Append source namespace name to key
 545                          //
 546                          subscriptionClassesKey.append (sourceNamespaceName.getString ());
 547                      
 548 kumpf           1.1      return subscriptionClassesKey;
 549                      }
 550                      
 551                      Boolean SubscriptionTable::_lockedLookupSubscriptionClassesEntry (
 552                          const String & key,
 553 aruran.ms       1.7      SubscriptionClassesTableEntry & tableEntry) const
 554 kumpf           1.1  {
 555                          ReadLock lock(_subscriptionClassesTableLock);
 556                      
 557                          return (_subscriptionClassesTable.lookup (key, tableEntry));
 558                      }
 559                      
 560 carolann.graves 1.9  void SubscriptionTable::_insertSubscriptionClassesEntry (
 561 kumpf           1.1      const CIMName & indicationClassName,
 562                          const CIMNamespaceName & sourceNamespaceName,
 563                          const Array <CIMInstance> & subscriptions)
 564                      {
 565                          PEG_METHOD_ENTER (TRC_INDICATION_SERVICE,
 566 carolann.graves 1.9          "SubscriptionTable::_insertSubscriptionClassesEntry");
 567 kumpf           1.1  
 568                          String subscriptionClassesKey = _generateSubscriptionClassesKey
 569                              (indicationClassName, sourceNamespaceName);
 570                          SubscriptionClassesTableEntry entry;
 571                          entry.indicationClassName = indicationClassName;
 572                          entry.sourceNamespaceName = sourceNamespaceName;
 573                          entry.subscriptions = subscriptions;
 574 carolann.graves 1.9  
 575 carolann.graves 1.10     //
 576                          //  Insert returns true on success, false if duplicate key
 577                          //
 578                          Boolean succeeded = _subscriptionClassesTable.insert
 579                              (subscriptionClassesKey, entry);
 580                          PEGASUS_ASSERT (succeeded);
 581 kumpf           1.1  
 582                      #ifdef PEGASUS_INDICATION_HASHTRACE
 583                          String traceString;
 584                          traceString.append (subscriptionClassesKey);
 585                          traceString.append (" Subscriptions: ");
 586                          for (Uint32 i = 0; i < subscriptions.size (); i++)
 587                          {
 588 carolann.graves 1.9          traceString.append (subscriptions [i].getPath ().toString());
 589 kumpf           1.1          traceString.append ("  ");
 590                          }
 591 carolann.graves 1.9  
 592                          PEG_TRACE_STRING (TRC_INDICATION_SERVICE_INTERNAL, Tracer::LEVEL3,
 593 kumpf           1.1          "INSERTED _subscriptionClassesTable entry: " + traceString);
 594                      #endif
 595                      
 596                          PEG_METHOD_EXIT ();
 597                      }
 598                      
 599 carolann.graves 1.9  void SubscriptionTable::_removeSubscriptionClassesEntry (
 600 kumpf           1.1      const String & key)
 601                      {
 602                          PEG_METHOD_ENTER (TRC_INDICATION_SERVICE,
 603 carolann.graves 1.9          "SubscriptionTable::_removeSubscriptionClassesEntry");
 604 kumpf           1.1  
 605 carolann.graves 1.10     //
 606                          //  Remove returns true on success, false if not found
 607                          //
 608                          Boolean succeeded = _subscriptionClassesTable.remove (key);
 609                          PEGASUS_ASSERT (succeeded);
 610 kumpf           1.1  
 611                      #ifdef PEGASUS_INDICATION_HASHTRACE
 612 carolann.graves 1.9      PEG_TRACE_STRING (TRC_INDICATION_SERVICE_INTERNAL, Tracer::LEVEL3,
 613 kumpf           1.1          "REMOVED _subscriptionClassesTable entry: " + key);
 614                      #endif
 615                      
 616                          PEG_METHOD_EXIT ();
 617                      }
 618                      
 619 carolann.graves 1.12 void SubscriptionTable::_updateSubscriptionProviders
 620                          (const CIMObjectPath & activeSubscriptionsKey,
 621                           const CIMInstance & subscription,
 622                           const Array <ProviderClassList> & updatedProviderList)
 623                      {
 624                          PEG_METHOD_ENTER (TRC_INDICATION_SERVICE,
 625                              "SubscriptionTable::_updateSubscriptionProviders");
 626                      
 627                          if (updatedProviderList.size () > 0)
 628                          {
 629                              //
 630                              //  At least one provider is still serving the
 631                              //  subscription
 632                              //  Update entry in Active Subscriptions table
 633                              //
 634                              _removeActiveSubscriptionsEntry (activeSubscriptionsKey);
 635                              _insertActiveSubscriptionsEntry (subscription, updatedProviderList);
 636                          }
 637                          else
 638                          {
 639                              //
 640 carolann.graves 1.12         //  The disabled or failed provider(s) was (were) the only provider(s)
 641                              //  serving the subscription
 642                              //  Implement the subscription's On Fatal Error Policy
 643                              //
 644                              Boolean removedOrDisabled =
 645                                  _subscriptionRepository->reconcileFatalError (subscription);
 646                              _removeActiveSubscriptionsEntry (activeSubscriptionsKey);
 647                              if (!removedOrDisabled)
 648                              {
 649                                  //
 650                                  //  If subscription was not disabled or deleted
 651                                  //  Update entry in Active Subscriptions table
 652                                  //  Note that in this case the updatedProviderList is
 653                                  //  empty - no providers are serving the subscription
 654                                  //  currently
 655                                  //
 656                                  _insertActiveSubscriptionsEntry (subscription,
 657                                      updatedProviderList);
 658                              }
 659                          }
 660                      
 661 carolann.graves 1.12     PEG_METHOD_EXIT ();
 662                      }
 663                      
 664 carolann.graves 1.6  void SubscriptionTable::insertSubscription (
 665 kumpf           1.1      const CIMInstance & subscription,
 666                          const Array <ProviderClassList> & providers,
 667                          const Array <CIMName> & indicationSubclassNames,
 668                          const CIMNamespaceName & sourceNamespaceName)
 669                      {
 670                          PEG_METHOD_ENTER (TRC_INDICATION_SERVICE,
 671                              "SubscriptionTable::insertSubscription");
 672                      
 673                          //
 674 carolann.graves 1.9      //  Insert entry into active subscriptions table
 675 kumpf           1.1      //
 676                          {
 677                              WriteLock lock(_activeSubscriptionsTableLock);
 678                      
 679                              _insertActiveSubscriptionsEntry (subscription, providers);
 680                          }
 681                      
 682                          //
 683 carolann.graves 1.9      //  Insert or update entries in subscription classes table
 684 kumpf           1.1      //
 685                          {
 686 carolann.graves 1.9          //
 687                              //  Acquire and hold the write lock during the entire
 688                              //  lookup/remove/insert process, allowing competing threads to apply
 689                              //  their logic over a consistent view of the data.
 690                              //  Do not call any other methods that need 
 691                              //  _subscriptionClassesTableLock.
 692                              //
 693                              WriteLock lock (_subscriptionClassesTableLock);
 694                              for (Uint32 i = 0; i < indicationSubclassNames.size (); i++)
 695 kumpf           1.1          {
 696 carolann.graves 1.9              String subscriptionClassesKey = _generateSubscriptionClassesKey
 697                                      (indicationSubclassNames [i], sourceNamespaceName);
 698                                  SubscriptionClassesTableEntry tableValue;
 699                                  if (_subscriptionClassesTable.lookup (subscriptionClassesKey,
 700                                      tableValue))
 701                                  {
 702                                      //
 703                                      //  If entry exists for this IndicationClassName-SourceNamespace
 704                                      //  pair, remove old entry and insert new entry
 705                                      //
 706                                      Array <CIMInstance> subscriptions = tableValue.subscriptions;
 707                                      subscriptions.append (subscription);
 708                                      _removeSubscriptionClassesEntry (subscriptionClassesKey);
 709                                      _insertSubscriptionClassesEntry (indicationSubclassNames [i],
 710                                          sourceNamespaceName, subscriptions);
 711                                  }
 712                                  else
 713                                  {
 714                                      //
 715                                      //  If no entry exists for this
 716                                      //  IndicationClassName-SourceNamespace pair, insert new entry
 717 carolann.graves 1.9                  //
 718                                      Array <CIMInstance> subscriptions;
 719                                      subscriptions.append (subscription);
 720                                      _insertSubscriptionClassesEntry (indicationSubclassNames [i],
 721                                          sourceNamespaceName, subscriptions);
 722                                  }
 723 kumpf           1.1          }
 724                          }
 725                      
 726                          PEG_METHOD_EXIT ();
 727                      }
 728                      
 729 carolann.graves 1.6  void SubscriptionTable::updateProviders (
 730 kumpf           1.1      const CIMObjectPath & subscriptionPath,
 731                          const ProviderClassList & provider,
 732                          Boolean addProvider)
 733                      {
 734                          PEG_METHOD_ENTER (TRC_INDICATION_SERVICE,
 735                              "SubscriptionTable::updateProviders");
 736                      
 737 carolann.graves 1.10     CIMObjectPath activeSubscriptionsKey = _generateActiveSubscriptionsKey
 738 kumpf           1.1          (subscriptionPath);
 739                          ActiveSubscriptionsTableEntry tableValue;
 740                          {
 741 carolann.graves 1.9          //
 742                              //  Acquire and hold the write lock during the entire
 743                              //  lookup/remove/insert process, allowing competing threads to apply
 744                              //  their logic over a consistent view of the data.
 745                              //  Do not call any other methods that need 
 746                              //  _activeSubscriptionsTableLock.
 747                              //
 748                              WriteLock lock (_activeSubscriptionsTableLock);
 749                              if (_activeSubscriptionsTable.lookup (activeSubscriptionsKey,
 750                                  tableValue))
 751 kumpf           1.1          {
 752 carolann.graves 1.9              Uint32 providerIndex = providerInList (provider.provider, 
 753                                      tableValue);
 754                                  if (addProvider)
 755 kumpf           1.1              {
 756 carolann.graves 1.9                  if (providerIndex == PEG_NOT_FOUND)
 757                                      {
 758                                          tableValue.providers.append (provider);
 759                                          _removeActiveSubscriptionsEntry (activeSubscriptionsKey);
 760                                          _insertActiveSubscriptionsEntry (tableValue.subscription,
 761                                              tableValue.providers);
 762                                      }
 763                                      else
 764                                      {
 765                                          CIMInstance p = provider.provider;
 766                                          PEG_TRACE_STRING (TRC_INDICATION_SERVICE_INTERNAL,
 767                                              Tracer::LEVEL2,
 768                                              "Provider " + 
 769                                              IndicationService::getProviderLogString (p) +
 770                                              " already in list for Subscription (" +
 771 carolann.graves 1.10                         activeSubscriptionsKey.toString () +
 772 carolann.graves 1.9                          ") in ActiveSubscriptionsTable");
 773                                      }
 774 kumpf           1.1              }
 775                                  else
 776                                  {
 777 carolann.graves 1.9                  if (providerIndex != PEG_NOT_FOUND)
 778                                      {
 779                                          tableValue.providers.remove (providerIndex);
 780                                          _removeActiveSubscriptionsEntry (activeSubscriptionsKey);
 781                                          _insertActiveSubscriptionsEntry (tableValue.subscription,
 782                                              tableValue.providers);
 783                                      }
 784                                      else
 785                                      {
 786                                          CIMInstance p = provider.provider;
 787                                          PEG_TRACE_STRING (TRC_INDICATION_SERVICE_INTERNAL,
 788                                              Tracer::LEVEL2,
 789                                              "Provider " + 
 790                                              IndicationService::getProviderLogString (p) +
 791                                              " not found in list for Subscription (" +
 792 carolann.graves 1.10                         activeSubscriptionsKey.toString () +
 793 carolann.graves 1.9                          ") in ActiveSubscriptionsTable");
 794                                      }
 795 kumpf           1.1              }
 796                              }
 797                              else
 798                              {
 799 carolann.graves 1.9              PEG_TRACE_STRING (TRC_INDICATION_SERVICE_INTERNAL, Tracer::LEVEL2,
 800 carolann.graves 1.10                 "Subscription (" + activeSubscriptionsKey.toString () +
 801 carolann.graves 1.9                  ") not found in ActiveSubscriptionsTable");
 802                          
 803                                  //
 804                                  //  The subscription may have been deleted in the mean time
 805                                  //  If so, no further update is required
 806                                  //
 807 kumpf           1.1          }
 808                          }
 809                      
 810                          PEG_METHOD_EXIT ();
 811                      }
 812                      
 813                      void SubscriptionTable::updateClasses (
 814                          const CIMObjectPath & subscriptionPath,
 815                          const CIMInstance & provider,
 816                          const CIMName & className)
 817                      {
 818                          PEG_METHOD_ENTER (TRC_INDICATION_SERVICE,
 819                              "SubscriptionTable::updateClasses");
 820                      
 821 carolann.graves 1.10     CIMObjectPath activeSubscriptionsKey = _generateActiveSubscriptionsKey
 822 kumpf           1.1          (subscriptionPath);
 823                          ActiveSubscriptionsTableEntry tableValue;
 824                      
 825                          {
 826 carolann.graves 1.9          //
 827                              //  Acquire and hold the write lock during the entire
 828                              //  lookup/remove/insert process, allowing competing threads to apply
 829                              //  their logic over a consistent view of the data.
 830                              //  Do not call any other methods that need 
 831                              //  _activeSubscriptionsTableLock.
 832                              //
 833                              WriteLock lock (_activeSubscriptionsTableLock);
 834                              if (_activeSubscriptionsTable.lookup (activeSubscriptionsKey, 
 835                                  tableValue))
 836 kumpf           1.1          {
 837 carolann.graves 1.9              Uint32 providerIndex = providerInList (provider, tableValue);
 838                                  if (providerIndex != PEG_NOT_FOUND)
 839 kumpf           1.1              {
 840 carolann.graves 1.9                  Uint32 classIndex = classInList (className,
 841                                          tableValue.providers [providerIndex]);
 842                                      if (classIndex == PEG_NOT_FOUND)
 843                                      {
 844                                          tableValue.providers [providerIndex].classList.append
 845                                              (className);
 846                                      }
 847                                      else //  classIndex != PEG_NOT_FOUND
 848                                      {
 849                                          tableValue.providers [providerIndex].classList.remove
 850                                              (classIndex);
 851                                      }
 852                      
 853                                      _removeActiveSubscriptionsEntry (activeSubscriptionsKey);
 854                                      _insertActiveSubscriptionsEntry (tableValue.subscription,
 855                                          tableValue.providers);
 856 kumpf           1.1              }
 857 carolann.graves 1.9              else
 858 kumpf           1.1              {
 859 carolann.graves 1.9                  PEG_TRACE_STRING (TRC_INDICATION_SERVICE_INTERNAL, 
 860                                          Tracer::LEVEL2,
 861                                          "Provider (" + provider.getPath ().toString () +
 862                                          ") not found in list for Subscription (" +
 863 carolann.graves 1.10                     activeSubscriptionsKey.toString () +
 864 carolann.graves 1.9                      ") in ActiveSubscriptionsTable");
 865 kumpf           1.1              }
 866                              }
 867                              else
 868                              {
 869 carolann.graves 1.9              //
 870                                  //  Subscription not found in Active Subscriptions table
 871                                  //
 872 kumpf           1.1          }
 873                          }
 874                      
 875                          PEG_METHOD_EXIT ();
 876                      }
 877                      
 878 carolann.graves 1.6  void SubscriptionTable::removeSubscription (
 879 kumpf           1.1      const CIMInstance & subscription,
 880                          const Array <CIMName> & indicationSubclassNames,
 881                          const CIMNamespaceName & sourceNamespaceName,
 882                          const Array <ProviderClassList> & providers)
 883                      {
 884                          PEG_METHOD_ENTER (TRC_INDICATION_SERVICE,
 885                              "SubscriptionTable::removeSubscription");
 886                      
 887                          //
 888 carolann.graves 1.9      //  Remove entry from active subscriptions table
 889 kumpf           1.1      //
 890                          {
 891                              WriteLock lock(_activeSubscriptionsTableLock);
 892                      
 893                              _removeActiveSubscriptionsEntry (
 894                                  _generateActiveSubscriptionsKey (subscription.getPath ()));
 895                          }
 896                      
 897                          //
 898 carolann.graves 1.9      //  Remove or update entries in subscription classes table
 899 kumpf           1.1      //
 900                          {
 901 carolann.graves 1.9          //
 902                              //  Acquire and hold the write lock during the entire
 903                              //  lookup/remove/insert process, allowing competing threads to apply
 904                              //  their logic over a consistent view of the data.
 905                              //  Do not call any other methods that need 
 906                              //  _subscriptionClassesTableLock.
 907                              //
 908                              WriteLock lock (_subscriptionClassesTableLock);
 909                              for (Uint32 i = 0; i < indicationSubclassNames.size (); i++)
 910 kumpf           1.1          {
 911 carolann.graves 1.9              String subscriptionClassesKey = _generateSubscriptionClassesKey
 912                                      (indicationSubclassNames [i], sourceNamespaceName);
 913                                  SubscriptionClassesTableEntry tableValue;
 914                                  if (_subscriptionClassesTable.lookup (subscriptionClassesKey,
 915                                      tableValue))
 916                                  {
 917                                      //
 918                                      //  If entry exists for this IndicationClassName-SourceNamespace
 919                                      //  pair, remove subscription from the list
 920                                      //
 921                                      Array <CIMInstance> subscriptions = tableValue.subscriptions;
 922                                      for (Uint32 j = 0; j < subscriptions.size (); j++)
 923                                      {
 924                                          if (subscriptions [j].getPath().identical
 925                                             (subscription.getPath()))
 926                                          {
 927                                              subscriptions.remove (j);
 928                                          }
 929                                      }
 930                          
 931                                      //
 932 carolann.graves 1.9                  //  Remove the old entry
 933                                      //
 934                                      _removeSubscriptionClassesEntry (subscriptionClassesKey);
 935                          
 936                                      //
 937                                      //  If there are still subscriptions in the list, insert the
 938                                      //  new entry
 939                                      //
 940                                      if (subscriptions.size () > 0)
 941 kumpf           1.1                  {
 942 carolann.graves 1.9                      _insertSubscriptionClassesEntry (
 943                                              indicationSubclassNames [i],
 944                                              sourceNamespaceName, subscriptions);
 945 kumpf           1.1                  }
 946                                  }
 947 carolann.graves 1.9              else
 948 kumpf           1.1              {
 949 carolann.graves 1.9                  //
 950                                      //  Entry not found in Subscription Classes table
 951                                      //
 952                                      PEG_TRACE_STRING (TRC_INDICATION_SERVICE_INTERNAL, 
 953                                          Tracer::LEVEL2,
 954                                          "Indication subclass and namespace (" + 
 955                                          subscriptionClassesKey +
 956                                          ") not found in SubscriptionClassesTable");
 957 kumpf           1.1              }
 958                              }
 959                          }
 960                      
 961                          PEG_METHOD_EXIT ();
 962                      }
 963                      
 964 carolann.graves 1.9  Uint32 SubscriptionTable::providerInList
 965                          (const CIMInstance & provider,
 966 kumpf           1.1       const ActiveSubscriptionsTableEntry & tableValue) const
 967                      {
 968                          PEG_METHOD_ENTER (TRC_INDICATION_SERVICE,
 969                              "SubscriptionTable::providerInList");
 970                      
 971                          //
 972                          //  Look for the provider in the list
 973                          //
 974                          for (Uint32 i = 0; i < tableValue.providers.size (); i++)
 975                          {
 976 carolann.graves 1.9          if (tableValue.providers [i].provider.getPath ().identical
 977 kumpf           1.1              (provider.getPath ()))
 978                              {
 979 gs.keenan       1.4              PEG_METHOD_EXIT ();
 980 kumpf           1.1              return i;
 981                              }
 982                          }
 983                      
 984 gs.keenan       1.4      PEG_METHOD_EXIT ();
 985 kumpf           1.1      return PEG_NOT_FOUND;
 986                      }
 987                      
 988                      
 989 carolann.graves 1.9  Uint32 SubscriptionTable::classInList
 990                          (const CIMName & className,
 991 kumpf           1.1       const ProviderClassList & providerClasses) const
 992                      {
 993                          PEG_METHOD_ENTER (TRC_INDICATION_SERVICE, "SubscriptionTable::classInList");
 994                      
 995                          //
 996                          //  Look for the class in the list
 997                          //
 998                          for (Uint32 i = 0; i < providerClasses.classList.size (); i++)
 999                          {
1000                              if (providerClasses.classList [i].equal (className))
1001                              {
1002 gs.keenan       1.4              PEG_METHOD_EXIT ();
1003 kumpf           1.1              return i;
1004                              }
1005                          }
1006                      
1007 gs.keenan       1.4      PEG_METHOD_EXIT ();
1008 kumpf           1.1      return PEG_NOT_FOUND;
1009                      }
1010                      
1011 kumpf           1.2  void SubscriptionTable::clear ()
1012                      {
1013                          PEG_METHOD_ENTER (TRC_INDICATION_SERVICE, "SubscriptionTable::clear");
1014                      
1015                          {
1016                              WriteLock lock (_activeSubscriptionsTableLock);
1017                              _activeSubscriptionsTable.clear ();
1018                          }
1019                          {
1020                              WriteLock lock (_subscriptionClassesTableLock);
1021                              _subscriptionClassesTable.clear ();
1022                          }
1023                      
1024                          PEG_METHOD_EXIT ();
1025                      }
1026                      
1027 kumpf           1.1  PEGASUS_NAMESPACE_END

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2