You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@celix.apache.org by pn...@apache.org on 2015/08/07 16:27:33 UTC

[1/3] celix git commit: CELIX-237: Updated celix launcher so that mutiple embedded framework can be started (e.g. testing client / server rsa)

Repository: celix
Updated Branches:
  refs/heads/feature/CELIX-237_rsa-ffi 87f3fabf7 -> da86474fb


CELIX-237: Updated celix launcher so that mutiple embedded framework can be started (e.g. testing client / server rsa)


Project: http://git-wip-us.apache.org/repos/asf/celix/repo
Commit: http://git-wip-us.apache.org/repos/asf/celix/commit/55e75be7
Tree: http://git-wip-us.apache.org/repos/asf/celix/tree/55e75be7
Diff: http://git-wip-us.apache.org/repos/asf/celix/diff/55e75be7

Branch: refs/heads/feature/CELIX-237_rsa-ffi
Commit: 55e75be72c24a62818fe3e2326c396725f1d7557
Parents: 87f3fab
Author: Pepijn Noltes <pe...@gmail.com>
Authored: Thu Aug 6 13:27:13 2015 +0200
Committer: Pepijn Noltes <pe...@gmail.com>
Committed: Thu Aug 6 13:27:13 2015 +0200

----------------------------------------------------------------------
 framework/private/src/framework.c               |  2 +
 launcher/private/src/launcher.c                 | 46 ++++++++++----------
 launcher/private/src/main.c                     | 24 ++++++----
 launcher/public/include/launcher.h              | 12 ++---
 .../remote_service_admin_dfi/tst/rsa_tests.cpp  | 24 ++++++----
 .../remote_service_admin_dfi/tst/run_tests.cpp  | 17 --------
 6 files changed, 62 insertions(+), 63 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/celix/blob/55e75be7/framework/private/src/framework.c
----------------------------------------------------------------------
diff --git a/framework/private/src/framework.c b/framework/private/src/framework.c
index 3f49cdc..6e6e1ba 100644
--- a/framework/private/src/framework.c
+++ b/framework/private/src/framework.c
@@ -335,6 +335,8 @@ celix_status_t framework_destroy(framework_pt framework) {
 	celixThreadMutex_destroy(&framework->mutex);
 	celixThreadCondition_destroy(&framework->condition);
 
+    properties_destroy(framework->configurationMap);
+
 	free(framework);
 
 	return status;

http://git-wip-us.apache.org/repos/asf/celix/blob/55e75be7/launcher/private/src/launcher.c
----------------------------------------------------------------------
diff --git a/launcher/private/src/launcher.c b/launcher/private/src/launcher.c
index 9c021ed..432c709 100644
--- a/launcher/private/src/launcher.c
+++ b/launcher/private/src/launcher.c
@@ -32,23 +32,22 @@
 #include <libgen.h>
 #include <signal.h>
 
+#ifndef CELIX_NO_CURLINIT
 #include <curl/curl.h>
+#endif
 
 #include "framework.h"
 #include "linked_list_iterator.h"
 
-static struct framework * framework;
-static properties_pt config;
-
 #ifdef WITH_APR
 static apr_pool_t *memoryPool;
 #endif
 
-int celixLauncher_launch(const char *configFile) {
+int celixLauncher_launch(const char *configFile, framework_pt *framework) {
     int status = 0;
     FILE *config = fopen(configFile, "r");
     if (config != NULL) {
-        status = celixLauncher_launchWithStream(config);
+        status = celixLauncher_launchWithStream(config, framework);
     } else {
         fprintf(stderr, "Error: invalid or non-existing configuration file: '%s'.", configFile);
         perror("");
@@ -57,10 +56,10 @@ int celixLauncher_launch(const char *configFile) {
     return status;
 }
 
-int celixLauncher_launchWithStream(FILE *stream) {
+int celixLauncher_launchWithStream(FILE *stream, framework_pt *framework) {
     int status = 0;
 
-    config = properties_loadWithStream(stream);
+    properties_pt config = properties_loadWithStream(stream);
     fclose(stream);
     // Make sure we've read it and that nothing went wrong with the file access...
     if (config == NULL) {
@@ -69,14 +68,16 @@ int celixLauncher_launchWithStream(FILE *stream) {
         status = 1;
     }
 
-    // Set signal handler
+
 #ifdef WITH_APR
     apr_status_t rv;
     apr_status_t s;
 #endif
 
+#ifndef CELIX_NO_CURLINIT
     // Before doing anything else, let's setup Curl
     curl_global_init(CURL_GLOBAL_NOTHING);
+#endif
 
 #ifdef WITH_APR
 	rv = apr_initialize();
@@ -93,19 +94,18 @@ int celixLauncher_launchWithStream(FILE *stream) {
 
     if (status == 0) {
         char *autoStart = properties_get(config, "cosgi.auto.start.1");
-        framework = NULL;
         celix_status_t status;
 #ifdef WITH_APR
-        status = framework_create(&framework, memoryPool, config);
+        status = framework_create(framework, memoryPool, config);
 #else
-        status = framework_create(&framework, config);
+        status = framework_create(framework, config);
 #endif
         bundle_pt fwBundle = NULL;
         if (status == CELIX_SUCCESS) {
-            status = fw_init(framework);
+            status = fw_init(*framework);
             if (status == CELIX_SUCCESS) {
                 // Start the system bundle
-                framework_getFrameworkBundle(framework, &fwBundle);
+                framework_getFrameworkBundle(*framework, &fwBundle);
                 bundle_start(fwBundle);
 
                 char delims[] = " ";
@@ -128,7 +128,7 @@ int celixLauncher_launchWithStream(FILE *stream) {
                 // First install all bundles
                 // Afterwards start them
                 arrayList_create(&installed);
-                framework_getFrameworkBundle(framework, &bundle);
+                framework_getFrameworkBundle(*framework, &bundle);
                 bundle_getContext(bundle, &context);
                 iter = linkedListIterator_create(bundles, 0);
                 while (linkedListIterator_hasNext(iter)) {
@@ -164,8 +164,11 @@ int celixLauncher_launchWithStream(FILE *stream) {
 	apr_terminate();
 #endif
 
+
+#ifndef CELIX_NO_CURLINIT
         // Cleanup Curl
         curl_global_cleanup();
+#endif
 
         printf("Launcher: Exit\n");
     }
@@ -173,19 +176,16 @@ int celixLauncher_launchWithStream(FILE *stream) {
     return status;
 }
 
-void celixLauncher_waitForShutdown(void) {
+void celixLauncher_waitForShutdown(framework_pt framework) {
     framework_waitForStop(framework);
+}
+
+void celixLauncher_destroy(framework_pt framework) {
     framework_destroy(framework);
-    properties_destroy(config);
 }
 
-void celixLauncher_stop(void) {
+void celixLauncher_stop(framework_pt framework) {
     bundle_pt fwBundle = NULL;
     framework_getFrameworkBundle(framework, &fwBundle);
     bundle_stop(fwBundle);
-}
-
-struct framework *celixLauncher_getFramework(void) {
-    return framework;
-}
-
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/celix/blob/55e75be7/launcher/private/src/main.c
----------------------------------------------------------------------
diff --git a/launcher/private/src/main.c b/launcher/private/src/main.c
index 00b08bd..82530e1 100644
--- a/launcher/private/src/main.c
+++ b/launcher/private/src/main.c
@@ -31,13 +31,13 @@
 #include "launcher.h"
 
 static void show_usage(char* prog_name);
-static void shutdownCelix(int signal);
+static void shutdown_framework(int signal);
 
 #define DEFAULT_CONFIG_FILE "config.properties"
 
-int main(int argc, char *argv[]) {
+static framework_pt framework = NULL;
 
-    (void) signal(SIGINT, shutdownCelix);
+int main(int argc, char *argv[]) {
 
     // Perform some minimal command-line option parsing...
     char *opt = NULL;
@@ -59,15 +59,21 @@ int main(int argc, char *argv[]) {
         config_file = DEFAULT_CONFIG_FILE;
     }
 
-    celixLauncher_launch(config_file);
-    celixLauncher_waitForShutdown();
+
+    // Set signal handler
+    (void) signal(SIGINT, shutdown_framework);
+
+    celixLauncher_launch(config_file, &framework);
+    celixLauncher_waitForShutdown(framework);
+    celixLauncher_destroy(framework);
 }
 
 static void show_usage(char* prog_name) {
     printf("Usage:\n  %s [path/to/config.properties]\n\n", basename(prog_name));
 }
 
-static void shutdownCelix(int signal) {
-    celixLauncher_stop();
-}
-
+static void shutdown_framework(int signal) {
+    if (framework != NULL) {
+        celixLauncher_stop(framework); //NOTE main thread will destroy
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/celix/blob/55e75be7/launcher/public/include/launcher.h
----------------------------------------------------------------------
diff --git a/launcher/public/include/launcher.h b/launcher/public/include/launcher.h
index 6ee8357..6077e03 100644
--- a/launcher/public/include/launcher.h
+++ b/launcher/public/include/launcher.h
@@ -30,10 +30,12 @@
 #include <stdio.h>
 #include "framework.h"
 
-int celixLauncher_launch(const char *configFile);
-int celixLauncher_launchWithStream(FILE *config);
-void celixLauncher_stop(void);
-void celixLauncher_waitForShutdown(void);
-struct framework *celixLauncher_getFramework(void);
+int celixLauncher_launch(const char *configFile, framework_pt *framework);
+int celixLauncher_launchWithStream(FILE *config, framework_pt *framework);
+
+void celixLauncher_stop(framework_pt framework);
+void celixLauncher_destroy(framework_pt framework);
+
+void celixLauncher_waitForShutdown(framework_pt framework);
 
 #endif //CELIX_LAUNCHER_H

http://git-wip-us.apache.org/repos/asf/celix/blob/55e75be7/remote_services/remote_service_admin_dfi/tst/rsa_tests.cpp
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/tst/rsa_tests.cpp b/remote_services/remote_service_admin_dfi/tst/rsa_tests.cpp
index a5a556a..f23babd 100644
--- a/remote_services/remote_service_admin_dfi/tst/rsa_tests.cpp
+++ b/remote_services/remote_service_admin_dfi/tst/rsa_tests.cpp
@@ -17,16 +17,19 @@ extern "C" {
 #include "remote_service_admin.h"
 
 
+framework_pt framework = NULL;
 bundle_context_pt context = NULL;
 service_reference_pt rsaRef = NULL;
 remote_service_admin_service_pt rsa = NULL;
 
-static void setupContextAndRsa(void) {
+static void setupFm(void) {
     int rc = 0;
-    struct framework *fm = celixLauncher_getFramework();
+
+    rc = celixLauncher_launch("config.properties", &framework);
+    CHECK_EQUAL(CELIX_SUCCESS, rc);
 
     bundle_pt bundle = NULL;
-    rc = framework_getFrameworkBundle(fm, &bundle);
+    rc = framework_getFrameworkBundle(framework, &bundle);
     CHECK_EQUAL(CELIX_SUCCESS, rc);
 
     rc = bundle_getContext(bundle, &context);
@@ -39,13 +42,19 @@ static void setupContextAndRsa(void) {
     CHECK_EQUAL(CELIX_SUCCESS, rc);
 }
 
-static void teardownContextAndRsa(void) {
+static void teardownFm(void) {
     int rc = 0;
     rc = bundleContext_ungetService(context, rsaRef, NULL);
     CHECK_EQUAL(CELIX_SUCCESS, rc);
+
+    celixLauncher_stop(framework);
+    celixLauncher_waitForShutdown(framework);
+    celixLauncher_destroy(framework);
+
     rsaRef = NULL;
     rsa = NULL;
     context = NULL;
+    framework = NULL;
 }
 
 static void testInfo(void) {
@@ -77,14 +86,11 @@ static void testImportService(void) {
 
 TEST_GROUP(RsaDfiTests) {
     void setup() {
-        celixLauncher_launch("config.properties");
-        setupContextAndRsa();
+        setupFm();
     }
 
     void teardown() {
-        teardownContextAndRsa();
-        celixLauncher_stop();
-        celixLauncher_waitForShutdown();
+        teardownFm();
     }
 };
 

http://git-wip-us.apache.org/repos/asf/celix/blob/55e75be7/remote_services/remote_service_admin_dfi/tst/run_tests.cpp
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/tst/run_tests.cpp b/remote_services/remote_service_admin_dfi/tst/run_tests.cpp
index 81d1908..c5e960c 100644
--- a/remote_services/remote_service_admin_dfi/tst/run_tests.cpp
+++ b/remote_services/remote_service_admin_dfi/tst/run_tests.cpp
@@ -4,23 +4,6 @@
 #include <CppUTest/TestHarness.h>
 #include "CppUTest/CommandLineTestRunner.h"
 
-
-extern "C" {
-    #include <stdio.h>
-
-    #include "launcher.h"
-    #include "framework.h"
-
-    static int startCelix(void) {
-        celixLauncher_launch("config.properties");
-    }
-
-    static int stopCelix(void) {
-        celixLauncher_stop();
-        celixLauncher_waitForShutdown();
-    }
-}
-
 int main(int argc, char** argv) {
     return RUN_ALL_TESTS(argc, argv);
 }
\ No newline at end of file


[3/3] celix git commit: CELIX-237: A lot of work on the rsa dfi bundle and some needed refactoring for the remote_service_admin setup to support an non proxy approach.

Posted by pn...@apache.org.
CELIX-237: A lot of work on the rsa dfi bundle and some needed refactoring for the remote_service_admin setup to support an non proxy approach.

- Fixed issue in launcher (cleared curl to soon)
- update service registry/registration so that error status for the factory will be returned.
- Fixed issue in log_factory, concerning a wrong assumption of the provided struct.
- Added rpath for the launcher. Have to see if this works with install, but for now this make running deployment from ide (clion) possible.
    Just set the workdir to the deploy location and use celix as executable
- Removed schema properties from calculator example
- Created a generic export/import_registration header for the (OSGi) generic api
- Moved some export/import_registration/reference code the import/export_registration source files
- Small updated to dfi for additional getters
- Updated rsa_dfi. rsa_dfi now creates a proxy based on dfi and also dfi for export
- Added rsa_dfi cpputest

Note: Still alot of work is needed in the dfi. Also rsa etcd deployment has problem. shm not tested, cfg works fine.


Project: http://git-wip-us.apache.org/repos/asf/celix/repo
Commit: http://git-wip-us.apache.org/repos/asf/celix/commit/da86474f
Tree: http://git-wip-us.apache.org/repos/asf/celix/tree/da86474f
Diff: http://git-wip-us.apache.org/repos/asf/celix/diff/da86474f

Branch: refs/heads/feature/CELIX-237_rsa-ffi
Commit: da86474fb187707d8443a3aeb30ac965b74b1d43
Parents: 55e75be
Author: Pepijn Noltes <pe...@gmail.com>
Authored: Fri Aug 7 16:19:05 2015 +0200
Committer: Pepijn Noltes <pe...@gmail.com>
Committed: Fri Aug 7 16:19:05 2015 +0200

----------------------------------------------------------------------
 framework/private/src/service_registration.c    |    5 +-
 framework/private/src/service_registry.c        |    2 +-
 launcher/CMakeLists.txt                         |    4 +
 launcher/private/src/launcher.c                 |   29 +-
 log_service/private/src/log_factory.c           |    2 +-
 .../examples/calculator_service/CMakeLists.txt  |    5 +-
 ....apache.celix.calc.api.Calculator.descriptor |   11 +
 .../private/src/calculator_activator.c          |    1 -
 .../public/include/calculator_service.h         |   25 -
 remote_services/examples/deploy.cmake           |   40 +-
 .../private/include/export_registration_impl.h  |    3 -
 .../private/include/remote_service_admin_impl.h |   17 -
 .../private/src/export_registration_impl.c      |   22 +-
 .../private/src/import_registration_impl.c      |   17 +
 .../public/include/export_registration.h        |   22 +
 .../public/include/import_registration.h        |   22 +
 .../public/include/remote_service_admin.h       |    6 +-
 .../remote_service_admin_dfi/CMakeLists.txt     |   21 +-
 .../dynamic_function_interface/CMakeLists.txt   |   10 +-
 .../dynamic_function_interface/dyn_function.c   |   31 +-
 .../dynamic_function_interface/dyn_function.h   |    5 +-
 .../dynamic_function_interface/dyn_interface.c  |   22 +
 .../dynamic_function_interface/dyn_interface.h  |    9 +-
 .../dynamic_function_interface/dyn_type.c       |    2 +
 .../json_serializer.c                           |   21 +-
 .../json_serializer.h                           |    3 +
 .../tst/dyn_function_tests.cpp                  |   29 +
 .../tst/dyn_interface_tests.cpp                 |   10 +-
 .../private/include/export_registration_dfi.h   |   21 +
 .../private/include/import_registration_dfi.h   |   20 +
 .../include/remote_service_admin_http_impl.h    |   23 +-
 .../private/src/export_registration_dfi.c       |  159 +++
 .../private/src/import_registration_dfi.c       |  231 ++++
 .../src/remote_service_admin_activator.c        |    4 +-
 .../private/src/remote_service_admin_dfi.c      |  783 +++++++++++++
 .../private/src/remote_service_admin_impl.c     | 1085 ------------------
 .../remote_service_admin_dfi/tst/CMakeLists.txt |   18 +-
 .../tst/config.properties.in                    |    3 +-
 .../remote_service_admin_dfi/tst/rsa_tests.cpp  |  182 ++-
 .../private/src/remote_service_admin_impl.c     |  129 +--
 .../private/src/remote_service_admin_impl.c     |   26 +-
 41 files changed, 1734 insertions(+), 1346 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/celix/blob/da86474f/framework/private/src/service_registration.c
----------------------------------------------------------------------
diff --git a/framework/private/src/service_registration.c b/framework/private/src/service_registration.c
index 8e84d1a..c7eb010 100644
--- a/framework/private/src/service_registration.c
+++ b/framework/private/src/service_registration.c
@@ -146,13 +146,14 @@ celix_status_t serviceRegistration_unregister(service_registration_pt registrati
 }
 
 celix_status_t serviceRegistration_getService(service_registration_pt registration, bundle_pt bundle, void **service) {
+	int status = CELIX_SUCCESS;
     if (registration->isServiceFactory) {
         service_factory_pt factory = registration->serviceFactory;
-        factory->getService(registration->serviceFactory, bundle, registration, service);
+        status = factory->getService(factory->factory, bundle, registration, service);
     } else {
         (*service) = registration->svcObj;
     }
-    return CELIX_SUCCESS;
+    return status;
 }
 
 celix_status_t serviceRegistration_ungetService(service_registration_pt registration, bundle_pt bundle, void **service) {

http://git-wip-us.apache.org/repos/asf/celix/blob/da86474f/framework/private/src/service_registry.c
----------------------------------------------------------------------
diff --git a/framework/private/src/service_registry.c b/framework/private/src/service_registry.c
index 85639b4..ca1641b 100644
--- a/framework/private/src/service_registry.c
+++ b/framework/private/src/service_registry.c
@@ -502,7 +502,7 @@ celix_status_t serviceRegistry_getService(service_registry_pt registry, bundle_p
 	celixThreadMutex_unlock(&registry->mutex);
 
 	if ((usage != NULL) && (*service == NULL)) {
-		serviceRegistration_getService(registration, bundle, service);
+		status = serviceRegistration_getService(registration, bundle, service);
 	}
 	celixThreadMutex_lock(&registry->mutex);
 	if ((!serviceRegistration_isValid(registration)) || (*service == NULL)) {

http://git-wip-us.apache.org/repos/asf/celix/blob/da86474f/launcher/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/launcher/CMakeLists.txt b/launcher/CMakeLists.txt
index 6001eaf..dac0ce7 100644
--- a/launcher/CMakeLists.txt
+++ b/launcher/CMakeLists.txt
@@ -18,6 +18,10 @@ celix_subproject(LAUNCHER "Option to build the launcher" "ON" DEPS UTILS FRAMEWO
 if (LAUNCHER) 
     find_package(CURL REQUIRED)
 
+    SET(CMAKE_SKIP_BUILD_RPATH  FALSE) #TODO needed?
+    SET(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE) #TODO needed?
+    SET(CMAKE_INSTALL_RPATH "${PROJECT_BINARY_DIR}/framework" "${PROJECT_BINARY_DIR}/utils")
+
     include_directories(public/include)
     
     add_executable(celix

http://git-wip-us.apache.org/repos/asf/celix/blob/da86474f/launcher/private/src/launcher.c
----------------------------------------------------------------------
diff --git a/launcher/private/src/launcher.c b/launcher/private/src/launcher.c
index 432c709..a6297a0 100644
--- a/launcher/private/src/launcher.c
+++ b/launcher/private/src/launcher.c
@@ -113,7 +113,6 @@ int celixLauncher_launchWithStream(FILE *stream, framework_pt *framework) {
                 char *save_ptr = NULL;
                 linked_list_pt bundles;
                 array_list_pt installed = NULL;
-                bundle_pt bundle = NULL;
                 bundle_context_pt context = NULL;
                 linked_list_iterator_pt iter = NULL;
                 unsigned int i;
@@ -128,8 +127,7 @@ int celixLauncher_launchWithStream(FILE *stream, framework_pt *framework) {
                 // First install all bundles
                 // Afterwards start them
                 arrayList_create(&installed);
-                framework_getFrameworkBundle(*framework, &bundle);
-                bundle_getContext(bundle, &context);
+                bundle_getContext(fwBundle, &context);
                 iter = linkedListIterator_create(bundles, 0);
                 while (linkedListIterator_hasNext(iter)) {
                     bundle_pt current = NULL;
@@ -159,18 +157,7 @@ int celixLauncher_launchWithStream(FILE *stream, framework_pt *framework) {
             printf("Problem creating framework\n");
         }
 
-#ifdef WITH_APR
-	apr_pool_destroy(memoryPool);
-	apr_terminate();
-#endif
-
-
-#ifndef CELIX_NO_CURLINIT
-        // Cleanup Curl
-        curl_global_cleanup();
-#endif
-
-        printf("Launcher: Exit\n");
+        printf("Launcher: Framework Started\n");
     }
 
     return status;
@@ -182,6 +169,18 @@ void celixLauncher_waitForShutdown(framework_pt framework) {
 
 void celixLauncher_destroy(framework_pt framework) {
     framework_destroy(framework);
+
+    #ifdef WITH_APR
+        apr_pool_destroy(memoryPool);
+        apr_terminate();
+    #endif
+
+    #ifndef CELIX_NO_CURLINIT
+        // Cleanup Curl
+        curl_global_cleanup();
+    #endif
+
+    printf("Launcher: Exit\n");
 }
 
 void celixLauncher_stop(framework_pt framework) {

http://git-wip-us.apache.org/repos/asf/celix/blob/da86474f/log_service/private/src/log_factory.c
----------------------------------------------------------------------
diff --git a/log_service/private/src/log_factory.c b/log_service/private/src/log_factory.c
index 7ea5b2f..d188044 100644
--- a/log_service/private/src/log_factory.c
+++ b/log_service/private/src/log_factory.c
@@ -72,7 +72,7 @@ celix_status_t logFactory_destroy(service_factory_pt *factory) {
 
 
 celix_status_t logFactory_getService(void *factory, bundle_pt bundle, service_registration_pt registration, void **service) {
-    log_service_factory_pt log_factory = ((service_factory_pt) factory)->factory;
+    log_service_factory_pt log_factory = factory;
     log_service_pt log_service = NULL;
     log_service_data_pt log_service_data = NULL;
 

http://git-wip-us.apache.org/repos/asf/celix/blob/da86474f/remote_services/examples/calculator_service/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/remote_services/examples/calculator_service/CMakeLists.txt b/remote_services/examples/calculator_service/CMakeLists.txt
index e17153e..91596ab 100644
--- a/remote_services/examples/calculator_service/CMakeLists.txt
+++ b/remote_services/examples/calculator_service/CMakeLists.txt
@@ -24,11 +24,14 @@ include_directories("public/include")
 SET(BUNDLE_SYMBOLICNAME "apache_celix_remoting_calculator_impl")
 SET(BUNDLE_VERSION "0.0.1")
 
-bundle(calculator SOURCES 
+    bundle(calculator SOURCES
 	private/src/calculator_impl
 	private/src/calculator_activator
     
     private/include/calculator_impl.h
+
+    FILES
+        org.apache.celix.calc.api.Calculator.descriptor
 )
 
 target_link_libraries(calculator celix_framework)

http://git-wip-us.apache.org/repos/asf/celix/blob/da86474f/remote_services/examples/calculator_service/org.apache.celix.calc.api.Calculator.descriptor
----------------------------------------------------------------------
diff --git a/remote_services/examples/calculator_service/org.apache.celix.calc.api.Calculator.descriptor b/remote_services/examples/calculator_service/org.apache.celix.calc.api.Calculator.descriptor
new file mode 100644
index 0000000..711df0b
--- /dev/null
+++ b/remote_services/examples/calculator_service/org.apache.celix.calc.api.Calculator.descriptor
@@ -0,0 +1,11 @@
+:header
+type=interface
+name=calculator
+version=1.0.0
+:annotations
+classname=org.example.Calculator
+:types
+:methods
+add(DD)D=add(PDD*D)N
+sub(DD)D=sub(PDD*D)N
+sqrt(D)D=sqrt(PD*D)N

http://git-wip-us.apache.org/repos/asf/celix/blob/da86474f/remote_services/examples/calculator_service/private/src/calculator_activator.c
----------------------------------------------------------------------
diff --git a/remote_services/examples/calculator_service/private/src/calculator_activator.c b/remote_services/examples/calculator_service/private/src/calculator_activator.c
index a4dfa46..13ea995 100644
--- a/remote_services/examples/calculator_service/private/src/calculator_activator.c
+++ b/remote_services/examples/calculator_service/private/src/calculator_activator.c
@@ -75,7 +75,6 @@ celix_status_t bundleActivator_start(void * userData, bundle_context_pt context)
 
 			properties = properties_create();
 			properties_set(properties, (char *) OSGI_RSA_SERVICE_EXPORTED_INTERFACES, (char *) CALCULATOR_SERVICE);
-      properties_set(properties, (char *) "protocol.schema", (char *)CALC_SCHEMA);
 
                         bundleContext_registerService(context, (char *) CALCULATOR_SERVICE, activator->service, properties, &activator->calculatorReg);
 

http://git-wip-us.apache.org/repos/asf/celix/blob/da86474f/remote_services/examples/calculator_service/public/include/calculator_service.h
----------------------------------------------------------------------
diff --git a/remote_services/examples/calculator_service/public/include/calculator_service.h b/remote_services/examples/calculator_service/public/include/calculator_service.h
index 964653e..8e2f0dc 100644
--- a/remote_services/examples/calculator_service/public/include/calculator_service.h
+++ b/remote_services/examples/calculator_service/public/include/calculator_service.h
@@ -35,31 +35,6 @@ typedef struct calculator *calculator_pt;
 
 typedef struct calculator_service *calculator_service_pt;
 
-#define CALC_SCHEMA "[\"add(DD)D\",\"sub(DD)D\",\"sqrt(D)D\"]"
-
-/*
-purpose different schema setup
-{
-  "methods" : [ "add(DD)D", "sub(DD)D", "sqrt(D)D", abc(Labc_input;)D", sum([D)D" ],
-  "types" : {
-    "abc_input" : "DDD a b c"
-  }
-} 
-
-struct abc_input {
-    double a;
-    double b;
-    double c;
-}
-
-//for [D the following struct layout will be assumed
-struct double_sequence {
-    size_t _max;
-    size_t _length;
-    double *buffer;
-};
-*/
-
 /*
  * The calculator service definition corresponds to the following Java interface:
  *

http://git-wip-us.apache.org/repos/asf/celix/blob/da86474f/remote_services/examples/deploy.cmake
----------------------------------------------------------------------
diff --git a/remote_services/examples/deploy.cmake b/remote_services/examples/deploy.cmake
index 0b17811..0515917 100644
--- a/remote_services/examples/deploy.cmake
+++ b/remote_services/examples/deploy.cmake
@@ -16,10 +16,44 @@
 # under the License.
 is_enabled(RSA_EXAMPLES)
 if (RSA_EXAMPLES)
+    is_enabled(RSA_REMOTE_SERVICE_ADMIN_HTTP)
+    if (RSA_REMOTE_SERVICE_ADMIN_HTTP)
+        is_enabled(RSA_DISCOVERY_CONFIGURED)
+        if (RSA_DISCOVERY_CONFIGURED)
+            deploy("remote-services-cfg" BUNDLES discovery_configured topology_manager remote_service_admin_http calculator shell shell_tui log_service log_writer
+                                         ENDPOINTS
+                                            org.apache.celix.calc.api.Calculator_endpoint
+                                            org.apache.celix.calc.api.Calculator2_endpoint
+                                         PROPERTIES
+                                            RSA_PORT=8001
+                                            DISCOVERY_CFG_POLL_ENDPOINTS=http://localhost:8082/org.apache.celix.discovery.configured
+                                            DISCOVERY_CFG_SERVER_PORT=8081)
+            deploy("remote-services-cfg-client" BUNDLES topology_manager remote_service_admin_http shell shell_tui log_service log_writer calculator_shell discovery_configured
+                                                ENDPOINTS org.apache.celix.calc.api.Calculator_proxy org.apache.celix.calc.api.Calculator2_proxy
+                                            PROPERTIES
+                                                RSA_PORT=8002
+                                                DISCOVERY_CFG_POLL_ENDPOINTS=http://localhost:8081/org.apache.celix.discovery.configured
+                                                DISCOVERY_CFG_SERVER_PORT=8082)
+        endif ()
+    endif ()
+
+    is_enabled(RSA_REMOTE_SERVICE_ADMIN_SHM)
+    if (RSA_REMOTE_SERVICE_ADMIN_SHM)
+        is_enabled(RSA_DISCOVERY_SHM)
+        if (RSA_DISCOVERY_SHM)
+            deploy("remote-services-shm" BUNDLES discovery_shm topology_manager remote_service_admin_shm calculator shell shell_tui log_service log_writer
+                                         ENDPOINTS org.apache.celix.calc.api.Calculator_endpoint)
+            deploy("remote-services-shm-client" BUNDLES topology_manager remote_service_admin_shm shell shell_tui log_service log_writer calculator_shell discovery_shm
+                                                ENDPOINTS org.apache.celix.calc.api.Calculator_proxy)
+        endif ()
+    endif ()
+
     is_enabled(RSA_DISCOVERY_ETCD)
     if (RSA_DISCOVERY_ETCD)
-        deploy("remote-services-etcd" BUNDLES discovery_etcd topology_manager remote_service_admin_http calculator shell shell_tui log_service log_writer)
-        deploy("remote-services-etcd-client" BUNDLES topology_manager remote_service_admin_http shell shell_tui log_service log_writer calculator_shell discovery_etcd)
+        deploy("remote-services-etcd" BUNDLES discovery_etcd topology_manager remote_service_admin_http calculator shell shell_tui log_service log_writer
+                                     ENDPOINTS org.apache.celix.calc.api.Calculator_endpoint)
+        deploy("remote-services-etcd-client" BUNDLES topology_manager remote_service_admin_http shell shell_tui log_service log_writer calculator_shell discovery_etcd
+                                            ENDPOINTS org.apache.celix.calc.api.Calculator_proxy)
     endif ()
 
-endif (RSA_EXAMPLES)
+endif (RSA_EXAMPLES)
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/celix/blob/da86474f/remote_services/remote_service_admin/private/include/export_registration_impl.h
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin/private/include/export_registration_impl.h b/remote_services/remote_service_admin/private/include/export_registration_impl.h
index ed38684..bb276f9 100644
--- a/remote_services/remote_service_admin/private/include/export_registration_impl.h
+++ b/remote_services/remote_service_admin/private/include/export_registration_impl.h
@@ -53,9 +53,6 @@ struct export_registration {
 celix_status_t exportRegistration_create(log_helper_pt helper, service_reference_pt reference, endpoint_description_pt endpoint, remote_service_admin_pt rsa, bundle_context_pt context, export_registration_pt *registration);
 celix_status_t exportRegistration_destroy(export_registration_pt *registration);
 celix_status_t exportRegistration_open(export_registration_pt registration);
-celix_status_t exportRegistration_close(export_registration_pt registration);
-celix_status_t exportRegistration_getException(export_registration_pt registration);
-celix_status_t exportRegistration_getExportReference(export_registration_pt registration, export_reference_pt *reference);
 
 celix_status_t exportRegistration_setEndpointDescription(export_registration_pt registration, endpoint_description_pt endpointDescription);
 celix_status_t exportRegistration_startTracking(export_registration_pt registration);

http://git-wip-us.apache.org/repos/asf/celix/blob/da86474f/remote_services/remote_service_admin/private/include/remote_service_admin_impl.h
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin/private/include/remote_service_admin_impl.h b/remote_services/remote_service_admin/private/include/remote_service_admin_impl.h
index 10b012e..b28757b 100644
--- a/remote_services/remote_service_admin/private/include/remote_service_admin_impl.h
+++ b/remote_services/remote_service_admin/private/include/remote_service_admin_impl.h
@@ -32,16 +32,6 @@
 #define BUNDLE_STORE_PROPERTY_NAME "ENDPOINTS"
 #define DEFAULT_BUNDLE_STORE "endpoints"
 
-struct export_reference {
-	endpoint_description_pt endpoint;
-	service_reference_pt reference;
-};
-
-struct import_reference {
-	endpoint_description_pt endpoint;
-	service_reference_pt reference;
-};
-
 celix_status_t remoteServiceAdmin_create(bundle_context_pt context, remote_service_admin_pt *admin);
 celix_status_t remoteServiceAdmin_destroy(remote_service_admin_pt *admin);
 
@@ -54,13 +44,6 @@ celix_status_t remoteServiceAdmin_getImportedEndpoints(remote_service_admin_pt a
 celix_status_t remoteServiceAdmin_importService(remote_service_admin_pt admin, endpoint_description_pt endpoint, import_registration_pt *registration);
 celix_status_t remoteServiceAdmin_removeImportedService(remote_service_admin_pt admin, import_registration_pt registration);
 
-
-celix_status_t exportReference_getExportedEndpoint(export_reference_pt reference, endpoint_description_pt *endpoint);
-celix_status_t exportReference_getExportedService(export_reference_pt reference);
-
-celix_status_t importReference_getImportedEndpoint(import_reference_pt reference);
-celix_status_t importReference_getImportedService(import_reference_pt reference);
-
 celix_status_t remoteServiceAdmin_destroyEndpointDescription(endpoint_description_pt *description);
 
 #endif /* REMOTE_SERVICE_ADMIN_IMPL_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/da86474f/remote_services/remote_service_admin/private/src/export_registration_impl.c
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin/private/src/export_registration_impl.c b/remote_services/remote_service_admin/private/src/export_registration_impl.c
index d6ce934..18cff6c 100644
--- a/remote_services/remote_service_admin/private/src/export_registration_impl.c
+++ b/remote_services/remote_service_admin/private/src/export_registration_impl.c
@@ -32,6 +32,12 @@
 #include "export_registration_impl.h"
 #include "remote_service_admin_impl.h"
 
+
+struct export_reference {
+	endpoint_description_pt endpoint;
+	service_reference_pt reference;
+};
+
 celix_status_t exportRegistration_endpointAdding(void * handle, service_reference_pt reference, void **service);
 celix_status_t exportRegistration_endpointAdded(void * handle, service_reference_pt reference, void *service);
 celix_status_t exportRegistration_endpointModified(void * handle, service_reference_pt reference, void *service);
@@ -175,7 +181,6 @@ celix_status_t exportRegistration_endpointRemoved(void * handle, service_referen
 
 celix_status_t exportRegistration_open(export_registration_pt registration) {
 	celix_status_t status = CELIX_SUCCESS;
-  /*
 	char *bundleStore = NULL;
 
 	bundleContext_getProperty(registration->context, BUNDLE_STORE_PROPERTY_NAME, &bundleStore);
@@ -193,7 +198,6 @@ celix_status_t exportRegistration_open(export_registration_pt registration) {
 		if (status == CELIX_SUCCESS) {
 		}
 	}
-  */
 
 	return status;
 }
@@ -240,3 +244,17 @@ celix_status_t exportRegistration_setEndpointDescription(export_registration_pt
 
 	return status;
 }
+
+celix_status_t exportReference_getExportedEndpoint(export_reference_pt reference, endpoint_description_pt *endpoint) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	*endpoint = reference->endpoint;
+
+	return status;
+}
+
+celix_status_t exportReference_getExportedService(export_reference_pt reference) {
+	celix_status_t status = CELIX_SUCCESS;
+	return status;
+}
+

http://git-wip-us.apache.org/repos/asf/celix/blob/da86474f/remote_services/remote_service_admin/private/src/import_registration_impl.c
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin/private/src/import_registration_impl.c b/remote_services/remote_service_admin/private/src/import_registration_impl.c
index ecf6e09..a9eb70e 100644
--- a/remote_services/remote_service_admin/private/src/import_registration_impl.c
+++ b/remote_services/remote_service_admin/private/src/import_registration_impl.c
@@ -34,6 +34,12 @@
 #include "import_registration_impl.h"
 #include "remote_service_admin_impl.h"
 
+struct import_reference {
+	endpoint_description_pt endpoint;
+	service_reference_pt reference;
+};
+
+
 
 celix_status_t importRegistration_proxyFactoryAdding(void * handle, service_reference_pt reference, void **service);
 celix_status_t importRegistration_proxyFactoryAdded(void * handle, service_reference_pt reference, void *service);
@@ -254,3 +260,14 @@ celix_status_t importRegistration_getImportReference(import_registration_pt regi
 
 	return status;
 }
+
+
+celix_status_t importReference_getImportedEndpoint(import_reference_pt reference) {
+	celix_status_t status = CELIX_SUCCESS;
+	return status;
+}
+
+celix_status_t importReference_getImportedService(import_reference_pt reference) {
+	celix_status_t status = CELIX_SUCCESS;
+	return status;
+}

http://git-wip-us.apache.org/repos/asf/celix/blob/da86474f/remote_services/remote_service_admin/public/include/export_registration.h
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin/public/include/export_registration.h b/remote_services/remote_service_admin/public/include/export_registration.h
new file mode 100644
index 0000000..9332274
--- /dev/null
+++ b/remote_services/remote_service_admin/public/include/export_registration.h
@@ -0,0 +1,22 @@
+/*
+ * Licensed under Apache License v2. See LICENSE for more information.
+ */
+#ifndef CELIX_EXPORT_REGISTRATION_H
+#define CELIX_EXPORT_REGISTRATION_H
+
+#include "celix_errno.h"
+#include "endpoint_description.h"
+#include "service_reference.h"
+
+typedef struct export_registration *export_registration_pt;
+
+typedef struct export_reference *export_reference_pt;
+
+celix_status_t exportRegistration_close(export_registration_pt registration);
+celix_status_t exportRegistration_getException(export_registration_pt registration);
+celix_status_t exportRegistration_getExportReference(export_registration_pt registration, export_reference_pt *reference);
+
+celix_status_t exportReference_getExportedEndpoint(export_reference_pt reference, endpoint_description_pt *endpoint);
+celix_status_t exportReference_getExportedService(export_reference_pt reference);
+
+#endif //CELIX_EXPORT_REGISTRATION_H

http://git-wip-us.apache.org/repos/asf/celix/blob/da86474f/remote_services/remote_service_admin/public/include/import_registration.h
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin/public/include/import_registration.h b/remote_services/remote_service_admin/public/include/import_registration.h
new file mode 100644
index 0000000..ef8193f
--- /dev/null
+++ b/remote_services/remote_service_admin/public/include/import_registration.h
@@ -0,0 +1,22 @@
+/*
+ * Licensed under Apache License v2. See LICENSE for more information.
+ */
+#ifndef CELIX_IMPORT_REGISTRATION_H
+#define CELIX_IMPORT_REGISTRATION_H
+
+#include "celix_errno.h"
+#include "endpoint_description.h"
+#include "service_reference.h"
+
+typedef struct import_registration *import_registration_pt;
+
+typedef struct import_reference *import_reference_pt;
+
+celix_status_t importRegistration_close(import_registration_pt registration);
+celix_status_t importRegistration_getException(import_registration_pt registration);
+celix_status_t importRegistration_getImportReference(import_registration_pt registration, import_reference_pt *reference);
+
+celix_status_t importReference_getImportedEndpoint(import_reference_pt reference);
+celix_status_t importReference_getImportedService(import_reference_pt reference);
+
+#endif //CELIX_IMPORT_REGISTRATION_H

http://git-wip-us.apache.org/repos/asf/celix/blob/da86474f/remote_services/remote_service_admin/public/include/remote_service_admin.h
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin/public/include/remote_service_admin.h b/remote_services/remote_service_admin/public/include/remote_service_admin.h
index b5b42ae..274f2e4 100644
--- a/remote_services/remote_service_admin/public/include/remote_service_admin.h
+++ b/remote_services/remote_service_admin/public/include/remote_service_admin.h
@@ -29,13 +29,11 @@
 
 #include "endpoint_listener.h"
 #include "service_reference.h"
+#include "export_registration.h"
+#include "import_registration.h"
 
 #define OSGI_RSA_REMOTE_SERVICE_ADMIN "remote_service_admin"
 
-typedef struct export_reference *export_reference_pt;
-typedef struct export_registration *export_registration_pt;
-typedef struct import_reference *import_reference_pt;
-typedef struct import_registration *import_registration_pt;
 typedef struct import_registration_factory *import_registration_factory_pt;
 typedef struct remote_service_admin *remote_service_admin_pt;
 

http://git-wip-us.apache.org/repos/asf/celix/blob/da86474f/remote_services/remote_service_admin_dfi/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/CMakeLists.txt b/remote_services/remote_service_admin_dfi/CMakeLists.txt
index 3937605..b7a66f3 100644
--- a/remote_services/remote_service_admin_dfi/CMakeLists.txt
+++ b/remote_services/remote_service_admin_dfi/CMakeLists.txt
@@ -22,27 +22,38 @@ if (RSA_REMOTE_SERVICE_ADMIN_DFI)
 
     add_subdirectory(dynamic_function_interface)
 
+    include_directories(private/include)
+
     include_directories(${FFI_INCLUDE_DIRS})
     include_directories(${CURL_INCLUDE_DIRS})
     include_directories(${JANSSON_INCLUDE_DIRS})
+
     include_directories("${PROJECT_SOURCE_DIR}/utils/public/include")
+
     include_directories("${PROJECT_SOURCE_DIR}/log_service/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")
     include_directories("${PROJECT_SOURCE_DIR}/remote_services/remote_service_admin_http/private/include")
+
     include_directories("${PROJECT_SOURCE_DIR}/remote_services/endpoint_listener/public/include")
+    include_directories("${PROJECT_SOURCE_DIR}/remote_services/remote_service_admin_dfi/dynamic_function_interface")
+    include_directories("${PROJECT_SOURCE_DIR}/remote_services/examples/calculator_service/public/include")
     
     SET_HEADER(BUNDLE_SYMBOLICNAME "apache_celix_remote_service_admin_dfi")
     SET(BUNDLE_VERSION "0.0.1")
     SET_HEADERS("Bundle-Name: Apache Celix Remote Service Admin HTTP for dynamic function interface")
     
     bundle(remote_service_admin_dfi SOURCES
-        private/src/remote_service_admin_impl
-        private/src/remote_service_admin_activator
-        ${PROJECT_SOURCE_DIR}/remote_services/remote_service_admin/private/src/export_registration_impl
-        ${PROJECT_SOURCE_DIR}/remote_services/remote_service_admin/private/src/import_registration_impl
+        private/src/remote_service_admin_dfi.c
+        private/src/remote_service_admin_activator.c
+        private/src/export_registration_dfi.c
+        private/src/import_registration_dfi.c
+
+        ${PROJECT_SOURCE_DIR}/remote_services/remote_service_admin/private/src/endpoint_description.c
+
         ${PROJECT_SOURCE_DIR}/remote_services/utils/private/src/civetweb.c
         ${PROJECT_SOURCE_DIR}/log_service/public/src/log_helper.c
     )

http://git-wip-us.apache.org/repos/asf/celix/blob/da86474f/remote_services/remote_service_admin_dfi/dynamic_function_interface/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/dynamic_function_interface/CMakeLists.txt b/remote_services/remote_service_admin_dfi/dynamic_function_interface/CMakeLists.txt
index ae1d5c3..0dad5e1 100644
--- a/remote_services/remote_service_admin_dfi/dynamic_function_interface/CMakeLists.txt
+++ b/remote_services/remote_service_admin_dfi/dynamic_function_interface/CMakeLists.txt
@@ -31,7 +31,7 @@ target_link_libraries(dfi ${FFI_LIBRARIES} ${JANSSON_LIBRARY})
 
 
 #if (FRAMEWORK_TESTS) TODO
-	add_executable(dfi_tests
+	add_executable(test_dfi
 	    tst/dyn_type_tests.cpp
 	    tst/dyn_function_tests.cpp
 	    tst/dyn_closure_tests.cpp
@@ -39,14 +39,14 @@ target_link_libraries(dfi ${FFI_LIBRARIES} ${JANSSON_LIBRARY})
 	    tst/json_serializer_tests.cpp
 	    tst/run_tests.cpp
 	)
-	target_link_libraries(dfi_tests dfi ${FFI_LIBRARIES} ${CPPUTEST_LIBRARY} ${JANSSON_LIBRARY}) 
+	target_link_libraries(test_dfi dfi ${FFI_LIBRARIES} ${CPPUTEST_LIBRARY} ${JANSSON_LIBRARY})
 
 	add_custom_target(copy-input 
 	    COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_CURRENT_LIST_DIR}/schemas schemas
 	    COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_CURRENT_LIST_DIR}/descriptors descriptors
 	)
-	add_dependencies(dfi_tests copy-input)
+	add_dependencies(test_dfi copy-input)
 
-    add_test(NAME run_dfi_tests COMMAND dfi_tests)
-	SETUP_TARGET_FOR_COVERAGE(dfi_tests_cov dfi_tests ${CMAKE_BINARY_DIR}/coverage/dfi)
+    add_test(NAME run_test_dfi COMMAND test_dfi)
+	SETUP_TARGET_FOR_COVERAGE(test_dfi_cov test_dfi ${CMAKE_BINARY_DIR}/coverage/dfi)
 #endif()

http://git-wip-us.apache.org/repos/asf/celix/blob/da86474f/remote_services/remote_service_admin_dfi/dynamic_function_interface/dyn_function.c
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/dynamic_function_interface/dyn_function.c b/remote_services/remote_service_admin_dfi/dynamic_function_interface/dyn_function.c
index 0ae2a8a..f80d26f 100644
--- a/remote_services/remote_service_admin_dfi/dynamic_function_interface/dyn_function.c
+++ b/remote_services/remote_service_admin_dfi/dynamic_function_interface/dyn_function.c
@@ -15,8 +15,6 @@
 #include "dyn_type.h"
 #include "dfi_log_util.h"
 
-DFI_SETUP_LOG(dynFunction)
-
 struct _dyn_function_type {
     char *name;
     struct types_head *refTypes; //NOTE not owned
@@ -45,6 +43,8 @@ static const int MEM_ERROR = 1;
 static const int PARSE_ERROR = 2;
 static const int ERROR = 2;
 
+DFI_SETUP_LOG(dynFunction)
+
 static int dynFunction_initCif(dyn_function_type *dynFunc);
 static int dynFunction_parseDescriptor(dyn_function_type *dynFunc, FILE *descriptor);
 static void dynFunction_ffiBind(ffi_cif *cif, void *ret, void *args[], void *userData); 
@@ -240,4 +240,31 @@ int dynFunction_getFnPointer(dyn_function_type *dynFunc, void (**fn)(void)) {
     return status;
 }
 
+int dynFunction_nrOfArguments(dyn_function_type *dynFunc) {
+    int count = 0;
+    dyn_function_argument_type *entry = NULL;
+    TAILQ_FOREACH(entry, &dynFunc->arguments, entries) {
+        count += 1;
+    }
+    return count;
+}
+
+dyn_type *dynFunction_argumentTypeForIndex(dyn_function_type *dynFunc, int argumentNr) {
+    dyn_type *result = NULL;
+    int index = 0;
+    dyn_function_argument_type *entry = NULL;
+    TAILQ_FOREACH(entry, &dynFunc->arguments, entries) {
+        if (index == argumentNr) {
+            result = entry->type;
+            break;
+        }
+        index +=1;
+    }
+    return result;
+}
+
+dyn_type * dynFunction_returnType(dyn_function_type *dynFunction) {
+    return dynFunction->funcReturn;
+}
+
 

http://git-wip-us.apache.org/repos/asf/celix/blob/da86474f/remote_services/remote_service_admin_dfi/dynamic_function_interface/dyn_function.h
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/dynamic_function_interface/dyn_function.h b/remote_services/remote_service_admin_dfi/dynamic_function_interface/dyn_function.h
index 2d5d6bb..b1abfb6 100644
--- a/remote_services/remote_service_admin_dfi/dynamic_function_interface/dyn_function.h
+++ b/remote_services/remote_service_admin_dfi/dynamic_function_interface/dyn_function.h
@@ -15,13 +15,16 @@
  */
 
 typedef struct _dyn_function_type dyn_function_type;
-typedef struct _dyn_closure_type dyn_closure_type;
 
 DFI_SETUP_LOG_HEADER(dynFunction);
 
 int dynFunction_parse(FILE *descriptorStream, struct types_head *refTypes, dyn_function_type **dynFunc);
 int dynFunction_parseWithStr(const char *descriptor, struct types_head *refTypes, dyn_function_type **dynFunc);
 
+int dynFunction_nrOfArguments(dyn_function_type *dynFunc);
+dyn_type *dynFunction_argumentTypeForIndex(dyn_function_type *dynFunc, int argumentNr);
+dyn_type * dynFunction_returnType(dyn_function_type *dynFunction);
+
 void dynFunction_destroy(dyn_function_type *dynFunc);
 int dynFunction_call(dyn_function_type *dynFunc, void(*fn)(void), void *returnValue, void **argValues);
 

http://git-wip-us.apache.org/repos/asf/celix/blob/da86474f/remote_services/remote_service_admin_dfi/dynamic_function_interface/dyn_interface.c
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/dynamic_function_interface/dyn_interface.c b/remote_services/remote_service_admin_dfi/dynamic_function_interface/dyn_interface.c
index 878cfea..5cd7104 100644
--- a/remote_services/remote_service_admin_dfi/dynamic_function_interface/dyn_interface.c
+++ b/remote_services/remote_service_admin_dfi/dynamic_function_interface/dyn_interface.c
@@ -12,6 +12,13 @@
 
 DFI_SETUP_LOG(dynInterface);
 
+struct _dyn_interface_type {
+    struct namvals_head header;
+    struct namvals_head annotations;
+    struct types_head types;
+    struct methods_head methods;
+};
+
 const int OK = 0;
 const int ERROR = 1;
 
@@ -369,3 +376,18 @@ static int dynInterface_getEntryForHead(struct namvals_head *head, const char *n
     }
     return status;
 }
+
+int dynInterface_methods(dyn_interface_type *intf, struct methods_head **list) {
+    int status = OK;
+    *list = &intf->methods;
+    return status;
+}
+
+int dynInterface_nrOfMethods(dyn_interface_type *intf) {
+    int count = 0;
+    struct method_entry *entry = NULL;
+    TAILQ_FOREACH(entry, &intf->methods, entries) {
+        count +=1;
+    }
+    return count;
+}

http://git-wip-us.apache.org/repos/asf/celix/blob/da86474f/remote_services/remote_service_admin_dfi/dynamic_function_interface/dyn_interface.h
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/dynamic_function_interface/dyn_interface.h b/remote_services/remote_service_admin_dfi/dynamic_function_interface/dyn_interface.h
index 0b0898f..f005bff 100644
--- a/remote_services/remote_service_admin_dfi/dynamic_function_interface/dyn_interface.h
+++ b/remote_services/remote_service_admin_dfi/dynamic_function_interface/dyn_interface.h
@@ -29,18 +29,11 @@ TAILQ_HEAD(methods_head, method_entry);
 
 typedef struct _dyn_interface_type dyn_interface_type;
 
-struct _dyn_interface_type {
-    struct namvals_head header;
-    struct namvals_head annotations;
-    struct types_head types;
-    struct methods_head methods;
-};
 
 struct method_entry {
     int index;
     char *id;
     char *name;
-
     dyn_function_type *dynFunc;
 
     TAILQ_ENTRY(method_entry) entries; 
@@ -53,6 +46,8 @@ int dynInterface_getName(dyn_interface_type *intf, char **name);
 int dynInterface_getVersion(dyn_interface_type *intf, char **version);
 int dynInterface_getHeaderEntry(dyn_interface_type *intf, const char *name, char **value);
 int dynInterface_getAnnotationEntry(dyn_interface_type *intf, const char *name, char **value);
+int dynInterface_methods(dyn_interface_type *intf, struct methods_head **list);
+int dynInterface_nrOfMethods(dyn_interface_type *intf);
 
 
 #endif

http://git-wip-us.apache.org/repos/asf/celix/blob/da86474f/remote_services/remote_service_admin_dfi/dynamic_function_interface/dyn_type.c
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/dynamic_function_interface/dyn_type.c b/remote_services/remote_service_admin_dfi/dynamic_function_interface/dyn_type.c
index 2946607..c8a9adb 100644
--- a/remote_services/remote_service_admin_dfi/dynamic_function_interface/dyn_type.c
+++ b/remote_services/remote_service_admin_dfi/dynamic_function_interface/dyn_type.c
@@ -763,6 +763,8 @@ static ffi_type * dynType_ffiTypeFor(int c) {
             break;
         case 'P' :
             type = &ffi_type_pointer;
+        case 'V' :
+            type = &ffi_type_void;
             break;
     }
     return type;

http://git-wip-us.apache.org/repos/asf/celix/blob/da86474f/remote_services/remote_service_admin_dfi/dynamic_function_interface/json_serializer.c
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/dynamic_function_interface/json_serializer.c b/remote_services/remote_service_admin_dfi/dynamic_function_interface/json_serializer.c
index 614e948..c6bda91 100644
--- a/remote_services/remote_service_admin_dfi/dynamic_function_interface/json_serializer.c
+++ b/remote_services/remote_service_admin_dfi/dynamic_function_interface/json_serializer.c
@@ -9,7 +9,7 @@
 #include <stdint.h>
 #include <string.h>
 
-static int jsonSerializer_createObject(dyn_type *type, json_t *object, void **result);
+static int jsonSerializer_createType(dyn_type *type, json_t *object, void **result);
 static int jsonSerializer_parseObject(dyn_type *type, json_t *object, void *inst);
 static int jsonSerializer_parseObjectMember(dyn_type *type, const char *name, json_t *val, void *inst);
 static int jsonSerializer_parseSequence(dyn_type *seq, json_t *array, void *seqLoc);
@@ -34,12 +34,7 @@ int jsonSerializer_deserialize(dyn_type *type, const char *input, void **result)
     json_t *root = json_loads(input, JSON_DECODE_ANY, &error);
 
     if (root != NULL) {
-        if (json_is_object(root)) {
-            status = jsonSerializer_createObject(type, root, result);
-        } else {
-            status = ERROR;
-            LOG_ERROR("Error expected root element to be an object");
-        }
+        status = jsonSerializer_deserializeJson(type, root, result);
         json_decref(root);
     } else {
         status = ERROR;
@@ -49,8 +44,12 @@ int jsonSerializer_deserialize(dyn_type *type, const char *input, void **result)
     return status;
 }
 
-static int jsonSerializer_createObject(dyn_type *type, json_t *object, void **result) {
-    assert(object != NULL);
+int jsonSerializer_deserializeJson(dyn_type *type, json_t *input, void **out) {
+    return jsonSerializer_createType(type, input, out);
+}
+
+static int jsonSerializer_createType(dyn_type *type, json_t *val, void **result) {
+    assert(val != NULL);
     int status = OK;
 
     void *inst = NULL;
@@ -58,7 +57,7 @@ static int jsonSerializer_createObject(dyn_type *type, json_t *object, void **re
 
     if (status == OK) {
         assert(inst != NULL);
-        status = jsonSerializer_parseObject(type, object, inst);
+        status = jsonSerializer_parseAny(type, inst, val);
 
         if (status != OK) {
             dynType_free(type, inst);
@@ -189,7 +188,7 @@ static int jsonSerializer_parseAny(dyn_type *type, void *loc, json_t *val) {
         case '*' :
             status = dynType_typedPointer_getTypedType(type, &subType);
             if (status == OK) {
-                status = jsonSerializer_createObject(subType, val, (void **)loc);
+                status = jsonSerializer_createType(subType, val, (void **) loc);
             }
             break;
         case 'P' :

http://git-wip-us.apache.org/repos/asf/celix/blob/da86474f/remote_services/remote_service_admin_dfi/dynamic_function_interface/json_serializer.h
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/dynamic_function_interface/json_serializer.h b/remote_services/remote_service_admin_dfi/dynamic_function_interface/json_serializer.h
index eb2e629..abfdd03 100644
--- a/remote_services/remote_service_admin_dfi/dynamic_function_interface/json_serializer.h
+++ b/remote_services/remote_service_admin_dfi/dynamic_function_interface/json_serializer.h
@@ -4,6 +4,7 @@
 #ifndef __JSON_SERIALIZER_H_
 #define __JSON_SERIALIZER_H_
 
+#include <jansson.h>
 #include "dfi_log_util.h"
 #include "dyn_type.h"
 
@@ -11,6 +12,8 @@
 DFI_SETUP_LOG_HEADER(jsonSerializer);
 
 int jsonSerializer_deserialize(dyn_type *type, const char *input, void **result);
+int jsonSerializer_deserializeJson(dyn_type *type, json_t *input, void **result);
+
 int jsonSerializer_serialize(dyn_type *type, void *input, char **output);
 
 #endif

http://git-wip-us.apache.org/repos/asf/celix/blob/da86474f/remote_services/remote_service_admin_dfi/dynamic_function_interface/tst/dyn_function_tests.cpp
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/dynamic_function_interface/tst/dyn_function_tests.cpp b/remote_services/remote_service_admin_dfi/dynamic_function_interface/tst/dyn_function_tests.cpp
index 410b3ec..9b681de 100644
--- a/remote_services/remote_service_admin_dfi/dynamic_function_interface/tst/dyn_function_tests.cpp
+++ b/remote_services/remote_service_admin_dfi/dynamic_function_interface/tst/dyn_function_tests.cpp
@@ -96,6 +96,31 @@ extern "C" {
         CHECK_EQUAL(2.2, returnVal);
         dynFunction_destroy(dynFunc);
     }
+
+    static void test_access_functions(void) {
+        dyn_function_type *dynFunc = NULL;
+        int rc;
+        rc = dynFunction_parseWithStr("add(D{DD a b}*D)V", NULL, &dynFunc);
+
+        CHECK_EQUAL(0, rc);
+
+        int nrOfArgs = dynFunction_nrOfArguments(dynFunc);
+        CHECK_EQUAL(3, nrOfArgs);
+
+        dyn_type *arg1 = dynFunction_argumentTypeForIndex(dynFunc, 1);
+        CHECK(arg1 != NULL);
+        CHECK_EQUAL('{', (char) dynType_descriptorType(arg1));
+
+        dyn_type *nonExist = dynFunction_argumentTypeForIndex(dynFunc, 10);
+        CHECK(nonExist == NULL);
+
+        dyn_type *returnType = dynFunction_returnType(dynFunc);
+        CHECK_EQUAL('V', (char) dynType_descriptorType(returnType));
+
+        dynFunction_destroy(dynFunc);
+    }
+
+
 }
 
 TEST_GROUP(DynFunctionTests) {
@@ -113,3 +138,7 @@ TEST(DynFunctionTests, DynFuncTest1) {
 TEST(DynFunctionTests, DynFuncTest2) {
     test_example2();
 }
+
+TEST(DynFunctionTests, DynFuncAccTest) {
+    test_access_functions();
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/celix/blob/da86474f/remote_services/remote_service_admin_dfi/dynamic_function_interface/tst/dyn_interface_tests.cpp
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/dynamic_function_interface/tst/dyn_interface_tests.cpp b/remote_services/remote_service_admin_dfi/dynamic_function_interface/tst/dyn_interface_tests.cpp
index 6453afd..679260f 100644
--- a/remote_services/remote_service_admin_dfi/dynamic_function_interface/tst/dyn_interface_tests.cpp
+++ b/remote_services/remote_service_admin_dfi/dynamic_function_interface/tst/dyn_interface_tests.cpp
@@ -57,7 +57,15 @@ extern "C" {
         status = dynInterface_getHeaderEntry(dynIntf, "nonExisting", &nonExist);
         CHECK(status != 0);
         CHECK(nonExist == NULL);
-        
+
+        struct methods_head *list = NULL;
+        status = dynInterface_methods(dynIntf, &list);
+        CHECK(status == 0);
+        CHECK(list != NULL);
+
+        int count = dynInterface_nrOfMethods(dynIntf);
+        CHECK_EQUAL(4, count);
+
         dynInterface_destroy(dynIntf);
     }
 

http://git-wip-us.apache.org/repos/asf/celix/blob/da86474f/remote_services/remote_service_admin_dfi/private/include/export_registration_dfi.h
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/private/include/export_registration_dfi.h b/remote_services/remote_service_admin_dfi/private/include/export_registration_dfi.h
new file mode 100644
index 0000000..4faf9b9
--- /dev/null
+++ b/remote_services/remote_service_admin_dfi/private/include/export_registration_dfi.h
@@ -0,0 +1,21 @@
+/**
+ * Licensed under Apache License v2. See LICENSE for more information.
+ */
+#ifndef CELIX_EXPORT_REGISTRATION_DFI_H
+#define CELIX_EXPORT_REGISTRATION_DFI_H
+
+
+#include "export_registration.h"
+#include "log_helper.h"
+#include "endpoint_description.h"
+
+celix_status_t exportRegistration_create(log_helper_pt helper, service_reference_pt reference, endpoint_description_pt endpoint, bundle_context_pt context, export_registration_pt *registration);
+celix_status_t exportRegistration_destroy(export_registration_pt registration);
+
+celix_status_t exportRegistration_start(export_registration_pt registration);
+celix_status_t exportRegistration_stop(export_registration_pt registration);
+
+celix_status_t exportRegistration_call(export_registration_pt export, char *data, int datalength, char **response, int *responseLength);
+
+
+#endif //CELIX_EXPORT_REGISTRATION_DFI_H

http://git-wip-us.apache.org/repos/asf/celix/blob/da86474f/remote_services/remote_service_admin_dfi/private/include/import_registration_dfi.h
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/private/include/import_registration_dfi.h b/remote_services/remote_service_admin_dfi/private/include/import_registration_dfi.h
new file mode 100644
index 0000000..d05375d
--- /dev/null
+++ b/remote_services/remote_service_admin_dfi/private/include/import_registration_dfi.h
@@ -0,0 +1,20 @@
+/**
+ * Licensed under Apache License v2. See LICENSE for more information.
+ */
+#ifndef CELIX_IMPORT_REGISTRATION_DFI_H
+#define CELIX_IMPORT_REGISTRATION_DFI_H
+
+#include "import_registration.h"
+
+#include <celix_errno.h>
+
+celix_status_t importRegistration_create(bundle_context_pt context, endpoint_description_pt  description, const char *classObject, import_registration_pt *import);
+void importRegistration_destroy(import_registration_pt import);
+
+celix_status_t importRegistration_start(import_registration_pt import);
+celix_status_t importRegistration_stop(import_registration_pt import);
+
+celix_status_t importRegistration_getService(import_registration_pt import, bundle_pt bundle, service_registration_pt registration, void **service);
+celix_status_t importRegistration_ungetService(import_registration_pt import, bundle_pt bundle, service_registration_pt registration, void **service);
+
+#endif //CELIX_IMPORT_REGISTRATION_DFI_H

http://git-wip-us.apache.org/repos/asf/celix/blob/da86474f/remote_services/remote_service_admin_dfi/private/include/remote_service_admin_http_impl.h
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/private/include/remote_service_admin_http_impl.h b/remote_services/remote_service_admin_dfi/private/include/remote_service_admin_http_impl.h
index dbf71c9..65ca83b 100644
--- a/remote_services/remote_service_admin_dfi/private/include/remote_service_admin_http_impl.h
+++ b/remote_services/remote_service_admin_dfi/private/include/remote_service_admin_http_impl.h
@@ -27,7 +27,7 @@
 #ifndef REMOTE_SERVICE_ADMIN_HTTP_IMPL_H_
 #define REMOTE_SERVICE_ADMIN_HTTP_IMPL_H_
 
-#include "remote_service_admin_impl.h"
+#include "remote_service_admin.h"
 #include "log_helper.h"
 #include "civetweb.h"
 
@@ -47,6 +47,27 @@ struct remote_service_admin {
 	struct mg_context *ctx;
 };
 
+
+celix_status_t remoteServiceAdmin_create(bundle_context_pt context, remote_service_admin_pt *admin);
+celix_status_t remoteServiceAdmin_destroy(remote_service_admin_pt *admin);
+
 celix_status_t remoteServiceAdmin_stop(remote_service_admin_pt admin);
+celix_status_t remoteServiceAdmin_send(remote_service_admin_pt rsa, endpoint_description_pt endpointDescription, char *methodSignature, char **reply, int* replyStatus);
+
+celix_status_t remoteServiceAdmin_exportService(remote_service_admin_pt admin, char *serviceId, properties_pt properties, array_list_pt *registrations);
+celix_status_t remoteServiceAdmin_removeExportedService(export_registration_pt registration);
+celix_status_t remoteServiceAdmin_getExportedServices(remote_service_admin_pt admin, array_list_pt *services);
+celix_status_t remoteServiceAdmin_getImportedEndpoints(remote_service_admin_pt admin, array_list_pt *services);
+celix_status_t remoteServiceAdmin_importService(remote_service_admin_pt admin, endpoint_description_pt endpoint, import_registration_pt *registration);
+celix_status_t remoteServiceAdmin_removeImportedService(remote_service_admin_pt admin, import_registration_pt registration);
+
+
+celix_status_t exportReference_getExportedEndpoint(export_reference_pt reference, endpoint_description_pt *endpoint);
+celix_status_t exportReference_getExportedService(export_reference_pt reference);
+
+celix_status_t importReference_getImportedEndpoint(import_reference_pt reference);
+celix_status_t importReference_getImportedService(import_reference_pt reference);
+
+celix_status_t remoteServiceAdmin_destroyEndpointDescription(endpoint_description_pt *description);
 
 #endif /* REMOTE_SERVICE_ADMIN_HTTP_IMPL_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/da86474f/remote_services/remote_service_admin_dfi/private/src/export_registration_dfi.c
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/private/src/export_registration_dfi.c b/remote_services/remote_service_admin_dfi/private/src/export_registration_dfi.c
new file mode 100644
index 0000000..7814d0d
--- /dev/null
+++ b/remote_services/remote_service_admin_dfi/private/src/export_registration_dfi.c
@@ -0,0 +1,159 @@
+/**
+ * Licensed under Apache License v2. See LICENSE for more information.
+ */
+#include <jansson.h>
+#include <dyn_interface.h>
+#include <json_serializer.h>
+#include "export_registration.h"
+#include "export_registration_dfi.h"
+#include "endpoint_description.h"
+
+struct export_registration {
+    endpoint_description_pt endpointDescription;
+    service_reference_pt reference;
+    dyn_interface_type *intf;
+    void *service;
+    bundle_pt bundle;
+
+    bool closed;
+};
+
+struct export_reference {
+    endpoint_description_pt endpoint;
+    service_reference_pt reference;
+};
+
+typedef void (*GEN_FUNC_TYPE)(void);
+
+struct generic_service_layout {
+    void *handle;
+    GEN_FUNC_TYPE methods[];
+};
+
+celix_status_t exportRegistration_create(log_helper_pt helper, service_reference_pt reference, endpoint_description_pt endpoint, bundle_context_pt context, export_registration_pt *registration) {
+    celix_status_t status = CELIX_SUCCESS;
+    //TODO
+    return status;
+}
+
+celix_status_t exportRegistration_call(export_registration_pt export, char *data, int datalength, char **response, int *responseLength) {
+    int status = CELIX_SUCCESS;
+    //TODO lock/sema export
+
+    printf("Parsing data: %s\n", data);
+    json_error_t error;
+    json_t *js_request = json_loads(data, 0, &error);
+    const char *sig;
+    if (js_request) {
+        if (json_unpack(js_request, "{s:s}", "m", &sig) != 0) {
+            printf("RSA: Got error '%s'\n", error.text);
+        }
+    } else {
+        printf("RSA: got error '%s' for '%s'\n", error.text, data);
+        return 0;
+    }
+
+    printf("RSA: Looking for method %s\n", sig);
+
+    struct methods_head *methods = NULL;
+    dynInterface_methods(export->intf, &methods);
+    struct method_entry *entry = NULL;
+    struct method_entry *method = NULL;
+    TAILQ_FOREACH(entry, methods, entries) {
+        if (strcmp(sig, entry->id) == 0) {
+            method = entry;
+            break;
+        }
+    }
+
+    if (method == NULL) {
+        status = CELIX_ILLEGAL_STATE;
+    }
+
+    if (method != NULL) {
+
+        int nrOfArgs = dynFunction_nrOfArguments(method->dynFunc);
+        void *args[nrOfArgs + 1]; //arg 0 is handle
+        dyn_type *returnType = dynFunction_returnType(method->dynFunc);
+
+        json_t *arguments = json_object_get(js_request, "a");
+        json_t *value;
+        size_t index;
+        json_array_foreach(arguments, index, value) {
+            dyn_type *argType = dynFunction_argumentTypeForIndex(method->dynFunc, index + 1);
+            status = jsonSerializer_deserializeJson(argType, value, &(args[index + 1]));
+            index += 1;
+            if (status != 0) {
+                break;
+            }
+        }
+
+        json_decref(js_request);
+
+        struct generic_service_layout *serv = export->service;
+        args[0] = serv->handle;
+        void *returnVal = NULL;
+        dynType_alloc(returnType, &returnVal);
+        dynFunction_call(method->dynFunc, serv->methods[method->index], returnVal, args);
+
+        status = jsonSerializer_serialize(returnType, returnVal, response);
+        if (returnVal != NULL) {
+            dynType_free(returnType, returnVal);
+        }
+
+        ///TODO add more status checks
+    }
+
+    //TODO unlock/sema export
+    return status;
+}
+
+celix_status_t exportRegistration_destroy(export_registration_pt registration) {
+    celix_status_t status = CELIX_SUCCESS;
+    //TODO
+    return status;
+}
+
+celix_status_t exportRegistration_start(export_registration_pt registration) {
+    celix_status_t status = CELIX_SUCCESS;
+    //TODO
+    return status;
+}
+
+celix_status_t exportRegistration_stop(export_registration_pt registration) {
+    celix_status_t status = CELIX_SUCCESS;
+    //TODO
+    return status;
+}
+
+celix_status_t exportRegistration_close(export_registration_pt registration) {
+    celix_status_t status = CELIX_SUCCESS;
+    //TODO
+    return status;
+}
+
+celix_status_t exportRegistration_getException(export_registration_pt registration) {
+    celix_status_t status = CELIX_SUCCESS;
+    //TODO
+    return status;
+}
+
+celix_status_t exportRegistration_getExportReference(export_registration_pt registration, export_reference_pt *reference) {
+    celix_status_t status = CELIX_SUCCESS;
+    //TODO
+    return status;
+}
+
+celix_status_t exportReference_getExportedEndpoint(export_reference_pt reference, endpoint_description_pt *endpoint) {
+    celix_status_t status = CELIX_SUCCESS;
+    *endpoint = reference->endpoint;
+    return status;
+}
+
+celix_status_t exportReference_getExportedService(export_reference_pt reference) {
+    celix_status_t status = CELIX_SUCCESS;
+    return status;
+}
+
+
+

http://git-wip-us.apache.org/repos/asf/celix/blob/da86474f/remote_services/remote_service_admin_dfi/private/src/import_registration_dfi.c
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/private/src/import_registration_dfi.c b/remote_services/remote_service_admin_dfi/private/src/import_registration_dfi.c
new file mode 100644
index 0000000..f8c544c
--- /dev/null
+++ b/remote_services/remote_service_admin_dfi/private/src/import_registration_dfi.c
@@ -0,0 +1,231 @@
+#include <malloc.h>
+#include "dyn_interface.h"
+#include "import_registration.h"
+#include "import_registration_dfi.h"
+
+struct import_registration {
+    bundle_context_pt context;
+    endpoint_description_pt  endpoint; //TODO owner? -> free when destroyed
+    const char *classObject; //NOTE owned by endpoint
+
+    service_factory_pt factory;
+    service_registration_pt factoryReg;
+
+    hash_map_pt proxies; //key -> bundle, value -> service_proxy
+};
+
+struct service_proxy {
+    dyn_interface_type *intf;
+    void *service;
+    int count;
+};
+
+static celix_status_t importRegistration_createProxy(import_registration_pt import, bundle_pt bundle,
+                                              struct service_proxy **proxy);
+static void importRegistration_proxyFunc(void *userData, void *args[], void *returnVal);
+static void importRegistration_destroyProxy(struct service_proxy *proxy);
+
+celix_status_t importRegistration_create(bundle_context_pt context, endpoint_description_pt  endpoint, const char *classObject, import_registration_pt *out) {
+    celix_status_t status = CELIX_SUCCESS;
+    import_registration_pt reg = calloc(1, sizeof(*reg));
+
+    if (reg != NULL) {
+        reg->factory = calloc(1, sizeof(*reg->factory));
+    }
+
+    if (reg != NULL && reg->factory != NULL) {
+        reg->context = context;
+        reg->endpoint = endpoint;
+        reg->classObject = classObject;
+        reg->proxies = hashMap_create(NULL, NULL, NULL, NULL);
+
+        reg->factory->factory = reg;
+        reg->factory->getService = (void *)importRegistration_getService;
+        reg->factory->ungetService = (void *)importRegistration_ungetService;
+    } else {
+        status = CELIX_ENOMEM;
+    }
+
+    if (status == CELIX_SUCCESS) {
+        *out = reg;
+    }
+
+    return status;
+}
+
+void importRegistration_destroy(import_registration_pt import) {
+    if (import != NULL) {
+        if (import->factory != NULL) {
+            free(import->factory);
+        }
+        free(import);
+    }
+}
+
+celix_status_t importRegistration_start(import_registration_pt import) {
+    celix_status_t  status = CELIX_SUCCESS;
+    if (import->factoryReg == NULL && import->factory != NULL) {
+        status = bundleContext_registerServiceFactory(import->context, (char *)import->classObject, import->factory, NULL /*TODO*/, &import->factoryReg);
+    } else {
+        status = CELIX_ILLEGAL_STATE;
+    }
+    return status;
+}
+
+celix_status_t importRegistration_stop(import_registration_pt import) {
+    celix_status_t status = CELIX_SUCCESS;
+    if (import->factoryReg != NULL) {
+        serviceRegistration_unregister(import->factoryReg);
+    }
+    //TODO unregister every serv instance?
+    return status;
+}
+
+
+celix_status_t importRegistration_getService(import_registration_pt import, bundle_pt bundle, service_registration_pt registration, void **out) {
+    celix_status_t  status = CELIX_SUCCESS;
+    struct service_proxy *proxy = hashMap_get(import->proxies, bundle); //TODO lock
+    if (proxy == NULL) {
+        status = importRegistration_createProxy(import, bundle, &proxy);
+        if (status == CELIX_SUCCESS) {
+            hashMap_put(import->proxies, bundle, proxy); //TODO lock
+        }
+    }
+
+    if (status == CELIX_SUCCESS) {
+        proxy->count += 1;
+        *out = proxy->service;
+    }
+
+    return status;
+}
+
+static celix_status_t importRegistration_createProxy(import_registration_pt import, bundle_pt bundle, struct service_proxy **out) {
+    celix_status_t  status = CELIX_SUCCESS;
+
+    char *descriptorFile = NULL;
+    char name[128];
+    snprintf(name, 128, "%s.descriptor", import->classObject);
+    status = bundle_getEntry(bundle, name, &descriptorFile);
+    if (status != CELIX_SUCCESS) {
+        printf("Cannot find entry '%s'\n", name);
+    }
+
+    struct service_proxy *proxy = NULL;
+    if (status == CELIX_SUCCESS) {
+        proxy = calloc(1, sizeof(*proxy));
+        if (proxy != NULL) {
+
+        } else {
+            status = CELIX_ENOMEM;
+        }
+    }
+
+    if (status == CELIX_SUCCESS) {
+        FILE *df = fopen(descriptorFile, "r");
+        if (df != NULL) {
+            int rc = dynInterface_parse(df, &proxy->intf);
+            fclose(df);
+            if (rc != 0) {
+                status = CELIX_BUNDLE_EXCEPTION;
+            }
+        }
+    }
+
+    void **serv = NULL;
+    if (status == CELIX_SUCCESS) {
+        size_t count = dynInterface_nrOfMethods(proxy->intf);
+        serv = calloc(1 + count, sizeof(void *));
+        serv[0] = proxy;
+
+        struct methods_head *list = NULL;
+        dynInterface_methods(proxy->intf, &list);
+        struct method_entry *entry = NULL;
+        void (*fn)(void);
+        int index = 0;
+        TAILQ_FOREACH(entry, list, entries) {
+            int rc = dynFunction_createClosure(entry->dynFunc, importRegistration_proxyFunc, entry, &fn);
+            serv[index + 1] = fn;
+            index += 1;
+
+            if (rc != 0) {
+                status = CELIX_BUNDLE_EXCEPTION;
+                break;
+            }
+        }
+    }
+
+    if (status == CELIX_SUCCESS) {
+        proxy->service = serv;
+    } else {
+        if (serv != NULL) {
+            free(serv);
+        }
+    }
+
+    if (status == CELIX_SUCCESS) {
+        *out = proxy;
+    }
+
+    return status;
+}
+
+static void importRegistration_proxyFunc(void *userData, void *args[], void *returnVal) {
+    struct method_entry *entry = userData;
+    //struct proxy_service *proxy = args[0];
+
+    printf("Calling function '%s'\n", entry->id);
+
+    //TODO
+}
+
+celix_status_t importRegistration_ungetService(import_registration_pt import, bundle_pt bundle, service_registration_pt registration, void **out) {
+    celix_status_t  status = CELIX_SUCCESS;
+    struct service_proxy *proxy = hashMap_get(import->proxies, bundle); //TODO lock
+    if (proxy != NULL) {
+        if (*out == proxy->service) {
+            proxy->count -= 1;
+        } else {
+            status = CELIX_ILLEGAL_ARGUMENT;
+        }
+
+        if (proxy->count == 0) {
+            importRegistration_destroyProxy(proxy);
+        }
+    }
+
+    return status;
+}
+
+static void importRegistration_destroyProxy(struct service_proxy *proxy) {
+    //TODO
+}
+
+
+celix_status_t importRegistration_close(import_registration_pt registration) {
+    celix_status_t status = CELIX_SUCCESS;
+    //TODO
+    return status;
+}
+
+celix_status_t importRegistration_getException(import_registration_pt registration) {
+    celix_status_t status = CELIX_SUCCESS;
+    //TODO
+    return status;
+}
+
+celix_status_t importRegistration_getImportReference(import_registration_pt registration, import_reference_pt *reference) {
+    celix_status_t status = CELIX_SUCCESS;
+    //TODO
+    return status;
+}
+
+celix_status_t importReference_getImportedEndpoint(import_reference_pt reference) {
+    celix_status_t status = CELIX_SUCCESS;
+    return status;
+}
+
+celix_status_t importReference_getImportedService(import_reference_pt reference) {
+    celix_status_t status = CELIX_SUCCESS;
+    return status;
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/celix/blob/da86474f/remote_services/remote_service_admin_dfi/private/src/remote_service_admin_activator.c
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/private/src/remote_service_admin_activator.c b/remote_services/remote_service_admin_dfi/private/src/remote_service_admin_activator.c
index e4125fc..9961a9b 100644
--- a/remote_services/remote_service_admin_dfi/private/src/remote_service_admin_activator.c
+++ b/remote_services/remote_service_admin_dfi/private/src/remote_service_admin_activator.c
@@ -29,8 +29,8 @@
 #include "service_registration.h"
 
 #include "remote_service_admin_http_impl.h"
-#include "export_registration_impl.h"
-#include "import_registration_impl.h"
+#include "export_registration_dfi.h"
+#include "import_registration_dfi.h"
 
 struct activator {
 	remote_service_admin_pt admin;


[2/3] celix git commit: CELIX-237: A lot of work on the rsa dfi bundle and some needed refactoring for the remote_service_admin setup to support an non proxy approach.

Posted by pn...@apache.org.
http://git-wip-us.apache.org/repos/asf/celix/blob/da86474f/remote_services/remote_service_admin_dfi/private/src/remote_service_admin_dfi.c
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/private/src/remote_service_admin_dfi.c b/remote_services/remote_service_admin_dfi/private/src/remote_service_admin_dfi.c
new file mode 100644
index 0000000..eae2816
--- /dev/null
+++ b/remote_services/remote_service_admin_dfi/private/src/remote_service_admin_dfi.c
@@ -0,0 +1,783 @@
+/**
+ *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.
+ */
+/*
+ * remote_service_admin_impl.c
+ *
+ *  \date       May 21, 2015
+ *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ *  \copyright	Apache License, Version 2.0
+ */
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <arpa/inet.h>
+#include <sys/socket.h>
+#include <netdb.h>
+#include <ifaddrs.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <uuid/uuid.h>
+#include <curl/curl.h>
+#include <sys/queue.h>
+
+#include <jansson.h>
+
+#include "import_registration_dfi.h"
+#include "export_registration_dfi.h"
+#include "dyn_interface.h"
+
+#include "remote_service_admin.h"
+#include "remote_constants.h"
+#include "constants.h"
+#include "utils.h"
+#include "bundle_context.h"
+#include "bundle.h"
+#include "service_reference.h"
+#include "service_registration.h"
+#include "log_helper.h"
+#include "log_service.h"
+#include "celix_threads.h"
+#include "civetweb.h"
+#include "log_helper.h"
+#include "endpoint_description.h"
+#include "dyn_interface.h"
+#include "json_serializer.h"
+
+// defines how often the webserver is restarted (with an increased port number)
+#define MAX_NUMBER_OF_RESTARTS 	5
+
+struct remote_service_admin {
+    bundle_context_pt context;
+    log_helper_pt loghelper;
+
+    celix_thread_mutex_t exportedServicesLock;
+    hash_map_pt exportedServices;
+
+    celix_thread_mutex_t importedServicesLock;
+    hash_map_pt importedServices;
+
+    char *port;
+    char *ip;
+
+    struct mg_context *ctx;
+};
+
+struct post {
+    const char *readptr;
+    int size;
+};
+
+struct get {
+    char *writeptr;
+    int size;
+};
+
+#define OSGI_RSA_REMOTE_PROXY_FACTORY 	"remote_proxy_factory"
+#define OSGI_RSA_REMOTE_PROXY_TIMEOUT   "remote_proxy_timeout"
+
+static const char *data_response_headers =
+        "HTTP/1.1 200 OK\r\n"
+                "Cache: no-cache\r\n"
+                "Content-Type: application/json\r\n"
+                "\r\n";
+
+static const char *no_content_response_headers =
+        "HTTP/1.1 204 OK\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";
+static const char *DEFAULT_IP = "127.0.0.1";
+
+static const unsigned int DEFAULT_TIMEOUT = 0;
+
+static int remoteServiceAdmin_callback(struct mg_connection *conn);
+
+static celix_status_t remoteServiceAdmin_createEndpointDescription(remote_service_admin_pt admin, service_reference_pt reference, char *interface, endpoint_description_pt *description);
+
+static celix_status_t remoteServiceAdmin_getIpAdress(char* interface, char** ip);
+
+static size_t remoteServiceAdmin_readCallback(void *ptr, size_t size, size_t nmemb, void *userp);
+static size_t remoteServiceAdmin_write(void *contents, size_t size, size_t nmemb, void *userp);
+static void remoteServiceAdmin_log(remote_service_admin_pt admin, int level, const char *file, int line, const char *msg, ...);
+
+celix_status_t remoteServiceAdmin_create(bundle_context_pt context, remote_service_admin_pt *admin) {
+    celix_status_t status = CELIX_SUCCESS;
+
+    *admin = calloc(1, sizeof(**admin));
+
+    if (!*admin) {
+        status = CELIX_ENOMEM;
+    } else {
+        unsigned int port_counter = 0;
+        char *port = NULL;
+        char *ip = NULL;
+        char *detectedIp = NULL;
+        (*admin)->context = context;
+        (*admin)->exportedServices = hashMap_create(NULL, NULL, NULL, NULL);
+        (*admin)->importedServices = hashMap_create(NULL, NULL, NULL, NULL);
+
+        celixThreadMutex_create(&(*admin)->exportedServicesLock, NULL);
+        celixThreadMutex_create(&(*admin)->importedServicesLock, NULL);
+
+        if (logHelper_create(context, &(*admin)->loghelper) == CELIX_SUCCESS) {
+            logHelper_start((*admin)->loghelper);
+            dynCommon_logSetup((void *)remoteServiceAdmin_log, *admin, 4);
+            dynType_logSetup((void *)remoteServiceAdmin_log, *admin, 4);
+            dynFunction_logSetup((void *)remoteServiceAdmin_log, *admin, 4);
+            dynInterface_logSetup((void *)remoteServiceAdmin_log, *admin, 4);
+        }
+
+        bundleContext_getProperty(context, "RSA_PORT", &port);
+        if (port == NULL) {
+            port = (char *)DEFAULT_PORT;
+        }
+
+        bundleContext_getProperty(context, "RSA_IP", &ip);
+        if (ip == NULL) {
+            char *interface = NULL;
+
+            bundleContext_getProperty(context, "RSA_INTERFACE", &interface);
+            if ((interface != NULL) && (remoteServiceAdmin_getIpAdress(interface, &detectedIp) != CELIX_SUCCESS)) {
+                logHelper_log((*admin)->loghelper, OSGI_LOGSERVICE_WARNING, "RSA: Could not retrieve IP adress for interface %s", interface);
+            }
+
+            if (ip == NULL) {
+                remoteServiceAdmin_getIpAdress(NULL, &detectedIp);
+            }
+
+            ip = detectedIp;
+        }
+
+        if (ip != NULL) {
+            logHelper_log((*admin)->loghelper, OSGI_LOGSERVICE_INFO, "RSA: Using %s for service annunciation", ip);
+            (*admin)->ip = strdup(ip);
+        }
+        else {
+            logHelper_log((*admin)->loghelper, OSGI_LOGSERVICE_WARNING, "RSA: No IP address for service annunciation set. Using %s", DEFAULT_IP);
+            (*admin)->ip = (char*) DEFAULT_IP;
+        }
+
+        if (detectedIp != NULL) {
+            free(detectedIp);
+        }
+
+        // Prepare callbacks structure. We have only one callback, the rest are NULL.
+        struct mg_callbacks callbacks;
+        memset(&callbacks, 0, sizeof(callbacks));
+        callbacks.begin_request = remoteServiceAdmin_callback;
+
+        do {
+            char newPort[10];
+            const char *options[] = { "listening_ports", port, NULL};
+
+            (*admin)->ctx = mg_start(&callbacks, (*admin), options);
+
+            if ((*admin)->ctx != NULL) {
+                logHelper_log((*admin)->loghelper, OSGI_LOGSERVICE_INFO, "RSA: Start webserver: %s", port);
+                (*admin)->port = strdup(port);
+
+            }
+            else {
+                char* endptr = port;
+                int currentPort = strtol(port, &endptr, 10);
+
+                errno = 0;
+
+                if (*endptr || errno != 0) {
+                    currentPort = strtol(DEFAULT_PORT, NULL, 10);
+                }
+
+                port_counter++;
+                snprintf(&newPort[0], 6,  "%d", (currentPort+1));
+
+                logHelper_log((*admin)->loghelper, OSGI_LOGSERVICE_ERROR, "Error while starting rsa server on port %s - retrying on port %s...", port, newPort);
+                port = newPort;
+            }
+        } while(((*admin)->ctx == NULL) && (port_counter < MAX_NUMBER_OF_RESTARTS));
+
+    }
+    return status;
+}
+
+
+celix_status_t remoteServiceAdmin_destroy(remote_service_admin_pt *admin)
+{
+    celix_status_t status = CELIX_SUCCESS;
+
+    free((*admin)->ip);
+    free((*admin)->port);
+    free(*admin);
+
+    //TODO destroy exports/imports
+
+    *admin = NULL;
+
+    return status;
+}
+
+
+celix_status_t remoteServiceAdmin_stop(remote_service_admin_pt admin) {
+    celix_status_t status = CELIX_SUCCESS;
+
+    celixThreadMutex_lock(&admin->exportedServicesLock);
+
+    hash_map_iterator_pt iter = hashMapIterator_create(admin->exportedServices);
+    while (hashMapIterator_hasNext(iter)) {
+        array_list_pt exports = hashMapIterator_nextValue(iter);
+        int i;
+        for (i = 0; i < arrayList_size(exports); i++) {
+            export_registration_pt export = arrayList_get(exports, i);
+            if (export != NULL) {
+                exportRegistration_stop(export);
+            }
+        }
+    }
+    hashMapIterator_destroy(iter);
+    celixThreadMutex_unlock(&admin->exportedServicesLock);
+
+    celixThreadMutex_lock(&admin->importedServicesLock);
+
+    iter = hashMapIterator_create(admin->importedServices);
+    while (hashMapIterator_hasNext(iter))
+    {
+
+        hash_map_entry_pt entry = hashMapIterator_nextEntry(iter);
+        import_registration_pt import = hashMapEntry_getValue(entry);
+
+        if (import != NULL) {
+            importRegistration_stop(import);
+        }
+    }
+
+    hashMapIterator_destroy(iter);
+    celixThreadMutex_unlock(&admin->importedServicesLock);
+
+    if (admin->ctx != NULL) {
+        logHelper_log(admin->loghelper, OSGI_LOGSERVICE_INFO, "RSA: Stopping webserver...");
+        mg_stop(admin->ctx);
+        admin->ctx = NULL;
+    }
+
+    hashMap_destroy(admin->exportedServices, false, false);
+    hashMap_destroy(admin->importedServices, false, false);
+
+    logHelper_stop(admin->loghelper);
+    logHelper_destroy(&admin->loghelper);
+
+    return status;
+}
+
+/**
+ * Request: http://host:port/services/{service}/{request}
+ */
+//void *remoteServiceAdmin_callback(enum mg_event event, struct mg_connection *conn, const struct mg_request_info *request_info) {
+
+celix_status_t importRegistration_getFactory(import_registration_pt import, service_factory_pt *factory);
+
+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) {
+        remote_service_admin_pt rsa = request_info->user_data;
+
+
+        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
+
+            const char *rest = uri+9;
+            char *interfaceStart = strchr(rest, '/');
+            int pos = interfaceStart - rest;
+            char service[pos+1];
+            strncpy(service, rest, pos);
+            service[pos] = '\0';
+            long serviceId = atol(service);
+
+            celixThreadMutex_lock(&rsa->exportedServicesLock);
+
+            //find endpoint
+            export_registration_pt export = NULL;
+            hash_map_iterator_pt iter = hashMapIterator_create(rsa->exportedServices);
+            while (hashMapIterator_hasNext(iter)) {
+                hash_map_entry_pt entry = hashMapIterator_nextEntry(iter);
+                array_list_pt exports = hashMapEntry_getValue(entry);
+                int expIt = 0;
+                for (expIt = 0; expIt < arrayList_size(exports); expIt++) {
+                    export_registration_pt check = arrayList_get(exports, expIt);
+                    export_reference_pt  ref = NULL;
+                    exportRegistration_getExportReference(check, &ref);
+                    endpoint_description_pt  checkEndpoint = NULL;
+                    exportReference_getExportedEndpoint(ref, &checkEndpoint);
+                    if (serviceId == checkEndpoint->serviceId) {
+                        export = check;
+                        break;
+                    }
+                }
+            }
+            hashMapIterator_destroy(iter);
+
+            if (export != NULL) {
+
+                uint64_t datalength = request_info->content_length;
+                char* data = malloc(datalength + 1);
+                mg_read(conn, data, datalength);
+                data[datalength] = '\0';
+
+                char *response = NULL;
+                int responceLength = 0;
+                int rc = exportRegistration_call(export, data, -1, &response, &responceLength);
+                //TODO check rc
+
+                if (response != NULL) {
+                    mg_write(conn, data_response_headers, strlen(data_response_headers));
+//              mg_write(conn, no_content_response_headers, strlen(no_content_response_headers));
+                    mg_write(conn, response, strlen(response));
+//              mg_send_data(conn, response, strlen(response));
+//              mg_write_data(conn, response, strlen(response));
+
+                    free(response);
+                } else {
+                    mg_write(conn, no_content_response_headers, strlen(no_content_response_headers));
+                }
+                result = 0;
+
+                free(data);
+            } else {
+                //TODO log warning
+            }
+
+            celixThreadMutex_unlock(&rsa->exportedServicesLock);
+
+        }
+    }
+
+    return result;
+}
+
+celix_status_t remoteServiceAdmin_exportService(remote_service_admin_pt admin, char *serviceId, properties_pt properties, array_list_pt *registrations) {
+    celix_status_t status = CELIX_SUCCESS;
+
+    arrayList_create(registrations);
+    array_list_pt references = NULL;
+    service_reference_pt reference = NULL;
+    char filter [256];
+
+    snprintf(filter, 256, "(%s=%s)", (char *)OSGI_FRAMEWORK_SERVICE_ID, serviceId);
+
+    status = bundleContext_getServiceReferences(admin->context, NULL, filter, &references);
+
+    logHelper_log(admin->loghelper, OSGI_LOGSERVICE_ERROR, "RSA: exportService called for serviceId %s", serviceId);
+
+    if (status == CELIX_SUCCESS && arrayList_size(references) >= 1) {
+        reference = arrayList_get(references, 0);
+    }
+
+    if(references != NULL){
+        arrayList_destroy(references);
+    }
+
+    if (reference == NULL) {
+        logHelper_log(admin->loghelper, OSGI_LOGSERVICE_ERROR, "ERROR: expected a reference for service id %s.", serviceId);
+        status = CELIX_ILLEGAL_STATE;
+    }
+
+    char *exports = NULL;
+    char *provided = NULL;
+    if (status == CELIX_SUCCESS) {
+        serviceReference_getProperty(reference, (char *) OSGI_RSA_SERVICE_EXPORTED_INTERFACES, &exports);
+        serviceReference_getProperty(reference, (char *) OSGI_FRAMEWORK_OBJECTCLASS, &provided);
+
+        if (exports == NULL || provided == NULL || strcmp(exports, provided) != 0) {
+            logHelper_log(admin->loghelper, OSGI_LOGSERVICE_WARNING, "RSA: No Services to export.");
+            status = CELIX_ILLEGAL_STATE;
+        }
+    }
+
+    bundle_pt bundle = NULL;
+    if (status == CELIX_SUCCESS) {
+        logHelper_log(admin->loghelper, OSGI_LOGSERVICE_INFO, "RSA: Export service (%s)", provided);
+        status = serviceReference_getBundle(reference, &bundle);
+    }
+
+    char *descriptorFile = NULL;
+    if (status == CELIX_SUCCESS) {
+        char name[128];
+        snprintf(name, 128, "%s.descriptor", exports);
+        status = bundle_getEntry(bundle, name, &descriptorFile);
+    }
+
+    if (status == CELIX_SUCCESS) {
+        dyn_interface_type *intf = NULL;
+        if (descriptorFile != NULL) {
+            FILE *df = fopen(descriptorFile, "r");
+            if (df != NULL) {
+                int rc = dynInterface_parse(df, &intf);
+                fclose(df);
+                if (rc != 0) {
+                    status = CELIX_BUNDLE_EXCEPTION;
+                    logHelper_log(admin->loghelper, OSGI_LOGSERVICE_WARNING, "RSA: Error parsing service descriptor.");
+                }
+            }
+        }
+    }
+
+    if (status == CELIX_SUCCESS) {
+        char *interface = provided;
+        endpoint_description_pt endpoint = NULL;
+        export_registration_pt registration = NULL;
+
+        remoteServiceAdmin_createEndpointDescription(admin, reference, interface, &endpoint);
+        printf("RSA: Creating export registration with endpoint pointer %p\n", endpoint);
+        status = exportRegistration_create(admin->loghelper, reference, endpoint, admin->context, &registration);
+        if (status == CELIX_SUCCESS) {
+            status = exportRegistration_start(registration);
+            if (status == CELIX_SUCCESS) {
+                arrayList_add(*registrations, registration);
+            }
+        }
+    }
+
+    if (status == CELIX_SUCCESS) {
+        celixThreadMutex_lock(&admin->exportedServicesLock);
+        hashMap_put(admin->exportedServices, reference, *registrations);
+        celixThreadMutex_unlock(&admin->exportedServicesLock);
+    }
+
+    return status;
+}
+
+celix_status_t remoteServiceAdmin_removeExportedService(export_registration_pt registration) {
+    celix_status_t status = CELIX_SUCCESS;
+    //TODO
+    /*
+    remote_service_admin_pt admin = registration->rsa;
+
+    celixThreadMutex_lock(&admin->exportedServicesLock);
+
+    hashMap_remove(admin->exportedServices, registration->reference);
+    //TODO stop ?
+
+    celixThreadMutex_unlock(&admin->exportedServicesLock);
+    */
+    return status;
+}
+
+static celix_status_t remoteServiceAdmin_createEndpointDescription(remote_service_admin_pt admin, service_reference_pt reference, char *interface, endpoint_description_pt *endpoint) {
+    celix_status_t status = CELIX_SUCCESS;
+    properties_pt endpointProperties = properties_create();
+
+
+    unsigned int size = 0;
+    char **keys;
+
+    serviceReference_getPropertyKeys(reference, &keys, &size);
+    for (int i = 0; i < size; i++) {
+        char *key = keys[i];
+        char *value = NULL;
+
+        if (serviceReference_getProperty(reference, key, &value) == CELIX_SUCCESS
+            && strcmp(key, (char*) OSGI_RSA_SERVICE_EXPORTED_INTERFACES) != 0
+            && strcmp(key, (char*) OSGI_FRAMEWORK_OBJECTCLASS) != 0) {
+            properties_set(endpointProperties, key, value);
+            printf("Added property '%s' with value '%s'\n", key, value);
+        }
+    }
+
+    hash_map_entry_pt entry = hashMap_getEntry(endpointProperties, (void *) OSGI_FRAMEWORK_SERVICE_ID);
+
+    char* key = hashMapEntry_getKey(entry);
+    char *serviceId = (char *) hashMap_remove(endpointProperties, (void *) OSGI_FRAMEWORK_SERVICE_ID);
+    char *uuid = NULL;
+
+    char buf[512];
+    snprintf(buf, 512,  "/service/%s/%s", serviceId, interface);
+
+    char url[1024];
+    snprintf(url, 1024, "http://%s:%s%s", admin->ip, admin->port, buf);
+
+    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 = calloc(1, sizeof(**endpoint));
+    if (!*endpoint) {
+        status = CELIX_ENOMEM;
+    } else {
+        (*endpoint)->id = properties_get(endpointProperties, (char*) OSGI_RSA_ENDPOINT_ID);
+        char *serviceId = NULL;
+        serviceReference_getProperty(reference, (char*) OSGI_FRAMEWORK_SERVICE_ID, &serviceId);
+        (*endpoint)->serviceId = strtoull(serviceId, NULL, 0);
+        (*endpoint)->frameworkUUID = properties_get(endpointProperties, (char*) OSGI_RSA_ENDPOINT_FRAMEWORK_UUID);
+        (*endpoint)->service = interface;
+        (*endpoint)->properties = endpointProperties;
+    }
+
+    free(key);
+    free(serviceId);
+    free(keys);
+
+    return status;
+}
+
+static celix_status_t remoteServiceAdmin_getIpAdress(char* interface, char** ip) {
+    celix_status_t status = CELIX_BUNDLE_EXCEPTION;
+
+    struct ifaddrs *ifaddr, *ifa;
+    char host[NI_MAXHOST];
+
+    if (getifaddrs(&ifaddr) != -1)
+    {
+        for (ifa = ifaddr; ifa != NULL && status != CELIX_SUCCESS; ifa = ifa->ifa_next)
+        {
+            if (ifa->ifa_addr == NULL)
+                continue;
+
+            if ((getnameinfo(ifa->ifa_addr,sizeof(struct sockaddr_in), host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST) == 0) && (ifa->ifa_addr->sa_family == AF_INET)) {
+                if (interface == NULL) {
+                    *ip = strdup(host);
+                    status = CELIX_SUCCESS;
+                }
+                else if (strcmp(ifa->ifa_name, interface) == 0) {
+                    *ip = strdup(host);
+                    status = CELIX_SUCCESS;
+                }
+            }
+        }
+
+        freeifaddrs(ifaddr);
+    }
+
+    return status;
+}
+
+
+celix_status_t remoteServiceAdmin_destroyEndpointDescription(endpoint_description_pt *description)
+{
+    celix_status_t status = CELIX_SUCCESS;
+
+    properties_destroy((*description)->properties);
+    free(*description);
+
+    return status;
+}
+
+
+celix_status_t remoteServiceAdmin_getExportedServices(remote_service_admin_pt admin, array_list_pt *services) {
+    celix_status_t status = CELIX_SUCCESS;
+    return status;
+}
+
+celix_status_t remoteServiceAdmin_getImportedEndpoints(remote_service_admin_pt admin, array_list_pt *services) {
+    celix_status_t status = CELIX_SUCCESS;
+    return status;
+}
+
+celix_status_t remoteServiceAdmin_importService(remote_service_admin_pt admin, endpoint_description_pt endpointDescription, import_registration_pt *out) {
+    celix_status_t status = CELIX_SUCCESS;
+
+    logHelper_log(admin->loghelper, OSGI_LOGSERVICE_INFO, "RSA: Import service %s", endpointDescription->service);
+
+    const char *objectClass = properties_get(endpointDescription->properties, "objectClass");
+    logHelper_log(admin->loghelper, OSGI_LOGSERVICE_INFO, "Registering service factory (proxy) for service '%s'\n", objectClass);
+
+
+    import_registration_pt import = NULL;
+    if (objectClass != NULL) {
+        status = importRegistration_create(admin->context, endpointDescription, objectClass, &import);
+    }
+
+    if (status == CELIX_SUCCESS) {
+        status = importRegistration_start(import);
+    }
+
+    //celixThreadMutex_lock(&admin->importedServicesLock);
+    //TODO add to list
+    //celixThreadMutex_unlock(&admin->importedServicesLock);
+
+    if (status == CELIX_SUCCESS) {
+        *out = import;
+    }
+
+    return status;
+}
+
+
+celix_status_t remoteServiceAdmin_removeImportedService(remote_service_admin_pt admin, import_registration_pt registration) {
+    celix_status_t status = CELIX_SUCCESS;
+    return status;
+    /*
+
+      endpoint_description_pt endpointDescription = (endpoint_description_pt) registration->endpointDescription;
+      import_registration_factory_pt registration_factory = NULL;
+
+      celixThreadMutex_lock(&admin->importedServicesLock);
+
+      registration_factory = (import_registration_factory_pt) hashMap_get(admin->importedServices, endpointDescription->service);
+
+      // factory available
+      if ((registration_factory == NULL) || (registration_factory->trackedFactory == NULL))
+      {
+          logHelper_log(admin->loghelper, OSGI_LOGSERVICE_ERROR, "RSA: Error while retrieving registration factory for imported service %s", endpointDescription->service);
+      }
+      else
+      {
+          registration_factory->trackedFactory->unregisterProxyService(registration_factory->trackedFactory->factory, endpointDescription);
+          arrayList_removeElement(registration_factory->registrations, registration);
+          importRegistration_destroy(registration);
+
+          if (arrayList_isEmpty(registration_factory->registrations))
+          {
+              logHelper_log(admin->loghelper, OSGI_LOGSERVICE_INFO, "RSA: closing proxy.");
+
+              serviceTracker_close(registration_factory->proxyFactoryTracker);
+              importRegistrationFactory_close(registration_factory);
+
+              hashMap_remove(admin->importedServices, endpointDescription->service);
+
+              importRegistrationFactory_destroy(&registration_factory);
+          }
+      }
+
+      celixThreadMutex_unlock(&admin->importedServicesLock);
+
+      return status;
+    */
+}
+
+
+celix_status_t remoteServiceAdmin_send(remote_service_admin_pt rsa, endpoint_description_pt endpointDescription, char *request, char **reply, int* replyStatus) {
+
+    struct post post;
+    post.readptr = request;
+    post.size = strlen(request);
+
+    struct get get;
+    get.size = 0;
+    get.writeptr = malloc(1);
+
+    char *serviceUrl = properties_get(endpointDescription->properties, (char*) ENDPOINT_URL);
+    char url[256];
+    snprintf(url, 256, "%s", serviceUrl);
+
+    // assume the default timeout
+    int timeout = DEFAULT_TIMEOUT;
+
+    char *timeoutStr = NULL;
+    // Check if the endpoint has a timeout, if so, use it.
+    timeoutStr = properties_get(endpointDescription->properties, (char*) OSGI_RSA_REMOTE_PROXY_TIMEOUT);
+    if (timeoutStr == NULL) {
+        // If not, get the global variable and use that one.
+        bundleContext_getProperty(rsa->context, (char*) OSGI_RSA_REMOTE_PROXY_TIMEOUT, &timeoutStr);
+    }
+
+    // Update timeout if a property is used to set it.
+    if (timeoutStr != NULL) {
+        timeout = atoi(timeoutStr);
+    }
+
+    celix_status_t status = CELIX_SUCCESS;
+    CURL *curl;
+    CURLcode res;
+
+    curl = curl_easy_init();
+    if(!curl) {
+        status = CELIX_ILLEGAL_STATE;
+    } else {
+        curl_easy_setopt(curl, CURLOPT_TIMEOUT, timeout);
+        curl_easy_setopt(curl, CURLOPT_URL, &url[0]);
+        curl_easy_setopt(curl, CURLOPT_POST, 1L);
+        curl_easy_setopt(curl, CURLOPT_READFUNCTION, remoteServiceAdmin_readCallback);
+        curl_easy_setopt(curl, CURLOPT_READDATA, &post);
+        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, remoteServiceAdmin_write);
+        curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&get);
+        curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, (curl_off_t)post.size);
+        res = curl_easy_perform(curl);
+        curl_easy_cleanup(curl);
+
+        *reply = get.writeptr;
+        *replyStatus = res;
+    }
+
+    return status;
+}
+
+static size_t remoteServiceAdmin_readCallback(void *ptr, size_t size, size_t nmemb, void *userp) {
+    struct post *post = userp;
+
+    if (post->size) {
+        *(char *) ptr = post->readptr[0];
+        post->readptr++;
+        post->size--;
+        return 1;
+    }
+
+    return 0;
+}
+
+static size_t remoteServiceAdmin_write(void *contents, size_t size, size_t nmemb, void *userp) {
+    size_t realsize = size * nmemb;
+    struct get *mem = (struct get *)userp;
+
+    mem->writeptr = realloc(mem->writeptr, mem->size + realsize + 1);
+    if (mem->writeptr == NULL) {
+        /* out of memory! */
+        printf("not enough memory (realloc returned NULL)");
+        exit(EXIT_FAILURE);
+    }
+
+    memcpy(&(mem->writeptr[mem->size]), contents, realsize);
+    mem->size += realsize;
+    mem->writeptr[mem->size] = 0;
+
+    return realsize;
+}
+
+
+static void remoteServiceAdmin_log(remote_service_admin_pt admin, int level, const char *file, int line, const char *msg, ...) {
+    va_list ap;
+    va_start(ap, msg);
+    int levels[5] = {0, OSGI_LOGSERVICE_ERROR, OSGI_LOGSERVICE_WARNING, OSGI_LOGSERVICE_INFO, OSGI_LOGSERVICE_DEBUG};
+
+    char buf1[256];
+    snprintf(buf1, 256, "FILE:%s, LINE:%i, MSG:", file, line);
+
+    char buf2[256];
+    vsnprintf(buf2, 256, msg, ap);
+    logHelper_log(admin->loghelper, levels[level], "%s%s", buf1, buf2);
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/celix/blob/da86474f/remote_services/remote_service_admin_dfi/private/src/remote_service_admin_impl.c
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/private/src/remote_service_admin_impl.c b/remote_services/remote_service_admin_dfi/private/src/remote_service_admin_impl.c
deleted file mode 100644
index ac54e8d..0000000
--- a/remote_services/remote_service_admin_dfi/private/src/remote_service_admin_impl.c
+++ /dev/null
@@ -1,1085 +0,0 @@
-/**
- *Licensed to the Apache Software Foundation (ASF) under one
- *or more contributor license agreements.  See the NOTICE file
- *distributed with this work for additional information
- *regarding copyright ownership.  The ASF licenses this file
- *to you under the Apache License, Version 2.0 (the
- *"License"); you may not use this file except in compliance
- *with the License.  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- *Unless required by applicable law or agreed to in writing,
- *software distributed under the License is distributed on an
- *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- *specific language governing permissions and limitations
- *under the License.
- */
-/*
- * remote_service_admin_impl.c
- *
- *  \date       May 21, 2015
- *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- *  \copyright	Apache License, Version 2.0
- */
-#include <stdio.h>
-#include <stdlib.h>
-
-#include <arpa/inet.h>
-#include <sys/socket.h>
-#include <netdb.h>
-#include <ifaddrs.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <uuid/uuid.h>
-
-#include <curl/curl.h>
-
-#include <ffi.h>
-#include <jansson.h>
-
-#include "export_registration_impl.h"
-#include "import_registration_impl.h"
-#include "remote_service_admin_impl.h"
-#include "remote_constants.h"
-#include "constants.h"
-#include "utils.h"
-#include "bundle_context.h"
-#include "bundle.h"
-#include "service_reference.h"
-#include "service_registration.h"
-#include "log_helper.h"
-#include "log_service.h"
-#include "celix_threads.h"
-#include "civetweb.h"
-#include "log_helper.h"
-#include "endpoint_description.h"
-
-// defines how often the webserver is restarted (with an increased port number)
-#define MAX_NUMBER_OF_RESTARTS 	5
-
-typedef void (*GEN_FUNC_TYPE)(void);
-
-struct generic_service_layout {
-    void *handle;
-    GEN_FUNC_TYPE functions[];
-};
-
-struct proxy {
-  remote_service_admin_pt admin;
-  char *sig;
-  int index;
-  ffi_cif cif;
-  ffi_closure *closure;
-  endpoint_description_pt endpointDescription
-};
-
-
-    
-
-
-struct remote_service_admin {
-	bundle_context_pt context;
-	log_helper_pt loghelper;
-
-	celix_thread_mutex_t exportedServicesLock;
-	hash_map_pt exportedServices;
-
-	celix_thread_mutex_t importedServicesLock;
-	hash_map_pt importedServices;
-
-	char *port;
-	char *ip;
-
-	struct mg_context *ctx;
-};
-
-struct post {
-    const char *readptr;
-    int size;
-};
-
-struct get {
-    char *writeptr;
-    int size;
-};
-
-static const char *data_response_headers =
-  "HTTP/1.1 200 OK\r\n"
-  "Cache: no-cache\r\n"
-  "Content-Type: application/json\r\n"
-  "\r\n";
-
-static const char *no_content_response_headers =
-  "HTTP/1.1 204 OK\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";
-static const char *DEFAULT_IP = "127.0.0.1";
-
-static const unsigned int DEFAULT_TIMEOUT = 0;
-
-static int remoteServiceAdmin_callback(struct mg_connection *conn);
-
-static celix_status_t remoteServiceAdmin_createEndpointDescription(remote_service_admin_pt admin, service_reference_pt reference, char *interface, endpoint_description_pt *description);
-
-static celix_status_t remoteServiceAdmin_getIpAdress(char* interface, char** ip);
-
-static size_t remoteServiceAdmin_readCallback(void *ptr, size_t size, size_t nmemb, void *userp);
-static size_t remoteServiceAdmin_write(void *contents, size_t size, size_t nmemb, void *userp);
-
-celix_status_t remoteServiceAdmin_create(bundle_context_pt context, remote_service_admin_pt *admin) {
-	celix_status_t status = CELIX_SUCCESS;
-
-	*admin = calloc(1, sizeof(**admin));
-
-	if (!*admin) {
-		status = CELIX_ENOMEM;
-	} else {
-		unsigned int port_counter = 0;
-		char *port = NULL;
-		char *ip = NULL;
-		char *detectedIp = NULL;
-		(*admin)->context = context;
-		(*admin)->exportedServices = hashMap_create(NULL, NULL, NULL, NULL);
-		(*admin)->importedServices = hashMap_create(NULL, NULL, NULL, NULL);
-
-		celixThreadMutex_create(&(*admin)->exportedServicesLock, NULL);
-		celixThreadMutex_create(&(*admin)->importedServicesLock, NULL);
-
-		if (logHelper_create(context, &(*admin)->loghelper) == CELIX_SUCCESS) {
-			logHelper_start((*admin)->loghelper);
-		}
-
-		bundleContext_getProperty(context, "RSA_PORT", &port);
-		if (port == NULL) {
-			port = (char *)DEFAULT_PORT;
-		}
-
-		bundleContext_getProperty(context, "RSA_IP", &ip);
-		if (ip == NULL) {
-			char *interface = NULL;
-
-			bundleContext_getProperty(context, "RSA_INTERFACE", &interface);
-			if ((interface != NULL) && (remoteServiceAdmin_getIpAdress(interface, &detectedIp) != CELIX_SUCCESS)) {
-				logHelper_log((*admin)->loghelper, OSGI_LOGSERVICE_WARNING, "RSA: Could not retrieve IP adress for interface %s", interface);
-			}
-
-			if (ip == NULL) {
-				remoteServiceAdmin_getIpAdress(NULL, &detectedIp);
-			}
-
-			ip = detectedIp;
-		}
-
-		if (ip != NULL) {
-			logHelper_log((*admin)->loghelper, OSGI_LOGSERVICE_INFO, "RSA: Using %s for service annunciation", ip);
-			(*admin)->ip = strdup(ip);
-		}
-		else {
-			logHelper_log((*admin)->loghelper, OSGI_LOGSERVICE_WARNING, "RSA: No IP address for service annunciation set. Using %s", DEFAULT_IP);
-			(*admin)->ip = (char*) DEFAULT_IP;
-		}
-
-		if (detectedIp != NULL) {
-			free(detectedIp);
-		}
-
-		// Prepare callbacks structure. We have only one callback, the rest are NULL.
-		struct mg_callbacks callbacks;
-		memset(&callbacks, 0, sizeof(callbacks));
-		callbacks.begin_request = remoteServiceAdmin_callback;
-
-		do {
-			char newPort[10];
-			const char *options[] = { "listening_ports", port, NULL};
-
-			(*admin)->ctx = mg_start(&callbacks, (*admin), options);
-
-			if ((*admin)->ctx != NULL) {
-				logHelper_log((*admin)->loghelper, OSGI_LOGSERVICE_INFO, "RSA: Start webserver: %s", port);
-				(*admin)->port = strdup(port);
-
-			}
-			else {
-		        char* endptr = port;
-		        int currentPort = strtol(port, &endptr, 10);
-
-				errno = 0;
-
-		        if (*endptr || errno != 0) {
-		            currentPort = strtol(DEFAULT_PORT, NULL, 10);
-		        }
-
-		        port_counter++;
-				snprintf(&newPort[0], 6,  "%d", (currentPort+1));
-
-				logHelper_log((*admin)->loghelper, OSGI_LOGSERVICE_ERROR, "Error while starting rsa server on port %s - retrying on port %s...", port, newPort);
-				port = newPort;
-			}
-		} while(((*admin)->ctx == NULL) && (port_counter < MAX_NUMBER_OF_RESTARTS));
-
-	}
-	return status;
-}
-
-
-celix_status_t remoteServiceAdmin_destroy(remote_service_admin_pt *admin)
-{
-    celix_status_t status = CELIX_SUCCESS;
-
-    free((*admin)->ip);
-    free((*admin)->port);
-    free(*admin);
-
-    *admin = NULL;
-
-    return status;
-}
-
-celix_status_t remoteServiceAdmin_stop(remote_service_admin_pt admin) {
-	celix_status_t status = CELIX_SUCCESS;
-
-    celixThreadMutex_lock(&admin->exportedServicesLock);
-
-	hash_map_iterator_pt iter = hashMapIterator_create(admin->exportedServices);
-	while (hashMapIterator_hasNext(iter)) {
-		array_list_pt exports = hashMapIterator_nextValue(iter);
-		int i;
-		for (i = 0; i < arrayList_size(exports); i++) {
-			export_registration_pt export = arrayList_get(exports, i);
-			exportRegistration_stopTracking(export);
-		}
-	}
-    hashMapIterator_destroy(iter);
-    celixThreadMutex_unlock(&admin->exportedServicesLock);
-
-    celixThreadMutex_lock(&admin->importedServicesLock);
-
-    iter = hashMapIterator_create(admin->importedServices);
-    while (hashMapIterator_hasNext(iter))
-    {
-    	hash_map_entry_pt entry = hashMapIterator_nextEntry(iter);
-
-    	import_registration_factory_pt importFactory = hashMapEntry_getValue(entry);
-
-        if (importFactory != NULL) {
-            int i;
-            for (i = 0; i < arrayList_size(importFactory->registrations); i++)
-            {
-                import_registration_pt importRegistration = arrayList_get(importFactory->registrations, i);
-
-                if (importFactory->trackedFactory != NULL)
-                {
-                    importFactory->trackedFactory->unregisterProxyService(importFactory->trackedFactory->factory, importRegistration->endpointDescription);
-                }
-            }
-
-            serviceTracker_close(importFactory->proxyFactoryTracker);
-            importRegistrationFactory_close(importFactory);
-
-            hashMapIterator_remove(iter);
-            importRegistrationFactory_destroy(&importFactory);
-            }
-    }
-    hashMapIterator_destroy(iter);
-    celixThreadMutex_unlock(&admin->importedServicesLock);
-
-	if (admin->ctx != NULL) {
-		logHelper_log(admin->loghelper, OSGI_LOGSERVICE_INFO, "RSA: Stopping webserver...");
-		mg_stop(admin->ctx);
-		admin->ctx = NULL;
-	}
-
-	hashMap_destroy(admin->exportedServices, false, false);
-	hashMap_destroy(admin->importedServices, false, false);
-
-	logHelper_stop(admin->loghelper);
-	logHelper_destroy(&admin->loghelper);
-
-	return status;
-}
-
-/**
- * Request: http://host:port/services/{service}/{request}
- */
-//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) {
-		remote_service_admin_pt rsa = request_info->user_data;
-
-
-		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
-
-			const char *rest = uri+9;
-			char *interfaceStart = strchr(rest, '/');
-			int pos = interfaceStart - rest;
-			char service[pos+1];
-			strncpy(service, rest, pos);
-			service[pos] = '\0';
-      long serviceId = atol(service);
-
-			celixThreadMutex_lock(&rsa->exportedServicesLock);
-
-      //find endpoint
-      export_registration_pt export = NULL;
-			hash_map_iterator_pt iter = hashMapIterator_create(rsa->exportedServices);
-			while (hashMapIterator_hasNext(iter)) {
-				hash_map_entry_pt entry = hashMapIterator_nextEntry(iter);
-				array_list_pt exports = hashMapEntry_getValue(entry);
-				int expIt = 0;
-				for (expIt = 0; expIt < arrayList_size(exports); expIt++) {
-					export_registration_pt check = arrayList_get(exports, expIt);
-					if (serviceId == check->endpointDescription->serviceId) {
-              export = check;
-              break;
-          }
-        }
-      }
-      hashMapIterator_destroy(iter);
-
-      if (export != NULL) {
-          uint64_t datalength = request_info->content_length;
-          char* data = malloc(datalength + 1);
-          mg_read(conn, data, datalength);
-          data[datalength] = '\0';
-
-          char *response = NULL;
-
-          //FIXME assuming add signature (add(double, double) : double)
-          /*TODO
-            export->endpoint->handleRequest(export->endpoint->endpoint, data, &response);
-            */
-
-
-          //retreive schema.
-          char *schema = NULL;
-          schema = properties_get(export->endpointDescription->properties, "protocol.schema");
-          printf("RSA: got schema %s\n", schema);
-
-
-          printf("Parsing data: %s\n", data);
-          json_error_t error;
-          json_t *js_request = json_loads(data, 0, &error);
-          const char *sig;
-          if (js_request) {
-              if (json_unpack(js_request, "{s:s}", "m", &sig) != 0) {
-                  printf("RSA: Got error '%s'\n", error.text);
-              }
-          } else {
-              printf("RSA: got error '%s' for '%s'\n", error.text, data);
-              return 0;
-          }
-
-          printf("RSA: Looking for method %s\n", sig);
-
-          json_t *js_schema = json_loads(schema, 0, &error);
-          int methodIndex = -1;
-          if (js_schema) {
-              //TODO parse schema and create cif
-              size_t index;
-              json_t *value;
-              json_array_foreach(js_schema, index, value) {
-                  if (strcmp(sig, json_string_value(value)) == 0) {
-                      //found match
-                      methodIndex = index;
-                      break;
-                  }
-              }
-          } else {
-              printf("RSA: got error '%s' for '%s'\n", error.text, schema);
-              return 0;
-          }
-
-          if (methodIndex < 0) {
-              printf("RSA: cannot find method '%s'\n", sig);
-              return 1;
-          }
-
-          size_t sigLength = strlen(sig);
-          char provArgs[sigLength];
-          bool startFound = false;
-          int i = 0;
-          int argIndex = 0;
-          for (; i < sigLength; i += 1) {
-              if (!startFound) {
-                  if (sig[i] == '(') {
-                      startFound = true;
-                  }
-              } else {
-                  if (sig[i] != ')') {
-                      provArgs[argIndex++] = sig[i];
-                  }
-              }
-          } 
-          provArgs[argIndex] = '\0';
-          size_t provArgsLength = strlen(provArgs) -1; 
-          printf("method index is %i and args are '%s'\n", methodIndex, provArgs);
-
-
-          //FFI part
-          ffi_cif cif;
-          ffi_type *argTypes[provArgsLength + 2]; //e.g. void *handle (extra), double a, double b, double *result (extra)
-          void *valuePointers[provArgsLength + 2];
-          //note assuming doubles!!
-          double values[provArgsLength];
-          double result = 0.0;
-          double *resultPointer = &result;
-          int rvalue = 0;
-
-          argTypes[0] = &ffi_type_pointer;
-          argTypes[provArgsLength +1] = &ffi_type_pointer; //last argument is return value, handled as a pointer
-          for (i = 0; i < provArgsLength; i += 1) {
-              //FIXME for now assuming double as arguments
-              argTypes[i+1] = &ffi_type_double;
-          }
-
-          valuePointers[0] = NULL;
-          valuePointers[provArgsLength+1] = &resultPointer;
-          for (i = 0; i < provArgsLength; i += 1) {
-              values[i] = 0.0;
-              valuePointers[i+1] = &(values[i]);
-          }
-
-          json_t *arguments = json_object_get(js_request, "a");
-          json_t *value;
-          size_t index;
-          json_array_foreach(arguments, index, value) {
-              values[index] = json_real_value(value); //setting values, again assuming double
-          }
-
-          json_decref(js_schema);
-          json_decref(js_request);
-
-          if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, provArgsLength + 2,
-                      &ffi_type_sint, argTypes) == FFI_OK)
-          {
-              printf("RSA: FFI PREP OK\n");
-
-              //TRYING TO CALL Calculate service
-              void *service = NULL;
-              bundleContext_getService(rsa->context, export->reference, &service);     
-              if (service == NULL) {
-                  printf("RSA: Ouch service is NULL\n");
-                  return 0;
-              } else {
-                  printf("RSA: service ok\n");
-              }
-
-              struct generic_service_layout *serv = service;
-
-              printf("RSA:Trying to call service using ffi\n");
-              valuePointers[0] = serv->handle;
-              ffi_call(&cif, serv->functions[methodIndex], &rvalue, valuePointers);
-              printf("RSA: Done calling service through ffi, got value %f\n", result);
-
-              json_t *resultRoot;
-              resultRoot = json_pack("{s:f}", "r", result);
-              response = json_dumps(resultRoot, 0);
-              json_decref(resultRoot);  
-          }
-
-          if (response != NULL) {
-              mg_write(conn, data_response_headers, strlen(data_response_headers));
-//              mg_write(conn, no_content_response_headers, strlen(no_content_response_headers));
-              mg_write(conn, response, strlen(response));
-//              mg_send_data(conn, response, strlen(response));
-//              mg_write_data(conn, response, strlen(response));
-
-              free(response);
-          } else {
-              mg_write(conn, no_content_response_headers, strlen(no_content_response_headers));
-          }
-          result = 0;
-
-          free(data);
-      } else {
-          //TODO log warning
-      }
-
-      celixThreadMutex_unlock(&rsa->exportedServicesLock);
-
-		}
-	}
-
-	return 1;
-}
-
-celix_status_t remoteServiceAdmin_handleRequest(remote_service_admin_pt rsa, char *service, char *data, char **reply) {
-	celixThreadMutex_lock(&rsa->exportedServicesLock);
-
-	hash_map_iterator_pt iter = hashMapIterator_create(rsa->exportedServices);
-	while (hashMapIterator_hasNext(iter)) {
-		hash_map_entry_pt entry = hashMapIterator_nextEntry(iter);
-		array_list_pt exports = hashMapEntry_getValue(entry);
-		int expIt = 0;
-		for (expIt = 0; expIt < arrayList_size(exports); expIt++) {
-			export_registration_pt export = arrayList_get(exports, expIt);
-			if (strcmp(service, export->endpointDescription->service) == 0) {
-				export->endpoint->handleRequest(export->endpoint->endpoint, data, reply);
-			}
-		}
-	}
-    hashMapIterator_destroy(iter);
-
-	celixThreadMutex_unlock(&rsa->exportedServicesLock);
-
-	return CELIX_SUCCESS;
-}
-
-celix_status_t remoteServiceAdmin_exportService(remote_service_admin_pt admin, char *serviceId, properties_pt properties, array_list_pt *registrations) {
-    celix_status_t status = CELIX_SUCCESS;
-    arrayList_create(registrations);
-    array_list_pt references = NULL;
-    service_reference_pt reference = NULL;
-    char filter [256];
-
-    snprintf(filter, 256, "(%s=%s)", (char *)OSGI_FRAMEWORK_SERVICE_ID, serviceId);
-
-    bundleContext_getServiceReferences(admin->context, NULL, filter, &references); //FIXME not safe
-
-    logHelper_log(admin->loghelper, OSGI_LOGSERVICE_ERROR, "RSA: exportService called for serviceId %s", serviceId);
-
-    if (arrayList_size(references) >= 1) {
-        reference = arrayList_get(references, 0);
-    }
-
-    if(references!=NULL){
-        arrayList_destroy(references);
-    }
-
-    if (reference == NULL) {
-        logHelper_log(admin->loghelper, OSGI_LOGSERVICE_ERROR, "ERROR: expected a reference for service id %s.", serviceId);
-        return CELIX_ILLEGAL_STATE;
-    }
-
-    char *exports = NULL;
-    char *provided = NULL;
-    char *schema = NULL;
-    serviceReference_getProperty(reference, (char *) OSGI_RSA_SERVICE_EXPORTED_INTERFACES, &exports);
-    serviceReference_getProperty(reference, (char *) OSGI_FRAMEWORK_OBJECTCLASS, &provided);
-    serviceReference_getProperty(reference, (char *) "protocol.schema", &schema);
-
-    if (exports == NULL || provided == NULL) {
-        logHelper_log(admin->loghelper, OSGI_LOGSERVICE_WARNING, "RSA: No Services to export.");
-            status = CELIX_ILLEGAL_STATE;
-    } else {
-        if (schema == NULL) {
-            logHelper_log(admin->loghelper, OSGI_LOGSERVICE_WARNING, "RSA: no protocol.schema found.");
-            status = CELIX_ILLEGAL_STATE;
-        } else {
-            logHelper_log(admin->loghelper, OSGI_LOGSERVICE_INFO, "RSA: Export service (%s)", provided);
-
-            char *interface = provided;
-            endpoint_description_pt endpoint = NULL;
-            export_registration_pt registration = NULL;
-
-            remoteServiceAdmin_createEndpointDescription(admin, reference, interface, &endpoint);
-            printf("RSA: Creating export registration with endpoint pointer %p\n", endpoint);
-            exportRegistration_create(admin->loghelper, reference, endpoint, admin, admin->context, &registration);
-            arrayList_add(*registrations, registration);
-
-            exportRegistration_open(registration);
-            exportRegistration_startTracking(registration);
-
-            celixThreadMutex_lock(&admin->exportedServicesLock);
-            hashMap_put(admin->exportedServices, reference, *registrations);
-            celixThreadMutex_unlock(&admin->exportedServicesLock);
-        }
-    }
-    return status;
-}
-
-celix_status_t remoteServiceAdmin_removeExportedService(export_registration_pt registration) {
-    celix_status_t status = CELIX_SUCCESS;
-    remote_service_admin_pt admin = registration->rsa;
-
-    celixThreadMutex_lock(&admin->exportedServicesLock);
-
-    hashMap_remove(admin->exportedServices, registration->reference);
-
-    celixThreadMutex_unlock(&admin->exportedServicesLock);
-
-    return status;
-}
-
-static celix_status_t remoteServiceAdmin_createEndpointDescription(remote_service_admin_pt admin, service_reference_pt reference, char *interface, endpoint_description_pt *endpoint) {
-	celix_status_t status = CELIX_SUCCESS;
-	properties_pt endpointProperties = properties_create();
-
-
-	unsigned int size = 0;
-    char **keys;
-
-    serviceReference_getPropertyKeys(reference, &keys, &size);
-    for (int i = 0; i < size; i++) {
-        char *key = keys[i];
-        char *value = NULL;
-
-        if (serviceReference_getProperty(reference, key, &value) == CELIX_SUCCESS
-        		&& strcmp(key, (char*) OSGI_RSA_SERVICE_EXPORTED_INTERFACES) != 0
-        		&& strcmp(key, (char*) OSGI_FRAMEWORK_OBJECTCLASS) != 0) {
-        	properties_set(endpointProperties, key, value);
-          printf("Added property '%s' with value '%s'\n", key, value);
-        }
-	}
-
-	hash_map_entry_pt entry = hashMap_getEntry(endpointProperties, (void *) OSGI_FRAMEWORK_SERVICE_ID);
-
-	char* key = hashMapEntry_getKey(entry);
-	char *serviceId = (char *) hashMap_remove(endpointProperties, (void *) OSGI_FRAMEWORK_SERVICE_ID);
-	char *uuid = NULL;
-
-	char buf[512];
-	snprintf(buf, 512,  "/service/%s/%s", serviceId, interface);
-
-	char url[1024];
-	snprintf(url, 1024, "http://%s:%s%s", admin->ip, admin->port, buf);
-
-	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 = calloc(1, sizeof(**endpoint));
-  if (!*endpoint) {
-      status = CELIX_ENOMEM;
-  } else {
-      (*endpoint)->id = properties_get(endpointProperties, (char*) OSGI_RSA_ENDPOINT_ID);
-      char *serviceId = NULL;
-      serviceReference_getProperty(reference, (char*) OSGI_FRAMEWORK_SERVICE_ID, &serviceId);
-      (*endpoint)->serviceId = strtoull(serviceId, NULL, 0);
-      (*endpoint)->frameworkUUID = properties_get(endpointProperties, (char*) OSGI_RSA_ENDPOINT_FRAMEWORK_UUID);
-      (*endpoint)->service = interface;
-      (*endpoint)->properties = endpointProperties;
-  }
-
-	free(key);
-	free(serviceId);
-	free(keys);
-
-	return status;
-}
-
-static celix_status_t remoteServiceAdmin_getIpAdress(char* interface, char** ip) {
-	celix_status_t status = CELIX_BUNDLE_EXCEPTION;
-
-	struct ifaddrs *ifaddr, *ifa;
-    char host[NI_MAXHOST];
-
-    if (getifaddrs(&ifaddr) != -1)
-    {
-		for (ifa = ifaddr; ifa != NULL && status != CELIX_SUCCESS; ifa = ifa->ifa_next)
-		{
-			if (ifa->ifa_addr == NULL)
-				continue;
-
-			if ((getnameinfo(ifa->ifa_addr,sizeof(struct sockaddr_in), host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST) == 0) && (ifa->ifa_addr->sa_family == AF_INET)) {
-				if (interface == NULL) {
-					*ip = strdup(host);
-					status = CELIX_SUCCESS;
-				}
-				else if (strcmp(ifa->ifa_name, interface) == 0) {
-					*ip = strdup(host);
-					status = CELIX_SUCCESS;
-				}
-			}
-		}
-
-		freeifaddrs(ifaddr);
-    }
-
-    return status;
-}
-
-
-celix_status_t remoteServiceAdmin_destroyEndpointDescription(endpoint_description_pt *description)
-{
-	celix_status_t status = CELIX_SUCCESS;
-
-	properties_destroy((*description)->properties);
-	free(*description);
-
-	return status;
-}
-
-
-celix_status_t remoteServiceAdmin_getExportedServices(remote_service_admin_pt admin, array_list_pt *services) {
-	celix_status_t status = CELIX_SUCCESS;
-	return status;
-}
-
-celix_status_t remoteServiceAdmin_getImportedEndpoints(remote_service_admin_pt admin, array_list_pt *services) {
-	celix_status_t status = CELIX_SUCCESS;
-	return status;
-}
-
-
-static int remoteServiceAdmin_remoteFunctionProxy(ffi_cif *cif, int *ret, void* args[], void *userData); //TODO MOVE
-static int remoteServiceAdmin_remoteFunctionProxy(ffi_cif *cif, int *ret, void* args[], void *userData) {
-   void **handle = args[0];
-   remote_service_admin_pt admin = (*handle);
-
-   struct proxy *proxy = userData;
-
-   printf("ffi closure got called for method sig %s with index %i\n", proxy->sig, proxy->index);
-
-   json_t *root = json_object();
-   json_t *sig = json_string(proxy->sig);
-   json_object_set(root, "m", sig);
-
-   json_t *arguments = json_array();
-   int i;
-   for (i = 1; i < proxy->cif.nargs -1; i += 1) {
-       //NOTE assuming double
-       double *dval = args[i];
-       json_t *value = json_real(*dval);
-       json_array_append(arguments, value);
-   }
-   json_object_set(root, "a", arguments);
-
-   char *data = json_dumps(root, 0);
-   char *reply = NULL;
-   int replyStatus;
-
-   remoteServiceAdmin_send(proxy->admin, proxy->endpointDescription, data, &reply, &replyStatus);
-   (*ret) = replyStatus;
-   printf("got reply from server '%s'\n", reply);
-
-   json_error_t error;
-   json_t *js_reply = json_loads(reply, JSON_DECODE_ANY, &error);
-   if (js_reply) {
-       //note assuming double
-       double **result = args[proxy->cif.nargs - 1];
-       json_unpack(js_reply, "{s:f}", "r", *result);
-       json_decref(js_reply);
-   } else {
-       printf("PROXY: got error '%s' for '%s'\n", error.text, reply);
-   }
-
-   json_decref(root);
-
-   free(data);
-   free(reply);
-
-   return 0;
-}
-
-
-celix_status_t remoteServiceAdmin_importService(remote_service_admin_pt admin, endpoint_description_pt endpointDescription, import_registration_pt *registration) {
-	celix_status_t status = CELIX_SUCCESS;
-
-	logHelper_log(admin->loghelper, OSGI_LOGSERVICE_INFO, "RSA: Import service %s", endpointDescription->service);
-
-  char *schema = properties_get(endpointDescription->properties, "protocol.schema");
-  if (schema == NULL) {
-    logHelper_log(admin->loghelper, OSGI_LOGSERVICE_WARNING, "RSA: protocol schema not found for endpoint\n");
-    return CELIX_SUCCESS;
-  }
-
-  printf("protocol.schema is '%s'\n", schema);
-  json_error_t error;
-  json_t *js_schema = json_loads(schema, 0, &error);
-  if (js_schema) {
-      //TODO parse schema and create cif
-      size_t numOfMethods = json_array_size(js_schema);
-      printf("RSA: num of method for proxy is %i\n", (int) numOfMethods);
-
-      struct generic_service_layout *service = calloc(1, sizeof(*service) + (numOfMethods-1) * sizeof(GEN_FUNC_TYPE)); 
-      service->handle = admin;
-
-        //struct generic_service_layout {
-        //    void *handle;
-        //    GEN_FUNC_TYPE functions[];
-        //};
-
-      size_t index;
-      json_t *value;
-      json_array_foreach(js_schema, index, value) {
-          //create closure
-
-          char *sig = json_string_value(value);
-          size_t sigLength = strlen(sig);
-          char provArgs[sigLength];
-          bool startFound = false;
-          int i = 0;
-          int argIndex = 0;
-          for (; i < sigLength; i += 1) {
-              if (!startFound) {
-                  if (sig[i] == '(') {
-                      startFound = true;
-                  }
-              } else {
-                  if (sig[i] != ')') {
-                      provArgs[argIndex++] = sig[i];
-                  }
-              }
-          } 
-          provArgs[argIndex] = '\0';
-          printf("method index is %i and args are '%s'\n", index, provArgs);
-
-          int provArgLength = strlen(provArgs) -1;
-
-          struct proxy *proxy = malloc(sizeof(*proxy));
-          proxy->admin = admin;
-          proxy->sig = strdup(sig);
-          proxy->index = index;
-          proxy->endpointDescription = endpointDescription;
-          
-          ffi_type **args = calloc(provArgLength +2, sizeof(ffi_type)); //TODO test if this can be on the stack
-
-          void (*function)(void);
-          proxy->closure = ffi_closure_alloc(sizeof(ffi_closure), &function);
-          service->functions[index] = function;
-
-          /* Initialize the argument info vectors */
-          args[0] = &ffi_type_pointer;
-          args[provArgLength + 1] = &ffi_type_pointer;
-          for (i = 0; i < provArgLength; i += 1) {
-              args[i+1] = &ffi_type_double;
-          }
-
-          if (proxy->closure) {
-            if (ffi_prep_cif(&proxy->cif, FFI_DEFAULT_ABI, provArgLength + 2, &ffi_type_sint, args) == FFI_OK) {
-                if (ffi_prep_closure_loc(proxy->closure, &proxy->cif, remoteServiceAdmin_remoteFunctionProxy, proxy, function) == FFI_OK) {
-                    printf("RSA: created closure for method '%s'\n", sig);
-                }
-            }
-          }
-      }
-                   
-      //TODO register with imported properties 
-      char *objectClass = properties_get(endpointDescription->properties, "objectClass");
-      service_registration_pt reg = NULL;
-      bundleContext_registerService(admin->context, objectClass, service, NULL, &reg);
-      printf("registered proxy service with objectclass '%s'\n", objectClass);
-
-  } else {
-      printf("RSA: got error '%s' for '%s'\n", error.text, schema);
-      return CELIX_ILLEGAL_STATE;
-  }
-
-
-  //celixThreadMutex_lock(&admin->importedServicesLock);
-  //celixThreadMutex_unlock(&admin->importedServicesLock);
-
-
-  return status;
-  /*
-
-	celixThreadMutex_lock(&admin->importedServicesLock);
-
-   import_registration_factory_pt registration_factory = (import_registration_factory_pt) hashMap_get(admin->importedServices, endpointDescription->service);
-
-	// check whether we already have a registration_factory registered in the hashmap
-	if (registration_factory == NULL)
-	{
-		status = importRegistrationFactory_install(admin->loghelper, endpointDescription->service, admin->context, &registration_factory);
-		if (status == CELIX_SUCCESS) {
-		    hashMap_put(admin->importedServices, endpointDescription->service, registration_factory);
-		}
-	}
-
-	 // factory available
-	if (status != CELIX_SUCCESS || (registration_factory->trackedFactory == NULL))
-	{
-		logHelper_log(admin->loghelper, OSGI_LOGSERVICE_WARNING, "RSA: no proxyFactory available.");
-		if (status == CELIX_SUCCESS) {
-			status = CELIX_SERVICE_EXCEPTION;
-		}
-	}
-	else
-	{
-		// we create an importRegistration per imported service
-		importRegistration_create(endpointDescription, admin, (sendToHandle) &remoteServiceAdmin_send, admin->context, registration);
-		registration_factory->trackedFactory->registerProxyService(registration_factory->trackedFactory->factory,  endpointDescription, admin, (sendToHandle) &remoteServiceAdmin_send);
-
-		arrayList_add(registration_factory->registrations, *registration);
-	}
-
-    celixThreadMutex_unlock(&admin->importedServicesLock);
-
-
-	return status;
-  */
-}
-
-
-celix_status_t remoteServiceAdmin_removeImportedService(remote_service_admin_pt admin, import_registration_pt registration) {
-	celix_status_t status = CELIX_SUCCESS;
-  return status;
-  /*
-
-	endpoint_description_pt endpointDescription = (endpoint_description_pt) registration->endpointDescription;
-	import_registration_factory_pt registration_factory = NULL;
-
-    celixThreadMutex_lock(&admin->importedServicesLock);
-
-    registration_factory = (import_registration_factory_pt) hashMap_get(admin->importedServices, endpointDescription->service);
-
-    // factory available
-    if ((registration_factory == NULL) || (registration_factory->trackedFactory == NULL))
-    {
-    	logHelper_log(admin->loghelper, OSGI_LOGSERVICE_ERROR, "RSA: Error while retrieving registration factory for imported service %s", endpointDescription->service);
-    }
-    else
-    {
-		registration_factory->trackedFactory->unregisterProxyService(registration_factory->trackedFactory->factory, endpointDescription);
-		arrayList_removeElement(registration_factory->registrations, registration);
-		importRegistration_destroy(registration);
-
-		if (arrayList_isEmpty(registration_factory->registrations))
-		{
-			logHelper_log(admin->loghelper, OSGI_LOGSERVICE_INFO, "RSA: closing proxy.");
-
-			serviceTracker_close(registration_factory->proxyFactoryTracker);
-			importRegistrationFactory_close(registration_factory);
-
-			hashMap_remove(admin->importedServices, endpointDescription->service);
-
-			importRegistrationFactory_destroy(&registration_factory);
-		}
-    }
-
-    celixThreadMutex_unlock(&admin->importedServicesLock);
-
-	return status;
-  */
-}
-
-
-celix_status_t remoteServiceAdmin_send(remote_service_admin_pt rsa, endpoint_description_pt endpointDescription, char *request, char **reply, int* replyStatus) {
-
-    struct post post;
-    post.readptr = request;
-    post.size = strlen(request);
-
-    struct get get;
-    get.size = 0;
-    get.writeptr = malloc(1);
-
-    char *serviceUrl = properties_get(endpointDescription->properties, (char*) ENDPOINT_URL);
-    char url[256];
-    snprintf(url, 256, "%s", serviceUrl);
-
-    // assume the default timeout
-    int timeout = DEFAULT_TIMEOUT;
-
-    char *timeoutStr = NULL;
-    // Check if the endpoint has a timeout, if so, use it.
-	timeoutStr = properties_get(endpointDescription->properties, (char*) OSGI_RSA_REMOTE_PROXY_TIMEOUT);
-    if (timeoutStr == NULL) {
-    	// If not, get the global variable and use that one.
-    	bundleContext_getProperty(rsa->context, (char*) OSGI_RSA_REMOTE_PROXY_TIMEOUT, &timeoutStr);
-    }
-
-    // Update timeout if a property is used to set it.
-    if (timeoutStr != NULL) {
-    	timeout = atoi(timeoutStr);
-    }
-
-    celix_status_t status = CELIX_SUCCESS;
-    CURL *curl;
-    CURLcode res;
-
-    curl = curl_easy_init();
-    if(!curl) {
-        status = CELIX_ILLEGAL_STATE;
-    } else {
-    	curl_easy_setopt(curl, CURLOPT_TIMEOUT, timeout);
-        curl_easy_setopt(curl, CURLOPT_URL, &url[0]);
-        curl_easy_setopt(curl, CURLOPT_POST, 1L);
-        curl_easy_setopt(curl, CURLOPT_READFUNCTION, remoteServiceAdmin_readCallback);
-        curl_easy_setopt(curl, CURLOPT_READDATA, &post);
-        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, remoteServiceAdmin_write);
-        curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&get);
-        curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, (curl_off_t)post.size);
-        res = curl_easy_perform(curl);
-        curl_easy_cleanup(curl);
-
-        *reply = get.writeptr;
-        *replyStatus = res;
-    }
-
-    return status;
-}
-
-static size_t remoteServiceAdmin_readCallback(void *ptr, size_t size, size_t nmemb, void *userp) {
-    struct post *post = userp;
-
-    if (post->size) {
-        *(char *) ptr = post->readptr[0];
-        post->readptr++;
-        post->size--;
-        return 1;
-    }
-
-    return 0;
-}
-
-static size_t remoteServiceAdmin_write(void *contents, size_t size, size_t nmemb, void *userp) {
-  size_t realsize = size * nmemb;
-  struct get *mem = (struct get *)userp;
-
-  mem->writeptr = realloc(mem->writeptr, mem->size + realsize + 1);
-  if (mem->writeptr == NULL) {
-    /* out of memory! */
-	printf("not enough memory (realloc returned NULL)");
-    exit(EXIT_FAILURE);
-  }
-
-  memcpy(&(mem->writeptr[mem->size]), contents, realsize);
-  mem->size += realsize;
-  mem->writeptr[mem->size] = 0;
-
-  return realsize;
-}
-
-
-celix_status_t exportReference_getExportedEndpoint(export_reference_pt reference, endpoint_description_pt *endpoint) {
-	celix_status_t status = CELIX_SUCCESS;
-
-	*endpoint = reference->endpoint;
-
-	return status;
-}
-
-celix_status_t exportReference_getExportedService(export_reference_pt reference) {
-	celix_status_t status = CELIX_SUCCESS;
-	return status;
-}
-
-celix_status_t importReference_getImportedEndpoint(import_reference_pt reference) {
-	celix_status_t status = CELIX_SUCCESS;
-	return status;
-}
-
-celix_status_t importReference_getImportedService(import_reference_pt reference) {
-	celix_status_t status = CELIX_SUCCESS;
-	return status;
-}

http://git-wip-us.apache.org/repos/asf/celix/blob/da86474f/remote_services/remote_service_admin_dfi/tst/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/tst/CMakeLists.txt b/remote_services/remote_service_admin_dfi/tst/CMakeLists.txt
index a9b7b00..d0814c6 100644
--- a/remote_services/remote_service_admin_dfi/tst/CMakeLists.txt
+++ b/remote_services/remote_service_admin_dfi/tst/CMakeLists.txt
@@ -14,16 +14,22 @@ include_directories(
     SET(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE) #TODO needed?
     SET(CMAKE_INSTALL_RPATH "${PROJECT_BINARY_DIR}/framework" "${PROJECT_BINARY_DIR}/utils")
 
-	add_executable(rsa_dfi_tests
-	    ${PROJECT_SOURCE_DIR}/launcher/private/src/launcher.c
+	add_executable(test_rsa_dfi
 	    run_tests.cpp
 	    rsa_tests.cpp
+
+	    ${PROJECT_SOURCE_DIR}/launcher/private/src/launcher.c #TODO move to libframework
+	    ${PROJECT_SOURCE_DIR}/remote_services/remote_service_admin/private/src/endpoint_description.c
 	)
-	target_link_libraries(rsa_dfi_tests ${CPPUTEST_LIBRARY} celix_framework celix_utils ${CURL_LIBRARIES})
+	target_link_libraries(test_rsa_dfi ${CPPUTEST_LIBRARY} celix_framework celix_utils ${CURL_LIBRARIES})
 
 	get_property(rsa_bundle_file TARGET remote_service_admin_dfi PROPERTY BUNDLE)
-	configure_file(config.properties.in config.properties @ONLY)
+	get_property(calc_bundle_file TARGET calculator PROPERTY BUNDLE)
+    configure_file(config.properties.in config.properties @ONLY)
+
+    add_dependencies(test_rsa_dfi remote_service_admin_dfi calculator)
+
 
-	add_test(NAME run_rsa_dfi_tests COMMAND rsa_dfi_tests)
-	SETUP_TARGET_FOR_COVERAGE(rsa_dfi_tests_cov rsa_dfi_tests ${CMAKE_BINARY_DIR}/coverage/rsa_dfi)
+	add_test(NAME run_test_rsa_dfi COMMAND test_rsa_dfi)
+	SETUP_TARGET_FOR_COVERAGE(test_rsa_dfi_cov test_rsa_dfi ${CMAKE_BINARY_DIR}/coverage/rsa_dfi)
 #endif()

http://git-wip-us.apache.org/repos/asf/celix/blob/da86474f/remote_services/remote_service_admin_dfi/tst/config.properties.in
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/tst/config.properties.in b/remote_services/remote_service_admin_dfi/tst/config.properties.in
index b926f36..df5e625 100644
--- a/remote_services/remote_service_admin_dfi/tst/config.properties.in
+++ b/remote_services/remote_service_admin_dfi/tst/config.properties.in
@@ -1 +1,2 @@
-cosgi.auto.start.1=@rsa_bundle_file@
\ No newline at end of file
+cosgi.auto.start.1=@rsa_bundle_file@ @calc_bundle_file@
+LOGHELPER_ENABLE_STDOUT_FALLBACK=true
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/celix/blob/da86474f/remote_services/remote_service_admin_dfi/tst/rsa_tests.cpp
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/tst/rsa_tests.cpp b/remote_services/remote_service_admin_dfi/tst/rsa_tests.cpp
index f23babd..060b15b 100644
--- a/remote_services/remote_service_admin_dfi/tst/rsa_tests.cpp
+++ b/remote_services/remote_service_admin_dfi/tst/rsa_tests.cpp
@@ -2,7 +2,10 @@
  * Licensed under Apache License v2. See LICENSE for more information.
  */
 #include <CppUTest/TestHarness.h>
-#include "CppUTest/CommandLineTestRunner.h"                                                                                                                                                                        
+#include <remote_constants.h>
+#include <constants.h>
+#include "CppUTest/CommandLineTestRunner.h"
+#include "../../examples/calculator_service/public/include/calculator_service.h"
 
 extern "C" {
 
@@ -15,71 +18,144 @@ extern "C" {
 #include "launcher.h"
 #include "framework.h"
 #include "remote_service_admin.h"
+#include "calculator_service.h"
 
 
-framework_pt framework = NULL;
-bundle_context_pt context = NULL;
-service_reference_pt rsaRef = NULL;
-remote_service_admin_service_pt rsa = NULL;
+    framework_pt framework = NULL;
+    bundle_context_pt context = NULL;
 
-static void setupFm(void) {
-    int rc = 0;
+    service_reference_pt rsaRef = NULL;
+    remote_service_admin_service_pt rsa = NULL;
 
-    rc = celixLauncher_launch("config.properties", &framework);
-    CHECK_EQUAL(CELIX_SUCCESS, rc);
+    service_reference_pt calcRef = NULL;
+    calculator_service_pt calc = NULL;
 
-    bundle_pt bundle = NULL;
-    rc = framework_getFrameworkBundle(framework, &bundle);
-    CHECK_EQUAL(CELIX_SUCCESS, rc);
+    static void setupFm(void) {
+        int rc = 0;
 
-    rc = bundle_getContext(bundle, &context);
-    CHECK_EQUAL(CELIX_SUCCESS, rc);
+        rc = celixLauncher_launch("config.properties", &framework);
+        CHECK_EQUAL(CELIX_SUCCESS, rc);
 
-    rc = bundleContext_getServiceReference(context, (char *)OSGI_RSA_REMOTE_SERVICE_ADMIN, &rsaRef);
-    CHECK_EQUAL(CELIX_SUCCESS, rc);
+        bundle_pt bundle = NULL;
+        rc = framework_getFrameworkBundle(framework, &bundle);
+        CHECK_EQUAL(CELIX_SUCCESS, rc);
 
-    rc = bundleContext_getService(context, rsaRef, (void **)&rsa);
-    CHECK_EQUAL(CELIX_SUCCESS, rc);
-}
+        rc = bundle_getContext(bundle, &context);
+        CHECK_EQUAL(CELIX_SUCCESS, rc);
 
-static void teardownFm(void) {
-    int rc = 0;
-    rc = bundleContext_ungetService(context, rsaRef, NULL);
-    CHECK_EQUAL(CELIX_SUCCESS, rc);
+        rc = bundleContext_getServiceReference(context, (char *)OSGI_RSA_REMOTE_SERVICE_ADMIN, &rsaRef);
+        CHECK_EQUAL(CELIX_SUCCESS, rc);
+        CHECK(rsaRef != NULL);
 
-    celixLauncher_stop(framework);
-    celixLauncher_waitForShutdown(framework);
-    celixLauncher_destroy(framework);
+        rc = bundleContext_getService(context, rsaRef, (void **)&rsa);
+        CHECK_EQUAL(CELIX_SUCCESS, rc);
 
-    rsaRef = NULL;
-    rsa = NULL;
-    context = NULL;
-    framework = NULL;
-}
+        rc = bundleContext_getServiceReference(context, (char *)CALCULATOR_SERVICE, &calcRef);
+        CHECK_EQUAL(CELIX_SUCCESS, rc);
+        CHECK(calcRef != NULL);
 
-static void testInfo(void) {
-    int rc = 0;
-    array_list_pt exported = NULL;
-    array_list_pt imported = NULL;
-    arrayList_create(&exported);
-    arrayList_create(&imported);
+        rc = bundleContext_getService(context, calcRef, (void **)&calc);
+        CHECK_EQUAL(CELIX_SUCCESS, rc);
+    }
 
-    rc = rsa->getExportedServices(rsa->admin, &exported);
-    CHECK_EQUAL(CELIX_SUCCESS, rc);
-    CHECK_EQUAL(0, arrayList_size(exported));
+    static void teardownFm(void) {
+        int rc = 0;
+        rc = bundleContext_ungetService(context, rsaRef, NULL);
+        CHECK_EQUAL(CELIX_SUCCESS, rc);
 
-    rc = rsa->getImportedEndpoints(rsa->admin, &imported);
-    CHECK_EQUAL(CELIX_SUCCESS, rc);
-    CHECK_EQUAL(0, arrayList_size(imported));
-}
+        rc = bundleContext_ungetService(context, calcRef, NULL);
+        CHECK_EQUAL(CELIX_SUCCESS, rc);
 
-static void testExportService(void) {
-    //TODO
-}
+        celixLauncher_stop(framework);
+        celixLauncher_waitForShutdown(framework);
+        celixLauncher_destroy(framework);
 
-static void testImportService(void) {
-    //TODO
-}
+        rsaRef = NULL;
+        rsa = NULL;
+        calcRef = NULL;
+        calc = NULL;
+        context = NULL;
+        framework = NULL;
+    }
+
+    static void testServices(void) {
+        int rc = 0;
+        array_list_pt exported = NULL;
+        array_list_pt imported = NULL;
+        arrayList_create(&exported);
+        arrayList_create(&imported);
+
+        rc = rsa->getExportedServices(rsa->admin, &exported);
+        CHECK_EQUAL(CELIX_SUCCESS, rc);
+        CHECK_EQUAL(0, arrayList_size(exported));
+
+        rc = rsa->getImportedEndpoints(rsa->admin, &imported);
+        CHECK_EQUAL(CELIX_SUCCESS, rc);
+        CHECK_EQUAL(0, arrayList_size(imported));
+
+        double result = 0;
+        rc = calc->add(calc->calculator, 2.0, 5.0, &result);
+        CHECK_EQUAL(CELIX_SUCCESS, rc);
+        CHECK_EQUAL(7.0, result);
+    }
+
+    static void testExportService(void) {
+        int rc = 0;
+        char *calcId = NULL;
+        array_list_pt regs = NULL;
+
+        rc = arrayList_create(&regs);
+        CHECK_EQUAL(CELIX_SUCCESS, rc);
+
+        rc = serviceReference_getProperty(calcRef, (char *)"service.id", &calcId);
+        CHECK_EQUAL(CELIX_SUCCESS, rc);
+
+        rc = rsa->exportService(rsa->admin, calcId, NULL, &regs);
+        CHECK_EQUAL(CELIX_SUCCESS, rc);
+
+        CHECK_EQUAL(1, arrayList_size(regs));
+    }
+
+    static void testImportService(void) {
+        int rc = 0;
+        import_registration_pt reg = NULL;
+        endpoint_description_pt endpoint = NULL;
+
+        properties_pt props = properties_create();
+        properties_set(props, (char *)OSGI_RSA_ENDPOINT_SERVICE_ID, (char *)"42");
+        properties_set(props, (char *)OSGI_RSA_ENDPOINT_FRAMEWORK_UUID, (char *)"eec5404d-51d0-47ef-8d86-c825a8beda42");
+        properties_set(props, (char *)OSGI_RSA_ENDPOINT_ID, (char *)"eec5404d-51d0-47ef-8d86-c825a8beda42-42");
+        properties_set(props, (char *)OSGI_FRAMEWORK_OBJECTCLASS,(char *)"org.apache.celix.Example");
+
+        rc = endpointDescription_create(props, &endpoint);
+        CHECK_EQUAL(CELIX_SUCCESS, rc);
+
+        rc = rsa->importService(rsa->admin, endpoint, &reg);
+        CHECK_EQUAL(CELIX_SUCCESS, rc);
+        CHECK(reg != NULL);
+
+        service_reference_pt ref = NULL;
+        rc = bundleContext_getServiceReference(context, (char *)"org.apache.celix.Example", &ref);
+        CHECK_EQUAL(CELIX_SUCCESS, rc);
+        CHECK(ref != NULL);
+
+        /* Cannot test. uses requesting bundles descriptor
+        void *service = NULL;
+        rc = bundleContext_getService(context, ref, &service);
+        CHECK_EQUAL(CELIX_SUCCESS, rc);
+        CHECK(service != NULL);
+         */
+    }
+
+    static void testBundles(void) {
+        array_list_pt bundles = NULL;
+
+        int rc = bundleContext_getBundles(context, &bundles);
+        CHECK_EQUAL(0, rc);
+        CHECK_EQUAL(3, arrayList_size(bundles)); //framework, rsa_dfi & calc
+
+        arrayList_destroy(bundles);
+    }
 
 }
 
@@ -95,7 +171,7 @@ TEST_GROUP(RsaDfiTests) {
 };
 
 TEST(RsaDfiTests, InfoTest) {
-    testInfo();
+    testServices();
 }
 
 TEST(RsaDfiTests, ExportService) {
@@ -105,3 +181,7 @@ TEST(RsaDfiTests, ExportService) {
 TEST(RsaDfiTests, ImportService) {
     testImportService();
 }
+
+TEST(RsaDfiTests, TestBundles) {
+    testBundles();
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/celix/blob/da86474f/remote_services/remote_service_admin_http/private/src/remote_service_admin_impl.c
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_http/private/src/remote_service_admin_impl.c b/remote_services/remote_service_admin_http/private/src/remote_service_admin_impl.c
index 319c849..41d1659 100644
--- a/remote_services/remote_service_admin_http/private/src/remote_service_admin_impl.c
+++ b/remote_services/remote_service_admin_http/private/src/remote_service_admin_impl.c
@@ -679,57 +679,74 @@ celix_status_t remoteServiceAdmin_removeImportedService(remote_service_admin_pt
 
 
 celix_status_t remoteServiceAdmin_send(remote_service_admin_pt rsa, endpoint_description_pt endpointDescription, char *request, char **reply, int* replyStatus) {
+	celix_status_t status = CELIX_SUCCESS;
 
-    struct post post;
-    post.readptr = request;
-    post.size = strlen(request);
+	struct post post;
+	struct get get;
+	char url[256];
+	if (request != NULL) {
 
-    struct get get;
-    get.size = 0;
-    get.writeptr = malloc(1);
 
-    char *serviceUrl = properties_get(endpointDescription->properties, (char*) ENDPOINT_URL);
-    char url[256];
-    snprintf(url, 256, "%s", serviceUrl);
+		post.readptr = request;
+		post.size = strlen(request);
 
-    // assume the default timeout
-    int timeout = DEFAULT_TIMEOUT;
+		get.size = 0;
+		get.writeptr = malloc(1);
 
-    char *timeoutStr = NULL;
-    // Check if the endpoint has a timeout, if so, use it.
-	timeoutStr = properties_get(endpointDescription->properties, (char*) OSGI_RSA_REMOTE_PROXY_TIMEOUT);
-    if (timeoutStr == NULL) {
-    	// If not, get the global variable and use that one.
-    	bundleContext_getProperty(rsa->context, (char*) OSGI_RSA_REMOTE_PROXY_TIMEOUT, &timeoutStr);
-    }
+		char *serviceUrl = properties_get(endpointDescription->properties, (char *) ENDPOINT_URL);
+		if (serviceUrl != NULL) {
+			snprintf(url, 256, "%s", serviceUrl);
+		} else {
+			status = CELIX_BUNDLE_EXCEPTION;
+			logHelper_log(rsa->loghelper, OSGI_LOGSERVICE_INFO, "Endpoint Description does not contain mandatory property '%s'", ENDPOINT_URL);
+		}
+	} else {
+		status = CELIX_ILLEGAL_ARGUMENT;
+	}
 
-    // Update timeout if a property is used to set it.
-    if (timeoutStr != NULL) {
-    	timeout = atoi(timeoutStr);
-    }
+	// assume the default timeout
+	int timeout = DEFAULT_TIMEOUT;
 
-    celix_status_t status = CELIX_SUCCESS;
-    CURL *curl;
-    CURLcode res;
-
-    curl = curl_easy_init();
-    if(!curl) {
-        status = CELIX_ILLEGAL_STATE;
-    } else {
-    	curl_easy_setopt(curl, CURLOPT_TIMEOUT, timeout);
-        curl_easy_setopt(curl, CURLOPT_URL, &url[0]);
-        curl_easy_setopt(curl, CURLOPT_POST, 1L);
-        curl_easy_setopt(curl, CURLOPT_READFUNCTION, remoteServiceAdmin_readCallback);
-        curl_easy_setopt(curl, CURLOPT_READDATA, &post);
-        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, remoteServiceAdmin_write);
-        curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&get);
-        curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, (curl_off_t)post.size);
-        res = curl_easy_perform(curl);
-        curl_easy_cleanup(curl);
-
-        *reply = get.writeptr;
-        *replyStatus = res;
-    }
+	if (status == CELIX_SUCCESS) {
+		char *timeoutStr = NULL;
+
+		// Check if the endpoint has a timeout, if so, use it.
+		timeoutStr = properties_get(endpointDescription->properties, (char *) OSGI_RSA_REMOTE_PROXY_TIMEOUT);
+		if (timeoutStr == NULL) {
+			// If not, get the global variable and use that one.
+			status = bundleContext_getProperty(rsa->context, (char *) OSGI_RSA_REMOTE_PROXY_TIMEOUT, &timeoutStr);
+		}
+
+		// Update timeout if a property is used to set it.
+		if (timeoutStr != NULL) {
+			timeout = atoi(timeoutStr);
+		}
+	}
+
+	if (status == CELIX_SUCCESS) {
+
+		CURL *curl;
+		CURLcode res;
+
+		curl = curl_easy_init();
+		if (!curl) {
+			status = CELIX_ILLEGAL_STATE;
+		} else {
+			curl_easy_setopt(curl, CURLOPT_TIMEOUT, timeout);
+			curl_easy_setopt(curl, CURLOPT_URL, &url[0]);
+			curl_easy_setopt(curl, CURLOPT_POST, 1L);
+			curl_easy_setopt(curl, CURLOPT_READFUNCTION, remoteServiceAdmin_readCallback);
+			curl_easy_setopt(curl, CURLOPT_READDATA, &post);
+			curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, remoteServiceAdmin_write);
+			curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *) &get);
+			curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, (curl_off_t) post.size);
+			res = curl_easy_perform(curl);
+			curl_easy_cleanup(curl);
+
+			*reply = get.writeptr;
+			*replyStatus = res;
+		}
+	}
 
     return status;
 }
@@ -764,27 +781,3 @@ static size_t remoteServiceAdmin_write(void *contents, size_t size, size_t nmemb
 
   return realsize;
 }
-
-
-celix_status_t exportReference_getExportedEndpoint(export_reference_pt reference, endpoint_description_pt *endpoint) {
-	celix_status_t status = CELIX_SUCCESS;
-
-	*endpoint = reference->endpoint;
-
-	return status;
-}
-
-celix_status_t exportReference_getExportedService(export_reference_pt reference) {
-	celix_status_t status = CELIX_SUCCESS;
-	return status;
-}
-
-celix_status_t importReference_getImportedEndpoint(import_reference_pt reference) {
-	celix_status_t status = CELIX_SUCCESS;
-	return status;
-}
-
-celix_status_t importReference_getImportedService(import_reference_pt reference) {
-	celix_status_t status = CELIX_SUCCESS;
-	return status;
-}

http://git-wip-us.apache.org/repos/asf/celix/blob/da86474f/remote_services/remote_service_admin_shm/private/src/remote_service_admin_impl.c
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_shm/private/src/remote_service_admin_impl.c b/remote_services/remote_service_admin_shm/private/src/remote_service_admin_impl.c
index 7f8f97a..34b8533 100644
--- a/remote_services/remote_service_admin_shm/private/src/remote_service_admin_impl.c
+++ b/remote_services/remote_service_admin_shm/private/src/remote_service_admin_impl.c
@@ -863,28 +863,4 @@ celix_status_t remoteServiceAdmin_removeImportedService(remote_service_admin_pt
     }
 
     return status;
-}
-
-celix_status_t exportReference_getExportedEndpoint(export_reference_pt reference, endpoint_description_pt *endpoint) {
-    celix_status_t status = CELIX_SUCCESS;
-
-    *endpoint = reference->endpoint;
-
-    return status;
-}
-
-celix_status_t exportReference_getExportedService(export_reference_pt reference) {
-    celix_status_t status = CELIX_SUCCESS;
-    return status;
-}
-
-celix_status_t importReference_getImportedEndpoint(import_reference_pt reference) {
-    celix_status_t status = CELIX_SUCCESS;
-    return status;
-}
-
-celix_status_t importReference_getImportedService(import_reference_pt reference) {
-    celix_status_t status = CELIX_SUCCESS;
-    return status;
-}
-
+}
\ No newline at end of file