(file) Return to WsmResponseEncoder.cpp CVS log (file) (dir) Up to [Pegasus] / pegasus / src / Pegasus / WsmServer

  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

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2