f91438de9902fc87ac774c011e1d02fa6845ce13
[tpot/pegasus/.git] / src / Pegasus / ExportClient / CIMExportClient.cpp
1 //%/////////////////////////////////////////////////////////////////////////////
2 //
3 // Copyright (c) 2000, 2001 BMC Software, Hewlett-Packard Company, IBM,
4 // The Open Group, Tivoli Systems
5 //
6 // Permission is hereby granted, free of charge, to any person obtaining a copy
7 // of this software and associated documentation files (the "Software"), to
8 // deal in the Software without restriction, including without limitation the
9 // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10 // sell copies of the Software, and to permit persons to whom the Software is
11 // furnished to do so, subject to the following conditions:
12 //
13 // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
14 // ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED
15 // "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
16 // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
17 // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
18 // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
19 // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 //
22 //==============================================================================
23 //
24 // Author: Mike Brasher (mbrasher@bmc.com)
25 //
26 // Modified By: Nitin Upasani, Hewlett-Packard Company (Nitin_Upasani@hp.com)
27 //
28 //              Nag Boranna, Hewlett-Packard Company (nagaraja_boranna@hp.com)
29 //
30 //%/////////////////////////////////////////////////////////////////////////////
31
32 #include <Pegasus/Common/Config.h>
33 #include <Pegasus/Common/HTTPConnection.h>
34 #include <Pegasus/Common/Destroyer.h>
35 #include <Pegasus/Common/XmlWriter.h>
36 #include <Pegasus/Common/TimeValue.h>
37 #include <Pegasus/Common/Exception.h>
38 #include "CIMExportRequestEncoder.h"
39 #include "CIMExportResponseDecoder.h"
40 #include "CIMExportClient.h"
41
42 #include <iostream>
43
44 PEGASUS_USING_STD;
45
46 PEGASUS_NAMESPACE_BEGIN
47
48 CIMExportClient::CIMExportClient(
49    Monitor* monitor,
50    HTTPConnector* httpConnector,
51    Uint32 timeOutMilliseconds)
52    : 
53    Base("CIMExportClient", MessageQueue::getNextQueueId()),
54    _monitor(monitor), 
55    _httpConnector(httpConnector),
56    _timeOutMilliseconds(timeOutMilliseconds),
57    _connected(false),
58    _responseDecoder(0),
59    _requestEncoder(0)
60 {
61    //
62    // Create client authenticator
63    //
64    _authenticator = new ClientAuthenticator();
65 }
66
67 CIMExportClient::~CIMExportClient()
68 {
69    delete _authenticator;    
70 }
71
72 void CIMExportClient::handleEnqueue(Message *message)
73 {
74    if( ! message )
75       return;
76    
77 }
78
79
80 void CIMExportClient::handleEnqueue()
81 {
82
83 }
84
85 const char* CIMExportClient::getQueueName() const
86 {
87    return "CIMExportClient";
88 }
89
90 void CIMExportClient::connect(const String& address)
91 {
92    // If already connected, bail out!
93     
94    if (_connected)
95       throw AlreadyConnected();
96     
97    // Create response decoder:
98     
99    _responseDecoder = new CIMExportResponseDecoder(
100       this, _requestEncoder, _authenticator);
101     
102    // Attempt to establish a connection:
103     
104    HTTPConnection* httpConnection;
105     
106    try
107    {
108       httpConnection = _httpConnector->connect(address, _responseDecoder);
109    }
110    catch (Exception& e)
111    {
112       delete _responseDecoder;
113       throw e;
114    }
115     
116    // Create request encoder:
117     
118    _requestEncoder = new CIMExportRequestEncoder(
119       httpConnection, _authenticator);
120
121    _responseDecoder->setEncoderQueue(_requestEncoder);    
122
123    _connected = true;
124 }
125
126 void CIMExportClient::connectLocal(const String& address, const String& userName)
127 {
128    if (userName.size())
129    {
130       _authenticator->setUserName(userName);
131    }
132    _authenticator->setAuthType(ClientAuthenticator::LOCAL);
133
134    connect(address);
135 }
136
137 void CIMExportClient::exportIndication(
138    const String& url,
139    const CIMInstance& instanceName)
140 {
141    String messageId = XmlWriter::getNextMessageId();
142     
143    // encode request
144    Message* request = new CIMExportIndicationRequestMessage(
145       messageId,
146       url,
147       instanceName,
148       QueueIdStack());
149
150    _authenticator->clearRequest();
151
152    _requestEncoder->enqueue(request);
153
154    Message* message = _waitForResponse(
155       CIM_EXPORT_INDICATION_RESPONSE_MESSAGE, messageId);
156
157    CIMExportIndicationResponseMessage* response = 
158       (CIMExportIndicationResponseMessage*)message;
159     
160    Destroyer<CIMExportIndicationResponseMessage> destroyer(response);
161     
162    _checkError(response);
163     
164    //return(response->cimClass);
165 }
166
167 Message* CIMExportClient::_waitForResponse(
168    const Uint32 messageType,
169    const String& messageId,
170    const Uint32 timeOutMilliseconds)
171 {
172    if (!_connected)
173       throw NotConnected();
174     
175    long rem = long(timeOutMilliseconds);
176
177    for (;;)
178    {
179       //
180       // Wait until the timeout expires or an event occurs:
181       //
182
183       TimeValue start = TimeValue::getCurrentTime();
184       _monitor->run(rem);
185       TimeValue stop = TimeValue::getCurrentTime();
186
187       //
188       // Check to see if incoming queue has a message of the appropriate
189       // type with the given message id:
190       //
191
192       Message* message = findByType(messageType);
193
194       if (message)
195       {
196          CIMResponseMessage* responseMessage = (CIMResponseMessage*)message;
197
198          if (responseMessage->messageId == messageId)
199          {
200             remove(responseMessage);
201             return responseMessage;
202          }
203       }
204
205       // 
206       // Terminate loop if timed out:
207       //
208
209       long diff = stop.toMilliseconds() - start.toMilliseconds();
210
211       if (diff >= rem)
212          break;
213
214       rem -= diff;
215    }
216
217    //
218    // Throw timed out exception:
219    //
220
221    throw TimedOut();
222 }
223
224 void CIMExportClient::_checkError(const CIMResponseMessage* responseMessage)
225 {
226    if (responseMessage &&
227        (responseMessage->cimException.getCode() != CIM_ERR_SUCCESS) )
228    {
229       throw responseMessage->cimException;
230    }
231 }
232
233 PEGASUS_NAMESPACE_END