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:[email protected]";>Apache Celix 
Project Team</a>
- *  \copyright  Apache License, Version 2.0
+ * \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 "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:[email protected]";>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_ */


Reply via email to