1 kumpf 1.2 //%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 kumpf 1.2 // 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 #include <cctype>
35 #include <cstdio>
36 #include <Pegasus/Common/Config.h>
37 #include <Pegasus/Common/Tracer.h>
|
45 kumpf 1.2 PEGASUS_NAMESPACE_BEGIN
46
47 CimToWsmResponseMapper::CimToWsmResponseMapper()
48 {
49 }
50
51 CimToWsmResponseMapper::~CimToWsmResponseMapper()
52 {
53 }
54
55 WsmResponse* CimToWsmResponseMapper::mapToWsmResponse(
56 const WsmRequest* wsmRequest,
57 const CIMResponseMessage* message)
58 {
59 AutoPtr<WsmResponse> wsmResponse;
60
61 if (message->cimException.getCode() != CIM_ERR_SUCCESS)
62 {
63 wsmResponse.reset(_mapToWsmFaultResponse(wsmRequest, message));
64 }
65 else
66 kumpf 1.2 {
67 switch (message->getType())
68 {
69 case CIM_GET_INSTANCE_RESPONSE_MESSAGE:
70 wsmResponse.reset(_mapToWsmGetResponse(
71 (WsmGetRequest*) wsmRequest,
72 (CIMGetInstanceResponseMessage*) message));
73 break;
74
75 case CIM_MODIFY_INSTANCE_RESPONSE_MESSAGE:
76 wsmResponse.reset(_mapToWsmPutResponse(
77 (WsmPutRequest*) wsmRequest,
78 (CIMModifyInstanceResponseMessage*) message));
79 break;
80
81 case CIM_CREATE_INSTANCE_RESPONSE_MESSAGE:
82 wsmResponse.reset(_mapToWsmCreateResponse(
83 (WsmCreateRequest*) wsmRequest,
84 (CIMCreateInstanceResponseMessage*) message));
85 break;
86
87 kumpf 1.2 case CIM_DELETE_INSTANCE_RESPONSE_MESSAGE:
88 wsmResponse.reset(_mapToWsmDeleteResponse(
89 (WsmDeleteRequest*) wsmRequest,
90 (CIMDeleteInstanceResponseMessage*) message));
91 break;
92
93 default:
94 PEGASUS_ASSERT(0);
95 break;
96 }
97 }
98 return wsmResponse.release();
99 }
100
101 WsmFaultResponse* CimToWsmResponseMapper::_mapToWsmFaultResponse(
102 const WsmRequest* wsmRequest,
103 const CIMResponseMessage* response)
104 {
105 WsmFault fault = mapCimExceptionToWsmFault(response->cimException);
106
107 WsmFaultResponse* wsmResponse = new WsmFaultResponse(wsmRequest, fault);
108 kumpf 1.2
109 return wsmResponse;
110 }
111
112 WsmFault CimToWsmResponseMapper::mapCimExceptionToWsmFault(
113 const CIMException& cimException)
114 {
115 WsmFault::Subcode subcode;
116 const ContentLanguageList& languageList =
117 cimException.getContentLanguages();
118 String reason = TraceableCIMException(cimException).getDescription();
119 String faultDetail;
120
121 switch (cimException.getCode())
122 {
123 case CIM_ERR_FAILED: // Too general to specify fault
124 case CIM_ERR_CLASS_HAS_CHILDREN: // Only ModifyClass and DeleteClass
125 case CIM_ERR_CLASS_HAS_INSTANCES: // Only ModifyClass and DeleteClass
126 case CIM_ERR_INVALID_SUPERCLASS: // Only CreateClass and ModifyClass
127 // These could map to wsa_ActionNotSupported if InvokeMethod is
128 // supported through Custom Actions.
129 kumpf 1.2 case CIM_ERR_METHOD_NOT_FOUND: // Only InvokeMethod
130 case CIM_ERR_METHOD_NOT_AVAILABLE: // Only InvokeMethod
131 case CIM_ERR_NO_SUCH_PROPERTY: // Only GetProperty and SetProperty
132 case CIM_ERR_TYPE_MISMATCH: // Only SetProperty
133 subcode = WsmFault::wsman_InternalError;
134 break;
135
136 case CIM_ERR_ACCESS_DENIED:
137 subcode = WsmFault::wsman_AccessDenied;
138 break;
139
140 case CIM_ERR_ALREADY_EXISTS:
141 subcode = WsmFault::wsman_AlreadyExists;
142 break;
143
144 case CIM_ERR_INVALID_CLASS:
145 subcode = WsmFault::wsa_DestinationUnreachable;
146 faultDetail = WSMAN_FAULTDETAIL_INVALIDRESOURCEURI;
147 break;
148
149 case CIM_ERR_INVALID_NAMESPACE:
150 kumpf 1.2 // Consider wsman_InvalidSelectors?
151 subcode = WsmFault::wsa_DestinationUnreachable;
152 // faultDetail is not set to WSMAN_FAULTDETAIL_INVALIDRESOURCEURI
153 // since this error reflects an incorrect Selector value rather
154 // than an incorrect ResourceURI.
155 break;
156
157 case CIM_ERR_INVALID_PARAMETER:
158 // For InvokeMethod, this would map to wsman_InvalidParameter.
159 // It is difficult to discern the correct fault for other
160 // operations. It make sense to use wxf_InvalidRepresentation for
161 // Create and Put, and wsman_InvalidSelectors for Get and Put.
162 subcode = WsmFault::wsman_InvalidParameter;
163 break;
164
165 case CIM_ERR_INVALID_QUERY:
166 // Note that Enumerate operations have a different subcode:
167 // wsen_CannotProcessFilter.
168 subcode = WsmFault::wsen_CannotProcessFilter;
169 break;
170
171 kumpf 1.2 case CIM_ERR_NOT_FOUND:
172 // DSP0226 Table 10 of master faults calls for
173 // DestinationUnreachable in cases when the resource is no found.
174 subcode = WsmFault::wsa_DestinationUnreachable;
175 break;
176
177 case CIM_ERR_NOT_SUPPORTED:
178 subcode = WsmFault::wsa_ActionNotSupported;
179 faultDetail = WSMAN_FAULTDETAIL_ACTIONMISMATCH;
180 break;
181
182 case CIM_ERR_QUERY_LANGUAGE_NOT_SUPPORTED:
183 // DSP0227 section 15.1.11 indicates that ExecuteQuery operations
184 // through WS-Management use CQL filter dialect. If this status
185 // code results, it is fair to assume filtering is not supported
186 // at all. Another option would be to use
187 // wsen_FilterDialectRequestedUnavailable.
188 subcode = WsmFault::wsen_FilteringNotSupported;
189 break;
190
191 default:
192 kumpf 1.2 PEGASUS_ASSERT(0);
193 }
194
195 return WsmFault(subcode, reason, languageList, faultDetail);
196 }
197
198 WsmGetResponse* CimToWsmResponseMapper::_mapToWsmGetResponse(
199 const WsmGetRequest* wsmRequest,
200 const CIMGetInstanceResponseMessage* response)
201 {
202 WsmInstance wsmInstance;
203
204 convertCimToWsmInstance(response->cimInstance, wsmInstance);
205
206 WsmGetResponse* wsmResponse =
207 new WsmGetResponse(
208 wsmInstance,
209 wsmRequest,
210 _getContentLanguages(response->operationContext));
211
212 return wsmResponse;
213 kumpf 1.2 }
214
215 WsmPutResponse* CimToWsmResponseMapper::_mapToWsmPutResponse(
216 const WsmPutRequest* wsmRequest,
217 const CIMModifyInstanceResponseMessage* response)
218 {
219 WsmPutResponse* wsmResponse =
220 new WsmPutResponse(
221 wsmRequest,
222 _getContentLanguages(response->operationContext));
223
224 return wsmResponse;
225 }
226
227 WsmCreateResponse* CimToWsmResponseMapper::_mapToWsmCreateResponse(
228 const WsmCreateRequest* wsmRequest,
229 const CIMCreateInstanceResponseMessage* response)
230 {
231 WsmEndpointReference epr;
232
233 convertObjPathToEPR(response->instanceName, epr);
234 kumpf 1.2
235 WsmCreateResponse* wsmResponse =
236 new WsmCreateResponse(
237 epr,
238 wsmRequest,
239 _getContentLanguages(response->operationContext));
240
241 return wsmResponse;
242 }
243
244 WsmDeleteResponse* CimToWsmResponseMapper::_mapToWsmDeleteResponse(
245 const WsmDeleteRequest* wsmRequest,
246 const CIMDeleteInstanceResponseMessage* response)
247 {
248 WsmDeleteResponse* wsmResponse =
249 new WsmDeleteResponse(
250 wsmRequest,
251 _getContentLanguages(response->operationContext));
252
253 return wsmResponse;
254 }
255 kumpf 1.2
256 void CimToWsmResponseMapper::convertCimToWsmInstance(
257 const CIMInstance& cimInstance,
258 WsmInstance& wsmInstance)
259 {
260 wsmInstance.setClassName(cimInstance.getClassName().getString());
261
262 for (Uint32 i = 0, n = cimInstance.getPropertyCount(); i < n; i++)
263 {
264 CIMConstProperty cimProperty = cimInstance.getProperty(i);
265 const String& propertyName = cimProperty.getName().getString();
266 const CIMValue& cimValue = cimProperty.getValue();
267
268 WsmValue wsmValue;
269 convertCimToWsmValue(cimValue, wsmValue);
270
271 WsmProperty wsmProperty(propertyName, wsmValue);
272 wsmInstance.addProperty(wsmProperty);
273 }
274 }
275
276 kumpf 1.2 template<class T>
277 static void _convertCimToWsmArrayValue(
278 const CIMValue& cimValue,
279 WsmValue& wsmValue)
280 {
281 Array<T> arr;
282 Array<String> strs;
283
284 cimValue.get(arr);
285 for (Uint32 i = 0, n = arr.size(); i < n; i++)
286 {
287 CIMValue val(arr[i]);
288 String str(val.toString());
289 if (val.getType() == CIMTYPE_BOOLEAN)
290 {
291 str.toLower();
292 }
293 strs.append(str);
294 }
295 wsmValue.set(strs);
296 }
297 kumpf 1.2
298 void CimToWsmResponseMapper::convertCimToWsmValue(
299 const CIMValue& cimValue,
300 WsmValue& wsmValue)
301 {
302 if (cimValue.isNull())
303 {
304 wsmValue.setNull();
305 return;
306 }
307
308 if (cimValue.isArray())
309 {
310 switch (cimValue.getType())
311 {
312 case CIMTYPE_BOOLEAN:
313 {
314 _convertCimToWsmArrayValue<Boolean>(cimValue, wsmValue);
315 break;
316 }
317
318 kumpf 1.2 case CIMTYPE_UINT8:
319 {
320 _convertCimToWsmArrayValue<Uint8>(cimValue, wsmValue);
321 break;
322 }
323
324 case CIMTYPE_SINT8:
325 {
326 _convertCimToWsmArrayValue<Sint8>(cimValue, wsmValue);
327 break;
328 }
329
330 case CIMTYPE_UINT16:
331 {
332 _convertCimToWsmArrayValue<Uint16>(cimValue, wsmValue);
333 break;
334 }
335
336 case CIMTYPE_SINT16:
337 {
338 _convertCimToWsmArrayValue<Sint16>(cimValue, wsmValue);
339 kumpf 1.2 break;
340 }
341
342 case CIMTYPE_UINT32:
343 {
344 _convertCimToWsmArrayValue<Uint32>(cimValue, wsmValue);
345 break;
346 }
347
348 case CIMTYPE_SINT32:
349 {
350 _convertCimToWsmArrayValue<Sint32>(cimValue, wsmValue);
351 break;
352 }
353
354 case CIMTYPE_UINT64:
355 {
356 _convertCimToWsmArrayValue<Uint64>(cimValue, wsmValue);
357 break;
358 }
359
360 kumpf 1.2 case CIMTYPE_SINT64:
361 {
362 _convertCimToWsmArrayValue<Sint64>(cimValue, wsmValue);
363 break;
364 }
365
366 case CIMTYPE_REAL32:
367 {
368 _convertCimToWsmArrayValue<Real32>(cimValue, wsmValue);
369 break;
370 }
371
372 case CIMTYPE_REAL64:
373 {
374 _convertCimToWsmArrayValue<Real64>(cimValue, wsmValue);
375 break;
376 }
377
378 case CIMTYPE_CHAR16:
379 {
380 _convertCimToWsmArrayValue<Char16>(cimValue, wsmValue);
381 kumpf 1.2 break;
382 }
383
384 case CIMTYPE_STRING:
385 {
386 _convertCimToWsmArrayValue<String>(cimValue, wsmValue);
387 break;
388 }
389
390 case CIMTYPE_DATETIME:
391 {
392 Array<CIMDateTime> dates;
393 Array<String> strs;
394 cimValue.get(dates);
395 for (Uint32 i = 0, n = dates.size(); i < n; i++)
396 {
|
613 dmitry.mikulin 1.3 void CimToWsmResponseMapper::convertCimToWsmDatetime(
614 const CIMDateTime& cimDT, String& wsmDT)
615 {
616 char buffer[50];
617 Uint32 size;
618
619 String cimStrDT = cimDT.toString();
620 CString cimCStrDT = cimStrDT.getCString();
621 const char* cimStr = (const char*) cimCStrDT;
622 Uint32 firstAsteriskPos = cimStrDT.find('*');
623
624 // DSP0230.
625 // 1. If CIM datetime string contains ":", use Interval cim:cimDateTime
626 // element.
627 // 2. If CIM datetime string contains "+" or "-" and does not contain any
628 // asterisks, use Datetime cim:cimDateTime element.
629 // 3. If CIM datetime string contains "+" or "-" and no asterisks in
630 // the hhmmss.mmmmmm portion, and only asterisks in the yyyymmdd portion,
631 // ATTN: this makes no sense. yyyymmdd cannot be wildcarded unless
632 // previous sections are wildcarded.
633 // use Time cim:cimDateTime element.
634 dmitry.mikulin 1.3 // 4. If CIM datetime string contains "+" or "-" and no asterisks in the
635 // yyyymmdd portion, and only asterisks in the hhmmss.mmmmmm portion,
636 // use Date cim:cimDateTime element.
637 // 5. In all other cases use CIM_DateTime element.
638
639 if (cimStr[21] == ':')
640 {
641 // Interval
642 Uint32 days = 0, hrs = 0, mins = 0, secs = 0, msecs = 0;
643 int conversions = sscanf(cimStr, "%8u%2u%2u%2u.%u:000",
644 &days, &hrs, &mins, &secs, &msecs);
645 if (conversions == 0 && cimStr[0] == '*')
646 days = 1;
647
648 wsmDT = "P";
649 if (conversions >= 1 && days)
650 {
651 wsmDT.append(Uint32ToString(buffer, days, size));
652 wsmDT.append(Char16('D'));
653 }
654 if (conversions >= 2 )
655 dmitry.mikulin 1.3 {
656 wsmDT.append(Char16('T'));
657 if (hrs)
658 {
659 wsmDT.append(Uint32ToString(buffer, hrs, size));
660 wsmDT.append(Char16('H'));
661 }
662 }
663 if (conversions >= 3 && mins)
664 {
665 wsmDT.append(Uint32ToString(buffer, mins, size));
666 wsmDT.append(Char16('M'));
667 }
668 if (conversions >= 4 && secs)
669 {
670 wsmDT.append(Uint32ToString(buffer, secs, size));
671 if (conversions >= 5 && msecs)
672 {
673 wsmDT.append(Char16('.'));
674 wsmDT.append(Uint32ToString(buffer, msecs, size));
675 }
676 dmitry.mikulin 1.3 wsmDT.append(Char16('S'));
677 }
678 }
679 else if ((cimStr[21] == '+' || cimStr[21] == '-') &&
680 firstAsteriskPos == PEG_NOT_FOUND)
681 {
682 // Datetime
683 Uint32 year = 0, month = 0, day = 0, utcoff = 0,
684 hrs = 0, mins = 0, secs = 0, msecs = 0;
685 char sign;
686 int conversions = sscanf(cimStr,
687 "%4u%2u%2u%2u%2u%2u.%6u%c%3u",
688 &year, &month, &day, &hrs, &mins, &secs, &msecs, &sign, &utcoff);
689
690 PEGASUS_ASSERT(conversions == 9);
691
692 if (utcoff == 0)
693 {
694 if (msecs)
695 {
696 sprintf(buffer, "%.4u-%.2u-%.2uT%.2u:%.2u:%.2u.%.6uZ",
697 dmitry.mikulin 1.3 year, month, day, hrs, mins, secs, msecs);
698 }
699 else
700 {
701 sprintf(buffer, "%.4u-%.2u-%.2uT%.2u:%.2u:%.2uZ",
702 year, month, day, hrs, mins, secs);
703 }
704 }
705 else
706 {
707 Uint32 utch = utcoff / 60;
708 Uint32 utcm = utcoff % 60;
709 if (msecs)
710 {
711 sprintf(buffer, "%.4u-%.2u-%.2uT%.2u:%.2u:%.2u.%.6u%c%.2u:%.2u",
712 year, month, day, hrs, mins, secs, msecs,
713 sign, utch, utcm);
714 }
715 else
716 {
717 sprintf(buffer, "%.4u-%.2u-%.2uT%.2u:%.2u:%.2u%c%.2u:%.2u",
718 dmitry.mikulin 1.3 year, month, day, hrs, mins, secs, sign, utch, utcm);
719 }
720 }
721 wsmDT = buffer;
722 }
723 else if ((cimStr[21] == '+' || cimStr[21] == '-') &&
724 firstAsteriskPos == 8)
725 {
726 // Date
727 Uint32 year = 0, month = 0, day = 0, utcoff = 0;
728 char sign;
729 int conversions = sscanf(cimStr, "%4u%2u%2u******.******%c%3u",
730 &year, &month, &day, &sign, &utcoff);
731
732 PEGASUS_ASSERT(conversions == 5);
733
734 if (utcoff == 0)
735 {
736 sprintf(buffer, "%.4u-%.2u-%.2uZ", year, month, day);
737 }
738 else
739 dmitry.mikulin 1.3 {
740 Uint32 utch = utcoff / 60;
741 Uint32 utcm = utcoff % 60;
742 sprintf(buffer, "%.4u-%.2u-%.2u%c%.2u:%.2u",
743 year, month, day, sign, utch, utcm);
744 }
745 wsmDT = buffer;
746 }
747 else
748 {
749 // CIM_DateTime
750 wsmDT = cimStr;
751 }
752 }
|