blob: 83488f8f6381ad182727b7de5309de8f23b1e3af [file] [log] [blame]
/*******************************************************************************
* Copyright (C) 2004-2006 Intel Corp. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* - Neither the name of Intel Corp. nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL Intel Corp. OR THE CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************/
/**
* @author Anas Nashif
* @author Liang Hou
*/
#ifdef HAVE_CONFIG_H
#include "wsman_config.h"
#endif
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <string.h>
#ifdef HAVE_PTHREAD_H
#include <pthread.h>
#endif
#ifndef WIN32
#include <dlfcn.h>
#endif
#include "u/libu.h"
#if 0
#include "wsman-faults.h"
#include "wsman-xml.h"
#include "wsman-plugins.h"
#include "wsman-server.h"
#include "wsman-dispatcher.h"
#endif
#include "wsman-soap.h"
#include "wsman-soap-envelope.h"
#include "wsman-server.h"
#include "wsman-xml.h"
#include "wsman-dispatcher.h"
#include "wsman-event-pool.h"
#include "wsman-subscription-repository.h"
WsManListenerH *wsman_dispatch_list_new()
{
WsManListenerH *list =
(WsManListenerH *) u_malloc(sizeof(WsManListenerH));
return list;
}
static int wsman_server_verify_plugin(WsDispatchInterfaceInfo *ifcinfo)
{
debug("Plugin '%s', version: %s", (ifcinfo->displayName), (ifcinfo->version) );
if (strcmp (OPENWSMAN_PLUGIN_API_VERSION, ifcinfo->version) == 0) {
return 1;
}
return 0;
}
WsContextH wsman_init_plugins(WsManListenerH * listener)
{
list_t *list = list_create(LISTCOUNT_T_MAX);
lnode_t *node;
WsContextH cntx = NULL;
WsDispatchInterfaceInfo *ifcinfo = NULL;
wsman_plugins_load(listener);
node = list_first(listener->plugins);
while (node) {
WsManPlugin *p = (WsManPlugin *) node->list_data;
if (p->init == NULL
|| p->init(p->p_handle, &(p->data)) == 0 ) {
error ("Plugin %s fails init()", p->p_name);
error("invalid plugin");
goto next_plugin;
}
p->ifc = (WsDispatchInterfaceInfo *)
malloc(sizeof(WsDispatchInterfaceInfo));
ifcinfo = p->ifc;
ifcinfo->extraData = p->data;
p->set_config = dlsym(p->p_handle, "set_config");
if (listener->config && p->set_config) {
p->set_config(p->p_handle, listener->config);
} else {
debug("no configuration available for plugin: %s", p->p_name);
}
if (p->get_endpoints)
p->get_endpoints(p->p_handle, p->ifc);
if (p->ifc && wsman_server_verify_plugin(ifcinfo)) {
lnode_t *i = lnode_create(p->ifc);
list_append(list, i);
} else {
error ("Plugin '%s' is not compatible with version of the software or plugin is invalid", p->p_name);
error("invalid plugin");
}
next_plugin:
node = list_next(listener->plugins, node);
}
cntx = ws_create_runtime(list);
return cntx;
}
#ifdef ENABLE_EVENTING_SUPPORT
SubsRepositoryOpSetH
wsman_init_subscription_repository(WsContextH cntx, char *uri)
{
SoapH soap = ws_context_get_runtime(cntx);
if(soap) {
soap->subscriptionOpSet = wsman_get_subsrepos_opset();
if(uri) {
soap->uri_subsRepository = u_strdup(uri);
soap->subscriptionOpSet->init_subscription(uri, NULL);
}
}
return soap->subscriptionOpSet;
}
EventPoolOpSetH
wsman_init_event_pool(WsContextH cntx, void*data)
{
SoapH soap = ws_context_get_runtime(cntx);
if(soap) {
soap->eventpoolOpSet = wsman_get_eventpool_opset();
soap->eventpoolOpSet->init(NULL);
}
return soap->eventpoolOpSet;
}
int wsman_clean_subsrepository(SoapH soap, SubsRepositoryEntryH entry)
{
int retVal = 0;
WsXmlDocH doc = ws_xml_read_memory( (char *)entry->strdoc, entry->len, "UTF-8", 0);
unsigned long expire;
WsmanFaultCodeType fault_code;
if(doc) {
WsXmlNodeH node = ws_xml_get_soap_body(doc);
if(node) {
node = ws_xml_get_child(node, 0, XML_NS_EVENTING, WSEVENT_SUBSCRIBE);
node = ws_xml_get_child(node, 0, XML_NS_EVENTING, WSEVENT_EXPIRES);
if(node == NULL) { //No specified expiration, delete it
debug("subscription %s deleted from the repository", entry->uuid);
soap->subscriptionOpSet->delete_subscription(soap->uri_subsRepository, entry->uuid+5);
retVal = 1;
}
else {
wsman_set_expiretime(node, &expire, &fault_code);
if(fault_code == WSMAN_RC_OK) {
if(time_expired(expire)) {
debug("subscription %s deleted from the repository", entry->uuid);
soap->subscriptionOpSet->delete_subscription(soap->uri_subsRepository, entry->uuid+5);
retVal = 1;
}
}
}
}
ws_xml_destroy_doc(doc);
}
return retVal;
}
void wsman_repos_notification_dispatcher(WsContextH cntx, SubsRepositoryEntryH entry, int subsNum)
{
WsmanMessage *wsman_msg = wsman_soap_message_new();
if(wsman_msg == NULL) return;
unsigned char *strdoc = entry->strdoc;
u_buf_construct(wsman_msg->request, strdoc, entry->len, entry->len);
dispatch_inbound_call(cntx->soap, wsman_msg, NULL);
wsman_soap_message_destroy(wsman_msg);
if(list_count(cntx->subscriptionMemList) > subsNum) {
lnode_t *node = list_last(cntx->subscriptionMemList);
WsSubscribeInfo *subs = (WsSubscribeInfo *)node->list_data;
//Update UUID in the memory
strncpy(subs->subsId, entry->uuid+5, EUIDLEN);
}
}
void *wsman_notification_manager(void *arg)
{
WsContextH cntx = (WsContextH) arg;
int r;
pthread_mutex_t mutex;
pthread_cond_t cond;
struct timespec timespec;
struct timeval tv;
if ((r = pthread_cond_init(&cond, NULL)) != 0) {
error("pthread_cond_init failed = %d", r);
return NULL;
}
if ((r = pthread_mutex_init(&mutex, NULL)) != 0) {
error("pthread_mutex_init failed = %d", r);
return NULL;
}
while (continue_working) {
pthread_mutex_lock(&mutex);
gettimeofday(&tv, NULL);
timespec.tv_sec = tv.tv_sec + 1;
timespec.tv_nsec = tv.tv_usec * 1000;
pthread_cond_timedwait(&cond, &mutex, &timespec);
pthread_mutex_unlock(&mutex);
wse_notification_manager(cntx);
}
return NULL;
}
#endif
void *wsman_server_auxiliary_loop_thread(void *arg)
{
WsContextH cntx = (WsContextH) arg;
int r;
pthread_mutex_t mutex;
pthread_cond_t cond;
struct timespec timespec;
struct timeval tv;
if ((r = pthread_cond_init(&cond, NULL)) != 0) {
error("pthread_cond_init failed = %d", r);
return NULL;
}
if ((r = pthread_mutex_init(&mutex, NULL)) != 0) {
error("pthread_mutex_init failed = %d", r);
return NULL;
}
while (continue_working) {
pthread_mutex_lock(&mutex);
gettimeofday(&tv, NULL);
timespec.tv_sec = tv.tv_sec + 1;
timespec.tv_nsec = tv.tv_usec * 1000;
pthread_cond_timedwait(&cond, &mutex, &timespec);
pthread_mutex_unlock(&mutex);
wsman_timeouts_manager(cntx, NULL);
#ifdef ENABLE_EVENTING_SUPPORT
wsman_heartbeat_generator(cntx, NULL);
#endif
}
return NULL;
}