BUG#: 8633
[tpot/pegasus.git.bak/pegasus.git] / src / Providers / TestProviders / CLITestProvider / CLITestProvider.cpp
1 //%LICENSE////////////////////////////////////////////////////////////////
2 //
3 // Licensed to The Open Group (TOG) under one or more contributor license
4 // agreements.  Refer to the OpenPegasusNOTICE.txt file distributed with
5 // this work for additional information regarding copyright ownership.
6 // Each contributor licenses this file to you under the OpenPegasus Open
7 // Source License; you may not use this file except in compliance with the
8 // License.
9 //
10 // Permission is hereby granted, free of charge, to any person obtaining a
11 // copy of this software and associated documentation files (the "Software"),
12 // to deal in the Software without restriction, including without limitation
13 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
14 // and/or sell copies of the Software, and to permit persons to whom the
15 // Software is furnished to do so, subject to the following conditions:
16 //
17 // The above copyright notice and this permission notice shall be included
18 // in all copies or substantial portions of the Software.
19 //
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
21 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
23 // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
24 // CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
25 // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
26 // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 //
28 //////////////////////////////////////////////////////////////////////////
29 //
30 //%/////////////////////////////////////////////////////////////////////////////
31
32 /*
33 Test Provider for cimcli. This provider is intended to be used as a
34 test driver only for cimcli.
35
36 This provider is based on the Test_CLITestProviderClass class. This class
37 includes all of the CIM Data types in both scalar and array form
38 and provides the following operations:
39
40 1. Initialize - Creates a single instance of the class with all of the 
41 properties initialized. this is placed in an array.
42
43 2. EnumerateInstances - Returns all instances in the instances array
44
45 3. GetInstance - Returns the single instance found in the array with the
46 input object path if found
47
48 4. Create instance - Creates a new instance of the target class and puts it
49 into the array
50
51 5. ModifyInstance - Attempts to modify an instance of the target class if one
52 is found in the instances array.
53
54 6. DeleteInstance - Delete an instance of the test class if found in the 
55 instances array.
56
57 6. Invoke method: Includes several methods as follows:
58    TBD
59
60 LIMITATIONS: The provider is intended to be used in a single namespace and so
61 does not include the namespace in the instances placed in the array. Therefore
62 if it is enabled for multiple namespaces, a user from some other namespace could
63 remove, get, or enumerate an instance created in another namespace.
64
65 It is intended to run a set of tests fairly rapidly so does not hold itself in
66 memory.  Therefore, if instances are put into the array after the normal Pegasus
67 timeout of providers for unload, they will be discarded.
68
69 */
70 #include "CLITestProvider.h"
71 #include <Pegasus/Common/PegasusAssert.h>
72 #include <Pegasus/Common/Tracer.h>
73 // Required because of some malignent link betweeh MessageLoader and Thread.h
74 #include <Pegasus/Common/MessageLoader.h>
75 #include <Pegasus/Common/Thread.h>
76 #include <Pegasus/Common/Mutex.h>
77
78 PEGASUS_USING_STD;
79 PEGASUS_USING_PEGASUS;
80
81
82 String _toString(Boolean x)
83 {
84     return((x)?"true" : "false");
85 }
86
87 static String _toString(const CIMPropertyList& pl)
88 {
89     String s;
90
91     if (pl.isNull())
92     {
93         s = "NULL";
94     }
95     else if (pl.size() == 0)
96     {
97         s = "EMPTY";
98     }
99     else
100     {
101         for (Uint32 i = 0; i < pl.size(); i++)
102         {
103             if (i > 0)
104             {
105                 s.append(", ");
106             }
107             s.append(pl[i].getString());
108         }
109     }
110     return s;
111 }
112 /*
113     Add the name value pair to the String target.  The result is the pair
114     added to target in the form
115     [; ]name "=" value
116 */
117 void _addParam(String& target, const String& name, const String& value)
118 {
119     if (target.size() != 0)
120     {
121         target.append("; ");
122     }
123     target.append(name);
124     target.append("=");
125     target.append(value);
126 }/*
127     Complete the host and namespace fields of an object path if there are
128     empty. 
129 */
130 void _completePath(const String& hostName,
131                             const CIMNamespaceName& nameSpace,
132                             CIMObjectPath& objectPath)
133 {
134     if (objectPath.getHost().size() == 0)
135         objectPath.setHost(hostName);
136     
137     if (objectPath.getNameSpace().isNull())
138         objectPath.setNameSpace(nameSpace);
139 }
140 // convert a fully qualified reference into a local reference
141 // (class name and keys only).
142 CIMObjectPath _localPath(const CIMObjectPath& inputPath)
143 {
144     CIMObjectPath localPath = CIMObjectPath(
145         String(),
146         CIMNamespaceName(),
147         inputPath.getClassName(),
148         inputPath.getKeyBindings());
149     return localPath;
150 }
151
152 // Serializes access to the instances array during the CIM requests
153 static Mutex instanceArrayMutex;
154
155 CLITestProvider::CLITestProvider()
156 {
157     _initialized = false;
158 }
159
160 CLITestProvider::~CLITestProvider()
161 {
162 }
163
164 void CLITestProvider::initialize(CIMOMHandle & cimom)
165 {
166     _cimom = cimom;
167 }
168
169 void CLITestProvider::terminate()
170 {
171     delete this;
172 }
173
174 void CLITestProvider::invokeMethod(
175     const OperationContext & context,
176     const CIMObjectPath & objectReference,
177     const CIMName & methodName,
178     const Array<CIMParamValue> & inParameters,
179     MethodResultResponseHandler & handler)
180 {
181     initializeProvider(objectReference.getNameSpace());
182
183     // convert a fully qualified reference into a local reference
184     // (class name and keys only).
185
186     CIMObjectPath localReference = CIMObjectPath(
187         String(),
188         CIMNamespaceName(),
189         objectReference.getClassName(),
190         objectReference.getKeyBindings());
191
192     handler.processing();
193
194     String outString = "CLITestProvider  Tests : ";
195
196     if (objectReference.getClassName().equal("Test_CLITestProviderClass"))
197     {
198         if (methodName.equal("ReferenceParamTest"))
199         {
200             if (inParameters.size() > 0)
201             {
202                 for(Uint32 i = 0; i < inParameters.size(); ++i)
203                 {
204                     CIMValue paramVal = inParameters[i].getValue();
205                     if (!paramVal.isNull())
206                     {
207                         if(paramVal.getType() == CIMTYPE_REFERENCE)
208                         {
209                             CIMObjectPath cop,cop1(
210                                 "test/Testprovider:class.k1="
211                                 "\"v1\",k2=\"v2\",k3=\"v3\"");
212                             paramVal.get(cop);
213                             PEGASUS_TEST_ASSERT(cop.identical(cop1) == true);
214                             outString.append(
215                                 "\n Passed Reference params Test1 ");
216                             PEGASUS_TEST_ASSERT(!cop.identical(cop1) == false);
217                             outString.append(
218                                 "\n Passed Reference params Test2    ");
219                         }
220                         else
221                         {
222                             //This code gets excuted for non reference
223                             //parameters.
224                             String replyName;
225                             paramVal.get(replyName);
226                             if (replyName != String::EMPTY)
227                             {
228                                 outString.append(replyName);
229                                 outString.append("\n");
230                                 outString.append("Passed String Param Test\n");
231                             }
232                         }
233                         outString.append("\n");
234                     }
235                     else
236                     {
237                         outString.append("Param Value is NULL");
238                     }
239                 }
240
241                 handler.deliver(CIMValue(outString));
242             }
243             else
244             {
245                 outString.append("Empty Parameters");
246                 handler.deliver(CIMValue(outString));
247             }
248         }
249
250         // This simply returns all parameters and
251         // sets return value set to zero. This should provide a complete
252         // test of all input and output parameter types for cimcli
253         else if(methodName.equal("InOutParamTest"))
254         {
255             if (inParameters.size() > 0)
256             {
257                 //simply returns all parameters
258                 handler.deliverParamValue(inParameters);
259             }
260         handler.deliver(Uint32(0));
261         }
262     }
263     handler.complete();
264 }
265
266 void CLITestProvider::getInstance(
267     const OperationContext & context,
268     const CIMObjectPath & instanceReference,
269     const Boolean includeQualifiers,
270     const Boolean includeClassOrigin,
271     const CIMPropertyList & propertyList,
272     InstanceResponseHandler & handler)
273 {
274     initializeProvider(instanceReference.getNameSpace());
275
276     handler.processing();
277
278     AutoMutex autoMut(instanceArrayMutex);
279
280     Uint32 index;
281     if ((index = findInstance(instanceReference)) != PEG_NOT_FOUND)
282     {
283         // Put input parameters into the requestInputParameters property so
284         // they can be tested on by the client.
285         String text;
286         _addParam(text, "propertyList", _toString(propertyList));
287         _addParam(text, "includeQualifiers", _toString(includeQualifiers));
288         _addParam(text, "includeClassOrigin", _toString(includeClassOrigin));
289
290         // clone and filter the returned instance. Clone so the original
291         // not modified by filter.
292         try
293         {
294             CIMInstance temp = _instances[index].clone();
295             temp.addProperty(CIMProperty("requestInputParameters", text));
296             temp.filter(includeQualifiers,includeClassOrigin, propertyList);
297             handler.deliver(temp);
298         }
299         catch(CIMException& e)
300         {
301             cerr << "CIMCLITestProvider: Exception Occured on deliver : " 
302                 << e.getMessage() << endl;
303             throw CIMException(e);
304         }
305     }
306     else
307     {
308         throw CIMException(CIM_ERR_NOT_FOUND);
309     }
310
311     handler.complete();
312 }
313
314 void CLITestProvider::enumerateInstances(
315     const OperationContext & context,
316     const CIMObjectPath & ref,
317     const Boolean includeQualifiers,
318     const Boolean includeClassOrigin,
319     const CIMPropertyList & propertyList,
320     InstanceResponseHandler & handler)
321 {
322     initializeProvider(ref.getNameSpace());
323
324     handler.processing();
325
326     AutoMutex autoMut(instanceArrayMutex);
327
328     CIMName reqClassName = ref.getClassName();
329
330     // Puts input parameters into the requestInputParameters property so
331     // they can be tested on by the client.
332     String text;
333     _addParam(text, "propertyList", _toString(propertyList));
334     _addParam(text, "includeQualifiers", _toString(includeQualifiers));
335     _addParam(text, "includeClassOrigin", _toString(includeClassOrigin));
336
337     for (Uint32 i = 0, n = _instances.size(); i < n; i++)
338     {
339         if (reqClassName == _instances[i].getClassName())
340         {
341             try
342             {
343                 CIMInstance temp = _instances[i].clone();
344                 temp.addProperty(CIMProperty("requestInputParameters", text));
345                 temp.filter(includeQualifiers,includeClassOrigin,
346                             propertyList);
347                 handler.deliver(temp);
348             }
349             catch(CIMException& e)
350             {
351                 cerr << "CIMCLITestProvider:Exception Occured : " 
352                     << e.getMessage() << endl;
353                 throw CIMException(e);
354             }
355         }
356     }
357     handler.complete();
358 }
359
360 void CLITestProvider::enumerateInstanceNames(
361     const OperationContext & context,
362     const CIMObjectPath & classReference,
363     ObjectPathResponseHandler & handler)
364 {
365     initializeProvider(classReference.getNameSpace());
366
367     handler.processing();
368
369     AutoMutex autoMut(instanceArrayMutex);
370
371     CIMName reqClassName = classReference.getClassName();
372
373     for (Uint32 i = 0, n = _instances.size(); i < n; i++)
374     {
375         if (reqClassName == _instances[i].getClassName())
376         {
377             try
378             {
379                 handler.deliver(_instances[i].getPath());
380             }
381             catch(CIMException& e)
382             {
383                 cerr << "CIMCLITestProvider:Exception Occured : " 
384                     << e.getMessage() << endl;
385                 throw CIMException(e);
386             }
387         }
388     }
389     handler.complete();
390 }
391
392
393 void CLITestProvider::modifyInstance(
394     const OperationContext & context,
395     const CIMObjectPath & instanceReference,
396     const CIMInstance & instanceObject,
397     const Boolean includeQualifiers,
398     const CIMPropertyList & propertyList,
399     ResponseHandler & handler)
400 {
401     initializeProvider(instanceReference.getNameSpace());
402
403     handler.processing();
404
405     // convert a fully qualified reference into a local reference
406     // (class name and keys only).
407
408     CIMClass mc = _getClass(instanceReference.getClassName(),
409                             instanceReference.getNameSpace());
410
411     // TODO confirm the correctness of allowing either the input path or
412     //      the build of the path from the instance to get the instance name
413     //      to modify.  Works but need to check DMTF specs.
414
415     // Get path from input instanceReference OR build it
416
417     CIMObjectPath localRef = (instanceReference.getKeyBindings().size() == 0)?
418                                 instanceObject.buildPath(mc)
419                                 :
420                                 _localPath(instanceReference);
421
422     AutoMutex autoMut(instanceArrayMutex);
423
424     // Find the proper instance.
425     Uint32 index;
426     if ((index = findInstance(localRef)) != PEG_NOT_FOUND)
427     {
428         // Modify the existing instance
429         Uint32 pos;
430         for (Uint32 j = 0 ;  j < instanceObject.getPropertyCount() ; j++)
431         {
432             CIMConstProperty r1 = instanceObject.getProperty(j);
433             CIMProperty r2 = r1.clone();
434             Uint32 pos;
435             try
436             {
437                 if ((pos = _instances[index].findProperty(r2.getName()))
438                      != PEG_NOT_FOUND)
439                 {
440                     _instances[index].removeProperty(pos);
441                     _instances[index].addProperty(r2);
442                 }
443                 else   // simply add the property since not in instance
444                 {
445                     // test if property is in class
446                     if (mc.findProperty(r2.getName()) != PEG_NOT_FOUND)
447                     {
448                         _instances[index].addProperty(r2);
449                     }
450                     else
451                     {
452                         throw CIMException(CIM_ERR_INVALID_PARAMETER,
453                               "Property Not in class " + 
454                               r2.getName().getString());
455                     }
456                 }
457             }  // end try block
458             catch(CIMException& e)
459             {
460                 throw CIMException(CIM_ERR_FAILED, 
461                                    " Updating Property " + e.getMessage());
462             }
463         }  // for loop processing properties
464
465         handler.complete();
466     } // end if found
467     else
468     {
469         throw CIMException(CIM_ERR_NOT_FOUND);
470     }
471 }
472
473 void CLITestProvider::createInstance(
474     const OperationContext & context,
475     const CIMObjectPath & instanceReference,
476     const CIMInstance & instanceObject,
477     ObjectPathResponseHandler & handler)
478 {
479     initializeProvider(instanceReference.getNameSpace());
480
481     handler.processing();
482
483     CIMObjectPath newInstanceRef = _localPath(instanceReference);
484
485     AutoMutex autoMut(instanceArrayMutex);
486     // If there are no properties in the reference, try to get the
487     // key properties and their values from the instanceObject
488     if (instanceReference.getKeyBindings().size() == 0)
489     {
490         Array<CIMKeyBinding> keys;
491
492         Uint32 pos = instanceObject.findProperty("Id");
493
494         if (pos != PEG_NOT_FOUND)
495         {
496             CIMConstProperty cimProperty = instanceObject.getProperty(pos);
497
498             keys.append(CIMKeyBinding(cimProperty.getName(),
499                                       cimProperty.getValue()));
500
501             newInstanceRef.setKeyBindings(keys);
502         }
503         else
504         {
505             throw CIMPropertyNotFoundException("Id");
506         }
507     }
508
509     // If the instance exists, throw already_exists exception
510     // Note: instances in the array do not have path component
511
512     Uint32 index;
513     if ((index = findInstance(newInstanceRef)) == PEG_NOT_FOUND)
514     {
515         // add the instance to the set of instances saved in the provider.
516         CIMInstance myInstance = instanceObject.clone();
517         myInstance.setPath(newInstanceRef);
518         _instances.append(myInstance);
519
520         // Deliver path of new instance
521         handler.deliver(newInstanceRef);
522         handler.complete();
523     }
524
525     else
526     {
527         throw CIMException(CIM_ERR_ALREADY_EXISTS);
528     }
529 }
530
531 void CLITestProvider::deleteInstance(
532     const OperationContext & context,
533     const CIMObjectPath & instanceReference,
534     ResponseHandler & handler)
535 {
536     initializeProvider(instanceReference.getNameSpace());
537
538     handler.processing();
539
540     // convert a fully qualified reference into a local reference
541     // (class name and keys only).
542
543     AutoMutex autoMut(instanceArrayMutex);
544
545     Uint32 index;
546     if ((index = findInstance(instanceReference)) != PEG_NOT_FOUND)
547     {
548         _instances.remove(index);
549     }
550     else
551     {
552         throw CIMException(CIM_ERR_NOT_FOUND);
553     }
554
555     handler.complete();
556     return;
557 }
558
559 /*
560     Processing of associator/Reference Operation Requests
561  
562     NOTE: This code is not based on any clear definition of the
563     relationship between objects but simply returning information
564     on instances that exist in the repository. Thus typically it returns
565     the target instance itself (i.e. association of an instance with
566     itself).  This works since the only goal of this provider
567     is a syntatic test of cimcli, not any association structure. So our
568     association is that every instance is associated with itself. Note that
569     this removes any meaning from the role and assoc/result class parameters
570     but we test the validity of these by returning a property in the
571     returned isntances containing all of these values so that the client
572     can test to determine if the provider received what was input.
573 */
574 void CLITestProvider::associators(
575     const OperationContext& context,
576     const CIMObjectPath& objectName,
577     const CIMName& associationClass,
578     const CIMName& resultClass,
579     const String& role,
580     const String& resultRole,
581     const Boolean includeQualifiers,
582     const Boolean includeClassOrigin,
583     const CIMPropertyList& propertyList,
584     ObjectResponseHandler& handler)
585 {
586     initializeProvider(objectName.getNameSpace());
587
588     // Get the namespace and host names to create the CIMObjectPath
589     CIMNamespaceName nameSpace = objectName.getNameSpace();
590     String host = System::getHostName();
591
592     handler.processing();
593     // complete processing the request
594     // Puts input parameters into the requestInputParameters property so that
595     // they can be tested on by the client.
596     String text;
597     _addParam(text, "role", role);
598     _addParam(text, "resultRole", resultRole);
599     _addParam(text, "associationClass", associationClass.getString());
600     _addParam(text, "resultClass", resultClass.getString());
601     _addParam(text, "includeQualifiers", _toString(includeQualifiers));
602     _addParam(text, "includeClassOrigin", _toString(includeClassOrigin));
603     _addParam(text, "propertyList", _toString(propertyList));
604
605     // Return an instance of the associated class for every instance
606     // currently in the local list.
607     Uint32 index;
608     if ((index = findInstance(objectName)) != PEG_NOT_FOUND)
609     {
610         try
611         {
612             CIMInstance temp = _instances[index].clone();
613             temp.addProperty(CIMProperty("requestInputParameters", text));
614             temp.setPath(objectName);
615             temp.filter(includeQualifiers,
616                         includeClassOrigin, propertyList);
617             handler.deliver(temp);
618         }
619         catch(CIMException& e)
620         {
621             cerr << "CIMCLITestProvider:Exception Occured : " 
622                 << e.getMessage() << endl;
623             throw CIMException(e);
624         }
625     }
626     handler.complete();
627 }
628
629 void CLITestProvider::associatorNames(
630     const OperationContext& context,
631     const CIMObjectPath& objectName,
632     const CIMName& associationClass,
633     const CIMName& resultClass,
634     const String& role,
635     const String& resultRole,
636     ObjectPathResponseHandler& handler)
637 {
638     initializeProvider(objectName.getNameSpace());
639     // Get the namespace and host names to create the CIMObjectPath
640     CIMNamespaceName nameSpace = objectName.getNameSpace();
641     String host = System::getHostName();
642
643     handler.processing();
644     // complete processing the request
645
646     // Return an instance of the associated class for every instance
647     // currently in the local list. Simple since we just return the
648     // input path if the instance exists.
649     Uint32 index;
650     if ((index = findInstance(objectName)) != PEG_NOT_FOUND)
651     {
652         try
653         {
654             handler.deliver(objectName);
655         }
656         catch(CIMException& e)
657         {
658             cerr << "CIMCLITestProvider:Exception Occured : " 
659                 << e.getMessage() << endl;
660             throw CIMException(e);
661         }
662     }
663     handler.complete();
664 }
665
666 void CLITestProvider::references(
667     const OperationContext& context,
668     const CIMObjectPath& objectName,
669     const CIMName& resultClass,
670     const String& role,
671     const Boolean includeQualifiers,
672     const Boolean includeClassOrigin,
673     const CIMPropertyList& propertyList,
674     ObjectResponseHandler& handler)
675 {
676     initializeProvider(objectName.getNameSpace());
677     // Get the namespace and host names to create the CIMObjectPath
678     CIMNamespaceName nameSpace = objectName.getNameSpace();
679     String host = System::getHostName();
680
681     handler.processing();
682
683     CIMName objectClassName = objectName.getClassName();
684
685     // if the target instance exists in the local storage, build the
686     // association class instance
687     AutoMutex autoMut(instanceArrayMutex);
688     Uint32 index;
689     if ((index = findInstance(objectName)) != PEG_NOT_FOUND)
690     {
691         Array<CIMName> refClassArray;
692         refClassArray.append(CIMName("Test_CLITestProviderLinkClass"));
693     
694         // Create a single instance of the Test_CLITestProviderLinkClass
695         // This creates a single fixed instance simply to allow the
696         // cimcli client to test results.  It also places the input parameters
697         // into the text result so that the client can confirm that the
698         // input parameters were passed to the provider.
699     
700         CIMInstance assocInstance("Test_CLITestProviderLinkClass");
701         
702         assocInstance.addProperty(CIMProperty(CIMName("parent"),
703             objectName,
704             0,
705             CIMName("Test_CLITestProviderClass")));
706     
707         assocInstance.addProperty(CIMProperty(CIMName("child"),
708             objectName,
709             0,
710             CIMName("Test_CLITestProviderClass")));
711    
712
713         // Put input parameters into the requestInputParameters property so
714         // they can be tested on by the client.
715         String text;
716         _addParam(text, "role", role);
717         _addParam(text, "resultClass", resultClass.getString());
718         _addParam(text, "includeQualifiers", _toString(includeQualifiers));
719         _addParam(text, "includeClassOrigin", _toString(includeClassOrigin));
720         _addParam(text, "propertyList", _toString(propertyList));
721     
722         assocInstance.addProperty(CIMProperty("requestInputParameters",
723                                               text));
724         // Create path for assoc instance.
725         CIMClass assocClass = _getClass(CIMName(
726             "Test_CLITestProviderLinkClass"),
727             nameSpace);
728     
729         CIMObjectPath objectPath =
730             assocInstance.buildPath(assocClass);
731     
732         _completePath(host, nameSpace, objectPath);
733     
734         assocInstance.setPath(objectPath);
735
736         // complete processing the request    
737         assocInstance.filter(includeQualifiers,
738                     includeClassOrigin, propertyList);
739
740         handler.deliver(assocInstance);
741     }
742     handler.complete();
743 }
744
745 // Return all references (association instance names) in which the given
746 // object is involved.
747
748 void CLITestProvider::referenceNames(
749     const OperationContext& context,
750     const CIMObjectPath& objectName,
751     const CIMName& resultClass,
752     const String& role,
753     ObjectPathResponseHandler& handler)
754 {
755     CIMNamespaceName nameSpace = objectName.getNameSpace();
756     initializeProvider(nameSpace);
757     // Get the namespace and host names to create the CIMObjectPath
758     String host = System::getHostName();
759
760     // If the objectName exists in the local list, build the instance
761     // of the association and then build the path for this instance.
762
763     AutoMutex autoMut(instanceArrayMutex);
764     Uint32 index;
765
766     if ((index = findInstance(objectName)) != PEG_NOT_FOUND)
767     {
768         Array<CIMName> refClassArray;
769         refClassArray.append(CIMName("Test_CLITestProviderLinkClass"));
770     
771         CIMInstance assocInstance("Test_CLITestProviderLinkClass");
772         
773         assocInstance.addProperty(CIMProperty(CIMName("parent"),
774             objectName,
775             0,
776             CIMName("Test_CLITestProviderClass")));
777     
778         assocInstance.addProperty(CIMProperty(CIMName("child"),
779             objectName,
780             0,
781             CIMName("Test_CLITestProviderClass")));
782     
783         CIMClass assocClass = _getClass(
784             CIMName("Test_CLITestProviderLinkClass"),
785             nameSpace);
786  
787         // build path for this instance   
788         CIMObjectPath objectPath =
789             assocInstance.buildPath(assocClass);
790     
791         _completePath(host, nameSpace, objectPath);
792     
793         handler.deliver(objectPath);
794     }
795     // complete processing the request
796     handler.complete();
797 }
798
799
800 /* get the defined class from the repository.
801     @param className CIMName name of the class to get
802     @return CIMClass with the class or unitialized if
803     there was an error in the getClass
804 */
805 CIMClass CLITestProvider::_getClass(const CIMName& className,
806                                     const CIMNamespaceName& ns)
807 {
808     CIMClass c;
809     try
810     {
811         c = _cimom.getClass(
812             OperationContext(),
813             ns,
814             className,
815             false,
816             true,
817             true,
818             CIMPropertyList());
819     }
820     catch (CIMException& e)
821     {
822         PEG_TRACE((TRC_DISCARDED_DATA, Tracer::LEVEL1,
823             "CLITestProvider GetClass operation failed: Class %s. Msg %s",
824             (const char*) className.getString().getCString(),
825             (const char*) e.getMessage().getCString()));
826         throw CIMException(CIM_ERR_FAILED);
827     }
828     return c;
829 }
830
831 /*
832     Find an instance in the instance array with path defined by
833     the input parameter. returns the index of the instance or PEG_NOT_FOUND
834 */
835 Uint32 CLITestProvider::findInstance(const CIMObjectPath& path)
836 {
837     CIMObjectPath localPath = _localPath(path);
838
839     for (Uint32 i = 0; i < _instances.size(); i++)
840     {
841         if(localPath == _instances[i].getPath())
842         {
843             return i;
844         }
845     }
846     return PEG_NOT_FOUND;
847 }
848 // Create the instances that will be considered inherently part of the
849 // provider for these tests.  This includes one instance of each class
850 // This was done with namespace input so that we could build association
851 // instances that require namespace.  It later turned out to be easier
852 // to build them on the fly so that the namespace parameter and the
853 // corresponding dynamic initialization of the provider (initializeProvider)
854 // are not really necessary.
855
856 void CLITestProvider::createInstances(const CIMNamespaceName& ns)
857 {
858     AutoMutex autoMut(instanceArrayMutex);
859
860     // Create a single instance with all properties and with path
861     // independent of namespace or hostname
862
863     CIMInstance instance("Test_CLITestProviderClass");
864
865     instance.addProperty(CIMProperty("Id", String("Mike")));
866     instance.addProperty(CIMProperty("Name", String("Bob")));
867     instance.addProperty(CIMProperty("scalBool", Boolean(true)));
868     instance.addProperty(CIMProperty("scalUint8", Uint8(220)));
869     instance.addProperty(CIMProperty("scalSint8", Sint8(124)));
870     instance.addProperty(CIMProperty("scalUint16", Uint16(100)));
871     instance.addProperty(CIMProperty("scalSint16", Sint16(100)));
872     instance.addProperty(CIMProperty("scalUint32", Uint32(100)));
873     instance.addProperty(CIMProperty("scalSint32", Sint32(100)));
874     instance.addProperty(CIMProperty("scalUint64", Uint64(100)));
875     instance.addProperty(CIMProperty("scalReal32", Real32(100)));
876     instance.addProperty(CIMProperty("scalReal64", Real64(100)));
877     instance.addProperty(CIMProperty("scalString", String("teststring")));
878     instance.addProperty(CIMProperty("scalDateTime",
879                                CIMDateTime("19991224120000.000000+360")));
880
881     // set Values into the corresponding array properties
882     Array<Boolean> ab;
883     ab.append(true); ab.append(false); ab.append(true);
884     instance.addProperty(CIMProperty("arrayBool", CIMValue(ab)));
885
886     Array<Uint8> auint8;
887     auint8.append(4); auint8.append(128); auint8.append(240);
888     instance.addProperty(CIMProperty("arrayUint8", CIMValue(auint8)));
889
890     Array<Sint8> asint8;
891     asint8.append(4); asint8.append(126); asint8.append(-126);
892     instance.addProperty(CIMProperty("arraySint8", CIMValue(asint8)));
893
894     Array<Uint16> auint16;
895     auint16.append(4); auint16.append(128); auint16.append(240);
896     instance.addProperty(CIMProperty("arrayUint16", CIMValue(auint16)));
897
898     Array<Sint16> asint16;
899     asint16.append(4); asint16.append(126); asint16.append(-126);
900     instance.addProperty(CIMProperty("arraySint16", CIMValue(asint16)));
901
902     Array<Uint32> auint32;
903     auint32.append(4); auint32.append(128); auint32.append(240);
904     instance.addProperty(CIMProperty("arrayUint32", CIMValue(auint32)));
905
906     Array<Sint32> asint32;
907     asint32.append(4); asint32.append(126); asint32.append(-126);
908     instance.addProperty(CIMProperty("arraySint32", CIMValue(asint32)));
909
910     Array<Uint64> auint64;
911     auint64.append(4); auint64.append(128); auint64.append(240);
912     instance.addProperty(CIMProperty("arrayUint64", CIMValue(auint64)));
913
914     Array<Real32> aReal32;
915     aReal32.append(4); aReal32.append(128); aReal32.append(240);
916     instance.addProperty(CIMProperty("arrayReal32", CIMValue(aReal32)));
917
918     Array<Real64> aReal64;
919     aReal64.append(4); aReal64.append(128); aReal64.append(240);
920     instance.addProperty(CIMProperty("arrayReal64", CIMValue(aReal64)));
921
922     Array<String> aString;
923     aString.append("First"); aString.append("Second"); aString.append("Third");
924     instance.addProperty(CIMProperty("arrayString", CIMValue(aString)));
925
926     Array<CIMDateTime> aCIMDateTime;
927     aCIMDateTime.append(CIMDateTime("19991224120000.000000+360"));
928     aCIMDateTime.append(CIMDateTime("19991224120000.000000+360"));
929     aCIMDateTime.append(CIMDateTime("19991224120000.000000+360"));
930     instance.addProperty(CIMProperty("arrayCIMDateTime",
931                                       CIMValue(aCIMDateTime)));
932     CIMObjectPath p("Test_CLITestProviderClass.Id=\"Mike\"");
933
934     instance.setPath(p);
935
936     _instances.append(instance);
937 }
938
939 void CLITestProvider::initializeProvider(const CIMNamespaceName& ns)
940 {
941     if (!_initialized)
942     {
943         createInstances(ns);
944     }
945     _initialized = true;
946 }
947