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

  1 karl  1.40 //%2006////////////////////////////////////////////////////////////////////////
  2 mike  1.2  //
  3 karl  1.30 // 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 karl  1.20 // IBM Corp.; EMC Corporation, The Open Group.
  7 karl  1.30 // Copyright (c) 2004 BMC Software; Hewlett-Packard Development Company, L.P.;
  8            // IBM Corp.; EMC Corporation; VERITAS Software Corporation; The Open Group.
  9 karl  1.32 // Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.;
 10            // EMC Corporation; VERITAS Software Corporation; The Open Group.
 11 karl  1.40 // Copyright (c) 2006 Hewlett-Packard Development Company, L.P.; IBM Corp.;
 12            // EMC Corporation; Symantec Corporation; The Open Group.
 13 mike  1.2  //
 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 kumpf 1.10 // 
 21 mike  1.2  // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
 22            // 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            // Author: Mike Brasher (mbrasher@bmc.com)
 33            //
 34            // Modified By: Nitin Upasani, Hewlett-Packard Company (Nitin_Upasani@hp.com)
 35            //              Nag Boranna, Hewlett-Packard Company (nagaraja_boranna@hp.com)
 36 kumpf 1.13 //              Carol Ann Krug Graves, Hewlett-Packard Company
 37            //                (carolann_graves@hp.com)
 38 kumpf 1.14 //              Yi Zhou, Hewlett-Packard Company (yi_zhou@hp.com)
 39 dj.gorey 1.24 //              Dan Gorey (djgorey@us.ibm.com)
 40 se.gupta 1.27 //				Seema Gupta (gseema@in.ibm.com) for PEP135
 41 kumpf    1.31 //              Roger Kumpf, Hewlett-Packard Company (roger_kumpf@hp.com)
 42 joyce.j  1.33 //              Josephine Eskaline Joyce, IBM (jojustin@in.ibm.com) for PEP#101
 43 j.alex   1.37 //              John Alex, IBM (johnalex@us.ibm.com) - Bug#2290
 44 dj.gorey 1.24 //
 45 mike     1.2  //%/////////////////////////////////////////////////////////////////////////////
 46               
 47               #include <Pegasus/Common/Config.h>
 48 kumpf    1.7  #include <Pegasus/Common/Constants.h>
 49 mike     1.2  #include <Pegasus/Common/HTTPConnection.h>
 50               #include <Pegasus/Common/XmlWriter.h>
 51               #include <Pegasus/Common/TimeValue.h>
 52               #include <Pegasus/Common/Exception.h>
 53 kumpf    1.8  #include <Pegasus/Common/PegasusVersion.h>
 54               
 55 mike     1.2  #include "CIMExportRequestEncoder.h"
 56               #include "CIMExportResponseDecoder.h"
 57               #include "CIMExportClient.h"
 58               
 59 humberto 1.18 // l10n
 60               #include <Pegasus/Common/MessageLoader.h>
 61               
 62 mike     1.2  #include <iostream>
 63               
 64               PEGASUS_USING_STD;
 65               
 66               PEGASUS_NAMESPACE_BEGIN
 67               
 68               CIMExportClient::CIMExportClient(
 69 mday     1.4     Monitor* monitor,
 70                  HTTPConnector* httpConnector,
 71 kumpf    1.12    Uint32 timeoutMilliseconds)
 72 mday     1.4     : 
 73 kumpf    1.14    MessageQueue(PEGASUS_QUEUENAME_EXPORTCLIENT),
 74                  _monitor(monitor),
 75 mday     1.3     _httpConnector(httpConnector),
 76 kumpf    1.14    _httpConnection(0),
 77 kumpf    1.12    _timeoutMilliseconds(timeoutMilliseconds),
 78 mday     1.3     _connected(false),
 79                  _responseDecoder(0),
 80                  _requestEncoder(0)
 81 mike     1.2  {
 82 kumpf    1.26     PEG_METHOD_ENTER (TRC_EXPORT_CLIENT, "CIMExportClient::CIMExportClient()");
 83                   PEG_METHOD_EXIT();
 84 mike     1.2  }
 85               
 86               CIMExportClient::~CIMExportClient()
 87               {
 88 kumpf    1.26     PEG_METHOD_ENTER (TRC_EXPORT_CLIENT, "CIMExportClient::~CIMExportClient()");
 89 konrad.r 1.15 
 90 kumpf    1.26     disconnect();
 91               
 92                   PEG_METHOD_EXIT();
 93 mike     1.2  }
 94               
 95 kumpf    1.14 void CIMExportClient::_connect()
 96 mday     1.4  {
 97 kumpf    1.34     PEG_METHOD_ENTER (TRC_EXPORT_CLIENT, "CIMExportClient::_connect()");
 98 kumpf    1.26 
 99 kumpf    1.34     // Create response decoder:
100 mike     1.2      
101 kumpf    1.34     _responseDecoder = new CIMExportResponseDecoder(
102                       this, _requestEncoder, &_authenticator);
103 mike     1.2      
104 kumpf    1.34     // Attempt to establish a connection:
105 mike     1.2      
106 kumpf    1.34     try
107                   {
108                       _httpConnection = _httpConnector->connect(_connectHost, 
109                           _connectPortNumber, 
110                           _connectSSLContext.get(),
111                           _responseDecoder);
112                   }
113                   catch (...)
114                   {
115                       // Some possible exceptions are CannotCreateSocketException,
116                       // CannotConnectException, and InvalidLocatorException
117 kumpf    1.14         delete _responseDecoder;
118 kumpf    1.26         PEG_METHOD_EXIT();
119 kumpf    1.34         throw;
120                   }
121 mike     1.2      
122 kumpf    1.34     // Create request encoder:
123 mike     1.2      
124 kumpf    1.34     String connectHost = _connectHost;
125                   if (connectHost.size())
126                   {
127                       char portStr[32];
128                       sprintf(portStr, ":%u", _connectPortNumber);
129                       connectHost.append(portStr);
130                   }
131 kumpf    1.29 
132 kumpf    1.34     _requestEncoder = new CIMExportRequestEncoder(
133                       _httpConnection, connectHost, &_authenticator);
134 mike     1.2  
135 kumpf    1.34     _responseDecoder->setEncoderQueue(_requestEncoder);    
136 mike     1.2  
137 kumpf    1.34     _connected = true;
138 kumpf    1.26 
139 kumpf    1.34     PEG_METHOD_EXIT();
140 mike     1.2  }
141               
142 kumpf    1.23 void CIMExportClient::_disconnect()
143               {
144 kumpf    1.26     PEG_METHOD_ENTER (TRC_EXPORT_CLIENT, "CIMExportClient::_disconnect()");
145               
146 kumpf    1.23     if (_connected)
147                   {
148                       //
149                       // destroy response decoder
150                       //
151 kumpf    1.41         delete _responseDecoder;
152                       _responseDecoder = 0;
153 kumpf    1.23 
154                       //
155                       // Close the connection
156                       //
157                       if (_httpConnector)
158                       {
159                           _httpConnector->disconnect(_httpConnection);
160                           _httpConnection = 0;
161                       }
162 dj.gorey 1.24           
163 kumpf    1.23 
164                       //
165                       // destroy request encoder
166                       //
167 kumpf    1.41         delete _requestEncoder;
168                       _requestEncoder = 0;
169 kumpf    1.23 
170                       _connected = false;
171                   }
172 kumpf    1.26     PEG_METHOD_EXIT();
173 kumpf    1.23 }
174               
175 kumpf    1.14 void CIMExportClient::_reconnect()
176               {
177 kumpf    1.26     PEG_METHOD_ENTER (TRC_EXPORT_CLIENT, "CIMExportClient::_reconnect()");
178 kumpf    1.23     _disconnect();
179                   _authenticator.setRequestMessage(0);
180 kumpf    1.14     _connect();
181 kumpf    1.26     PEG_METHOD_EXIT();
182 kumpf    1.14 }
183               
184               void CIMExportClient::connect(
185                   const String& host,
186                   const Uint32 portNumber)
187               {
188 kumpf    1.26    PEG_METHOD_ENTER (TRC_EXPORT_CLIENT, "CIMExportClient::connect()");
189 kumpf    1.14    // If already connected, bail out!
190                   
191                  if (_connected)
192 kumpf    1.26    {
193                     PEG_METHOD_EXIT();
194 kumpf    1.14       throw AlreadyConnectedException();
195 kumpf    1.26    }
196 kumpf    1.14     
197                   //
198                   // If the host is empty, set hostName to "localhost"
199                   //
200                   String hostName = host;
201                   if (host == String::EMPTY)
202                   {
203                       hostName = "localhost";
204                   }
205               
206                   //
207                   // Set authentication information
208                   //
209 kumpf    1.23     _authenticator.clear();
210 kumpf    1.14 
211 kumpf    1.28     _connectSSLContext.reset(0);
212 kumpf    1.14     _connectHost = hostName;
213                   _connectPortNumber = portNumber;
214               
215                   _connect();
216 kumpf    1.26     PEG_METHOD_EXIT();
217 kumpf    1.14 }
218               
219 kumpf    1.17 void CIMExportClient::connect(
220                   const String& host,
221                   const Uint32 portNumber,
222                   const SSLContext& sslContext)
223               {
224 kumpf    1.26     PEG_METHOD_ENTER (TRC_EXPORT_CLIENT, "CIMExportClient::connect()");
225               
226                   // If already connected, bail out!
227 kumpf    1.17 
228 kumpf    1.26     if (_connected)
229                   {
230                      PEG_METHOD_EXIT();
231                      throw AlreadyConnectedException();
232                   }
233 kumpf    1.17 
234                   //
235                   // If the host is empty, set hostName to "localhost"
236                   //
237                   String hostName = host;
238                   if (host == String::EMPTY)
239                   {
240                       hostName = "localhost";
241                   }
242               
243                   //
244                   // Set authentication information
245                   //
246 kumpf    1.23     _authenticator.clear();
247 kumpf    1.17 
248 kumpf    1.28     _connectSSLContext.reset(new SSLContext(sslContext));
249 kumpf    1.17     _connectHost = hostName;
250                   _connectPortNumber = portNumber;
251               
252                   try
253                   {
254                       _connect();
255                   }
256 kumpf    1.34     catch (...)
257 kumpf    1.17     {
258 kumpf    1.28         _connectSSLContext.reset();
259 kumpf    1.26         PEG_METHOD_EXIT();
260 kumpf    1.17         throw;
261                   }
262 kumpf    1.26     PEG_METHOD_EXIT();
263 kumpf    1.17 }
264               
265 kumpf    1.14 void CIMExportClient::disconnect()
266 mike     1.2  {
267 kumpf    1.26     PEG_METHOD_ENTER (TRC_EXPORT_CLIENT, "CIMExportClient::disconnect()");
268 kumpf    1.23     _disconnect();
269                   _authenticator.clear();
270 kumpf    1.28     _connectSSLContext.reset();
271 kumpf    1.26     PEG_METHOD_EXIT();
272 mike     1.2  }
273               
274               void CIMExportClient::exportIndication(
275 mday     1.4     const String& url,
276 chuck    1.16    const CIMInstance& instanceName,
277 kumpf    1.39    const ContentLanguageList& contentLanguages)
278 mike     1.2  {
279 carolann.graves 1.35     PEG_METHOD_ENTER (TRC_EXPORT_CLIENT, "CIMExportClient::exportIndication()");
280 kumpf           1.26 
281 carolann.graves 1.35     try
282                          {
283                              // encode request
284                              // l10n  
285                              CIMRequestMessage* request = new CIMExportIndicationRequestMessage(
286                                  String::EMPTY,
287                                  url,
288                                  instanceName,
289                                  QueueIdStack(),
290                                  String::EMPTY,
291                                  String::EMPTY);
292 se.gupta        1.27 
293 carolann.graves 1.35         request->operationContext.set
294                                  (ContentLanguageListContainer(contentLanguages));
295 mike            1.2  
296 carolann.graves 1.35         Message* message = _doRequest(request,
297                                  CIM_EXPORT_INDICATION_RESPONSE_MESSAGE);
298 mike            1.2  
299 carolann.graves 1.35         CIMExportIndicationResponseMessage* response = 
300                                  (CIMExportIndicationResponseMessage*)message;
301 mike            1.2      
302 carolann.graves 1.35         AutoPtr<CIMExportIndicationResponseMessage> ap(response);
303                          }
304                          catch (const Exception & e)
305                          {
306                              PEG_TRACE_STRING (TRC_DISCARDED_DATA, Tracer::LEVEL4, 
307                                  "Failed to export indication: " + e.getMessage ());
308                              throw;
309                          }
310                          catch (...)
311                          {
312                              PEG_TRACE_STRING (TRC_DISCARDED_DATA, Tracer::LEVEL4, 
313                                  "Failed to export indication");
314                              throw;
315                          }
316 kumpf           1.26 
317 carolann.graves 1.35     PEG_METHOD_EXIT();
318 mike            1.2  }
319                      
320 kumpf           1.14 Message* CIMExportClient::_doRequest(
321                          CIMRequestMessage * request,
322                          const Uint32 expectedResponseMessageType
323                      )
324 mike            1.2  {
325 kumpf           1.26     PEG_METHOD_ENTER (TRC_EXPORT_CLIENT, "CIMExportClient::_doRequest()");
326                      
327 kumpf           1.14     if (!_connected)
328                          {
329                             delete request;
330 kumpf           1.26        PEG_METHOD_EXIT();
331 kumpf           1.14        throw NotConnectedException();
332                          }
333                          
334                          String messageId = XmlWriter::getNextMessageId();
335                          const_cast<String &>(request->messageId) = messageId;
336                      
337 kumpf           1.23     _authenticator.setRequestMessage(0);
338 kumpf           1.14 
339                          // ATTN-RK-P2-20020416: We should probably clear out the queue first.
340                          PEGASUS_ASSERT(getCount() == 0);  // Shouldn't be any messages in our queue
341                      
342                          //
343 kumpf           1.22     //  Set HTTP method in request to POST
344 kumpf           1.14     //
345 kumpf           1.22     request->setHttpMethod (HTTP_METHOD__POST);
346 kumpf           1.14 
347                          _requestEncoder->enqueue(request);
348                      
349                          Uint64 startMilliseconds = TimeValue::getCurrentTime().toMilliseconds();
350                          Uint64 nowMilliseconds = startMilliseconds;
351                          Uint64 stopMilliseconds = nowMilliseconds + _timeoutMilliseconds;
352                      
353                          while (nowMilliseconds < stopMilliseconds)
354                          {
355                      	//
356                      	// Wait until the timeout expires or an event occurs:
357                      	//
358 kumpf           1.31         _monitor->run(Uint32(stopMilliseconds - nowMilliseconds));
359 kumpf           1.14        
360                      	//
361                      	// Check to see if incoming queue has a message
362                      	//
363                      
364                      	Message* response = dequeue();
365                      
366                      	if (response)
367                      	{
368                                  // Shouldn't be any more messages in our queue
369                                  PEGASUS_ASSERT(getCount() == 0);
370                      
371                                  //
372 kumpf           1.21             //  Future:  If M-POST is used and HTTP response is 501 Not
373                                  //  Implemented or 510 Not Extended, retry with POST method
374 kumpf           1.14             //
375 j.alex          1.37             //
376                      
377                                  // Reconnect to reset the connection
378                                  // if Server response contained a Connection: Close Header
379                                  //
380 j.alex          1.38             if (response->getCloseConnect() == true){
381                                      _reconnect();
382                                      response->setCloseConnect(false);
383 j.alex          1.37             }
384                      
385 kumpf           1.14 
386                                  if (response->getType() == CLIENT_EXCEPTION_MESSAGE)
387                                  {
388                                      Exception* clientException =
389                                          ((ClientExceptionMessage*)response)->clientException;
390                                      delete response;
391 kumpf           1.26                 PEG_TRACE_STRING(TRC_EXPORT_CLIENT, Tracer::LEVEL4, "Client Exception Message received.");
392 kumpf           1.21 
393 joyce.j         1.33                 AutoPtr<Exception> d(clientException);
394 kumpf           1.21 
395                                      //
396                                      // Determine and throw the specific class of client exception
397                                      //
398                      
399                                      CIMClientMalformedHTTPException* malformedHTTPException =
400                                          dynamic_cast<CIMClientMalformedHTTPException*>(
401                                              clientException);
402                                      if (malformedHTTPException)
403                                      {
404 kumpf           1.26                     PEG_METHOD_EXIT();
405 kumpf           1.21                     throw *malformedHTTPException;
406                                      }
407                      
408                                      CIMClientHTTPErrorException* httpErrorException =
409                                          dynamic_cast<CIMClientHTTPErrorException*>(
410                                              clientException);
411                                      if (httpErrorException)
412                                      {
413 kumpf           1.26                     PEG_METHOD_EXIT();
414 kumpf           1.21                     throw *httpErrorException;
415                                      }
416                      
417                                      CIMClientXmlException* xmlException =
418                                          dynamic_cast<CIMClientXmlException*>(clientException);
419                                      if (xmlException)
420                                      {
421 kumpf           1.26                     PEG_METHOD_EXIT();
422 kumpf           1.21                     throw *xmlException;
423                                      }
424                      
425                                      CIMClientResponseException* responseException =
426                                          dynamic_cast<CIMClientResponseException*>(clientException);
427                                      if (responseException)
428                                      {
429 kumpf           1.26                     PEG_METHOD_EXIT();
430 kumpf           1.21                     throw *responseException;
431                                      }
432                      
433 kumpf           1.26                 PEG_METHOD_EXIT();
434 kumpf           1.14                 throw *clientException;
435                                  }
436                                  else if (response->getType() == expectedResponseMessageType)
437                                  {
438 kumpf           1.26                 PEG_TRACE_STRING(TRC_EXPORT_CLIENT, Tracer::LEVEL4, 
439 carolann.graves 1.35                     "Received expected indication response message.");
440 kumpf           1.14                 CIMResponseMessage* cimResponse = (CIMResponseMessage*)response;
441                                      if (cimResponse->messageId != messageId)
442                                      {
443 humberto        1.18 		  // l10n
444                      		  
445                      		  // CIMClientResponseException responseException(
446                      		  //   String("Mismatched response message ID:  Got \"") +
447                      		  //    cimResponse->messageId + "\", expected \"" +
448                      		  //    messageId + "\".");
449                      
450                      		  MessageLoaderParms mlParms("ExportClient.CIMExportClient.MISMATCHED_RESPONSE_ID", 
451 kumpf           1.26                       "Mismatched response message ID:  Got \"$0\", expected \"$1\".", 
452                                            cimResponse->messageId, messageId);
453 humberto        1.18 		  String mlString(MessageLoader::getMessage(mlParms));
454                      
455                      		  CIMClientResponseException responseException(mlString);
456                      
457                      		  delete response;
458 kumpf           1.26                   PEG_METHOD_EXIT();
459 humberto        1.18 		  throw responseException;
460 kumpf           1.14                 }
461                                      if (cimResponse->cimException.getCode() != CIM_ERR_SUCCESS)
462                                      {
463 kumpf           1.26                     PEG_TRACE_STRING(TRC_EXPORT_CLIENT, Tracer::LEVEL4, 
464                                              "Received indication failure message.");
465 kumpf           1.14                     CIMException cimException(
466                                              cimResponse->cimException.getCode(),
467                                              cimResponse->cimException.getMessage());
468                                          delete response;
469 kumpf           1.26                     PEG_METHOD_EXIT();
470 kumpf           1.14 	            throw cimException;
471                                      }
472 kumpf           1.26                 PEG_METHOD_EXIT();
473 kumpf           1.14                 return response;
474                                  }
475 j.alex          1.38             else if (dynamic_cast<CIMRequestMessage*>(response) != 0)
476                                  {
477                                      // Respond to an authentication challenge
478                                      _requestEncoder->enqueue(response);
479                                      nowMilliseconds = TimeValue::getCurrentTime().toMilliseconds();
480                                      stopMilliseconds = nowMilliseconds + _timeoutMilliseconds;
481                                      continue;
482                                  }
483 kumpf           1.14             else
484                                  {
485 humberto        1.18 	      // l10n
486                      
487                      	      // CIMClientResponseException responseException(
488                      	      //   "Mismatched response message type.");
489                      		
490                      	      MessageLoaderParms mlParms("ExportClient.CIMExportClient.MISMATCHED_RESPONSE", 
491                      					 "Mismatched response message type.");
492                      	      String mlString(MessageLoader::getMessage(mlParms));
493                      	      
494                      	      CIMClientResponseException responseException(mlString);
495                      
496                      	      delete response;
497 kumpf           1.26 
498                                    PEG_TRACE_STRING(TRC_EXPORT_CLIENT, Tracer::LEVEL4, mlString);
499                      
500                                    PEG_METHOD_EXIT();
501 humberto        1.18 	      throw responseException;
502 kumpf           1.14             }
503                      	}
504                      
505                              nowMilliseconds = TimeValue::getCurrentTime().toMilliseconds();
506                      	pegasus_yield();
507                          }
508                      
509                          //
510                          // Reconnect to reset the connection (disregard late response)
511                          //
512                          try
513                          {
514 kumpf           1.26         PEG_TRACE_STRING(TRC_EXPORT_CLIENT, Tracer::LEVEL4, "Doing a _reconnect()...");
515 kumpf           1.14         _reconnect();
516                          }
517                          catch (...)
518                          {
519                          }
520                      
521 carolann.graves 1.35     PEG_TRACE_STRING(TRC_EXPORT_CLIENT, Tracer::LEVEL4, "Connection to the listener timed out.");
522 kumpf           1.26     PEG_METHOD_EXIT();
523 kumpf           1.14     //
524                          // Throw timed out exception:
525                          //
526                          throw ConnectionTimeoutException();
527 mike            1.2  }
528                      
529                      PEGASUS_NAMESPACE_END

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2