OW_HTTPXMLCIMListener.cpp

Go to the documentation of this file.
00001 /*******************************************************************************
00002 * Copyright (C) 2001-2004 Vintela, Inc. All rights reserved.
00003 *
00004 * Redistribution and use in source and binary forms, with or without
00005 * modification, are permitted provided that the following conditions are met:
00006 *
00007 *  - Redistributions of source code must retain the above copyright notice,
00008 *    this list of conditions and the following disclaimer.
00009 *
00010 *  - Redistributions in binary form must reproduce the above copyright notice,
00011 *    this list of conditions and the following disclaimer in the documentation
00012 *    and/or other materials provided with the distribution.
00013 *
00014 *  - Neither the name of Vintela, Inc. nor the names of its
00015 *    contributors may be used to endorse or promote products derived from this
00016 *    software without specific prior written permission.
00017 *
00018 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
00019 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00020 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00021 * ARE DISCLAIMED. IN NO EVENT SHALL Vintela, Inc. OR THE CONTRIBUTORS
00022 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00023 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00024 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00025 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00026 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00027 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00028 * POSSIBILITY OF SUCH DAMAGE.
00029 *******************************************************************************/
00030 
00035 #include "OW_config.h"
00036 #include "OW_HTTPXMLCIMListener.hpp"
00037 #include "OW_CIMListenerCallback.hpp"
00038 #include "OW_HTTPServer.hpp"
00039 #include "OW_XMLListener.hpp"
00040 #include "OW_HTTPException.hpp"
00041 #include "OW_Format.hpp"
00042 #include "OW_MutexLock.hpp"
00043 #include "OW_ListenerAuthenticator.hpp"
00044 #include "OW_CIMInstance.hpp"
00045 #include "OW_CIMValue.hpp"
00046 #include "OW_CIMClass.hpp"
00047 #include "OW_CIMProperty.hpp"
00048 #include "OW_RandomNumber.hpp"
00049 #include "OW_ServiceEnvironmentIFC.hpp"
00050 #include "OW_ConfigOpts.hpp"
00051 #include "OW_ServerSocket.hpp"
00052 #include "OW_SelectEngine.hpp"
00053 #include "OW_SelectableIFC.hpp"
00054 #include "OW_IOException.hpp"
00055 #include "OW_Thread.hpp"
00056 #include "OW_Assertion.hpp"
00057 #include "OW_ClientCIMOMHandle.hpp"
00058 #include "OW_CIMProtocolIFC.hpp"
00059 #include "OW_NullLogger.hpp"
00060 #include "OW_FileSystem.hpp"
00061 #include "OW_ConfigFile.hpp"
00062 
00063 #include <algorithm> // for std::remove
00064 
00065 namespace OW_NAMESPACE
00066 {
00067 
00068 using namespace WBEMFlags;
00069 
00070 // This anonymous namespace has the effect of giving this class internal
00071 // linkage.  That means it won't cause a link error if another translation
00072 // unit has a class with the same name.
00073 namespace
00074 {
00075 
00076 const String COMPONENT_NAME("ow.listener.cimxml");
00077 
00078 #ifdef OW_WIN32
00079 class EventSelectable : public SelectableIFC
00080 {
00081 public:
00082    EventSelectable()
00083       : SelectableIFC()
00084       , m_event(NULL)
00085    {
00086       if(!(m_event = ::CreateEvent(NULL, TRUE, FALSE, NULL)))
00087       {
00088          OW_THROW(IOException, "Unable to create WIN32 event handle");
00089       }
00090    }
00091    ~EventSelectable()
00092    {
00093       if(m_event)
00094       {
00095          ::CloseHandle(m_event);
00096       }
00097    }
00098    Select_t getSelectObj() const
00099    {
00100       Select_t st;
00101       st.event = m_event;
00102       return st;
00103    }
00104 
00105    void setEvent()
00106    {
00107       if(m_event)
00108       {
00109          if(!::SetEvent(m_event))
00110          {
00111             OW_THROW(IOException, "Signaling termination event failed");
00112          }
00113       }
00114    }
00115 
00116    void resetEvent()
00117    {
00118       if(m_event)
00119       {
00120          ::ResetEvent(m_event);
00121       }
00122    }
00123 
00124 private:
00125    HANDLE m_event;
00126 };
00127 typedef IntrusiveReference<EventSelectable> EventSelectableRef;
00128 
00129 #endif
00130 
00131 typedef std::pair<SelectableIFCRef, SelectableCallbackIFCRef> SelectablePair_t;
00132 class HTTPXMLCIMListenerServiceEnvironment : public ServiceEnvironmentIFC
00133 {
00134 public:
00135    HTTPXMLCIMListenerServiceEnvironment(
00136       IntrusiveReference<ListenerAuthenticator> authenticator,
00137       RequestHandlerIFCRef listener,
00138       const LoggerRef& logger,
00139       Reference<Array<SelectablePair_t> > selectables,
00140       const String& certFileName,
00141       const String& keyFileName = String())
00142    : m_pLAuthenticator(authenticator)
00143    , m_XMLListener(listener)
00144    , m_logger(logger ? logger : LoggerRef(new NullLogger))
00145    , m_selectables(selectables)
00146    {
00147       if(certFileName.empty())
00148       {
00149          setConfigItem(ConfigOpts::HTTP_SERVER_HTTP_PORT_opt, String(0), E_OVERWRITE_PREVIOUS);
00150          setConfigItem(ConfigOpts::HTTP_SERVER_HTTPS_PORT_opt, String(-1), E_OVERWRITE_PREVIOUS);
00151       }
00152       else
00153       {
00154          setConfigItem(ConfigOpts::HTTP_SERVER_HTTP_PORT_opt, String(-1), E_OVERWRITE_PREVIOUS);
00155          setConfigItem(ConfigOpts::HTTP_SERVER_HTTPS_PORT_opt, String(0), E_OVERWRITE_PREVIOUS);
00156          setConfigItem(ConfigOpts::HTTP_SERVER_SSL_CERT_opt, certFileName, E_OVERWRITE_PREVIOUS);
00157          setConfigItem(ConfigOpts::HTTP_SERVER_SSL_KEY_opt,
00158                keyFileName.empty()?certFileName:keyFileName, E_OVERWRITE_PREVIOUS);
00159       }
00160 
00161       setConfigItem(ConfigOpts::HTTP_SERVER_MAX_CONNECTIONS_opt, String(10), E_OVERWRITE_PREVIOUS);
00162       setConfigItem(ConfigOpts::HTTP_SERVER_SINGLE_THREAD_opt, "false", E_OVERWRITE_PREVIOUS);
00163       setConfigItem(ConfigOpts::HTTP_SERVER_ENABLE_DEFLATE_opt, "true", E_OVERWRITE_PREVIOUS);
00164       setConfigItem(ConfigOpts::HTTP_SERVER_USE_DIGEST_opt, "false", E_OVERWRITE_PREVIOUS);
00165       setConfigItem(ConfigOpts::HTTP_SERVER_USE_UDS_opt, "false", E_OVERWRITE_PREVIOUS);
00166    }
00167    virtual ~HTTPXMLCIMListenerServiceEnvironment() {}
00168    virtual bool authenticate(String &userName,
00169       const String &info, String &details, OperationContext& context) const
00170    {
00171       return m_pLAuthenticator->authenticate(userName, info, details, context);
00172    }
00173    virtual void addSelectable(const SelectableIFCRef& obj,
00174       const SelectableCallbackIFCRef& cb)
00175    {
00176       m_selectables->push_back(std::make_pair(obj, cb));
00177    }
00178 
00179    struct selectableFinder
00180    {
00181       selectableFinder(const SelectableIFCRef& obj) : m_obj(obj) {}
00182       template <typename T>
00183       bool operator()(const T& x)
00184       {
00185          return x.first == m_obj;
00186       }
00187       const SelectableIFCRef& m_obj;
00188    };
00189 
00190    virtual void removeSelectable(const SelectableIFCRef& obj)
00191    {
00192       m_selectables->erase(std::remove_if (m_selectables->begin(), m_selectables->end(),
00193          selectableFinder(obj)), m_selectables->end());
00194    }
00195    virtual String getConfigItem(const String &name, const String& defRetVal) const
00196    {
00197       return ConfigFile::getConfigItem(m_configItems, name, defRetVal);
00198    }
00199    virtual StringArray getMultiConfigItem(const String &itemName, 
00200       const StringArray& defRetVal, const char* tokenizeSeparator) const
00201    {
00202       return ConfigFile::getMultiConfigItem(m_configItems, itemName, defRetVal, tokenizeSeparator);
00203    }
00204    virtual void setConfigItem(const String& item, const String& value, EOverwritePreviousFlag overwritePrevious)
00205    {
00206       ConfigFile::setConfigItem(m_configItems, item, value, 
00207          overwritePrevious == E_OVERWRITE_PREVIOUS ? ConfigFile::E_OVERWRITE_PREVIOUS : ConfigFile::E_PRESERVE_PREVIOUS);
00208    }
00209    
00210    virtual RequestHandlerIFCRef getRequestHandler(const String&) const
00211    {
00212       RequestHandlerIFCRef ref(m_XMLListener.getLibRef(),
00213             m_XMLListener->clone());
00214       ref->setEnvironment(ServiceEnvironmentIFCRef(const_cast<HTTPXMLCIMListenerServiceEnvironment*>(this)));
00215       return ref;
00216    }
00217    virtual LoggerRef getLogger() const
00218    {
00219       return getLogger(COMPONENT_NAME);
00220    }
00221    virtual LoggerRef getLogger(const String& componentName) const
00222    {
00223       LoggerRef rv(m_logger->clone());
00224       rv->setDefaultComponent(componentName);
00225       return rv;
00226    }
00227 private:
00228    ConfigFile::ConfigMap m_configItems;
00229    IntrusiveReference<ListenerAuthenticator> m_pLAuthenticator;
00230    RequestHandlerIFCRef m_XMLListener;
00231    LoggerRef m_logger;
00232    Reference<Array<SelectablePair_t> > m_selectables;
00233 };
00234 class SelectEngineThread : public Thread
00235 {
00236 public:
00237    SelectEngineThread(const Reference<Array<SelectablePair_t> >& selectables)
00238    : Thread()
00239    , m_selectables(selectables)
00240 #ifdef OW_WIN32
00241    , m_stopObject(new EventSelectable)
00242    {
00243    }
00244 #else
00245    , m_stopObject(UnnamedPipe::createUnnamedPipe())
00246    {
00247       m_stopObject->setBlocking(UnnamedPipe::E_NONBLOCKING);
00248    }
00249 #endif
00250 
00254    virtual Int32 run()
00255    {
00256       SelectEngine engine;
00257       SelectableCallbackIFCRef cb(new SelectEngineStopper(engine));
00258       m_selectables->push_back(std::make_pair(m_stopObject, cb));
00259       for (size_t i = 0; i < m_selectables->size(); ++i)
00260       {
00261          engine.addSelectableObject((*m_selectables)[i].first,
00262             (*m_selectables)[i].second);
00263       }
00264       engine.go();
00265       return 0;
00266    }
00267    virtual void doCooperativeCancel()
00268    {
00269 #ifdef OW_WIN32
00270       // signal the event to stop the select engine so the
00271       // thread will exit
00272       m_stopObject->setEvent();
00273 #else
00274       // write something into the stop pipe to stop the select engine so the
00275       // thread will exit
00276       if (m_stopObject->writeInt(0) == -1)
00277       {
00278          OW_THROW_ERRNO_MSG(IOException, "Writing to the termination pipe failed");
00279       }
00280 #endif
00281    }
00282 
00283 private:
00284    Reference<Array<SelectablePair_t> > m_selectables;
00285 #ifdef OW_WIN32
00286    EventSelectableRef m_stopObject;
00287 #else
00288    UnnamedPipeRef m_stopObject;
00289 #endif
00290 };
00291 
00292 
00293 
00294 } // end anonymous namespace
00295 
00296 class HTTPXMLCIMListenerCallback : public CIMListenerCallback
00297 {
00298 private: 
00299    IntrusiveReference<ListenerAuthenticator> m_pLAuthenticator;
00300    Bool m_useHTTPS; 
00301 public:
00306    HTTPXMLCIMListenerCallback(IntrusiveReference<ListenerAuthenticator> authenticator,
00307       Bool useHTTPS = false,
00308       const LoggerRef& logger = LoggerRef(0))
00309       : m_pLAuthenticator(authenticator)
00310       , m_useHTTPS(useHTTPS) 
00311    {
00312    }
00313    ~HTTPXMLCIMListenerCallback()
00314 {
00315    try
00316    {
00317       MutexLock lock(m_mutex);
00318       for (callbackMap_t::iterator i = m_callbacks.begin();
00319          i != m_callbacks.end(); ++i)
00320       {
00321          registrationInfo reg = i->second;
00322    
00323          try
00324          {
00325             deleteRegistrationObjects(reg);
00326          }
00327          catch (Exception&)
00328          {
00329             // if an error occured, then just ignore it.  We don't have any way
00330             // of logging it!
00331          }
00332          catch (...)
00333          {
00334             // who knows what happened, but we need to continue deregistering...
00335          }
00336       }
00337       m_pLAuthenticator = 0;
00338    }
00339    catch (...)
00340    {
00341       // don't let exceptions escape
00342    }
00343 }
00363    String registerForIndication(const String& url,
00364          const String& ns, const String& filter,
00365          const String& querylanguage,
00366          const String& sourceNamespace,
00367          const CIMListenerCallbackRef& cb,
00368          const ClientAuthCBIFCRef& authCb,
00369          UInt16 httpPort, 
00370          UInt16 httpsPort)
00371    {
00372       registrationInfo reg;
00373       // create an http client with the url from the object path
00374       URL curl(url);
00375       reg.cimomUrl = curl;
00376       ClientCIMOMHandleRef hdl = ClientCIMOMHandle::createFromURL(url, authCb);
00377       String ipAddress = hdl->getWBEMProtocolHandler()->getLocalAddress().getAddress();
00378       CIMClass delivery(CIMNULL);
00379       String urlPrefix;
00380 
00381       UInt16 listenerPort = httpsPort;
00382       if(m_useHTTPS) // Listener will be recieving over https
00383       {
00384          urlPrefix = "https://";
00385          try
00386          {
00387             delivery = hdl->getClass(ns, "CIM_IndicationHandlerCIMXML");
00388          }
00389          catch (CIMException& e)
00390          {
00391             if (e.getErrNo() == CIMException::NOT_FOUND)
00392             {
00393                // the > 2.6 doesn't exist, try to get the 2.5 class
00394                delivery = hdl->getClass(ns, "CIM_IndicationHandlerXMLHTTPS");
00395             }
00396             else
00397                throw;
00398          }
00399       }
00400       else
00401       {
00402          try
00403          {
00404             delivery = hdl->getClass(ns, "CIM_IndicationHandlerCIMXML");
00405          }
00406          catch (CIMException& e)
00407          {
00408             if (e.getErrNo() == CIMException::NOT_FOUND)
00409             {
00410                // the > 2.6 doesn't exist, try to get the 2.5 class
00411                delivery = hdl->getClass(ns, "CIM_IndicationHandlerXMLHTTP");
00412             }
00413             else
00414                throw;
00415          }
00416          urlPrefix = "http://";
00417          listenerPort = httpPort;
00418       }
00419       CIMInstance ci = delivery.newInstance();
00420       MutexLock lock(m_mutex);
00421       String httpPath;
00422       RandomNumber rn(0, 0x7FFFFFFF);
00423       do
00424       {
00425          String randomHashValue(rn.getNextNumber());
00426          httpPath = "/cimListener" + randomHashValue;
00427       } while (m_callbacks.find(httpPath) != m_callbacks.end());
00428       reg.httpCredentials = m_pLAuthenticator->getNewCredentials();
00429       ci.setProperty("Destination", CIMValue(urlPrefix + reg.httpCredentials + "@" +
00430                ipAddress + ":" + String(UInt32(listenerPort)) + httpPath));
00431       ci.setProperty("SystemCreationClassName", CIMValue("CIM_System"));
00432       ci.setProperty("SystemName", CIMValue(ipAddress));
00433       ci.setProperty("CreationClassName", CIMValue(delivery.getName()));
00434       ci.setProperty("Name", CIMValue(httpPath));
00435       ci.setProperty("Owner", CIMValue("HTTPXMLCIMListener on " + ipAddress));
00436       try
00437       {
00438          reg.handler = hdl->createInstance(ns, ci);
00439       }
00440       catch (CIMException& e)
00441       {
00442          // We don't care if it already exists, but err out on anything else
00443          if (e.getErrNo() != CIMException::ALREADY_EXISTS)
00444          {
00445             throw;
00446          }
00447          else
00448          {
00449             reg.handler = CIMObjectPath(ns, ci);
00450          }
00451       }
00452       // get class of CIM_IndicationFilter and new instance of it
00453       CIMClass cimFilter = hdl->getClass(ns, "CIM_IndicationFilter", E_LOCAL_ONLY);
00454       ci = cimFilter.newInstance();
00455       // set Query property to query that was passed into function
00456       ci.setProperty("Query", CIMValue(filter));
00457       // set QueryLanguage property
00458       ci.setProperty("QueryLanguage", CIMValue(querylanguage));
00459       ci.setProperty("SystemCreationClassName", CIMValue("CIM_System"));
00460       ci.setProperty("SystemName", CIMValue(ipAddress));
00461       ci.setProperty("CreationClassName", CIMValue(cimFilter.getName()));
00462       ci.setProperty("Name", CIMValue(httpPath));
00463       if (!sourceNamespace.empty())
00464       {
00465          ci.setProperty("SourceNamespace", CIMValue(sourceNamespace));
00466       }
00467       // create instance of filter
00468       reg.filter = hdl->createInstance(ns, ci);
00469       // get class of CIM_IndicationSubscription and new instance of it.
00470       // CIM_IndicationSubscription is an association class that connects
00471       // the IndicationFilter to the IndicationHandler.
00472       CIMClass cimClientFilterDelivery = hdl->getClass(ns,
00473             "CIM_IndicationSubscription", E_LOCAL_ONLY);
00474       ci = cimClientFilterDelivery.newInstance();
00475       // set the properties for the filter and the handler
00476       ci.setProperty("filter", CIMValue(reg.filter));
00477       ci.setProperty("handler", CIMValue(reg.handler));
00478       // creating the instance the CIM_IndicationSubscription creates
00479       // the event subscription
00480       reg.subscription = hdl->createInstance(ns, ci);
00481       //save info for deletion later and callback delivery
00482       reg.callback = cb;
00483       reg.ns = ns;
00484       reg.authCb = authCb;
00485       m_callbacks[httpPath] = reg;
00486       return httpPath;
00487    }
00488 
00495    void deregisterForIndication( const String& handle )
00496    {
00497       MutexLock lock(m_mutex);
00498       callbackMap_t::iterator i = m_callbacks.find(handle);
00499       if (i != m_callbacks.end())
00500       {
00501          registrationInfo reg = i->second;
00502          m_callbacks.erase(i);
00503          lock.release();
00504          m_pLAuthenticator->removeCredentials(reg.httpCredentials);
00505          deleteRegistrationObjects(reg);
00506       }
00507    }
00508 
00509 protected:
00510    virtual void doIndicationOccurred( CIMInstance& ci,
00511          const String& listenerPath )
00512    {
00513       CIMListenerCallbackRef cb;
00514       { // scope for the MutexLock
00515          MutexLock lock(m_mutex);
00516          callbackMap_t::iterator i = m_callbacks.find(listenerPath);
00517          if (i == m_callbacks.end())
00518          {
00519             OW_THROWCIMMSG(CIMException::ACCESS_DENIED,
00520                   Format("No listener for path: %1", listenerPath).c_str());
00521          }
00522          cb = i->second.callback;
00523       }
00524       cb->indicationOccurred( ci, listenerPath );
00525    }
00526 private:
00527 
00528 #ifdef OW_WIN32
00529 #pragma warning (push)
00530 #pragma warning (disable: 4251)
00531 #endif
00532 
00533    struct registrationInfo
00534    {
00535       registrationInfo()
00536          : handler(CIMNULL)
00537          , filter(CIMNULL)
00538          , subscription(CIMNULL)
00539       {}
00540       URL cimomUrl;
00541       String ns;
00542       CIMObjectPath handler;
00543       CIMObjectPath filter;
00544       CIMObjectPath subscription;
00545       CIMListenerCallbackRef callback;
00546       String httpCredentials;
00547       ClientAuthCBIFCRef authCb;
00548    };
00549    typedef Map< String, registrationInfo > callbackMap_t;
00550    callbackMap_t m_callbacks;
00551    void deleteRegistrationObjects( const registrationInfo& reg )
00552    {
00553       ClientCIMOMHandleRef hdl = ClientCIMOMHandle::createFromURL(reg.cimomUrl.toString(), reg.authCb);
00554       hdl->deleteInstance(reg.ns, reg.subscription);
00555       hdl->deleteInstance(reg.ns, reg.filter);
00556       hdl->deleteInstance(reg.ns, reg.handler);
00557    }
00558    Mutex m_mutex;
00559 };
00560 
00561 
00562 
00564 HTTPXMLCIMListener::HTTPXMLCIMListener(const LoggerRef& logger,
00565    const String& certFileName, const String& keyFileName)
00566    : m_pLAuthenticator(new ListenerAuthenticator)
00567    , m_httpServer(new HTTPServer)
00568    , m_httpListenPort(0)
00569    , m_httpsListenPort(0)
00570    , m_certFileName(certFileName)
00571    , m_keyFileName(keyFileName)
00572    , m_callback(new HTTPXMLCIMListenerCallback(m_pLAuthenticator, !certFileName.empty()))
00573    , m_XMLListener(SharedLibraryRef(0), new XMLListener(m_callback))
00574 {
00575    if(!certFileName.empty())
00576    {
00577       if(!FileSystem::canRead(certFileName))
00578       {
00579          OW_THROW_ERRNO_MSG(IOException, 
00580             Format("Unable to open certificate file %1",
00581                certFileName).c_str());
00582       }
00583    }
00584    if(!keyFileName.empty())
00585    {
00586       if(!FileSystem::canRead(keyFileName))
00587       {
00588          OW_THROW(IOException, 
00589             Format("Unable to open key file %1",
00590                keyFileName).c_str());
00591       }
00592    }
00593 
00594    Reference<Array<SelectablePair_t> >
00595       selectables(new Array<SelectablePair_t>);
00596    ServiceEnvironmentIFCRef env(new HTTPXMLCIMListenerServiceEnvironment(
00597       m_pLAuthenticator, m_XMLListener, logger, selectables, certFileName, keyFileName));
00598    m_httpServer->init(env);
00599    m_httpServer->start();  // The http server will add it's server
00600    // sockets to the environment's selectables, which is really
00601    // the selectabls defined above.  We'll give these to the select engine thread
00602    // below which will use them to run the select engine.
00603    m_httpListenPort = m_httpServer->getLocalHTTPAddress().getPort();
00604    m_httpsListenPort = m_httpServer->getLocalHTTPSAddress().getPort();
00605    // start a thread to run the http server
00606    m_httpThread = new SelectEngineThread(selectables);
00607    m_httpThread->start();
00608 }
00610 HTTPXMLCIMListener::~HTTPXMLCIMListener()
00611 {
00612    try
00613    {
00614       shutdownHttpServer();
00615       m_pLAuthenticator = 0;
00616    }
00617    catch (...)
00618    {
00619       // don't let exceptions escape
00620    }
00621 }
00622 void
00623 HTTPXMLCIMListener::shutdownHttpServer()
00624 {
00625    if (m_httpThread)
00626    {
00627       m_httpThread->cooperativeCancel();
00628       // wait for the thread to quit
00629       m_httpThread->join();
00630       m_httpThread = 0;
00631    }
00632    if (m_httpServer)
00633    {
00634       // stop the http server
00635       m_httpServer->shutdown();
00636       m_httpServer = 0;
00637    }
00638 }
00640 String
00641 HTTPXMLCIMListener::registerForIndication(
00642    const String& url,
00643    const String& ns,
00644    const String& filter,
00645    const String& querylanguage,
00646    const String& sourceNamespace,
00647    const CIMListenerCallbackRef& cb,
00648    const ClientAuthCBIFCRef& authCb)
00649 {
00650    return m_callback->registerForIndication(url,ns,filter,querylanguage,
00651                              sourceNamespace,cb,authCb,
00652                              m_httpListenPort,m_httpsListenPort); 
00653 }
00655 void
00656 HTTPXMLCIMListener::deregisterForIndication( const String& handle )
00657 {
00658    m_callback->deregisterForIndication(handle); 
00659 }
00660 
00661 } // end namespace OW_NAMESPACE
00662 

Generated on Thu Feb 9 08:48:00 2006 for openwbem by  doxygen 1.4.6