1 a.dunfey 1.1 //%2006////////////////////////////////////////////////////////////////////////
2 //
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 // IBM Corp.; EMC Corporation, The Open Group.
7 // Copyright (c) 2004 BMC Software; Hewlett-Packard Development Company, L.P.;
8 // IBM Corp.; EMC Corporation; VERITAS Software Corporation; The Open Group.
9 // Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.;
10 // EMC Corporation; VERITAS Software Corporation; The Open Group.
11 // Copyright (c) 2006 Hewlett-Packard Development Company, L.P.; IBM Corp.;
12 // EMC Corporation; Symantec Corporation; The Open Group.
13 //
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 a.dunfey 1.1 // 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
33 ///////////////////////////////////////////////////////////////////////////////
34 // Interop Provider - This provider services those classes from the
35 // DMTF Interop schema in an implementation compliant with the SMI-S v1.1
36 // Server Profile
37 //
38 // Please see PG_ServerProfile20.mof in the directory
39 // $(PEGASUS_ROOT)/Schemas/Pegasus/InterOp/VER20 for retails regarding the
40 // classes supported by this control provider.
41 //
42 // Interop forces all creates to the PEGASUS_NAMESPACENAME_INTEROP
43 a.dunfey 1.1 // namespace. There is a test on each operation that returns
44 // the Invalid Class CIMDError
45 // This is a control provider and as such uses the Tracer functions
46 // for data and function traces. Since we do not expect high volume
47 // use we added a number of traces to help diagnostics.
48 ///////////////////////////////////////////////////////////////////////////////
49
50 #include "InteropProvider.h"
51 #include "InteropProviderUtils.h"
52 #include "InteropConstants.h"
53
54 PEGASUS_USING_STD;
55 PEGASUS_NAMESPACE_BEGIN;
56
57 //
58 // Given the two references in the association, this function creates an
59 // instance of the PG_ElementConformsToProfile class.
60 //
61 CIMInstance buildElementConformsToProfile(
62 const CIMObjectPath & currentProfile,
63 const CIMObjectPath & currentElement,
64 a.dunfey 1.1 const CIMClass & elementConformsClass)
65 {
66 Array<CIMName> elementPropArray;
67 elementPropArray.append(
68 ELEMENTCONFORMSTOPROFILE_PROPERTY_CONFORMANTSTANDARD);
69 elementPropArray.append(
70 ELEMENTCONFORMSTOPROFILE_PROPERTY_MANAGEDELEMENT);
71 CIMPropertyList elementPropList(elementPropArray);
72
73 CIMInstance tmpInstance =
74 elementConformsClass.buildInstance(false, false,
75 elementPropList);
76 setPropertyValue(tmpInstance,
77 ELEMENTCONFORMSTOPROFILE_PROPERTY_CONFORMANTSTANDARD,
78 currentProfile);
79 setPropertyValue(tmpInstance,
80 ELEMENTCONFORMSTOPROFILE_PROPERTY_MANAGEDELEMENT,
81 currentElement);
82 tmpInstance.setPath(tmpInstance.buildPath(
83 elementConformsClass));
84 return tmpInstance;
85 a.dunfey 1.1 }
86
87 //
88 // Enumerates all of the ElementConformsToProfile association instances.
89 //
90 Array<CIMInstance> InteropProvider::enumElementConformsToProfileInstances(
91 const OperationContext & opContext, const CIMNamespaceName & opNamespace)
92 {
93 CIMClass elementConformsClass = repository->getClass(
94 PEGASUS_NAMESPACENAME_INTEROP,
95 PEGASUS_CLASSNAME_PG_ELEMENTCONFORMSTOPROFILE,
96 false, true, false);
97
98 AutoMutex holder(interopMut);
99 Array<CIMInstance> instances;
100 verifyCachedInfo();
101 // Loop through the cached profile Id's and related info about its
102 // conforming elements.
103 for(Uint32 i = 0, n = profileIds.size(); i < n; ++i)
104 {
105 String & profileId = profileIds[i];
106 a.dunfey 1.1 Array<CIMName> & elementList = conformingElements[i];
107 Array<CIMNamespaceName> & namespaceList = elementNamespaces[i];
108 Array<CIMObjectPath> conformingElementPaths;
109 for(Uint32 j = 0, m = elementList.size(); j < m; ++j)
110 {
111 CIMName & currentElement = elementList[j];
112 CIMNamespaceName & currentNamespace = namespaceList[j];
113
114 if(opNamespace == PEGASUS_NAMESPACENAME_INTEROP ||
115 opNamespace == currentNamespace)
116 {
117 String currentElementStr(currentElement.getString());
118 if(currentElementStr.find(PEGASUS_DYNAMIC) == 0)
119 {
120 // If the provider profile registration did not provide a
121 // list of conforming elements (presumably because there is
122 // no such definite list), then the provider is required
123 // to provide instances of ElementConformsToProfile in the
124 // vendor namespace, so we do not generate instances.
125 if(opNamespace != PEGASUS_NAMESPACENAME_INTEROP)
126 {
127 a.dunfey 1.1 continue;
128 }
129 CIMName subclassName(
130 currentElementStr.subString(PEGASUS_DYNAMIC_LEN));
131 Array<CIMInstance> elementConformsInstances =
132 cimomHandle.enumerateInstances(opContext,
133 currentNamespace, subclassName, true, false, false,
134 true, CIMPropertyList());
135
136 // Retrieve the Conforming Element
137 for(Uint32 k = 0, x = elementConformsInstances.size();
138 k < x; ++k)
139 {
140 CIMInstance & currentInstance =
141 elementConformsInstances[k];
142
143 // Make sure that the current instance points to the
144 // current profile ID.
145 CIMObjectPath profilePath =
146 getRequiredValue<CIMObjectPath>(
147 elementConformsInstances[k],
148 a.dunfey 1.1 ELEMENTCONFORMSTOPROFILE_PROPERTY_CONFORMANTSTANDARD);
149 const Array<CIMKeyBinding> & keys =
150 profilePath.getKeyBindings();
151 if(keys.size() != 1)
152 continue;
153 if(keys.size() == 1 && keys[0].getValue() == profileId)
154 {
155 conformingElementPaths.append(
156 getRequiredValue<CIMObjectPath>(
157 currentInstance,
158 ELEMENTCONFORMSTOPROFILE_PROPERTY_MANAGEDELEMENT));
159 }
160 }
161 }
162 else
163 {
164 // All of the instances of the current element in the
165 // corresponding namespace conform to the current profile.
166 Array<CIMObjectPath> paths =
167 cimomHandle.enumerateInstanceNames(opContext,
168 currentNamespace, currentElement);
169 a.dunfey 1.1 // Set the namespace in the paths just in case
170 for(Uint32 k = 0, x = paths.size();
171 k < x; ++k)
172 {
173 CIMObjectPath & curPath = paths[k];
174 curPath.setNameSpace(currentNamespace);
175 curPath.setHost(hostName);
176 }
177 conformingElementPaths.appendArray(paths);
178 }
179 }
180 }
181
182 // Create the object path for the RegisteredProfile using the given
183 // profileId.
184 CIMObjectPath profilePath = buildDependencyReference(
185 hostName, profileIds[i], PEGASUS_CLASSNAME_PG_REGISTEREDPROFILE);
186
187 // Build all of the ElementConformsToProfile instances for the current
188 // profile.
189 for(Uint32 k = 0, x = conformingElementPaths.size(); k < x; ++k)
190 a.dunfey 1.1 {
191 instances.append(buildElementConformsToProfile(profilePath,
192 conformingElementPaths[k], elementConformsClass));
193 }
194 }
195
196 // Now add the default instance: the association between the Server Profile
197 // and the ObjectManager (if we're in the Interop namespace)
198 if(opNamespace == PEGASUS_NAMESPACENAME_INTEROP)
199 {
200 // Build up the Object Path for the server profile
201 CIMObjectPath serverProfile = buildDependencyReference(hostName,
202 buildProfileInstanceId(SNIA_NAME, "Server", SNIA_VER_110),
203 PEGASUS_CLASSNAME_PG_REGISTEREDPROFILE);
204 // Retrieve the Object Manager instance
205 CIMInstance objManager = getObjectManagerInstance();
206
207 instances.append(buildElementConformsToProfile(serverProfile,
208 objManager.getPath(), elementConformsClass));
209 }
210
211 a.dunfey 1.1 return instances;
212 }
213
214
215 typedef Array<String> StringArray;
216
217 void InteropProvider::verifyCachedInfo()
218 {
219 // TBD: May need an algorithm to determine whether or not the information
220 // cached by the Interop Provider is out of date in some way. Until that
221 // can be created, then providers that are dynamically registered after
222 // the Server profile has already been traversed may not be properly
223 // reflected. Although this is a shortcoming, the current users of this
224 // functionality do not generally use dynamic registration as part of their
225 // installation procedures.
226 }
227
228 //
229 // Function that determines in which namespaces a provider supports a given
230 // class. This information is needed to properly implement the
231 // ElementConformsToProfile association.
232 a.dunfey 1.1 //
233 Array<String> findProviderNamespacesForElement(
234 const String & moduleName, const String & providerName,
235 const CIMName & elementClass, CIMRepository * repository,
236 Array<CIMInstance> & providerCapabilitiesInstances)
237 {
238 Array<CIMInstance> capabilities;
239 if(providerCapabilitiesInstances.size() == 0)
240 {
241 Array<CIMName> propList;
242 propList.append(PROVIDERCAPABILITIES_PROPERTY_PROVIDERMODULENAME);
243 propList.append(PROVIDERCAPABILITIES_PROPERTY_PROVIDERNAME);
244 propList.append(PROVIDERCAPABILITIES_PROPERTY_NAMESPACES);
245 propList.append(PROVIDERCAPABILITIES_PROPERTY_CLASSNAME);
246 capabilities = repository->enumerateInstancesForClass(
247 PEGASUS_NAMESPACENAME_INTEROP,
248 PEGASUS_CLASSNAME_PROVIDERCAPABILITIES, true, false, false);
249 }
250 else
251 {
252 capabilities = providerCapabilitiesInstances;
253 a.dunfey 1.1 }
254
255 for(Uint32 i = 0, n = capabilities.size(); i < n; ++i)
256 {
257 CIMInstance & currentCapabilities = capabilities[i];
258 Uint32 propIndex = currentCapabilities.findProperty(
259 PROVIDERCAPABILITIES_PROPERTY_PROVIDERMODULENAME);
260 PEGASUS_ASSERT(propIndex != PEG_NOT_FOUND);
261 String currentName;
262 currentCapabilities.getProperty(propIndex).getValue().get(
263 currentName);
264 if(currentName == moduleName)
265 {
266 propIndex = currentCapabilities.findProperty(
267 PROVIDERCAPABILITIES_PROPERTY_PROVIDERNAME);
268 PEGASUS_ASSERT(propIndex != PEG_NOT_FOUND);
269 currentCapabilities.getProperty(propIndex).getValue().get(
270 currentName);
271 if(currentName == providerName)
272 {
273 propIndex = currentCapabilities.findProperty(
274 a.dunfey 1.1 PROVIDERCAPABILITIES_PROPERTY_CLASSNAME);
275 PEGASUS_ASSERT(propIndex != PEG_NOT_FOUND);
276 currentCapabilities.getProperty(propIndex).getValue().get(
277 currentName);
278 if(elementClass.equal(CIMName(currentName)))
279 {
280 propIndex = currentCapabilities.findProperty(
281 PROVIDERCAPABILITIES_PROPERTY_NAMESPACES);
282 PEGASUS_ASSERT(propIndex != PEG_NOT_FOUND);
283 Array<String> namespaces;
284 currentCapabilities.getProperty(propIndex).getValue().get(
285 namespaces);
286 return namespaces;
287 }
288 }
289 }
290 }
291
292 throw PEGASUS_CIM_EXCEPTION(CIM_ERR_NOT_FOUND,
293 "Could not find provider capabilities registered for module " +
294 moduleName + ", provider " + providerName + ", and class " +
295 a.dunfey 1.1 elementClass.getString());
296 }
297
298 //
299 // Method that caches certain profile registration information. Specifically,
300 // information pertaining to the ElementConformsToProfofile association
301 // implementation is kept here.
302 //
303 void InteropProvider::cacheProfileRegistrationInfo()
304 {
305 Array<CIMInstance> instances;
306 Array<CIMInstance> providerCapabilitiesInstances;
307 // Retrieve all of the provider profile registration info
308 Array<CIMName> propList;
309 propList.append(CAPABILITIES_PROPERTY_PROVIDERMODULENAME);
310 propList.append(CAPABILITIES_PROPERTY_PROVIDERNAME);
311 propList.append(PROFILECAPABILITIES_PROPERTY_PROFILEVERSION);
312 propList.append(PROFILECAPABILITIES_PROPERTY_REGISTEREDPROFILE);
313 propList.append(PROFILECAPABILITIES_PROPERTY_OTHERREGISTEREDPROFILE);
314 propList.append(PROFILECAPABILITIES_PROPERTY_OTHERPROFILEORGANIZATION);
315 propList.append(PROFILECAPABILITIES_PROPERTY_CONFORMINGELEMENTS);
316 a.dunfey 1.1 Array<CIMInstance> providerProfileInstances =
317 repository->enumerateInstancesForClass(PEGASUS_NAMESPACENAME_INTEROP,
318 PEGASUS_CLASSNAME_PG_PROVIDERPROFILECAPABILITIES, true,
319 false, false, CIMPropertyList(propList));
320 CIMClass elementConformsClass = repository->getClass(
321 PEGASUS_NAMESPACENAME_INTEROP,
322 PEGASUS_CLASSNAME_PG_ELEMENTCONFORMSTOPROFILE,
323 false, true, false);
324 CIMClass registeredProfileClass = repository->getClass(
325 PEGASUS_NAMESPACENAME_INTEROP,
326 PEGASUS_CLASSNAME_PG_REGISTEREDPROFILE,
327 false, true, false);
328 Array<CIMInstance> capabilities;
329
330 // Loop through the provider profile info to determine what profiles are
331 // supported by what providers, and to build the ElementConformsToProfile
332 // associations.
333 for(Uint32 i = 0, n = providerProfileInstances.size(); i < n; ++i)
334 {
335 CIMInstance & currentProfileInstance = providerProfileInstances[i];
336 String moduleName = getRequiredValue<String>(currentProfileInstance,
337 a.dunfey 1.1 CAPABILITIES_PROPERTY_PROVIDERMODULENAME);
338 String providerName = getRequiredValue<String>(currentProfileInstance,
339 CAPABILITIES_PROPERTY_PROVIDERNAME);
340 String profileName;
341 Uint16 profileOrganization = 0;
342 String profileVersion;
343 String organizationName;
344 Array<String> profileNames; // Not going to use this info
345 Array<String> profileVersions; // Not going to use this info
346 Array<Uint16> profileOrganizations; // Not going to use this info
347 Array<String> profileOrganizationNames; // Not going to use this info
348 String profileId = extractProfileInfo(currentProfileInstance,
349 profileCapabilitiesClass,
350 registeredProfileClass,
351 profileName,
352 profileVersion,
353 profileOrganization,
354 organizationName,
355 profileNames,
356 profileVersions,
357 profileOrganizations,
358 a.dunfey 1.1 profileOrganizationNames,
359 true);
360 Uint32 propIndex = currentProfileInstance.findProperty(
361 PROFILECAPABILITIES_PROPERTY_CONFORMINGELEMENTS);
362
363 Array<CIMName> elementPropArray;
364 elementPropArray.append(
365 ELEMENTCONFORMSTOPROFILE_PROPERTY_CONFORMANTSTANDARD);
366 elementPropArray.append(
367 ELEMENTCONFORMSTOPROFILE_PROPERTY_MANAGEDELEMENT);
368 CIMPropertyList elementPropList(elementPropArray);
369
370 Array<CIMName> conformingElementsForProfile;
371 Array<CIMNamespaceName> elementNamespacesForProfile;
372
373 Array<String> elementClasses;
374 currentProfileInstance.getProperty(propIndex).getValue().get(
375 elementClasses);
376 //if(propIndex == PEG_NOT_FOUND)
377 if(elementClasses.size() == 0)
378 {
379 a.dunfey 1.1 // Get the namespaces in which this provider operates and trim down
380 // the list of capabilities instaces to just those that are related
381 // to this one.
382 String moduleName = getRequiredValue<String>(
383 currentProfileInstance,
384 CAPABILITIES_PROPERTY_PROVIDERMODULENAME);
385 String providerName = getRequiredValue<String>(
386 currentProfileInstance,
387 CAPABILITIES_PROPERTY_PROVIDERNAME);
388 if(capabilities.size() == 0)
389 {
390 Array<CIMName> propList;
391 propList.append(
392 PROVIDERCAPABILITIES_PROPERTY_PROVIDERMODULENAME);
393 propList.append(PROVIDERCAPABILITIES_PROPERTY_PROVIDERNAME);
394 propList.append(PROVIDERCAPABILITIES_PROPERTY_NAMESPACES);
395 propList.append(PROVIDERCAPABILITIES_PROPERTY_CLASSNAME);
396 capabilities = repository->enumerateInstancesForClass(
397 PEGASUS_NAMESPACENAME_INTEROP,
398 PEGASUS_CLASSNAME_PROVIDERCAPABILITIES, true, false,
399 false);
400 a.dunfey 1.1 }
401 Array<CIMInstance> capabilitiesForProvider;
402 Array<CIMNamespaceName> namespacesForProvider;
403 Array<CIMNameArray> subclassesForNamespace;
404 for(Uint32 j = 0, m = capabilities.size(); j < m; ++j)
405 {
406 CIMInstance & currentInstance = capabilities[j];
407 String curModuleName = getRequiredValue<String>(
408 currentInstance, CAPABILITIES_PROPERTY_PROVIDERMODULENAME);
409 String curProviderName = getRequiredValue<String>(
410 currentInstance, CAPABILITIES_PROPERTY_PROVIDERNAME);
411 if(curModuleName == moduleName &&
412 curProviderName == providerName)
413 {
414 CIMName currentClass(getRequiredValue<String>(
415 currentInstance,
416 PROVIDERCAPABILITIES_PROPERTY_CLASSNAME));
417 capabilitiesForProvider.append(currentInstance);
418 StringArray curNamespaces =
419 getRequiredValue<StringArray>(currentInstance,
420 PROVIDERCAPABILITIES_PROPERTY_NAMESPACES);
421 a.dunfey 1.1 Sint32 z = 0;
422 Sint32 y = curNamespaces.size();
423
424 // If one of the namespaces is Interop, then continue
425 bool interopNamespaceFound = false;
426 for(; z < y; ++z)
427 {
428 if(CIMNamespaceName(curNamespaces[z]) ==
429 PEGASUS_NAMESPACENAME_INTEROP)
430 {
431 interopNamespaceFound = true;
432 break;
433 }
434 }
435 if(interopNamespaceFound)
436 continue;
437
438 // See if the current namespaces are already listed
439 for(Sint32 z = 0, y = curNamespaces.size(); z < y; ++z)
440 {
441 Sint32 foundIndex = -1;
442 a.dunfey 1.1 CIMNamespaceName curNamespace = curNamespaces[z];
443 Uint32 k = 0;
444 Uint32 x = namespacesForProvider.size();
445 for(; k < x; ++k)
446 {
447 if(curNamespace == namespacesForProvider[k])
448 {
449 foundIndex = (Sint32)k;
450 break;
451 }
452 }
453 if(foundIndex == -1)
454 {
455 // Get all the subclasses of
456 // ElementConformsToProfile in the namespace and
457 // cache them.
458 foundIndex = namespacesForProvider.size();
459 Array<CIMName> subClasses =
460 repository->enumerateClassNames(curNamespace,
461 PEGASUS_CLASSNAME_CIM_ELEMENTCONFORMSTOPROFILE,
462 true);
463 a.dunfey 1.1 subClasses.append(
464 PEGASUS_CLASSNAME_CIM_ELEMENTCONFORMSTOPROFILE
465 );
466 namespacesForProvider.append(curNamespace);
467 subclassesForNamespace.append(subClasses);
468 }
469
470 // Now search to see if the current class is one of the
471 // subclasses in this namespace, and finally, if it is
472 // add it to the list
473 Array<CIMName> & subClasses =
474 subclassesForNamespace[foundIndex];
475 for(k = 0, x = subClasses.size(); k < x; ++k)
476 {
477 if(subClasses[k] == currentClass)
478 {
479 String dynamicElement = PEGASUS_DYNAMIC +
480 currentClass.getString();
481 conformingElementsForProfile.append(
482 dynamicElement);
483 elementNamespacesForProfile.append(
484 a.dunfey 1.1 curNamespace);
485 }
486 }
487 }
488 }
489 }
490 }
491 else
492 {
493 //Array<String> elementClasses;
494 //currentProfileInstance.getProperty(propIndex).getValue().get(
495 // elementClasses);
496 for(Uint32 j = 0, m = elementClasses.size(); j < m; ++j)
497 {
498 CIMName elementClass(elementClasses[j]);
499 Array<String> searchNamespaces =
500 findProviderNamespacesForElement(
501 moduleName, providerName,
502 elementClass,
503 repository,
504 providerCapabilitiesInstances);
505 a.dunfey 1.1 Uint32 k = 0;
506 Uint32 x = searchNamespaces.size();
507 for(; k < x; ++k)
508 {
509 conformingElementsForProfile.append(elementClass);
510 elementNamespacesForProfile.append(searchNamespaces[k]);
511 }
512 }
513 }
514
515 Sint32 foundIndex = -1;
516 for(Sint32 j = 0, m = profileIds.size(); j < m; ++j)
517 {
518 if(profileIds[j] == profileId)
519 {
520 foundIndex = j;
521 break;
522 }
523 }
524
525 if(foundIndex >= 0)
526 a.dunfey 1.1 {
527 // Append the results to already existing entries
528 conformingElements[foundIndex].appendArray(
529 conformingElementsForProfile);
530 elementNamespaces[foundIndex].appendArray(
531 elementNamespacesForProfile);
532 }
533 else
534 {
535 profileIds.append(profileId);
536 conformingElements.append(conformingElementsForProfile);
537 elementNamespaces.append(elementNamespacesForProfile);
538 }
539 }
540 }
541
542 PEGASUS_NAMESPACE_END;
543 // END_OF_FILE
|