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;
|
56 a.dunfey 1.1
57 //
58 // Property names for CIM_Namespace Class
59 //
60 #define CIM_NAMESPACE_PROPERTY_NAME COMMON_PROPERTY_NAME
61 #define CIM_NAMESPACE_PROPERTY_CREATIONCLASSNAME \
62 COMMON_PROPERTY_CREATIONCLASSNAME
63 #define CIM_NAMESPACE_PROPERTY_SYSTEMCREATIONCLASSNAME \
64 COMMON_PROPERTY_SYSTEMCREATIONCLASSNAME
65 #define CIM_NAMESPACE_PROPERTY_SYSTEMNAME COMMON_PROPERTY_SYSTEMNAME
66 static const CIMName CIM_NAMESPACE_PROPERTY_OBJECTMANAGERCREATIONCLASSNAME(
67 "ObjectManagerCreationClassName");
68 static const CIMName CIM_NAMESPACE_PROPERTY_OBJECTMANAGERNAME(
69 "ObjectManagerName");
70 static const CIMName CIM_NAMESPACE_PROPERTY_CLASSINFO(
71 "ClassInfo");
72 static const CIMName CIM_NAMESPACE_PROPERTY_DESCRIPTIONOFCLASSINFO(
73 "DescriptionOfClassInfo");
74 static const CIMName CIM_NAMESPACE_PROPERTY_CLASSTYPE("ClassType");
75
76 // Additional Property names for PG_Namespace Class
77 a.dunfey 1.1
78 static const CIMName PG_NAMESPACE_PROPERTY_SCHEMAUPDATESALLOWED(
79 "SchemaUpdatesAllowed");
80 static const CIMName PG_NAMESPACE_PROPERTY_ISSHAREABLE(
81 "IsShareable");
82 static const CIMName PG_NAMESPACE_PROPERTY_PARENTNAMESPACE(
83 "ParentNamespace");
84 #define PG_NAMESPACE_PROPERTY_NAME COMMON_PROPERTY_NAME
85
86 //
87 // Get the instances of CIM_Namespace. Gets all instances of the namespace from
88 // the repository namespace management functions. Builds instances that
89 // match all of the request attributes.
90 //
91 Array<CIMInstance> InteropProvider::enumNamespaceInstances()
92 {
93 PEG_METHOD_ENTER(TRC_CONTROLPROVIDER,
94 "InteropProvider::_getInstancesCIMNamespace()");
95
96 Array<CIMNamespaceName> namespaceNames = repository->enumerateNameSpaces();
97 Array<CIMInstance> instanceArray;
98 a.dunfey 1.1
99 // Build instances of PG namespace since that is the leaf class
100 for (Uint32 i = 0, n = namespaceNames.size(); i < n; i++)
101 {
102 instanceArray.append(
103 buildNamespaceInstance(namespaceNames[i].getString()));
104 }
105
106 PEG_METHOD_EXIT();
107 return instanceArray;
108 }
109
110 //
111 // Returns an array of all of the NamespaceInManager association instances
112 // for this CIMOM. One instance will be produced for every namespace present
113 // in the CIMOM/repository.
114 //
115 Array<CIMInstance> InteropProvider::enumNamespaceInManagerInstances()
116 {
117 PEG_METHOD_ENTER(TRC_CONTROLPROVIDER,
118 "InteropProvider::buildInstancesNamespaceInManager");
119 a.dunfey 1.1
120 Array<CIMInstance> namespaceInstances = enumNamespaceInstances();
121
122 CIMObjectPath objectManagerPath = getObjectManagerInstance().getPath();
123
124 Array<CIMInstance> assocInstances;
125 CIMClass targetClass;
126
127 CIMInstance instanceskel = buildInstanceSkeleton(
128 PEGASUS_NAMESPACENAME_INTEROP,
129 PEGASUS_CLASSNAME_PG_NAMESPACEINMANAGER, targetClass);
130 // Build and instance for each namespace instance.
131 for (Uint32 i = 0 ; i < namespaceInstances.size() ; i++)
132 {
133 CIMInstance instance = instanceskel.clone();
134 setPropertyValue(instance, PROPERTY_ANTECEDENT, objectManagerPath);
135 setPropertyValue(instance, PROPERTY_DEPENDENT,
136 namespaceInstances[i].getPath());
137
138 CIMObjectPath objPath = instance.buildPath(targetClass);
139 objPath.setHost(hostName);
140 a.dunfey 1.1 objPath.setNameSpace(PEGASUS_NAMESPACENAME_INTEROP);
141 instance.setPath(objPath);
142 assocInstances.append(instance);
143 }
144 PEG_METHOD_EXIT();
145 return assocInstances;
146 }
147
148
149 //
150 // Generates one instance of the PG_Namespace class for the specified
151 // namespace.
152 //
153 CIMInstance InteropProvider::buildNamespaceInstance(
154 const String & nameSpace)
155 {
156 PEG_METHOD_ENTER(TRC_CONTROLPROVIDER,
157 "InteropProvider::buildInstancePGNamespace");
158
159 CIMClass targetClass;
160 CIMInstance instance = buildInstanceSkeleton(
161 a.dunfey 1.1 PEGASUS_NAMESPACENAME_INTEROP, PEGASUS_CLASSNAME_PGNAMESPACE,
162 targetClass);
163
164 setCommonKeys(instance);
165
166 // ObjectManagerCreationClassName
167 setPropertyValue(instance,
168 CIM_NAMESPACE_PROPERTY_OBJECTMANAGERCREATIONCLASSNAME,
169 PEGASUS_CLASSNAME_PG_OBJECTMANAGER.getString());
170
171 // ObjectManagerName
172 setPropertyValue(instance, CIM_NAMESPACE_PROPERTY_OBJECTMANAGERNAME,
173 objectManagerName);
174
175 // CreationClassName
176 setPropertyValue(instance, CIM_NAMESPACE_PROPERTY_CREATIONCLASSNAME,
177 PEGASUS_CLASSNAME_PGNAMESPACE.getString());
178 // Name
179 // This is the namespace name itself
180 setPropertyValue(instance, CIM_NAMESPACE_PROPERTY_NAME,
181 nameSpace);
182 a.dunfey 1.1
183 // ClassInfo
184 // Set the classinfo to unknown and the description to namespace.
185 setPropertyValue(instance, CIM_NAMESPACE_PROPERTY_CLASSINFO, Uint16(0));
186
187 // DescriptionOfClassInfo
188 setPropertyValue(instance, CIM_NAMESPACE_PROPERTY_DESCRIPTIONOFCLASSINFO,
189 String("namespace"));
190
191 // ClassType
192 setPropertyValue(instance, CIM_NAMESPACE_PROPERTY_CLASSTYPE,
193 Uint16(2));
194
195
196 //
197 // Everything above was commmon to CIM Namespace. The following are
198 // PG_Namespace Properties
199 //
200 CIMRepository::NameSpaceAttributes attributes;
201 repository->getNameSpaceAttributes(nameSpace, attributes);
|
204 a.dunfey 1.1 Boolean shareable = false;
205 Boolean updatesAllowed = true;
206 for (CIMRepository::NameSpaceAttributes::Iterator i = attributes.start();
207 i; i++)
208 {
209 String key=i.key();
210 String value = i.value();
211 if(String::equalNoCase(key,"shareable"))
212 {
213 if (String::equalNoCase(value,"true"))
214 shareable=true;
215 }
216 else if(String::equalNoCase(key,"updatesAllowed"))
217 {
218 if (String::equalNoCase(value,"false"))
219 updatesAllowed=false;
220 }
221 // Test to be sure we are returning proper namespace name
222 else if (String::equalNoCase(key,"name"))
223 {
224 if (!String::equalNoCase(value, nameSpace))
225 a.dunfey 1.1 {
226 PEG_METHOD_EXIT();
227 // This is poor exception since it reflects internal error. Do
228 // error log
229 throw CIMNotSupportedException(
230 "Namespace attribute rtnd error for key " + key +
231 "expected " + nameSpace + value + " in " +
232 String(thisProvider));
233 }
234
235 name = value;
236 }
237 else if (String::equalNoCase(key,"parent"))
238 {
239 parent=value;
240 }
241 else
242 {
243 PEG_METHOD_EXIT();
244 // Poor error definition since it reflects internal error. do error
245 // log
246 a.dunfey 1.1 throw PEGASUS_CIM_EXCEPTION (CIM_ERR_NOT_SUPPORTED, nameSpace +
247 " namespace attribute " + key + " option not supported in" +
248 String(thisProvider));
249 }
250 }
251
252 // SchemaUpdatesAllowed
253 setPropertyValue(instance, PG_NAMESPACE_PROPERTY_SCHEMAUPDATESALLOWED,
254 updatesAllowed);
255
256 // IsShareable
257 setPropertyValue(instance, PG_NAMESPACE_PROPERTY_ISSHAREABLE, shareable);
258
259 // ParentNamespace
260 setPropertyValue(instance, PG_NAMESPACE_PROPERTY_PARENTNAMESPACE, parent);
261 setPropertyValue(instance, PG_NAMESPACE_PROPERTY_NAME, name);
262
263 CIMObjectPath objPath = instance.buildPath(targetClass);
264 objPath.setHost(hostName);
265 objPath.setNameSpace(PEGASUS_NAMESPACENAME_INTEROP);
266 instance.setPath(objPath);
267 a.dunfey 1.1 PEG_METHOD_EXIT();
268 return instance;
269 }
270
271 //
272 // Function that takes an instance of the CIM_Namespace class, checks whether
273 // the key properties are present,
274 //
275 String buildNamespacePath(
276 CIMObjectPath & namespacePath,
277 const CIMInstance& instance,
278 const String & objectManagerName)
279 {
280 PEG_METHOD_ENTER(TRC_CONTROLPROVIDER,
281 "InteropProvider::buildNamespacePath");
282
283 unsigned int propIndex = PEG_NOT_FOUND;
284 CIMName propertyName;
285
286 if(instance.findProperty(CIM_NAMESPACE_PROPERTY_SYSTEMCREATIONCLASSNAME)
287 == PEG_NOT_FOUND)
288 a.dunfey 1.1 {
289 propertyName = CIM_NAMESPACE_PROPERTY_SYSTEMCREATIONCLASSNAME;
290 }
291 else if(instance.findProperty(CIM_NAMESPACE_PROPERTY_SYSTEMNAME)
292 == PEG_NOT_FOUND)
293 {
294 propertyName = CIM_NAMESPACE_PROPERTY_SYSTEMNAME;
295 }
296 else if(instance.findProperty(
297 CIM_NAMESPACE_PROPERTY_OBJECTMANAGERCREATIONCLASSNAME)
298 == PEG_NOT_FOUND)
299 {
300 propertyName = CIM_NAMESPACE_PROPERTY_OBJECTMANAGERCREATIONCLASSNAME;
301 }
302 else if(instance.findProperty(
303 CIM_NAMESPACE_PROPERTY_OBJECTMANAGERNAME)
304 == PEG_NOT_FOUND)
305 {
306 propertyName = CIM_NAMESPACE_PROPERTY_OBJECTMANAGERNAME;
307 }
308 else if(instance.findProperty(
309 a.dunfey 1.1 CIM_NAMESPACE_PROPERTY_CREATIONCLASSNAME)
310 == PEG_NOT_FOUND)
311 {
312 propertyName = CIM_NAMESPACE_PROPERTY_CREATIONCLASSNAME;
313 }
314 else if((propIndex = instance.findProperty(CIM_NAMESPACE_PROPERTY_NAME))
315 == PEG_NOT_FOUND)
316 {
317 propertyName = CIM_NAMESPACE_PROPERTY_NAME;
318 }
319
320 if(propIndex == PEG_NOT_FOUND)
321 {
322 PEG_TRACE_STRING(TRC_CONTROLPROVIDER, Tracer::LEVEL4,
323 "Invalid CIM_Namespace Key Property " + propertyName.getString());
324 PEG_METHOD_EXIT();
325 throw CIMInvalidParameterException(
326 "Invalid CIM_Namespace key property: " + propertyName.getString());
327 }
328
|
330 a.dunfey 1.1 "CIM_Namespace Keys Valid");
331
332 Array<CIMKeyBinding> keyBindings;
333
334 String newNamespaceName;
335 instance.getProperty(propIndex).getValue().get(newNamespaceName);
336 keyBindings.append(CIMKeyBinding(
337 CIM_NAMESPACE_PROPERTY_NAME,
338 newNamespaceName, CIMKeyBinding::STRING));
339
340 keyBindings.append(CIMKeyBinding(
341 CIM_NAMESPACE_PROPERTY_CREATIONCLASSNAME,
342 PEGASUS_CLASSNAME_PGNAMESPACE.getString(), CIMKeyBinding::STRING));
343
344 keyBindings.append(CIMKeyBinding(
345 CIM_NAMESPACE_PROPERTY_SYSTEMCREATIONCLASSNAME,
346 System::getSystemCreationClassName(), CIMKeyBinding::STRING));
347
348 String hostName = System::getFullyQualifiedHostName();
349 keyBindings.append(CIMKeyBinding(
350 CIM_NAMESPACE_PROPERTY_SYSTEMNAME,
351 a.dunfey 1.1 hostName, CIMKeyBinding::STRING));
352
353 keyBindings.append(CIMKeyBinding(
354 CIM_NAMESPACE_PROPERTY_OBJECTMANAGERCREATIONCLASSNAME,
355 PEGASUS_CLASSNAME_PG_OBJECTMANAGER.getString(),
356 CIMKeyBinding::STRING));
357
358 keyBindings.append(CIMKeyBinding(
359 CIM_NAMESPACE_PROPERTY_OBJECTMANAGERNAME,
360 objectManagerName, CIMKeyBinding::STRING));
361
362 namespacePath = CIMObjectPath(hostName, PEGASUS_NAMESPACENAME_INTEROP,
363 PEGASUS_CLASSNAME_PGNAMESPACE, keyBindings);
364 return newNamespaceName;
365 }
366
367 //
368 // Validates the keys for the ObjectPath representing an instance of
369 // PG_Namespace. Having this function should be more efficient than creating an
370 // instance of PG_Namespace and then comparing the object paths.
371 //
372 a.dunfey 1.1 CIMNamespaceName validateNamespaceKeys(
373 const CIMObjectPath& objectPath,
374 const String & objectManagerName)
375 {
376 PEG_METHOD_ENTER(TRC_CONTROLPROVIDER,
377 "InteropProvider::validatePGNamespaceKeys");
378
379 CIMName propertyName;
380 if(!validateRequiredProperty(
381 objectPath,
382 CIM_NAMESPACE_PROPERTY_SYSTEMCREATIONCLASSNAME,
383 PEGASUS_CLASSNAME_PG_COMPUTERSYSTEM.getString()))
384 {
385 propertyName = CIM_NAMESPACE_PROPERTY_SYSTEMCREATIONCLASSNAME;
386 }
387 else if(!validateRequiredProperty(
388 objectPath,
389 CIM_NAMESPACE_PROPERTY_SYSTEMNAME,
390 System::getFullyQualifiedHostName()))
391 {
392 propertyName = CIM_NAMESPACE_PROPERTY_SYSTEMNAME;
393 a.dunfey 1.1 }
394 else if(!validateRequiredProperty(
395 objectPath,
396 CIM_NAMESPACE_PROPERTY_OBJECTMANAGERCREATIONCLASSNAME,
397 PEGASUS_CLASSNAME_PG_OBJECTMANAGER.getString()))
398 {
399 propertyName = CIM_NAMESPACE_PROPERTY_OBJECTMANAGERCREATIONCLASSNAME;
400 }
401 else if(!validateRequiredProperty(
402 objectPath,
403 CIM_NAMESPACE_PROPERTY_OBJECTMANAGERNAME,
404 objectManagerName))
405 {
406 propertyName = CIM_NAMESPACE_PROPERTY_OBJECTMANAGERNAME;
407 }
408 else if(!validateRequiredProperty(
409 objectPath,
410 CIM_NAMESPACE_PROPERTY_CREATIONCLASSNAME,
411 PEGASUS_CLASSNAME_PGNAMESPACE.getString()))
412 {
413 propertyName = CIM_NAMESPACE_PROPERTY_CREATIONCLASSNAME;
414 a.dunfey 1.1 }
415 else if(!validateRequiredProperty(objectPath,
416 CIM_NAMESPACE_PROPERTY_NAME,
417 String::EMPTY))
418 {
419 propertyName = CIM_NAMESPACE_PROPERTY_NAME;
420 }
421
422 if(!propertyName.isNull())
423 {
424 PEG_METHOD_EXIT();
425 throw CIMInvalidParameterException(
426 "Invalid key property: " + propertyName.getString());
427 }
428
429 PEG_METHOD_EXIT();
430 return CIMNamespaceName(getKeyValue(objectPath, CIM_NAMESPACE_PROPERTY_NAME));
431 }
432
433 void InteropProvider::deleteNamespace(
434 const CIMObjectPath & instanceName)
435 a.dunfey 1.1 {
436 PEG_METHOD_ENTER(TRC_CONTROLPROVIDER,
437 "InteropProvider::deleteNamespace()");
438 // Validate requred keys and retrieve namespace name. An exception
439 // will be thrown if the object path is not valid.
440 CIMNamespaceName deleteNamespaceName =
441 validateNamespaceKeys(instanceName, objectManagerName);
442
443 if (deleteNamespaceName.equal(PEGASUS_NAMESPACENAME_ROOT))
444 {
445 PEG_METHOD_EXIT();
446 throw CIMNotSupportedException("root namespace cannot be deleted.");
447 }
448
449 repository->deleteNameSpace(deleteNamespaceName);
450
451 PEG_TRACE_STRING(TRC_CONTROLPROVIDER, Tracer::LEVEL4,
452 "Namespace = " + deleteNamespaceName.getString() +
453 " successfully deleted.");
454
455 Logger::put(Logger::STANDARD_LOG, System::CIMSERVER, Logger::TRACE,
456 a.dunfey 1.1 "Interop Provider Delete Namespace: $0",
457 deleteNamespaceName.getString());
458 PEG_METHOD_EXIT();
459 }
460
461 CIMObjectPath InteropProvider::createNamespace(
462 const CIMInstance & namespaceInstance)
463 {
464 PEG_METHOD_ENTER(TRC_CONTROLPROVIDER,
465 "InteropProvider::createNamespace()");
466 // The buildNamespacePath method performs some validation on the
467 // namespace instance, creates a valid object path that can be used
468 // by the client to access the instance later, and retrieves the
469 // namespace to be created.
470 CIMObjectPath newInstanceReference;
471 CIMNamespaceName newNamespaceName = buildNamespacePath(
472 newInstanceReference, namespaceInstance, objectManagerName);
473
474 // Create the new namespace
475 try
476 {
477 a.dunfey 1.1 PEG_TRACE_STRING(TRC_CONTROLPROVIDER, Tracer::LEVEL4,
478 "Namespace = " + newNamespaceName.getString() +
479 " to be created.");
480
481 CIMRepository::NameSpaceAttributes attributes;
482
483 // Set shareable attribute to "false" if property is not present
484 Boolean shareable = false;
485 if(getPropertyValue(namespaceInstance,
486 PG_NAMESPACE_PROPERTY_ISSHAREABLE, false))
487 {
488 attributes.insert("shareable", "true");
489 }
490 else
491 {
492 attributes.insert("shareable", "false");
493 }
494
495 // Set updatesAllowed attribute to "false" if property is not present
496 Boolean updatesAllowed = false;
497 if (getPropertyValue(namespaceInstance,
498 a.dunfey 1.1 PG_NAMESPACE_PROPERTY_SCHEMAUPDATESALLOWED, false))
499 {
500 attributes.insert("updatesAllowed", "true");
501 }
502 else
503 {
504 attributes.insert("updatesAllowed", "false");
505 }
506
507 // Set the parent attribute if the property is present, but don't set
508 // it at all otherwise.
509 String parent = getPropertyValue(namespaceInstance,
510 PG_NAMESPACE_PROPERTY_PARENTNAMESPACE, String::EMPTY);
511 if (parent != String::EMPTY)
512 attributes.insert("parent",parent);
513
514 //
515 // Create the namespace with the retrieved attributes.
516 //
517 repository->createNameSpace(newNamespaceName, attributes);
518
519 a.dunfey 1.1 PEG_TRACE_STRING(TRC_CONTROLPROVIDER, Tracer::LEVEL4,
520 "Namespace = " + newNamespaceName.getString() +
521 " successfully created.");
522 Logger::put(Logger::STANDARD_LOG, System::CIMSERVER, Logger::TRACE,
523 "Create Namespace: Shareable = $0, Updates allowed: $1, Parent: $2",
524 newNamespaceName.getString(), shareable?
525 "true" : "false", shareable? "true" : "false", parent );
526
527 }
528 catch(const CIMException&)
529 {
530 PEG_METHOD_EXIT();
531 throw;
532 }
533 catch(const Exception&)
534 {
535 PEG_METHOD_EXIT();
536 throw;
537 }
538
539 return newInstanceReference;
540 a.dunfey 1.1 }
541
|