1 martin 1.5 //%LICENSE////////////////////////////////////////////////////////////////
|
2 martin 1.6 //
|
3 martin 1.5 // 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 martin 1.6 //
|
10 martin 1.5 // 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 martin 1.6 //
|
17 martin 1.5 // The above copyright notice and this permission notice shall be included
18 // in all copies or substantial portions of the Software.
|
19 martin 1.6 //
|
20 martin 1.5 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
21 martin 1.6 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
22 martin 1.5 // 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 martin 1.6 //
|
28 martin 1.5 //////////////////////////////////////////////////////////////////////////
|
29 kumpf 1.2 //
30 //%/////////////////////////////////////////////////////////////////////////////
31
32 #include <cctype>
33 #include <cstdio>
34 #include <Pegasus/Common/Config.h>
35 #include <Pegasus/Common/HTTPConnection.h>
36 #include <Pegasus/Common/HTTPMessage.h>
37 #include <Pegasus/Common/Tracer.h>
38 #include <Pegasus/Common/AutoPtr.h>
39 #include <Pegasus/Common/MessageLoader.h>
40
41 #include "WsmConstants.h"
42 #include "WsmReader.h"
43 #include "WsmWriter.h"
44 #include "WsmResponseEncoder.h"
|
45 kumpf 1.4 #include "WsmToCimRequestMapper.h"
46 #include "SoapResponse.h"
|
47 rohini.deshpande 1.13 #include "CimToWsmResponseMapper.h"
|
48 kumpf 1.2
49 PEGASUS_USING_STD;
50
51 PEGASUS_NAMESPACE_BEGIN
52
53 WsmResponseEncoder::WsmResponseEncoder()
54 {
55 }
56
57 WsmResponseEncoder::~WsmResponseEncoder()
58 {
59 }
60
|
61 kumpf 1.4 void WsmResponseEncoder::_sendResponse(SoapResponse* response)
|
62 kumpf 1.2 {
63 PEG_METHOD_ENTER(TRC_WSMSERVER, "WsmResponseEncoder::sendResponse");
64 PEG_TRACE((TRC_WSMSERVER, Tracer::LEVEL3,
|
65 kumpf 1.4 "WsmResponseEncoder::sendResponse()"));
|
66 kumpf 1.2
67 if (!response)
68 {
69 PEG_METHOD_EXIT();
70 return;
71 }
72
73 Uint32 queueId = response->getQueueId();
74 Boolean httpCloseConnect = response->getHttpCloseConnect();
75
|
76 marek 1.3 PEG_TRACE((TRC_WSMSERVER, Tracer::LEVEL4,
|
77 kumpf 1.2 "WsmResponseEncoder::sendResponse()- "
78 "response->getHttpCloseConnect() returned %d",
79 httpCloseConnect));
80
81 MessageQueue* queue = MessageQueue::lookup(queueId);
82 if (!queue)
83 {
|
84 marek 1.3 PEG_TRACE((TRC_DISCARDED_DATA, Tracer::LEVEL1,
|
85 kumpf 1.2 "ERROR: non-existent queueId = %u, response not sent.", queueId));
86 PEG_METHOD_EXIT();
87 return;
88 }
89 PEGASUS_ASSERT(dynamic_cast<HTTPConnection*>(queue) != 0);
90
|
91 kumpf 1.4 Buffer message = response->getResponseContent();
|
92 kumpf 1.2
93 // Note: WS-Management responses are never sent in chunks, so there is no
94 // need to check dynamic_cast<HTTPConnection*>(queue)->isChunkRequested().
95 // HTTPMessage::isComplete() defaults to true, and we leave it that way.
96
97 AutoPtr<HTTPMessage> httpMessage(new HTTPMessage(message));
98
99 httpMessage->setCloseConnect(httpCloseConnect);
100 queue->enqueue(httpMessage.release());
101
102 PEG_METHOD_EXIT();
103 }
104
|
105 kumpf 1.4 void WsmResponseEncoder::_sendUnreportableSuccess(WsmResponse* response)
106 {
107 // DSP0226 R6.2-2: If the mustUnderstand attribute is set to
108 // "true", the service shall comply with the request. If the
109 // response would exceed the maximum size, the service should
110 // return a wsman:EncodingLimit fault. Because a service might
111 // execute the operation prior to knowing the response size, the
112 // service should undo any effects of the operation before
113 // issuing the fault. If the operation cannot be reversed (such
114 // as a destructive wxf:Put or wxf:Delete, or a wxf:Create), the
115 // service shall indicate that the operation succeeded in the
116 // wsman:EncodingLimit fault with the following detail code:
117 // http://schemas.dmtf.org/wbem/wsman/1/wsman/faultDetail/
118 // UnreportableSuccess
119
120 WsmFault fault(WsmFault::wsman_EncodingLimit,
121 MessageLoaderParms(
122 "WsmServer.WsmResponseEncoder.UNREPORTABLE_SUCCESS",
123 "Success response could not be encoded within "
124 "requested envelope size limits."),
125 WSMAN_FAULTDETAIL_UNREPORTABLESUCCESS);
126 kumpf 1.4 WsmFaultResponse faultResponse(
|
127 kumpf 1.7 response->getRelatesTo(),
128 response->getQueueId(),
|
129 kumpf 1.4 response->getHttpMethod(),
|
130 kumpf 1.7 response->getHttpCloseConnect(),
|
131 mike 1.11 response->getOmitXMLProcessingInstruction(),
|
132 kumpf 1.4 fault);
133
134 SoapResponse soapResponse(&faultResponse);
135 _sendResponse(&soapResponse);
136 }
137
|
138 kumpf 1.8 SoapResponse* WsmResponseEncoder::_buildEncodingLimitFault(
139 WsmResponse* response)
|
140 kumpf 1.4 {
141 WsmFault fault(WsmFault::wsman_EncodingLimit,
142 MessageLoaderParms(
143 "WsmServer.WsmResponseEncoder.MAX_ENV_SIZE_EXCEEDED",
144 "Response could not be encoded within requested "
145 "envelope size limits."),
146 WSMAN_FAULTDETAIL_MAXENVELOPESIZE);
147 WsmFaultResponse faultResponse(
|
148 kumpf 1.7 response->getRelatesTo(),
149 response->getQueueId(),
|
150 kumpf 1.4 response->getHttpMethod(),
|
151 kumpf 1.7 response->getHttpCloseConnect(),
|
152 mike 1.11 response->getOmitXMLProcessingInstruction(),
|
153 kumpf 1.4 fault);
154
|
155 kumpf 1.8 return new SoapResponse(&faultResponse);
|
156 kumpf 1.4 }
157
|
158 kumpf 1.2 void WsmResponseEncoder::enqueue(WsmResponse* response)
159 {
160 PEG_METHOD_ENTER(TRC_WSMSERVER, "WsmResponseEncoder::enqueue()");
161 PEGASUS_ASSERT(response);
162
|
163 marek 1.3 PEG_TRACE((TRC_WSMSERVER, Tracer::LEVEL4,
|
164 kumpf 1.2 "WsmResponseEncoder::enqueue()- "
165 "response->getHttpCloseConnect() returned %d",
166 response->getHttpCloseConnect()));
167
|
168 kumpf 1.7 try
|
169 kumpf 1.2 {
|
170 anusha.kandepu 1.15 switch (response->getOperationType())
|
171 kumpf 1.4 {
172 case WS_TRANSFER_GET:
173 _encodeWxfGetResponse((WxfGetResponse*) response);
174 break;
175
176 case WS_TRANSFER_PUT:
177 _encodeWxfPutResponse((WxfPutResponse*) response);
178 break;
179
180 case WS_TRANSFER_CREATE:
181 _encodeWxfCreateResponse((WxfCreateResponse*) response);
182 break;
183
|
184 rohini.deshpande 1.13 case WS_SUBSCRIPTION_CREATE:
185 _encodeWxfSubCreateResponse((WxfSubCreateResponse*) response);
186 break;
187
|
188 kumpf 1.4 case WS_TRANSFER_DELETE:
189 _encodeWxfDeleteResponse((WxfDeleteResponse*) response);
190 break;
|
191 rohini.deshpande 1.13
192 case WS_SUBSCRIPTION_DELETE:
193 _encodeWxfSubDeleteResponse((WxfSubDeleteResponse*) response);
194 break;
|
195 kumpf 1.4
196 case WS_ENUMERATION_RELEASE:
197 _encodeWsenReleaseResponse((WsenReleaseResponse*) response);
198 break;
199
200 case WSM_FAULT:
201 _encodeWsmFaultResponse((WsmFaultResponse*) response);
202 break;
203
204 case SOAP_FAULT:
205 _encodeSoapFaultResponse((SoapFaultResponse*) response);
206 break;
207
|
208 mike 1.11 case WS_INVOKE:
209 _encodeWsInvokeResponse((WsInvokeResponse*)response);
210 break;
211
|
212 kumpf 1.8 case WS_ENUMERATION_ENUMERATE:
213 case WS_ENUMERATION_PULL:
214 // These cases are handled specially to allow for the message
215 // contents to be tuned according to the MaxEnvelopeSize value.
|
216 kumpf 1.4 default:
217 // Unexpected message type
|
218 dl.meetei 1.14 PEGASUS_UNREACHABLE(PEGASUS_ASSERT(0);)
|
219 kumpf 1.4 break;
220 }
221 }
222 catch (PEGASUS_STD(bad_alloc)&)
223 {
|
224 venkat.puvvada 1.10 MessageLoaderParms parms(
225 "WsmServer.WsmResponseEncoder.OUT_OF_MEMORY",
226 "A System error has occurred. Please retry the "
227 "WS-Management operation at a later time.");
228
229 Logger::put_l(
230 Logger::ERROR_LOG, System::CIMSERVER, Logger::SEVERE, parms);
|
231 mike 1.11
|
232 venkat.puvvada 1.10 MessageQueue* queue = MessageQueue::lookup(response->getQueueId());
233 HTTPConnection* httpQueue = dynamic_cast<HTTPConnection*>(queue);
234 PEGASUS_ASSERT(httpQueue);
235
236 // Handle the internal server error on this connection.
237 httpQueue->handleInternalServerError(0, true);
|
238 kumpf 1.2 }
239
240 PEG_METHOD_EXIT();
241 }
242
|
243 kumpf 1.4 void WsmResponseEncoder::_encodeWxfGetResponse(WxfGetResponse* response)
|
244 kumpf 1.2 {
|
245 kumpf 1.4 SoapResponse soapResponse(response);
|
246 kumpf 1.2 Buffer body;
|
247 mike 1.11 WsmWriter::appendInstanceElement(body, response->getResourceUri(),
248 response->getInstance(), PEGASUS_INSTANCE_NS, false);
|
249 kumpf 1.4 if (soapResponse.appendBodyContent(body))
250 {
251 _sendResponse(&soapResponse);
252 }
253 else
254 {
255 _sendUnreportableSuccess(response);
256 }
|
257 kumpf 1.2 }
258
|
259 kumpf 1.4 void WsmResponseEncoder::_encodeWxfPutResponse(WxfPutResponse* response)
|
260 kumpf 1.2 {
|
261 kumpf 1.4 SoapResponse soapResponse(response);
|
262 kumpf 1.2 Buffer headers;
263
264 // DSP0226 R6.5-1: A service receiving a message that contains the
265 // wsman:RequestEPR header block should return a response that contains
266 // a wsman:RequestedEPR header block. This block contains the most recent
267 // EPR of the resource being accessed or a status code if the service
268 // cannot determine or return the EPR. This EPR reflects any identity
269 // changes that may have occurred as a result of the current operation, as
270 // set forth in the following behavior. The header block in the
271 // corresponding response message has the following format:
272 // <wsman:RequestedEPR...>
273 // [ <wsa:EndpointReference>
274 // wsa:EndpointReferenceType
275 // </wsa:EndpointReference> |
276 // <wsman:EPRInvalid/> |
277 // <wsman:EPRUnknown/> ]
278 // </wsman:RequestedEPR>
279 if (response->getRequestedEPR())
280 {
281 WsmWriter::appendStartTag(
282 headers, WsmNamespaces::WS_MAN, STRLIT("RequestedEPR"));
283 kumpf 1.2 WsmWriter::appendStartTag(
|
284 kumpf 1.7 headers,
|
285 kumpf 1.4 WsmNamespaces::WS_ADDRESSING, STRLIT("EndpointReference"));
|
286 kumpf 1.2 WsmWriter::appendEPRElement(headers, response->getEPR());
287 WsmWriter::appendEndTag(
|
288 kumpf 1.7 headers,
|
289 kumpf 1.4 WsmNamespaces::WS_ADDRESSING, STRLIT("EndpointReference"));
|
290 kumpf 1.2 WsmWriter::appendEndTag(
291 headers, WsmNamespaces::WS_MAN, STRLIT("RequestedEPR"));
292 }
|
293 kumpf 1.4
294 if (soapResponse.appendHeader(headers))
295 {
296 _sendResponse(&soapResponse);
297 }
298 else
299 {
300 _sendUnreportableSuccess(response);
301 }
|
302 kumpf 1.2 }
303
|
304 kumpf 1.4 void WsmResponseEncoder::_encodeWxfCreateResponse(WxfCreateResponse* response)
|
305 kumpf 1.2 {
|
306 kumpf 1.4 SoapResponse soapResponse(response);
|
307 kumpf 1.2 Buffer body;
|
308 kumpf 1.4
|
309 kumpf 1.2 WsmWriter::appendStartTag(
310 body, WsmNamespaces::WS_TRANSFER, STRLIT("ResourceCreated"));
311 WsmWriter::appendEPRElement(body, response->getEPR());
312 WsmWriter::appendEndTag(
313 body, WsmNamespaces::WS_TRANSFER, STRLIT("ResourceCreated"));
|
314 kumpf 1.4
315 if (soapResponse.appendBodyContent(body))
316 {
317 _sendResponse(&soapResponse);
318 }
319 else
320 {
321 _sendUnreportableSuccess(response);
322 }
323 }
324
|
325 rohini.deshpande 1.13 void WsmResponseEncoder::_encodeWxfSubCreateResponse(
326 WxfSubCreateResponse* response)
327 {
328 SoapResponse soapResponse(response);
329 Buffer body;
330 WsmEndpointReference epr = response->getEPR();
331
332 WsmWriter::appendStartTag(
333 body, WsmNamespaces::WS_EVENTING, STRLIT("SubscribeResponse"));
334 WsmWriter::appendStartTag(
335 body, WsmNamespaces::WS_EVENTING, STRLIT("SubscriptionManager"));
336
337 WsmWriter::appendTagValue( body,
338 WsmNamespaces::WS_EVENTING,
339 STRLIT("Address"),
340 epr.address);
341
342 WsmWriter::appendStartTag(
343 body, WsmNamespaces::WS_EVENTING, STRLIT("ReferenceParameters"));
344
345 // This is the identifier of the Subscription. Subscription name is
346 rohini.deshpande 1.13 // the subscribe request's messageID(without the uuid part) which
347 // is same as relates to field of the response.
348 String subId = response->getRelatesTo().subString(PEGASUS_WS_UUID_LENGTH);
349 WsmWriter::appendTagValue( body,
350 WsmNamespaces::WS_EVENTING,
351 STRLIT("Identifier"),
352 subId);
353
354 WsmWriter::appendEndTag(
355 body, WsmNamespaces::WS_EVENTING, STRLIT("ReferenceParameters"));
356 WsmWriter::appendEndTag(
357 body, WsmNamespaces::WS_EVENTING, STRLIT("SubscriptionManager"));
358
359 CIMDateTime dt;
360 String dat;
361
362 response->getSubscriptionDuration(dt);
363
364 if(WsmUtils::toMicroSecondString(dt) != "0")
365 {
366 CimToWsmResponseMapper Map;
367 rohini.deshpande 1.13 Map.convertCimToWsmDatetime(dt, dat);
368 /**
369 Get the expires field. This is as duration in the
370 IndicationSubscription instance, with the units as microseconds.
371 We get it as a string, then convert it to Uint64, then convert
372 that to the CIMDatetime interval format. That is converted to the
373 WsmDatetime format, which is something like P1DT1M1S.
374 */
375 WsmWriter::appendTagValue( body,
376 WsmNamespaces::WS_EVENTING,
377 STRLIT("Expires"),
378 dat);
379 }
380 WsmWriter::appendEndTag(
381 body, WsmNamespaces::WS_EVENTING, STRLIT("SubscribeResponse"));
382
383 if (soapResponse.appendBodyContent(body))
384 {
385 _sendResponse(&soapResponse);
386 }
387 else
388 rohini.deshpande 1.13 {
389 _sendUnreportableSuccess(response);
390 }
391 }
392
|
393 kumpf 1.4 void WsmResponseEncoder::_encodeWxfDeleteResponse(WxfDeleteResponse* response)
394 {
395 SoapResponse soapResponse(response);
396 _sendResponse(&soapResponse);
397 }
398
|
399 rohini.deshpande 1.13 void WsmResponseEncoder::_encodeWxfSubDeleteResponse(
400 WxfSubDeleteResponse* response)
401 {
402 SoapResponse soapResponse(response);
403 _sendResponse(&soapResponse);
404 }
405
406
|
407 kumpf 1.8 SoapResponse* WsmResponseEncoder::encodeWsenEnumerateResponse(
408 WsenEnumerateResponse* response,
409 Uint32& numDataItemsEncoded)
|
410 kumpf 1.4 {
|
411 karl 1.12 PEG_METHOD_ENTER(TRC_WSMSERVER,
412 "WsmResponseEncoder::encodeWsenEnumerateResponse");
413
|
414 kumpf 1.8 AutoPtr<SoapResponse> soapResponse(new SoapResponse(response));
|
415 kumpf 1.4 Buffer headers;
416
417 if (response->requestedItemCount())
418 {
419 WsmWriter::appendStartTag(
420 headers, WsmNamespaces::WS_MAN, STRLIT("TotalItemsCountEstimate"));
421 WsmWriter::append(headers, response->getItemCount());
422 WsmWriter::appendEndTag(
423 headers, WsmNamespaces::WS_MAN, STRLIT("TotalItemsCountEstimate"));
424 }
425
426 if (!_encodeEnumerationData(
|
427 kumpf 1.8 *soapResponse.get(),
|
428 kumpf 1.7 headers,
|
429 kumpf 1.4 WS_ENUMERATION_ENUMERATE,
430 response->getEnumerationContext(),
431 response->isComplete(),
|
432 kumpf 1.8 response->getEnumerationData(),
|
433 mike 1.11 numDataItemsEncoded,
434 response->getResourceUri()))
|
435 kumpf 1.4 {
|
436 kumpf 1.8 soapResponse.reset(_buildEncodingLimitFault(response));
|
437 kumpf 1.4 }
438
|
439 karl 1.12 PEG_METHOD_EXIT();
|
440 kumpf 1.8 return soapResponse.release();
|
441 kumpf 1.4 }
442
|
443 kumpf 1.8 SoapResponse* WsmResponseEncoder::encodeWsenPullResponse(
444 WsenPullResponse* response,
445 Uint32& numDataItemsEncoded)
|
446 kumpf 1.4 {
|
447 kumpf 1.8 AutoPtr<SoapResponse> soapResponse(new SoapResponse(response));
|
448 kumpf 1.4 Buffer headers;
449
450 if (!_encodeEnumerationData(
|
451 kumpf 1.8 *soapResponse.get(),
|
452 kumpf 1.7 headers,
|
453 kumpf 1.4 WS_ENUMERATION_PULL,
454 response->getEnumerationContext(),
455 response->isComplete(),
|
456 kumpf 1.8 response->getEnumerationData(),
|
457 mike 1.11 numDataItemsEncoded,
458 response->getResourceUri()))
|
459 kumpf 1.4 {
|
460 kumpf 1.8 soapResponse.reset(_buildEncodingLimitFault(response));
|
461 kumpf 1.4 }
462
|
463 kumpf 1.8 return soapResponse.release();
|
464 kumpf 1.4 }
465
466 Boolean WsmResponseEncoder::_encodeEnumerationData(
467 SoapResponse& soapResponse,
468 Buffer& headers,
469 WsmOperationType operation,
470 Uint64 contextId,
471 Boolean isComplete,
|
472 kumpf 1.8 WsenEnumerationData& data,
|
473 mike 1.11 Uint32& numDataItemsEncoded,
474 const String& resourceUri)
|
475 kumpf 1.4 {
|
476 karl 1.12 PEG_METHOD_ENTER(TRC_WSMSERVER,
477 "WsmResponseEncoder::_encodeEnumerationData");
|
478 kumpf 1.4 Buffer bodyHeader, bodyTrailer;
479
480 PEGASUS_ASSERT(operation == WS_ENUMERATION_ENUMERATE ||
481 operation == WS_ENUMERATION_PULL);
482
|
483 kumpf 1.8 numDataItemsEncoded = 0;
484
|
485 kumpf 1.4 WsmWriter::appendStartTag(
|
486 kumpf 1.7 bodyHeader, WsmNamespaces::WS_ENUMERATION,
487 operation == WS_ENUMERATION_ENUMERATE ?
|
488 kumpf 1.4 STRLIT("EnumerateResponse") : STRLIT("PullResponse"));
489
|
490 kumpf 1.9 // Include an EnumerationContext in the response. If this response
491 // completes the enumeration, this element will be modified/removed below.
492 Uint32 ecPos = bodyHeader.size();
493 WsmWriter::appendStartTag(
494 bodyHeader, WsmNamespaces::WS_ENUMERATION,
495 STRLIT("EnumerationContext"));
496 WsmWriter::append(bodyHeader, contextId);
497 WsmWriter::appendEndTag(
498 bodyHeader, WsmNamespaces::WS_ENUMERATION,
499 STRLIT("EnumerationContext"));
500 Uint32 ecSize = bodyHeader.size() - ecPos;
|
501 kumpf 1.4
|
502 karl 1.12 PEG_TRACE((TRC_WSMSERVER, Tracer::LEVEL4,
503 "Encoder data size %u ",data.getSize()));
504
|
505 kumpf 1.4 if (data.getSize() > 0)
506 {
507 WsmWriter::appendStartTag(
|
508 kumpf 1.7 bodyHeader,
509 operation == WS_ENUMERATION_ENUMERATE ?
510 WsmNamespaces::WS_MAN : WsmNamespaces::WS_ENUMERATION,
|
511 kumpf 1.4 STRLIT("Items"));
512 WsmWriter::appendEndTag(
|
513 kumpf 1.7 bodyTrailer,
514 operation == WS_ENUMERATION_ENUMERATE ?
515 WsmNamespaces::WS_MAN : WsmNamespaces::WS_ENUMERATION,
|
516 kumpf 1.4 STRLIT("Items"));
517 }
518
519 Uint32 eosPos = bodyTrailer.size();
520 Uint32 eosSize = 0;
521 if (isComplete)
522 {
|
523 kumpf 1.9 // Write an EndOfSequence element with the expectation that all the
524 // elements fit within MaxEnvelopeSize. This element will be removed
525 // below if the assumption proves untrue. This element is written
526 // up front before all the response data was included, because adding
527 // the EndOfSequence element later might push the response size past
528 // the MaxEnvelopeSize.
|
529 kumpf 1.4 WsmWriter::appendEmptyTag(
|
530 kumpf 1.7 bodyTrailer,
531 operation == WS_ENUMERATION_ENUMERATE ?
532 WsmNamespaces::WS_MAN : WsmNamespaces::WS_ENUMERATION,
|
533 kumpf 1.4 STRLIT("EndOfSequence"));
534 eosSize = bodyTrailer.size() - eosPos;
535 }
536
537 WsmWriter::appendEndTag(
|
538 kumpf 1.7 bodyTrailer, WsmNamespaces::WS_ENUMERATION,
539 operation == WS_ENUMERATION_ENUMERATE ?
|
540 kumpf 1.4 STRLIT("EnumerateResponse") : STRLIT("PullResponse"));
541
542 // Fault the request if it can't be encoded within the limits
543 if (!soapResponse.appendHeader(headers) ||
544 !soapResponse.appendBodyHeader(bodyHeader) ||
545 !soapResponse.appendBodyTrailer(bodyTrailer))
546 {
547 return false;
548 }
549
550 // Now add the list of items
|
551 mike 1.11 Uint32 i = 0;
|
552 kumpf 1.4
553 if (data.enumerationMode == WSEN_EM_OBJECT)
554 {
555 for (i = 0; i < data.instances.size(); i++)
556 {
557 Buffer body;
558
559 if (data.polymorphismMode == WSMB_PM_EXCLUDE_SUBCLASS_PROPERTIES)
560 {
561 // The response does not contain the subclass properties, but
|
562 kumpf 1.7 // the class name is still that of the subclass.
|
563 kumpf 1.4 // Replace it here.
564 data.instances[i].setClassName(
565 WsmToCimRequestMapper::convertResourceUriToClassName(
566 data.classUri).getString());
567 }
568
|
569 mike 1.11 WsmWriter::appendInstanceElement(body, resourceUri,
570 data.instances[i], PEGASUS_INSTANCE_NS, false);
571
|
572 kumpf 1.4 if (!soapResponse.appendBodyContent(body))
573 {
574 break;
575 }
576 }
577 }
578 else if (data.enumerationMode == WSEN_EM_EPR)
579 {
580 for (i = 0; i < data.eprs.size(); i++)
581 {
582 Buffer body;
583
584 WsmWriter::appendStartTag(
|
585 kumpf 1.7 body,
586 WsmNamespaces::WS_ADDRESSING,
|
587 kumpf 1.4 STRLIT("EndpointReference"));
588 WsmWriter::appendEPRElement(body, data.eprs[i]);
589 WsmWriter::appendEndTag(
|
590 kumpf 1.7 body,
591 WsmNamespaces::WS_ADDRESSING,
|
592 kumpf 1.4 STRLIT("EndpointReference"));
593 if (!soapResponse.appendBodyContent(body))
594 {
595 break;
596 }
597 }
598 }
599 else if (data.enumerationMode == WSEN_EM_OBJECT_AND_EPR)
600 {
601 for (i = 0; i < data.instances.size(); i++)
602 {
603 Buffer body;
604
605 WsmWriter::appendStartTag(
|
606 kumpf 1.7 body,
607 WsmNamespaces::WS_MAN,
|
608 kumpf 1.4 STRLIT("Item"));
609
610 if (data.polymorphismMode == WSMB_PM_EXCLUDE_SUBCLASS_PROPERTIES)
611 {
612 // The response does not contain the subclass properties, but
|
613 kumpf 1.7 // the class name is still that of the subclass.
|
614 kumpf 1.4 // Replace it here.
615 data.instances[i].setClassName(
616 WsmToCimRequestMapper::convertResourceUriToClassName(
617 data.classUri).getString());
618 }
619
|
620 mike 1.11 WsmWriter::appendInstanceElement(body, resourceUri,
621 data.instances[i], PEGASUS_INSTANCE_NS, false);
|
622 kumpf 1.7
|
623 kumpf 1.4 WsmWriter::appendStartTag(
|
624 kumpf 1.7 body,
625 WsmNamespaces::WS_ADDRESSING,
|
626 kumpf 1.4 STRLIT("EndpointReference"));
627 WsmWriter::appendEPRElement(body, data.eprs[i]);
628 WsmWriter::appendEndTag(
|
629 kumpf 1.7 body,
630 WsmNamespaces::WS_ADDRESSING,
|
631 kumpf 1.4 STRLIT("EndpointReference"));
632
633 WsmWriter::appendEndTag(
|
634 kumpf 1.7 body,
635 WsmNamespaces::WS_MAN,
|
636 kumpf 1.4 STRLIT("Item"));
637
638 if (!soapResponse.appendBodyContent(body))
639 {
640 break;
641 }
642 }
643 }
644 else
645 {
|
646 dl.meetei 1.14 PEGASUS_UNREACHABLE(PEGASUS_ASSERT(0);)
|
647 kumpf 1.4 }
648
|
649 kumpf 1.8 numDataItemsEncoded = i;
650
|
651 kumpf 1.4 // If the list is not empty, but none of the items have been successfully
652 // added to the soapResponse, fault the request because it cannot be
653 // encoded within the specified limits.
|
654 kumpf 1.8 if (data.getSize() > 0 && numDataItemsEncoded == 0)
|
655 kumpf 1.4 {
656 return false;
657 }
658
|
659 kumpf 1.9 if (isComplete)
|
660 kumpf 1.4 {
|
661 kumpf 1.9 if (data.getSize() > numDataItemsEncoded)
662 {
663 // The request is complete but could not be encoded within
664 // MaxEnvelopeSize. Clear EndOfSequence tag.
665 soapResponse.getBodyTrailer().remove(eosPos, eosSize);
666 }
667 else
668 {
669 // All the enumeration results were written. Update the
670 // EnumerationContext element.
671 if (operation == WS_ENUMERATION_ENUMERATE)
672 {
673 // DSP0226 R8.2.3-5: A conformant service that supports
674 // optimized enumeration and has not returned all items of the
675 // enumeration sequence in the wsen:EnumerateResponse message
676 // shall return a wsen:EnumerationContext element that is
677 // initialized such that a subsequent wsen:Pull message will
678 // return the set of items after those returned in the
679 // wsen:EnumerateResponse. If all items of the enumeration
680 // sequence have been returned in the wsen:EnumerateResponse
681 // message, the service should return an empty
682 kumpf 1.9 // wsen:EnumerationContext element and shall return the
683 // wsman:EndOfSequence element in the response.
684 Buffer emptyEc(50);
685 WsmWriter::appendEmptyTag(
686 emptyEc, WsmNamespaces::WS_ENUMERATION,
687 STRLIT("EnumerationContext"));
688 soapResponse.getBodyHeader().remove(ecPos, ecSize);
689 soapResponse.getBodyHeader().insert(
690 ecPos, emptyEc.getData(), emptyEc.size());
691 }
692 else
693 {
694 // DSP0226 R8.4-8: If the wsen:EndOfSequence marker occurs in
695 // the wsen:PullResponse message, the wsen:EnumerationContext
696 // element shall be omitted, as the enumeration has completed.
697 // The client cannot subsequently issue a wsen:Release message.
698 soapResponse.getBodyHeader().remove(ecPos, ecSize);
699 }
700 }
|
701 kumpf 1.4 }
|
702 karl 1.12 PEG_METHOD_EXIT();
|
703 kumpf 1.4 return true;
|
704 kumpf 1.2 }
705
|
706 kumpf 1.4 void WsmResponseEncoder::_encodeWsenReleaseResponse(
707 WsenReleaseResponse* response)
|
708 kumpf 1.2 {
|
709 kumpf 1.4 SoapResponse soapResponse(response);
710 _sendResponse(&soapResponse);
|
711 kumpf 1.2 }
712
713 void WsmResponseEncoder::_encodeWsmFaultResponse(WsmFaultResponse* response)
714 {
|
715 kumpf 1.4 SoapResponse soapResponse(response);
716 _sendResponse(&soapResponse);
|
717 kumpf 1.2 }
718
719 void WsmResponseEncoder::_encodeSoapFaultResponse(SoapFaultResponse* response)
720 {
|
721 kumpf 1.4 SoapResponse soapResponse(response);
722 _sendResponse(&soapResponse);
|
723 kumpf 1.2 }
724
|
725 mike 1.11 void WsmResponseEncoder::_encodeWsInvokeResponse(
726 WsInvokeResponse* response)
727 {
728 SoapResponse* soapResponse = new SoapResponse(response);
729
730 Buffer body;
731 WsmWriter::appendInvokeOutputElement(
732 body,
733 response->resourceUri,
734 response->className,
735 response->methodName,
736 response->instance,
737 PEGASUS_INVOKE_NS);
738
739 if (soapResponse->appendBodyContent(body))
740 {
741 _sendResponse(soapResponse);
742 }
743 else
744 {
745 delete soapResponse;
746 mike 1.11 _sendUnreportableSuccess(response);
747 }
748 }
749
|
750 kumpf 1.2 PEGASUS_NAMESPACE_END
|