You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@celix.apache.org by ab...@apache.org on 2014/08/13 10:46:10 UTC

svn commit: r1617689 [2/2] - in /celix/trunk: framework/private/src/ framework/public/include/ remote_services/ remote_services/calculator_endpoint/ remote_services/calculator_endpoint/private/src/ remote_services/calculator_proxy/ remote_services/calc...

Modified: celix/trunk/remote_services/discovery_configured/private/src/endpoint_descriptor_reader.c
URL: http://svn.apache.org/viewvc/celix/trunk/remote_services/discovery_configured/private/src/endpoint_descriptor_reader.c?rev=1617689&r1=1617688&r2=1617689&view=diff
==============================================================================
--- celix/trunk/remote_services/discovery_configured/private/src/endpoint_descriptor_reader.c (original)
+++ celix/trunk/remote_services/discovery_configured/private/src/endpoint_descriptor_reader.c Wed Aug 13 08:46:09 2014
@@ -25,10 +25,14 @@
  */
 
 #include <stdbool.h>
-#include <libxml/xmlreader.h>
 #include <string.h>
+#include <libxml/xmlreader.h>
+
+#include "constants.h"
+#include "remote_constants.h"
 
 #include "endpoint_description.h"
+#include "endpoint_descriptor_common.h"
 #include "endpoint_descriptor_reader.h"
 #include "properties.h"
 #include "utils.h"
@@ -37,21 +41,6 @@ struct endpoint_descriptor_reader {
     xmlTextReaderPtr reader;
 };
 
-typedef enum {
-    VALUE_TYPE_STRING,
-    VALUE_TYPE_LONG,
-    VALUE_TYPE_DOUBLE,
-    VALUE_TYPE_FLOAT,
-    VALUE_TYPE_INTEGER,
-    VALUE_TYPE_BYTE,
-    VALUE_TYPE_CHAR,
-    VALUE_TYPE_BOOLEAN,
-    VALUE_TYPE_SHORT,
-} valueType;
-
-
-static valueType getValueType(char *name);
-
 celix_status_t endpointDescriptorReader_create(endpoint_descriptor_reader_pt *reader) {
     celix_status_t status = CELIX_SUCCESS;
 
@@ -73,6 +62,28 @@ celix_status_t endpointDescriptorReader_
     return status;
 }
 
+void endpointDescriptorReader_addSingleValuedProperty(properties_pt properties, const xmlChar* name, const xmlChar* value) {
+	properties_set(properties, strdup((char *) name), strdup((char *) value));
+}
+
+void endpointDescriptorReader_addMultiValuedProperty(properties_pt properties, const xmlChar* name, array_list_pt values) {
+	char *value = malloc(256);
+	if (value) {
+		int i, size = arrayList_size(values);
+		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, strdup((char *) name), strdup(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;
 
@@ -88,26 +99,32 @@ celix_status_t endpointDescriptorReader_
         bool inValue = false;
 
         const xmlChar *propertyName = NULL;
-        const xmlChar *propertyType = NULL;
         const xmlChar *propertyValue = NULL;
-        const xmlChar *value = NULL;
+        valueType propertyType = VALUE_TYPE_STRING;
         xmlChar *valueBuffer = xmlMalloc(256);
         valueBuffer[0] = '\0';
         unsigned int currentSize = 255;
 
-//        array_list_pt propertyValues = NULL;
-//        arrayList_create(&propertyValues);
+        array_list_pt propertyValues = NULL;
+        arrayList_create(&propertyValues);
 
         array_list_pt endpointDescriptions = NULL;
-        arrayList_create(&endpointDescriptions);
+        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 == 1) {
+        while (read == XML_TEXTREADER_MODE_INTERACTIVE) {
             int type = xmlTextReaderNodeType(reader->reader);
 
-            if (type == 1) {
+            if (type == XML_READER_TYPE_ELEMENT) {
                 const xmlChar *localname = xmlTextReaderConstLocalName(reader->reader);
 
                 if (inXml) {
@@ -129,113 +146,92 @@ celix_status_t endpointDescriptorReader_
                     }
 
                     valueBuffer = xmlStrcat(valueBuffer, BAD_CAST ">");
-//                    read = xmlTextReaderRead(reader);
-//                    continue;
-                } else if (xmlStrcmp(localname, BAD_CAST "endpoint-description") == 0) {
+                } else if (xmlStrcmp(localname, ENDPOINT_DESCRIPTION) == 0) {
                     endpointProperties = properties_create();
-                } else if (xmlStrcmp(localname, BAD_CAST "property") == 0) {
+                } else if (xmlStrcmp(localname, PROPERTY) == 0) {
                     inProperty = true;
-                    propertyName = xmlTextReaderGetAttribute(reader->reader, BAD_CAST "name");
-//                    propertyType = getValueType((const char *) xmlTextReaderGetAttribute(reader, "value-type"));
-//                    propertyType = xmlTextReaderGetAttribute(reader->reader, BAD_CAST "value-type");
-                    propertyValue = xmlTextReaderGetAttribute(reader->reader, BAD_CAST "value");
-//                    arrayList_clear(propertyValues);
+
+                    propertyName = xmlTextReaderGetAttribute(reader->reader, NAME);
+                    propertyValue = xmlTextReaderGetAttribute(reader->reader, VALUE);
+                    xmlChar* type = xmlTextReaderGetAttribute(reader->reader, VALUE_TYPE);
+                    propertyType = valueTypeFromString((char*) type);
+                    arrayList_clear(propertyValues);
 
                     if (xmlTextReaderIsEmptyElement(reader->reader)) {
                         inProperty = false;
 
                         if (propertyValue != NULL) {
-                            printf("Only string support\n");
-    //                        m_endpointProperties.put(m_propertyName, m_propertyType.parse(m_propertyValue));
-                            properties_set(endpointProperties, (char *) propertyName, (char *) propertyValue);
+                        	if (propertyType != VALUE_TYPE_STRING && strcmp(OSGI_RSA_ENDPOINT_SERVICE_ID, (char*) propertyName)) {
+                        		printf("ENDPOINT_DESCRIPTOR_READER: Only single-valued string supported for %s\n", propertyName);
+                        	}
+                        	endpointDescriptorReader_addSingleValuedProperty(endpointProperties, propertyName, propertyValue);
                         }
 
-                        free((void *) propertyName);
-                        free((void *) propertyValue);
+                        xmlFree((void *) propertyName);
+                        xmlFree((void *) propertyValue);
+                        xmlFree((void *) type);
                     }
-
-                    //                    read = xmlTextReaderRead(reader);
-//                    continue;
                 } else {
-                    valueBuffer[0] = '\0';
-                    value = NULL;
-                    inArray |= inProperty && xmlStrcmp(localname, BAD_CAST "array") == 0;
-                    inList |= inProperty && xmlStrcmp(localname, BAD_CAST "list") == 0;
-                    inSet |= inProperty && xmlStrcmp(localname, BAD_CAST "set") == 0;
-                    inXml |= inProperty && xmlStrcmp(localname, BAD_CAST "xml") == 0;
-                    inValue |= inProperty && xmlStrcmp(localname, BAD_CAST "value") == 0;
-                }
-            }
-
-            if (type == 15) {
-                const xmlChar *localname = xmlTextReaderConstLocalName(reader->reader);
+                    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, BAD_CAST "xml") != 0)  {
-                        xmlStrcmp(valueBuffer, BAD_CAST "</");
-                        xmlStrcmp(valueBuffer, localname);
-                        xmlStrcmp(valueBuffer, BAD_CAST ">");
+                    if (xmlStrcmp(localname, XML) != 0)  {
+                    	valueBuffer = xmlStrcat(valueBuffer, BAD_CAST "</");
+                    	valueBuffer = xmlStrcat(valueBuffer, localname);
+                    	valueBuffer = xmlStrcat(valueBuffer, BAD_CAST ">");
                     }
                     else {
                         inXml = false;
                     }
-//                    read = xmlTextReaderRead(reader);
-//                    continue;
-                } else if (xmlStrcmp(localname, BAD_CAST "endpoint-description") == 0) {
+                } else if (xmlStrcmp(localname, ENDPOINT_DESCRIPTION) == 0) {
                     endpoint_description_pt endpointDescription = NULL;
+                    // Completely parsed endpoint description, add it to our list of results...
                     endpointDescription_create(endpointProperties, &endpointDescription);
                     arrayList_add(endpointDescriptions, endpointDescription);
-//                    endpointProperties = properties_create();
-//                    hashMap_clear(endpointProperties, false, false);
-//                    read = xmlTextReaderRead(reader);
-//                    continue;
-                } else if (xmlStrcmp(localname, BAD_CAST "property") == 0) {
+
+                    endpointProperties = properties_create();
+                } else if (xmlStrcmp(localname, PROPERTY) == 0) {
                     inProperty = false;
 
-                    if (inArray) {
-                        printf("No array support\n");
-//                        m_endpointProperties.put(m_propertyName, getPropertyValuesArray());
-                    }
-                    else if (inList) {
-                        printf("No list support\n");
-//                        m_endpointProperties.put(m_propertyName, getPropertyValuesList());
-                    }
-                    else if (inSet) {
-                        printf("No set support\n");
-//                        m_endpointProperties.put(m_propertyName, getPropertyValuesSet());
+                    if (inArray || inList || inSet) {
+						endpointDescriptorReader_addMultiValuedProperty(endpointProperties, propertyName, propertyValues);
                     }
                     else if (propertyValue != NULL) {
-                        printf("Only string support\n");
-//                        m_endpointProperties.put(m_propertyName, m_propertyType.parse(m_propertyValue));
-                        properties_set(endpointProperties, (char *) propertyName, (char *) propertyValue);
+                    	if (propertyType != VALUE_TYPE_STRING) {
+                    		printf("ENDPOINT_DESCRIPTOR_READER: Only string support for %s\n", propertyName);
+                    	}
+                    	endpointDescriptorReader_addSingleValuedProperty(endpointProperties, propertyName, propertyValue);
 
-                        free((void *) propertyValue);
+                        xmlFree((void *) propertyValue);
                     }
                     else {
-                        properties_set(endpointProperties, (char *) propertyName, (char *) valueBuffer);
+                    	endpointDescriptorReader_addSingleValuedProperty(endpointProperties, propertyName, valueBuffer);
                     }
 
-                    free((void *) propertyName);
+                    xmlFree((void *) propertyName);
+                    arrayList_clear(propertyValues);
 
+                    propertyType = VALUE_TYPE_STRING;
                     inArray = false;
                     inList = false;
                     inSet = false;
                     inXml = false;
-//                    read = xmlTextReaderRead(reader);
-//                    continue;
-                } else if (xmlStrcmp(localname, BAD_CAST "value") == 0) {
-//                    m_propertyValues.add(m_propertyType.parse(m_valueBuffer.toString()));
-//                    arrayList_add(propertyValues, valueBuffer);
+                } else if (xmlStrcmp(localname, VALUE) == 0) {
+                    arrayList_add(propertyValues, strdup((char*) valueBuffer));
+                    valueBuffer[0] = 0;
                     inValue = false;
-//                    read = xmlTextReaderRead(reader);
-//                    continue;
                 }
-            }
-
-            if (type == 3) {
+            } else if (type == XML_READER_TYPE_TEXT) {
                 if (inValue || inXml) {
                     const xmlChar *value = xmlTextReaderValue(reader->reader);
-                    printf("Value: %s\n", value);
                     valueBuffer = xmlStrcat(valueBuffer, value);
                     xmlFree((void *)value);
                 }
@@ -243,61 +239,61 @@ celix_status_t endpointDescriptorReader_
 
             read = xmlTextReaderRead(reader->reader);
         }
-        *endpoints = endpointDescriptions;
 
-//        arrayList_destroy(propertyValues);
-        free(valueBuffer);
+        arrayList_destroy(propertyValues);
+        xmlFree(valueBuffer);
+
         xmlFreeTextReader(reader->reader);
     }
 
     return status;
 }
 
-//static valueType getValueType(char *name) {
-//    if (name == NULL || strcmp(name, "") == 0) {
-//        return VALUE_TYPE_STRING;
-//    }
-//    if (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, "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;
-//    }
-//}
+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;
-    endpointDescriptorReader_create(&reader);
 
     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=\"http://ws.acme.com:9000/hello\" />"
-        "<property name=\"objectClass\" value=\"com.acme.Foo\" />"
+        "<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\">"
@@ -307,44 +303,67 @@ int main() {
             "</xml>"
         "</property>"
     "</endpoint-description>"
-            "<endpoint-description>"
-                    "<property name=\"service.intents\">"
-                        "<list>"
-                            "<value>SOAP</value>"
-                            "<value>HTTP</value>"
-                        "</list>"
-                    "</property>"
-                    "<property name=\"endpoint.id\" value=\"http://ws.acme.com:9000/goodbye\" />"
-                    "<property name=\"objectClass\" value=\"com.acme.Doo\" />"
-                    "<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_parseDocument(reader, doc, &list);
-
-    int i;
-    for (i = 0; i < arrayList_size(list); i++) {
-        endpoint_description_pt edp = arrayList_get(list, i);
-        printf("Service: %s\n", edp->service);
-        printf("Id: %s\n", edp->id);
-
-        endpointDescription_destroy(edp);
-    }
-
-    if (list != NULL) {
-        arrayList_destroy(list);
-    }
+		"<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: %ld\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);
+	endpointDescriptorReader_destroy(reader);
 
     return 0;
 }
+#endif

Modified: celix/trunk/remote_services/discovery_configured/private/src/endpoint_descriptor_writer.c
URL: http://svn.apache.org/viewvc/celix/trunk/remote_services/discovery_configured/private/src/endpoint_descriptor_writer.c?rev=1617689&r1=1617688&r2=1617689&view=diff
==============================================================================
--- celix/trunk/remote_services/discovery_configured/private/src/endpoint_descriptor_writer.c (original)
+++ celix/trunk/remote_services/discovery_configured/private/src/endpoint_descriptor_writer.c Wed Aug 13 08:46:09 2014
@@ -25,9 +25,14 @@
  */
 #include <stdlib.h>
 #include <stdio.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 {
@@ -73,7 +78,7 @@ celix_status_t endpointDescriptorWriter_
     if (rc < 0) {
         status = CELIX_BUNDLE_EXCEPTION;
     } else {
-        rc = xmlTextWriterStartElementNS(writer->writer, NULL, BAD_CAST "endpoint-descriptions", BAD_CAST "http://www.osgi.org/xmlns/rsa/v1.0.0");
+        rc = xmlTextWriterStartElementNS(writer->writer, NULL, ENDPOINT_DESCRIPTIONS, XMLNS);
         if (rc < 0) {
             status = CELIX_BUNDLE_EXCEPTION;
         } else {
@@ -101,20 +106,58 @@ celix_status_t endpointDescriptorWriter_
     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, BAD_CAST "endpoint-description");
+        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);
-            xmlTextWriterStartElement(writer->writer, BAD_CAST "property");
-            xmlTextWriterWriteAttribute(writer->writer, BAD_CAST "name", hashMapEntry_getKey(entry));
-            xmlTextWriterWriteAttribute(writer->writer, BAD_CAST "value", hashMapEntry_getValue(entry));
+
+            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);
@@ -126,6 +169,32 @@ static celix_status_t endpointDescriptor
 }
 
 
+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);
@@ -133,13 +202,19 @@ int main() {
     arrayList_create(&list);
 
     properties_pt props = properties_create();
-    properties_set(props, "a", "b");
+    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, "a", "b");
+    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);
@@ -154,3 +229,4 @@ int main() {
 
     printf("%s\n", buffer);
 }
+#endif

Modified: celix/trunk/remote_services/discovery_configured/private/src/endpoint_discovery_poller.c
URL: http://svn.apache.org/viewvc/celix/trunk/remote_services/discovery_configured/private/src/endpoint_discovery_poller.c?rev=1617689&r1=1617688&r2=1617689&view=diff
==============================================================================
--- celix/trunk/remote_services/discovery_configured/private/src/endpoint_discovery_poller.c (original)
+++ celix/trunk/remote_services/discovery_configured/private/src/endpoint_discovery_poller.c Wed Aug 13 08:46:09 2014
@@ -1,155 +1,255 @@
 /**
- *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
+ * 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
+ *   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.
+ * 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:celix-dev@incubator.apache.org">Apache Celix Project Team</a>
- *  \copyright  Apache License, Version 2.0
+ * \date       3 Jul 2014
+ * \author     <a href="mailto:celix-dev@incubator.apache.org">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 "endpoint_discovery_poller.h"
 #include "hash_map.h"
 #include "array_list.h"
 #include "celix_threads.h"
 #include "utils.h"
+
 #include "endpoint_listener.h"
+#include "endpoint_discovery_poller.h"
+#include "endpoint_descriptor_reader.h"
 
 struct endpoint_discovery_poller {
     discovery_pt discovery;
     hash_map_pt entries;
+
     celix_thread_mutex_t pollerLock;
     celix_thread_t pollerThread;
+
+    unsigned int poll_interval;
+    volatile bool running;
 };
 
+#define DISCOVERY_POLL_ENDPOINTS "DISCOVERY_CFG_POLL_ENDPOINTS"
+#define DEFAULT_POLL_ENDPOINTS "http://localhost:9999/org.apache.celix.discovery.configured"
+
+#define DISCOVERY_POLL_INTERVAL "DISCOVERY_CFG_POLL_INTERVAL"
+#define DEFAULT_POLL_INTERVAL "10"
+
 static void *endpointDiscoveryPoller_poll(void *data);
 static celix_status_t endpointDiscoveryPoller_getEndpoints(endpoint_discovery_poller_pt poller, char *url, array_list_pt *updatedEndpoints);
-static size_t endpointDiscoveryPoller_writeMemory(void *contents, size_t size, size_t nmemb, void *memoryPtr);
 static celix_status_t endpointDiscoveryPoller_endpointDescriptionEquals(void *endpointPtr, void *comparePtr, bool *equals);
 
-celix_status_t endpointDiscoveryPoller_create(discovery_pt discovery, endpoint_discovery_poller_pt *poller) {
+/**
+ * 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 = CELIX_SUCCESS;
-    *poller = malloc(sizeof(**poller));
+
+    *poller = malloc(sizeof(struct endpoint_discovery_poller));
     if (!poller) {
-        status = CELIX_ENOMEM;
-    } else {
-        (*poller)->discovery = discovery;
-        (*poller)->entries = hashMap_create(utils_stringHash, NULL, utils_stringEquals, NULL);
-        status = celixThreadMutex_create(&(*poller)->pollerLock, NULL);
-        if (status != CELIX_SUCCESS) {
-            status = CELIX_ILLEGAL_STATE;
-        } else {
-            celixThread_create(&(*poller)->pollerThread, NULL, endpointDiscoveryPoller_poll, *poller);
-        }
+        return CELIX_ENOMEM;
+    }
+
+	status = celixThreadMutex_create(&(*poller)->pollerLock, NULL);
+	if (status != CELIX_SUCCESS) {
+		return status;
+	}
+
+	char* interval = NULL;
+	status = bundleContext_getProperty(context, DISCOVERY_POLL_INTERVAL, &interval);
+	if (!interval) {
+		interval = DEFAULT_POLL_INTERVAL;
+	}
+
+	char* endpoints = NULL;
+	status = bundleContext_getProperty(context, DISCOVERY_POLL_ENDPOINTS, &endpoints);
+	if (!endpoints) {
+		endpoints = DEFAULT_POLL_ENDPOINTS;
+	}
+	// we're going to mutate the string with strtok, so create a copy...
+	endpoints = strdup(endpoints);
+
+	(*poller)->poll_interval = atoi(interval);
+	(*poller)->discovery = discovery;
+	(*poller)->entries = hashMap_create(utils_stringHash, NULL, utils_stringEquals, NULL);
+
+	const char* sep = ",";
+	char* tok = strtok(endpoints, sep);
+	while (tok) {
+		endpointDiscoveryPoller_addDiscoveryEndpoint(*poller, strdup(utils_stringTrim(tok)));
+		tok = strtok(NULL, sep);
+	}
+	// Clean up after ourselves...
+	free(endpoints);
+
+    status = celixThreadMutex_lock(&(*poller)->pollerLock);
+    if (status != CELIX_SUCCESS) {
+        return CELIX_BUNDLE_EXCEPTION;
     }
+
+	status = celixThread_create(&(*poller)->pollerThread, NULL, endpointDiscoveryPoller_poll, *poller);
+	if (status != CELIX_SUCCESS) {
+		return status;
+	}
+
+	(*poller)->running = true;
+
+    status = celixThreadMutex_unlock(&(*poller)->pollerLock);
+
     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 = CELIX_SUCCESS;
+
+    (*poller)->running = false;
+
+    celixThread_join((*poller)->pollerThread, NULL);
+
+    status = celixThreadMutex_lock(&(*poller)->pollerLock);
+    if (status != CELIX_SUCCESS) {
+        return CELIX_BUNDLE_EXCEPTION;
+    }
+
+	hashMap_destroy((*poller)->entries, true, false);
+
+    status = celixThreadMutex_unlock(&(*poller)->pollerLock);
+
+    free(*poller);
+
+	return status;
+}
+
+/**
+ * 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 = CELIX_SUCCESS;
 
     status = celixThreadMutex_lock(&(poller)->pollerLock);
-    if (status != 0) {
-        status = CELIX_BUNDLE_EXCEPTION;
-    } else {
-        array_list_pt endpoints;
-        status = arrayList_createWithEquals(endpointDiscoveryPoller_endpointDescriptionEquals, &endpoints);
-        if (status == CELIX_SUCCESS) {
-            hashMap_put(poller->entries, url, endpoints);
-        }
-        status = celixThreadMutex_unlock(&poller->pollerLock);
-        if (status != 0) {
-            status = CELIX_BUNDLE_EXCEPTION;
-        }
+    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) {
+			hashMap_put(poller->entries, 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;
 
     status = celixThreadMutex_lock(&poller->pollerLock);
-    if (status != 0) {
-        status = CELIX_BUNDLE_EXCEPTION;
-    } else {
-        array_list_pt entries = hashMap_remove(poller->entries, url);
-        int i;
-        for (i = 0; i < arrayList_size(entries); i++) {
-            endpoint_description_pt endpoint = arrayList_get(entries, i);
-            // discovery_removeDiscoveredEndpoint(poller->discovery, endpoint);
-        }
-        arrayList_destroy(entries);
-
-        status = celixThreadMutex_unlock(&poller->pollerLock);
-        if (status != 0) {
-            status = CELIX_BUNDLE_EXCEPTION;
-        }
+    if (status != CELIX_SUCCESS) {
+        return CELIX_BUNDLE_EXCEPTION;
     }
 
+	array_list_pt entries = hashMap_remove(poller->entries, url);
+	for (int i = 0; i < arrayList_size(entries); i++) {
+		endpoint_description_pt endpoint = arrayList_get(entries, i);
+
+		discovery_removeDiscoveredEndpoint(poller->discovery, endpoint);
+	}
+	arrayList_destroy(entries);
+
+	status = celixThreadMutex_unlock(&poller->pollerLock);
+
     return status;
 }
 
 static void *endpointDiscoveryPoller_poll(void *data) {
     endpoint_discovery_poller_pt poller = (endpoint_discovery_poller_pt) data;
+    discovery_pt discovery = poller->discovery;
 
-    celix_status_t status = celixThreadMutex_lock(&poller->pollerLock);
-    if (status != 0) {
-        status = CELIX_BUNDLE_EXCEPTION;
-    } else {
-        hash_map_iterator_pt iterator = hashMapIterator_create(poller->entries);
-        while (hashMapIterator_hasNext(iterator)) {
-            array_list_pt currentEndpoints = hashMapIterator_nextValue(iterator);
-            char *url = hashMapIterator_nextKey(iterator);
-
-            array_list_pt updatedEndpoints = NULL;
-            status = endpointDiscoveryPoller_getEndpoints(poller, url, &updatedEndpoints);
-            if (status == CELIX_SUCCESS) {
-                int i;
-                for (i = 0; i < arrayList_size(currentEndpoints); i++) {
-                    endpoint_description_pt endpoint = arrayList_get(currentEndpoints, i);
-                    if (!arrayList_contains(updatedEndpoints, endpoint)) {
-                        // status = discovery_removeDiscoveredEndpoint(poller->discovery, endpoint);
-                    }
-                }
-
-                arrayList_clear(currentEndpoints);
-                arrayList_addAll(currentEndpoints, updatedEndpoints);
-                arrayList_destroy(updatedEndpoints);
-
-                for (i = 0; i < arrayList_size(currentEndpoints); i++) {
-                    endpoint_description_pt endpoint = arrayList_get(currentEndpoints, i);
-                    // status = discovery_addDiscoveredEndpoint(poller->discovery, endpoint);
-                }
-            }
-        }
+    useconds_t interval = poller->poll_interval * 1000000L;
+
+    while (poller->running) {
+    	usleep(interval);
 
-        status = celixThreadMutex_unlock(&poller->pollerLock);
-        if (status != 0) {
-            status = CELIX_BUNDLE_EXCEPTION;
+        celix_status_t status = celixThreadMutex_lock(&poller->pollerLock);
+        if (status != CELIX_SUCCESS) {
+        	printf("ENDPOINT_POLLER: failed to obtain lock; retrying...\n");
+        	continue;
         }
+
+		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);
+
+			array_list_pt updatedEndpoints = NULL;
+			// create an arraylist with a custom equality test to ensure we can find endpoints properly...
+			status = arrayList_createWithEquals(endpointDiscoveryPoller_endpointDescriptionEquals, &updatedEndpoints);
+
+			status = endpointDiscoveryPoller_getEndpoints(poller, url, &updatedEndpoints);
+			if (status != CELIX_SUCCESS) {
+				continue;
+			}
+
+			for (int i = 0; i < arrayList_size(currentEndpoints); i++) {
+				endpoint_description_pt endpoint = arrayList_get(currentEndpoints, i);
+				if (!arrayList_contains(updatedEndpoints, endpoint)) {
+					status = discovery_removeDiscoveredEndpoint(poller->discovery, endpoint);
+				}
+			}
+
+			arrayList_clear(currentEndpoints);
+			if (updatedEndpoints) {
+				arrayList_addAll(currentEndpoints, updatedEndpoints);
+				arrayList_destroy(updatedEndpoints);
+			}
+
+			for (int i = 0; i < arrayList_size(currentEndpoints); i++) {
+				endpoint_description_pt endpoint = arrayList_get(currentEndpoints, i);
+
+				status = discovery_addDiscoveredEndpoint(poller->discovery, endpoint);
+			}
+		}
+
+		status = celixThreadMutex_unlock(&poller->pollerLock);
+		if (status != CELIX_SUCCESS) {
+        	printf("ENDPOINT_POLLER: failed to release lock; retrying...\n");
+		}
     }
 
     return NULL;
@@ -160,6 +260,23 @@ struct MemoryStruct {
   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)!\n");
+        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;
 
@@ -172,7 +289,7 @@ static celix_status_t endpointDiscoveryP
 
     curl_global_init(CURL_GLOBAL_ALL);
     curl = curl_easy_init();
-    if(!curl) {
+    if (!curl) {
         status = CELIX_ILLEGAL_STATE;
     } else {
         curl_easy_setopt(curl, CURLOPT_URL, url);
@@ -183,33 +300,30 @@ static celix_status_t endpointDiscoveryP
     }
 
     // process endpoints file
+    if (res == CURLE_OK) {
+        endpoint_descriptor_reader_pt reader = NULL;
+
+    	status = endpointDescriptorReader_create(&reader);
+    	if (status == CELIX_SUCCESS) {
+			status = endpointDescriptorReader_parseDocument(reader, chunk.memory, updatedEndpoints);
+    	}
+
+    	if (reader) {
+			endpointDescriptorReader_destroy(reader);
+    	}
+    } else {
+    	printf("ENDPOINT_POLLER: unable to read endpoints, reason: %s\n", curl_easy_strerror(res));
+    }
 
     // clean up endpoints file
-    if(chunk.memory) {
+    if (chunk.memory) {
         free(chunk.memory);
     }
+
     curl_global_cleanup();
     return status;
 }
 
-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) {
-        /* out of memory! */
-        printf("not enough memory (realloc returned NULL)\n");
-        return 0;
-    }
-
-    memcpy(&(mem->memory[mem->size]), contents, realsize);
-    mem->size += realsize;
-    mem->memory[mem->size] = 0;
-
-    return realsize;
-}
-
 static celix_status_t endpointDiscoveryPoller_endpointDescriptionEquals(void *endpointPtr, void *comparePtr, bool *equals) {
     endpoint_description_pt endpoint = (endpoint_description_pt) endpointPtr;
     endpoint_description_pt compare = (endpoint_description_pt) comparePtr;

Added: celix/trunk/remote_services/discovery_configured/private/src/endpoint_discovery_server.c
URL: http://svn.apache.org/viewvc/celix/trunk/remote_services/discovery_configured/private/src/endpoint_discovery_server.c?rev=1617689&view=auto
==============================================================================
--- celix/trunk/remote_services/discovery_configured/private/src/endpoint_discovery_server.c (added)
+++ celix/trunk/remote_services/discovery_configured/private/src/endpoint_discovery_server.c Wed Aug 13 08:46:09 2014
@@ -0,0 +1,309 @@
+/**
+ * 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:celix-dev@incubator.apache.org">Apache Celix Project Team</a>
+ * \copyright	Apache License, Version 2.0
+ */
+#include <stdlib.h>
+
+#include "civetweb.h"
+#include "celix_errno.h"
+#include "utils.h"
+
+#include "endpoint_descriptor_writer.h"
+#include "endpoint_discovery_server.h"
+
+#define DISCOVERY_SERVER_PORT "DISCOVERY_CFG_SERVER_PORT"
+#define DEFAULT_SERVER_PORT "9999"
+
+#define DISCOVERY_SERVER_PATH "DISCOVERY_CFG_SERVER_PATH"
+#define DEFAULT_SERVER_PATH "/org.apache.celix.discovery.configured"
+
+#define DEFAULT_SERVER_THREADS "10"
+
+#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 {
+    hash_map_pt entries; // key = endpointId, value = endpoint_descriptor_pt
+
+    celix_thread_mutex_t serverLock;
+
+    const char* path;
+    struct mg_context* ctx;
+};
+
+// Forward declarations...
+static int endpointDiscoveryServer_callback(struct mg_connection *conn);
+static char* format_path(char* path);
+
+celix_status_t endpointDiscoveryServer_create(discovery_pt discovery, bundle_context_pt context, endpoint_discovery_server_pt *server) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	*server = malloc(sizeof(struct endpoint_discovery_server));
+	if (!*server) {
+		return CELIX_ENOMEM;
+	}
+
+	(*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;
+	}
+
+	char *port = NULL;
+	bundleContext_getProperty(context, DISCOVERY_SERVER_PORT, &port);
+	if (port == NULL) {
+		port = DEFAULT_SERVER_PORT;
+	}
+
+	char *path = NULL;
+	bundleContext_getProperty(context, DISCOVERY_SERVER_PATH, &path);
+	if (path == NULL) {
+		path = DEFAULT_SERVER_PATH;
+	}
+
+	(*server)->path = format_path(path);
+
+	const char *options[] = {
+		"listening_ports", port,
+		"num_threads", DEFAULT_SERVER_THREADS,
+		NULL
+	};
+
+	const struct mg_callbacks callbacks = {
+		.begin_request = endpointDiscoveryServer_callback,
+	};
+
+	(*server)->ctx = mg_start(&callbacks, (*server), options);
+
+	printf("CONFIGURED_DISCOVERY: Starting discovery server on port %s...\n", port);
+
+	return status;
+}
+
+celix_status_t endpointDiscoveryServer_destroy(endpoint_discovery_server_pt *server) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	// stop & block until the actual server is shut down...
+	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(*server);
+
+	return status;
+}
+
+celix_status_t endpointDiscoveryServer_addEndpoint(endpoint_discovery_server_pt server, endpoint_description_pt endpoint) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	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) {
+		printf("CONFIGURED_DISCOVERY: exposing new endpoint \"%s\"...\n", 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 = CELIX_SUCCESS;
+
+	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);
+
+		printf("CONFIGURED_DISCOVERY: 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(char* path) {
+	char* result = strdup(utils_stringTrim(path));
+	// 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 = CELIX_SUCCESS;
+
+	status = arrayList_create(endpoints);
+	if (status != CELIX_SUCCESS) {
+		return CELIX_ENOMEM;
+	}
+
+	status = celixThreadMutex_lock(&server->serverLock);
+	if (status != CELIX_SUCCESS) {
+		return CELIX_BUNDLE_EXCEPTION;
+	}
+
+	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);
+
+	status = celixThreadMutex_unlock(&server->serverLock);
+	if (status != CELIX_SUCCESS) {
+		return CELIX_BUNDLE_EXCEPTION;
+	}
+
+	return status;
+}
+
+static int endpointDiscoveryServer_writeEndpoints(struct mg_connection* conn, array_list_pt endpoints) {
+	celix_status_t status = CELIX_SUCCESS;
+
+    endpoint_descriptor_writer_pt writer = NULL;
+    status = endpointDescriptorWriter_create(&writer);
+    if (status != CELIX_SUCCESS) {
+    	return CIVETWEB_REQUEST_NOT_HANDLED;
+    }
+
+    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));
+    }
+
+    status = endpointDescriptorWriter_destroy(writer);
+
+	return CIVETWEB_REQUEST_HANDLED;
+}
+
+// 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;
+	endpointDiscoveryServer_getEndpoints(server, NULL, &endpoints);
+	if (endpoints) {
+		status = endpointDiscoveryServer_writeEndpoints(conn, endpoints);
+
+		arrayList_destroy(endpoints);
+	}
+
+	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;
+	endpointDiscoveryServer_getEndpoints(server, endpoint_id, &endpoints);
+	if (endpoints) {
+		status = endpointDiscoveryServer_writeEndpoints(conn, endpoints);
+
+		arrayList_destroy(endpoints);
+	}
+
+	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;
+}

Modified: celix/trunk/remote_services/remote_service_admin/private/src/endpoint_description.c
URL: http://svn.apache.org/viewvc/celix/trunk/remote_services/remote_service_admin/private/src/endpoint_description.c?rev=1617689&r1=1617688&r2=1617689&view=diff
==============================================================================
--- celix/trunk/remote_services/remote_service_admin/private/src/endpoint_description.c (original)
+++ celix/trunk/remote_services/remote_service_admin/private/src/endpoint_description.c Wed Aug 13 08:46:09 2014
@@ -24,6 +24,7 @@
  *  \copyright  Apache License, Version 2.0
  */
 #include <stdlib.h>
+#include <stdio.h>
 
 #include "celix_errno.h"
 
@@ -31,21 +32,31 @@
 #include "remote_constants.h"
 #include "constants.h"
 
-static celix_status_t endpointDescription_verifyLongProperty(endpoint_description_pt description, char *propertyName, long *longProperty);
+static celix_status_t endpointDescription_verifyLongProperty(properties_pt properties, char *propertyName, long *longProperty);
 
 celix_status_t endpointDescription_create(properties_pt properties, endpoint_description_pt *endpointDescription) {
+	celix_status_t status = CELIX_SUCCESS;
 
     *endpointDescription = malloc(sizeof(**endpointDescription));
 
-    (*endpointDescription)->properties = properties;
+    long serviceId = 0L;
+    status = endpointDescription_verifyLongProperty(properties, (char *) OSGI_RSA_ENDPOINT_SERVICE_ID, &serviceId);
+    if (status != CELIX_SUCCESS) {
+    	return status;
+    }
 
-    (*endpointDescription)->frameworkUUID = NULL;
-    endpointDescription_verifyLongProperty(*endpointDescription, (char *) OSGI_RSA_ENDPOINT_SERVICE_ID, &(*endpointDescription)->serviceId);
+    (*endpointDescription)->properties = properties;
+    (*endpointDescription)->frameworkUUID = properties_get(properties, (char *) OSGI_RSA_ENDPOINT_FRAMEWORK_UUID);
     (*endpointDescription)->id = properties_get(properties, (char *) OSGI_RSA_ENDPOINT_ID);
     (*endpointDescription)->service = properties_get(properties, (char *) OSGI_FRAMEWORK_OBJECTCLASS);
+    (*endpointDescription)->serviceId = serviceId;
 
+    if (!(*endpointDescription)->frameworkUUID || !(*endpointDescription)->id || !(*endpointDescription)->service) {
+    	printf("ENDPOINT_DESCRIPTION: incomplete description!\n");
+    	status = CELIX_BUNDLE_EXCEPTION;
+    }
 
-    return CELIX_SUCCESS;
+    return status;
 }
 
 celix_status_t endpointDescription_destroy(endpoint_description_pt description) {
@@ -54,10 +65,10 @@ celix_status_t endpointDescription_destr
     return CELIX_SUCCESS;
 }
 
-static celix_status_t endpointDescription_verifyLongProperty(endpoint_description_pt description, char *propertyName, long *longProperty) {
+static celix_status_t endpointDescription_verifyLongProperty(properties_pt properties, char *propertyName, long *longProperty) {
     celix_status_t status = CELIX_SUCCESS;
 
-    char *value = properties_get(description->properties, propertyName);
+    char *value = properties_get(properties, propertyName);
     if (value == NULL) {
         *longProperty = 0l;
     } else {

Modified: celix/trunk/remote_services/remote_service_admin/public/include/endpoint_description.h
URL: http://svn.apache.org/viewvc/celix/trunk/remote_services/remote_service_admin/public/include/endpoint_description.h?rev=1617689&r1=1617688&r2=1617689&view=diff
==============================================================================
--- celix/trunk/remote_services/remote_service_admin/public/include/endpoint_description.h (original)
+++ celix/trunk/remote_services/remote_service_admin/public/include/endpoint_description.h Wed Aug 13 08:46:09 2014
@@ -31,7 +31,6 @@
 #include "array_list.h"
 
 struct endpoint_description {
-    array_list_pt configurationTypes;
     char *frameworkUUID;
     char *id;
     // array_list_pt intents;

Modified: celix/trunk/remote_services/remote_service_admin_http/CMakeLists.txt
URL: http://svn.apache.org/viewvc/celix/trunk/remote_services/remote_service_admin_http/CMakeLists.txt?rev=1617689&r1=1617688&r2=1617689&view=diff
==============================================================================
--- celix/trunk/remote_services/remote_service_admin_http/CMakeLists.txt (original)
+++ celix/trunk/remote_services/remote_service_admin_http/CMakeLists.txt Wed Aug 13 08:46:09 2014
@@ -20,6 +20,7 @@ find_package(CURL REQUIRED)
 
 include_directories(${CURL_INCLUDE_DIRS})
 include_directories("${PROJECT_SOURCE_DIR}/utils/public/include")
+include_directories("${PROJECT_SOURCE_DIR}/remote_services/utils/private/include")
 include_directories("${PROJECT_SOURCE_DIR}/remote_services/utils/public/include")
 include_directories("${PROJECT_SOURCE_DIR}/remote_services/remote_service_admin/public/include")
 include_directories("${PROJECT_SOURCE_DIR}/remote_services/remote_service_admin/private/include")
@@ -34,7 +35,7 @@ bundle(remote_service_admin_http SOURCES
 	private/src/export_registration_impl
 	private/src/import_registration_impl
 	private/src/remote_service_admin_activator
-	private/src/civetweb.c
+	${PROJECT_SOURCE_DIR}/remote_services/utils/private/src/civetweb.c
 )
     
 target_link_libraries(remote_service_admin_http celix_framework ${APRUTIL_LIBRARY} ${CURL_LIBRARIES})

Modified: celix/trunk/remote_services/remote_service_admin_http/private/src/import_registration_impl.c
URL: http://svn.apache.org/viewvc/celix/trunk/remote_services/remote_service_admin_http/private/src/import_registration_impl.c?rev=1617689&r1=1617688&r2=1617689&view=diff
==============================================================================
--- celix/trunk/remote_services/remote_service_admin_http/private/src/import_registration_impl.c (original)
+++ celix/trunk/remote_services/remote_service_admin_http/private/src/import_registration_impl.c Wed Aug 13 08:46:09 2014
@@ -127,7 +127,7 @@ celix_status_t importRegistrationFactory
 	if (status == CELIX_SUCCESS) {
 		status = bundle_start(registration_factory->bundle);
 		if (status == CELIX_SUCCESS) {
-			printf("%s sucessfully started\n", name);
+			printf("%s successfully started\n", name);
 		}
 	}
 	else
@@ -219,13 +219,13 @@ celix_status_t importRegistrationFactory
 	}
 	else if ((status = importRegistrationFactory_open(*registration_factory)) != CELIX_SUCCESS)
 	{
-		printf("remoteServiceAdmin_importService: cannot open registration_factory for %s \n  ", serviceName);
+		printf("remoteServiceAdmin_importService: cannot open registration_factory for %s \n", serviceName);
 		importRegistrationFactory_destroy(registration_factory);
 	}
 	else
 	{
 		importRegistration_createProxyFactoryTracker(*registration_factory, &((*registration_factory)->proxyFactoryTracker));
-		printf("remoteServiceAdmin_importService: new registration_factory added for %s at %p\n  ", serviceName, (*registration_factory)->proxyFactoryTracker);
+		printf("remoteServiceAdmin_importService: new registration_factory added for %s at %p\n", serviceName, (*registration_factory)->proxyFactoryTracker);
 	}
 
 	return status;

Modified: celix/trunk/remote_services/remote_service_admin_http/private/src/remote_service_admin_impl.c
URL: http://svn.apache.org/viewvc/celix/trunk/remote_services/remote_service_admin_http/private/src/remote_service_admin_impl.c?rev=1617689&r1=1617688&r2=1617689&view=diff
==============================================================================
--- celix/trunk/remote_services/remote_service_admin_http/private/src/remote_service_admin_impl.c (original)
+++ celix/trunk/remote_services/remote_service_admin_http/private/src/remote_service_admin_impl.c Wed Aug 13 08:46:09 2014
@@ -54,17 +54,20 @@ struct get {
     int size;
 };
 
-static const char *ajax_reply_start =
+static const char *response_headers =
   "HTTP/1.1 200 OK\r\n"
   "Cache: no-cache\r\n"
-  "Content-Type: application/x-javascript\r\n"
+  "Content-Type: application/json\r\n"
   "\r\n";
 
+// TODO do we need to specify a non-Amdatu specific configuration type?!
+static const char * const CONFIGURATION_TYPE = "org.amdatu.remote.admin.http";
+static const char * const ENDPOINT_URL = "org.amdatu.remote.admin.http.url";
 
 static const char *DEFAULT_PORT = "8888";
 
-//void *remoteServiceAdmin_callback(enum mg_event event, struct mg_connection *conn, const struct mg_request_info *request_info);
 static int remoteServiceAdmin_callback(struct mg_connection *conn);
+
 celix_status_t remoteServiceAdmin_installEndpoint(remote_service_admin_pt admin, export_registration_pt registration, service_reference_pt reference, char *interface);
 celix_status_t remoteServiceAdmin_createEndpointDescription(remote_service_admin_pt admin, properties_pt serviceProperties, properties_pt endpointProperties, char *interface, endpoint_description_pt *description);
 static celix_status_t constructServiceUrl(remote_service_admin_pt admin, char *service, char **serviceUrl);
@@ -149,12 +152,13 @@ celix_status_t remoteServiceAdmin_stop(r
 //void *remoteServiceAdmin_callback(enum mg_event event, struct mg_connection *conn, const struct mg_request_info *request_info) {
 
 static int remoteServiceAdmin_callback(struct mg_connection *conn) {
+	int result = 0; // zero means: let civetweb handle it further, any non-zero value means it is handled by us...
+
 	const struct mg_request_info *request_info = mg_get_request_info(conn);
 	if (request_info->uri != NULL) {
-		printf("REMOTE_SERVICE_ADMIN: Handle request: %s\n", request_info->uri);
 		remote_service_admin_pt rsa = request_info->user_data;
 
-		if (strncmp(request_info->uri, "/service/", 9) == 0) {
+		if (strncmp(request_info->uri, "/service/", 9) == 0 && strcmp("POST", request_info->request_method) == 0) {
 			// uri = /services/myservice/call
 			const char *uri = request_info->uri;
 			// rest = myservice/call
@@ -167,18 +171,6 @@ static int remoteServiceAdmin_callback(s
 			strncpy(service, rest, pos);
 			service[pos] = '\0';
 
-			printf("Got service %s, interfaceStart is %s and callStart is %s\n", service, interfaceStart, callStart);
-
-//			char *request = callStart+1;
-
-			const char *lengthStr = mg_get_header(conn, (const char *) "Content-Length");
-			int datalength = apr_atoi64(lengthStr);
-			char data[datalength+1];
-			mg_read(conn, data, datalength);
-			data[datalength] = '\0';
-
-			printf("%s\n", data);
-
 			hash_map_iterator_pt iter = hashMapIterator_create(rsa->exportedServices);
 			while (hashMapIterator_hasNext(iter)) {
 				hash_map_entry_pt entry = hashMapIterator_nextEntry(iter);
@@ -188,12 +180,22 @@ static int remoteServiceAdmin_callback(s
 					export_registration_pt export = arrayList_get(exports, expIt);
 					long serviceId = atol(service);
 					if (serviceId == export->endpointDescription->serviceId) {
-						char *reply = NULL;
-						export->endpoint->handleRequest(export->endpoint->endpoint, data, &reply);
-						if (reply != NULL) {
-							mg_printf(conn, "%s", ajax_reply_start);
-							mg_printf(conn, "%s", reply);
+						uint64_t datalength = request_info->content_length;
+						char* data = malloc(datalength + 1);
+						mg_read(conn, data, datalength);
+						data[datalength] = '\0';
+
+						char *response = NULL;
+						export->endpoint->handleRequest(export->endpoint->endpoint, data, &response);
+
+						if (response != NULL) {
+							mg_write(conn, response_headers, strlen(response_headers));
+							mg_write(conn, response, strlen(response));
+
+							result = 1;
 						}
+
+						free(data);
 					}
 				}
 			}
@@ -201,7 +203,7 @@ static int remoteServiceAdmin_callback(s
 		}
 	}
 
-	return 1;
+	return result;
 }
 
 celix_status_t remoteServiceAdmin_handleRequest(remote_service_admin_pt rsa, char *service, char *data, char **reply) {
@@ -341,22 +343,25 @@ celix_status_t remoteServiceAdmin_instal
 
 	char *serviceId = (char *) hashMap_remove(endpointProperties, (void *) OSGI_FRAMEWORK_SERVICE_ID);
 	char *uuid = NULL;
-	bundleContext_getProperty(admin->context, OSGI_FRAMEWORK_FRAMEWORK_UUID, &uuid);
-	properties_set(endpointProperties, (char *) OSGI_RSA_ENDPOINT_FRAMEWORK_UUID, uuid);
-	properties_set(endpointProperties, (char *) OSGI_FRAMEWORK_OBJECTCLASS, interface);
-	properties_set(endpointProperties, (char *) OSGI_RSA_ENDPOINT_SERVICE_ID, serviceId);
-	properties_set(endpointProperties, "service.imported", "true");
-
-//    properties_set(endpointProperties, ".ars.path", buf);
-//    properties_set(endpointProperties, ".ars.port", admin->port);
 
 	char buf[512];
 	sprintf(buf, "/service/%s/%s", serviceId, interface);
     char *url = NULL;
     constructServiceUrl(admin,buf, &url);
-    properties_set(endpointProperties, ".ars.alias", url);
 
-    properties_set(endpointProperties, "service.imported.configs", ".ars");
+	uuid_t endpoint_uid;
+	uuid_generate(endpoint_uid);
+	char endpoint_uuid[37];
+	uuid_unparse_lower(endpoint_uid, endpoint_uuid);
+
+	bundleContext_getProperty(admin->context, OSGI_FRAMEWORK_FRAMEWORK_UUID, &uuid);
+	properties_set(endpointProperties, (char*) OSGI_RSA_ENDPOINT_FRAMEWORK_UUID, uuid);
+	properties_set(endpointProperties, (char*) OSGI_FRAMEWORK_OBJECTCLASS, interface);
+	properties_set(endpointProperties, (char*) OSGI_RSA_ENDPOINT_SERVICE_ID, serviceId);
+	properties_set(endpointProperties, (char*) OSGI_RSA_ENDPOINT_ID, endpoint_uuid);
+	properties_set(endpointProperties, (char*) OSGI_RSA_SERVICE_IMPORTED, "true");
+    properties_set(endpointProperties, (char*) OSGI_RSA_SERVICE_IMPORTED_CONFIGS, (char*) CONFIGURATION_TYPE);
+    properties_set(endpointProperties, (char*) ENDPOINT_URL, url);
 
 	endpoint_description_pt endpointDescription = NULL;
 	remoteServiceAdmin_createEndpointDescription(admin, serviceProperties, endpointProperties, interface, &endpointDescription);
@@ -396,8 +401,6 @@ static celix_status_t constructServiceUr
 	return status;
 }
 
-
-
 celix_status_t remoteServiceAdmin_createEndpointDescription(remote_service_admin_pt admin, properties_pt serviceProperties,
 		properties_pt endpointProperties, char *interface, endpoint_description_pt *description) {
 	celix_status_t status = CELIX_SUCCESS;
@@ -409,22 +412,11 @@ celix_status_t remoteServiceAdmin_create
 	if (!*description) {
 		status = CELIX_ENOMEM;
 	} else {
-		char *uuid = NULL;
-		status = bundleContext_getProperty(admin->context, (char *)OSGI_FRAMEWORK_FRAMEWORK_UUID, &uuid);
-		if (status == CELIX_SUCCESS) {
-//		    char uuid[37];
-//		    uuid_t uid;
-//            uuid_generate(uid);
-//            uuid_unparse(uid, uuid);
-//
-//            printf("%s\n", uuid);
-
-			(*description)->properties = endpointProperties;
-			(*description)->frameworkUUID = uuid;
-			(*description)->serviceId = apr_atoi64(properties_get(serviceProperties, (char *) OSGI_FRAMEWORK_SERVICE_ID));
-			(*description)->id = apr_pstrdup(childPool, properties_get(serviceProperties, (char *) OSGI_FRAMEWORK_SERVICE_ID)); // Should be uuid
-			(*description)->service = interface;
-		}
+		(*description)->id = properties_get(endpointProperties, (char*) OSGI_RSA_ENDPOINT_ID);
+		(*description)->serviceId = apr_atoi64(properties_get(serviceProperties, (char*) OSGI_FRAMEWORK_SERVICE_ID));
+		(*description)->frameworkUUID = properties_get(endpointProperties, (char*) OSGI_RSA_ENDPOINT_FRAMEWORK_UUID);
+		(*description)->service = interface;
+		(*description)->properties = endpointProperties;
 	}
 
 	return status;
@@ -506,8 +498,6 @@ celix_status_t remoteServiceAdmin_remove
 }
 
 
-
-
 celix_status_t remoteServiceAdmin_send(remote_service_admin_pt rsa, endpoint_description_pt endpointDescription, char *request, char **reply, int* replyStatus) {
 
     struct post post;
@@ -518,8 +508,7 @@ celix_status_t remoteServiceAdmin_send(r
     get.size = 0;
     get.writeptr = malloc(1);
 
-    char *serviceUrl = properties_get(endpointDescription->properties, ".ars.alias");
-    printf("CALCULATOR_PROXY: URL: %s\n", serviceUrl);
+    char *serviceUrl = properties_get(endpointDescription->properties, (char*) ENDPOINT_URL);
     char *url = apr_pstrcat(rsa->pool, serviceUrl, NULL);
 
     celix_status_t status = CELIX_SUCCESS;
@@ -540,10 +529,10 @@ celix_status_t remoteServiceAdmin_send(r
         res = curl_easy_perform(curl);
         curl_easy_cleanup(curl);
 
-        printf("CALCULATOR_PROXY: Data read: \"%s\" %d\n", get.writeptr, res);
         *reply = get.writeptr;
-
+        *replyStatus = res;
     }
+
     return status;
 }
 

Modified: celix/trunk/remote_services/remote_service_admin_shm/private/src/remote_service_admin_impl.c
URL: http://svn.apache.org/viewvc/celix/trunk/remote_services/remote_service_admin_shm/private/src/remote_service_admin_impl.c?rev=1617689&r1=1617688&r2=1617689&view=diff
==============================================================================
--- celix/trunk/remote_services/remote_service_admin_shm/private/src/remote_service_admin_impl.c (original)
+++ celix/trunk/remote_services/remote_service_admin_shm/private/src/remote_service_admin_impl.c Wed Aug 13 08:46:09 2014
@@ -929,7 +929,7 @@ celix_status_t remoteServiceAdmin_create
             (*description)->properties = endpointProperties;
             (*description)->frameworkUUID = uuid;
             (*description)->serviceId = apr_atoi64(properties_get(serviceProperties, (char *) OSGI_FRAMEWORK_SERVICE_ID));
-            (*description)->id = properties_get(endpointProperties, (char *) OSGI_RSA_SERVICE_LOCATION);
+            (*description)->id = properties_get(endpointProperties, (char *) OSGI_RSA_SERVICE_LOCATION); // TODO this should be a UUID!
             (*description)->service = interface;
         }
     }

Modified: celix/trunk/remote_services/topology_manager/private/src/topology_manager.c
URL: http://svn.apache.org/viewvc/celix/trunk/remote_services/topology_manager/private/src/topology_manager.c?rev=1617689&r1=1617688&r2=1617689&view=diff
==============================================================================
--- celix/trunk/remote_services/topology_manager/private/src/topology_manager.c (original)
+++ celix/trunk/remote_services/topology_manager/private/src/topology_manager.c Wed Aug 13 08:46:09 2014
@@ -49,7 +49,6 @@ struct topology_manager {
 	array_list_pt rsaList;
 	hash_map_pt exportedServices;
 	hash_map_pt importedServices;
-
 	hash_map_pt importInterests;
 };
 
@@ -85,9 +84,9 @@ celix_status_t topologyManager_destroy(t
 	celix_status_t status = CELIX_SUCCESS;
 
 	arrayList_destroy(manager->rsaList);
-	hashMap_destroy(manager->exportedServices,false,false);
-	hashMap_destroy(manager->importedServices,false,false);
-	hashMap_destroy(manager->importInterests,false,false);
+	hashMap_destroy(manager->exportedServices, false, false);
+	hashMap_destroy(manager->importedServices, false, false);
+	hashMap_destroy(manager->importInterests, false, false);
 
 	return status;
 }
@@ -108,6 +107,7 @@ celix_status_t topologyManager_rsaAdded(
 
 	printf("TOPOLOGY_MANAGER: Added RSA\n");
 	arrayList_add(manager->rsaList, service);
+	// TODO add the imported/exported services to the given RSA...
 
 	return status;
 }
@@ -124,6 +124,7 @@ celix_status_t topologyManager_rsaRemove
 
 	printf("TOPOLOGY_MANAGER: Removed RSA\n");
 	arrayList_removeElement(manager->rsaList, service);
+	// TODO remove the imported/exported services from the given RSA...
 
 	return status;
 }
@@ -131,11 +132,13 @@ celix_status_t topologyManager_rsaRemove
 celix_status_t topologyManager_serviceChanged(void *listener, service_event_pt event) {
 	celix_status_t status = CELIX_SUCCESS;
 	service_listener_pt listen = listener;
-
 	topology_manager_pt manager = listen->handle;
+
+	printf("TOPOLOGY_MANAGER: found event reference %p\n", event->reference);
+
 	service_registration_pt registration = NULL;
-	printf("found event reference %p\n", event->reference);
 	serviceReference_getServiceRegistration(event->reference, &registration);
+
 	properties_pt props = NULL;
 	serviceRegistration_getProperties(registration, &props);
 	char *name = properties_get(props, (char *) OSGI_FRAMEWORK_OBJECTCLASS);
@@ -144,13 +147,12 @@ celix_status_t topologyManager_serviceCh
 
 	if (event->type == OSGI_FRAMEWORK_SERVICE_EVENT_REGISTERED) {
 		if (export != NULL) {
+			printf("TOPOLOGY_MANAGER: Service registering: %s\n", name);
 			status = topologyManager_exportService(manager, event->reference, serviceId);
 		}
 	} else if (event->type == OSGI_FRAMEWORK_SERVICE_EVENT_UNREGISTERING) {
-		//if (export != NULL) {
-			printf("TOPOLOGY_MANAGER: Service unregistering: %s\n", name);
-			status = topologyManager_removeService(manager, event->reference, serviceId);
-		//}
+		printf("TOPOLOGY_MANAGER: Service unregistering: %s\n", name);
+		status = topologyManager_removeService(manager, event->reference, serviceId);
 	}
 
 	return status;
@@ -159,7 +161,7 @@ celix_status_t topologyManager_serviceCh
 celix_status_t topologyManager_endpointAdded(void *handle, endpoint_description_pt endpoint, char *machtedFilter) {
 	celix_status_t status = CELIX_SUCCESS;
 	topology_manager_pt manager = handle;
-	printf("TOPOLOGY_MANAGER: Endpoint added\n");
+	printf("TOPOLOGY_MANAGER: Endpoint (%s; %s) added...\n", endpoint->service, endpoint->id);
 
 	status = topologyManager_importService(manager, endpoint);
 
@@ -169,7 +171,7 @@ celix_status_t topologyManager_endpointA
 celix_status_t topologyManager_endpointRemoved(void *handle, endpoint_description_pt endpoint, char *machtedFilter) {
 	celix_status_t status = CELIX_SUCCESS;
 	topology_manager_pt manager = handle;
-	printf("TOPOLOGY_MANAGER: Endpoint removed\n");
+	printf("TOPOLOGY_MANAGER: Endpoint (%s; %s) removed...\n", endpoint->service, endpoint->id);
 
 	if (hashMap_containsKey(manager->importedServices, endpoint)) {
 		hash_map_pt imports = hashMap_get(manager->importedServices, endpoint);

Copied: celix/trunk/remote_services/utils/private/include/civetweb.h (from r1613832, celix/trunk/remote_services/remote_service_admin_http/private/include/civetweb.h)
URL: http://svn.apache.org/viewvc/celix/trunk/remote_services/utils/private/include/civetweb.h?p2=celix/trunk/remote_services/utils/private/include/civetweb.h&p1=celix/trunk/remote_services/remote_service_admin_http/private/include/civetweb.h&r1=1613832&r2=1617689&rev=1617689&view=diff
==============================================================================
--- celix/trunk/remote_services/remote_service_admin_http/private/include/civetweb.h (original)
+++ celix/trunk/remote_services/utils/private/include/civetweb.h Wed Aug 13 08:46:09 2014
@@ -39,6 +39,7 @@ struct mg_request_info {
     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
+    uint64_t content_length;
     long remote_ip;             // Client's IP address
     int remote_port;            // Client's port
     int is_ssl;                 // 1 if SSL-ed, 0 if not

Copied: celix/trunk/remote_services/utils/private/src/civetweb.c (from r1613832, celix/trunk/remote_services/remote_service_admin_http/private/src/civetweb.c)
URL: http://svn.apache.org/viewvc/celix/trunk/remote_services/utils/private/src/civetweb.c?p2=celix/trunk/remote_services/utils/private/src/civetweb.c&p1=celix/trunk/remote_services/remote_service_admin_http/private/src/civetweb.c&r1=1613832&r2=1617689&rev=1617689&view=diff
==============================================================================
--- celix/trunk/remote_services/remote_service_admin_http/private/src/civetweb.c (original)
+++ celix/trunk/remote_services/utils/private/src/civetweb.c Wed Aug 13 08:46:09 2014
@@ -2502,7 +2502,8 @@ static int authorize(struct mg_connectio
     // Loop over passwords file
     p = (char *) filep->membuf;
     while (mg_fgets(line, sizeof(line), filep, &p) != NULL) {
-        if (sscanf(line, "%[^:]:%[^:]:%s", f_user, f_domain, ha1) != 3) {
+    	// JaWi - limit the sizes to up to 255 characters...
+        if (sscanf(line, "%255[^:]:%255[^:]:%255s", f_user, f_domain, ha1) != 3) {
             continue;
         }
 
@@ -5445,6 +5446,8 @@ static int getreq(struct mg_connection *
         } else {
             conn->content_len = 0;
         }
+        // JaWi: expose content length to request info for generic use...
+        conn->request_info.content_length = conn->content_len;
         conn->birth_time = time(NULL);
     }
     return ebuf[0] == '\0';

Copied: celix/trunk/remote_services/utils/private/src/md5.inl (from r1613832, celix/trunk/remote_services/remote_service_admin_http/private/src/md5.inl)
URL: http://svn.apache.org/viewvc/celix/trunk/remote_services/utils/private/src/md5.inl?p2=celix/trunk/remote_services/utils/private/src/md5.inl&p1=celix/trunk/remote_services/remote_service_admin_http/private/src/md5.inl&r1=1613832&r2=1617689&rev=1617689&view=diff
==============================================================================
    (empty)

Modified: celix/trunk/remote_services/utils/public/include/remote_constants.h
URL: http://svn.apache.org/viewvc/celix/trunk/remote_services/utils/public/include/remote_constants.h?rev=1617689&r1=1617688&r2=1617689&view=diff
==============================================================================
--- celix/trunk/remote_services/utils/public/include/remote_constants.h (original)
+++ celix/trunk/remote_services/utils/public/include/remote_constants.h Wed Aug 13 08:46:09 2014
@@ -31,7 +31,8 @@ static const char * const OSGI_RSA_SERVI
 static const char * const OSGI_RSA_ENDPOINT_FRAMEWORK_UUID = "endpoint.framework.uuid";
 static const char * const OSGI_RSA_ENDPOINT_SERVICE_ID = "endpoint.service.id";
 static const char * const OSGI_RSA_ENDPOINT_ID = "endpoint.id";
-
+static const char * const OSGI_RSA_SERVICE_IMPORTED = "service.imported";
+static const char * const OSGI_RSA_SERVICE_IMPORTED_CONFIGS = "service.imported.configs";
 static const char * const OSGI_RSA_SERVICE_LOCATION = "service.location";
 
 #endif /* REMOTE_CONSTANTS_H_ */