PEP 55 Update license on source files to current license text and date
[tpot/pegasus/.git] / src / Clients / cimomperf / cimomperf.cpp
1 //%2003////////////////////////////////////////////////////////////////////////
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 //
8 // Permission is hereby granted, free of charge, to any person obtaining a copy
9 // of this software and associated documentation files (the "Software"), to
10 // deal in the Software without restriction, including without limitation the
11 // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
12 // sell copies of the Software, and to permit persons to whom the Software is
13 // furnished to do so, subject to the following conditions:
14 // 
15 // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
16 // ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED
17 // "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
18 // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
19 // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
20 // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
21 // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 //
24 //==============================================================================
25 //
26 // Author: Karl Schopmeyer (k.schopmeyer@opengroup.org)
27 //
28 // Modified By: Carol Ann Krug Graves, Hewlett-Packard Company
29 //                (carolann_graves@hp.com)
30 //
31 //%/////////////////////////////////////////////////////////////////////////////
32
33 /* This is a simplistic display program for the CIMOM performance characteristics.
34         This version simply gets the instances of the performace class and displays
35         the resulting average counts.
36         TODO  KS
37         1. Convert to use the correct class when it is available.
38         2. Get the header information from the class, not fixed.
39         3. Keep history and present so that there is a total
40         4. Do Total so that we have overall counts.
41         5. Do percentages
42 */
43 #include <Pegasus/Common/Config.h>
44 #include <cassert>
45 #include <Pegasus/Client/CIMClient.h>
46 #include <Pegasus/Common/HTTPConnector.h>
47 #include <Pegasus/Common/OptionManager.h>
48 #include <Pegasus/Common/Stopwatch.h>
49 #include <Pegasus/Common/FileSystem.h>
50
51 PEGASUS_USING_PEGASUS;
52 PEGASUS_USING_STD;
53
54 const String DEFAULT_NAMESPACE = "root/cimv2";
55
56 static const char * usage = "blah blah";
57 static const char * extra = "more blah";
58
59 //------------------------------------------------------------------------------
60 //
61 // _indent()
62 //
63 //------------------------------------------------------------------------------
64
65 static void _indent(PEGASUS_STD(ostream)& os, Uint32 level, Uint32 indentSize)
66 {
67     Uint32 n = level * indentSize;
68     if (n > 50)
69     {
70     cout << "Jumped Ship " << level << " size " << indentSize << endl;
71     exit(1);
72     }
73
74     for (Uint32 i = 0; i < n; i++)
75         os << ' ';
76 }
77 void mofFormat(
78     PEGASUS_STD(ostream)& os, 
79     const char* text, 
80     Uint32 indentSize)
81 {
82     char* tmp = strcpy(new char[strlen(text) + 1], text);
83     Uint32 count = 0;
84     Uint32 indent = 0;
85     Boolean quoteState = false;
86     Boolean qualifierState = false;
87     char c;
88     char prevchar;
89     while (c = *tmp++)
90     {
91         count++;
92         // This is too simplistic and must move to a token based mini parser
93         // but will do for now. One problem is tokens longer than 12 characters that
94         // overrun the max line length.
95         switch (c)
96         {
97             case '\n':
98                 os << Sint8(c);
99                 prevchar = c;
100                 count = 0 + (indent * indentSize);
101                 _indent(os, indent, indentSize);   
102                 break;
103
104             case '\"':   // quote 
105                 os << Sint8(c);
106                 prevchar = c;
107                 quoteState = !quoteState;
108                 break;
109
110             case ' ':
111                 os << Sint8(c);
112                 prevchar = c;
113                 if (count > 66)
114                 {
115                     if (quoteState)
116                     {   
117                         os << "\"\n";
118                         _indent(os, indent + 1, indentSize);   
119                         os <<"\"";
120                     }
121                     else
122                     {
123                         os <<"\n";
124                         _indent(os, indent + 1,  indentSize);   
125                     }
126                     count = 0 + ((indent + 1) * indentSize);
127                 }
128                 break;
129             case '[':
130                 if (prevchar == '\n')
131                 {
132                     indent++;
133                     _indent(os, indent,  indentSize);
134                     qualifierState = true;
135                 }
136                 os << Sint8(c);
137                 prevchar = c;
138                 break;
139
140             case ']':
141                 if (qualifierState)
142                 {
143                     if (indent > 0)
144                         indent--;
145                     qualifierState = false;
146                 }
147                 os << Sint8(c);
148                 prevchar = c;
149                 break;
150
151             default:
152                 os << Sint8(c);
153                 prevchar = c;
154         }
155
156     }
157 }
158
159 void GetOptions(
160     OptionManager& om,
161     int& argc,
162     char** argv,
163     const String& testHome)
164 {
165     static const char* outputFormats[] = { "xml", "mof", "txt"};
166     static const Uint32 NUM_OUTPUTFORMATS = sizeof(outputFormats) /
167                                             sizeof(outputFormats[0]);
168
169     static struct OptionRow optionsTable[] =
170         //optionname defaultvalue rqd  type domain domainsize clname hlpmsg
171     {
172         {"location", "localhost:5988", false, Option::STRING, 0, 0, "-n",
173                                         "specifies system and port" },
174         
175         {"namespace", "root/cimv2", false, Option::STRING, 0, 0, "-n",
176                                         "specifies namespace to use for operation" },
177         
178
179
180         {"version", "false", false, Option::BOOLEAN, 0, 0, "v",
181                                         "Displays software Version "},
182
183         {"help", "false", false, Option::BOOLEAN, 0, 0, "h",
184                             "Prints help message with command line options "},
185
186         {"debug", "false", false, Option::BOOLEAN, 0, 0, "d", 
187                      "Not Used "},
188     };
189     const Uint32 NUM_OPTIONS = sizeof(optionsTable) / sizeof(optionsTable[0]);
190
191     om.registerOptions(optionsTable, NUM_OPTIONS);
192
193     //We want to make this code common to all of the commands
194
195     String configFile = "/CLTest.conf";
196
197     cout << "Config file from " << configFile << endl;
198
199     if (FileSystem::exists(configFile))
200              om.mergeFile(configFile);
201
202     om.mergeCommandLine(argc, argv);
203
204     om.checkRequiredOptions();
205
206 }
207
208 void printHelp(char* name, OptionManager om)
209 {
210     String header = "Usage ";
211     header.append(name);
212
213     //om.printOptionsHelpTxt(header, trailer);
214 }
215
216 /* PrintHelp - This is temporary until we expand the options manager to allow
217    options help to be defined with the OptionRow entries and presented from
218    those entries.
219 */
220 void printHelpMsg(const char* pgmName, const char* usage, const char* extraHelp, 
221                 OptionManager om)
222 {
223     cout << endl << pgmName << endl;
224     cout << "Usage: " << pgmName << endl << usage << endl;
225     cout << endl;
226     // ATTN: KS om.printHelp(const char* pgmName, OptionManager om);
227     cout << extraHelp << endl;
228
229 }
230
231
232 int main(int argc, char** argv)
233 {
234
235     // Get options (from command line and from configuration file); this
236     // removes corresponding options and their arguments fromt he command
237     // line.
238
239     // Get options (from command line and from configuration file); this
240     // removes corresponding options and their arguments fromt he command
241     // line.
242
243     OptionManager om;
244
245     try
246     {
247                  String testHome = ".";
248                  GetOptions(om, argc, argv, testHome);
249                  // om.print();
250     }
251     catch (Exception& e)
252     {
253                  cerr << argv[0] << ": " << e.getMessage() << endl;
254                  exit(1);
255     }
256
257
258     // Check to see if user asked for help (-h otpion):
259     if (om.valueEquals("verbose", "true"))
260     {
261                 printHelpMsg(argv[0], usage, extra, om);
262                 exit(0);
263     }
264
265     // Establish the namespace from the input parameters
266     String nameSpace;
267     if(om.lookupValue("namespace", nameSpace))
268     {
269        cout << "Namespace = " << nameSpace << endl;
270
271     }
272
273     Boolean verboseTest = (om.valueEquals("verbose", "true")) ? true :false;
274
275     Boolean debug = (om.valueEquals("debug", "true")) ? true :false;
276     
277         if (om.valueEquals("help", "true"))
278     {
279         String header = "Usage ";
280         String trailer = "";
281         om.printOptionsHelpTxt(header, trailer);
282         exit(0);
283     }
284
285     String location =   "localhost:5988";
286     if(om.lookupValue("location", location))
287     {
288        cout << "Location = " << location << endl;
289
290     }
291
292         String className = "IBM_CIMOMStatData";
293
294     CIMClient client;
295
296     try
297     {
298         client.connect(location, String::EMPTY, String::EMPTY);
299     } 
300     
301     catch(Exception& e)
302     {
303           cerr << argv[0] << " Exception connecting to : " << location << endl;
304           cerr << e.getMessage() << endl;
305     }
306         CIMClass performanceClass;
307         try
308         {
309                 performanceClass = client.getClass(nameSpace,
310                                                                                    className,
311                                                                                    false,
312                                                                                    false,
313                                                                                    false);
314         }
315
316     catch(Exception& e)
317     {
318           cerr << argv[0] << "Exception getClass : " << className
319                    << e.getMessage() << endl;
320           exit(1);
321     }
322     try
323     {
324                 Boolean localOnly = false;
325                 Boolean deepInheritance = false;
326                 Boolean includeQualifiers = false;
327                 Boolean includeClassOrigin = false;
328                 
329                 Array<CIMInstance> instances; 
330                 instances = client.enumerateInstances(nameSpace,
331                                                            className,
332                                                            deepInheritance,
333                                                            localOnly,
334                                                            includeQualifiers,
335                                                            includeClassOrigin);
336                 
337                 // Output a table with the values
338                 
339                 // First build the header from the values strings in the class
340                 printf("%-25s%10s %10s %10s %10s %10s\n%-25s%10s %10s %10s %10s %10s\n",
341                            "CIM", "Number of", "CIMOM", "Provider",
342                             "Request", "Response",
343                            "Operation", "Requests", "Time", "Time", "Size", "Size");
344                 
345                 // Output the returned instances
346                 
347                 for (Uint32 i = 0; i < instances.size(); i++)
348                 {
349                         CIMInstance instance = instances[i];
350             /* Took this out because not used and
351                toMof not member of CIMInstance any more
352                KS 6 June 2002
353                         if (debug) 
354                         {
355                                 Array<Sint8> x;
356                                 instance.toMof(x);
357                         
358                                 x.append('\0');
359                         
360                                 mofFormat(cout, x.getData(), 4);
361                         }
362             */
363                         // Build a line for every information entry.
364
365                         // Get the request type property for this instance
366                         // Note that for the moment it is simply an integer.
367                         Uint32 pos;
368                         CIMProperty p;
369
370                         String statName;
371                         CIMValue v;
372
373                         if ((pos = instance.findProperty("name")) != PEG_NOT_FOUND)
374                         {
375                                 p = (instance.getProperty(pos));
376                                 v = p.getValue();
377                                 if (v.getType() == CIMTYPE_STRING)
378                                 {
379                                         v.get(statName);
380                                 }
381                         }
382                         else
383                         {
384                                 statName = "UNKNOWN";
385                         }
386
387                         // now get number of requests property "NumberofRequests"
388                         Uint64 numberOfRequests = 0;
389                         if ((pos = instance.findProperty("NumberofRequests")) != PEG_NOT_FOUND)
390                         {
391                                 p = (instance.getProperty(pos));
392                                 v = p.getValue();
393                                 if (v.getType() == CIMTYPE_UINT64)
394                                 {
395                                         v.get(numberOfRequests);
396                                 }
397                         }
398                         // Get the total CIMOM Time property "TotalCimomTime"
399                         Uint64 totalCimomTime = 0;
400                         Uint64 averageCimomTime = 0;
401
402                         if ((pos = instance.findProperty("TotalCimomTime")) != PEG_NOT_FOUND)
403                         {
404                                 p = (instance.getProperty(pos));
405                                 v = p.getValue();
406                                 if (v.getType() == CIMTYPE_UINT64)
407                                 {
408                                         v.get(totalCimomTime);
409                                 }
410                                 else
411                                         cerr << "Error Property value " << "TotalCimomTime" << endl;
412                         }
413                         else
414                                 cerr << "Error Property " << "TotalCimomTime" << endl;
415
416                         if (totalCimomTime != 0) {
417                                 averageCimomTime =  totalCimomTime / numberOfRequests;
418                         }
419                         // Get the total Provider Time property "TotalProviderTime"
420
421                         Uint64 totalProviderTime = 0; 
422                         Uint64 averageProviderTime = 0;
423
424                         if ((pos = instance.findProperty("TotalProviderTime")) != PEG_NOT_FOUND)
425                         {
426                                 p = (instance.getProperty(pos));
427                                 v = p.getValue();
428                                 if (v.getType() == CIMTYPE_UINT64)
429                                 {
430                                         v.get(totalProviderTime);
431                                 }
432                                 else
433                                         cerr << "Error Property Vlaue " << "TotalProviderTime" << endl;
434                         }
435                         else
436                                 cerr << "Error Property " << "TotalCimomTime" << endl;
437
438                         if (totalCimomTime != 0) {
439                                 averageProviderTime =  totalProviderTime / numberOfRequests;
440                         }
441                         // Get the total Response size property "TotalResponseSize"
442
443                         Uint64 totalResponseSize = 0;
444                         Uint64 averageResponseSize = 0;
445
446
447                         if ((pos = instance.findProperty("TotalResponseSize")) != PEG_NOT_FOUND)
448                         {
449                                 p = (instance.getProperty(pos));
450                                 v = p.getValue();
451                                 if (v.getType() == CIMTYPE_UINT64)
452                                 {
453                                         v.get(totalResponseSize);
454                                 }
455                         }
456                         if (totalCimomTime != 0) {
457                                 averageResponseSize =  totalResponseSize / numberOfRequests;
458                         }
459                         //Get the total request size property "TotalRequestSize"
460
461                         Uint64 totalRequestSize = 0;
462                         Uint64 averageRequestSize = 0;
463
464
465                         if ((pos = instance.findProperty("TotalRequestSize")) != PEG_NOT_FOUND)
466                         {
467                                 p = (instance.getProperty(pos));
468                                 v = p.getValue();
469                                 if (v.getType() == CIMTYPE_UINT64)
470                                 {
471                                         v.get(totalRequestSize);
472                                 }
473                         }
474                         if (totalRequestSize != 0)
475                         {
476                                 averageRequestSize = totalRequestSize / numberOfRequests;
477                         }
478
479                         // If there are requests made, output one line with the total
480                         //if (numberOfRequests > 0) {
481                                 printf(" %-25s%9lu %10lu %10lu %10lu %10lu\n",
482                                            (const char*)statName.getCString(),
483                                            numberOfRequests, averageCimomTime,
484                                            averageProviderTime, averageRequestSize, 
485                                            averageResponseSize);
486                         //}
487                 }
488     }
489     catch(Exception& e)
490     {
491           cerr << argv[0] << "Exception : " << className
492                         << e.getMessage() << endl;
493
494           exit(1);
495     }
496
497     return 0;
498 }
499