http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/discovery/private/src/discovery_activator.c ---------------------------------------------------------------------- diff --git a/remote_services/discovery/private/src/discovery_activator.c b/remote_services/discovery/private/src/discovery_activator.c deleted file mode 100644 index 3267d25..0000000 --- a/remote_services/discovery/private/src/discovery_activator.c +++ /dev/null @@ -1,186 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -/* - * discovery_activator.c - * - * \date Aug 8, 2014 - * \author <a href="mailto:[email protected]">Apache Celix Project Team</a> - * \copyright Apache License, Version 2.0 - */ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - - -#include "bundle_activator.h" -#include "service_tracker.h" -#include "constants.h" - -#include "log_helper.h" -#include "discovery.h" -#include "remote_constants.h" - -struct activator { - bundle_context_pt context; - discovery_pt discovery; - log_helper_pt loghelper; - - service_tracker_pt endpointListenerTracker; - endpoint_listener_pt endpointListener; - service_registration_pt endpointListenerService; -}; - -celix_status_t bundleActivator_createEPLTracker(struct activator *activator, service_tracker_pt *tracker) { - celix_status_t status; - - service_tracker_customizer_pt customizer = NULL; - - status = serviceTrackerCustomizer_create(activator->discovery, discovery_endpointListenerAdding, discovery_endpointListenerAdded, discovery_endpointListenerModified, - discovery_endpointListenerRemoved, &customizer); - - if (status == CELIX_SUCCESS) { - status = serviceTracker_create(activator->context, (char *) OSGI_ENDPOINT_LISTENER_SERVICE, customizer, tracker); - } - - return status; -} - -celix_status_t bundleActivator_create(bundle_context_pt context, void **userData) { - celix_status_t status; - - struct activator* activator = calloc(1,sizeof(struct activator)); - if (!activator) { - return CELIX_ENOMEM; - } - - status = discovery_create(context, &activator->discovery); - if (status == CELIX_SUCCESS) { - activator->context = context; - - logHelper_create(context, &activator->loghelper); - - status = bundleActivator_createEPLTracker(activator, &activator->endpointListenerTracker); - if(status==CELIX_SUCCESS){ - *userData = activator; - } - else{ - bundleActivator_destroy(activator,context); - } - } - else{ - free(activator); - } - - return status; -} - -celix_status_t bundleActivator_start(void * userData, bundle_context_pt context) { - celix_status_t status; - struct activator *activator = userData; - const char *uuid = NULL; - - logHelper_start(activator->loghelper); - - status = bundleContext_getProperty(context, OSGI_FRAMEWORK_FRAMEWORK_UUID, &uuid); - if (!uuid) { - logHelper_log(activator->loghelper, OSGI_LOGSERVICE_DEBUG, "no framework UUID defined?!"); - return CELIX_ILLEGAL_STATE; - } - - size_t len = 11 + strlen(OSGI_FRAMEWORK_OBJECTCLASS) + strlen(OSGI_RSA_ENDPOINT_FRAMEWORK_UUID) + strlen(uuid); - char *scope = malloc(len + 1); - if (!scope) { - return CELIX_ENOMEM; - } - - sprintf(scope, "(&(%s=*)(%s=%s))", OSGI_FRAMEWORK_OBJECTCLASS, OSGI_RSA_ENDPOINT_FRAMEWORK_UUID, uuid); - scope[len] = 0; - - logHelper_log(activator->loghelper, OSGI_LOGSERVICE_DEBUG, "using scope %s.", scope); - - properties_pt props = properties_create(); - properties_set(props, "DISCOVERY", "true"); - properties_set(props, (char *) OSGI_ENDPOINT_LISTENER_SCOPE, scope); - - if (status == CELIX_SUCCESS) { - status = serviceTracker_open(activator->endpointListenerTracker); - } - - if (status == CELIX_SUCCESS) { - status = discovery_start(activator->discovery); - } - - if (status == CELIX_SUCCESS) { - endpoint_listener_pt endpointListener = calloc(1, sizeof(struct endpoint_listener)); - - if (endpointListener) { - endpointListener->handle = activator->discovery; - endpointListener->endpointAdded = discovery_endpointAdded; - endpointListener->endpointRemoved = discovery_endpointRemoved; - - status = bundleContext_registerService(context, (char *) OSGI_ENDPOINT_LISTENER_SERVICE, endpointListener, props, &activator->endpointListenerService); - - if (status == CELIX_SUCCESS) { - activator->endpointListener = endpointListener; - } - } - } - // We can release the scope, as properties_set makes a copy of the key & value... - free(scope); - - return status; -} - -celix_status_t bundleActivator_stop(void * userData, bundle_context_pt context) { - celix_status_t status; - struct activator *activator = userData; - - status = discovery_stop(activator->discovery); - - status = serviceTracker_close(activator->endpointListenerTracker); - - status = serviceRegistration_unregister(activator->endpointListenerService); - free(activator->endpointListener); - - logHelper_stop(activator->loghelper); - - return status; -} - -celix_status_t bundleActivator_destroy(void * userData, bundle_context_pt context) { - celix_status_t status; - struct activator *activator = userData; - - status = serviceTracker_destroy(activator->endpointListenerTracker); - - status = discovery_destroy(activator->discovery); - - logHelper_destroy(&activator->loghelper); - - activator->loghelper = NULL; - activator->endpointListenerTracker = NULL; - activator->endpointListenerService = NULL; - activator->discovery = NULL; - activator->context = NULL; - - free(activator); - - return status; -}
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/discovery/private/src/endpoint_descriptor_reader.c ---------------------------------------------------------------------- diff --git a/remote_services/discovery/private/src/endpoint_descriptor_reader.c b/remote_services/discovery/private/src/endpoint_descriptor_reader.c deleted file mode 100644 index ea176bf..0000000 --- a/remote_services/discovery/private/src/endpoint_descriptor_reader.c +++ /dev/null @@ -1,387 +0,0 @@ -/** - *Licensed to the Apache Software Foundation (ASF) under one - *or more contributor license agreements. See the NOTICE file - *distributed with this work for additional information - *regarding copyright ownership. The ASF licenses this file - *to you under the Apache License, Version 2.0 (the - *"License"); you may not use this file except in compliance - *with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - *Unless required by applicable law or agreed to in writing, - *software distributed under the License is distributed on an - *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - *specific language governing permissions and limitations - *under the License. - */ -/* - * endpoint_descriptor_reader.c - * - * \date 24 Jul 2014 - * \author <a href="mailto:[email protected]">Apache Celix Project Team</a> - * \copyright Apache License, Version 2.0 - */ - -#include <stdbool.h> -#include <string.h> -#include <libxml/xmlreader.h> - -#include "log_helper.h" -#include "remote_constants.h" - -#include "endpoint_description.h" -#include "endpoint_descriptor_common.h" -#include "endpoint_descriptor_reader.h" - -struct endpoint_descriptor_reader { - xmlTextReaderPtr reader; - log_helper_pt* loghelper; -}; - -static valueType valueTypeFromString(char *name); - -celix_status_t endpointDescriptorReader_create(endpoint_discovery_poller_pt poller, endpoint_descriptor_reader_pt *reader) { - celix_status_t status = CELIX_SUCCESS; - - *reader = malloc(sizeof(**reader)); - if (!*reader) { - status = CELIX_ENOMEM; - } else { - (*reader)->reader = NULL; - (*reader)->loghelper = poller->loghelper; - } - - return status; -} - -celix_status_t endpointDescriptorReader_destroy(endpoint_descriptor_reader_pt reader) { - celix_status_t status = CELIX_SUCCESS; - - reader->loghelper = NULL; - - free(reader); - - return status; -} - -void endpointDescriptorReader_addSingleValuedProperty(properties_pt properties, const xmlChar* name, const xmlChar* value) { - properties_set(properties, (char *) name, (char*) value); -} - -void endpointDescriptorReader_addMultiValuedProperty(properties_pt properties, const xmlChar* name, array_list_pt values) { - char *value = calloc(256, sizeof(*value)); - if (value) { - unsigned int size = arrayList_size(values); - unsigned int i; - for (i = 0; i < size; i++) { - char* item = (char*) arrayList_get(values, i); - if (i > 0) { - value = strcat(value, ","); - } - value = strcat(value, item); - } - - properties_set(properties, (char *) name, value); - - free(value); - } -} - -celix_status_t endpointDescriptorReader_parseDocument(endpoint_descriptor_reader_pt reader, char *document, array_list_pt *endpoints) { - celix_status_t status = CELIX_SUCCESS; - - reader->reader = xmlReaderForMemory(document, (int) strlen(document), NULL, "UTF-8", 0); - if (reader->reader == NULL) { - status = CELIX_BUNDLE_EXCEPTION; - } else { - bool inProperty = false; - bool inXml = false; - bool inArray = false; - bool inList = false; - bool inSet = false; - bool inValue = false; - - const xmlChar *propertyName = NULL; - const xmlChar *propertyValue = NULL; - valueType propertyType = VALUE_TYPE_STRING; - xmlChar *valueBuffer = xmlMalloc(256); - valueBuffer[0] = '\0'; - - array_list_pt propertyValues = NULL; - arrayList_create(&propertyValues); - - array_list_pt endpointDescriptions = NULL; - if (*endpoints) { - // use the given arraylist... - endpointDescriptions = *endpoints; - } else { - arrayList_create(&endpointDescriptions); - // return the read endpoints... - *endpoints = endpointDescriptions; - } - - properties_pt endpointProperties = NULL; - - int read = xmlTextReaderRead(reader->reader); - while (read == XML_TEXTREADER_MODE_INTERACTIVE) { - int type = xmlTextReaderNodeType(reader->reader); - - if (type == XML_READER_TYPE_ELEMENT) { - const xmlChar *localname = xmlTextReaderConstLocalName(reader->reader); - - if (inXml) { - valueBuffer = xmlStrcat(valueBuffer, BAD_CAST "<"); - valueBuffer = xmlStrcat(valueBuffer, localname); - - int i = xmlTextReaderMoveToFirstAttribute(reader->reader); - while (i == 1) { - const xmlChar *name = xmlTextReaderConstName(reader->reader); - const xmlChar *value = xmlTextReaderConstValue(reader->reader); - - valueBuffer = xmlStrcat(valueBuffer, BAD_CAST " "); - valueBuffer = xmlStrcat(valueBuffer, name); - valueBuffer = xmlStrcat(valueBuffer, BAD_CAST "=\""); - valueBuffer = xmlStrcat(valueBuffer, BAD_CAST value); - valueBuffer = xmlStrcat(valueBuffer, BAD_CAST "\""); - - i = xmlTextReaderMoveToNextAttribute(reader->reader); - } - - valueBuffer = xmlStrcat(valueBuffer, BAD_CAST ">"); - } else if (xmlStrcmp(localname, ENDPOINT_DESCRIPTION) == 0) { - - if (endpointProperties != NULL) - properties_destroy(endpointProperties); - - endpointProperties = properties_create(); - } else if (xmlStrcmp(localname, PROPERTY) == 0) { - inProperty = true; - - propertyName = xmlTextReaderGetAttribute(reader->reader, NAME); - propertyValue = xmlTextReaderGetAttribute(reader->reader, VALUE); - xmlChar *vtype = xmlTextReaderGetAttribute(reader->reader, VALUE_TYPE); - propertyType = valueTypeFromString((char*) vtype); - arrayList_clear(propertyValues); - - if (xmlTextReaderIsEmptyElement(reader->reader)) { - inProperty = false; - - if (propertyValue != NULL) { - endpointDescriptorReader_addSingleValuedProperty(endpointProperties, propertyName, propertyValue); - } - - xmlFree((void *) propertyName); - xmlFree((void *) propertyValue); - xmlFree((void *) vtype); - } - } else { - valueBuffer[0] = 0; - inArray |= inProperty && xmlStrcmp(localname, ARRAY) == 0; - inList |= inProperty && xmlStrcmp(localname, LIST) == 0; - inSet |= inProperty && xmlStrcmp(localname, SET) == 0; - inXml |= inProperty && xmlStrcmp(localname, XML) == 0; - inValue |= inProperty && xmlStrcmp(localname, VALUE) == 0; - } - } else if (type == XML_READER_TYPE_END_ELEMENT) { - const xmlChar *localname = xmlTextReaderConstLocalName(reader->reader); - - if (inXml) { - if (xmlStrcmp(localname, XML) != 0) { - valueBuffer = xmlStrcat(valueBuffer, BAD_CAST "</"); - valueBuffer = xmlStrcat(valueBuffer, localname); - valueBuffer = xmlStrcat(valueBuffer, BAD_CAST ">"); - } - else { - inXml = false; - } - } else if (xmlStrcmp(localname, ENDPOINT_DESCRIPTION) == 0) { - endpoint_description_pt endpointDescription = NULL; - // Completely parsed endpoint description, add it to our list of results... - if(endpointDescription_create(endpointProperties, &endpointDescription) == CELIX_SUCCESS){ - arrayList_add(endpointDescriptions, endpointDescription); - } - - endpointProperties = properties_create(); - } else if (xmlStrcmp(localname, PROPERTY) == 0) { - inProperty = false; - - if (inArray || inList || inSet) { - endpointDescriptorReader_addMultiValuedProperty(endpointProperties, propertyName, propertyValues); - } - else if (propertyValue != NULL) { - if (propertyType != VALUE_TYPE_STRING) { - logHelper_log(*reader->loghelper, OSGI_LOGSERVICE_WARNING, "ENDPOINT_DESCRIPTOR_READER: Only string support for %s\n", propertyName); - } - endpointDescriptorReader_addSingleValuedProperty(endpointProperties, propertyName, propertyValue); - - xmlFree((void *) propertyValue); - } - else { - endpointDescriptorReader_addSingleValuedProperty(endpointProperties, propertyName, valueBuffer); - } - - xmlFree((void *) propertyName); - unsigned int k=0; - for(;k<arrayList_size(propertyValues);k++){ - free(arrayList_get(propertyValues,k)); - } - arrayList_clear(propertyValues); - - propertyType = VALUE_TYPE_STRING; - inArray = false; - inList = false; - inSet = false; - inXml = false; - } else if (xmlStrcmp(localname, VALUE) == 0) { - arrayList_add(propertyValues, strdup((char*) valueBuffer)); - valueBuffer[0] = 0; - inValue = false; - } - } else if (type == XML_READER_TYPE_TEXT) { - if (inValue || inXml) { - const xmlChar *value = xmlTextReaderValue(reader->reader); - valueBuffer = xmlStrcat(valueBuffer, value); - xmlFree((void *)value); - } - } - - read = xmlTextReaderRead(reader->reader); - } - - if(endpointProperties!=NULL){ - properties_destroy(endpointProperties); - } - - unsigned int k=0; - for(;k<arrayList_size(propertyValues);k++){ - free(arrayList_get(propertyValues,k)); - } - arrayList_destroy(propertyValues); - xmlFree(valueBuffer); - - xmlFreeTextReader(reader->reader); - } - - return status; -} - -static valueType valueTypeFromString(char *name) { - if (name == NULL || strcmp(name, "") == 0 || strcmp(name, "String") == 0) { - return VALUE_TYPE_STRING; - } else if (strcmp(name, "long") == 0 || strcmp(name, "Long") == 0) { - return VALUE_TYPE_LONG; - } else if (strcmp(name, "double") == 0 || strcmp(name, "Double") == 0) { - return VALUE_TYPE_DOUBLE; - } else if (strcmp(name, "float") == 0 || strcmp(name, "Float") == 0) { - return VALUE_TYPE_FLOAT; - } else if (strcmp(name, "int") == 0 || strcmp(name, "integer") == 0 || strcmp(name, "Integer") == 0) { - return VALUE_TYPE_INTEGER; - } else if (strcmp(name, "short") == 0 || strcmp(name, "Short") == 0) { - return VALUE_TYPE_SHORT; - } else if (strcmp(name, "byte") == 0 || strcmp(name, "Byte") == 0) { - return VALUE_TYPE_BYTE; - } else if (strcmp(name, "char") == 0 || strcmp(name, "Character") == 0) { - return VALUE_TYPE_CHAR; - } else if (strcmp(name, "boolean") == 0 || strcmp(name, "Boolean") == 0) { - return VALUE_TYPE_BOOLEAN; - } else { - return VALUE_TYPE_STRING; - } -} - -#ifdef RSA_ENDPOINT_TEST_READER -int main() { - array_list_pt list = NULL; - endpoint_descriptor_reader_pt reader = NULL; - - char *doc = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" -"<endpoint-descriptions xmlns=\"http://www.osgi.org/xmlns/rsa/v1.0.0\">" - "<endpoint-description>" - "<property name=\"endpoint.service.id\" value-type=\"long\" value=\"6\"/>" - "<property name=\"endpoint.framework.uuid\" value=\"2983D849-93B1-4C2C-AC6D-5BCDA93ACB96\"/>" - "<property name=\"service.intents\">" - "<list>" - "<value>SOAP</value>" - "<value>HTTP</value>" - "</list>" - "</property>" - "<property name=\"endpoint.id\" value=\"11111111-1111-1111-1111-111111111111\" />" - "<property name=\"objectClass\"><array><value>com.acme.Foo</value></array></property>" - "<property name=\"endpoint.package.version.com.acme\" value=\"4.2\" />" - "<property name=\"service.imported.configs\" value=\"com.acme\" />" - "<property name=\"service.imported\" value=\"true\"/>" - "<property name=\"com.acme.ws.xml\">" - "<xml>" - "<config xmlns=\"http://acme.com/defs\">" - "<port>1029</port>" - "<host>www.acme.com</host>" - "</config>" - "</xml>" - "</property>" - "</endpoint-description>" - "<endpoint-description>" - "<property name=\"endpoint.service.id\" value-type=\"long\" value=\"5\"/>" - "<property name=\"endpoint.framework.uuid\" value=\"2983D849-93B1-4C2C-AC6D-5BCDA93ACB96\"/>" - "<property name=\"service.intents\">" - "<list>" - "<value>SOAP</value>" - "<value>HTTP</value>" - "</list>" - "</property>" - "<property name=\"endpoint.id\" value=\"22222222-2222-2222-2222-222222222222\" />" - "<property name=\"objectClass\"><array><value>com.acme.Bar</value></array></property>" - "<property name=\"endpoint.package.version.com.acme\" value=\"4.2\" />" - "<property name=\"service.imported.configs\" value=\"com.acme\" />" - "<property name=\"com.acme.ws.xml\">" - "<xml>" - "<config xmlns=\"http://acme.com/defs\">" - "<port>1029</port>" - "<host>www.acme.com</host>" - "</config>" - "</xml>" - "</property>" - "</endpoint-description>" - "</endpoint-descriptions>"; - - endpointDescriptorReader_create(&reader); - - endpointDescriptorReader_parseDocument(reader, doc, &list); - - int i; - for (i = 0; i < arrayList_size(list); i++) { - printf("\nEndpoint description #%d:\n", (i+1)); - endpoint_description_pt edp = arrayList_get(list, i); - printf("Id: %s\n", edp->id); - printf("Service Id: %lu\n", edp->serviceId); - printf("Framework UUID: %s\n", edp->frameworkUUID); - printf("Service: %s\n", edp->service); - - properties_pt props = edp->properties; - if (props) { - printf("Service properties:\n"); - hash_map_iterator_pt iter = hashMapIterator_create(props); - while (hashMapIterator_hasNext(iter)) { - hash_map_entry_pt entry = hashMapIterator_nextEntry(iter); - - printf("- %s => '%s'\n", hashMapEntry_getKey(entry), hashMapEntry_getValue(entry)); - } - hashMapIterator_destroy(iter); - } else { - printf("No service properties...\n"); - } - - - endpointDescription_destroy(edp); - } - - if (list != NULL) { - arrayList_destroy(list); - } - - endpointDescriptorReader_destroy(reader); - - return 0; -} -#endif http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/discovery/private/src/endpoint_descriptor_writer.c ---------------------------------------------------------------------- diff --git a/remote_services/discovery/private/src/endpoint_descriptor_writer.c b/remote_services/discovery/private/src/endpoint_descriptor_writer.c deleted file mode 100644 index 71b07b4..0000000 --- a/remote_services/discovery/private/src/endpoint_descriptor_writer.c +++ /dev/null @@ -1,233 +0,0 @@ -/** - *Licensed to the Apache Software Foundation (ASF) under one - *or more contributor license agreements. See the NOTICE file - *distributed with this work for additional information - *regarding copyright ownership. The ASF licenses this file - *to you under the Apache License, Version 2.0 (the - *"License"); you may not use this file except in compliance - *with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - *Unless required by applicable law or agreed to in writing, - *software distributed under the License is distributed on an - *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - *specific language governing permissions and limitations - *under the License. - */ -/* - * endpoint_descriptor_writer.c - * - * \date 26 Jul 2014 - * \author <a href="mailto:[email protected]">Apache Celix Project Team</a> - * \copyright Apache License, Version 2.0 - */ -#include <stdlib.h> -#include <string.h> -#include <libxml/xmlwriter.h> - -#include "constants.h" -#include "remote_constants.h" - -#include "endpoint_description.h" -#include "endpoint_descriptor_common.h" -#include "endpoint_descriptor_writer.h" - -struct endpoint_descriptor_writer { - xmlBufferPtr buffer; - xmlTextWriterPtr writer; -}; - -static celix_status_t endpointDescriptorWriter_writeEndpoint(endpoint_descriptor_writer_pt writer, endpoint_description_pt endpoint); - -static char* valueTypeToString(valueType type); - -celix_status_t endpointDescriptorWriter_create(endpoint_descriptor_writer_pt *writer) { - celix_status_t status = CELIX_SUCCESS; - - *writer = malloc(sizeof(**writer)); - if (!*writer) { - status = CELIX_ENOMEM; - } else { - (*writer)->buffer = xmlBufferCreate(); - if ((*writer)->buffer == NULL) { - status = CELIX_BUNDLE_EXCEPTION; - } else { - (*writer)->writer = xmlNewTextWriterMemory((*writer)->buffer, 0); - if ((*writer)->writer == NULL) { - status = CELIX_BUNDLE_EXCEPTION; - } - } - } - - return status; -} - -celix_status_t endpointDescriptorWriter_destroy(endpoint_descriptor_writer_pt writer) { - xmlFreeTextWriter(writer->writer); - xmlBufferFree(writer->buffer); - free(writer); - return CELIX_SUCCESS; -} - -celix_status_t endpointDescriptorWriter_writeDocument(endpoint_descriptor_writer_pt writer, array_list_pt endpoints, char **document) { - celix_status_t status = CELIX_SUCCESS; - int rc; - - rc = xmlTextWriterStartDocument(writer->writer, NULL, "UTF-8", NULL); - if (rc < 0) { - status = CELIX_BUNDLE_EXCEPTION; - } else { - rc = xmlTextWriterStartElementNS(writer->writer, NULL, ENDPOINT_DESCRIPTIONS, XMLNS); - if (rc < 0) { - status = CELIX_BUNDLE_EXCEPTION; - } else { - unsigned int i; - for (i = 0; i < arrayList_size(endpoints); i++) { - endpoint_description_pt endpoint = arrayList_get(endpoints, i); - status = endpointDescriptorWriter_writeEndpoint(writer, endpoint); - } - if (status == CELIX_SUCCESS) { - rc = xmlTextWriterEndElement(writer->writer); - if (rc < 0) { - status = CELIX_BUNDLE_EXCEPTION; - } else { - rc = xmlTextWriterEndDocument(writer->writer); - if (rc < 0) { - status = CELIX_BUNDLE_EXCEPTION; - } else { - *document = (char *) writer->buffer->content; - } - } - } - } - } - - return status; -} - -static celix_status_t endpointDescriptorWriter_writeArrayValue(xmlTextWriterPtr writer, const xmlChar* value) { - xmlTextWriterStartElement(writer, ARRAY); - xmlTextWriterStartElement(writer, VALUE); - xmlTextWriterWriteString(writer, value); - xmlTextWriterEndElement(writer); // value - xmlTextWriterEndElement(writer); // array - - return CELIX_SUCCESS; -} - -static celix_status_t endpointDescriptorWriter_writeTypedValue(xmlTextWriterPtr writer, valueType type, const xmlChar* value) { - xmlTextWriterWriteAttribute(writer, VALUE_TYPE, (const xmlChar*) valueTypeToString(type)); - xmlTextWriterWriteAttribute(writer, VALUE, value); - - return CELIX_SUCCESS; -} - -static celix_status_t endpointDescriptorWriter_writeUntypedValue(xmlTextWriterPtr writer, const xmlChar* value) { - xmlTextWriterWriteAttribute(writer, VALUE, value); - - return CELIX_SUCCESS; -} - -static celix_status_t endpointDescriptorWriter_writeEndpoint(endpoint_descriptor_writer_pt writer, endpoint_description_pt endpoint) { - celix_status_t status = CELIX_SUCCESS; - - if (endpoint == NULL || writer == NULL) { - status = CELIX_ILLEGAL_ARGUMENT; - } else { - xmlTextWriterStartElement(writer->writer, ENDPOINT_DESCRIPTION); - - hash_map_iterator_pt iter = hashMapIterator_create(endpoint->properties); - while (hashMapIterator_hasNext(iter)) { - hash_map_entry_pt entry = hashMapIterator_nextEntry(iter); - - void* propertyName = hashMapEntry_getKey(entry); - const xmlChar* propertyValue = (const xmlChar*) hashMapEntry_getValue(entry); - - xmlTextWriterStartElement(writer->writer, PROPERTY); - xmlTextWriterWriteAttribute(writer->writer, NAME, propertyName); - - if (strcmp(OSGI_FRAMEWORK_OBJECTCLASS, (char*) propertyName) == 0) { - // objectClass *must* be represented as array of string values... - endpointDescriptorWriter_writeArrayValue(writer->writer, propertyValue); - } else if (strcmp(OSGI_RSA_ENDPOINT_SERVICE_ID, (char*) propertyName) == 0) { - // endpoint.service.id *must* be represented as long value... - endpointDescriptorWriter_writeTypedValue(writer->writer, VALUE_TYPE_LONG, propertyValue); - } else { - // represent all other values as plain string values... - endpointDescriptorWriter_writeUntypedValue(writer->writer, propertyValue); - } - - xmlTextWriterEndElement(writer->writer); - } - hashMapIterator_destroy(iter); - - xmlTextWriterEndElement(writer->writer); - } - - return status; -} - - -static char* valueTypeToString(valueType type) { - switch (type) { - case VALUE_TYPE_BOOLEAN: - return "boolean"; - case VALUE_TYPE_BYTE: - return "byte"; - case VALUE_TYPE_CHAR: - return "char"; - case VALUE_TYPE_DOUBLE: - return "double"; - case VALUE_TYPE_FLOAT: - return "float"; - case VALUE_TYPE_INTEGER: - return "int"; - case VALUE_TYPE_LONG: - return "long"; - case VALUE_TYPE_SHORT: - return "short"; - case VALUE_TYPE_STRING: - // FALL-THROUGH! - default: - return "string"; - } -} - -#ifdef RSA_ENDPOINT_TEST_WRITER -int main() { - endpoint_descriptor_writer_pt writer = NULL; - endpointDescriptorWriter_create(&writer); - array_list_pt list = NULL; - arrayList_create(&list); - - properties_pt props = properties_create(); - properties_set(props, "objectClass", "com.acme.Foo"); - properties_set(props, "endpoint.service.id", "3"); - properties_set(props, "endpoint.id", "abcdefghijklmnopqrstuvwxyz"); - properties_set(props, "endpoint.framework.uuid", "2983D849-93B1-4C2C-AC6D-5BCDA93ACB96"); - endpoint_description_pt epd = NULL; - endpointDescription_create(props, &epd); - arrayList_add(list, epd); - - properties_pt props2 = properties_create(); - properties_set(props2, "objectClass", "com.acme.Bar"); - properties_set(props, "endpoint.service.id", "4"); - properties_set(props, "endpoint.id", "abcdefghijklmnopqrstuvwxyz"); - properties_set(props, "endpoint.framework.uuid", "2983D849-93B1-4C2C-AC6D-5BCDA93ACB96"); - endpoint_description_pt epd2 = NULL; - endpointDescription_create(props2, &epd2); - arrayList_add(list, epd2); - - char *buffer = NULL; - endpointDescriptorWriter_writeDocument(writer, list, &buffer); - - arrayList_destroy(list); - endpointDescription_destroy(epd); - endpointDescription_destroy(epd2); - endpointDescriptorWriter_destroy(writer); - - printf("%s\n", buffer); -} -#endif http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/discovery/private/src/endpoint_discovery_poller.c ---------------------------------------------------------------------- diff --git a/remote_services/discovery/private/src/endpoint_discovery_poller.c b/remote_services/discovery/private/src/endpoint_discovery_poller.c deleted file mode 100644 index 73fb7ba..0000000 --- a/remote_services/discovery/private/src/endpoint_discovery_poller.c +++ /dev/null @@ -1,403 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -/* - * endpoint_discovery_poller.c - * - * \date 3 Jul 2014 - * \author <a href="mailto:[email protected]">Apache Celix Project Team</a> - * \copyright Apache License, Version 2.0 - */ -#include <stdbool.h> -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <unistd.h> - -#include <curl/curl.h> - -#include "bundle_context.h" -#include "log_helper.h" -#include "utils.h" - -#include "discovery_impl.h" - -#include "endpoint_descriptor_reader.h" - - -#define DISCOVERY_POLL_INTERVAL "DISCOVERY_CFG_POLL_INTERVAL" -#define DEFAULT_POLL_INTERVAL "10" - - -static void *endpointDiscoveryPoller_performPeriodicPoll(void *data); -celix_status_t endpointDiscoveryPoller_poll(endpoint_discovery_poller_pt poller, char *url, array_list_pt currentEndpoints); -static celix_status_t endpointDiscoveryPoller_getEndpoints(endpoint_discovery_poller_pt poller, char *url, array_list_pt *updatedEndpoints); -static celix_status_t endpointDiscoveryPoller_endpointDescriptionEquals(const void *endpointPtr, const void *comparePtr, bool *equals); - -/** - * Allocates memory and initializes a new endpoint_discovery_poller instance. - */ -celix_status_t endpointDiscoveryPoller_create(discovery_pt discovery, bundle_context_pt context, endpoint_discovery_poller_pt *poller) { - celix_status_t status; - - *poller = malloc(sizeof(struct endpoint_discovery_poller)); - if (!*poller) { - return CELIX_ENOMEM; - } - - (*poller)->loghelper = &discovery->loghelper; - - status = celixThreadMutex_create(&(*poller)->pollerLock, NULL); - if (status != CELIX_SUCCESS) { - return status; - } - - const char* interval = NULL; - status = bundleContext_getProperty(context, DISCOVERY_POLL_INTERVAL, &interval); - if (!interval) { - interval = DEFAULT_POLL_INTERVAL; - } - - const char* endpointsProp = NULL; - status = bundleContext_getProperty(context, DISCOVERY_POLL_ENDPOINTS, &endpointsProp); - if (!endpointsProp) { - endpointsProp = DEFAULT_POLL_ENDPOINTS; - } - // we're going to mutate the string with strtok, so create a copy... - char* endpoints = strdup(endpointsProp); - - (*poller)->poll_interval = atoi(interval); - (*poller)->discovery = discovery; - (*poller)->running = false; - (*poller)->entries = hashMap_create(utils_stringHash, NULL, utils_stringEquals, NULL); - - const char* sep = ","; - char *save_ptr = NULL; - char* tok = strtok_r(endpoints, sep, &save_ptr); - while (tok) { - endpointDiscoveryPoller_addDiscoveryEndpoint(*poller, utils_stringTrim(tok)); - tok = strtok_r(NULL, sep, &save_ptr); - } - // Clean up after ourselves... - free(endpoints); - - status = celixThreadMutex_lock(&(*poller)->pollerLock); - if (status != CELIX_SUCCESS) { - return CELIX_BUNDLE_EXCEPTION; - } - - (*poller)->running = true; - - status += celixThread_create(&(*poller)->pollerThread, NULL, endpointDiscoveryPoller_performPeriodicPoll, *poller); - status += celixThreadMutex_unlock(&(*poller)->pollerLock); - - if(status != CELIX_SUCCESS){ - status = CELIX_BUNDLE_EXCEPTION; - } - - return status; -} - -/** - * Destroys and frees up memory for a given endpoint_discovery_poller struct. - */ -celix_status_t endpointDiscoveryPoller_destroy(endpoint_discovery_poller_pt poller) { - celix_status_t status; - - poller->running = false; - - celixThread_join(poller->pollerThread, NULL); - - hash_map_iterator_pt iterator = hashMapIterator_create(poller->entries); - while (hashMapIterator_hasNext(iterator)) { - hash_map_entry_pt entry = hashMapIterator_nextEntry(iterator); - - if ( endpointDiscoveryPoller_removeDiscoveryEndpoint(poller, (char*) hashMapEntry_getKey(entry)) == CELIX_SUCCESS) { - hashMapIterator_destroy(iterator); - iterator = hashMapIterator_create(poller->entries); - } - } - hashMapIterator_destroy(iterator); - - status = celixThreadMutex_lock(&poller->pollerLock); - - if (status != CELIX_SUCCESS) { - return CELIX_BUNDLE_EXCEPTION; - } - - hashMap_destroy(poller->entries, true, false); - - status = celixThreadMutex_unlock(&poller->pollerLock); - - poller->loghelper = NULL; - - free(poller); - - return status; -} - - -celix_status_t endpointDiscoveryPoller_getDiscoveryEndpoints(endpoint_discovery_poller_pt poller, array_list_pt urls) { - celixThreadMutex_lock(&(poller)->pollerLock); - - hash_map_iterator_pt iterator = hashMapIterator_create(poller->entries); - - while(hashMapIterator_hasNext(iterator)) { - hash_map_entry_pt entry = hashMapIterator_nextEntry(iterator); - char* toAdd = strdup((char*) hashMapEntry_getKey(entry)); - arrayList_add(urls, toAdd); - } - - hashMapIterator_destroy(iterator); - - celixThreadMutex_unlock(&(poller)->pollerLock); - - return CELIX_SUCCESS; -} - -/** - * Adds a new endpoint URL to the list of polled endpoints. - */ -celix_status_t endpointDiscoveryPoller_addDiscoveryEndpoint(endpoint_discovery_poller_pt poller, char *url) { - celix_status_t status; - - status = celixThreadMutex_lock(&(poller)->pollerLock); - if (status != CELIX_SUCCESS) { - return CELIX_BUNDLE_EXCEPTION; - } - - // Avoid memory leaks when adding an already existing URL... - array_list_pt endpoints = hashMap_get(poller->entries, url); - if (endpoints == NULL) { - status = arrayList_createWithEquals(endpointDiscoveryPoller_endpointDescriptionEquals, &endpoints); - - if (status == CELIX_SUCCESS) { - logHelper_log(*poller->loghelper, OSGI_LOGSERVICE_DEBUG, "ENDPOINT_POLLER: add new discovery endpoint with url %s", url); - hashMap_put(poller->entries, strdup(url), endpoints); - endpointDiscoveryPoller_poll(poller, url, endpoints); - } - } - - status = celixThreadMutex_unlock(&poller->pollerLock); - - return status; -} - -/** - * Removes an endpoint URL from the list of polled endpoints. - */ -celix_status_t endpointDiscoveryPoller_removeDiscoveryEndpoint(endpoint_discovery_poller_pt poller, char *url) { - celix_status_t status = CELIX_SUCCESS; - - if (celixThreadMutex_lock(&poller->pollerLock) != CELIX_SUCCESS) { - status = CELIX_BUNDLE_EXCEPTION; - } else { - hash_map_entry_pt entry = hashMap_getEntry(poller->entries, url); - - if (entry == NULL) { - logHelper_log(*poller->loghelper, OSGI_LOGSERVICE_DEBUG, "ENDPOINT_POLLER: There was no entry found belonging to url %s - maybe already removed?", url); - } else { - char* origKey = hashMapEntry_getKey(entry); - - logHelper_log(*poller->loghelper, OSGI_LOGSERVICE_DEBUG, "ENDPOINT_POLLER: remove discovery endpoint with url %s", url); - - array_list_pt entries = hashMap_remove(poller->entries, url); - - if (entries != NULL) { - for (unsigned int i = arrayList_size(entries); i > 0; i--) { - endpoint_description_pt endpoint = arrayList_get(entries, i - 1); - discovery_removeDiscoveredEndpoint(poller->discovery, endpoint); - arrayList_remove(entries, i - 1); - endpointDescription_destroy(endpoint); - } - arrayList_destroy(entries); - } - - free(origKey); - } - status = celixThreadMutex_unlock(&poller->pollerLock); - } - - return status; -} - - - - -celix_status_t endpointDiscoveryPoller_poll(endpoint_discovery_poller_pt poller, char *url, array_list_pt currentEndpoints) { - celix_status_t status; - array_list_pt updatedEndpoints = NULL; - - // create an arraylist with a custom equality test to ensure we can find endpoints properly... - arrayList_createWithEquals(endpointDiscoveryPoller_endpointDescriptionEquals, &updatedEndpoints); - status = endpointDiscoveryPoller_getEndpoints(poller, url, &updatedEndpoints); - - if (status == CELIX_SUCCESS) { - if (updatedEndpoints!=NULL) { - for (unsigned int i = arrayList_size(currentEndpoints); i > 0; i--) { - endpoint_description_pt endpoint = arrayList_get(currentEndpoints, i - 1); - - if (!arrayList_contains(updatedEndpoints, endpoint)) { - status = discovery_removeDiscoveredEndpoint(poller->discovery, endpoint); - arrayList_remove(currentEndpoints, i - 1); - endpointDescription_destroy(endpoint); - } - } - - for (int i = arrayList_size(updatedEndpoints); i > 0; i--) { - endpoint_description_pt endpoint = arrayList_remove(updatedEndpoints, 0); - - if (!arrayList_contains(currentEndpoints, endpoint)) { - arrayList_add(currentEndpoints, endpoint); - status = discovery_addDiscoveredEndpoint(poller->discovery, endpoint); - } else { - endpointDescription_destroy(endpoint); - - } - } - } - } - - if(updatedEndpoints!=NULL){ - arrayList_destroy(updatedEndpoints); - } - - return status; -} - -static void *endpointDiscoveryPoller_performPeriodicPoll(void *data) { - endpoint_discovery_poller_pt poller = (endpoint_discovery_poller_pt) data; - - useconds_t interval = (useconds_t) (poller->poll_interval * 1000000L); - - while (poller->running) { - usleep(interval); - celix_status_t status = celixThreadMutex_lock(&poller->pollerLock); - - if (status != CELIX_SUCCESS) { - logHelper_log(*poller->loghelper, OSGI_LOGSERVICE_WARNING, "ENDPOINT_POLLER: failed to obtain lock; retrying..."); - } else { - hash_map_iterator_pt iterator = hashMapIterator_create(poller->entries); - - while (hashMapIterator_hasNext(iterator)) { - hash_map_entry_pt entry = hashMapIterator_nextEntry(iterator); - - char *url = hashMapEntry_getKey(entry); - array_list_pt currentEndpoints = hashMapEntry_getValue(entry); - - endpointDiscoveryPoller_poll(poller, url, currentEndpoints); - } - - hashMapIterator_destroy(iterator); - } - - status = celixThreadMutex_unlock(&poller->pollerLock); - if (status != CELIX_SUCCESS) { - logHelper_log(*poller->loghelper, OSGI_LOGSERVICE_WARNING, "ENDPOINT_POLLER: failed to release lock; retrying..."); - } - } - - return NULL; -} - - - -struct MemoryStruct { - char *memory; - size_t size; -}; - -static size_t endpointDiscoveryPoller_writeMemory(void *contents, size_t size, size_t nmemb, void *memoryPtr) { - size_t realsize = size * nmemb; - struct MemoryStruct *mem = (struct MemoryStruct *)memoryPtr; - - mem->memory = realloc(mem->memory, mem->size + realsize + 1); - if(mem->memory == NULL) { - printf("ENDPOINT_POLLER: not enough memory (realloc returned NULL)!"); - return 0; - } - - memcpy(&(mem->memory[mem->size]), contents, realsize); - mem->size += realsize; - mem->memory[mem->size] = 0; - - return realsize; -} - -static celix_status_t endpointDiscoveryPoller_getEndpoints(endpoint_discovery_poller_pt poller, char *url, array_list_pt *updatedEndpoints) { - celix_status_t status = CELIX_SUCCESS; - - - CURL *curl = NULL; - CURLcode res = CURLE_OK; - - struct MemoryStruct chunk; - chunk.memory = malloc(1); - chunk.size = 0; - - curl = curl_easy_init(); - if (!curl) { - status = CELIX_ILLEGAL_STATE; - } else { - curl_easy_setopt(curl, CURLOPT_URL, url); - curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1); - curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, endpointDiscoveryPoller_writeMemory); - curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&chunk); - curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 5L); - curl_easy_setopt(curl, CURLOPT_TIMEOUT, 10L); - res = curl_easy_perform(curl); - - curl_easy_cleanup(curl); - } - - // process endpoints file - if (res == CURLE_OK) { - endpoint_descriptor_reader_pt reader = NULL; - - status = endpointDescriptorReader_create(poller, &reader); - if (status == CELIX_SUCCESS) { - status = endpointDescriptorReader_parseDocument(reader, chunk.memory, updatedEndpoints); - } - - if (reader) { - endpointDescriptorReader_destroy(reader); - } - } else { - logHelper_log(*poller->loghelper, OSGI_LOGSERVICE_ERROR, "ENDPOINT_POLLER: unable to read endpoints from %s, reason: %s", url, curl_easy_strerror(res)); - } - - // clean up endpoints file - if (chunk.memory) { - free(chunk.memory); - } - - return status; -} - -static celix_status_t endpointDiscoveryPoller_endpointDescriptionEquals(const void *endpointPtr, const void *comparePtr, bool *equals) { - endpoint_description_pt endpoint = (endpoint_description_pt) endpointPtr; - endpoint_description_pt compare = (endpoint_description_pt) comparePtr; - - if (strcmp(endpoint->id, compare->id) == 0) { - *equals = true; - } else { - *equals = false; - } - - return CELIX_SUCCESS; -} http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/discovery/private/src/endpoint_discovery_server.c ---------------------------------------------------------------------- diff --git a/remote_services/discovery/private/src/endpoint_discovery_server.c b/remote_services/discovery/private/src/endpoint_discovery_server.c deleted file mode 100644 index f5f82af..0000000 --- a/remote_services/discovery/private/src/endpoint_discovery_server.c +++ /dev/null @@ -1,450 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -/* - * endpoint_discovery_server.c - * - * \date Aug 12, 2014 - * \author <a href="mailto:[email protected]">Apache Celix Project Team</a> - * \copyright Apache License, Version 2.0 - */ -#include <stdlib.h> -#include <string.h> -#include <arpa/inet.h> -#include <netdb.h> -#ifndef ANDROID -#include <ifaddrs.h> -#endif -#include "civetweb.h" -#include "celix_errno.h" -#include "utils.h" -#include "log_helper.h" -#include "discovery.h" -#include "discovery_impl.h" - -#include "endpoint_descriptor_writer.h" - -// defines how often the webserver is restarted (with an increased port number) -#define MAX_NUMBER_OF_RESTARTS 15 -#define DEFAULT_SERVER_THREADS "1" - -#define CIVETWEB_REQUEST_NOT_HANDLED 0 -#define CIVETWEB_REQUEST_HANDLED 1 - -static const char *response_headers = - "HTTP/1.1 200 OK\r\n" - "Cache: no-cache\r\n" - "Content-Type: application/xml;charset=utf-8\r\n" - "\r\n"; - -struct endpoint_discovery_server { - log_helper_pt* loghelper; - hash_map_pt entries; // key = endpointId, value = endpoint_descriptor_pt - - celix_thread_mutex_t serverLock; - - const char* path; - const char *port; - const char* ip; - struct mg_context* ctx; -}; - -// Forward declarations... -static int endpointDiscoveryServer_callback(struct mg_connection *conn); -static char* format_path(const char* path); - -#ifndef ANDROID -static celix_status_t endpointDiscoveryServer_getIpAdress(char* interface, char** ip); -#endif - -celix_status_t endpointDiscoveryServer_create(discovery_pt discovery, bundle_context_pt context, endpoint_discovery_server_pt *server) { - celix_status_t status; - - const char *port = NULL; - const char *ip = NULL; - char *detectedIp = NULL; - const char *path = NULL; - const char *retries = NULL; - - int max_ep_num = MAX_NUMBER_OF_RESTARTS; - - *server = malloc(sizeof(struct endpoint_discovery_server)); - if (!*server) { - return CELIX_ENOMEM; - } - - (*server)->loghelper = &discovery->loghelper; - (*server)->entries = hashMap_create(&utils_stringHash, NULL, &utils_stringEquals, NULL); - if (!(*server)->entries) { - return CELIX_ENOMEM; - } - - status = celixThreadMutex_create(&(*server)->serverLock, NULL); - if (status != CELIX_SUCCESS) { - return CELIX_BUNDLE_EXCEPTION; - } - - bundleContext_getProperty(context, DISCOVERY_SERVER_IP, &ip); -#ifndef ANDROID - if (ip == NULL) { - const char *interface = NULL; - - bundleContext_getProperty(context, DISCOVERY_SERVER_INTERFACE, &interface); - if ((interface != NULL) && (endpointDiscoveryServer_getIpAdress((char*)interface, &detectedIp) != CELIX_SUCCESS)) { - logHelper_log(*(*server)->loghelper, OSGI_LOGSERVICE_WARNING, "Could not retrieve IP adress for interface %s", interface); - } - - if (detectedIp == NULL) { - endpointDiscoveryServer_getIpAdress(NULL, &detectedIp); - } - - ip = detectedIp; - } -#endif - - if (ip != NULL) { - logHelper_log(*(*server)->loghelper, OSGI_LOGSERVICE_INFO, "Using %s for service annunciation", ip); - (*server)->ip = strdup(ip); - } - else { - logHelper_log(*(*server)->loghelper, OSGI_LOGSERVICE_WARNING, "No IP address for service annunciation set. Using %s", DEFAULT_SERVER_IP); - (*server)->ip = strdup((char*) DEFAULT_SERVER_IP); - } - - if (detectedIp != NULL) { - free(detectedIp); - } - - bundleContext_getProperty(context, DISCOVERY_SERVER_PORT, &port); - if (port == NULL) { - port = DEFAULT_SERVER_PORT; - } - - bundleContext_getProperty(context, DISCOVERY_SERVER_PATH, &path); - if (path == NULL) { - path = DEFAULT_SERVER_PATH; - } - - bundleContext_getProperty(context, DISCOVERY_SERVER_MAX_EP, &retries); - if (retries != NULL) { - errno=0; - max_ep_num = strtol(retries,NULL,10); - if(errno!=0 || max_ep_num<=0){ - max_ep_num=MAX_NUMBER_OF_RESTARTS; - } - } - - (*server)->path = format_path(path); - - const struct mg_callbacks callbacks = { - .begin_request = endpointDiscoveryServer_callback, - }; - - unsigned int port_counter = 0; - char newPort[10]; - - do { - const char *options[] = { - "listening_ports", port, - "num_threads", DEFAULT_SERVER_THREADS, - NULL - }; - - (*server)->ctx = mg_start(&callbacks, (*server), options); - - if ((*server)->ctx != NULL) - { - logHelper_log(discovery->loghelper, OSGI_LOGSERVICE_INFO, "Starting discovery server on port %s...", port); - } - else { - errno = 0; - char* endptr = (char*)port; - long currentPort = strtol(port, &endptr, 10); - - if (*endptr || errno != 0) { - currentPort = strtol(DEFAULT_SERVER_PORT, NULL, 10); - } - - port_counter++; - snprintf(&newPort[0], 10, "%ld", (currentPort+1)); - - logHelper_log(discovery->loghelper, OSGI_LOGSERVICE_ERROR, "Error while starting discovery server on port %s - retrying on port %s...", port, newPort); - port = newPort; - - } - - } while(((*server)->ctx == NULL) && (port_counter < max_ep_num)); - - (*server)->port = strdup(port); - - return status; -} - -celix_status_t endpointDiscoveryServer_getUrl(endpoint_discovery_server_pt server, char* url) -{ - celix_status_t status = CELIX_BUNDLE_EXCEPTION; - - if (server->ip && server->port && server->path) { - sprintf(url, "http://%s:%s/%s", server->ip, server->port, server->path); - status = CELIX_SUCCESS; - } - - return status; -} - -celix_status_t endpointDiscoveryServer_destroy(endpoint_discovery_server_pt server) { - celix_status_t status; - - // stop & block until the actual server is shut down... - if (server->ctx != NULL) { - mg_stop(server->ctx); - server->ctx = NULL; - } - - status = celixThreadMutex_lock(&server->serverLock); - - hashMap_destroy(server->entries, true /* freeKeys */, false /* freeValues */); - - status = celixThreadMutex_unlock(&server->serverLock); - status = celixThreadMutex_destroy(&server->serverLock); - - free((void*) server->path); - free((void*) server->port); - free((void*) server->ip); - - free(server); - - return status; -} - -celix_status_t endpointDiscoveryServer_addEndpoint(endpoint_discovery_server_pt server, endpoint_description_pt endpoint) { - celix_status_t status; - - status = celixThreadMutex_lock(&server->serverLock); - if (status != CELIX_SUCCESS) { - return CELIX_BUNDLE_EXCEPTION; - } - - // create a local copy of the endpointId which we can control... - char* endpointId = strdup(endpoint->id); - endpoint_description_pt cur_value = hashMap_get(server->entries, endpointId); - if (!cur_value) { - logHelper_log(*server->loghelper, OSGI_LOGSERVICE_INFO, "exposing new endpoint \"%s\"...", endpointId); - - hashMap_put(server->entries, endpointId, endpoint); - } - - status = celixThreadMutex_unlock(&server->serverLock); - if (status != CELIX_SUCCESS) { - return CELIX_BUNDLE_EXCEPTION; - } - - return status; -} - -celix_status_t endpointDiscoveryServer_removeEndpoint(endpoint_discovery_server_pt server, endpoint_description_pt endpoint) { - celix_status_t status; - - status = celixThreadMutex_lock(&server->serverLock); - if (status != CELIX_SUCCESS) { - return CELIX_BUNDLE_EXCEPTION; - } - - hash_map_entry_pt entry = hashMap_getEntry(server->entries, endpoint->id); - if (entry) { - char* key = hashMapEntry_getKey(entry); - - logHelper_log(*server->loghelper, OSGI_LOGSERVICE_INFO, "removing endpoint \"%s\"...\n", key); - - hashMap_remove(server->entries, key); - - // we've made this key, see _addEnpoint above... - free((void*) key); - } - - status = celixThreadMutex_unlock(&server->serverLock); - if (status != CELIX_SUCCESS) { - return CELIX_BUNDLE_EXCEPTION; - } - - return status; -} - -static char* format_path(const char* path) { - char* result = strdup(path); - result = utils_stringTrim(result); - // check whether the path starts with a leading slash... - if (result[0] != '/') { - size_t len = strlen(result); - result = realloc(result, len + 2); - memmove(result + 1, result, len); - result[0] = '/'; - result[len + 1] = 0; - } - return result; -} - -static celix_status_t endpointDiscoveryServer_getEndpoints(endpoint_discovery_server_pt server, const char* the_endpoint_id, array_list_pt *endpoints) { - celix_status_t status; - - status = arrayList_create(endpoints); - if (status != CELIX_SUCCESS) { - return CELIX_ENOMEM; - } - - - hash_map_iterator_pt iter = hashMapIterator_create(server->entries); - while (hashMapIterator_hasNext(iter)) { - hash_map_entry_pt entry = hashMapIterator_nextEntry(iter); - - char* endpoint_id = hashMapEntry_getKey(entry); - if (the_endpoint_id == NULL || strcmp(the_endpoint_id, endpoint_id) == 0) { - endpoint_description_pt endpoint = hashMapEntry_getValue(entry); - - arrayList_add(*endpoints, endpoint); - } - } - hashMapIterator_destroy(iter); - - return status; -} - -static int endpointDiscoveryServer_writeEndpoints(struct mg_connection* conn, array_list_pt endpoints) { - celix_status_t status; - int rv = CIVETWEB_REQUEST_NOT_HANDLED; - - endpoint_descriptor_writer_pt writer = NULL; - status = endpointDescriptorWriter_create(&writer); - if (status == CELIX_SUCCESS) { - - char *buffer = NULL; - status = endpointDescriptorWriter_writeDocument(writer, endpoints, &buffer); - if (buffer) { - mg_write(conn, response_headers, strlen(response_headers)); - mg_write(conn, buffer, strlen(buffer)); - } - - rv = CIVETWEB_REQUEST_HANDLED; - } - - if(writer!=NULL){ - endpointDescriptorWriter_destroy(writer); - } - - return rv; -} - -// returns all endpoints as XML... -static int endpointDiscoveryServer_returnAllEndpoints(endpoint_discovery_server_pt server, struct mg_connection* conn) { - int status = CIVETWEB_REQUEST_NOT_HANDLED; - - array_list_pt endpoints = NULL; - - if (celixThreadMutex_lock(&server->serverLock) == CELIX_SUCCESS) { - endpointDiscoveryServer_getEndpoints(server, NULL, &endpoints); - if (endpoints) { - status = endpointDiscoveryServer_writeEndpoints(conn, endpoints); - - arrayList_destroy(endpoints); - } - - - celixThreadMutex_unlock(&server->serverLock); - } - - return status; -} - -// returns a single endpoint as XML... -static int endpointDiscoveryServer_returnEndpoint(endpoint_discovery_server_pt server, struct mg_connection* conn, const char* endpoint_id) { - int status = CIVETWEB_REQUEST_NOT_HANDLED; - - array_list_pt endpoints = NULL; - - if (celixThreadMutex_lock(&server->serverLock) == CELIX_SUCCESS) { - endpointDiscoveryServer_getEndpoints(server, endpoint_id, &endpoints); - if (endpoints) { - status = endpointDiscoveryServer_writeEndpoints(conn, endpoints); - - arrayList_destroy(endpoints); - } - - celixThreadMutex_unlock(&server->serverLock); - } - - return status; -} - -static int endpointDiscoveryServer_callback(struct mg_connection* conn) { - int status = CIVETWEB_REQUEST_NOT_HANDLED; - - const struct mg_request_info *request_info = mg_get_request_info(conn); - if (request_info->uri != NULL && strcmp("GET", request_info->request_method) == 0) { - endpoint_discovery_server_pt server = request_info->user_data; - - const char *uri = request_info->uri; - const size_t path_len = strlen(server->path); - const size_t uri_len = strlen(uri); - - if (strncmp(server->path, uri, strlen(server->path)) == 0) { - // Be lenient when it comes to the trailing slash... - if (path_len == uri_len || (uri_len == (path_len + 1) && uri[path_len] == '/')) { - status = endpointDiscoveryServer_returnAllEndpoints(server, conn); - } else { - const char* endpoint_id = uri + path_len + 1; // right after the slash... - - status = endpointDiscoveryServer_returnEndpoint(server, conn, endpoint_id); - } - } - } - - return status; -} - -#ifndef ANDROID -static celix_status_t endpointDiscoveryServer_getIpAdress(char* interface, char** ip) { - celix_status_t status = CELIX_BUNDLE_EXCEPTION; - - struct ifaddrs *ifaddr, *ifa; - char host[NI_MAXHOST]; - - if (getifaddrs(&ifaddr) != -1) - { - for (ifa = ifaddr; ifa != NULL && status != CELIX_SUCCESS; ifa = ifa->ifa_next) - { - if (ifa->ifa_addr == NULL) - continue; - - if ((getnameinfo(ifa->ifa_addr,sizeof(struct sockaddr_in), host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST) == 0) && (ifa->ifa_addr->sa_family == AF_INET)) { - if (interface == NULL) { - *ip = strdup(host); - status = CELIX_SUCCESS; - } - else if (strcmp(ifa->ifa_name, interface) == 0) { - *ip = strdup(host); - status = CELIX_SUCCESS; - } - } - } - - freeifaddrs(ifaddr); - } - - return status; -} -#endif http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/discovery_common/CMakeLists.txt ---------------------------------------------------------------------- diff --git a/remote_services/discovery_common/CMakeLists.txt b/remote_services/discovery_common/CMakeLists.txt new file mode 100644 index 0000000..9388c90 --- /dev/null +++ b/remote_services/discovery_common/CMakeLists.txt @@ -0,0 +1,33 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + + +find_package(LibXml2 REQUIRED) + +add_library(discovery_common STATIC + src/discovery.c + src/discovery_activator.c + src/endpoint_descriptor_reader.c + src/endpoint_descriptor_writer.c + src/endpoint_discovery_poller.c + src/endpoint_discovery_server.c + src/civetweb.c +) +target_include_directories(discovery_common PUBLIC include) +target_include_directories(discovery_common PRIVATE src ${LIBXML2_INCLUDE_DIR}) +target_link_libraries(discovery_common PRIVATE ${LIBXML2_LIBRARIES} Celix::framework) +target_link_libraries(discovery_common PUBLIC Celix::log_helper Celix::remote_service_admin_api) \ No newline at end of file http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/discovery_common/include/civetweb.h ---------------------------------------------------------------------- diff --git a/remote_services/discovery_common/include/civetweb.h b/remote_services/discovery_common/include/civetweb.h new file mode 100644 index 0000000..61a8e98 --- /dev/null +++ b/remote_services/discovery_common/include/civetweb.h @@ -0,0 +1,657 @@ +/* Copyright (c) 2013-2014 the Civetweb developers + * Copyright (c) 2004-2013 Sergey Lyubka + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef CIVETWEB_HEADER_INCLUDED +#define CIVETWEB_HEADER_INCLUDED + +#ifndef CIVETWEB_VERSION +#define CIVETWEB_VERSION "1.7" +#endif + +#ifndef CIVETWEB_API + #if defined(_WIN32) + #if defined(CIVETWEB_DLL_EXPORTS) + #define CIVETWEB_API __declspec(dllexport) + #elif defined(CIVETWEB_DLL_IMPORTS) + #define CIVETWEB_API __declspec(dllimport) + #else + #define CIVETWEB_API + #endif + #else + #define CIVETWEB_API + #endif +#endif + +#include <stdio.h> +#include <stddef.h> + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +struct mg_context; /* Handle for the HTTP service itself */ +struct mg_connection; /* Handle for the individual connection */ + + +/* This structure contains information about the HTTP request. */ +struct mg_request_info { + const char *request_method; /* "GET", "POST", etc */ + const char *uri; /* URL-decoded URI */ + const char *http_version; /* E.g. "1.0", "1.1" */ + const char *query_string; /* URL part after '?', not including '?', or + NULL */ + const char *remote_user; /* Authenticated user, or NULL if no auth + used */ + char remote_addr[48]; /* Client's IP address as a string. */ + long remote_ip; /* Client's IP address. Deprecated: use remote_addr instead */ + + long long content_length; /* Length (in bytes) of the request body, + can be -1 if no length was given. */ + int remote_port; /* Client's port */ + int is_ssl; /* 1 if SSL-ed, 0 if not */ + void *user_data; /* User data pointer passed to mg_start() */ + void *conn_data; /* Connection-specific user data */ + + int num_headers; /* Number of HTTP headers */ + struct mg_header { + const char *name; /* HTTP header name */ + const char *value; /* HTTP header value */ + } http_headers[64]; /* Maximum 64 headers */ +}; + + +/* This structure needs to be passed to mg_start(), to let civetweb know + which callbacks to invoke. For a detailed description, see + https://github.com/bel2125/civetweb/blob/master/docs/UserManual.md */ +struct mg_callbacks { + /* Called when civetweb has received new HTTP request. + If the callback returns one, it must process the request + by sending valid HTTP headers and a body. Civetweb will not do + any further processing. Otherwise it must return zero. + Note that since V1.7 the "begin_request" function is called + before an authorization check. If an authorization check is + required, use a request_handler instead. + Return value: + 0: civetweb will process the request itself. In this case, + the callback must not send any data to the client. + 1: callback already processed the request. Civetweb will + not send any data after the callback returned. */ + int (*begin_request)(struct mg_connection *); + + /* Called when civetweb has finished processing request. */ + void (*end_request)(const struct mg_connection *, int reply_status_code); + + /* Called when civetweb is about to log a message. If callback returns + non-zero, civetweb does not log anything. */ + int (*log_message)(const struct mg_connection *, const char *message); + + /* Called when civetweb initializes SSL library. + Parameters: + user_data: parameter user_data passed when starting the server. + Return value: + 0: civetweb will set up the SSL certificate. + 1: civetweb assumes the callback already set up the certificate. + -1: initializing ssl fails. */ + int (*init_ssl)(void *ssl_context, void *user_data); + + /* Called when websocket request is received, before websocket handshake. + Return value: + 0: civetweb proceeds with websocket handshake. + 1: connection is closed immediately. */ + int (*websocket_connect)(const struct mg_connection *); + + /* Called when websocket handshake is successfully completed, and + connection is ready for data exchange. */ + void (*websocket_ready)(struct mg_connection *); + + /* Called when data frame has been received from the client. + Parameters: + bits: first byte of the websocket frame, see websocket RFC at + http://tools.ietf.org/html/rfc6455, section 5.2 + data, data_len: payload, with mask (if any) already applied. + Return value: + 1: keep this websocket connection open. + 0: close this websocket connection. */ + int (*websocket_data)(struct mg_connection *, int bits, + char *data, size_t data_len); + + /* Called when civetweb is closing a connection. The per-context mutex is + locked when this is invoked. This is primarily useful for noting when + a websocket is closing and removing it from any application-maintained + list of clients. */ + void (*connection_close)(struct mg_connection *); + + /* Called when civetweb tries to open a file. Used to intercept file open + calls, and serve file data from memory instead. + Parameters: + path: Full path to the file to open. + data_len: Placeholder for the file size, if file is served from + memory. + Return value: + NULL: do not serve file from memory, proceed with normal file open. + non-NULL: pointer to the file contents in memory. data_len must be + initilized with the size of the memory block. */ + const char * (*open_file)(const struct mg_connection *, + const char *path, size_t *data_len); + + /* Called when civetweb is about to serve Lua server page, if + Lua support is enabled. + Parameters: + lua_context: "lua_State *" pointer. */ + void (*init_lua)(struct mg_connection *, void *lua_context); + + /* Called when civetweb has uploaded a file to a temporary directory as a + result of mg_upload() call. + Parameters: + file_name: full path name to the uploaded file. */ + void (*upload)(struct mg_connection *, const char *file_name); + + /* Called when civetweb is about to send HTTP error to the client. + Implementing this callback allows to create custom error pages. + Parameters: + status: HTTP error status code. + Return value: + 1: run civetweb error handler. + 0: callback already handled the error. */ + int (*http_error)(struct mg_connection *, int status); + + /* Called after civetweb context has been created, before requests + are processed. + Parameters: + ctx: context handle */ + void (*init_context)(struct mg_context * ctx); + + /* Called when civetweb context is deleted. + Parameters: + ctx: context handle */ + void (*exit_context)(struct mg_context * ctx); +}; + + +/* Start web server. + + Parameters: + callbacks: mg_callbacks structure with user-defined callbacks. + options: NULL terminated list of option_name, option_value pairs that + specify Civetweb configuration parameters. + + Side-effects: on UNIX, ignores SIGCHLD and SIGPIPE signals. If custom + processing is required for these, signal handlers must be set up + after calling mg_start(). + + + Example: + const char *options[] = { + "document_root", "/var/www", + "listening_ports", "80,443s", + NULL + }; + struct mg_context *ctx = mg_start(&my_func, NULL, options); + + Refer to https://github.com/bel2125/civetweb/blob/master/docs/UserManual.md + for the list of valid option and their possible values. + + Return: + web server context, or NULL on error. */ +CIVETWEB_API struct mg_context *mg_start(const struct mg_callbacks *callbacks, + void *user_data, + const char **configuration_options); + + +/* Stop the web server. + + Must be called last, when an application wants to stop the web server and + release all associated resources. This function blocks until all Civetweb + threads are stopped. Context pointer becomes invalid. */ +CIVETWEB_API void mg_stop(struct mg_context *); + + +/* mg_request_handler + + Called when a new request comes in. This callback is URI based + and configured with mg_set_request_handler(). + + Parameters: + conn: current connection information. + cbdata: the callback data configured with mg_set_request_handler(). + Returns: + 0: the handler could not handle the request, so fall through. + 1: the handler processed the request. */ +typedef int (* mg_request_handler)(struct mg_connection *conn, void *cbdata); + + +/* mg_set_request_handler + + Sets or removes a URI mapping for a request handler. + + URI's are ordered and prefixed URI's are supported. For example, + consider two URIs: /a/b and /a + /a matches /a + /a/b matches /a/b + /a/c matches /a + + Parameters: + ctx: server context + uri: the URI to configure + handler: the callback handler to use when the URI is requested. + If NULL, the URI will be removed. + cbdata: the callback data to give to the handler when it s requested. */ +CIVETWEB_API void mg_set_request_handler(struct mg_context *ctx, const char *uri, mg_request_handler handler, void *cbdata); + + +/* Get the value of particular configuration parameter. + The value returned is read-only. Civetweb does not allow changing + configuration at run time. + If given parameter name is not valid, NULL is returned. For valid + names, return value is guaranteed to be non-NULL. If parameter is not + set, zero-length string is returned. */ +CIVETWEB_API const char *mg_get_option(const struct mg_context *ctx, const char *name); + + +/* Get context from connection. */ +CIVETWEB_API struct mg_context *mg_get_context(struct mg_connection *conn); + + +/* Get user data passed to mg_start from context. */ +CIVETWEB_API void *mg_get_user_data(struct mg_context *ctx); + + +#if defined(MG_LEGACY_INTERFACE) +/* Return array of strings that represent valid configuration options. + For each option, option name and default value is returned, i.e. the + number of entries in the array equals to number_of_options x 2. + Array is NULL terminated. */ +/* Deprecated: Use mg_get_valid_options instead. */ +CIVETWEB_API const char **mg_get_valid_option_names(void); +#endif + + +struct mg_option { + const char * name; + int type; + const char * default_value; +}; + +enum { + CONFIG_TYPE_UNKNOWN = 0x0, + CONFIG_TYPE_NUMBER = 0x1, + CONFIG_TYPE_STRING = 0x2, + CONFIG_TYPE_FILE = 0x3, + CONFIG_TYPE_DIRECTORY = 0x4, + CONFIG_TYPE_BOOLEAN = 0x5, + CONFIG_TYPE_EXT_PATTERN = 0x6 +}; + + +/* Return array of struct mg_option, representing all valid configuration + options of civetweb.c. + The array is terminated by a NULL name option. */ +CIVETWEB_API const struct mg_option *mg_get_valid_options(void); + + +/* Get the list of ports that civetweb is listening on. + size is the size of the ports int array and ssl int array to fill. + It is the caller's responsibility to make sure ports and ssl each + contain at least size int elements worth of memory to write into. + Return value is the number of ports and ssl information filled in. + The value returned is read-only. Civetweb does not allow changing + configuration at run time. */ +CIVETWEB_API size_t mg_get_ports(const struct mg_context *ctx, size_t size, int* ports, int* ssl); + + +/* Add, edit or delete the entry in the passwords file. + + This function allows an application to manipulate .htpasswd files on the + fly by adding, deleting and changing user records. This is one of the + several ways of implementing authentication on the server side. For another, + cookie-based way please refer to the examples/chat in the source tree. + + If password is not NULL, entry is added (or modified if already exists). + If password is NULL, entry is deleted. + + Return: + 1 on success, 0 on error. */ +CIVETWEB_API int mg_modify_passwords_file(const char *passwords_file_name, + const char *domain, + const char *user, + const char *password); + + +/* Return information associated with the request. */ +CIVETWEB_API struct mg_request_info *mg_get_request_info(struct mg_connection *); + + +/* Send data to the client. + Return: + 0 when the connection has been closed + -1 on error + >0 number of bytes written on success */ +CIVETWEB_API int mg_write(struct mg_connection *, const void *buf, size_t len); + + +/* Send data to a websocket client wrapped in a websocket frame. Uses mg_lock + to ensure that the transmission is not interrupted, i.e., when the + application is proactively communicating and responding to a request + simultaneously. + + Send data to a websocket client wrapped in a websocket frame. + This function is available when civetweb is compiled with -DUSE_WEBSOCKET + + Return: + 0 when the connection has been closed + -1 on error + >0 number of bytes written on success */ +CIVETWEB_API int mg_websocket_write(struct mg_connection* conn, int opcode, + const char *data, size_t data_len); + + +/* Blocks until unique access is obtained to this connection. Intended for use + with websockets only. + Invoke this before mg_write or mg_printf when communicating with a + websocket if your code has server-initiated communication as well as + communication in direct response to a message. */ +CIVETWEB_API void mg_lock_connection(struct mg_connection* conn); +CIVETWEB_API void mg_unlock_connection(struct mg_connection* conn); + +#if defined(MG_LEGACY_INTERFACE) +#define mg_lock mg_lock_connection +#define mg_unlock mg_unlock_connection +#endif + +/* Lock server context. This lock may be used to protect ressources + that are shared between different connection/worker threads. */ +CIVETWEB_API void mg_lock_context(struct mg_context* ctx); +CIVETWEB_API void mg_unlock_context(struct mg_context* ctx); + + +/* Opcodes, from http://tools.ietf.org/html/rfc6455 */ +enum { + WEBSOCKET_OPCODE_CONTINUATION = 0x0, + WEBSOCKET_OPCODE_TEXT = 0x1, + WEBSOCKET_OPCODE_BINARY = 0x2, + WEBSOCKET_OPCODE_CONNECTION_CLOSE = 0x8, + WEBSOCKET_OPCODE_PING = 0x9, + WEBSOCKET_OPCODE_PONG = 0xa +}; + + +/* Macros for enabling compiler-specific checks forprintf-like arguments. */ +#undef PRINTF_FORMAT_STRING +#if defined(_MSC_VER) && _MSC_VER >= 1400 +#include <sal.h> +#if defined(_MSC_VER) && _MSC_VER > 1400 +#define PRINTF_FORMAT_STRING(s) _Printf_format_string_ s +#else +#define PRINTF_FORMAT_STRING(s) __format_string s +#endif +#else +#define PRINTF_FORMAT_STRING(s) s +#endif + +#ifdef __GNUC__ +#define PRINTF_ARGS(x, y) __attribute__((format(printf, x, y))) +#else +#define PRINTF_ARGS(x, y) +#endif + +/* Send data to the client usingprintf() semantics. + Works exactly like mg_write(), but allows to do message formatting. */ +CIVETWEB_API int mg_printf(struct mg_connection *, + PRINTF_FORMAT_STRING(const char *fmt), ...) PRINTF_ARGS(2, 3); + + +/* Send contents of the entire file together with HTTP headers. */ +CIVETWEB_API void mg_send_file(struct mg_connection *conn, const char *path); + + +/* Read data from the remote end, return number of bytes read. + Return: + 0 connection has been closed by peer. No more data could be read. + < 0 read error. No more data could be read from the connection. + > 0 number of bytes read into the buffer. */ +CIVETWEB_API int mg_read(struct mg_connection *, void *buf, size_t len); + + +/* Get the value of particular HTTP header. + + This is a helper function. It traverses request_info->http_headers array, + and if the header is present in the array, returns its value. If it is + not present, NULL is returned. */ +CIVETWEB_API const char *mg_get_header(const struct mg_connection *, const char *name); + + +/* Get a value of particular form variable. + + Parameters: + data: pointer to form-uri-encoded buffer. This could be either POST data, + or request_info.query_string. + data_len: length of the encoded data. + var_name: variable name to decode from the buffer + dst: destination buffer for the decoded variable + dst_len: length of the destination buffer + + Return: + On success, length of the decoded variable. + On error: + -1 (variable not found). + -2 (destination buffer is NULL, zero length or too small to hold the + decoded variable). + + Destination buffer is guaranteed to be '\0' - terminated if it is not + NULL or zero length. */ +CIVETWEB_API int mg_get_var(const char *data, size_t data_len, + const char *var_name, char *dst, size_t dst_len); + + +/* Get a value of particular form variable. + + Parameters: + data: pointer to form-uri-encoded buffer. This could be either POST data, + or request_info.query_string. + data_len: length of the encoded data. + var_name: variable name to decode from the buffer + dst: destination buffer for the decoded variable + dst_len: length of the destination buffer + occurrence: which occurrence of the variable, 0 is the first, 1 the + second... + this makes it possible to parse a query like + b=x&a=y&a=z which will have occurrence values b:0, a:0 and a:1 + + Return: + On success, length of the decoded variable. + On error: + -1 (variable not found). + -2 (destination buffer is NULL, zero length or too small to hold the + decoded variable). + + Destination buffer is guaranteed to be '\0' - terminated if it is not + NULL or zero length. */ +CIVETWEB_API int mg_get_var2(const char *data, size_t data_len, + const char *var_name, char *dst, size_t dst_len, size_t occurrence); + + +/* Fetch value of certain cookie variable into the destination buffer. + + Destination buffer is guaranteed to be '\0' - terminated. In case of + failure, dst[0] == '\0'. Note that RFC allows many occurrences of the same + parameter. This function returns only first occurrence. + + Return: + On success, value length. + On error: + -1 (either "Cookie:" header is not present at all or the requested + parameter is not found). + -2 (destination buffer is NULL, zero length or too small to hold the + value). */ +CIVETWEB_API int mg_get_cookie(const char *cookie, const char *var_name, + char *buf, size_t buf_len); + + +/* Download data from the remote web server. + host: host name to connect to, e.g. "foo.com", or "10.12.40.1". + port: port number, e.g. 80. + use_ssl: wether to use SSL connection. + error_buffer, error_buffer_size: error message placeholder. + request_fmt,...: HTTP request. + Return: + On success, valid pointer to the new connection, suitable for mg_read(). + On error, NULL. error_buffer contains error message. + Example: + char ebuf[100]; + struct mg_connection *conn; + conn = mg_download("google.com", 80, 0, ebuf, sizeof(ebuf), + "%s", "GET / HTTP/1.0\r\nHost: google.com\r\n\r\n"); + */ +CIVETWEB_API struct mg_connection *mg_download(const char *host, int port, int use_ssl, + char *error_buffer, size_t error_buffer_size, + PRINTF_FORMAT_STRING(const char *request_fmt), + ...) PRINTF_ARGS(6, 7); + + +/* Close the connection opened by mg_download(). */ +CIVETWEB_API void mg_close_connection(struct mg_connection *conn); + + +/* File upload functionality. Each uploaded file gets saved into a temporary + file and MG_UPLOAD event is sent. + Return number of uploaded files. */ +CIVETWEB_API int mg_upload(struct mg_connection *conn, const char *destination_dir); + + +/* Convenience function -- create detached thread. + Return: 0 on success, non-0 on error. */ +typedef void * (*mg_thread_func_t)(void *); +CIVETWEB_API int mg_start_thread(mg_thread_func_t f, void *p); + + +/* Return builtin mime type for the given file name. + For unrecognized extensions, "text/plain" is returned. */ +CIVETWEB_API const char *mg_get_builtin_mime_type(const char *file_name); + + +/* Return Civetweb version. */ +CIVETWEB_API const char *mg_version(void); + + +/* URL-decode input buffer into destination buffer. + 0-terminate the destination buffer. + form-url-encoded data differs from URI encoding in a way that it + uses '+' as character for space, see RFC 1866 section 8.2.1 + http://ftp.ics.uci.edu/pub/ietf/html/rfc1866.txt + Return: length of the decoded data, or -1 if dst buffer is too small. */ +CIVETWEB_API int mg_url_decode(const char *src, int src_len, char *dst, + int dst_len, int is_form_url_encoded); + + +/* URL-encode input buffer into destination buffer. + returns the length of the resulting buffer or -1 + is the buffer is too small. */ +CIVETWEB_API int mg_url_encode(const char *src, char *dst, size_t dst_len); + + +/* MD5 hash given strings. + Buffer 'buf' must be 33 bytes long. Varargs is a NULL terminated list of + ASCIIz strings. When function returns, buf will contain human-readable + MD5 hash. Example: + char buf[33]; + mg_md5(buf, "aa", "bb", NULL); */ +CIVETWEB_API char *mg_md5(char buf[33], ...); + + +/* Print error message to the opened error log stream. + This utilizes the provided logging configuration. + conn: connection + fmt: format string without the line return + ...: variable argument list + Example: + mg_cry(conn,"i like %s", "logging"); */ +CIVETWEB_API void mg_cry(struct mg_connection *conn, + PRINTF_FORMAT_STRING(const char *fmt), ...) PRINTF_ARGS(2, 3); + + +/* utility method to compare two buffers, case incensitive. */ +CIVETWEB_API int mg_strncasecmp(const char *s1, const char *s2, size_t len); + +/* Connect to a websocket as a client + Parameters: + host: host to connect to, i.e. "echo.websocket.org" or "192.168.1.1" or "localhost" + port: server port + use_ssl: make a secure connection to server + error_buffer, error_buffer_size: buffer for an error message + path: server path you are trying to connect to, i.e. if connection to localhost/app, path should be "/app" + origin: value of the Origin HTTP header + data_func: callback that should be used when data is received from the server + user_data: user supplied argument + + Return: + On success, valid mg_connection object. + On error, NULL. Se error_buffer for details. +*/ + +typedef int (*websocket_data_func)(struct mg_connection *, int bits, + char *data, size_t data_len); + +typedef void (*websocket_close_func)(struct mg_connection *); + +CIVETWEB_API struct mg_connection *mg_connect_websocket_client(const char *host, int port, int use_ssl, + char *error_buffer, size_t error_buffer_size, + const char *path, const char *origin, + websocket_data_func data_func, websocket_close_func close_func, + void * user_data); + +/* Connect to a TCP server as a client (can be used to connect to a HTTP server) + Parameters: + host: host to connect to, i.e. "www.wikipedia.org" or "192.168.1.1" or "localhost" + port: server port + use_ssl: make a secure connection to server + error_buffer, error_buffer_size: buffer for an error message + + Return: + On success, valid mg_connection object. + On error, NULL. Se error_buffer for details. +*/ +CIVETWEB_API struct mg_connection *mg_connect_client(const char *host, int port, int use_ssl, + char *error_buffer, size_t error_buffer_size); + + +enum { + TIMEOUT_INFINITE = -1 +}; + +/* Wait for a response from the server + Parameters: + conn: connection + ebuf, ebuf_len: error message placeholder. + timeout: time to wait for a response in milliseconds (if < 0 then wait forever) + + Return: + On success, >= 0 + On error/timeout, < 0 +*/ +CIVETWEB_API int mg_get_response(struct mg_connection *conn, char *ebuf, size_t ebuf_len, int timeout); + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* CIVETWEB_HEADER_INCLUDED */ http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/discovery_common/include/discovery.h ---------------------------------------------------------------------- diff --git a/remote_services/discovery_common/include/discovery.h b/remote_services/discovery_common/include/discovery.h new file mode 100644 index 0000000..ee79caf --- /dev/null +++ b/remote_services/discovery_common/include/discovery.h @@ -0,0 +1,67 @@ +/** + *Licensed to the Apache Software Foundation (ASF) under one + *or more contributor license agreements. See the NOTICE file + *distributed with this work for additional information + *regarding copyright ownership. The ASF licenses this file + *to you under the Apache License, Version 2.0 (the + *"License"); you may not use this file except in compliance + *with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + *Unless required by applicable law or agreed to in writing, + *software distributed under the License is distributed on an + *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + *specific language governing permissions and limitations + *under the License. + */ +/* + * discovery.h + * + * \date Sep 29, 2011 + * \author <a href="mailto:[email protected]">Apache Celix Project Team</a> + * \copyright Apache License, Version 2.0 + */ + +#ifndef DISCOVERY_H_ +#define DISCOVERY_H_ + +#include "bundle_context.h" +#include "service_reference.h" + +#include "endpoint_description.h" +#include "endpoint_listener.h" + +#define DISCOVERY_SERVER_INTERFACE "DISCOVERY_CFG_SERVER_INTERFACE" +#define DISCOVERY_SERVER_IP "DISCOVERY_CFG_SERVER_IP" +#define DISCOVERY_SERVER_PORT "DISCOVERY_CFG_SERVER_PORT" +#define DISCOVERY_SERVER_PATH "DISCOVERY_CFG_SERVER_PATH" +#define DISCOVERY_POLL_ENDPOINTS "DISCOVERY_CFG_POLL_ENDPOINTS" +#define DISCOVERY_SERVER_MAX_EP "DISCOVERY_CFG_SERVER_MAX_EP" + +typedef struct discovery *discovery_pt; + + +/* those one could be put into a general discovery.h - file */ +celix_status_t discovery_create(bundle_context_pt context, discovery_pt *discovery); +celix_status_t discovery_destroy(discovery_pt discovery); + +celix_status_t discovery_start(discovery_pt discovery); +celix_status_t discovery_stop(discovery_pt discovery); + +celix_status_t discovery_endpointAdded(void *handle, endpoint_description_pt endpoint, char *machtedFilter); +celix_status_t discovery_endpointRemoved(void *handle, endpoint_description_pt endpoint, char *machtedFilter); + +celix_status_t discovery_endpointListenerAdding(void * handle, service_reference_pt reference, void **service); +celix_status_t discovery_endpointListenerAdded(void * handle, service_reference_pt reference, void * service); +celix_status_t discovery_endpointListenerModified(void * handle, service_reference_pt reference, void * service); +celix_status_t discovery_endpointListenerRemoved(void * handle, service_reference_pt reference, void * service); + +celix_status_t discovery_informEndpointListeners(discovery_pt discovery, endpoint_description_pt endpoint, bool endpointAdded); +celix_status_t discovery_updateEndpointListener(discovery_pt discovery, service_reference_pt reference, endpoint_listener_pt service); + +celix_status_t discovery_addDiscoveredEndpoint(discovery_pt discovery, endpoint_description_pt endpoint); +celix_status_t discovery_removeDiscoveredEndpoint(discovery_pt discovery, endpoint_description_pt endpoint); + +#endif /* DISCOVERY_H_ */
