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 2017/11/21 20:07:58 UTC
[01/19] celix git commit: CELIX-417: Refactor for CMake usage in RSA,
PSA and Docker. mostly trying to identify the api and common libraries
Repository: celix
Updated Branches:
refs/heads/feature/CELIX-417-cmake-refactor a1c308879 -> 2a670f265
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/utils/private/src/md5.inl
----------------------------------------------------------------------
diff --git a/remote_services/utils/private/src/md5.inl b/remote_services/utils/private/src/md5.inl
deleted file mode 100644
index 4da933d..0000000
--- a/remote_services/utils/private/src/md5.inl
+++ /dev/null
@@ -1,461 +0,0 @@
-/*
- * This an amalgamation of md5.c and md5.h into a single file
- * with all static declaration to reduce linker conflicts
- * in Civetweb.
- *
- * The MD5_STATIC declaration was added to facilitate static
- * inclusion.
- * No Face Press, LLC
- */
-
-/* $Id: md5.h,v 1.4 2002/04/13 19:20:28 lpd Exp $ */
-/*
- Independent implementation of MD5 (RFC 1321).
-
- This code implements the MD5 Algorithm defined in RFC 1321, whose
- text is available at
- http://www.ietf.org/rfc/rfc1321.txt
- The code is derived from the text of the RFC, including the test suite
- (section A.5) but excluding the rest of Appendix A. It does not include
- any code or documentation that is identified in the RFC as being
- copyrighted.
-
- The original and principal author of md5.h is L. Peter Deutsch
- <gh...@aladdin.com>. Other authors are noted in the change history
- that follows (in reverse chronological order):
-
- 2002-04-13 lpd Removed support for non-ANSI compilers; removed
- references to Ghostscript; clarified derivation from RFC 1321;
- now handles byte order either statically or dynamically.
- 1999-11-04 lpd Edited comments slightly for automatic TOC extraction.
- 1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5);
- added conditionalization for C++ compilation from Martin
- Purschke <pu...@bnl.gov>.
- 1999-05-03 lpd Original version.
- */
-
-#ifndef md5_INCLUDED
-# define md5_INCLUDED
-
-/*
- * This package supports both compile-time and run-time determination of CPU
- * byte order. If ARCH_IS_BIG_ENDIAN is defined as 0, the code will be
- * compiled to run only on little-endian CPUs; if ARCH_IS_BIG_ENDIAN is
- * defined as non-zero, the code will be compiled to run only on big-endian
- * CPUs; if ARCH_IS_BIG_ENDIAN is not defined, the code will be compiled to
- * run on either big- or little-endian CPUs, but will run slightly less
- * efficiently on either one than if ARCH_IS_BIG_ENDIAN is defined.
- */
-
-typedef unsigned char md5_byte_t; /* 8-bit byte */
-typedef unsigned int md5_word_t; /* 32-bit word */
-
-/* Define the state of the MD5 Algorithm. */
-typedef struct md5_state_s {
- md5_word_t count[2]; /* message length in bits, lsw first */
- md5_word_t abcd[4]; /* digest buffer */
- md5_byte_t buf[64]; /* accumulate block */
-} md5_state_t;
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-
-/* Initialize the algorithm. */
-MD5_STATIC void md5_init(md5_state_t *pms);
-
-/* Append a string to the message. */
-MD5_STATIC void md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes);
-
-/* Finish the message and return the digest. */
-MD5_STATIC void md5_finish(md5_state_t *pms, md5_byte_t digest[16]);
-
-#ifdef __cplusplus
-} /* end extern "C" */
-#endif
-
-#endif /* md5_INCLUDED */
-
-/*
- Copyright (C) 1999, 2000, 2002 Aladdin Enterprises. All rights reserved.
-
- This software is provided 'as-is', without any express or implied
- warranty. In no event will the authors be held liable for any damages
- arising from the use of this software.
-
- Permission is granted to anyone to use this software for any purpose,
- including commercial applications, and to alter it and redistribute it
- freely, subject to the following restrictions:
-
- 1. The origin of this software must not be misrepresented; you must not
- claim that you wrote the original software. If you use this software
- in a product, an acknowledgment in the product documentation would be
- appreciated but is not required.
- 2. Altered source versions must be plainly marked as such, and must not be
- misrepresented as being the original software.
- 3. This notice may not be removed or altered from any source distribution.
-
- L. Peter Deutsch
- ghost@aladdin.com
-
- */
-/* $Id: md5.c,v 1.6 2002/04/13 19:20:28 lpd Exp $ */
-/*
- Independent implementation of MD5 (RFC 1321).
-
- This code implements the MD5 Algorithm defined in RFC 1321, whose
- text is available at
- http://www.ietf.org/rfc/rfc1321.txt
- The code is derived from the text of the RFC, including the test suite
- (section A.5) but excluding the rest of Appendix A. It does not include
- any code or documentation that is identified in the RFC as being
- copyrighted.
-
- The original and principal author of md5.c is L. Peter Deutsch
- <gh...@aladdin.com>. Other authors are noted in the change history
- that follows (in reverse chronological order):
-
- 2002-04-13 lpd Clarified derivation from RFC 1321; now handles byte order
- either statically or dynamically; added missing #include <string.h>
- in library.
- 2002-03-11 lpd Corrected argument list for main(), and added int return
- type, in test program and T value program.
- 2002-02-21 lpd Added missing #include <stdio.h> in test program.
- 2000-07-03 lpd Patched to eliminate warnings about "constant is
- unsigned in ANSI C, signed in traditional"; made test program
- self-checking.
- 1999-11-04 lpd Edited comments slightly for automatic TOC extraction.
- 1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5).
- 1999-05-03 lpd Original version.
- */
-
-#ifndef MD5_STATIC
-#include <string.h>
-#endif
-
-#undef BYTE_ORDER /* 1 = big-endian, -1 = little-endian, 0 = unknown */
-#ifdef ARCH_IS_BIG_ENDIAN
-# define BYTE_ORDER (ARCH_IS_BIG_ENDIAN ? 1 : -1)
-#else
-# define BYTE_ORDER 0
-#endif
-
-#define T_MASK ((md5_word_t)~0)
-#define T1 /* 0xd76aa478 */ (T_MASK ^ 0x28955b87)
-#define T2 /* 0xe8c7b756 */ (T_MASK ^ 0x173848a9)
-#define T3 0x242070db
-#define T4 /* 0xc1bdceee */ (T_MASK ^ 0x3e423111)
-#define T5 /* 0xf57c0faf */ (T_MASK ^ 0x0a83f050)
-#define T6 0x4787c62a
-#define T7 /* 0xa8304613 */ (T_MASK ^ 0x57cfb9ec)
-#define T8 /* 0xfd469501 */ (T_MASK ^ 0x02b96afe)
-#define T9 0x698098d8
-#define T10 /* 0x8b44f7af */ (T_MASK ^ 0x74bb0850)
-#define T11 /* 0xffff5bb1 */ (T_MASK ^ 0x0000a44e)
-#define T12 /* 0x895cd7be */ (T_MASK ^ 0x76a32841)
-#define T13 0x6b901122
-#define T14 /* 0xfd987193 */ (T_MASK ^ 0x02678e6c)
-#define T15 /* 0xa679438e */ (T_MASK ^ 0x5986bc71)
-#define T16 0x49b40821
-#define T17 /* 0xf61e2562 */ (T_MASK ^ 0x09e1da9d)
-#define T18 /* 0xc040b340 */ (T_MASK ^ 0x3fbf4cbf)
-#define T19 0x265e5a51
-#define T20 /* 0xe9b6c7aa */ (T_MASK ^ 0x16493855)
-#define T21 /* 0xd62f105d */ (T_MASK ^ 0x29d0efa2)
-#define T22 0x02441453
-#define T23 /* 0xd8a1e681 */ (T_MASK ^ 0x275e197e)
-#define T24 /* 0xe7d3fbc8 */ (T_MASK ^ 0x182c0437)
-#define T25 0x21e1cde6
-#define T26 /* 0xc33707d6 */ (T_MASK ^ 0x3cc8f829)
-#define T27 /* 0xf4d50d87 */ (T_MASK ^ 0x0b2af278)
-#define T28 0x455a14ed
-#define T29 /* 0xa9e3e905 */ (T_MASK ^ 0x561c16fa)
-#define T30 /* 0xfcefa3f8 */ (T_MASK ^ 0x03105c07)
-#define T31 0x676f02d9
-#define T32 /* 0x8d2a4c8a */ (T_MASK ^ 0x72d5b375)
-#define T33 /* 0xfffa3942 */ (T_MASK ^ 0x0005c6bd)
-#define T34 /* 0x8771f681 */ (T_MASK ^ 0x788e097e)
-#define T35 0x6d9d6122
-#define T36 /* 0xfde5380c */ (T_MASK ^ 0x021ac7f3)
-#define T37 /* 0xa4beea44 */ (T_MASK ^ 0x5b4115bb)
-#define T38 0x4bdecfa9
-#define T39 /* 0xf6bb4b60 */ (T_MASK ^ 0x0944b49f)
-#define T40 /* 0xbebfbc70 */ (T_MASK ^ 0x4140438f)
-#define T41 0x289b7ec6
-#define T42 /* 0xeaa127fa */ (T_MASK ^ 0x155ed805)
-#define T43 /* 0xd4ef3085 */ (T_MASK ^ 0x2b10cf7a)
-#define T44 0x04881d05
-#define T45 /* 0xd9d4d039 */ (T_MASK ^ 0x262b2fc6)
-#define T46 /* 0xe6db99e5 */ (T_MASK ^ 0x1924661a)
-#define T47 0x1fa27cf8
-#define T48 /* 0xc4ac5665 */ (T_MASK ^ 0x3b53a99a)
-#define T49 /* 0xf4292244 */ (T_MASK ^ 0x0bd6ddbb)
-#define T50 0x432aff97
-#define T51 /* 0xab9423a7 */ (T_MASK ^ 0x546bdc58)
-#define T52 /* 0xfc93a039 */ (T_MASK ^ 0x036c5fc6)
-#define T53 0x655b59c3
-#define T54 /* 0x8f0ccc92 */ (T_MASK ^ 0x70f3336d)
-#define T55 /* 0xffeff47d */ (T_MASK ^ 0x00100b82)
-#define T56 /* 0x85845dd1 */ (T_MASK ^ 0x7a7ba22e)
-#define T57 0x6fa87e4f
-#define T58 /* 0xfe2ce6e0 */ (T_MASK ^ 0x01d3191f)
-#define T59 /* 0xa3014314 */ (T_MASK ^ 0x5cfebceb)
-#define T60 0x4e0811a1
-#define T61 /* 0xf7537e82 */ (T_MASK ^ 0x08ac817d)
-#define T62 /* 0xbd3af235 */ (T_MASK ^ 0x42c50dca)
-#define T63 0x2ad7d2bb
-#define T64 /* 0xeb86d391 */ (T_MASK ^ 0x14792c6e)
-
-
-static void
-md5_process(md5_state_t *pms, const md5_byte_t *data /*[64]*/)
-{
- md5_word_t
- a = pms->abcd[0], b = pms->abcd[1],
- c = pms->abcd[2], d = pms->abcd[3];
- md5_word_t t;
-#if BYTE_ORDER > 0
- /* Define storage only for big-endian CPUs. */
- md5_word_t X[16];
-#else
- /* Define storage for little-endian or both types of CPUs. */
- md5_word_t xbuf[16];
- const md5_word_t *X;
-#endif
-
- {
-#if BYTE_ORDER == 0
- /*
- * Determine dynamically whether this is a big-endian or
- * little-endian machine, since we can use a more efficient
- * algorithm on the latter.
- */
- static const int w = 1;
-
- if (*((const md5_byte_t *)&w)) /* dynamic little-endian */
-#endif
-#if BYTE_ORDER <= 0 /* little-endian */
- {
- /*
- * On little-endian machines, we can process properly aligned
- * data without copying it.
- */
- if (!((data - (const md5_byte_t *)0) & 3)) {
- /* data are properly aligned */
- X = (const md5_word_t *)data;
- } else {
- /* not aligned */
- memcpy(xbuf, data, 64);
- X = xbuf;
- }
- }
-#endif
-#if BYTE_ORDER == 0
- else /* dynamic big-endian */
-#endif
-#if BYTE_ORDER >= 0 /* big-endian */
- {
- /*
- * On big-endian machines, we must arrange the bytes in the
- * right order.
- */
- const md5_byte_t *xp = data;
- int i;
-
-# if BYTE_ORDER == 0
- X = xbuf; /* (dynamic only) */
-# else
-# define xbuf X /* (static only) */
-# endif
- for (i = 0; i < 16; ++i, xp += 4)
- xbuf[i] = xp[0] + (xp[1] << 8) + (xp[2] << 16) + (xp[3] << 24);
- }
-#endif
- }
-
-#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
-
- /* Round 1. */
- /* Let [abcd k s i] denote the operation
- a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */
-#define F(x, y, z) (((x) & (y)) | (~(x) & (z)))
-#define SET(a, b, c, d, k, s, Ti)\
- t = a + F(b,c,d) + X[k] + Ti;\
- a = ROTATE_LEFT(t, s) + b
- /* Do the following 16 operations. */
- SET(a, b, c, d, 0, 7, T1);
- SET(d, a, b, c, 1, 12, T2);
- SET(c, d, a, b, 2, 17, T3);
- SET(b, c, d, a, 3, 22, T4);
- SET(a, b, c, d, 4, 7, T5);
- SET(d, a, b, c, 5, 12, T6);
- SET(c, d, a, b, 6, 17, T7);
- SET(b, c, d, a, 7, 22, T8);
- SET(a, b, c, d, 8, 7, T9);
- SET(d, a, b, c, 9, 12, T10);
- SET(c, d, a, b, 10, 17, T11);
- SET(b, c, d, a, 11, 22, T12);
- SET(a, b, c, d, 12, 7, T13);
- SET(d, a, b, c, 13, 12, T14);
- SET(c, d, a, b, 14, 17, T15);
- SET(b, c, d, a, 15, 22, T16);
-#undef SET
-
- /* Round 2. */
- /* Let [abcd k s i] denote the operation
- a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */
-#define G(x, y, z) (((x) & (z)) | ((y) & ~(z)))
-#define SET(a, b, c, d, k, s, Ti)\
- t = a + G(b,c,d) + X[k] + Ti;\
- a = ROTATE_LEFT(t, s) + b
- /* Do the following 16 operations. */
- SET(a, b, c, d, 1, 5, T17);
- SET(d, a, b, c, 6, 9, T18);
- SET(c, d, a, b, 11, 14, T19);
- SET(b, c, d, a, 0, 20, T20);
- SET(a, b, c, d, 5, 5, T21);
- SET(d, a, b, c, 10, 9, T22);
- SET(c, d, a, b, 15, 14, T23);
- SET(b, c, d, a, 4, 20, T24);
- SET(a, b, c, d, 9, 5, T25);
- SET(d, a, b, c, 14, 9, T26);
- SET(c, d, a, b, 3, 14, T27);
- SET(b, c, d, a, 8, 20, T28);
- SET(a, b, c, d, 13, 5, T29);
- SET(d, a, b, c, 2, 9, T30);
- SET(c, d, a, b, 7, 14, T31);
- SET(b, c, d, a, 12, 20, T32);
-#undef SET
-
- /* Round 3. */
- /* Let [abcd k s t] denote the operation
- a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). */
-#define H(x, y, z) ((x) ^ (y) ^ (z))
-#define SET(a, b, c, d, k, s, Ti)\
- t = a + H(b,c,d) + X[k] + Ti;\
- a = ROTATE_LEFT(t, s) + b
- /* Do the following 16 operations. */
- SET(a, b, c, d, 5, 4, T33);
- SET(d, a, b, c, 8, 11, T34);
- SET(c, d, a, b, 11, 16, T35);
- SET(b, c, d, a, 14, 23, T36);
- SET(a, b, c, d, 1, 4, T37);
- SET(d, a, b, c, 4, 11, T38);
- SET(c, d, a, b, 7, 16, T39);
- SET(b, c, d, a, 10, 23, T40);
- SET(a, b, c, d, 13, 4, T41);
- SET(d, a, b, c, 0, 11, T42);
- SET(c, d, a, b, 3, 16, T43);
- SET(b, c, d, a, 6, 23, T44);
- SET(a, b, c, d, 9, 4, T45);
- SET(d, a, b, c, 12, 11, T46);
- SET(c, d, a, b, 15, 16, T47);
- SET(b, c, d, a, 2, 23, T48);
-#undef SET
-
- /* Round 4. */
- /* Let [abcd k s t] denote the operation
- a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s). */
-#define I(x, y, z) ((y) ^ ((x) | ~(z)))
-#define SET(a, b, c, d, k, s, Ti)\
- t = a + I(b,c,d) + X[k] + Ti;\
- a = ROTATE_LEFT(t, s) + b
- /* Do the following 16 operations. */
- SET(a, b, c, d, 0, 6, T49);
- SET(d, a, b, c, 7, 10, T50);
- SET(c, d, a, b, 14, 15, T51);
- SET(b, c, d, a, 5, 21, T52);
- SET(a, b, c, d, 12, 6, T53);
- SET(d, a, b, c, 3, 10, T54);
- SET(c, d, a, b, 10, 15, T55);
- SET(b, c, d, a, 1, 21, T56);
- SET(a, b, c, d, 8, 6, T57);
- SET(d, a, b, c, 15, 10, T58);
- SET(c, d, a, b, 6, 15, T59);
- SET(b, c, d, a, 13, 21, T60);
- SET(a, b, c, d, 4, 6, T61);
- SET(d, a, b, c, 11, 10, T62);
- SET(c, d, a, b, 2, 15, T63);
- SET(b, c, d, a, 9, 21, T64);
-#undef SET
-
- /* Then perform the following additions. (That is increment each
- of the four registers by the value it had before this block
- was started.) */
- pms->abcd[0] += a;
- pms->abcd[1] += b;
- pms->abcd[2] += c;
- pms->abcd[3] += d;
-}
-
-MD5_STATIC void
-md5_init(md5_state_t *pms)
-{
- pms->count[0] = pms->count[1] = 0;
- pms->abcd[0] = 0x67452301;
- pms->abcd[1] = /*0xefcdab89*/ T_MASK ^ 0x10325476;
- pms->abcd[2] = /*0x98badcfe*/ T_MASK ^ 0x67452301;
- pms->abcd[3] = 0x10325476;
-}
-
-MD5_STATIC void
-md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes)
-{
- const md5_byte_t *p = data;
- int left = nbytes;
- int offset = (pms->count[0] >> 3) & 63;
- md5_word_t nbits = (md5_word_t)(nbytes << 3);
-
- if (nbytes <= 0)
- return;
-
- /* Update the message length. */
- pms->count[1] += nbytes >> 29;
- pms->count[0] += nbits;
- if (pms->count[0] < nbits)
- pms->count[1]++;
-
- /* Process an initial partial block. */
- if (offset) {
- int copy = (offset + nbytes > 64 ? 64 - offset : nbytes);
-
- memcpy(pms->buf + offset, p, copy);
- if (offset + copy < 64)
- return;
- p += copy;
- left -= copy;
- md5_process(pms, pms->buf);
- }
-
- /* Process full blocks. */
- for (; left >= 64; p += 64, left -= 64)
- md5_process(pms, p);
-
- /* Process a final partial block. */
- if (left)
- memcpy(pms->buf, p, left);
-}
-
-MD5_STATIC void
-md5_finish(md5_state_t *pms, md5_byte_t digest[16])
-{
- static const md5_byte_t pad[64] = {
- 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- };
- md5_byte_t data[8];
- int i;
-
- /* Save the length before padding. */
- for (i = 0; i < 8; ++i)
- data[i] = (md5_byte_t)(pms->count[i >> 2] >> ((i & 3) << 3));
- /* Pad to 56 bytes mod 64. */
- md5_append(pms, pad, ((55 - (pms->count[0] >> 3)) & 63) + 1);
- /* Append the length. */
- md5_append(pms, data, 8);
- for (i = 0; i < 16; ++i)
- digest[i] = (md5_byte_t)(pms->abcd[i >> 2] >> ((i & 3) << 3));
-}
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/shell/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/shell/CMakeLists.txt b/shell/CMakeLists.txt
index 31822c4..ae8cf3f 100644
--- a/shell/CMakeLists.txt
+++ b/shell/CMakeLists.txt
@@ -39,7 +39,7 @@ if (SHELL)
src/help_command
)
target_include_directories(shell PRIVATE src ${CURL_INCLUDE_DIRS})
- target_link_libraries(shell PRIVATE Celix::shell_api ${CURL_LIBRARIES} Celix::log_service_api log_helper)
+ target_link_libraries(shell PRIVATE Celix::shell_api ${CURL_LIBRARIES} Celix::log_service_api Celix::log_helper)
install_bundle(shell
HEADERS
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/shell/README.md
----------------------------------------------------------------------
diff --git a/shell/README.md b/shell/README.md
index 76f1cc7..a20450c 100644
--- a/shell/README.md
+++ b/shell/README.md
@@ -30,4 +30,5 @@ ANSI colors when printing info. default is true.
## Using info
If the Celix Shell is installed The `FindCelix.cmake` will set:
- - The `Celix::dependency_manager_cxx_static` library target
+ - The `Celix::shell_api` interface (i.e. header only) library target
+ - The `Celix::shell` bundle target
[06/19] celix git commit: CELIX-417: Refactor for CMake usage in RSA,
PSA and Docker. mostly trying to identify the api and common libraries
Posted by pn...@apache.org.
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/remote_service_admin_dfi/rsa/private/src/remote_service_admin_dfi.c
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/rsa/private/src/remote_service_admin_dfi.c b/remote_services/remote_service_admin_dfi/rsa/private/src/remote_service_admin_dfi.c
deleted file mode 100644
index 9feab9f..0000000
--- a/remote_services/remote_service_admin_dfi/rsa/private/src/remote_service_admin_dfi.c
+++ /dev/null
@@ -1,775 +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 <netdb.h>
-#include <ifaddrs.h>
-#include <string.h>
-#include <uuid/uuid.h>
-#include <curl/curl.h>
-
-#include <jansson.h>
-#include "json_serializer.h"
-#include "remote_service_admin.h"
-#include "celix_threads.h"
-#include "hash_map.h"
-#include "array_list.h"
-
-#include "import_registration_dfi.h"
-#include "export_registration_dfi.h"
-#include "remote_service_admin_dfi.h"
-#include "dyn_interface.h"
-#include "json_rpc.h"
-
-#include "remote_constants.h"
-#include "constants.h"
-#include "civetweb.h"
-
-// defines how often the webserver is restarted (with an increased port number)
-#define MAX_NUMBER_OF_RESTARTS 5
-
-
-#define RSA_LOG_ERROR(admin, msg, ...) \
- logHelper_log((admin)->loghelper, OSGI_LOGSERVICE_ERROR, (msg), ##__VA_ARGS__)
-
-#define RSA_LOG_WARNING(admin, msg, ...) \
- logHelper_log((admin)->loghelper, OSGI_LOGSERVICE_ERROR, (msg), ##__VA_ARGS__)
-
-#define RSA_LOG_DEBUG(admin, msg, ...) \
- logHelper_log((admin)->loghelper, OSGI_LOGSERVICE_ERROR, (msg), ##__VA_ARGS__)
-
-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;
- array_list_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, properties_pt props, char *interface, endpoint_description_pt *description);
-static celix_status_t remoteServiceAdmin_send(void *handle, endpoint_description_pt endpointDescription, char *request, char **reply, int* replyStatus);
-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;
- const char *port = NULL;
- const char *ip = NULL;
- char *detectedIp = NULL;
- (*admin)->context = context;
- (*admin)->exportedServices = hashMap_create(NULL, NULL, NULL, NULL);
- arrayList_create(&(*admin)->importedServices);
-
- 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, 1);
- dynType_logSetup((void *)remoteServiceAdmin_log, *admin, 1);
- dynFunction_logSetup((void *)remoteServiceAdmin_log, *admin, 1);
- dynInterface_logSetup((void *)remoteServiceAdmin_log, *admin, 1);
- jsonSerializer_logSetup((void *)remoteServiceAdmin_log, *admin, 1);
- jsonRpc_logSetup((void *)remoteServiceAdmin_log, *admin, 1);
- }
-
- bundleContext_getProperty(context, "RSA_PORT", &port);
- if (port == NULL) {
- port = (char *)DEFAULT_PORT;
- }
-
- bundleContext_getProperty(context, "RSA_IP", &ip);
- if (ip == NULL) {
- const char *interface = NULL;
-
- bundleContext_getProperty(context, "RSA_INTERFACE", &interface);
- if ((interface != NULL) && (remoteServiceAdmin_getIpAdress((char*)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 = strdup((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;
-
- char newPort[10];
-
- do {
-
- const char *options[] = { "listening_ports", port, "num_threads", "5", 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 {
- errno = 0;
- char* endptr = (char*)port;
- int currentPort = strtol(port, &endptr, 10);
-
- 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);
- exportRegistration_destroy(export);
- }
- }
- arrayList_destroy(exports);
- }
- hashMapIterator_destroy(iter);
- celixThreadMutex_unlock(&admin->exportedServicesLock);
-
- celixThreadMutex_lock(&admin->importedServicesLock);
- int i;
- int size = arrayList_size(admin->importedServices);
- for (i = 0; i < size ; i += 1) {
- import_registration_pt import = arrayList_get(admin->importedServices, i);
- if (import != NULL) {
- importRegistration_stop(import);
- importRegistration_destroy(import);
- }
- }
- 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);
- arrayList_destroy(admin->importedServices);
-
- 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 = 1; // 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';
- unsigned long serviceId = strtoul(service,NULL,10);
-
- 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;
- free(ref);
- break;
- }
- free(ref);
- }
- }
- 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);
- if (rc != CELIX_SUCCESS) {
- RSA_LOG_ERROR(rsa, "Error trying to invoke remove service, got error %i\n", rc);
- }
-
- if (rc == CELIX_SUCCESS && response != NULL) {
- mg_write(conn, data_response_headers, strlen(data_response_headers));
- mg_write(conn, response, strlen(response));
- free(response);
- } else {
- mg_write(conn, no_content_response_headers, strlen(no_content_response_headers));
- }
- result = 1;
-
- free(data);
- } else {
- result = 0;
- RSA_LOG_WARNING(rsa, "NO export registration found for service id %lu", serviceId);
- }
-
- 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;
-
- 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);
-
- int i;
- int size = arrayList_size(references);
- for (i = 0; i < size; i += 1) {
- if (i == 0) {
- reference = arrayList_get(references, i);
- } else {
- bundleContext_ungetServiceReference(admin->context, arrayList_get(references, i));
- }
- }
- 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;
- }
-
- const char *exports = NULL;
- const 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;
- } else {
- logHelper_log(admin->loghelper, OSGI_LOGSERVICE_INFO, "RSA: Export service (%s)", provided);
- }
- }
-
- if (status == CELIX_SUCCESS) {
- const char *interface = provided;
- endpoint_description_pt endpoint = NULL;
- export_registration_pt registration = NULL;
-
- remoteServiceAdmin_createEndpointDescription(admin, reference, properties, (char*)interface, &endpoint);
- //TODO precheck if descriptor exists
- status = exportRegistration_create(admin->loghelper, reference, endpoint, admin->context, ®istration);
- 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);
- }
- else{
- arrayList_destroy(*registrations);
- *registrations = NULL;
- }
-
- return status;
-}
-
-celix_status_t remoteServiceAdmin_removeExportedService(remote_service_admin_pt admin, export_registration_pt registration) {
- celix_status_t status;
-
- logHelper_log(admin->loghelper, OSGI_LOGSERVICE_INFO, "RSA_DFI: Removing exported service");
-
- export_reference_pt ref = NULL;
- status = exportRegistration_getExportReference(registration, &ref);
-
- if (status == CELIX_SUCCESS && ref != NULL) {
- service_reference_pt servRef;
- celixThreadMutex_lock(&admin->exportedServicesLock);
- exportReference_getExportedService(ref, &servRef);
-
- array_list_pt exports = (array_list_pt)hashMap_remove(admin->exportedServices, servRef);
- if(exports!=NULL){
- arrayList_destroy(exports);
- }
-
- exportRegistration_close(registration);
- exportRegistration_destroy(registration);
-
- celixThreadMutex_unlock(&admin->exportedServicesLock);
-
- free(ref);
-
- } else {
- logHelper_log(admin->loghelper, OSGI_LOGSERVICE_ERROR, "Cannot find reference for registration");
- }
-
- return status;
-}
-
-static celix_status_t remoteServiceAdmin_createEndpointDescription(remote_service_admin_pt admin, service_reference_pt reference, properties_pt props, 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];
- const 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);
- }
- }
-
- 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);
- const 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);
-
- if (props != NULL) {
- hash_map_iterator_pt propIter = hashMapIterator_create(props);
- while (hashMapIterator_hasNext(propIter)) {
- hash_map_entry_pt entry = hashMapIterator_nextEntry(propIter);
- properties_set(endpointProperties, (char*)hashMapEntry_getKey(entry), (char*)hashMapEntry_getValue(entry));
- }
- hashMapIterator_destroy(propIter);
- }
-
- *endpoint = calloc(1, sizeof(**endpoint));
- if (!*endpoint) {
- status = CELIX_ENOMEM;
- } else {
- (*endpoint)->id = (char*)properties_get(endpointProperties, (char*) OSGI_RSA_ENDPOINT_ID);
- const char *serviceId = NULL;
- serviceReference_getProperty(reference, (char*) OSGI_FRAMEWORK_SERVICE_ID, &serviceId);
- (*endpoint)->serviceId = strtoull(serviceId, NULL, 0);
- (*endpoint)->frameworkUUID = (char*) properties_get(endpointProperties, (char*) OSGI_RSA_ENDPOINT_FRAMEWORK_UUID);
- (*endpoint)->service = strndup(interface, 1024*10);
- (*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)->service);
- 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;
- import_registration_pt import = NULL;
-
- const char *objectClass = properties_get(endpointDescription->properties, "objectClass");
- const char *serviceVersion = properties_get(endpointDescription->properties, (char*) CELIX_FRAMEWORK_SERVICE_VERSION);
-
- logHelper_log(admin->loghelper, OSGI_LOGSERVICE_INFO, "RSA: Import service %s", endpointDescription->service);
- logHelper_log(admin->loghelper, OSGI_LOGSERVICE_INFO, "Registering service factory (proxy) for service '%s'\n", objectClass);
-
- if (objectClass != NULL) {
- status = importRegistration_create(admin->context, endpointDescription, objectClass, serviceVersion, &import);
- }
- if (status == CELIX_SUCCESS && import != NULL) {
- importRegistration_setSendFn(import, (send_func_type) remoteServiceAdmin_send, admin);
- }
-
- if (status == CELIX_SUCCESS && import != NULL) {
- status = importRegistration_start(import);
- }
-
- celixThreadMutex_lock(&admin->importedServicesLock);
- arrayList_add(admin->importedServices, import);
- 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;
- logHelper_log(admin->loghelper, OSGI_LOGSERVICE_INFO, "RSA_DFI: Removing imported service");
-
- celixThreadMutex_lock(&admin->importedServicesLock);
- int i;
- int size = arrayList_size(admin->importedServices);
- import_registration_pt current = NULL;
- for (i = 0; i < size; i += 1) {
- current = arrayList_get(admin->importedServices, i);
- if (current == registration) {
- arrayList_remove(admin->importedServices, i);
- importRegistration_close(current);
- importRegistration_destroy(current);
- break;
- }
- }
- celixThreadMutex_unlock(&admin->importedServicesLock);
-
- return status;
-}
-
-
-static celix_status_t remoteServiceAdmin_send(void *handle, endpoint_description_pt endpointDescription, char *request, char **reply, int* replyStatus) {
- remote_service_admin_pt rsa = handle;
- struct post post;
- post.readptr = request;
- post.size = strlen(request);
-
- struct get get;
- get.size = 0;
- get.writeptr = malloc(1);
-
- char *serviceUrl = (char*)properties_get(endpointDescription->properties, (char*) ENDPOINT_URL);
- char url[256];
- snprintf(url, 256, "%s", serviceUrl);
-
- // assume the default timeout
- int timeout = DEFAULT_TIMEOUT;
-
- const char *timeoutStr = NULL;
- // Check if the endpoint has a timeout, if so, use it.
- timeoutStr = (char*) 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_NOSIGNAL, 1);
- curl_easy_setopt(curl, CURLOPT_TIMEOUT, timeout);
- curl_easy_setopt(curl, CURLOPT_URL, url);
- 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);
- logHelper_log(rsa->loghelper, OSGI_LOGSERVICE_DEBUG, "RSA: Performing curl post\n");
- res = curl_easy_perform(curl);
-
- *reply = get.writeptr;
- *replyStatus = res;
-
- curl_easy_cleanup(curl);
- }
-
- 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);
- va_end(ap);
-}
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/remote_service_admin_dfi/rsa/src/dfi_utils.c
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/rsa/src/dfi_utils.c b/remote_services/remote_service_admin_dfi/rsa/src/dfi_utils.c
new file mode 100644
index 0000000..1b1eb36
--- /dev/null
+++ b/remote_services/remote_service_admin_dfi/rsa/src/dfi_utils.c
@@ -0,0 +1,98 @@
+/**
+ *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.
+ */
+
+#include "dfi_utils.h"
+#include <stdlib.h>
+#include <unistd.h>
+
+static celix_status_t dfi_findFileForFramework(bundle_context_pt context, const char *fileName, FILE **out) {
+ celix_status_t status;
+
+ char pwd[1024];
+ char path[1024];
+ const char *extPath = NULL;
+
+ status = bundleContext_getProperty(context, "CELIX_FRAMEWORK_EXTENDER_PATH", &extPath);
+ if (status != CELIX_SUCCESS || extPath == NULL) {
+ getcwd(pwd, sizeof(pwd));
+ extPath = pwd;
+ }
+
+ snprintf(path, sizeof(path), "%s/%s", extPath, fileName);
+
+ if (status == CELIX_SUCCESS) {
+ FILE *df = fopen(path, "r");
+ if (df == NULL) {
+ status = CELIX_FILE_IO_EXCEPTION;
+ } else {
+ *out = df;
+ }
+ }
+
+ return status;
+}
+
+static celix_status_t dfi_findFileForBundle(bundle_pt bundle, const char *fileName, FILE **out) {
+ celix_status_t status;
+
+ char *path = NULL;
+ char metaInfFileName[512];
+ snprintf(metaInfFileName, sizeof(metaInfFileName), "META-INF/descriptors/%s", fileName);
+
+ status = bundle_getEntry(bundle, fileName, &path);
+
+ if (status != CELIX_SUCCESS || path == NULL) {
+ status = bundle_getEntry(bundle, metaInfFileName, &path);
+ }
+
+ if (status == CELIX_SUCCESS && path != NULL) {
+ FILE *df = fopen(path, "r");
+ if (df == NULL) {
+ status = CELIX_FILE_IO_EXCEPTION;
+ } else {
+ *out = df;
+ }
+
+ }
+
+ free(path);
+ return status;
+}
+
+celix_status_t dfi_findDescriptor(bundle_context_pt context, bundle_pt bundle, const char *name, FILE **out) {
+ celix_status_t status;
+ char fileName[128];
+
+ snprintf(fileName, 128, "%s.descriptor", name);
+
+ long id;
+ status = bundle_getBundleId(bundle, &id);
+
+ if (status == CELIX_SUCCESS) {
+ if (id == 0) {
+ //framework bundle
+ status = dfi_findFileForFramework(context, fileName, out);
+ } else {
+ //normal bundle
+ status = dfi_findFileForBundle(bundle, fileName, out);
+ }
+ }
+
+ return status;
+}
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/remote_service_admin_dfi/rsa/src/dfi_utils.h
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/rsa/src/dfi_utils.h b/remote_services/remote_service_admin_dfi/rsa/src/dfi_utils.h
new file mode 100644
index 0000000..cec8aa1
--- /dev/null
+++ b/remote_services/remote_service_admin_dfi/rsa/src/dfi_utils.h
@@ -0,0 +1,30 @@
+/**
+ *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.
+ */
+#ifndef DFI_UTILS_H_
+#define DFI_UTILS_H_
+
+#include "bundle.h"
+#include "bundle_context.h"
+#include <stdio.h>
+#include "celix_errno.h"
+
+
+celix_status_t dfi_findDescriptor(bundle_context_pt context, bundle_pt bundle, const char *name, FILE **out);
+
+#endif
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/remote_service_admin_dfi/rsa/src/export_registration_dfi.c
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/rsa/src/export_registration_dfi.c b/remote_services/remote_service_admin_dfi/rsa/src/export_registration_dfi.c
new file mode 100644
index 0000000..b83b5a8
--- /dev/null
+++ b/remote_services/remote_service_admin_dfi/rsa/src/export_registration_dfi.c
@@ -0,0 +1,251 @@
+/**
+ *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.
+ */
+
+#include <jansson.h>
+#include <dyn_interface.h>
+#include <json_serializer.h>
+#include <remote_constants.h>
+#include <remote_service_admin.h>
+#include <service_tracker_customizer.h>
+#include <service_tracker.h>
+#include <json_rpc.h>
+#include "constants.h"
+#include "export_registration_dfi.h"
+#include "dfi_utils.h"
+
+struct export_reference {
+ endpoint_description_pt endpoint; //owner
+ service_reference_pt reference;
+};
+
+struct export_registration {
+ bundle_context_pt context;
+ struct export_reference exportReference;
+ char *servId;
+ dyn_interface_type *intf; //owner
+ service_tracker_pt tracker;
+
+ celix_thread_mutex_t mutex;
+ void *service; //protected by mutex
+
+ //TODO add tracker and lock
+ bool closed;
+};
+
+static void exportRegistration_addServ(export_registration_pt reg, service_reference_pt ref, void *service);
+static void exportRegistration_removeServ(export_registration_pt reg, service_reference_pt ref, void *service);
+
+celix_status_t exportRegistration_create(log_helper_pt helper, service_reference_pt reference, endpoint_description_pt endpoint, bundle_context_pt context, export_registration_pt *out) {
+ celix_status_t status = CELIX_SUCCESS;
+
+ const char *servId = NULL;
+ status = serviceReference_getProperty(reference, "service.id", &servId);
+ if (status != CELIX_SUCCESS) {
+ logHelper_log(helper, OSGI_LOGSERVICE_WARNING, "Cannot find service.id for ref");
+ }
+
+ export_registration_pt reg = NULL;
+ if (status == CELIX_SUCCESS) {
+ reg = calloc(1, sizeof(*reg));
+ if (reg == NULL) {
+ status = CELIX_ENOMEM;
+ }
+ }
+
+
+ if (status == CELIX_SUCCESS) {
+ reg->context = context;
+ reg->exportReference.endpoint = endpoint;
+ reg->exportReference.reference = reference;
+ reg->closed = false;
+
+ celixThreadMutex_create(®->mutex, NULL);
+ }
+
+ const char *exports = NULL;
+ CELIX_DO_IF(status, serviceReference_getProperty(reference, (char *) OSGI_RSA_SERVICE_EXPORTED_INTERFACES, &exports));
+
+ bundle_pt bundle = NULL;
+ CELIX_DO_IF(status, serviceReference_getBundle(reference, &bundle));
+
+ FILE *descriptor = NULL;
+ if (status == CELIX_SUCCESS) {
+ status = dfi_findDescriptor(context, bundle, exports, &descriptor);
+ }
+
+ if (status != CELIX_SUCCESS || descriptor == NULL) {
+ status = CELIX_BUNDLE_EXCEPTION;
+ logHelper_log(helper, OSGI_LOGSERVICE_ERROR, "Cannot find/open descriptor for '%s'", exports);
+ }
+
+ if (status == CELIX_SUCCESS) {
+ int rc = dynInterface_parse(descriptor, ®->intf);
+ fclose(descriptor);
+ if (rc != 0) {
+ status = CELIX_BUNDLE_EXCEPTION;
+ logHelper_log(helper, OSGI_LOGSERVICE_WARNING, "RSA: Error parsing service descriptor.");
+ }
+ else{
+ /* Add the interface version as a property in the properties_map */
+ char* intfVersion = NULL;
+ dynInterface_getVersionString(reg->intf, &intfVersion);
+ const char *serviceVersion = properties_get(endpoint->properties,(char*) CELIX_FRAMEWORK_SERVICE_VERSION);
+ if(serviceVersion!=NULL){
+ if(strcmp(serviceVersion,intfVersion)!=0){
+ logHelper_log(helper, OSGI_LOGSERVICE_WARNING, "Service version (%s) and interface version from the descriptor (%s) are not the same!",serviceVersion,intfVersion);
+ }
+ }
+ else{
+ properties_set(endpoint->properties, (char*) CELIX_FRAMEWORK_SERVICE_VERSION, intfVersion);
+ }
+ }
+ }
+
+ if (status == CELIX_SUCCESS) {
+ service_tracker_customizer_pt cust = NULL;
+ status = serviceTrackerCustomizer_create(reg, NULL, (void *) exportRegistration_addServ, NULL,
+ (void *) exportRegistration_removeServ, &cust);
+ if (status == CELIX_SUCCESS) {
+ char filter[32];
+ snprintf(filter, 32, "(service.id=%s)", servId);
+ status = serviceTracker_createWithFilter(reg->context, filter, cust, ®->tracker);
+ }
+ }
+
+ if (status == CELIX_SUCCESS) {
+ *out = reg;
+ } else {
+ logHelper_log(helper, OSGI_LOGSERVICE_ERROR, "Error creating export registration");
+ exportRegistration_destroy(reg);
+ }
+
+ return status;
+}
+
+celix_status_t exportRegistration_call(export_registration_pt export, char *data, int datalength, char **responseOut, int *responseLength) {
+ int status = CELIX_SUCCESS;
+
+ //printf("calling for '%s'\n");
+
+ *responseLength = -1;
+ celixThreadMutex_lock(&export->mutex);
+ status = jsonRpc_call(export->intf, export->service, data, responseOut);
+ celixThreadMutex_unlock(&export->mutex);
+
+ return status;
+}
+
+void exportRegistration_destroy(export_registration_pt reg) {
+ if (reg != NULL) {
+ if (reg->intf != NULL) {
+ dyn_interface_type *intf = reg->intf;
+ reg->intf = NULL;
+ dynInterface_destroy(intf);
+ }
+
+ if (reg->exportReference.endpoint != NULL) {
+ endpoint_description_pt ep = reg->exportReference.endpoint;
+ reg->exportReference.endpoint = NULL;
+ endpointDescription_destroy(ep);
+ }
+ if (reg->tracker != NULL) {
+ serviceTracker_destroy(reg->tracker);
+ }
+ celixThreadMutex_destroy(®->mutex);
+
+ free(reg);
+ }
+}
+
+celix_status_t exportRegistration_start(export_registration_pt reg) {
+ celix_status_t status = CELIX_SUCCESS;
+
+ serviceTracker_open(reg->tracker);
+ return status;
+}
+
+
+celix_status_t exportRegistration_stop(export_registration_pt reg) {
+ celix_status_t status = CELIX_SUCCESS;
+ if (status == CELIX_SUCCESS) {
+ status = bundleContext_ungetServiceReference(reg->context, reg->exportReference.reference);
+ serviceTracker_close(reg->tracker);
+ }
+ return status;
+}
+
+static void exportRegistration_addServ(export_registration_pt reg, service_reference_pt ref, void *service) {
+ celixThreadMutex_lock(®->mutex);
+ reg->service = service;
+ celixThreadMutex_unlock(®->mutex);
+}
+
+static void exportRegistration_removeServ(export_registration_pt reg, service_reference_pt ref, void *service) {
+ celixThreadMutex_lock(®->mutex);
+ if (reg->service == service) {
+ reg->service = NULL;
+ }
+ celixThreadMutex_unlock(®->mutex);
+}
+
+
+celix_status_t exportRegistration_close(export_registration_pt reg) {
+ celix_status_t status = CELIX_SUCCESS;
+ exportRegistration_stop(reg);
+ 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 *out) {
+ celix_status_t status = CELIX_SUCCESS;
+ export_reference_pt ref = calloc(1, sizeof(*ref));
+ if (ref != NULL) {
+ ref->endpoint = registration->exportReference.endpoint;
+ ref->reference = registration->exportReference.reference;
+ } else {
+ status = CELIX_ENOMEM;
+ }
+
+ if (status == CELIX_SUCCESS) {
+ *out = ref;
+ }
+
+ 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, service_reference_pt *ref) {
+ celix_status_t status = CELIX_SUCCESS;
+ *ref = reference->reference;
+ return status;
+}
+
+
+
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/remote_service_admin_dfi/rsa/src/export_registration_dfi.h
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/rsa/src/export_registration_dfi.h b/remote_services/remote_service_admin_dfi/rsa/src/export_registration_dfi.h
new file mode 100644
index 0000000..93f37ba
--- /dev/null
+++ b/remote_services/remote_service_admin_dfi/rsa/src/export_registration_dfi.h
@@ -0,0 +1,38 @@
+/**
+ *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.
+ */
+
+#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_close(export_registration_pt registration);
+void 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/2a670f26/remote_services/remote_service_admin_dfi/rsa/src/import_registration_dfi.c
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/rsa/src/import_registration_dfi.c b/remote_services/remote_service_admin_dfi/rsa/src/import_registration_dfi.c
new file mode 100644
index 0000000..0b8dcf7
--- /dev/null
+++ b/remote_services/remote_service_admin_dfi/rsa/src/import_registration_dfi.c
@@ -0,0 +1,402 @@
+/**
+ *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.
+ */
+
+#include <stdlib.h>
+#include <jansson.h>
+#include <json_rpc.h>
+#include <assert.h>
+#include "version.h"
+#include "json_serializer.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
+ version_pt version;
+
+ celix_thread_mutex_t mutex; //protects send & sendhandle
+ send_func_type send;
+ void *sendHandle;
+
+ service_factory_pt factory;
+ service_registration_pt factoryReg;
+
+ hash_map_pt proxies; //key -> bundle, value -> service_proxy
+ celix_thread_mutex_t proxiesMutex; //protects proxies
+};
+
+struct service_proxy {
+ dyn_interface_type *intf;
+ void *service;
+ size_t 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);
+static void importRegistration_clearProxies(import_registration_pt import);
+
+celix_status_t importRegistration_create(bundle_context_pt context, endpoint_description_pt endpoint, const char *classObject, const char* serviceVersion,
+ 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);
+
+ celixThreadMutex_create(®->mutex, NULL);
+ celixThreadMutex_create(®->proxiesMutex, NULL);
+ status = version_createVersionFromString((char*)serviceVersion,&(reg->version));
+
+ reg->factory->handle = reg;
+ reg->factory->getService = (void *)importRegistration_getService;
+ reg->factory->ungetService = (void *)importRegistration_ungetService;
+ } else {
+ status = CELIX_ENOMEM;
+ }
+
+ if (status == CELIX_SUCCESS) {
+ //printf("IMPORT REGISTRATION IS %p\n", reg);
+ *out = reg;
+ }
+ else{
+ importRegistration_destroy(reg);
+ }
+
+ return status;
+}
+
+
+celix_status_t importRegistration_setSendFn(import_registration_pt reg,
+ send_func_type send,
+ void *handle) {
+ celixThreadMutex_lock(®->mutex);
+ reg->send = send;
+ reg->sendHandle = handle;
+ celixThreadMutex_unlock(®->mutex);
+
+ return CELIX_SUCCESS;
+}
+
+static void importRegistration_clearProxies(import_registration_pt import) {
+ if (import != NULL) {
+ pthread_mutex_lock(&import->proxiesMutex);
+ if (import->proxies != NULL) {
+ hash_map_iterator_pt iter = hashMapIterator_create(import->proxies);
+ while (hashMapIterator_hasNext(iter)) {
+ hash_map_entry_pt entry = hashMapIterator_nextEntry(iter);
+ struct service_proxy *proxy = hashMapEntry_getValue(entry);
+ importRegistration_destroyProxy(proxy);
+ }
+ hashMapIterator_destroy(iter);
+ }
+ pthread_mutex_unlock(&import->proxiesMutex);
+ }
+}
+
+void importRegistration_destroy(import_registration_pt import) {
+ if (import != NULL) {
+ if (import->proxies != NULL) {
+ hashMap_destroy(import->proxies, false, false);
+ import->proxies = NULL;
+ }
+
+ pthread_mutex_destroy(&import->mutex);
+ pthread_mutex_destroy(&import->proxiesMutex);
+
+ if (import->factory != NULL) {
+ free(import->factory);
+ }
+
+ if(import->version!=NULL){
+ version_destroy(import->version);
+ }
+ free(import);
+ }
+}
+
+celix_status_t importRegistration_start(import_registration_pt import) {
+ celix_status_t status = CELIX_SUCCESS;
+ if (import->factoryReg == NULL && import->factory != NULL) {
+ properties_pt props = NULL;
+ properties_copy(import->endpoint->properties, &props);
+ status = bundleContext_registerServiceFactory(import->context, (char *)import->classObject, import->factory, props, &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);
+ import->factoryReg = NULL;
+ }
+
+ importRegistration_clearProxies(import);
+
+ 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;
+
+ /*
+ module_pt module = NULL;
+ char *name = NULL;
+ bundle_getCurrentModule(bundle, &module);
+ module_getSymbolicName(module, &name);
+ printf("getting service for bundle '%s'\n", name);
+ */
+
+
+ pthread_mutex_lock(&import->proxiesMutex);
+ struct service_proxy *proxy = hashMap_get(import->proxies, bundle);
+ if (proxy == NULL) {
+ status = importRegistration_createProxy(import, bundle, &proxy);
+ if (status == CELIX_SUCCESS) {
+ hashMap_put(import->proxies, bundle, proxy);
+ }
+ }
+
+ if (status == CELIX_SUCCESS) {
+ proxy->count += 1;
+ *out = proxy->service;
+ }
+ pthread_mutex_unlock(&import->proxiesMutex);
+
+ return status;
+}
+
+static celix_status_t importRegistration_createProxy(import_registration_pt import, bundle_pt bundle, struct service_proxy **out) {
+ celix_status_t status;
+ dyn_interface_type* intf = NULL;
+ FILE *descriptor = NULL;
+
+ status = dfi_findDescriptor(import->context, bundle, import->classObject, &descriptor);
+
+ if (status != CELIX_SUCCESS || descriptor == NULL) {
+ //TODO use log helper logHelper_log(helper, OSGI_LOGSERVICE_ERROR, "Cannot find/open descriptor for '%s'", import->classObject);
+ fprintf(stderr, "RSA_DFI: Cannot find/open descriptor for '%s'", import->classObject);
+ return CELIX_BUNDLE_EXCEPTION;
+ }
+
+ if (status == CELIX_SUCCESS) {
+ int rc = dynInterface_parse(descriptor, &intf);
+ fclose(descriptor);
+ if (rc != 0 || intf==NULL) {
+ return CELIX_BUNDLE_EXCEPTION;
+ }
+ }
+
+ /* Check if the imported service version is compatible with the one in the consumer descriptor */
+ version_pt consumerVersion = NULL;
+ bool isCompatible = false;
+ dynInterface_getVersion(intf,&consumerVersion);
+ version_isCompatible(consumerVersion,import->version,&isCompatible);
+
+ if(!isCompatible){
+ char* cVerString = NULL;
+ char* pVerString = NULL;
+ version_toString(consumerVersion,&cVerString);
+ version_toString(import->version,&pVerString);
+ printf("Service version mismatch: consumer has %s, provider has %s. NOT creating proxy.\n",cVerString,pVerString);
+ dynInterface_destroy(intf);
+ free(cVerString);
+ free(pVerString);
+ status = CELIX_SERVICE_EXCEPTION;
+ }
+
+ struct service_proxy *proxy = NULL;
+ if (status == CELIX_SUCCESS) {
+ proxy = calloc(1, sizeof(*proxy));
+ if (proxy == NULL) {
+ status = CELIX_ENOMEM;
+ }
+ }
+
+ if (status == CELIX_SUCCESS) {
+ proxy->intf = intf;
+ size_t count = dynInterface_nrOfMethods(proxy->intf);
+ proxy->service = calloc(1 + count, sizeof(void *));
+ if (proxy->service == NULL) {
+ status = CELIX_ENOMEM;
+ }
+ }
+
+ if (status == CELIX_SUCCESS) {
+ void **serv = proxy->service;
+ serv[0] = import;
+
+ struct methods_head *list = NULL;
+ dynInterface_methods(proxy->intf, &list);
+ struct method_entry *entry = NULL;
+ void (*fn)(void) = NULL;
+ 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) {
+ *out = proxy;
+ } else if (proxy != NULL) {
+ if (proxy->intf != NULL) {
+ dynInterface_destroy(proxy->intf);
+ proxy->intf = NULL;
+ }
+ free(proxy->service);
+ free(proxy);
+ }
+
+ return status;
+}
+
+static void importRegistration_proxyFunc(void *userData, void *args[], void *returnVal) {
+ int status = CELIX_SUCCESS;
+ struct method_entry *entry = userData;
+ import_registration_pt import = *((void **)args[0]);
+
+ if (import == NULL || import->send == NULL) {
+ status = CELIX_ILLEGAL_ARGUMENT;
+ }
+
+
+ char *invokeRequest = NULL;
+ if (status == CELIX_SUCCESS) {
+ status = jsonRpc_prepareInvokeRequest(entry->dynFunc, entry->id, args, &invokeRequest);
+ //printf("Need to send following json '%s'\n", invokeRequest);
+ }
+
+
+ if (status == CELIX_SUCCESS) {
+ char *reply = NULL;
+ int rc = 0;
+ //printf("sending request\n");
+ celixThreadMutex_lock(&import->mutex);
+ if (import->send != NULL) {
+ import->send(import->sendHandle, import->endpoint, invokeRequest, &reply, &rc);
+ }
+ celixThreadMutex_unlock(&import->mutex);
+ //printf("request sended. got reply '%s' with status %i\n", reply, rc);
+
+ if (rc == 0) {
+ //fjprintf("Handling reply '%s'\n", reply);
+ status = jsonRpc_handleReply(entry->dynFunc, reply, args);
+ }
+
+ *(int *) returnVal = rc;
+
+ free(invokeRequest); //Allocated by json_dumps in jsonRpc_prepareInvokeRequest
+ free(reply); //Allocated by json_dumps in remoteServiceAdmin_send through curl call
+ }
+
+ if (status != CELIX_SUCCESS) {
+ //TODO log error
+ }
+}
+
+celix_status_t importRegistration_ungetService(import_registration_pt import, bundle_pt bundle, service_registration_pt registration, void **out) {
+ celix_status_t status = CELIX_SUCCESS;
+
+ assert(import != NULL);
+ assert(import->proxies != NULL);
+
+ pthread_mutex_lock(&import->proxiesMutex);
+
+ struct service_proxy *proxy = hashMap_get(import->proxies, bundle);
+ if (proxy != NULL) {
+ if (*out == proxy->service) {
+ proxy->count -= 1;
+ } else {
+ status = CELIX_ILLEGAL_ARGUMENT;
+ }
+
+ if (proxy->count == 0) {
+ hashMap_remove(import->proxies, bundle);
+ importRegistration_destroyProxy(proxy);
+ }
+ }
+
+ pthread_mutex_unlock(&import->proxiesMutex);
+
+ return status;
+}
+
+static void importRegistration_destroyProxy(struct service_proxy *proxy) {
+ if (proxy != NULL) {
+ if (proxy->intf != NULL) {
+ dynInterface_destroy(proxy->intf);
+ }
+ if (proxy->service != NULL) {
+ free(proxy->service);
+ }
+ free(proxy);
+ }
+}
+
+
+celix_status_t importRegistration_close(import_registration_pt registration) {
+ celix_status_t status = CELIX_SUCCESS;
+ importRegistration_stop(registration);
+ 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;
+}
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/remote_service_admin_dfi/rsa/src/import_registration_dfi.h
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/rsa/src/import_registration_dfi.h b/remote_services/remote_service_admin_dfi/rsa/src/import_registration_dfi.h
new file mode 100644
index 0000000..aac4bc7
--- /dev/null
+++ b/remote_services/remote_service_admin_dfi/rsa/src/import_registration_dfi.h
@@ -0,0 +1,44 @@
+/**
+ *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.
+ */
+
+#ifndef CELIX_IMPORT_REGISTRATION_DFI_H
+#define CELIX_IMPORT_REGISTRATION_DFI_H
+
+#include "import_registration.h"
+#include "dfi_utils.h"
+
+#include <celix_errno.h>
+
+typedef void (*send_func_type)(void *handle, endpoint_description_pt endpointDescription, char *request, char **reply, int* replyStatus);
+
+celix_status_t importRegistration_create(bundle_context_pt context, endpoint_description_pt description, const char *classObject, const char* serviceVersion,
+ import_registration_pt *import);
+celix_status_t importRegistration_close(import_registration_pt import);
+void importRegistration_destroy(import_registration_pt import);
+
+celix_status_t importRegistration_setSendFn(import_registration_pt reg,
+ send_func_type,
+ void *handle);
+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/2a670f26/remote_services/remote_service_admin_dfi/rsa/src/remote_service_admin_activator.c
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/rsa/src/remote_service_admin_activator.c b/remote_services/remote_service_admin_dfi/rsa/src/remote_service_admin_activator.c
new file mode 100644
index 0000000..d4cc765
--- /dev/null
+++ b/remote_services/remote_service_admin_dfi/rsa/src/remote_service_admin_activator.c
@@ -0,0 +1,124 @@
+/**
+ *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_activator.c
+ *
+ * \date Sep 30, 2011
+ * \author <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ * \copyright Apache License, Version 2.0
+ */
+#include <stdlib.h>
+#include <remote_service_admin.h>
+
+#include "remote_service_admin_dfi.h"
+
+#include "bundle_activator.h"
+#include "service_registration.h"
+
+#include "export_registration_dfi.h"
+#include "import_registration_dfi.h"
+
+struct activator {
+ remote_service_admin_pt admin;
+ remote_service_admin_service_pt adminService;
+ service_registration_pt registration;
+};
+
+celix_status_t bundleActivator_create(bundle_context_pt context, void **userData) {
+ celix_status_t status = CELIX_SUCCESS;
+ struct activator *activator;
+
+ activator = calloc(1, sizeof(*activator));
+ if (!activator) {
+ status = CELIX_ENOMEM;
+ } else {
+ activator->admin = NULL;
+ activator->registration = NULL;
+
+ *userData = activator;
+ }
+
+ return status;
+}
+
+celix_status_t bundleActivator_start(void * userData, bundle_context_pt context) {
+ celix_status_t status = CELIX_SUCCESS;
+ struct activator *activator = userData;
+ remote_service_admin_service_pt remoteServiceAdmin = NULL;
+
+ status = remoteServiceAdmin_create(context, &activator->admin);
+ if (status == CELIX_SUCCESS) {
+ remoteServiceAdmin = calloc(1, sizeof(*remoteServiceAdmin));
+ if (!remoteServiceAdmin) {
+ status = CELIX_ENOMEM;
+ } else {
+ remoteServiceAdmin->admin = activator->admin;
+ remoteServiceAdmin->exportService = remoteServiceAdmin_exportService;
+
+ remoteServiceAdmin->getExportedServices = remoteServiceAdmin_getExportedServices;
+ remoteServiceAdmin->getImportedEndpoints = remoteServiceAdmin_getImportedEndpoints;
+ remoteServiceAdmin->importService = remoteServiceAdmin_importService;
+
+ remoteServiceAdmin->exportReference_getExportedEndpoint = exportReference_getExportedEndpoint;
+ remoteServiceAdmin->exportReference_getExportedService = exportReference_getExportedService;
+
+ remoteServiceAdmin->exportRegistration_close = remoteServiceAdmin_removeExportedService;
+ remoteServiceAdmin->exportRegistration_getException = exportRegistration_getException;
+ remoteServiceAdmin->exportRegistration_getExportReference = exportRegistration_getExportReference;
+
+ remoteServiceAdmin->importReference_getImportedEndpoint = importReference_getImportedEndpoint;
+ remoteServiceAdmin->importReference_getImportedService = importReference_getImportedService;
+
+ remoteServiceAdmin->importRegistration_close = remoteServiceAdmin_removeImportedService;
+ remoteServiceAdmin->importRegistration_getException = importRegistration_getException;
+ remoteServiceAdmin->importRegistration_getImportReference = importRegistration_getImportReference;
+
+ status = bundleContext_registerService(context, OSGI_RSA_REMOTE_SERVICE_ADMIN, remoteServiceAdmin, NULL, &activator->registration);
+ activator->adminService = remoteServiceAdmin;
+ }
+ }
+
+ return status;
+}
+
+celix_status_t bundleActivator_stop(void * userData, bundle_context_pt context) {
+ celix_status_t status = CELIX_SUCCESS;
+ struct activator *activator = userData;
+
+ serviceRegistration_unregister(activator->registration);
+ activator->registration = NULL;
+
+ remoteServiceAdmin_stop(activator->admin);
+ remoteServiceAdmin_destroy(&activator->admin);
+
+ free(activator->adminService);
+
+ return status;
+}
+
+celix_status_t bundleActivator_destroy(void * userData, bundle_context_pt context) {
+ celix_status_t status = CELIX_SUCCESS;
+ struct activator *activator = userData;
+
+ free(activator);
+
+ return status;
+}
+
+
[04/19] celix git commit: CELIX-417: Refactor for CMake usage in RSA,
PSA and Docker. mostly trying to identify the api and common libraries
Posted by pn...@apache.org.
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/topology_manager/private/src/topology_manager.c
----------------------------------------------------------------------
diff --git a/remote_services/topology_manager/private/src/topology_manager.c b/remote_services/topology_manager/private/src/topology_manager.c
deleted file mode 100644
index 6472b01..0000000
--- a/remote_services/topology_manager/private/src/topology_manager.c
+++ /dev/null
@@ -1,985 +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.
- */
-/*
- * topology_manager.c
- *
- * \date Sep 29, 2011
- * \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 <string.h>
-
-#include "celixbool.h"
-#include "topology_manager.h"
-#include "bundle_context.h"
-#include "constants.h"
-#include "bundle.h"
-#include "remote_service_admin.h"
-#include "remote_constants.h"
-#include "filter.h"
-#include "listener_hook_service.h"
-#include "utils.h"
-#include "service_reference.h"
-#include "service_registration.h"
-#include "log_service.h"
-#include "log_helper.h"
-#include "topology_manager.h"
-#include "scope.h"
-#include "hash_map.h"
-
-struct topology_manager {
- bundle_context_pt context;
-
- celix_thread_mutex_t rsaListLock;
- celix_thread_mutexattr_t rsaListLockAttr;
- array_list_pt rsaList;
-
- celix_thread_mutex_t listenerListLock;
- hash_map_pt listenerList;
-
- celix_thread_mutex_t exportedServicesLock;
- hash_map_pt exportedServices;
-
- celix_thread_mutex_t importedServicesLock;
- celix_thread_mutexattr_t importedServicesLockAttr;
- hash_map_pt importedServices;
-
- scope_pt scope;
-
- log_helper_pt loghelper;
-};
-
-celix_status_t topologyManager_exportScopeChanged(void *handle, char *service_name);
-celix_status_t topologyManager_importScopeChanged(void *handle, char *service_name);
-celix_status_t topologyManager_notifyListenersEndpointAdded(topology_manager_pt manager, remote_service_admin_service_pt rsa, array_list_pt registrations);
-celix_status_t topologyManager_notifyListenersEndpointRemoved(topology_manager_pt manager, remote_service_admin_service_pt rsa, export_registration_pt export);
-
-celix_status_t topologyManager_create(bundle_context_pt context, log_helper_pt logHelper, topology_manager_pt *manager, void **scope) {
- celix_status_t status = CELIX_SUCCESS;
-
- *manager = calloc(1, sizeof(**manager));
-
- if (!*manager) {
- return CELIX_ENOMEM;
- }
-
- (*manager)->context = context;
- (*manager)->rsaList = NULL;
-
- arrayList_create(&(*manager)->rsaList);
-
-
- celixThreadMutexAttr_create(&(*manager)->rsaListLockAttr);
- celixThreadMutexAttr_settype(&(*manager)->rsaListLockAttr, CELIX_THREAD_MUTEX_RECURSIVE);
- celixThreadMutex_create(&(*manager)->rsaListLock, &(*manager)->rsaListLockAttr);
-
- celixThreadMutexAttr_create(&(*manager)->importedServicesLockAttr);
- celixThreadMutexAttr_settype(&(*manager)->importedServicesLockAttr, CELIX_THREAD_MUTEX_RECURSIVE);
- celixThreadMutex_create(&(*manager)->importedServicesLock, &(*manager)->importedServicesLockAttr);
-
- celixThreadMutex_create(&(*manager)->exportedServicesLock, NULL);
- celixThreadMutex_create(&(*manager)->listenerListLock, NULL);
-
- (*manager)->listenerList = hashMap_create(serviceReference_hashCode, NULL, serviceReference_equals2, NULL);
- (*manager)->exportedServices = hashMap_create(serviceReference_hashCode, NULL, serviceReference_equals2, NULL);
- (*manager)->importedServices = hashMap_create(NULL, NULL, NULL, NULL);
-
- status = scope_scopeCreate(*manager, &(*manager)->scope);
- scope_setExportScopeChangedCallback((*manager)->scope, topologyManager_exportScopeChanged);
- scope_setImportScopeChangedCallback((*manager)->scope, topologyManager_importScopeChanged);
- *scope = (*manager)->scope;
-
- (*manager)->loghelper = logHelper;
-
-
- return status;
-}
-
-celix_status_t topologyManager_destroy(topology_manager_pt manager) {
- celix_status_t status = CELIX_SUCCESS;
-
- celixThreadMutex_lock(&manager->listenerListLock);
- hashMap_destroy(manager->listenerList, false, false);
-
- celixThreadMutex_unlock(&manager->listenerListLock);
- celixThreadMutex_destroy(&manager->listenerListLock);
-
- celixThreadMutex_lock(&manager->rsaListLock);
-
- arrayList_destroy(manager->rsaList);
-
- celixThreadMutex_unlock(&manager->rsaListLock);
- celixThreadMutex_destroy(&manager->rsaListLock);
- celixThreadMutexAttr_destroy(&manager->rsaListLockAttr);
-
- celixThreadMutex_lock(&manager->exportedServicesLock);
-
- hashMap_destroy(manager->exportedServices, false, false);
-
- celixThreadMutex_unlock(&manager->exportedServicesLock);
- celixThreadMutex_destroy(&manager->exportedServicesLock);
-
- celixThreadMutex_lock(&manager->importedServicesLock);
-
- hashMap_destroy(manager->importedServices, false, false);
-
- celixThreadMutex_unlock(&manager->importedServicesLock);
- celixThreadMutex_destroy(&manager->importedServicesLock);
- celixThreadMutexAttr_destroy(&manager->importedServicesLockAttr);
-
- scope_scopeDestroy(manager->scope);
- free(manager);
-
- return status;
-}
-
-celix_status_t topologyManager_closeImports(topology_manager_pt manager) {
- celix_status_t status;
-
- status = celixThreadMutex_lock(&manager->importedServicesLock);
-
- hash_map_iterator_pt iter = hashMapIterator_create(manager->importedServices);
- while (hashMapIterator_hasNext(iter)) {
- hash_map_entry_pt entry = hashMapIterator_nextEntry(iter);
- endpoint_description_pt ep = hashMapEntry_getKey(entry);
- hash_map_pt imports = hashMapEntry_getValue(entry);
-
- if (imports != NULL) {
- logHelper_log(manager->loghelper, OSGI_LOGSERVICE_INFO, "TOPOLOGY_MANAGER: Remove imported service (%s; %s).", ep->service, ep->id);
- hash_map_iterator_pt importsIter = hashMapIterator_create(imports);
-
- while (hashMapIterator_hasNext(importsIter)) {
- hash_map_entry_pt entry = hashMapIterator_nextEntry(importsIter);
-
- remote_service_admin_service_pt rsa = hashMapEntry_getKey(entry);
- import_registration_pt import = hashMapEntry_getValue(entry);
-
- status = rsa->importRegistration_close(rsa->admin, import);
- if (status == CELIX_SUCCESS) {
- hashMapIterator_remove(importsIter);
- }
- }
- hashMapIterator_destroy(importsIter);
-
- hashMapIterator_remove(iter);
-
- hashMap_destroy(imports, false, false);
- }
- }
- hashMapIterator_destroy(iter);
-
- status = celixThreadMutex_unlock(&manager->importedServicesLock);
-
- return status;
-}
-
-celix_status_t topologyManager_rsaAdding(void * handle, service_reference_pt reference, void **service) {
- celix_status_t status;
- topology_manager_pt manager = (topology_manager_pt) handle;
-
- status = bundleContext_getService(manager->context, reference, service);
-
- return status;
-}
-
-celix_status_t topologyManager_rsaAdded(void * handle, service_reference_pt reference, void * service) {
- celix_status_t status;
- topology_manager_pt manager = (topology_manager_pt) handle;
- properties_pt serviceProperties = NULL;
- remote_service_admin_service_pt rsa = (remote_service_admin_service_pt) service;
- logHelper_log(manager->loghelper, OSGI_LOGSERVICE_INFO, "TOPOLOGY_MANAGER: Added RSA");
-
- status = celixThreadMutex_lock(&manager->rsaListLock);
-
- if (status == CELIX_SUCCESS) {
- arrayList_add(manager->rsaList, rsa);
- status = celixThreadMutex_unlock(&manager->rsaListLock);
- }
-
- // add already imported services to new rsa
- if (status == CELIX_SUCCESS) {
- status = celixThreadMutex_lock(&manager->importedServicesLock);
-
- if (status == CELIX_SUCCESS) {
- hash_map_iterator_pt importedServicesIterator = hashMapIterator_create(manager->importedServices);
-
- while (hashMapIterator_hasNext(importedServicesIterator)) {
- hash_map_entry_pt entry = hashMapIterator_nextEntry(importedServicesIterator);
- endpoint_description_pt endpoint = hashMapEntry_getKey(entry);
- if (scope_allowImport(manager->scope, endpoint)) {
- import_registration_pt import = NULL;
- status = rsa->importService(rsa->admin, endpoint, &import);
-
- if (status == CELIX_SUCCESS) {
- hash_map_pt imports = hashMapEntry_getValue(entry);
-
- if (imports == NULL) {
- imports = hashMap_create(NULL, NULL, NULL, NULL);
- hashMap_put(manager->importedServices,endpoint,imports);
- }
-
- hashMap_put(imports, service, import);
- }
- }
- }
-
- hashMapIterator_destroy(importedServicesIterator);
-
- celixThreadMutex_unlock(&manager->importedServicesLock);
- }
- }
-
- // add already exported services to new rsa
- if (status == CELIX_SUCCESS) {
- status = celixThreadMutex_lock(&manager->exportedServicesLock);
-
- if (status == CELIX_SUCCESS) {
- hash_map_iterator_pt exportedServicesIterator = hashMapIterator_create(manager->exportedServices);
-
- while (hashMapIterator_hasNext(exportedServicesIterator)) {
- hash_map_entry_pt entry = hashMapIterator_nextEntry(exportedServicesIterator);
- service_reference_pt reference = hashMapEntry_getKey(entry);
- const char* serviceId = NULL;
-
- serviceReference_getProperty(reference, OSGI_FRAMEWORK_SERVICE_ID, &serviceId);
-
- scope_getExportProperties(manager->scope, reference, &serviceProperties);
-
- array_list_pt endpoints = NULL;
- status = rsa->exportService(rsa->admin, (char*)serviceId, serviceProperties, &endpoints);
-
- if (status == CELIX_SUCCESS) {
- hash_map_pt exports = hashMapEntry_getValue(entry);
-
- if (exports == NULL) {
- exports = hashMap_create(NULL, NULL, NULL, NULL);
- hashMap_put(manager->exportedServices,reference,exports);
- }
-
- hashMap_put(exports, rsa, endpoints);
- status = topologyManager_notifyListenersEndpointAdded(manager, rsa, endpoints);
- }
- }
-
- hashMapIterator_destroy(exportedServicesIterator);
-
- celixThreadMutex_unlock(&manager->exportedServicesLock);
- }
- }
- return status;
-}
-
-celix_status_t topologyManager_rsaModified(void * handle, service_reference_pt reference, void * service) {
- celix_status_t status = CELIX_SUCCESS;
-
- // Nop...
-
- return status;
-}
-
-celix_status_t topologyManager_rsaRemoved(void * handle, service_reference_pt reference, void * service) {
- celix_status_t status = CELIX_SUCCESS;
- topology_manager_pt manager = (topology_manager_pt) handle;
- remote_service_admin_service_pt rsa = (remote_service_admin_service_pt) service;
-
- if (celixThreadMutex_lock(&manager->exportedServicesLock) == CELIX_SUCCESS) {
- hash_map_iterator_pt iter = hashMapIterator_create(manager->exportedServices);
-
- while (hashMapIterator_hasNext(iter)) {
-
- hash_map_entry_pt entry = hashMapIterator_nextEntry(iter);
- service_reference_pt key = hashMapEntry_getKey(entry);
- hash_map_pt exports = hashMapEntry_getValue(entry);
-
- /*
- * the problem here is that also the rsa has a a list of
- * endpoints which is destroyed when closing the exportRegistration
- */
- array_list_pt exports_list = hashMap_get(exports, rsa);
-
- if (exports_list != NULL) {
- int exportsIter = 0;
- int exportListSize = arrayList_size(exports_list);
- for (exportsIter = 0; exports_list != NULL && exportsIter < exportListSize; exportsIter++) {
- export_registration_pt export = arrayList_get(exports_list, exportsIter);
- topologyManager_notifyListenersEndpointRemoved(manager, rsa, export);
- rsa->exportRegistration_close(rsa->admin, export);
- }
- }
-
- hashMap_remove(exports, rsa);
- /*if(exports_list!=NULL){
- arrayList_destroy(exports_list);
- }*/
-
- if (hashMap_size(exports) == 0) {
- hashMap_remove(manager->exportedServices, key);
- hashMap_destroy(exports, false, false);
-
- hashMapIterator_destroy(iter);
- iter = hashMapIterator_create(manager->exportedServices);
- }
- }
- hashMapIterator_destroy(iter);
- celixThreadMutex_unlock(&manager->exportedServicesLock);
- }
-
- if (celixThreadMutex_lock(&manager->importedServicesLock) == CELIX_SUCCESS) {
- hash_map_iterator_pt iter = hashMapIterator_create(manager->importedServices);
-
- while (hashMapIterator_hasNext(iter)) {
- hash_map_entry_pt entry = hashMapIterator_nextEntry(iter);
- hash_map_pt imports = hashMapEntry_getValue(entry);
-
- import_registration_pt import = hashMap_get(imports, rsa);
-
- if (import != NULL) {
- celix_status_t subStatus = rsa->importRegistration_close(rsa->admin, import);
-
- if (subStatus == CELIX_SUCCESS) {
- hashMap_remove(imports, rsa);
- } else {
- status = subStatus;
- }
- }
- }
- hashMapIterator_destroy(iter);
- celixThreadMutex_unlock(&manager->importedServicesLock);
- }
-
- if (celixThreadMutex_lock(&manager->rsaListLock) == CELIX_SUCCESS) {
- arrayList_removeElement(manager->rsaList, rsa);
- celixThreadMutex_unlock(&manager->rsaListLock);
- }
-
- logHelper_log(manager->loghelper, OSGI_LOGSERVICE_INFO, "TOPOLOGY_MANAGER: Removed RSA");
-
- return status;
-}
-
-
-celix_status_t topologyManager_serviceChanged(void *listener, service_event_pt event) {
- celix_status_t status = CELIX_SUCCESS;
- service_listener_pt listen = listener;
- topology_manager_pt manager = listen->handle;
-
- const char* export = NULL;
- const char* serviceId = NULL;
- serviceReference_getProperty(event->reference, OSGI_RSA_SERVICE_EXPORTED_INTERFACES, &export);
- serviceReference_getProperty(event->reference, OSGI_FRAMEWORK_SERVICE_ID, &serviceId);
-
- if (!export) {
- // Nothing needs to be done: we're not interested...
- return status;
- }
-
- switch (event->type) {
- case OSGI_FRAMEWORK_SERVICE_EVENT_REGISTERED:
- status = topologyManager_addExportedService(manager, event->reference, (char*)serviceId);
- break;
- case OSGI_FRAMEWORK_SERVICE_EVENT_MODIFIED:
- status = topologyManager_removeExportedService(manager, event->reference, (char*)serviceId);
-
- if (status == CELIX_SUCCESS) {
- status = topologyManager_addExportedService(manager, event->reference, (char*)serviceId);
- }
- break;
- case OSGI_FRAMEWORK_SERVICE_EVENT_UNREGISTERING:
- status = topologyManager_removeExportedService(manager, event->reference, (char*)serviceId);
- break;
- case OSGI_FRAMEWORK_SERVICE_EVENT_MODIFIED_ENDMATCH:
- break;
- }
-
- return status;
-}
-
-celix_status_t topologyManager_exportScopeChanged(void *handle, char *filterStr) {
- celix_status_t status = CELIX_SUCCESS;
- topology_manager_pt manager = (topology_manager_pt) handle;
- service_registration_pt reg = NULL;
- const char* serviceId = NULL;
- bool found;
- properties_pt props;
- filter_pt filter = filter_create(filterStr);
-
- if (filter == NULL) {
- printf("filter creating failed\n");
- return CELIX_ENOMEM;
- }
-
- // add already exported services to new rsa
- if (celixThreadMutex_lock(&manager->exportedServicesLock) == CELIX_SUCCESS) {
- hash_map_iterator_pt exportedServicesIterator = hashMapIterator_create(manager->exportedServices);
- int size = hashMap_size(manager->exportedServices);
- service_reference_pt *srvRefs = (service_reference_pt *) calloc(size, sizeof(service_reference_pt));
- char **srvIds = (char **) calloc(size, sizeof(char*));
- int nrFound = 0;
-
- found = false;
-
- while (hashMapIterator_hasNext(exportedServicesIterator)) {
- hash_map_entry_pt entry = hashMapIterator_nextEntry(exportedServicesIterator);
- service_reference_pt reference = hashMapEntry_getKey(entry);
- reg = NULL;
- serviceReference_getServiceRegistration(reference, ®);
- if (reg != NULL) {
- props = NULL;
- serviceRegistration_getProperties(reg, &props);
- status = filter_match(filter, props, &found);
- if (found) {
- srvRefs[nrFound] = reference;
- serviceReference_getProperty(reference, OSGI_FRAMEWORK_SERVICE_ID, &serviceId);
- srvIds[nrFound++] = (char*)serviceId;
- }
- }
- }
-
- hashMapIterator_destroy(exportedServicesIterator);
- celixThreadMutex_unlock(&manager->exportedServicesLock);
-
- if (nrFound > 0) {
- for (int i = 0; i < nrFound; i++) {
- // Question: can srvRefs become invalid meanwhile??
- const char* export = NULL;
- serviceReference_getProperty(srvRefs[i], (char *) OSGI_RSA_SERVICE_EXPORTED_INTERFACES, &export);
-
- if (export) {
- celix_status_t substatus = topologyManager_removeExportedService(manager, srvRefs[i], srvIds[i]);
-
- if (substatus != CELIX_SUCCESS) {
- logHelper_log(manager->loghelper, OSGI_LOGSERVICE_ERROR, "TOPOLOGY_MANAGER: Removal of exported service (%s) failed.", srvIds[i]);
- } else {
- substatus = topologyManager_addExportedService(manager, srvRefs[i], srvIds[i]);
- }
-
- if (substatus != CELIX_SUCCESS) {
- status = substatus;
- }
- }
- }
- }
-
- free(srvRefs);
- free(srvIds);
- }
-
- filter_destroy(filter);
-
- return status;
-}
-
-celix_status_t topologyManager_importScopeChanged(void *handle, char *service_name) {
- celix_status_t status = CELIX_SUCCESS;
- endpoint_description_pt endpoint;
- topology_manager_pt manager = (topology_manager_pt) handle;
- bool found = false;
-
- // add already exported services to new rsa
- if (celixThreadMutex_lock(&manager->importedServicesLock) == CELIX_SUCCESS) {
- hash_map_iterator_pt importedServicesIterator = hashMapIterator_create(manager->importedServices);
- while (!found && hashMapIterator_hasNext(importedServicesIterator)) {
- hash_map_entry_pt entry = hashMapIterator_nextEntry(importedServicesIterator);
- endpoint = hashMapEntry_getKey(entry);
-
- entry = hashMap_getEntry(endpoint->properties, (void *) OSGI_FRAMEWORK_OBJECTCLASS);
- char* name = (char *) hashMapEntry_getValue(entry);
- // Test if a service with the same name is imported
- if (strcmp(name, service_name) == 0) {
- found = true;
- }
- }
- hashMapIterator_destroy(importedServicesIterator);
- celixThreadMutex_unlock(&manager->importedServicesLock);
- }
-
- if (found) {
- status = topologyManager_removeImportedService(manager, endpoint, NULL);
-
- if (status != CELIX_SUCCESS) {
- logHelper_log(manager->loghelper, OSGI_LOGSERVICE_ERROR, "TOPOLOGY_MANAGER: Removal of imported service (%s; %s) failed.", endpoint->service, endpoint->id);
- } else {
- status = topologyManager_addImportedService(manager, endpoint, NULL);
- }
- }
- return status;
-}
-
-celix_status_t topologyManager_addImportedService(void *handle, endpoint_description_pt endpoint, char *matchedFilter) {
- celix_status_t status = CELIX_SUCCESS;
- topology_manager_pt manager = handle;
-
- logHelper_log(manager->loghelper, OSGI_LOGSERVICE_INFO, "TOPOLOGY_MANAGER: Add imported service (%s; %s).", endpoint->service, endpoint->id);
-
- if (celixThreadMutex_lock(&manager->importedServicesLock) == CELIX_SUCCESS) {
-
- hash_map_pt imports = hashMap_create(NULL, NULL, NULL, NULL);
- hashMap_put(manager->importedServices, endpoint, imports);
-
- if (scope_allowImport(manager->scope, endpoint)) {
- if (celixThreadMutex_lock(&manager->rsaListLock) == CELIX_SUCCESS) {
- int size = arrayList_size(manager->rsaList);
-
- for (int iter = 0; iter < size; iter++) {
- import_registration_pt import = NULL;
- remote_service_admin_service_pt rsa = arrayList_get(manager->rsaList, iter);
- celix_status_t substatus = rsa->importService(rsa->admin, endpoint, &import);
- if (substatus == CELIX_SUCCESS) {
- hashMap_put(imports, rsa, import);
- } else {
- status = substatus;
- }
- }
- celixThreadMutex_unlock(&manager->rsaListLock);
- }
-
- }
-
- celixThreadMutex_unlock(&manager->importedServicesLock);
- }
-
-
- return status;
-}
-
-celix_status_t topologyManager_removeImportedService(void *handle, endpoint_description_pt endpoint, char *matchedFilter) {
- celix_status_t status = CELIX_SUCCESS;
- topology_manager_pt manager = handle;
-
- logHelper_log(manager->loghelper, OSGI_LOGSERVICE_INFO, "TOPOLOGY_MANAGER: Remove imported service (%s; %s).", endpoint->service, endpoint->id);
-
- if (celixThreadMutex_lock(&manager->importedServicesLock) == CELIX_SUCCESS) {
-
- hash_map_iterator_pt iter = hashMapIterator_create(manager->importedServices);
- while (hashMapIterator_hasNext(iter)) {
- hash_map_entry_pt entry = hashMapIterator_nextEntry(iter);
- endpoint_description_pt ep = hashMapEntry_getKey(entry);
- hash_map_pt imports = hashMapEntry_getValue(entry);
-
- if (imports != NULL && strcmp(endpoint->id, ep->id) == 0) {
- hash_map_iterator_pt importsIter = hashMapIterator_create(imports);
-
- while (hashMapIterator_hasNext(importsIter)) {
- hash_map_entry_pt entry = hashMapIterator_nextEntry(importsIter);
- remote_service_admin_service_pt rsa = hashMapEntry_getKey(entry);
- import_registration_pt import = hashMapEntry_getValue(entry);
- celix_status_t substatus = rsa->importRegistration_close(rsa->admin, import);
- if (substatus == CELIX_SUCCESS) {
- hashMapIterator_remove(importsIter);
- } else {
- status = substatus;
- }
- }
- hashMapIterator_destroy(importsIter);
- hashMapIterator_remove(iter);
-
- hashMap_destroy(imports, false, false);
- }
- }
- hashMapIterator_destroy(iter);
- celixThreadMutex_unlock(&manager->importedServicesLock);
- }
-
- return status;
-}
-
-celix_status_t topologyManager_addExportedService(topology_manager_pt manager, service_reference_pt reference, char *serviceId) {
- celix_status_t status = CELIX_SUCCESS;
- properties_pt serviceProperties = NULL;
-
- logHelper_log(manager->loghelper, OSGI_LOGSERVICE_INFO, "TOPOLOGY_MANAGER: Add exported service (%s).", serviceId);
-
- if (celixThreadMutex_lock(&manager->exportedServicesLock) == CELIX_SUCCESS) {
- scope_getExportProperties(manager->scope, reference, &serviceProperties);
- hash_map_pt exports = hashMap_create(NULL, NULL, NULL, NULL);
- hashMap_put(manager->exportedServices, reference, exports);
-
- if (celixThreadMutex_lock(&manager->rsaListLock) == CELIX_SUCCESS) {
- int size = arrayList_size(manager->rsaList);
-
- if (size == 0) {
- logHelper_log(manager->loghelper, OSGI_LOGSERVICE_WARNING, "TOPOLOGY_MANAGER: No RSA available yet.");
- }
-
- for (int iter = 0; iter < size; iter++) {
- remote_service_admin_service_pt rsa = arrayList_get(manager->rsaList, iter);
-
- array_list_pt endpoints = NULL;
- celix_status_t substatus = rsa->exportService(rsa->admin, serviceId, serviceProperties, &endpoints);
-
- if (substatus == CELIX_SUCCESS) {
- hashMap_put(exports, rsa, endpoints);
- topologyManager_notifyListenersEndpointAdded(manager, rsa, endpoints);
- } else {
- status = substatus;
- }
- }
- celixThreadMutex_unlock(&manager->rsaListLock);
- }
- celixThreadMutex_unlock(&manager->exportedServicesLock);
- }
-
- return status;
-}
-
-celix_status_t topologyManager_removeExportedService(topology_manager_pt manager, service_reference_pt reference, char *serviceId) {
- celix_status_t status = CELIX_SUCCESS;
-
- logHelper_log(manager->loghelper, OSGI_LOGSERVICE_INFO, "TOPOLOGY_MANAGER: Remove exported service (%s).", serviceId);
-
- if (celixThreadMutex_lock(&manager->exportedServicesLock) == CELIX_SUCCESS) {
- hash_map_pt exports = hashMap_get(manager->exportedServices, reference);
- if (exports) {
- hash_map_iterator_pt iter = hashMapIterator_create(exports);
- while (hashMapIterator_hasNext(iter)) {
- hash_map_entry_pt entry = hashMapIterator_nextEntry(iter);
- remote_service_admin_service_pt rsa = hashMapEntry_getKey(entry);
- array_list_pt exportRegistrations = hashMapEntry_getValue(entry);
-
- int size = arrayList_size(exportRegistrations);
-
- for (int exportsIter = 0; exportsIter < size; exportsIter++) {
- export_registration_pt export = arrayList_get(exportRegistrations, exportsIter);
- topologyManager_notifyListenersEndpointRemoved(manager, rsa, export);
- rsa->exportRegistration_close(rsa->admin, export);
- }
-
- hashMap_remove(exports, rsa);
- //arrayList_destroy(exportRegistrations);
- hashMapIterator_destroy(iter);
- iter = hashMapIterator_create(exports);
-
- }
- hashMapIterator_destroy(iter);
- }
- exports = hashMap_remove(manager->exportedServices, reference);
-
- if (exports != NULL) {
- hashMap_destroy(exports, false, false);
- }
-
- celixThreadMutex_unlock(&manager->exportedServicesLock);
- }
-
- return status;
-}
-
-celix_status_t topologyManager_getEndpointDescriptionForExportRegistration(remote_service_admin_service_pt rsa, export_registration_pt export, endpoint_description_pt *endpoint) {
- celix_status_t status;
-
- export_reference_pt reference = NULL;
- status = rsa->exportRegistration_getExportReference(export, &reference);
-
- if (status == CELIX_SUCCESS) {
- status = rsa->exportReference_getExportedEndpoint(reference, endpoint);
- }
-
- free(reference);
-
- return status;
-}
-
-celix_status_t topologyManager_endpointListenerAdding(void* handle, service_reference_pt reference, void** service) {
- celix_status_t status = CELIX_SUCCESS;
- topology_manager_pt manager = (topology_manager_pt) handle;
-
- bundleContext_getService(manager->context, reference, service);
-
- return status;
-}
-
-celix_status_t topologyManager_endpointListenerAdded(void* handle, service_reference_pt reference, void* service) {
- celix_status_t status = CELIX_SUCCESS;
- topology_manager_pt manager = handle;
- const char* scope = NULL;
-
- logHelper_log(manager->loghelper, OSGI_LOGSERVICE_INFO, "TOPOLOGY_MANAGER: Added ENDPOINT_LISTENER");
-
- if (celixThreadMutex_lock(&manager->listenerListLock) == CELIX_SUCCESS) {
- hashMap_put(manager->listenerList, reference, NULL);
- celixThreadMutex_unlock(&manager->listenerListLock);
-
- serviceReference_getProperty(reference, OSGI_ENDPOINT_LISTENER_SCOPE, &scope);
-
- filter_pt filter = filter_create(scope);
- hash_map_iterator_pt refIter = hashMapIterator_create(manager->exportedServices);
-
- while (hashMapIterator_hasNext(refIter)) {
- hash_map_pt rsaExports = hashMapIterator_nextValue(refIter);
- hash_map_iterator_pt rsaIter = hashMapIterator_create(rsaExports);
-
- while (hashMapIterator_hasNext(rsaIter)) {
- hash_map_entry_pt entry = hashMapIterator_nextEntry(rsaIter);
- remote_service_admin_service_pt rsa = hashMapEntry_getKey(entry);
- array_list_pt registrations = hashMapEntry_getValue(entry);
-
- int arrayListSize = arrayList_size(registrations);
- int cnt = 0;
-
- for (; cnt < arrayListSize; cnt++) {
- export_registration_pt export = arrayList_get(registrations, cnt);
- endpoint_description_pt endpoint = NULL;
-
- status = topologyManager_getEndpointDescriptionForExportRegistration(rsa, export, &endpoint);
- if (status == CELIX_SUCCESS) {
- bool matchResult = false;
- filter_match(filter, endpoint->properties, &matchResult);
- if (matchResult) {
- endpoint_listener_pt listener = (endpoint_listener_pt) service;
- status = listener->endpointAdded(listener->handle, endpoint, (char*)scope);
- }
- }
- }
- }
- hashMapIterator_destroy(rsaIter);
- }
- hashMapIterator_destroy(refIter);
-
- filter_destroy(filter);
- }
-
- return status;
-}
-
-celix_status_t topologyManager_endpointListenerModified(void * handle, service_reference_pt reference, void * service) {
- celix_status_t status;
-
- status = topologyManager_endpointListenerRemoved(handle, reference, service);
-
- if (status == CELIX_SUCCESS) {
- status = topologyManager_endpointListenerAdded(handle, reference, service);
- }
-
- return status;
-}
-
-celix_status_t topologyManager_endpointListenerRemoved(void * handle, service_reference_pt reference, void * service) {
- celix_status_t status = CELIX_SUCCESS;
- topology_manager_pt manager = handle;
-
- if (celixThreadMutex_lock(&manager->listenerListLock) == CELIX_SUCCESS) {
-
- if (hashMap_remove(manager->listenerList, reference)) {
- logHelper_log(manager->loghelper, OSGI_LOGSERVICE_INFO, "EndpointListener Removed");
- }
-
- celixThreadMutex_unlock(&manager->listenerListLock);
- }
-
- return status;
-}
-
-celix_status_t topologyManager_notifyListenersEndpointAdded(topology_manager_pt manager, remote_service_admin_service_pt rsa, array_list_pt registrations) {
- celix_status_t status = CELIX_SUCCESS;
-
- if (celixThreadMutex_lock(&manager->listenerListLock) == CELIX_SUCCESS) {
-
- hash_map_iterator_pt iter = hashMapIterator_create(manager->listenerList);
- while (hashMapIterator_hasNext(iter)) {
- const char* scope = NULL;
- endpoint_listener_pt epl = NULL;
- service_reference_pt reference = hashMapIterator_nextKey(iter);
-
- serviceReference_getProperty(reference, OSGI_ENDPOINT_LISTENER_SCOPE, &scope);
-
- status = bundleContext_getService(manager->context, reference, (void **) &epl);
- if (status == CELIX_SUCCESS) {
- filter_pt filter = filter_create(scope);
-
- int regSize = arrayList_size(registrations);
- for (int regIt = 0; regIt < regSize; regIt++) {
- export_registration_pt export = arrayList_get(registrations, regIt);
- endpoint_description_pt endpoint = NULL;
- celix_status_t substatus = topologyManager_getEndpointDescriptionForExportRegistration(rsa, export, &endpoint);
- if (substatus == CELIX_SUCCESS) {
- bool matchResult = false;
- filter_match(filter, endpoint->properties, &matchResult);
- if (matchResult) {
- status = epl->endpointAdded(epl->handle, endpoint, (char*)scope);
- }
- } else {
- status = substatus;
- }
- }
- filter_destroy(filter);
- }
- }
- hashMapIterator_destroy(iter);
- celixThreadMutex_unlock(&manager->listenerListLock);
- }
-
- return status;
-}
-
-celix_status_t topologyManager_notifyListenersEndpointRemoved(topology_manager_pt manager, remote_service_admin_service_pt rsa, export_registration_pt export) {
- celix_status_t status = CELIX_SUCCESS;
-
- if (celixThreadMutex_lock(&manager->listenerListLock) == CELIX_SUCCESS) {
- hash_map_iterator_pt iter = hashMapIterator_create(manager->listenerList);
- while (hashMapIterator_hasNext(iter)) {
- endpoint_description_pt endpoint = NULL;
- endpoint_listener_pt epl = NULL;
- celix_status_t substatus;
- const char* scope = NULL;
-
- service_reference_pt reference = hashMapIterator_nextKey(iter);
- serviceReference_getProperty(reference, OSGI_ENDPOINT_LISTENER_SCOPE, &scope);
-
- substatus = bundleContext_getService(manager->context, reference, (void **) &epl);
-
- if (substatus == CELIX_SUCCESS) {
- substatus = topologyManager_getEndpointDescriptionForExportRegistration(rsa, export, &endpoint);
- }
-
- if (substatus == CELIX_SUCCESS) {
- substatus = epl->endpointRemoved(epl->handle, endpoint, NULL);
- }
-
- /* if (substatus != CELIX_SUCCESS) {
- status = substatus;
-
- }
- */
- }
- hashMapIterator_destroy(iter);
- celixThreadMutex_unlock(&manager->listenerListLock);
- }
-
- return status;
-}
-
-celix_status_t topologyManager_extendFilter(topology_manager_pt manager, char *filter, char **updatedFilter) {
- celix_status_t status;
- bundle_context_pt context = manager->context;
- const char* uuid = NULL;
-
- status = bundleContext_getProperty(context, OSGI_FRAMEWORK_FRAMEWORK_UUID, &uuid);
-
- if (!uuid) {
- logHelper_log(manager->loghelper, OSGI_LOGSERVICE_ERROR, "TOPOLOGY_MANAGER: no framework UUID defined?!");
- return CELIX_BUNDLE_EXCEPTION;
- }
-
- int len = 10 + strlen(filter) + strlen(OSGI_RSA_ENDPOINT_FRAMEWORK_UUID) + strlen(uuid);
- *updatedFilter = malloc(len);
- if (!*updatedFilter) {
- return CELIX_ENOMEM;
- }
-
- snprintf(*updatedFilter, len, "(&%s(!(%s=%s)))", filter, OSGI_RSA_ENDPOINT_FRAMEWORK_UUID, uuid);
-
- return status;
-}
-
-celix_status_t topologyManager_listenerAdded(void *handle, array_list_pt listeners) {
- celix_status_t status = CELIX_SUCCESS;
- topology_manager_pt manager = handle;
-
- for (int i = 0; i < arrayList_size(listeners); i++) {
- listener_hook_info_pt info = arrayList_get(listeners, i);
- bundle_pt bundle = NULL, self = NULL;
- bundleContext_getBundle(info->context, &bundle);
- bundleContext_getBundle(manager->context, &self);
- if (bundle == self) {
- logHelper_log(manager->loghelper, OSGI_LOGSERVICE_DEBUG, "TOPOLOGY_MANAGER: Ignore myself.");
- continue;
- }
-
- logHelper_log(manager->loghelper, OSGI_LOGSERVICE_INFO, "TOPOLOGY_MANAGER: listener with filter \"%s\" added", info->filter);
-
- char *filter = NULL;
- bool free_filter = true;
- status = topologyManager_extendFilter(manager, info->filter, &filter);
-#if 0
- if(filter != NULL){
- // TODO: add status handling
- status = celixThreadMutex_lock(&manager->importScopesLock);
-
- struct scope *interest = hashMap_get(manager->importScopes, filter);
- if (interest) {
- interest->refs++;
- free(filter);
- filter = NULL;
- } else {
- interest = malloc(sizeof(*interest));
- interest->filter = filter;
- interest->refs = 1;
- hashMap_put(manager->importScopes, filter, interest);
- free_filter = false;
- }
-
- status = celixThreadMutex_unlock(&manager->importScopesLock);
- }
-#endif
-
- if (filter != NULL && free_filter) {
- free(filter);
- }
-
- }
-
- return status;
-}
-
-celix_status_t topologyManager_listenerRemoved(void *handle, array_list_pt listeners) {
- celix_status_t status = CELIX_SUCCESS;
- topology_manager_pt manager = handle;
-
- for (int i = 0; i < arrayList_size(listeners); i++) {
- listener_hook_info_pt info = arrayList_get(listeners, i);
-
- bundle_pt bundle = NULL, self = NULL;
- bundleContext_getBundle(info->context, &bundle);
- bundleContext_getBundle(manager->context, &self);
- if (bundle == self) {
- logHelper_log(manager->loghelper, OSGI_LOGSERVICE_DEBUG, "TOPOLOGY_MANAGER: Ignore myself.");
- continue;
- }
-
- logHelper_log(manager->loghelper, OSGI_LOGSERVICE_INFO, "TOPOLOGY_MANAGER: listener with filter \"%s\" removed.", info->filter);
-
- char *filter = NULL;
- topologyManager_extendFilter(manager, info->filter, &filter);
-#if 0
- status = celixThreadMutex_lock(&manager->importScopesLock);
-
- struct scope *interest = hashMap_get(manager->importScopes, filter);
- if (interest != NULL && --interest->refs <= 0) {
- // last reference, remove from scope
- hash_map_entry_pt entry = hashMap_getEntry(manager->importScopes, filter);
- char* key = (char*) hashMapEntry_getKey(entry);
- interest = hashMap_remove(manager->importScopes, filter);
- free(key);
- free(interest);
- }
-#endif
-
- if (filter != NULL) {
- free(filter);
- }
-#if 0
- status = celixThreadMutex_unlock(&manager->importScopesLock);
-#endif
- }
-
- return status;
-}
-
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/topology_manager/public/include/tm_scope.h
----------------------------------------------------------------------
diff --git a/remote_services/topology_manager/public/include/tm_scope.h b/remote_services/topology_manager/public/include/tm_scope.h
deleted file mode 100644
index d4f60ca..0000000
--- a/remote_services/topology_manager/public/include/tm_scope.h
+++ /dev/null
@@ -1,46 +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.
- */
-/*
- * tm_scope.h
- *
- * \date Oct 29, 2015
- * \author <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- * \copyright Apache License, Version 2.0
- */
-
-#ifndef TM_SCOPE_H_
-#define TM_SCOPE_H_
-
-#include "celix_errno.h"
-
-#define TOPOLOGYMANAGER_SCOPE_SERVICE "tm_scope"
-
-
-struct tm_scope_service {
- void *handle; // scope_pt
- celix_status_t (*addExportScope)(void *handle, char *filter, properties_pt props);
- celix_status_t (*removeExportScope)(void *handle, char *filter);
- celix_status_t (*addImportScope)(void *handle, char *filter);
- celix_status_t (*removeImportScope)(void *handle, char *filter);
-};
-
-typedef struct tm_scope_service tm_scope_service_t;
-typedef tm_scope_service_t *tm_scope_service_pt;
-
-#endif /* TM_SCOPE_H_ */
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/topology_manager/src/activator.c
----------------------------------------------------------------------
diff --git a/remote_services/topology_manager/src/activator.c b/remote_services/topology_manager/src/activator.c
new file mode 100644
index 0000000..7f39a25
--- /dev/null
+++ b/remote_services/topology_manager/src/activator.c
@@ -0,0 +1,289 @@
+/**
+ *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.
+ */
+/*
+ * activator.c
+ *
+ * \date Sep 29, 2011
+ * \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 <string.h>
+
+#include "constants.h"
+#include "bundle_activator.h"
+#include "service_tracker.h"
+#include "service_registration.h"
+
+#include "topology_manager.h"
+#include "endpoint_listener.h"
+#include "remote_constants.h"
+#include "listener_hook_service.h"
+#include "log_service.h"
+#include "log_helper.h"
+#include "scope.h"
+#include "tm_scope.h"
+#include "topology_manager.h"
+
+struct activator {
+ bundle_context_pt context;
+
+ topology_manager_pt manager;
+
+ service_tracker_pt endpointListenerTracker;
+ service_tracker_pt remoteServiceAdminTracker;
+ service_listener_pt serviceListener;
+
+ endpoint_listener_pt endpointListener;
+ service_registration_pt endpointListenerService;
+
+ listener_hook_service_pt hookService;
+ service_registration_pt hook;
+
+ tm_scope_service_pt scopeService;
+ service_registration_pt scopeReg;
+
+ log_helper_pt loghelper;
+};
+
+
+static celix_status_t bundleActivator_createEPLTracker(struct activator *activator, service_tracker_pt *tracker);
+static celix_status_t bundleActivator_createRSATracker(struct activator *activator, service_tracker_pt *tracker);
+static celix_status_t bundleActivator_createServiceListener(struct activator *activator, service_listener_pt *listener);
+
+celix_status_t bundleActivator_create(bundle_context_pt context, void **userData) {
+ celix_status_t status = CELIX_SUCCESS;
+ struct activator *activator = NULL;
+ void *scope;
+
+ activator = calloc(1, sizeof(struct activator));
+
+ if (!activator) {
+ return CELIX_ENOMEM;
+ }
+
+ activator->context = context;
+ activator->endpointListenerService = NULL;
+ activator->endpointListenerTracker = NULL;
+ activator->hook = NULL;
+ activator->manager = NULL;
+ activator->remoteServiceAdminTracker = NULL;
+ activator->serviceListener = NULL;
+ activator->scopeService = calloc(1, sizeof(*(activator->scopeService)));
+ if (activator->scopeService == NULL)
+ {
+ free(activator);
+ return CELIX_ENOMEM;
+ }
+
+ activator->scopeService->addExportScope = tm_addExportScope;
+ activator->scopeService->removeExportScope = tm_removeExportScope;
+ activator->scopeService->addImportScope = tm_addImportScope;
+ activator->scopeService->removeImportScope = tm_removeImportScope;
+ activator->scopeReg = NULL; // explicitly needed, otherwise exception
+
+ logHelper_create(context, &activator->loghelper);
+ logHelper_start(activator->loghelper);
+
+ status = topologyManager_create(context, activator->loghelper, &activator->manager, &scope);
+ activator->scopeService->handle = scope;
+
+ if (status == CELIX_SUCCESS) {
+ status = bundleActivator_createEPLTracker(activator, &activator->endpointListenerTracker);
+ if (status == CELIX_SUCCESS) {
+ status = bundleActivator_createRSATracker(activator, &activator->remoteServiceAdminTracker);
+ if (status == CELIX_SUCCESS) {
+ status = bundleActivator_createServiceListener(activator, &activator->serviceListener);
+ if (status == CELIX_SUCCESS) {
+ *userData = activator;
+ }
+ }
+ }
+ }
+
+ if(status != CELIX_SUCCESS){
+ bundleActivator_destroy(activator,context);
+ }
+
+ return status;
+}
+
+static celix_status_t bundleActivator_createEPLTracker(struct activator *activator, service_tracker_pt *tracker) {
+ celix_status_t status;
+
+ service_tracker_customizer_pt customizer = NULL;
+
+ status = serviceTrackerCustomizer_create(activator->manager, topologyManager_endpointListenerAdding, topologyManager_endpointListenerAdded, topologyManager_endpointListenerModified,
+ topologyManager_endpointListenerRemoved, &customizer);
+
+ if (status == CELIX_SUCCESS) {
+ status = serviceTracker_create(activator->context, (char *) OSGI_ENDPOINT_LISTENER_SERVICE, customizer, tracker);
+ }
+
+ return status;
+}
+
+static celix_status_t bundleActivator_createRSATracker(struct activator *activator, service_tracker_pt *tracker) {
+ celix_status_t status;
+
+ service_tracker_customizer_pt customizer = NULL;
+
+ status = serviceTrackerCustomizer_create(activator->manager, topologyManager_rsaAdding, topologyManager_rsaAdded, topologyManager_rsaModified, topologyManager_rsaRemoved, &customizer);
+
+ if (status == CELIX_SUCCESS) {
+ status = serviceTracker_create(activator->context, OSGI_RSA_REMOTE_SERVICE_ADMIN, customizer, tracker);
+ }
+
+ return status;
+}
+
+static celix_status_t bundleActivator_createServiceListener(struct activator *activator, service_listener_pt *listener) {
+ celix_status_t status = CELIX_SUCCESS;
+
+ *listener = malloc(sizeof(**listener));
+ if (!*listener) {
+ return CELIX_ENOMEM;
+ }
+
+ (*listener)->handle = activator->manager;
+ (*listener)->serviceChanged = topologyManager_serviceChanged;
+
+ return status;
+}
+
+celix_status_t bundleActivator_start(void * userData, bundle_context_pt context) {
+ celix_status_t status;
+ struct activator *activator = userData;
+
+ endpoint_listener_pt endpointListener = malloc(sizeof(*endpointListener));
+ endpointListener->handle = activator->manager;
+ endpointListener->endpointAdded = topologyManager_addImportedService;
+ endpointListener->endpointRemoved = topologyManager_removeImportedService;
+ activator->endpointListener = endpointListener;
+
+ const char *uuid = NULL;
+ status = bundleContext_getProperty(activator->context, OSGI_FRAMEWORK_FRAMEWORK_UUID, &uuid);
+ if (!uuid) {
+ logHelper_log(activator->loghelper, OSGI_LOGSERVICE_ERROR, "TOPOLOGY_MANAGER: no framework UUID defined?!");
+ return CELIX_ILLEGAL_STATE;
+ }
+
+ size_t len = 14 + strlen(OSGI_FRAMEWORK_OBJECTCLASS) + strlen(OSGI_RSA_ENDPOINT_FRAMEWORK_UUID) + strlen(uuid);
+ char *scope = malloc(len);
+ if (!scope) {
+ return CELIX_ENOMEM;
+ }
+
+ snprintf(scope, len, "(&(%s=*)(!(%s=%s)))", OSGI_FRAMEWORK_OBJECTCLASS, OSGI_RSA_ENDPOINT_FRAMEWORK_UUID, uuid);
+
+ logHelper_log(activator->loghelper, OSGI_LOGSERVICE_INFO, "TOPOLOGY_MANAGER: endpoint listener scope is %s", scope);
+
+ properties_pt props = properties_create();
+ properties_set(props, (char *) OSGI_ENDPOINT_LISTENER_SCOPE, scope);
+
+ // We can release the scope, as properties_set makes a copy of the key & value...
+ free(scope);
+
+ bundleContext_registerService(context, (char *) OSGI_ENDPOINT_LISTENER_SERVICE, endpointListener, props, &activator->endpointListenerService);
+
+ listener_hook_service_pt hookService = malloc(sizeof(*hookService));
+ hookService->handle = activator->manager;
+ hookService->added = topologyManager_listenerAdded;
+ hookService->removed = topologyManager_listenerRemoved;
+ activator->hookService = hookService;
+
+ bundleContext_registerService(context, (char *) OSGI_FRAMEWORK_LISTENER_HOOK_SERVICE_NAME, hookService, NULL, &activator->hook);
+ bundleContext_addServiceListener(context, activator->serviceListener, "(service.exported.interfaces=*)");
+
+ if (status == CELIX_SUCCESS) {
+ serviceTracker_open(activator->remoteServiceAdminTracker);
+ }
+
+ if (status == CELIX_SUCCESS) {
+ status = serviceTracker_open(activator->endpointListenerTracker);
+ }
+
+ bundleContext_registerService(context, (char *) TOPOLOGYMANAGER_SCOPE_SERVICE, activator->scopeService, NULL, &activator->scopeReg);
+
+ array_list_pt references = NULL;
+ bundleContext_getServiceReferences(context, NULL, "(service.exported.interfaces=*)", &references);
+ int i;
+ for (i = 0; i < arrayList_size(references); i++) {
+ service_reference_pt reference = arrayList_get(references, i);
+ const char* serviceId = NULL;
+ status = CELIX_DO_IF(status, serviceReference_getProperty(reference, OSGI_FRAMEWORK_SERVICE_ID, &serviceId));
+
+ CELIX_DO_IF(status, topologyManager_addExportedService(activator->manager, reference, (char*)serviceId));
+ }
+ arrayList_destroy(references);
+
+ return status;
+}
+
+celix_status_t bundleActivator_stop(void * userData, bundle_context_pt context) {
+ celix_status_t status = CELIX_SUCCESS;
+ struct activator *activator = userData;
+
+ if (serviceTracker_close(activator->remoteServiceAdminTracker) == CELIX_SUCCESS) {
+ serviceTracker_destroy(activator->remoteServiceAdminTracker);
+ }
+
+ if (serviceTracker_close(activator->endpointListenerTracker) == CELIX_SUCCESS) {
+ serviceTracker_destroy(activator->endpointListenerTracker);
+ }
+
+ bundleContext_removeServiceListener(context, activator->serviceListener);
+ free(activator->serviceListener);
+
+ serviceRegistration_unregister(activator->hook);
+ free(activator->hookService);
+
+ serviceRegistration_unregister(activator->endpointListenerService);
+ free(activator->endpointListener);
+
+ serviceRegistration_unregister(activator->scopeReg);
+
+ topologyManager_closeImports(activator->manager);
+
+ return status;
+}
+
+celix_status_t bundleActivator_destroy(void * userData, bundle_context_pt context) {
+ celix_status_t status = CELIX_SUCCESS;
+
+ struct activator *activator = userData;
+ if (!activator || !activator->manager) {
+ status = CELIX_BUNDLE_EXCEPTION;
+ } else {
+ logHelper_stop(activator->loghelper);
+ logHelper_destroy(&activator->loghelper);
+
+ status = topologyManager_destroy(activator->manager);
+
+ if (activator->scopeService) {
+ free(activator->scopeService);
+ }
+
+ free(activator);
+ }
+
+ return status;
+}
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/topology_manager/src/scope.c
----------------------------------------------------------------------
diff --git a/remote_services/topology_manager/src/scope.c b/remote_services/topology_manager/src/scope.c
new file mode 100644
index 0000000..b81d050
--- /dev/null
+++ b/remote_services/topology_manager/src/scope.c
@@ -0,0 +1,326 @@
+/**
+ *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.
+ */
+/*
+ * scope.c
+ *
+ * \date Sep 29, 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 <string.h>
+#include "scope.h"
+#include "tm_scope.h"
+#include "topology_manager.h"
+#include "utils.h"
+
+struct scope_item {
+ properties_pt props;
+};
+
+struct scope {
+ void *manager; // owner of the scope datastructure
+ celix_thread_mutex_t exportScopeLock;
+ hash_map_pt exportScopes; // key is filter, value is scope_item (properties set)
+
+ celix_thread_mutex_t importScopeLock;
+ array_list_pt importScopes; // list of filters
+
+ celix_status_t (*exportScopeChangedHandler)(void* manager, char *filter);
+ celix_status_t (*importScopeChangedHandler)(void* manager, char *filter);
+};
+
+static celix_status_t import_equal(const void *, const void *, bool *equals);
+
+/*
+ * SERVICES
+ */
+
+celix_status_t tm_addExportScope(void *handle, char *filter, properties_pt props) {
+ celix_status_t status = CELIX_SUCCESS;
+ scope_pt scope = (scope_pt) handle;
+ properties_pt present;
+
+ if (handle == NULL)
+ return CELIX_ILLEGAL_ARGUMENT;
+
+ if (celixThreadMutex_lock(&scope->exportScopeLock) == CELIX_SUCCESS) {
+ // For now we just don't allow two exactly the same filters
+ // TODO: What we actually need is the following
+ // If part of the new filter is already present in any of the filters in exportScopes
+ // we have to assure that the new filter defines other property keys than the property keys
+ // in the already defined filter!
+ present = (properties_pt) hashMap_get(scope->exportScopes, filter);
+ if (present == NULL) {
+ struct scope_item *item = calloc(1, sizeof(*item));
+ if (item == NULL) {
+ status = CELIX_ENOMEM;
+ } else {
+ item->props = props;
+ hashMap_put(scope->exportScopes, (void*) strdup(filter), (void*) item);
+ }
+ } else {
+ // don't allow the same filter twice
+ properties_destroy(props);
+ status = CELIX_ILLEGAL_ARGUMENT;
+ }
+ celixThreadMutex_unlock(&scope->exportScopeLock);
+ }
+
+ if (scope->exportScopeChangedHandler != NULL) {
+ status = CELIX_DO_IF(status, scope->exportScopeChangedHandler(scope->manager, filter));
+ }
+
+ return status;
+}
+
+celix_status_t tm_removeExportScope(void *handle, char *filter) {
+ celix_status_t status = CELIX_SUCCESS;
+ scope_pt scope = (scope_pt) handle;
+
+ if (handle == NULL)
+ return CELIX_ILLEGAL_ARGUMENT;
+
+ if (celixThreadMutex_lock(&scope->exportScopeLock) == CELIX_SUCCESS) {
+ struct scope_item *present = (struct scope_item *) hashMap_get(scope->exportScopes, filter);
+ if (present == NULL) {
+ status = CELIX_ILLEGAL_ARGUMENT;
+ } else {
+ properties_destroy(present->props);
+ hashMap_remove(scope->exportScopes, filter); // frees also the item!
+ }
+ celixThreadMutex_unlock(&scope->exportScopeLock);
+ }
+ if (scope->exportScopeChangedHandler != NULL) {
+ status = CELIX_DO_IF(status, scope->exportScopeChangedHandler(scope->manager, filter));
+ }
+ return status;
+}
+
+celix_status_t tm_addImportScope(void *handle, char *filter) {
+ celix_status_t status = CELIX_SUCCESS;
+ scope_pt scope = (scope_pt) handle;
+
+ filter_pt new;
+
+ if (handle == NULL)
+ return CELIX_ILLEGAL_ARGUMENT;
+ new = filter_create(filter);
+ if (new == NULL) {
+ return CELIX_ILLEGAL_ARGUMENT; // filter not parseble
+ }
+ if (celixThreadMutex_lock(&scope->importScopeLock) == CELIX_SUCCESS) {
+ int index = arrayList_indexOf(scope->importScopes, new);
+ filter_pt present = (filter_pt) arrayList_get(scope->importScopes, index);
+ if (present == NULL) {
+ arrayList_add(scope->importScopes, new);
+ } else {
+ filter_destroy(new);
+ status = CELIX_ILLEGAL_ARGUMENT;
+ }
+
+ celixThreadMutex_unlock(&scope->importScopeLock);
+ }
+ if (scope->importScopeChangedHandler != NULL) {
+ status = CELIX_DO_IF(status, scope->importScopeChangedHandler(scope->manager, filter));
+ }
+ return status;
+}
+
+celix_status_t tm_removeImportScope(void *handle, char *filter) {
+ celix_status_t status = CELIX_SUCCESS;
+ scope_pt scope = (scope_pt) handle;
+ filter_pt new;
+
+ if (handle == NULL)
+ return CELIX_ILLEGAL_ARGUMENT;
+
+ new = filter_create(filter);
+ if (new == NULL) {
+ return CELIX_ILLEGAL_ARGUMENT; // filter not parseble
+ }
+
+ if (celixThreadMutex_lock(&scope->importScopeLock) == CELIX_SUCCESS) {
+ int index = arrayList_indexOf(scope->importScopes, new);
+ filter_pt present = (filter_pt) arrayList_get(scope->importScopes, index);
+ if (present == NULL)
+ status = CELIX_ILLEGAL_ARGUMENT;
+ else {
+ arrayList_removeElement(scope->importScopes, present);
+ filter_destroy(present);
+ }
+ celixThreadMutex_unlock(&scope->importScopeLock);
+ }
+ if (scope->importScopeChangedHandler != NULL) {
+ status = CELIX_DO_IF(status, scope->importScopeChangedHandler(scope->manager, filter));
+ }
+ filter_destroy(new);
+ return status;
+}
+
+/*****************************************************************************
+ * GLOBAL FUNCTIONS
+ *****************************************************************************/
+
+void scope_setExportScopeChangedCallback(scope_pt scope, celix_status_t (*changed)(void *handle, char *servName)) {
+ scope->exportScopeChangedHandler = changed;
+}
+
+void scope_setImportScopeChangedCallback(scope_pt scope, celix_status_t (*changed)(void *handle, char *servName)) {
+ scope->importScopeChangedHandler = changed;
+}
+
+celix_status_t scope_scopeCreate(void *handle, scope_pt *scope) {
+ celix_status_t status = CELIX_SUCCESS;
+
+ *scope = calloc(1, sizeof **scope);
+
+ if (*scope == NULL) {
+ return CELIX_ENOMEM;
+ }
+
+ (*scope)->manager = handle;
+ celixThreadMutex_create(&(*scope)->exportScopeLock, NULL);
+ celixThreadMutex_create(&(*scope)->importScopeLock, NULL);
+
+ (*scope)->exportScopes = hashMap_create(utils_stringHash, NULL, utils_stringEquals, NULL);
+ arrayList_createWithEquals(import_equal, &((*scope)->importScopes));
+ (*scope)->exportScopeChangedHandler = NULL;
+
+ return status;
+}
+
+celix_status_t scope_scopeDestroy(scope_pt scope) {
+ celix_status_t status = CELIX_SUCCESS;
+
+ if (celixThreadMutex_lock(&scope->exportScopeLock) == CELIX_SUCCESS) {
+ hash_map_iterator_pt iter = hashMapIterator_create(scope->exportScopes);
+ while (hashMapIterator_hasNext(iter)) {
+ hash_map_entry_pt scopedEntry = hashMapIterator_nextEntry(iter);
+ struct scope_item *item = (struct scope_item*) hashMapEntry_getValue(scopedEntry);
+ properties_destroy(item->props);
+ }
+ hashMapIterator_destroy(iter);
+ hashMap_destroy(scope->exportScopes, true, true); // free keys, free values
+ celixThreadMutex_unlock(&scope->exportScopeLock);
+ }
+
+ if (celixThreadMutex_lock(&scope->importScopeLock) == CELIX_SUCCESS) {
+ array_list_iterator_pt imp_iter = arrayListIterator_create(scope->importScopes);
+ while (arrayListIterator_hasNext(imp_iter)) {
+ filter_pt element = (filter_pt) arrayListIterator_next(imp_iter);
+ filter_destroy(element);
+ // no need to call arrayList_removeElement(element) because complete list is destroyed
+ }
+ arrayListIterator_destroy(imp_iter);
+ arrayList_destroy(scope->importScopes);
+ celixThreadMutex_unlock(&scope->importScopeLock);
+ }
+
+ celixThreadMutex_destroy(&scope->exportScopeLock);
+ celixThreadMutex_destroy(&scope->importScopeLock);
+ free(scope);
+ return status;
+}
+
+/*****************************************************************************
+ * STATIC FUNCTIONS
+ *****************************************************************************/
+static celix_status_t import_equal(const void *src, const void *dest, bool *equals) {
+ celix_status_t status;
+
+ filter_pt src_filter = (filter_pt) src;
+ filter_pt dest_filter = (filter_pt) dest;
+ status = filter_match_filter(src_filter, dest_filter, equals);
+ return status;
+}
+
+bool scope_allowImport(scope_pt scope, endpoint_description_pt endpoint) {
+ bool allowImport = false;
+ array_list_iterator_pt iter;
+
+ if (celixThreadMutex_lock(&(scope->importScopeLock)) == CELIX_SUCCESS) {
+ if (arrayList_size(scope->importScopes) == 0) {
+ allowImport = true;
+ } else {
+ iter = arrayListIterator_create(scope->importScopes);
+ while ((allowImport == false) && arrayListIterator_hasNext(iter)) {
+ filter_pt element = (filter_pt) arrayListIterator_next(iter);
+ filter_match(element, endpoint->properties, &allowImport);
+ }
+ arrayListIterator_destroy(iter);
+ }
+ celixThreadMutex_unlock(&scope->importScopeLock);
+ }
+ return allowImport;
+}
+
+celix_status_t scope_getExportProperties(scope_pt scope, service_reference_pt reference, properties_pt *props) {
+ celix_status_t status = CELIX_SUCCESS;
+ unsigned int size = 0;
+ char **keys;
+ bool found = false;
+
+ *props = NULL;
+ properties_pt serviceProperties = properties_create(); // GB: not sure if a copy is needed
+ // or serviceReference_getProperties() is
+ // is acceptable
+
+ serviceReference_getPropertyKeys(reference, &keys, &size);
+ for (int i = 0; i < size; i++) {
+ char *key = keys[i];
+ const 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(serviceProperties, key, value);
+ }
+
+ }
+
+ free(keys);
+
+ if (celixThreadMutex_lock(&(scope->exportScopeLock)) == CELIX_SUCCESS) {
+ hash_map_iterator_pt scopedPropIter = hashMapIterator_create(scope->exportScopes);
+ // TODO: now stopping if first filter matches, alternatively we could build up
+ // the additional output properties for each filter that matches?
+ while ((!found) && hashMapIterator_hasNext(scopedPropIter)) {
+ hash_map_entry_pt scopedEntry = hashMapIterator_nextEntry(scopedPropIter);
+ char *filterStr = (char *) hashMapEntry_getKey(scopedEntry);
+ filter_pt filter = filter_create(filterStr);
+ if (filter != NULL) {
+ // test if the scope filter matches the exported service properties
+ status = filter_match(filter, serviceProperties, &found);
+ if (found) {
+ struct scope_item *item = (struct scope_item *) hashMapEntry_getValue(scopedEntry);
+ *props = item->props;
+ }
+ }
+ filter_destroy(filter);
+ }
+ hashMapIterator_destroy(scopedPropIter);
+ properties_destroy(serviceProperties);
+
+ celixThreadMutex_unlock(&(scope->exportScopeLock));
+ }
+
+ return status;
+}
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/topology_manager/src/scope.h
----------------------------------------------------------------------
diff --git a/remote_services/topology_manager/src/scope.h b/remote_services/topology_manager/src/scope.h
new file mode 100644
index 0000000..4035e2c
--- /dev/null
+++ b/remote_services/topology_manager/src/scope.h
@@ -0,0 +1,150 @@
+/**
+ *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.
+ */
+/*
+ * scope.h
+ *
+ * \date Sep 29, 2015
+ * \author <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ * \copyright Apache License, Version 2.0
+ */
+
+#ifndef TOPOLOGY_SCOPE_H_
+#define TOPOLOGY_SCOPE_H_
+
+#include "celixbool.h"
+#include "celix_errno.h"
+#include "celix_threads.h"
+#include "hash_map.h"
+#include "endpoint_description.h"
+#include "properties.h"
+#include "service_reference.h"
+#include "tm_scope.h"
+
+typedef struct scope *scope_pt;
+
+
+
+/* \brief create scope structure
+ *
+ * \param owning component pointer
+ * \param scope to be created
+ *
+ * \return CELIX_SUCCESS
+ * CELIX_ENOMEM
+ */
+celix_status_t scope_scopeCreate(void *handle, scope_pt *scope);
+
+/* \brief destroy scope structure
+ *
+ * \param scope to be destroyed
+ *
+ * \return CELIX_SUCCESS
+ */
+celix_status_t scope_scopeDestroy(scope_pt scope);
+
+/* \brief register export scope change callback of topology manager
+ *
+ * \param scope structure
+ * \param changed function pointer
+ *
+ * \return -
+ */
+void scope_setExportScopeChangedCallback(scope_pt scope, celix_status_t (*changed)(void *handle, char *servName));
+
+/* \brief register import scope change callback of topology manager
+ *
+ * \param scope structure
+ * \param changed function pointer
+ *
+ * \return -
+ */
+void scope_setImportScopeChangedCallback(scope_pt scope, celix_status_t (*changed)(void *handle, char *servName));
+
+
+/* \brief Test if scope allows import of service
+ *
+ * \param scope containing import rules
+ * \param endpoint import service endpoint description
+ *
+ * \return true import allowed
+ * false import not allowed
+ */
+bool scope_allowImport(scope_pt scope, endpoint_description_pt endpoint);
+
+/* \brief Test if scope allows import of service
+ *
+ * \param scope containing export rules
+ * \param reference to service
+ * \param props, additional properties defining restrictions for the exported service
+ * NULL if no additional restrictions found
+ *
+ * \return CELIX_SUCCESS
+ *
+ */
+celix_status_t scope_getExportProperties(scope_pt scope, service_reference_pt reference, properties_pt *props);
+
+/* \brief add restricted scope for specified exported service
+ *
+ * \param handle pointer to scope
+ * \param filter, filter string
+ * \param props additional properties defining restrictions for the exported service
+ *
+ * \return CELIX_SUCCESS if added to scope
+ * CELIX_ILLEGAL_ARGUMENT if service scope is already restricted before
+ *
+ */
+celix_status_t tm_addExportScope(void *handle, char *filter, properties_pt props);
+
+/* \brief remove restricted scope for specified exported service
+ *
+ * \param handle pointer to scope
+ * \param filter, filter string
+ *
+ * \return CELIX_SUCCESS if removed
+ * CELIX_ILLEGAL_ARGUMENT if service not found in scope
+ *
+ */
+celix_status_t tm_removeExportScope(void *handle, char *filter);
+
+/* \brief add restricted scope for specified imported service
+ *
+ * \param handle pointer to scope
+ * \param filter, filter string
+ * \param props additional properties defining restrictions for the imported service
+ *
+ * \return CELIX_SUCCESS if added to scope
+ * CELIX_ILLEGAL_ARGUMENT if service scope is already restricted before
+ *
+ */
+celix_status_t tm_addImportScope(void *handle, char *filter);
+
+
+/* \brief remove restricted scope for specified imported service
+ *
+ * \param handle pointer to scope
+ * \param filter, filter string
+ *
+ * \return CELIX_SUCCESS if removed
+ * CELIX_ILLEGAL_ARGUMENT if service not found in scope
+ *
+ */
+celix_status_t tm_removeImportScope(void *handle, char *filter);
+
+
+#endif // TOPOLOGY_SCOPE_H_
[16/19] celix git commit: CELIX-417: Refactor for CMake usage in RSA,
PSA and Docker. mostly trying to identify the api and common libraries
Posted by pn...@apache.org.
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/pubsub/pubsub_discovery/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_discovery/CMakeLists.txt b/pubsub/pubsub_discovery/CMakeLists.txt
index 948da3e..0e7d6c5 100644
--- a/pubsub/pubsub_discovery/CMakeLists.txt
+++ b/pubsub/pubsub_discovery/CMakeLists.txt
@@ -18,26 +18,25 @@
find_package(CURL REQUIRED)
find_package(Jansson REQUIRED)
-include_directories("${CURL_INCLUDE_DIR}")
-include_directories("${JANSSON_INCLUDE_DIR}")
-include_directories("${PROJECT_SOURCE_DIR}/pubsub/pubsub_common/public/include")
-include_directories("${PROJECT_SOURCE_DIR}/pubsub/api/pubsub")
-include_directories("${PROJECT_SOURCE_DIR}/etcdlib/public/include")
-include_directories("private/include")
-include_directories("public/include")
-
add_bundle(org.apache.celix.pubsub_discovery.etcd.PubsubDiscovery
BUNDLE_SYMBOLICNAME "apache_celix_pubsub_discovery_etcd"
VERSION "1.0.0"
SOURCES
- private/src/psd_activator.c
- private/src/pubsub_discovery_impl.c
- private/src/etcd_common.c
- private/src/etcd_watcher.c
- private/src/etcd_writer.c
+ src/psd_activator.c
+ src/pubsub_discovery_impl.c
+ src/etcd_common.c
+ src/etcd_watcher.c
+ src/etcd_writer.c
${PROJECT_SOURCE_DIR}/pubsub/pubsub_common/public/src/pubsub_endpoint.c
${PROJECT_SOURCE_DIR}/pubsub/pubsub_common/public/src/pubsub_utils.c
)
-target_link_libraries(org.apache.celix.pubsub_discovery.etcd.PubsubDiscovery celix_framework celix_utils etcdlib_static ${CURL_LIBRARIES} ${JANSSON_LIBRARIES})
+target_include_directories(org.apache.celix.pubsub_discovery.etcd.PubsubDiscovery PRIVATE
+ src
+ include
+ ${CURL_INCLUDE_DIR}
+ ${JANSSON_INCLUDE_DIR}
+ )
+
+target_link_libraries(org.apache.celix.pubsub_discovery.etcd.PubsubDiscovery PRIVATE Celix::framework Celix::etcdlib_static ${CURL_LIBRARIES} ${JANSSON_LIBRARIES})
install_bundle(org.apache.celix.pubsub_discovery.etcd.PubsubDiscovery)
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/pubsub/pubsub_discovery/private/include/etcd_common.h
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_discovery/private/include/etcd_common.h b/pubsub/pubsub_discovery/private/include/etcd_common.h
deleted file mode 100644
index 7a3e7b6..0000000
--- a/pubsub/pubsub_discovery/private/include/etcd_common.h
+++ /dev/null
@@ -1,28 +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.
- */
-
-#ifndef ETCD_COMMON_H_
-#define ETCD_COMMON_H_
-
-#include "bundle_context.h"
-#include "celix_errno.h"
-
-celix_status_t etcdCommon_init(bundle_context_pt context);
-
-#endif /* ETCD_COMMON_H_ */
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/pubsub/pubsub_discovery/private/include/etcd_watcher.h
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_discovery/private/include/etcd_watcher.h b/pubsub/pubsub_discovery/private/include/etcd_watcher.h
deleted file mode 100644
index c425e60..0000000
--- a/pubsub/pubsub_discovery/private/include/etcd_watcher.h
+++ /dev/null
@@ -1,38 +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.
- */
-
-#ifndef ETCD_WATCHER_H_
-#define ETCD_WATCHER_H_
-
-#include "bundle_context.h"
-#include "celix_errno.h"
-
-#include "pubsub_discovery.h"
-#include "pubsub_endpoint.h"
-
-typedef struct etcd_watcher *etcd_watcher_pt;
-
-celix_status_t etcdWatcher_create(pubsub_discovery_pt discovery, bundle_context_pt context, const char *scope, const char* topic, etcd_watcher_pt *watcher);
-celix_status_t etcdWatcher_destroy(etcd_watcher_pt watcher);
-celix_status_t etcdWatcher_stop(etcd_watcher_pt watcher);
-
-celix_status_t etcdWatcher_getPublisherEndpointFromKey(pubsub_discovery_pt discovery, const char* key, const char* value, pubsub_endpoint_pt* pubEP);
-
-
-#endif /* ETCD_WATCHER_H_ */
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/pubsub/pubsub_discovery/private/include/etcd_writer.h
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_discovery/private/include/etcd_writer.h b/pubsub/pubsub_discovery/private/include/etcd_writer.h
deleted file mode 100644
index 3ff98b9..0000000
--- a/pubsub/pubsub_discovery/private/include/etcd_writer.h
+++ /dev/null
@@ -1,39 +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.
- */
-
-#ifndef ETCD_WRITER_H_
-#define ETCD_WRITER_H_
-
-#include "bundle_context.h"
-#include "celix_errno.h"
-
-#include "pubsub_discovery.h"
-#include "pubsub_endpoint.h"
-
-typedef struct etcd_writer *etcd_writer_pt;
-
-
-etcd_writer_pt etcdWriter_create(pubsub_discovery_pt discovery);
-void etcdWriter_destroy(etcd_writer_pt writer);
-
-celix_status_t etcdWriter_addPublisherEndpoint(etcd_writer_pt writer, pubsub_endpoint_pt pubEP,bool storeEP);
-celix_status_t etcdWriter_deletePublisherEndpoint(etcd_writer_pt writer, pubsub_endpoint_pt pubEP);
-
-
-#endif /* ETCD_WRITER_H_ */
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/pubsub/pubsub_discovery/private/include/pubsub_discovery_impl.h
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_discovery/private/include/pubsub_discovery_impl.h b/pubsub/pubsub_discovery/private/include/pubsub_discovery_impl.h
deleted file mode 100644
index 676a6ab..0000000
--- a/pubsub/pubsub_discovery/private/include/pubsub_discovery_impl.h
+++ /dev/null
@@ -1,72 +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.
- */
-
-#ifndef PUBSUB_DISCOVERY_IMPL_H_
-#define PUBSUB_DISCOVERY_IMPL_H_
-
-#include "bundle_context.h"
-#include "service_reference.h"
-
-#include "etcd_watcher.h"
-#include "etcd_writer.h"
-#include "pubsub_endpoint.h"
-
-#define FREE_MEM(ptr) if(ptr) {free(ptr); ptr = NULL;}
-
-struct watcher_info {
- etcd_watcher_pt watcher;
- int nr_references;
-};
-
-struct pubsub_discovery {
- bundle_context_pt context;
-
- celix_thread_mutex_t discoveredPubsMutex;
- hash_map_pt discoveredPubs; //<topic,List<pubsub_endpoint_pt>>
-
- celix_thread_mutex_t listenerReferencesMutex;
- hash_map_pt listenerReferences; //key=serviceReference, value=nop
-
- celix_thread_mutex_t watchersMutex;
- hash_map_pt watchers; //key = topicname, value = struct watcher_info
-
- etcd_writer_pt writer;
-};
-
-
-celix_status_t pubsub_discovery_create(bundle_context_pt context, pubsub_discovery_pt* node_discovery);
-celix_status_t pubsub_discovery_destroy(pubsub_discovery_pt node_discovery);
-celix_status_t pubsub_discovery_start(pubsub_discovery_pt node_discovery);
-celix_status_t pubsub_discovery_stop(pubsub_discovery_pt node_discovery);
-
-celix_status_t pubsub_discovery_addNode(pubsub_discovery_pt node_discovery, pubsub_endpoint_pt pubEP);
-celix_status_t pubsub_discovery_removeNode(pubsub_discovery_pt node_discovery, pubsub_endpoint_pt pubEP);
-
-celix_status_t pubsub_discovery_tmPublisherAnnounceAdded(void * handle, service_reference_pt reference, void * service);
-celix_status_t pubsub_discovery_tmPublisherAnnounceModified(void * handle, service_reference_pt reference, void * service);
-celix_status_t pubsub_discovery_tmPublisherAnnounceRemoved(void * handle, service_reference_pt reference, void * service);
-
-celix_status_t pubsub_discovery_announcePublisher(void *handle, pubsub_endpoint_pt pubEP);
-celix_status_t pubsub_discovery_removePublisher(void *handle, pubsub_endpoint_pt pubEP);
-celix_status_t pubsub_discovery_interestedInTopic(void *handle, const char* scope, const char* topic);
-celix_status_t pubsub_discovery_uninterestedInTopic(void *handle, const char* scope, const char* topic);
-
-celix_status_t pubsub_discovery_informPublishersListeners(pubsub_discovery_pt discovery, pubsub_endpoint_pt endpoint, bool endpointAdded);
-
-#endif /* PUBSUB_DISCOVERY_IMPL_H_ */
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/pubsub/pubsub_discovery/private/src/etcd_common.c
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_discovery/private/src/etcd_common.c b/pubsub/pubsub_discovery/private/src/etcd_common.c
deleted file mode 100644
index c757801..0000000
--- a/pubsub/pubsub_discovery/private/src/etcd_common.c
+++ /dev/null
@@ -1,82 +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.
- */
-
-#include <stdbool.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-
-#include "celix_log.h"
-#include "constants.h"
-
-#include <curl/curl.h>
-#include "etcd.h"
-#include "etcd_watcher.h"
-
-#include "pubsub_discovery.h"
-#include "pubsub_discovery_impl.h"
-
-
-#define MAX_ROOTNODE_LENGTH 128
-#define MAX_LOCALNODE_LENGTH 4096
-#define MAX_FIELD_LENGTH 128
-
-#define CFG_ETCD_SERVER_IP "PUBSUB_DISCOVERY_ETCD_SERVER_IP"
-#define DEFAULT_ETCD_SERVER_IP "127.0.0.1"
-
-#define CFG_ETCD_SERVER_PORT "PUBSUB_DISCOVERY_ETCD_SERVER_PORT"
-#define DEFAULT_ETCD_SERVER_PORT 2379
-
-// be careful - this should be higher than the curl timeout
-#define CFG_ETCD_TTL "DISCOVERY_ETCD_TTL"
-#define DEFAULT_ETCD_TTL 30
-
-
-celix_status_t etcdCommon_init(bundle_context_pt context) {
- celix_status_t status = CELIX_SUCCESS;
- const char* etcd_server = NULL;
- const char* etcd_port_string = NULL;
- int etcd_port = 0;
-
- if ((bundleContext_getProperty(context, CFG_ETCD_SERVER_IP, &etcd_server) != CELIX_SUCCESS) || !etcd_server) {
- etcd_server = DEFAULT_ETCD_SERVER_IP;
- }
-
- if ((bundleContext_getProperty(context, CFG_ETCD_SERVER_PORT, &etcd_port_string) != CELIX_SUCCESS) || !etcd_port_string) {
- etcd_port = DEFAULT_ETCD_SERVER_PORT;
- } else {
- char* endptr = NULL;
- errno = 0;
- etcd_port = strtol(etcd_port_string, &endptr, 10);
- if (*endptr || errno != 0) {
- etcd_port = DEFAULT_ETCD_SERVER_PORT;
- }
- }
-
- printf("PSD: Using discovery HOST:PORT: %s:%i\n", etcd_server, etcd_port);
-
- if (etcd_init(etcd_server, etcd_port, CURL_GLOBAL_DEFAULT) != 0) {
- status = CELIX_BUNDLE_EXCEPTION;
- } else {
- status = CELIX_SUCCESS;
- }
-
- return status;
-}
-
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/pubsub/pubsub_discovery/private/src/etcd_watcher.c
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_discovery/private/src/etcd_watcher.c b/pubsub/pubsub_discovery/private/src/etcd_watcher.c
deleted file mode 100644
index 3c3a5a8..0000000
--- a/pubsub/pubsub_discovery/private/src/etcd_watcher.c
+++ /dev/null
@@ -1,290 +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.
- */
-
-#include <stdbool.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-
-#include "celix_log.h"
-#include "constants.h"
-
-#include "etcd.h"
-#include "etcd_watcher.h"
-
-#include "pubsub_discovery.h"
-#include "pubsub_discovery_impl.h"
-
-
-
-#define MAX_ROOTNODE_LENGTH 128
-#define MAX_LOCALNODE_LENGTH 4096
-#define MAX_FIELD_LENGTH 128
-
-#define CFG_ETCD_ROOT_PATH "PUBSUB_DISCOVERY_ETCD_ROOT_PATH"
-#define DEFAULT_ETCD_ROOTPATH "pubsub/discovery"
-
-#define CFG_ETCD_SERVER_IP "PUBSUB_DISCOVERY_ETCD_SERVER_IP"
-#define DEFAULT_ETCD_SERVER_IP "127.0.0.1"
-
-#define CFG_ETCD_SERVER_PORT "PUBSUB_DISCOVERY_ETCD_SERVER_PORT"
-#define DEFAULT_ETCD_SERVER_PORT 2379
-
-// be careful - this should be higher than the curl timeout
-#define CFG_ETCD_TTL "DISCOVERY_ETCD_TTL"
-#define DEFAULT_ETCD_TTL 30
-
-
-struct etcd_watcher {
- pubsub_discovery_pt pubsub_discovery;
-
- celix_thread_mutex_t watcherLock;
- celix_thread_t watcherThread;
-
- char *scope;
- char *topic;
- volatile bool running;
-};
-
-struct etcd_writer {
- pubsub_discovery_pt pubsub_discovery;
- celix_thread_mutex_t localPubsLock;
- array_list_pt localPubs;
- volatile bool running;
- celix_thread_t writerThread;
-};
-
-
-// note that the rootNode shouldn't have a leading slash
-static celix_status_t etcdWatcher_getTopicRootPath(bundle_context_pt context, const char *scope, const char *topic, char* rootNode, int rootNodeLen) {
- celix_status_t status = CELIX_SUCCESS;
- const char* rootPath = NULL;
-
- if (((bundleContext_getProperty(context, CFG_ETCD_ROOT_PATH, &rootPath)) != CELIX_SUCCESS) || (!rootPath)) {
- snprintf(rootNode, rootNodeLen, "%s/%s/%s", DEFAULT_ETCD_ROOTPATH, scope, topic);
- } else {
- snprintf(rootNode, rootNodeLen, "%s/%s/%s", rootPath, scope, topic);
- }
-
- return status;
-}
-
-static celix_status_t etcdWatcher_getRootPath(bundle_context_pt context, char* rootNode) {
- celix_status_t status = CELIX_SUCCESS;
- const char* rootPath = NULL;
-
- if (((bundleContext_getProperty(context, CFG_ETCD_ROOT_PATH, &rootPath)) != CELIX_SUCCESS) || (!rootPath)) {
- strncpy(rootNode, DEFAULT_ETCD_ROOTPATH, MAX_ROOTNODE_LENGTH);
- } else {
- strncpy(rootNode, rootPath, MAX_ROOTNODE_LENGTH);
- }
-
- return status;
-}
-
-
-static void add_node(const char *key, const char *value, void* arg) {
- pubsub_discovery_pt ps_discovery = (pubsub_discovery_pt) arg;
- pubsub_endpoint_pt pubEP = NULL;
- celix_status_t status = etcdWatcher_getPublisherEndpointFromKey(ps_discovery, key, value, &pubEP);
- if(!status && pubEP) {
- pubsub_discovery_addNode(ps_discovery, pubEP);
- }
-}
-
-static celix_status_t etcdWatcher_addAlreadyExistingPublishers(pubsub_discovery_pt ps_discovery, const char *rootPath, long long * highestModified) {
- celix_status_t status = CELIX_SUCCESS;
- if(etcd_get_directory(rootPath, add_node, ps_discovery, highestModified)) {
- status = CELIX_ILLEGAL_ARGUMENT;
- }
- return status;
-}
-
-// gets everything from provided key
-celix_status_t etcdWatcher_getPublisherEndpointFromKey(pubsub_discovery_pt pubsub_discovery, const char* etcdKey, const char* etcdValue, pubsub_endpoint_pt* pubEP) {
-
- celix_status_t status = CELIX_SUCCESS;
-
- char rootPath[MAX_ROOTNODE_LENGTH];
- char *expr = NULL;
- char scope[MAX_FIELD_LENGTH];
- char topic[MAX_FIELD_LENGTH];
- char fwUUID[MAX_FIELD_LENGTH];
- char serviceId[MAX_FIELD_LENGTH];
-
- memset(rootPath,0,MAX_ROOTNODE_LENGTH);
- memset(topic,0,MAX_FIELD_LENGTH);
- memset(fwUUID,0,MAX_FIELD_LENGTH);
- memset(serviceId,0,MAX_FIELD_LENGTH);
-
- etcdWatcher_getRootPath(pubsub_discovery->context, rootPath);
-
- asprintf(&expr, "/%s/%%[^/]/%%[^/]/%%[^/]/%%[^/].*", rootPath);
- if(expr) {
- int foundItems = sscanf(etcdKey, expr, scope, topic, fwUUID, serviceId);
- free(expr);
- if (foundItems != 4) { // Could happen when a directory is removed, just don't process this.
- status = CELIX_ILLEGAL_STATE;
- }
- else{
- status = pubsubEndpoint_create(fwUUID,scope,topic,strtol(serviceId,NULL,10),etcdValue,NULL,pubEP);
- }
- }
- return status;
-}
-
-/*
- * performs (blocking) etcd_watch calls to check for
- * changing discovery endpoint information within etcd.
- */
-static void* etcdWatcher_run(void* data) {
- etcd_watcher_pt watcher = (etcd_watcher_pt) data;
- time_t timeBeforeWatch = time(NULL);
- char rootPath[MAX_ROOTNODE_LENGTH];
- long long highestModified = 0;
-
- pubsub_discovery_pt ps_discovery = watcher->pubsub_discovery;
- bundle_context_pt context = ps_discovery->context;
-
- memset(rootPath, 0, MAX_ROOTNODE_LENGTH);
-
- //TODO: add topic to etcd key
- etcdWatcher_getTopicRootPath(context, watcher->scope, watcher->topic, rootPath, MAX_ROOTNODE_LENGTH);
- etcdWatcher_addAlreadyExistingPublishers(ps_discovery, rootPath, &highestModified);
-
- while ((celixThreadMutex_lock(&watcher->watcherLock) == CELIX_SUCCESS) && watcher->running) {
-
- char *rkey = NULL;
- char *value = NULL;
- char *preValue = NULL;
- char *action = NULL;
- long long modIndex;
-
- celixThreadMutex_unlock(&watcher->watcherLock);
-
- if (etcd_watch(rootPath, highestModified + 1, &action, &preValue, &value, &rkey, &modIndex) == 0 && action != NULL) {
- pubsub_endpoint_pt pubEP = NULL;
- if ((strcmp(action, "set") == 0) || (strcmp(action, "create") == 0)) {
- if (etcdWatcher_getPublisherEndpointFromKey(ps_discovery, rkey, value, &pubEP) == CELIX_SUCCESS) {
- pubsub_discovery_addNode(ps_discovery, pubEP);
- }
- } else if (strcmp(action, "delete") == 0) {
- if (etcdWatcher_getPublisherEndpointFromKey(ps_discovery, rkey, preValue, &pubEP) == CELIX_SUCCESS) {
- pubsub_discovery_removeNode(ps_discovery, pubEP);
- }
- } else if (strcmp(action, "expire") == 0) {
- if (etcdWatcher_getPublisherEndpointFromKey(ps_discovery, rkey, preValue, &pubEP) == CELIX_SUCCESS) {
- pubsub_discovery_removeNode(ps_discovery, pubEP);
- }
- } else if (strcmp(action, "update") == 0) {
- if (etcdWatcher_getPublisherEndpointFromKey(ps_discovery, rkey, value, &pubEP) == CELIX_SUCCESS) {
- pubsub_discovery_addNode(ps_discovery, pubEP);
- }
- } else {
- fw_log(logger, OSGI_FRAMEWORK_LOG_INFO, "Unexpected action: %s", action);
- }
- highestModified = modIndex;
- } else if (time(NULL) - timeBeforeWatch <= (DEFAULT_ETCD_TTL / 4)) {
- sleep(DEFAULT_ETCD_TTL / 4);
- }
-
- FREE_MEM(action);
- FREE_MEM(value);
- FREE_MEM(preValue);
- FREE_MEM(rkey);
-
- /* prevent busy waiting, in case etcd_watch returns false */
-
-
- if (time(NULL) - timeBeforeWatch > (DEFAULT_ETCD_TTL / 4)) {
- timeBeforeWatch = time(NULL);
- }
-
- }
-
- if (watcher->running == false) {
- celixThreadMutex_unlock(&watcher->watcherLock);
- }
-
- return NULL;
-}
-
-celix_status_t etcdWatcher_create(pubsub_discovery_pt pubsub_discovery, bundle_context_pt context, const char *scope, const char *topic, etcd_watcher_pt *watcher) {
- celix_status_t status = CELIX_SUCCESS;
-
-
- if (pubsub_discovery == NULL) {
- return CELIX_BUNDLE_EXCEPTION;
- }
-
- (*watcher) = calloc(1, sizeof(struct etcd_watcher));
-
- if(*watcher == NULL){
- return CELIX_ENOMEM;
- }
-
- (*watcher)->pubsub_discovery = pubsub_discovery;
- (*watcher)->scope = strdup(scope);
- (*watcher)->topic = strdup(topic);
-
-
- celixThreadMutex_create(&(*watcher)->watcherLock, NULL);
-
- celixThreadMutex_lock(&(*watcher)->watcherLock);
-
- status = celixThread_create(&(*watcher)->watcherThread, NULL, etcdWatcher_run, *watcher);
- if (status == CELIX_SUCCESS) {
- (*watcher)->running = true;
- }
-
- celixThreadMutex_unlock(&(*watcher)->watcherLock);
-
-
- return status;
-}
-
-celix_status_t etcdWatcher_destroy(etcd_watcher_pt watcher) {
-
- celix_status_t status = CELIX_SUCCESS;
-
- char rootPath[MAX_ROOTNODE_LENGTH];
- etcdWatcher_getTopicRootPath(watcher->pubsub_discovery->context, watcher->scope, watcher->topic, rootPath, MAX_ROOTNODE_LENGTH);
- celixThreadMutex_destroy(&(watcher->watcherLock));
-
- free(watcher->scope);
- free(watcher->topic);
- free(watcher);
-
- return status;
-}
-
-celix_status_t etcdWatcher_stop(etcd_watcher_pt watcher){
- celix_status_t status = CELIX_SUCCESS;
-
- celixThreadMutex_lock(&(watcher->watcherLock));
- watcher->running = false;
- celixThreadMutex_unlock(&(watcher->watcherLock));
-
- celixThread_join(watcher->watcherThread, NULL);
-
- return status;
-
-}
-
-
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/pubsub/pubsub_discovery/private/src/etcd_writer.c
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_discovery/private/src/etcd_writer.c b/pubsub/pubsub_discovery/private/src/etcd_writer.c
deleted file mode 100644
index 1c423f3..0000000
--- a/pubsub/pubsub_discovery/private/src/etcd_writer.c
+++ /dev/null
@@ -1,189 +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.
- */
-
-#include <stdbool.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-
-#include "celix_log.h"
-#include "constants.h"
-
-#include "etcd.h"
-#include "etcd_writer.h"
-
-#include "pubsub_discovery.h"
-#include "pubsub_discovery_impl.h"
-
-#define MAX_ROOTNODE_LENGTH 128
-
-#define CFG_ETCD_ROOT_PATH "PUBSUB_DISCOVERY_ETCD_ROOT_PATH"
-#define DEFAULT_ETCD_ROOTPATH "pubsub/discovery"
-
-#define CFG_ETCD_SERVER_IP "PUBSUB_DISCOVERY_ETCD_SERVER_IP"
-#define DEFAULT_ETCD_SERVER_IP "127.0.0.1"
-
-#define CFG_ETCD_SERVER_PORT "PUBSUB_DISCOVERY_ETCD_SERVER_PORT"
-#define DEFAULT_ETCD_SERVER_PORT 2379
-
-// be careful - this should be higher than the curl timeout
-#define CFG_ETCD_TTL "DISCOVERY_ETCD_TTL"
-#define DEFAULT_ETCD_TTL 30
-
-struct etcd_writer {
- pubsub_discovery_pt pubsub_discovery;
- celix_thread_mutex_t localPubsLock;
- array_list_pt localPubs;
- volatile bool running;
- celix_thread_t writerThread;
-};
-
-
-static const char* etcdWriter_getRootPath(bundle_context_pt context);
-static void* etcdWriter_run(void* data);
-
-
-etcd_writer_pt etcdWriter_create(pubsub_discovery_pt disc) {
- etcd_writer_pt writer = calloc(1, sizeof(*writer));
- if(writer) {
- celixThreadMutex_create(&writer->localPubsLock, NULL);
- arrayList_create(&writer->localPubs);
- writer->pubsub_discovery = disc;
- writer->running = true;
- celixThread_create(&writer->writerThread, NULL, etcdWriter_run, writer);
- }
- return writer;
-}
-
-void etcdWriter_destroy(etcd_writer_pt writer) {
- char dir[MAX_ROOTNODE_LENGTH];
- const char *rootPath = etcdWriter_getRootPath(writer->pubsub_discovery->context);
-
- writer->running = false;
- celixThread_join(writer->writerThread, NULL);
-
- celixThreadMutex_lock(&writer->localPubsLock);
- for(int i = 0; i < arrayList_size(writer->localPubs); i++) {
- pubsub_endpoint_pt pubEP = (pubsub_endpoint_pt)arrayList_get(writer->localPubs,i);
- memset(dir,0,MAX_ROOTNODE_LENGTH);
- snprintf(dir,MAX_ROOTNODE_LENGTH,"%s/%s/%s/%s",rootPath,pubEP->scope,pubEP->topic,pubEP->frameworkUUID);
- etcd_del(dir);
- pubsubEndpoint_destroy(pubEP);
- }
- arrayList_destroy(writer->localPubs);
-
- celixThreadMutex_unlock(&writer->localPubsLock);
- celixThreadMutex_destroy(&(writer->localPubsLock));
-
- free(writer);
-}
-
-celix_status_t etcdWriter_addPublisherEndpoint(etcd_writer_pt writer, pubsub_endpoint_pt pubEP, bool storeEP){
- celix_status_t status = CELIX_BUNDLE_EXCEPTION;
-
- if(storeEP){
- const char *fwUUID = NULL;
- bundleContext_getProperty(writer->pubsub_discovery->context, OSGI_FRAMEWORK_FRAMEWORK_UUID, &fwUUID);
- if(fwUUID && strcmp(pubEP->frameworkUUID, fwUUID) == 0) {
- celixThreadMutex_lock(&writer->localPubsLock);
- pubsub_endpoint_pt p = NULL;
- pubsubEndpoint_clone(pubEP, &p);
- arrayList_add(writer->localPubs,p);
- celixThreadMutex_unlock(&writer->localPubsLock);
- }
- }
-
- char *key;
-
- const char* ttlStr = NULL;
- int ttl = 0;
-
- // determine ttl
- if ((bundleContext_getProperty(writer->pubsub_discovery->context, CFG_ETCD_TTL, &ttlStr) != CELIX_SUCCESS) || !ttlStr) {
- ttl = DEFAULT_ETCD_TTL;
- } else {
- char* endptr = NULL;
- errno = 0;
- ttl = strtol(ttlStr, &endptr, 10);
- if (*endptr || errno != 0) {
- ttl = DEFAULT_ETCD_TTL;
- }
- }
-
- const char *rootPath = etcdWriter_getRootPath(writer->pubsub_discovery->context);
-
- asprintf(&key,"%s/%s/%s/%s/%ld",rootPath,pubEP->scope,pubEP->topic,pubEP->frameworkUUID,pubEP->serviceID);
-
- if(!etcd_set(key,pubEP->endpoint,ttl,false)){
- status = CELIX_ILLEGAL_ARGUMENT;
- }
- FREE_MEM(key);
- return status;
-}
-
-celix_status_t etcdWriter_deletePublisherEndpoint(etcd_writer_pt writer, pubsub_endpoint_pt pubEP) {
- celix_status_t status = CELIX_SUCCESS;
- char *key = NULL;
-
- const char *rootPath = etcdWriter_getRootPath(writer->pubsub_discovery->context);
-
- asprintf(&key, "%s/%s/%s/%s/%ld", rootPath, pubEP->scope, pubEP->topic, pubEP->frameworkUUID, pubEP->serviceID);
-
- celixThreadMutex_lock(&writer->localPubsLock);
- for (unsigned int i = 0; i < arrayList_size(writer->localPubs); i++) {
- pubsub_endpoint_pt ep = arrayList_get(writer->localPubs, i);
- if (pubsubEndpoint_equals(ep, pubEP)) {
- arrayList_remove(writer->localPubs, i);
- pubsubEndpoint_destroy(ep);
- break;
- }
- }
- celixThreadMutex_unlock(&writer->localPubsLock);
-
- if (etcd_del(key)) {
- printf("Failed to remove key %s from ETCD\n",key);
- status = CELIX_ILLEGAL_ARGUMENT;
- }
- FREE_MEM(key);
- return status;
-}
-
-static void* etcdWriter_run(void* data) {
- etcd_writer_pt writer = (etcd_writer_pt)data;
- while(writer->running) {
- celixThreadMutex_lock(&writer->localPubsLock);
- for(int i=0; i < arrayList_size(writer->localPubs); i++) {
- etcdWriter_addPublisherEndpoint(writer,(pubsub_endpoint_pt)arrayList_get(writer->localPubs,i),false);
- }
- celixThreadMutex_unlock(&writer->localPubsLock);
- sleep(DEFAULT_ETCD_TTL / 2);
- }
-
- return NULL;
-}
-
-static const char* etcdWriter_getRootPath(bundle_context_pt context) {
- const char* rootPath = NULL;
- bundleContext_getProperty(context, CFG_ETCD_ROOT_PATH, &rootPath);
- if(rootPath == NULL) {
- rootPath = DEFAULT_ETCD_ROOTPATH;
- }
- return rootPath;
-}
-
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/pubsub/pubsub_discovery/private/src/psd_activator.c
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_discovery/private/src/psd_activator.c b/pubsub/pubsub_discovery/private/src/psd_activator.c
deleted file mode 100644
index 89a517d..0000000
--- a/pubsub/pubsub_discovery/private/src/psd_activator.c
+++ /dev/null
@@ -1,171 +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.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "bundle_activator.h"
-#include "service_tracker.h"
-#include "service_registration.h"
-#include "constants.h"
-#include "celix_log.h"
-
-#include "pubsub_common.h"
-#include "publisher_endpoint_announce.h"
-#include "pubsub_discovery.h"
-#include "pubsub_discovery_impl.h"
-
-struct activator {
- bundle_context_pt context;
- pubsub_discovery_pt pubsub_discovery;
-
- service_tracker_pt pstmPublishersTracker;
-
- publisher_endpoint_announce_pt publisherEPAnnounce;
- service_registration_pt publisherEPAnnounceService;
-};
-
-static celix_status_t createTMPublisherAnnounceTracker(struct activator *activator, service_tracker_pt *tracker) {
- celix_status_t status = CELIX_SUCCESS;
-
- service_tracker_customizer_pt customizer = NULL;
-
- status = serviceTrackerCustomizer_create(activator->pubsub_discovery,
- NULL,
- pubsub_discovery_tmPublisherAnnounceAdded,
- pubsub_discovery_tmPublisherAnnounceModified,
- pubsub_discovery_tmPublisherAnnounceRemoved,
- &customizer);
-
- if (status == CELIX_SUCCESS) {
- status = serviceTracker_create(activator->context, (char *) PUBSUB_TM_ANNOUNCE_PUBLISHER_SERVICE, customizer, tracker);
- }
-
- return status;
-}
-
-celix_status_t bundleActivator_create(bundle_context_pt context, void **userData) {
- celix_status_t status = CELIX_SUCCESS;
-
- struct activator* activator = calloc(1, sizeof(*activator));
-
- if (activator) {
- activator->context = context;
- activator->pstmPublishersTracker = NULL;
- activator->publisherEPAnnounce = NULL;
- activator->publisherEPAnnounceService = NULL;
-
- status = pubsub_discovery_create(context, &activator->pubsub_discovery);
-
- if (status == CELIX_SUCCESS) {
- status = createTMPublisherAnnounceTracker(activator, &(activator->pstmPublishersTracker));
- }
-
- if (status == CELIX_SUCCESS) {
- *userData = activator;
- } else {
- free(activator);
- }
- } else {
- status = CELIX_ENOMEM;
- }
-
- return status;
-
-}
-
-celix_status_t bundleActivator_start(void * userData, bundle_context_pt context) {
- celix_status_t status = CELIX_SUCCESS;
-
- struct activator *activator = userData;
-
- publisher_endpoint_announce_pt pubEPAnnouncer = calloc(1, sizeof(*pubEPAnnouncer));
-
- if (pubEPAnnouncer) {
-
- pubEPAnnouncer->handle = activator->pubsub_discovery;
- pubEPAnnouncer->announcePublisher = pubsub_discovery_announcePublisher;
- pubEPAnnouncer->removePublisher = pubsub_discovery_removePublisher;
- pubEPAnnouncer->interestedInTopic = pubsub_discovery_interestedInTopic;
- pubEPAnnouncer->uninterestedInTopic = pubsub_discovery_uninterestedInTopic;
- activator->publisherEPAnnounce = pubEPAnnouncer;
-
- properties_pt props = properties_create();
- properties_set(props, "PUBSUB_DISCOVERY", "true");
-
- // pubsub_discovery_start needs to be first to initalize the propert etcd_watcher values
- status = pubsub_discovery_start(activator->pubsub_discovery);
-
- if (status == CELIX_SUCCESS) {
- status = serviceTracker_open(activator->pstmPublishersTracker);
- }
-
- if (status == CELIX_SUCCESS) {
- status = bundleContext_registerService(context, (char *) PUBSUB_DISCOVERY_SERVICE, pubEPAnnouncer, props, &activator->publisherEPAnnounceService);
- }
-
-
- }
- else{
- status = CELIX_ENOMEM;
- }
-
- if(status!=CELIX_SUCCESS && pubEPAnnouncer!=NULL){
- free(pubEPAnnouncer);
- }
-
-
- return status;
-}
-
-celix_status_t bundleActivator_stop(void * userData, bundle_context_pt context) {
- celix_status_t status = CELIX_SUCCESS;
- struct activator *activator = userData;
-
- status += pubsub_discovery_stop(activator->pubsub_discovery);
-
- status += serviceTracker_close(activator->pstmPublishersTracker);
-
- status += serviceRegistration_unregister(activator->publisherEPAnnounceService);
-
- if (status == CELIX_SUCCESS) {
- free(activator->publisherEPAnnounce);
- }
-
- return status;
-}
-
-celix_status_t bundleActivator_destroy(void * userData, bundle_context_pt context) {
- celix_status_t status = CELIX_SUCCESS;
- struct activator *activator = userData;
-
- status += serviceTracker_destroy(activator->pstmPublishersTracker);
- status += pubsub_discovery_destroy(activator->pubsub_discovery);
-
- activator->publisherEPAnnounce = NULL;
- activator->publisherEPAnnounceService = NULL;
- activator->pstmPublishersTracker = NULL;
- activator->pubsub_discovery = NULL;
- activator->context = NULL;
-
- free(activator);
-
- return status;
-}
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/pubsub/pubsub_discovery/private/src/pubsub_discovery_impl.c
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_discovery/private/src/pubsub_discovery_impl.c b/pubsub/pubsub_discovery/private/src/pubsub_discovery_impl.c
deleted file mode 100644
index 94a8e11..0000000
--- a/pubsub/pubsub_discovery/private/src/pubsub_discovery_impl.c
+++ /dev/null
@@ -1,457 +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.
- */
-
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <stdbool.h>
-#include <netdb.h>
-#include <netinet/in.h>
-
-#include "constants.h"
-#include "celix_threads.h"
-#include "bundle_context.h"
-#include "array_list.h"
-#include "utils.h"
-#include "celix_errno.h"
-#include "filter.h"
-#include "service_reference.h"
-#include "service_registration.h"
-
-#include "publisher_endpoint_announce.h"
-#include "etcd_common.h"
-#include "etcd_watcher.h"
-#include "etcd_writer.h"
-#include "pubsub_endpoint.h"
-#include "pubsub_discovery_impl.h"
-
-/* Discovery activator functions */
-celix_status_t pubsub_discovery_create(bundle_context_pt context, pubsub_discovery_pt *ps_discovery) {
- celix_status_t status = CELIX_SUCCESS;
-
- *ps_discovery = calloc(1, sizeof(**ps_discovery));
-
- if (*ps_discovery == NULL) {
- status = CELIX_ENOMEM;
- }
- else{
- (*ps_discovery)->context = context;
- (*ps_discovery)->discoveredPubs = hashMap_create(utils_stringHash, NULL, utils_stringEquals, NULL);
- (*ps_discovery)->listenerReferences = hashMap_create(serviceReference_hashCode, NULL, serviceReference_equals2, NULL);
- (*ps_discovery)->watchers = hashMap_create(utils_stringHash,NULL,utils_stringEquals, NULL);
- celixThreadMutex_create(&(*ps_discovery)->listenerReferencesMutex, NULL);
- celixThreadMutex_create(&(*ps_discovery)->discoveredPubsMutex, NULL);
- celixThreadMutex_create(&(*ps_discovery)->watchersMutex, NULL);
- }
-
- return status;
-}
-
-celix_status_t pubsub_discovery_destroy(pubsub_discovery_pt ps_discovery) {
- celix_status_t status = CELIX_SUCCESS;
-
- celixThreadMutex_lock(&ps_discovery->discoveredPubsMutex);
-
- hash_map_iterator_pt iter = hashMapIterator_create(ps_discovery->discoveredPubs);
-
- while (hashMapIterator_hasNext(iter)) {
- array_list_pt pubEP_list = (array_list_pt) hashMapIterator_nextValue(iter);
-
- for(int i=0; i < arrayList_size(pubEP_list); i++) {
- pubsubEndpoint_destroy(((pubsub_endpoint_pt)arrayList_get(pubEP_list,i)));
- }
- arrayList_destroy(pubEP_list);
- }
-
- hashMapIterator_destroy(iter);
-
- hashMap_destroy(ps_discovery->discoveredPubs, true, false);
- ps_discovery->discoveredPubs = NULL;
-
- celixThreadMutex_unlock(&ps_discovery->discoveredPubsMutex);
-
- celixThreadMutex_destroy(&ps_discovery->discoveredPubsMutex);
-
-
- celixThreadMutex_lock(&ps_discovery->listenerReferencesMutex);
-
- hashMap_destroy(ps_discovery->listenerReferences, false, false);
- ps_discovery->listenerReferences = NULL;
-
- celixThreadMutex_unlock(&ps_discovery->listenerReferencesMutex);
-
- celixThreadMutex_destroy(&ps_discovery->listenerReferencesMutex);
-
- free(ps_discovery);
-
- return status;
-}
-
-celix_status_t pubsub_discovery_start(pubsub_discovery_pt ps_discovery) {
- celix_status_t status = CELIX_SUCCESS;
- status = etcdCommon_init(ps_discovery->context);
- ps_discovery->writer = etcdWriter_create(ps_discovery);
-
- return status;
-}
-
-celix_status_t pubsub_discovery_stop(pubsub_discovery_pt ps_discovery) {
- celix_status_t status = CELIX_SUCCESS;
-
- const char* fwUUID = NULL;
-
- bundleContext_getProperty(ps_discovery->context, OSGI_FRAMEWORK_FRAMEWORK_UUID, &fwUUID);
- if (fwUUID == NULL) {
- printf("PSD: Cannot retrieve fwUUID.\n");
- return CELIX_INVALID_BUNDLE_CONTEXT;
- }
-
- celixThreadMutex_lock(&ps_discovery->watchersMutex);
-
- hash_map_iterator_pt iter = hashMapIterator_create(ps_discovery->watchers);
- while (hashMapIterator_hasNext(iter)) {
- struct watcher_info * wi = hashMapIterator_nextValue(iter);
- etcdWatcher_stop(wi->watcher);
- }
- hashMapIterator_destroy(iter);
-
- celixThreadMutex_lock(&ps_discovery->discoveredPubsMutex);
-
- /* Unexport all publishers for the local framework, and also delete from ETCD publisher belonging to the local framework */
-
- iter = hashMapIterator_create(ps_discovery->discoveredPubs);
- while (hashMapIterator_hasNext(iter)) {
- array_list_pt pubEP_list = (array_list_pt) hashMapIterator_nextValue(iter);
-
- int i;
- for (i = 0; i < arrayList_size(pubEP_list); i++) {
- pubsub_endpoint_pt pubEP = (pubsub_endpoint_pt) arrayList_get(pubEP_list, i);
- if (strcmp(pubEP->frameworkUUID, fwUUID) == 0) {
- etcdWriter_deletePublisherEndpoint(ps_discovery->writer, pubEP);
- } else {
- pubsub_discovery_informPublishersListeners(ps_discovery, pubEP, false);
- arrayList_remove(pubEP_list, i);
- pubsubEndpoint_destroy(pubEP);
- i--;
- }
- }
- }
-
- hashMapIterator_destroy(iter);
-
- celixThreadMutex_unlock(&ps_discovery->discoveredPubsMutex);
- etcdWriter_destroy(ps_discovery->writer);
-
- iter = hashMapIterator_create(ps_discovery->watchers);
- while (hashMapIterator_hasNext(iter)) {
- struct watcher_info * wi = hashMapIterator_nextValue(iter);
- etcdWatcher_destroy(wi->watcher);
- }
- hashMapIterator_destroy(iter);
- hashMap_destroy(ps_discovery->watchers, true, true);
- celixThreadMutex_unlock(&ps_discovery->watchersMutex);
- return status;
-}
-
-/* Functions called by the etcd_watcher */
-
-celix_status_t pubsub_discovery_addNode(pubsub_discovery_pt pubsub_discovery, pubsub_endpoint_pt pubEP) {
- celix_status_t status = CELIX_SUCCESS;
- bool inform=false;
- celixThreadMutex_lock(&pubsub_discovery->discoveredPubsMutex);
-
- char *pubs_key = createScopeTopicKey(pubEP->scope, pubEP->topic);
- array_list_pt pubEP_list = (array_list_pt)hashMap_get(pubsub_discovery->discoveredPubs,pubs_key);
- if(pubEP_list==NULL){
- arrayList_create(&pubEP_list);
- arrayList_add(pubEP_list,pubEP);
- hashMap_put(pubsub_discovery->discoveredPubs,strdup(pubs_key),pubEP_list);
- inform=true;
- }
- else{
- int i;
- bool found = false;
- for(i=0;i<arrayList_size(pubEP_list) && !found;i++){
- found = pubsubEndpoint_equals(pubEP,(pubsub_endpoint_pt)arrayList_get(pubEP_list,i));
- }
- if(found){
- pubsubEndpoint_destroy(pubEP);
- }
- else{
- arrayList_add(pubEP_list,pubEP);
- inform=true;
- }
- }
- free(pubs_key);
-
- celixThreadMutex_unlock(&pubsub_discovery->discoveredPubsMutex);
-
- if(inform){
- status = pubsub_discovery_informPublishersListeners(pubsub_discovery,pubEP,true);
- }
-
- return status;
-}
-
-celix_status_t pubsub_discovery_removeNode(pubsub_discovery_pt pubsub_discovery, pubsub_endpoint_pt pubEP) {
- celix_status_t status = CELIX_SUCCESS;
- pubsub_endpoint_pt p = NULL;
- bool found = false;
-
- celixThreadMutex_lock(&pubsub_discovery->discoveredPubsMutex);
- char *pubs_key = createScopeTopicKey(pubEP->scope, pubEP->topic);
- array_list_pt pubEP_list = (array_list_pt) hashMap_get(pubsub_discovery->discoveredPubs, pubs_key);
- free(pubs_key);
- if (pubEP_list == NULL) {
- printf("PSD: Cannot find any registered publisher for topic %s. Something is not consistent.\n", pubEP->topic);
- status = CELIX_ILLEGAL_STATE;
- } else {
- int i;
-
- for (i = 0; !found && i < arrayList_size(pubEP_list); i++) {
- p = arrayList_get(pubEP_list, i);
- found = pubsubEndpoint_equals(pubEP, p);
- if (found) {
- arrayList_remove(pubEP_list, i);
- pubsubEndpoint_destroy(p);
- }
- }
- }
-
- celixThreadMutex_unlock(&pubsub_discovery->discoveredPubsMutex);
- if (found) {
- status = pubsub_discovery_informPublishersListeners(pubsub_discovery, pubEP, false);
- }
- pubsubEndpoint_destroy(pubEP);
-
- return status;
-}
-
-/* Callback to the pubsub_topology_manager */
-celix_status_t pubsub_discovery_informPublishersListeners(pubsub_discovery_pt pubsub_discovery, pubsub_endpoint_pt pubEP, bool epAdded) {
- celix_status_t status = CELIX_SUCCESS;
-
- // Inform listeners of new publisher endpoint
- celixThreadMutex_lock(&pubsub_discovery->listenerReferencesMutex);
-
- if (pubsub_discovery->listenerReferences != NULL) {
- hash_map_iterator_pt iter = hashMapIterator_create(pubsub_discovery->listenerReferences);
- while (hashMapIterator_hasNext(iter)) {
- service_reference_pt reference = hashMapIterator_nextKey(iter);
-
- publisher_endpoint_announce_pt listener = NULL;
-
- bundleContext_getService(pubsub_discovery->context, reference, (void**) &listener);
- if (epAdded) {
- listener->announcePublisher(listener->handle, pubEP);
- } else {
- listener->removePublisher(listener->handle, pubEP);
- }
- bundleContext_ungetService(pubsub_discovery->context, reference, NULL);
- }
- hashMapIterator_destroy(iter);
- }
-
- celixThreadMutex_unlock(&pubsub_discovery->listenerReferencesMutex);
-
- return status;
-}
-
-
-/* Service's functions implementation */
-celix_status_t pubsub_discovery_announcePublisher(void *handle, pubsub_endpoint_pt pubEP) {
- celix_status_t status = CELIX_SUCCESS;
- printf("pubsub_discovery_announcePublisher : %s / %s\n", pubEP->topic, pubEP->endpoint);
- pubsub_discovery_pt pubsub_discovery = (pubsub_discovery_pt) handle;
-
- celixThreadMutex_lock(&pubsub_discovery->discoveredPubsMutex);
-
- char *pub_key = createScopeTopicKey(pubEP->scope,pubEP->topic);
- array_list_pt pubEP_list = (array_list_pt)hashMap_get(pubsub_discovery->discoveredPubs,pub_key);
-
- if(pubEP_list==NULL){
- arrayList_create(&pubEP_list);
- hashMap_put(pubsub_discovery->discoveredPubs,strdup(pub_key),pubEP_list);
- }
- free(pub_key);
- pubsub_endpoint_pt p = NULL;
- pubsubEndpoint_clone(pubEP, &p);
-
- arrayList_add(pubEP_list,p);
-
- status = etcdWriter_addPublisherEndpoint(pubsub_discovery->writer,p,true);
-
- celixThreadMutex_unlock(&pubsub_discovery->discoveredPubsMutex);
-
- return status;
-}
-
-celix_status_t pubsub_discovery_removePublisher(void *handle, pubsub_endpoint_pt pubEP) {
- celix_status_t status = CELIX_SUCCESS;
-
- pubsub_discovery_pt pubsub_discovery = (pubsub_discovery_pt) handle;
-
- celixThreadMutex_lock(&pubsub_discovery->discoveredPubsMutex);
-
- char *pub_key = createScopeTopicKey(pubEP->scope,pubEP->topic);
- array_list_pt pubEP_list = (array_list_pt)hashMap_get(pubsub_discovery->discoveredPubs,pub_key);
- free(pub_key);
- if(pubEP_list==NULL){
- printf("PSD: Cannot find any registered publisher for topic %s. Something is not consistent.\n",pubEP->topic);
- status = CELIX_ILLEGAL_STATE;
- }
- else{
-
- int i;
- bool found = false;
- pubsub_endpoint_pt p = NULL;
-
- for(i=0;!found && i<arrayList_size(pubEP_list);i++){
- p = (pubsub_endpoint_pt)arrayList_get(pubEP_list,i);
- found = pubsubEndpoint_equals(pubEP,p);
- }
-
- if(!found){
- printf("PSD: Trying to remove a not existing endpoint. Something is not consistent.\n");
- status = CELIX_ILLEGAL_STATE;
- }
- else{
-
- arrayList_removeElement(pubEP_list,p);
-
- status = etcdWriter_deletePublisherEndpoint(pubsub_discovery->writer,p);
-
- pubsubEndpoint_destroy(p);
- }
- }
-
- celixThreadMutex_unlock(&pubsub_discovery->discoveredPubsMutex);
-
- return status;
-}
-
-celix_status_t pubsub_discovery_interestedInTopic(void *handle, const char* scope, const char* topic) {
- pubsub_discovery_pt pubsub_discovery = (pubsub_discovery_pt) handle;
-
- char *scope_topic_key = createScopeTopicKey(scope, topic);
- celixThreadMutex_lock(&pubsub_discovery->watchersMutex);
- struct watcher_info * wi = hashMap_get(pubsub_discovery->watchers, scope_topic_key);
- if(wi) {
- wi->nr_references++;
- free(scope_topic_key);
- } else {
- wi = calloc(1, sizeof(*wi));
- etcdWatcher_create(pubsub_discovery, pubsub_discovery->context, scope, topic, &wi->watcher);
- wi->nr_references = 1;
- hashMap_put(pubsub_discovery->watchers, scope_topic_key, wi);
- }
-
- celixThreadMutex_unlock(&pubsub_discovery->watchersMutex);
-
- return CELIX_SUCCESS;
-}
-
-celix_status_t pubsub_discovery_uninterestedInTopic(void *handle, const char* scope, const char* topic) {
- pubsub_discovery_pt pubsub_discovery = (pubsub_discovery_pt) handle;
-
- char *scope_topic_key = createScopeTopicKey(scope, topic);
- celixThreadMutex_lock(&pubsub_discovery->watchersMutex);
-
- hash_map_entry_pt entry = hashMap_getEntry(pubsub_discovery->watchers, scope_topic_key);
- if(entry) {
- struct watcher_info * wi = hashMapEntry_getValue(entry);
- wi->nr_references--;
- if(wi->nr_references == 0) {
- char *key = hashMapEntry_getKey(entry);
- hashMap_remove(pubsub_discovery->watchers, scope_topic_key);
- free(key);
- free(scope_topic_key);
- etcdWatcher_stop(wi->watcher);
- etcdWatcher_destroy(wi->watcher);
- free(wi);
- }
- } else {
- fprintf(stderr, "[DISC] Inconsistency error: Removing unknown topic %s\n", topic);
- }
- celixThreadMutex_unlock(&pubsub_discovery->watchersMutex);
- return CELIX_SUCCESS;
-}
-
-/* pubsub_topology_manager tracker callbacks */
-
-celix_status_t pubsub_discovery_tmPublisherAnnounceAdded(void * handle, service_reference_pt reference, void * service) {
- celix_status_t status = CELIX_SUCCESS;
-
- pubsub_discovery_pt pubsub_discovery = (pubsub_discovery_pt)handle;
- publisher_endpoint_announce_pt listener = (publisher_endpoint_announce_pt)service;
-
- celixThreadMutex_lock(&pubsub_discovery->discoveredPubsMutex);
- celixThreadMutex_lock(&pubsub_discovery->listenerReferencesMutex);
-
- /* Notify the PSTM about discovered publisher endpoints */
- hash_map_iterator_pt iter = hashMapIterator_create(pubsub_discovery->discoveredPubs);
- while(hashMapIterator_hasNext(iter)){
- array_list_pt pubEP_list = (array_list_pt)hashMapIterator_nextValue(iter);
- int i;
- for(i=0;i<arrayList_size(pubEP_list);i++){
- pubsub_endpoint_pt pubEP = (pubsub_endpoint_pt)arrayList_get(pubEP_list,i);
- status += listener->announcePublisher(listener->handle, pubEP);
- }
- }
-
- hashMapIterator_destroy(iter);
-
- hashMap_put(pubsub_discovery->listenerReferences, reference, NULL);
-
- celixThreadMutex_unlock(&pubsub_discovery->listenerReferencesMutex);
- celixThreadMutex_unlock(&pubsub_discovery->discoveredPubsMutex);
-
- printf("PSD: pubsub_tm_announce_publisher added.\n");
-
- return status;
-}
-
-celix_status_t pubsub_discovery_tmPublisherAnnounceModified(void * handle, service_reference_pt reference, void * service) {
- celix_status_t status = CELIX_SUCCESS;
-
- status = pubsub_discovery_tmPublisherAnnounceRemoved(handle, reference, service);
- if (status == CELIX_SUCCESS) {
- status = pubsub_discovery_tmPublisherAnnounceAdded(handle, reference, service);
- }
-
- return status;
-}
-
-celix_status_t pubsub_discovery_tmPublisherAnnounceRemoved(void * handle, service_reference_pt reference, void * service) {
- celix_status_t status = CELIX_SUCCESS;
- pubsub_discovery_pt pubsub_discovery = handle;
-
- celixThreadMutex_lock(&pubsub_discovery->listenerReferencesMutex);
-
- if (pubsub_discovery->listenerReferences != NULL) {
- if (hashMap_remove(pubsub_discovery->listenerReferences, reference)) {
- printf("PSD: pubsub_tm_announce_publisher removed.\n");
- }
- }
- celixThreadMutex_unlock(&pubsub_discovery->listenerReferencesMutex);
-
- return status;
-}
-
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/pubsub/pubsub_discovery/public/include/pubsub_discovery.h
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_discovery/public/include/pubsub_discovery.h b/pubsub/pubsub_discovery/public/include/pubsub_discovery.h
deleted file mode 100644
index f77905a..0000000
--- a/pubsub/pubsub_discovery/public/include/pubsub_discovery.h
+++ /dev/null
@@ -1,26 +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.
- */
-
-#ifndef PUBSUB_DISCOVERY_H_
-#define PUBSUB_DISCOVERY_H_
-
-typedef struct pubsub_discovery *pubsub_discovery_pt;
-
-
-#endif /* PUBSUB_DISCOVERY_H_ */
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/pubsub/pubsub_discovery/src/etcd_common.c
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_discovery/src/etcd_common.c b/pubsub/pubsub_discovery/src/etcd_common.c
new file mode 100644
index 0000000..c757801
--- /dev/null
+++ b/pubsub/pubsub_discovery/src/etcd_common.c
@@ -0,0 +1,82 @@
+/**
+ *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.
+ */
+
+#include <stdbool.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+
+#include "celix_log.h"
+#include "constants.h"
+
+#include <curl/curl.h>
+#include "etcd.h"
+#include "etcd_watcher.h"
+
+#include "pubsub_discovery.h"
+#include "pubsub_discovery_impl.h"
+
+
+#define MAX_ROOTNODE_LENGTH 128
+#define MAX_LOCALNODE_LENGTH 4096
+#define MAX_FIELD_LENGTH 128
+
+#define CFG_ETCD_SERVER_IP "PUBSUB_DISCOVERY_ETCD_SERVER_IP"
+#define DEFAULT_ETCD_SERVER_IP "127.0.0.1"
+
+#define CFG_ETCD_SERVER_PORT "PUBSUB_DISCOVERY_ETCD_SERVER_PORT"
+#define DEFAULT_ETCD_SERVER_PORT 2379
+
+// be careful - this should be higher than the curl timeout
+#define CFG_ETCD_TTL "DISCOVERY_ETCD_TTL"
+#define DEFAULT_ETCD_TTL 30
+
+
+celix_status_t etcdCommon_init(bundle_context_pt context) {
+ celix_status_t status = CELIX_SUCCESS;
+ const char* etcd_server = NULL;
+ const char* etcd_port_string = NULL;
+ int etcd_port = 0;
+
+ if ((bundleContext_getProperty(context, CFG_ETCD_SERVER_IP, &etcd_server) != CELIX_SUCCESS) || !etcd_server) {
+ etcd_server = DEFAULT_ETCD_SERVER_IP;
+ }
+
+ if ((bundleContext_getProperty(context, CFG_ETCD_SERVER_PORT, &etcd_port_string) != CELIX_SUCCESS) || !etcd_port_string) {
+ etcd_port = DEFAULT_ETCD_SERVER_PORT;
+ } else {
+ char* endptr = NULL;
+ errno = 0;
+ etcd_port = strtol(etcd_port_string, &endptr, 10);
+ if (*endptr || errno != 0) {
+ etcd_port = DEFAULT_ETCD_SERVER_PORT;
+ }
+ }
+
+ printf("PSD: Using discovery HOST:PORT: %s:%i\n", etcd_server, etcd_port);
+
+ if (etcd_init(etcd_server, etcd_port, CURL_GLOBAL_DEFAULT) != 0) {
+ status = CELIX_BUNDLE_EXCEPTION;
+ } else {
+ status = CELIX_SUCCESS;
+ }
+
+ return status;
+}
+
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/pubsub/pubsub_discovery/src/etcd_common.h
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_discovery/src/etcd_common.h b/pubsub/pubsub_discovery/src/etcd_common.h
new file mode 100644
index 0000000..7a3e7b6
--- /dev/null
+++ b/pubsub/pubsub_discovery/src/etcd_common.h
@@ -0,0 +1,28 @@
+/**
+ *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.
+ */
+
+#ifndef ETCD_COMMON_H_
+#define ETCD_COMMON_H_
+
+#include "bundle_context.h"
+#include "celix_errno.h"
+
+celix_status_t etcdCommon_init(bundle_context_pt context);
+
+#endif /* ETCD_COMMON_H_ */
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/pubsub/pubsub_discovery/src/etcd_watcher.c
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_discovery/src/etcd_watcher.c b/pubsub/pubsub_discovery/src/etcd_watcher.c
new file mode 100644
index 0000000..3c3a5a8
--- /dev/null
+++ b/pubsub/pubsub_discovery/src/etcd_watcher.c
@@ -0,0 +1,290 @@
+/**
+ *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.
+ */
+
+#include <stdbool.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+
+#include "celix_log.h"
+#include "constants.h"
+
+#include "etcd.h"
+#include "etcd_watcher.h"
+
+#include "pubsub_discovery.h"
+#include "pubsub_discovery_impl.h"
+
+
+
+#define MAX_ROOTNODE_LENGTH 128
+#define MAX_LOCALNODE_LENGTH 4096
+#define MAX_FIELD_LENGTH 128
+
+#define CFG_ETCD_ROOT_PATH "PUBSUB_DISCOVERY_ETCD_ROOT_PATH"
+#define DEFAULT_ETCD_ROOTPATH "pubsub/discovery"
+
+#define CFG_ETCD_SERVER_IP "PUBSUB_DISCOVERY_ETCD_SERVER_IP"
+#define DEFAULT_ETCD_SERVER_IP "127.0.0.1"
+
+#define CFG_ETCD_SERVER_PORT "PUBSUB_DISCOVERY_ETCD_SERVER_PORT"
+#define DEFAULT_ETCD_SERVER_PORT 2379
+
+// be careful - this should be higher than the curl timeout
+#define CFG_ETCD_TTL "DISCOVERY_ETCD_TTL"
+#define DEFAULT_ETCD_TTL 30
+
+
+struct etcd_watcher {
+ pubsub_discovery_pt pubsub_discovery;
+
+ celix_thread_mutex_t watcherLock;
+ celix_thread_t watcherThread;
+
+ char *scope;
+ char *topic;
+ volatile bool running;
+};
+
+struct etcd_writer {
+ pubsub_discovery_pt pubsub_discovery;
+ celix_thread_mutex_t localPubsLock;
+ array_list_pt localPubs;
+ volatile bool running;
+ celix_thread_t writerThread;
+};
+
+
+// note that the rootNode shouldn't have a leading slash
+static celix_status_t etcdWatcher_getTopicRootPath(bundle_context_pt context, const char *scope, const char *topic, char* rootNode, int rootNodeLen) {
+ celix_status_t status = CELIX_SUCCESS;
+ const char* rootPath = NULL;
+
+ if (((bundleContext_getProperty(context, CFG_ETCD_ROOT_PATH, &rootPath)) != CELIX_SUCCESS) || (!rootPath)) {
+ snprintf(rootNode, rootNodeLen, "%s/%s/%s", DEFAULT_ETCD_ROOTPATH, scope, topic);
+ } else {
+ snprintf(rootNode, rootNodeLen, "%s/%s/%s", rootPath, scope, topic);
+ }
+
+ return status;
+}
+
+static celix_status_t etcdWatcher_getRootPath(bundle_context_pt context, char* rootNode) {
+ celix_status_t status = CELIX_SUCCESS;
+ const char* rootPath = NULL;
+
+ if (((bundleContext_getProperty(context, CFG_ETCD_ROOT_PATH, &rootPath)) != CELIX_SUCCESS) || (!rootPath)) {
+ strncpy(rootNode, DEFAULT_ETCD_ROOTPATH, MAX_ROOTNODE_LENGTH);
+ } else {
+ strncpy(rootNode, rootPath, MAX_ROOTNODE_LENGTH);
+ }
+
+ return status;
+}
+
+
+static void add_node(const char *key, const char *value, void* arg) {
+ pubsub_discovery_pt ps_discovery = (pubsub_discovery_pt) arg;
+ pubsub_endpoint_pt pubEP = NULL;
+ celix_status_t status = etcdWatcher_getPublisherEndpointFromKey(ps_discovery, key, value, &pubEP);
+ if(!status && pubEP) {
+ pubsub_discovery_addNode(ps_discovery, pubEP);
+ }
+}
+
+static celix_status_t etcdWatcher_addAlreadyExistingPublishers(pubsub_discovery_pt ps_discovery, const char *rootPath, long long * highestModified) {
+ celix_status_t status = CELIX_SUCCESS;
+ if(etcd_get_directory(rootPath, add_node, ps_discovery, highestModified)) {
+ status = CELIX_ILLEGAL_ARGUMENT;
+ }
+ return status;
+}
+
+// gets everything from provided key
+celix_status_t etcdWatcher_getPublisherEndpointFromKey(pubsub_discovery_pt pubsub_discovery, const char* etcdKey, const char* etcdValue, pubsub_endpoint_pt* pubEP) {
+
+ celix_status_t status = CELIX_SUCCESS;
+
+ char rootPath[MAX_ROOTNODE_LENGTH];
+ char *expr = NULL;
+ char scope[MAX_FIELD_LENGTH];
+ char topic[MAX_FIELD_LENGTH];
+ char fwUUID[MAX_FIELD_LENGTH];
+ char serviceId[MAX_FIELD_LENGTH];
+
+ memset(rootPath,0,MAX_ROOTNODE_LENGTH);
+ memset(topic,0,MAX_FIELD_LENGTH);
+ memset(fwUUID,0,MAX_FIELD_LENGTH);
+ memset(serviceId,0,MAX_FIELD_LENGTH);
+
+ etcdWatcher_getRootPath(pubsub_discovery->context, rootPath);
+
+ asprintf(&expr, "/%s/%%[^/]/%%[^/]/%%[^/]/%%[^/].*", rootPath);
+ if(expr) {
+ int foundItems = sscanf(etcdKey, expr, scope, topic, fwUUID, serviceId);
+ free(expr);
+ if (foundItems != 4) { // Could happen when a directory is removed, just don't process this.
+ status = CELIX_ILLEGAL_STATE;
+ }
+ else{
+ status = pubsubEndpoint_create(fwUUID,scope,topic,strtol(serviceId,NULL,10),etcdValue,NULL,pubEP);
+ }
+ }
+ return status;
+}
+
+/*
+ * performs (blocking) etcd_watch calls to check for
+ * changing discovery endpoint information within etcd.
+ */
+static void* etcdWatcher_run(void* data) {
+ etcd_watcher_pt watcher = (etcd_watcher_pt) data;
+ time_t timeBeforeWatch = time(NULL);
+ char rootPath[MAX_ROOTNODE_LENGTH];
+ long long highestModified = 0;
+
+ pubsub_discovery_pt ps_discovery = watcher->pubsub_discovery;
+ bundle_context_pt context = ps_discovery->context;
+
+ memset(rootPath, 0, MAX_ROOTNODE_LENGTH);
+
+ //TODO: add topic to etcd key
+ etcdWatcher_getTopicRootPath(context, watcher->scope, watcher->topic, rootPath, MAX_ROOTNODE_LENGTH);
+ etcdWatcher_addAlreadyExistingPublishers(ps_discovery, rootPath, &highestModified);
+
+ while ((celixThreadMutex_lock(&watcher->watcherLock) == CELIX_SUCCESS) && watcher->running) {
+
+ char *rkey = NULL;
+ char *value = NULL;
+ char *preValue = NULL;
+ char *action = NULL;
+ long long modIndex;
+
+ celixThreadMutex_unlock(&watcher->watcherLock);
+
+ if (etcd_watch(rootPath, highestModified + 1, &action, &preValue, &value, &rkey, &modIndex) == 0 && action != NULL) {
+ pubsub_endpoint_pt pubEP = NULL;
+ if ((strcmp(action, "set") == 0) || (strcmp(action, "create") == 0)) {
+ if (etcdWatcher_getPublisherEndpointFromKey(ps_discovery, rkey, value, &pubEP) == CELIX_SUCCESS) {
+ pubsub_discovery_addNode(ps_discovery, pubEP);
+ }
+ } else if (strcmp(action, "delete") == 0) {
+ if (etcdWatcher_getPublisherEndpointFromKey(ps_discovery, rkey, preValue, &pubEP) == CELIX_SUCCESS) {
+ pubsub_discovery_removeNode(ps_discovery, pubEP);
+ }
+ } else if (strcmp(action, "expire") == 0) {
+ if (etcdWatcher_getPublisherEndpointFromKey(ps_discovery, rkey, preValue, &pubEP) == CELIX_SUCCESS) {
+ pubsub_discovery_removeNode(ps_discovery, pubEP);
+ }
+ } else if (strcmp(action, "update") == 0) {
+ if (etcdWatcher_getPublisherEndpointFromKey(ps_discovery, rkey, value, &pubEP) == CELIX_SUCCESS) {
+ pubsub_discovery_addNode(ps_discovery, pubEP);
+ }
+ } else {
+ fw_log(logger, OSGI_FRAMEWORK_LOG_INFO, "Unexpected action: %s", action);
+ }
+ highestModified = modIndex;
+ } else if (time(NULL) - timeBeforeWatch <= (DEFAULT_ETCD_TTL / 4)) {
+ sleep(DEFAULT_ETCD_TTL / 4);
+ }
+
+ FREE_MEM(action);
+ FREE_MEM(value);
+ FREE_MEM(preValue);
+ FREE_MEM(rkey);
+
+ /* prevent busy waiting, in case etcd_watch returns false */
+
+
+ if (time(NULL) - timeBeforeWatch > (DEFAULT_ETCD_TTL / 4)) {
+ timeBeforeWatch = time(NULL);
+ }
+
+ }
+
+ if (watcher->running == false) {
+ celixThreadMutex_unlock(&watcher->watcherLock);
+ }
+
+ return NULL;
+}
+
+celix_status_t etcdWatcher_create(pubsub_discovery_pt pubsub_discovery, bundle_context_pt context, const char *scope, const char *topic, etcd_watcher_pt *watcher) {
+ celix_status_t status = CELIX_SUCCESS;
+
+
+ if (pubsub_discovery == NULL) {
+ return CELIX_BUNDLE_EXCEPTION;
+ }
+
+ (*watcher) = calloc(1, sizeof(struct etcd_watcher));
+
+ if(*watcher == NULL){
+ return CELIX_ENOMEM;
+ }
+
+ (*watcher)->pubsub_discovery = pubsub_discovery;
+ (*watcher)->scope = strdup(scope);
+ (*watcher)->topic = strdup(topic);
+
+
+ celixThreadMutex_create(&(*watcher)->watcherLock, NULL);
+
+ celixThreadMutex_lock(&(*watcher)->watcherLock);
+
+ status = celixThread_create(&(*watcher)->watcherThread, NULL, etcdWatcher_run, *watcher);
+ if (status == CELIX_SUCCESS) {
+ (*watcher)->running = true;
+ }
+
+ celixThreadMutex_unlock(&(*watcher)->watcherLock);
+
+
+ return status;
+}
+
+celix_status_t etcdWatcher_destroy(etcd_watcher_pt watcher) {
+
+ celix_status_t status = CELIX_SUCCESS;
+
+ char rootPath[MAX_ROOTNODE_LENGTH];
+ etcdWatcher_getTopicRootPath(watcher->pubsub_discovery->context, watcher->scope, watcher->topic, rootPath, MAX_ROOTNODE_LENGTH);
+ celixThreadMutex_destroy(&(watcher->watcherLock));
+
+ free(watcher->scope);
+ free(watcher->topic);
+ free(watcher);
+
+ return status;
+}
+
+celix_status_t etcdWatcher_stop(etcd_watcher_pt watcher){
+ celix_status_t status = CELIX_SUCCESS;
+
+ celixThreadMutex_lock(&(watcher->watcherLock));
+ watcher->running = false;
+ celixThreadMutex_unlock(&(watcher->watcherLock));
+
+ celixThread_join(watcher->watcherThread, NULL);
+
+ return status;
+
+}
+
+
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/pubsub/pubsub_discovery/src/etcd_watcher.h
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_discovery/src/etcd_watcher.h b/pubsub/pubsub_discovery/src/etcd_watcher.h
new file mode 100644
index 0000000..c425e60
--- /dev/null
+++ b/pubsub/pubsub_discovery/src/etcd_watcher.h
@@ -0,0 +1,38 @@
+/**
+ *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.
+ */
+
+#ifndef ETCD_WATCHER_H_
+#define ETCD_WATCHER_H_
+
+#include "bundle_context.h"
+#include "celix_errno.h"
+
+#include "pubsub_discovery.h"
+#include "pubsub_endpoint.h"
+
+typedef struct etcd_watcher *etcd_watcher_pt;
+
+celix_status_t etcdWatcher_create(pubsub_discovery_pt discovery, bundle_context_pt context, const char *scope, const char* topic, etcd_watcher_pt *watcher);
+celix_status_t etcdWatcher_destroy(etcd_watcher_pt watcher);
+celix_status_t etcdWatcher_stop(etcd_watcher_pt watcher);
+
+celix_status_t etcdWatcher_getPublisherEndpointFromKey(pubsub_discovery_pt discovery, const char* key, const char* value, pubsub_endpoint_pt* pubEP);
+
+
+#endif /* ETCD_WATCHER_H_ */
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/pubsub/pubsub_discovery/src/etcd_writer.c
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_discovery/src/etcd_writer.c b/pubsub/pubsub_discovery/src/etcd_writer.c
new file mode 100644
index 0000000..1c423f3
--- /dev/null
+++ b/pubsub/pubsub_discovery/src/etcd_writer.c
@@ -0,0 +1,189 @@
+/**
+ *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.
+ */
+
+#include <stdbool.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+
+#include "celix_log.h"
+#include "constants.h"
+
+#include "etcd.h"
+#include "etcd_writer.h"
+
+#include "pubsub_discovery.h"
+#include "pubsub_discovery_impl.h"
+
+#define MAX_ROOTNODE_LENGTH 128
+
+#define CFG_ETCD_ROOT_PATH "PUBSUB_DISCOVERY_ETCD_ROOT_PATH"
+#define DEFAULT_ETCD_ROOTPATH "pubsub/discovery"
+
+#define CFG_ETCD_SERVER_IP "PUBSUB_DISCOVERY_ETCD_SERVER_IP"
+#define DEFAULT_ETCD_SERVER_IP "127.0.0.1"
+
+#define CFG_ETCD_SERVER_PORT "PUBSUB_DISCOVERY_ETCD_SERVER_PORT"
+#define DEFAULT_ETCD_SERVER_PORT 2379
+
+// be careful - this should be higher than the curl timeout
+#define CFG_ETCD_TTL "DISCOVERY_ETCD_TTL"
+#define DEFAULT_ETCD_TTL 30
+
+struct etcd_writer {
+ pubsub_discovery_pt pubsub_discovery;
+ celix_thread_mutex_t localPubsLock;
+ array_list_pt localPubs;
+ volatile bool running;
+ celix_thread_t writerThread;
+};
+
+
+static const char* etcdWriter_getRootPath(bundle_context_pt context);
+static void* etcdWriter_run(void* data);
+
+
+etcd_writer_pt etcdWriter_create(pubsub_discovery_pt disc) {
+ etcd_writer_pt writer = calloc(1, sizeof(*writer));
+ if(writer) {
+ celixThreadMutex_create(&writer->localPubsLock, NULL);
+ arrayList_create(&writer->localPubs);
+ writer->pubsub_discovery = disc;
+ writer->running = true;
+ celixThread_create(&writer->writerThread, NULL, etcdWriter_run, writer);
+ }
+ return writer;
+}
+
+void etcdWriter_destroy(etcd_writer_pt writer) {
+ char dir[MAX_ROOTNODE_LENGTH];
+ const char *rootPath = etcdWriter_getRootPath(writer->pubsub_discovery->context);
+
+ writer->running = false;
+ celixThread_join(writer->writerThread, NULL);
+
+ celixThreadMutex_lock(&writer->localPubsLock);
+ for(int i = 0; i < arrayList_size(writer->localPubs); i++) {
+ pubsub_endpoint_pt pubEP = (pubsub_endpoint_pt)arrayList_get(writer->localPubs,i);
+ memset(dir,0,MAX_ROOTNODE_LENGTH);
+ snprintf(dir,MAX_ROOTNODE_LENGTH,"%s/%s/%s/%s",rootPath,pubEP->scope,pubEP->topic,pubEP->frameworkUUID);
+ etcd_del(dir);
+ pubsubEndpoint_destroy(pubEP);
+ }
+ arrayList_destroy(writer->localPubs);
+
+ celixThreadMutex_unlock(&writer->localPubsLock);
+ celixThreadMutex_destroy(&(writer->localPubsLock));
+
+ free(writer);
+}
+
+celix_status_t etcdWriter_addPublisherEndpoint(etcd_writer_pt writer, pubsub_endpoint_pt pubEP, bool storeEP){
+ celix_status_t status = CELIX_BUNDLE_EXCEPTION;
+
+ if(storeEP){
+ const char *fwUUID = NULL;
+ bundleContext_getProperty(writer->pubsub_discovery->context, OSGI_FRAMEWORK_FRAMEWORK_UUID, &fwUUID);
+ if(fwUUID && strcmp(pubEP->frameworkUUID, fwUUID) == 0) {
+ celixThreadMutex_lock(&writer->localPubsLock);
+ pubsub_endpoint_pt p = NULL;
+ pubsubEndpoint_clone(pubEP, &p);
+ arrayList_add(writer->localPubs,p);
+ celixThreadMutex_unlock(&writer->localPubsLock);
+ }
+ }
+
+ char *key;
+
+ const char* ttlStr = NULL;
+ int ttl = 0;
+
+ // determine ttl
+ if ((bundleContext_getProperty(writer->pubsub_discovery->context, CFG_ETCD_TTL, &ttlStr) != CELIX_SUCCESS) || !ttlStr) {
+ ttl = DEFAULT_ETCD_TTL;
+ } else {
+ char* endptr = NULL;
+ errno = 0;
+ ttl = strtol(ttlStr, &endptr, 10);
+ if (*endptr || errno != 0) {
+ ttl = DEFAULT_ETCD_TTL;
+ }
+ }
+
+ const char *rootPath = etcdWriter_getRootPath(writer->pubsub_discovery->context);
+
+ asprintf(&key,"%s/%s/%s/%s/%ld",rootPath,pubEP->scope,pubEP->topic,pubEP->frameworkUUID,pubEP->serviceID);
+
+ if(!etcd_set(key,pubEP->endpoint,ttl,false)){
+ status = CELIX_ILLEGAL_ARGUMENT;
+ }
+ FREE_MEM(key);
+ return status;
+}
+
+celix_status_t etcdWriter_deletePublisherEndpoint(etcd_writer_pt writer, pubsub_endpoint_pt pubEP) {
+ celix_status_t status = CELIX_SUCCESS;
+ char *key = NULL;
+
+ const char *rootPath = etcdWriter_getRootPath(writer->pubsub_discovery->context);
+
+ asprintf(&key, "%s/%s/%s/%s/%ld", rootPath, pubEP->scope, pubEP->topic, pubEP->frameworkUUID, pubEP->serviceID);
+
+ celixThreadMutex_lock(&writer->localPubsLock);
+ for (unsigned int i = 0; i < arrayList_size(writer->localPubs); i++) {
+ pubsub_endpoint_pt ep = arrayList_get(writer->localPubs, i);
+ if (pubsubEndpoint_equals(ep, pubEP)) {
+ arrayList_remove(writer->localPubs, i);
+ pubsubEndpoint_destroy(ep);
+ break;
+ }
+ }
+ celixThreadMutex_unlock(&writer->localPubsLock);
+
+ if (etcd_del(key)) {
+ printf("Failed to remove key %s from ETCD\n",key);
+ status = CELIX_ILLEGAL_ARGUMENT;
+ }
+ FREE_MEM(key);
+ return status;
+}
+
+static void* etcdWriter_run(void* data) {
+ etcd_writer_pt writer = (etcd_writer_pt)data;
+ while(writer->running) {
+ celixThreadMutex_lock(&writer->localPubsLock);
+ for(int i=0; i < arrayList_size(writer->localPubs); i++) {
+ etcdWriter_addPublisherEndpoint(writer,(pubsub_endpoint_pt)arrayList_get(writer->localPubs,i),false);
+ }
+ celixThreadMutex_unlock(&writer->localPubsLock);
+ sleep(DEFAULT_ETCD_TTL / 2);
+ }
+
+ return NULL;
+}
+
+static const char* etcdWriter_getRootPath(bundle_context_pt context) {
+ const char* rootPath = NULL;
+ bundleContext_getProperty(context, CFG_ETCD_ROOT_PATH, &rootPath);
+ if(rootPath == NULL) {
+ rootPath = DEFAULT_ETCD_ROOTPATH;
+ }
+ return rootPath;
+}
+
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/pubsub/pubsub_discovery/src/etcd_writer.h
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_discovery/src/etcd_writer.h b/pubsub/pubsub_discovery/src/etcd_writer.h
new file mode 100644
index 0000000..3ff98b9
--- /dev/null
+++ b/pubsub/pubsub_discovery/src/etcd_writer.h
@@ -0,0 +1,39 @@
+/**
+ *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.
+ */
+
+#ifndef ETCD_WRITER_H_
+#define ETCD_WRITER_H_
+
+#include "bundle_context.h"
+#include "celix_errno.h"
+
+#include "pubsub_discovery.h"
+#include "pubsub_endpoint.h"
+
+typedef struct etcd_writer *etcd_writer_pt;
+
+
+etcd_writer_pt etcdWriter_create(pubsub_discovery_pt discovery);
+void etcdWriter_destroy(etcd_writer_pt writer);
+
+celix_status_t etcdWriter_addPublisherEndpoint(etcd_writer_pt writer, pubsub_endpoint_pt pubEP,bool storeEP);
+celix_status_t etcdWriter_deletePublisherEndpoint(etcd_writer_pt writer, pubsub_endpoint_pt pubEP);
+
+
+#endif /* ETCD_WRITER_H_ */
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/pubsub/pubsub_discovery/src/psd_activator.c
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_discovery/src/psd_activator.c b/pubsub/pubsub_discovery/src/psd_activator.c
new file mode 100644
index 0000000..89a517d
--- /dev/null
+++ b/pubsub/pubsub_discovery/src/psd_activator.c
@@ -0,0 +1,171 @@
+/**
+ *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.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "bundle_activator.h"
+#include "service_tracker.h"
+#include "service_registration.h"
+#include "constants.h"
+#include "celix_log.h"
+
+#include "pubsub_common.h"
+#include "publisher_endpoint_announce.h"
+#include "pubsub_discovery.h"
+#include "pubsub_discovery_impl.h"
+
+struct activator {
+ bundle_context_pt context;
+ pubsub_discovery_pt pubsub_discovery;
+
+ service_tracker_pt pstmPublishersTracker;
+
+ publisher_endpoint_announce_pt publisherEPAnnounce;
+ service_registration_pt publisherEPAnnounceService;
+};
+
+static celix_status_t createTMPublisherAnnounceTracker(struct activator *activator, service_tracker_pt *tracker) {
+ celix_status_t status = CELIX_SUCCESS;
+
+ service_tracker_customizer_pt customizer = NULL;
+
+ status = serviceTrackerCustomizer_create(activator->pubsub_discovery,
+ NULL,
+ pubsub_discovery_tmPublisherAnnounceAdded,
+ pubsub_discovery_tmPublisherAnnounceModified,
+ pubsub_discovery_tmPublisherAnnounceRemoved,
+ &customizer);
+
+ if (status == CELIX_SUCCESS) {
+ status = serviceTracker_create(activator->context, (char *) PUBSUB_TM_ANNOUNCE_PUBLISHER_SERVICE, customizer, tracker);
+ }
+
+ return status;
+}
+
+celix_status_t bundleActivator_create(bundle_context_pt context, void **userData) {
+ celix_status_t status = CELIX_SUCCESS;
+
+ struct activator* activator = calloc(1, sizeof(*activator));
+
+ if (activator) {
+ activator->context = context;
+ activator->pstmPublishersTracker = NULL;
+ activator->publisherEPAnnounce = NULL;
+ activator->publisherEPAnnounceService = NULL;
+
+ status = pubsub_discovery_create(context, &activator->pubsub_discovery);
+
+ if (status == CELIX_SUCCESS) {
+ status = createTMPublisherAnnounceTracker(activator, &(activator->pstmPublishersTracker));
+ }
+
+ if (status == CELIX_SUCCESS) {
+ *userData = activator;
+ } else {
+ free(activator);
+ }
+ } else {
+ status = CELIX_ENOMEM;
+ }
+
+ return status;
+
+}
+
+celix_status_t bundleActivator_start(void * userData, bundle_context_pt context) {
+ celix_status_t status = CELIX_SUCCESS;
+
+ struct activator *activator = userData;
+
+ publisher_endpoint_announce_pt pubEPAnnouncer = calloc(1, sizeof(*pubEPAnnouncer));
+
+ if (pubEPAnnouncer) {
+
+ pubEPAnnouncer->handle = activator->pubsub_discovery;
+ pubEPAnnouncer->announcePublisher = pubsub_discovery_announcePublisher;
+ pubEPAnnouncer->removePublisher = pubsub_discovery_removePublisher;
+ pubEPAnnouncer->interestedInTopic = pubsub_discovery_interestedInTopic;
+ pubEPAnnouncer->uninterestedInTopic = pubsub_discovery_uninterestedInTopic;
+ activator->publisherEPAnnounce = pubEPAnnouncer;
+
+ properties_pt props = properties_create();
+ properties_set(props, "PUBSUB_DISCOVERY", "true");
+
+ // pubsub_discovery_start needs to be first to initalize the propert etcd_watcher values
+ status = pubsub_discovery_start(activator->pubsub_discovery);
+
+ if (status == CELIX_SUCCESS) {
+ status = serviceTracker_open(activator->pstmPublishersTracker);
+ }
+
+ if (status == CELIX_SUCCESS) {
+ status = bundleContext_registerService(context, (char *) PUBSUB_DISCOVERY_SERVICE, pubEPAnnouncer, props, &activator->publisherEPAnnounceService);
+ }
+
+
+ }
+ else{
+ status = CELIX_ENOMEM;
+ }
+
+ if(status!=CELIX_SUCCESS && pubEPAnnouncer!=NULL){
+ free(pubEPAnnouncer);
+ }
+
+
+ return status;
+}
+
+celix_status_t bundleActivator_stop(void * userData, bundle_context_pt context) {
+ celix_status_t status = CELIX_SUCCESS;
+ struct activator *activator = userData;
+
+ status += pubsub_discovery_stop(activator->pubsub_discovery);
+
+ status += serviceTracker_close(activator->pstmPublishersTracker);
+
+ status += serviceRegistration_unregister(activator->publisherEPAnnounceService);
+
+ if (status == CELIX_SUCCESS) {
+ free(activator->publisherEPAnnounce);
+ }
+
+ return status;
+}
+
+celix_status_t bundleActivator_destroy(void * userData, bundle_context_pt context) {
+ celix_status_t status = CELIX_SUCCESS;
+ struct activator *activator = userData;
+
+ status += serviceTracker_destroy(activator->pstmPublishersTracker);
+ status += pubsub_discovery_destroy(activator->pubsub_discovery);
+
+ activator->publisherEPAnnounce = NULL;
+ activator->publisherEPAnnounceService = NULL;
+ activator->pstmPublishersTracker = NULL;
+ activator->pubsub_discovery = NULL;
+ activator->context = NULL;
+
+ free(activator);
+
+ return status;
+}
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/pubsub/pubsub_discovery/src/pubsub_discovery.h
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_discovery/src/pubsub_discovery.h b/pubsub/pubsub_discovery/src/pubsub_discovery.h
new file mode 100644
index 0000000..f77905a
--- /dev/null
+++ b/pubsub/pubsub_discovery/src/pubsub_discovery.h
@@ -0,0 +1,26 @@
+/**
+ *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.
+ */
+
+#ifndef PUBSUB_DISCOVERY_H_
+#define PUBSUB_DISCOVERY_H_
+
+typedef struct pubsub_discovery *pubsub_discovery_pt;
+
+
+#endif /* PUBSUB_DISCOVERY_H_ */
[03/19] celix git commit: CELIX-417: Refactor for CMake usage in RSA,
PSA and Docker. mostly trying to identify the api and common libraries
Posted by pn...@apache.org.
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/topology_manager/src/topology_manager.c
----------------------------------------------------------------------
diff --git a/remote_services/topology_manager/src/topology_manager.c b/remote_services/topology_manager/src/topology_manager.c
new file mode 100644
index 0000000..6472b01
--- /dev/null
+++ b/remote_services/topology_manager/src/topology_manager.c
@@ -0,0 +1,985 @@
+/**
+ *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.
+ */
+/*
+ * topology_manager.c
+ *
+ * \date Sep 29, 2011
+ * \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 <string.h>
+
+#include "celixbool.h"
+#include "topology_manager.h"
+#include "bundle_context.h"
+#include "constants.h"
+#include "bundle.h"
+#include "remote_service_admin.h"
+#include "remote_constants.h"
+#include "filter.h"
+#include "listener_hook_service.h"
+#include "utils.h"
+#include "service_reference.h"
+#include "service_registration.h"
+#include "log_service.h"
+#include "log_helper.h"
+#include "topology_manager.h"
+#include "scope.h"
+#include "hash_map.h"
+
+struct topology_manager {
+ bundle_context_pt context;
+
+ celix_thread_mutex_t rsaListLock;
+ celix_thread_mutexattr_t rsaListLockAttr;
+ array_list_pt rsaList;
+
+ celix_thread_mutex_t listenerListLock;
+ hash_map_pt listenerList;
+
+ celix_thread_mutex_t exportedServicesLock;
+ hash_map_pt exportedServices;
+
+ celix_thread_mutex_t importedServicesLock;
+ celix_thread_mutexattr_t importedServicesLockAttr;
+ hash_map_pt importedServices;
+
+ scope_pt scope;
+
+ log_helper_pt loghelper;
+};
+
+celix_status_t topologyManager_exportScopeChanged(void *handle, char *service_name);
+celix_status_t topologyManager_importScopeChanged(void *handle, char *service_name);
+celix_status_t topologyManager_notifyListenersEndpointAdded(topology_manager_pt manager, remote_service_admin_service_pt rsa, array_list_pt registrations);
+celix_status_t topologyManager_notifyListenersEndpointRemoved(topology_manager_pt manager, remote_service_admin_service_pt rsa, export_registration_pt export);
+
+celix_status_t topologyManager_create(bundle_context_pt context, log_helper_pt logHelper, topology_manager_pt *manager, void **scope) {
+ celix_status_t status = CELIX_SUCCESS;
+
+ *manager = calloc(1, sizeof(**manager));
+
+ if (!*manager) {
+ return CELIX_ENOMEM;
+ }
+
+ (*manager)->context = context;
+ (*manager)->rsaList = NULL;
+
+ arrayList_create(&(*manager)->rsaList);
+
+
+ celixThreadMutexAttr_create(&(*manager)->rsaListLockAttr);
+ celixThreadMutexAttr_settype(&(*manager)->rsaListLockAttr, CELIX_THREAD_MUTEX_RECURSIVE);
+ celixThreadMutex_create(&(*manager)->rsaListLock, &(*manager)->rsaListLockAttr);
+
+ celixThreadMutexAttr_create(&(*manager)->importedServicesLockAttr);
+ celixThreadMutexAttr_settype(&(*manager)->importedServicesLockAttr, CELIX_THREAD_MUTEX_RECURSIVE);
+ celixThreadMutex_create(&(*manager)->importedServicesLock, &(*manager)->importedServicesLockAttr);
+
+ celixThreadMutex_create(&(*manager)->exportedServicesLock, NULL);
+ celixThreadMutex_create(&(*manager)->listenerListLock, NULL);
+
+ (*manager)->listenerList = hashMap_create(serviceReference_hashCode, NULL, serviceReference_equals2, NULL);
+ (*manager)->exportedServices = hashMap_create(serviceReference_hashCode, NULL, serviceReference_equals2, NULL);
+ (*manager)->importedServices = hashMap_create(NULL, NULL, NULL, NULL);
+
+ status = scope_scopeCreate(*manager, &(*manager)->scope);
+ scope_setExportScopeChangedCallback((*manager)->scope, topologyManager_exportScopeChanged);
+ scope_setImportScopeChangedCallback((*manager)->scope, topologyManager_importScopeChanged);
+ *scope = (*manager)->scope;
+
+ (*manager)->loghelper = logHelper;
+
+
+ return status;
+}
+
+celix_status_t topologyManager_destroy(topology_manager_pt manager) {
+ celix_status_t status = CELIX_SUCCESS;
+
+ celixThreadMutex_lock(&manager->listenerListLock);
+ hashMap_destroy(manager->listenerList, false, false);
+
+ celixThreadMutex_unlock(&manager->listenerListLock);
+ celixThreadMutex_destroy(&manager->listenerListLock);
+
+ celixThreadMutex_lock(&manager->rsaListLock);
+
+ arrayList_destroy(manager->rsaList);
+
+ celixThreadMutex_unlock(&manager->rsaListLock);
+ celixThreadMutex_destroy(&manager->rsaListLock);
+ celixThreadMutexAttr_destroy(&manager->rsaListLockAttr);
+
+ celixThreadMutex_lock(&manager->exportedServicesLock);
+
+ hashMap_destroy(manager->exportedServices, false, false);
+
+ celixThreadMutex_unlock(&manager->exportedServicesLock);
+ celixThreadMutex_destroy(&manager->exportedServicesLock);
+
+ celixThreadMutex_lock(&manager->importedServicesLock);
+
+ hashMap_destroy(manager->importedServices, false, false);
+
+ celixThreadMutex_unlock(&manager->importedServicesLock);
+ celixThreadMutex_destroy(&manager->importedServicesLock);
+ celixThreadMutexAttr_destroy(&manager->importedServicesLockAttr);
+
+ scope_scopeDestroy(manager->scope);
+ free(manager);
+
+ return status;
+}
+
+celix_status_t topologyManager_closeImports(topology_manager_pt manager) {
+ celix_status_t status;
+
+ status = celixThreadMutex_lock(&manager->importedServicesLock);
+
+ hash_map_iterator_pt iter = hashMapIterator_create(manager->importedServices);
+ while (hashMapIterator_hasNext(iter)) {
+ hash_map_entry_pt entry = hashMapIterator_nextEntry(iter);
+ endpoint_description_pt ep = hashMapEntry_getKey(entry);
+ hash_map_pt imports = hashMapEntry_getValue(entry);
+
+ if (imports != NULL) {
+ logHelper_log(manager->loghelper, OSGI_LOGSERVICE_INFO, "TOPOLOGY_MANAGER: Remove imported service (%s; %s).", ep->service, ep->id);
+ hash_map_iterator_pt importsIter = hashMapIterator_create(imports);
+
+ while (hashMapIterator_hasNext(importsIter)) {
+ hash_map_entry_pt entry = hashMapIterator_nextEntry(importsIter);
+
+ remote_service_admin_service_pt rsa = hashMapEntry_getKey(entry);
+ import_registration_pt import = hashMapEntry_getValue(entry);
+
+ status = rsa->importRegistration_close(rsa->admin, import);
+ if (status == CELIX_SUCCESS) {
+ hashMapIterator_remove(importsIter);
+ }
+ }
+ hashMapIterator_destroy(importsIter);
+
+ hashMapIterator_remove(iter);
+
+ hashMap_destroy(imports, false, false);
+ }
+ }
+ hashMapIterator_destroy(iter);
+
+ status = celixThreadMutex_unlock(&manager->importedServicesLock);
+
+ return status;
+}
+
+celix_status_t topologyManager_rsaAdding(void * handle, service_reference_pt reference, void **service) {
+ celix_status_t status;
+ topology_manager_pt manager = (topology_manager_pt) handle;
+
+ status = bundleContext_getService(manager->context, reference, service);
+
+ return status;
+}
+
+celix_status_t topologyManager_rsaAdded(void * handle, service_reference_pt reference, void * service) {
+ celix_status_t status;
+ topology_manager_pt manager = (topology_manager_pt) handle;
+ properties_pt serviceProperties = NULL;
+ remote_service_admin_service_pt rsa = (remote_service_admin_service_pt) service;
+ logHelper_log(manager->loghelper, OSGI_LOGSERVICE_INFO, "TOPOLOGY_MANAGER: Added RSA");
+
+ status = celixThreadMutex_lock(&manager->rsaListLock);
+
+ if (status == CELIX_SUCCESS) {
+ arrayList_add(manager->rsaList, rsa);
+ status = celixThreadMutex_unlock(&manager->rsaListLock);
+ }
+
+ // add already imported services to new rsa
+ if (status == CELIX_SUCCESS) {
+ status = celixThreadMutex_lock(&manager->importedServicesLock);
+
+ if (status == CELIX_SUCCESS) {
+ hash_map_iterator_pt importedServicesIterator = hashMapIterator_create(manager->importedServices);
+
+ while (hashMapIterator_hasNext(importedServicesIterator)) {
+ hash_map_entry_pt entry = hashMapIterator_nextEntry(importedServicesIterator);
+ endpoint_description_pt endpoint = hashMapEntry_getKey(entry);
+ if (scope_allowImport(manager->scope, endpoint)) {
+ import_registration_pt import = NULL;
+ status = rsa->importService(rsa->admin, endpoint, &import);
+
+ if (status == CELIX_SUCCESS) {
+ hash_map_pt imports = hashMapEntry_getValue(entry);
+
+ if (imports == NULL) {
+ imports = hashMap_create(NULL, NULL, NULL, NULL);
+ hashMap_put(manager->importedServices,endpoint,imports);
+ }
+
+ hashMap_put(imports, service, import);
+ }
+ }
+ }
+
+ hashMapIterator_destroy(importedServicesIterator);
+
+ celixThreadMutex_unlock(&manager->importedServicesLock);
+ }
+ }
+
+ // add already exported services to new rsa
+ if (status == CELIX_SUCCESS) {
+ status = celixThreadMutex_lock(&manager->exportedServicesLock);
+
+ if (status == CELIX_SUCCESS) {
+ hash_map_iterator_pt exportedServicesIterator = hashMapIterator_create(manager->exportedServices);
+
+ while (hashMapIterator_hasNext(exportedServicesIterator)) {
+ hash_map_entry_pt entry = hashMapIterator_nextEntry(exportedServicesIterator);
+ service_reference_pt reference = hashMapEntry_getKey(entry);
+ const char* serviceId = NULL;
+
+ serviceReference_getProperty(reference, OSGI_FRAMEWORK_SERVICE_ID, &serviceId);
+
+ scope_getExportProperties(manager->scope, reference, &serviceProperties);
+
+ array_list_pt endpoints = NULL;
+ status = rsa->exportService(rsa->admin, (char*)serviceId, serviceProperties, &endpoints);
+
+ if (status == CELIX_SUCCESS) {
+ hash_map_pt exports = hashMapEntry_getValue(entry);
+
+ if (exports == NULL) {
+ exports = hashMap_create(NULL, NULL, NULL, NULL);
+ hashMap_put(manager->exportedServices,reference,exports);
+ }
+
+ hashMap_put(exports, rsa, endpoints);
+ status = topologyManager_notifyListenersEndpointAdded(manager, rsa, endpoints);
+ }
+ }
+
+ hashMapIterator_destroy(exportedServicesIterator);
+
+ celixThreadMutex_unlock(&manager->exportedServicesLock);
+ }
+ }
+ return status;
+}
+
+celix_status_t topologyManager_rsaModified(void * handle, service_reference_pt reference, void * service) {
+ celix_status_t status = CELIX_SUCCESS;
+
+ // Nop...
+
+ return status;
+}
+
+celix_status_t topologyManager_rsaRemoved(void * handle, service_reference_pt reference, void * service) {
+ celix_status_t status = CELIX_SUCCESS;
+ topology_manager_pt manager = (topology_manager_pt) handle;
+ remote_service_admin_service_pt rsa = (remote_service_admin_service_pt) service;
+
+ if (celixThreadMutex_lock(&manager->exportedServicesLock) == CELIX_SUCCESS) {
+ hash_map_iterator_pt iter = hashMapIterator_create(manager->exportedServices);
+
+ while (hashMapIterator_hasNext(iter)) {
+
+ hash_map_entry_pt entry = hashMapIterator_nextEntry(iter);
+ service_reference_pt key = hashMapEntry_getKey(entry);
+ hash_map_pt exports = hashMapEntry_getValue(entry);
+
+ /*
+ * the problem here is that also the rsa has a a list of
+ * endpoints which is destroyed when closing the exportRegistration
+ */
+ array_list_pt exports_list = hashMap_get(exports, rsa);
+
+ if (exports_list != NULL) {
+ int exportsIter = 0;
+ int exportListSize = arrayList_size(exports_list);
+ for (exportsIter = 0; exports_list != NULL && exportsIter < exportListSize; exportsIter++) {
+ export_registration_pt export = arrayList_get(exports_list, exportsIter);
+ topologyManager_notifyListenersEndpointRemoved(manager, rsa, export);
+ rsa->exportRegistration_close(rsa->admin, export);
+ }
+ }
+
+ hashMap_remove(exports, rsa);
+ /*if(exports_list!=NULL){
+ arrayList_destroy(exports_list);
+ }*/
+
+ if (hashMap_size(exports) == 0) {
+ hashMap_remove(manager->exportedServices, key);
+ hashMap_destroy(exports, false, false);
+
+ hashMapIterator_destroy(iter);
+ iter = hashMapIterator_create(manager->exportedServices);
+ }
+ }
+ hashMapIterator_destroy(iter);
+ celixThreadMutex_unlock(&manager->exportedServicesLock);
+ }
+
+ if (celixThreadMutex_lock(&manager->importedServicesLock) == CELIX_SUCCESS) {
+ hash_map_iterator_pt iter = hashMapIterator_create(manager->importedServices);
+
+ while (hashMapIterator_hasNext(iter)) {
+ hash_map_entry_pt entry = hashMapIterator_nextEntry(iter);
+ hash_map_pt imports = hashMapEntry_getValue(entry);
+
+ import_registration_pt import = hashMap_get(imports, rsa);
+
+ if (import != NULL) {
+ celix_status_t subStatus = rsa->importRegistration_close(rsa->admin, import);
+
+ if (subStatus == CELIX_SUCCESS) {
+ hashMap_remove(imports, rsa);
+ } else {
+ status = subStatus;
+ }
+ }
+ }
+ hashMapIterator_destroy(iter);
+ celixThreadMutex_unlock(&manager->importedServicesLock);
+ }
+
+ if (celixThreadMutex_lock(&manager->rsaListLock) == CELIX_SUCCESS) {
+ arrayList_removeElement(manager->rsaList, rsa);
+ celixThreadMutex_unlock(&manager->rsaListLock);
+ }
+
+ logHelper_log(manager->loghelper, OSGI_LOGSERVICE_INFO, "TOPOLOGY_MANAGER: Removed RSA");
+
+ return status;
+}
+
+
+celix_status_t topologyManager_serviceChanged(void *listener, service_event_pt event) {
+ celix_status_t status = CELIX_SUCCESS;
+ service_listener_pt listen = listener;
+ topology_manager_pt manager = listen->handle;
+
+ const char* export = NULL;
+ const char* serviceId = NULL;
+ serviceReference_getProperty(event->reference, OSGI_RSA_SERVICE_EXPORTED_INTERFACES, &export);
+ serviceReference_getProperty(event->reference, OSGI_FRAMEWORK_SERVICE_ID, &serviceId);
+
+ if (!export) {
+ // Nothing needs to be done: we're not interested...
+ return status;
+ }
+
+ switch (event->type) {
+ case OSGI_FRAMEWORK_SERVICE_EVENT_REGISTERED:
+ status = topologyManager_addExportedService(manager, event->reference, (char*)serviceId);
+ break;
+ case OSGI_FRAMEWORK_SERVICE_EVENT_MODIFIED:
+ status = topologyManager_removeExportedService(manager, event->reference, (char*)serviceId);
+
+ if (status == CELIX_SUCCESS) {
+ status = topologyManager_addExportedService(manager, event->reference, (char*)serviceId);
+ }
+ break;
+ case OSGI_FRAMEWORK_SERVICE_EVENT_UNREGISTERING:
+ status = topologyManager_removeExportedService(manager, event->reference, (char*)serviceId);
+ break;
+ case OSGI_FRAMEWORK_SERVICE_EVENT_MODIFIED_ENDMATCH:
+ break;
+ }
+
+ return status;
+}
+
+celix_status_t topologyManager_exportScopeChanged(void *handle, char *filterStr) {
+ celix_status_t status = CELIX_SUCCESS;
+ topology_manager_pt manager = (topology_manager_pt) handle;
+ service_registration_pt reg = NULL;
+ const char* serviceId = NULL;
+ bool found;
+ properties_pt props;
+ filter_pt filter = filter_create(filterStr);
+
+ if (filter == NULL) {
+ printf("filter creating failed\n");
+ return CELIX_ENOMEM;
+ }
+
+ // add already exported services to new rsa
+ if (celixThreadMutex_lock(&manager->exportedServicesLock) == CELIX_SUCCESS) {
+ hash_map_iterator_pt exportedServicesIterator = hashMapIterator_create(manager->exportedServices);
+ int size = hashMap_size(manager->exportedServices);
+ service_reference_pt *srvRefs = (service_reference_pt *) calloc(size, sizeof(service_reference_pt));
+ char **srvIds = (char **) calloc(size, sizeof(char*));
+ int nrFound = 0;
+
+ found = false;
+
+ while (hashMapIterator_hasNext(exportedServicesIterator)) {
+ hash_map_entry_pt entry = hashMapIterator_nextEntry(exportedServicesIterator);
+ service_reference_pt reference = hashMapEntry_getKey(entry);
+ reg = NULL;
+ serviceReference_getServiceRegistration(reference, ®);
+ if (reg != NULL) {
+ props = NULL;
+ serviceRegistration_getProperties(reg, &props);
+ status = filter_match(filter, props, &found);
+ if (found) {
+ srvRefs[nrFound] = reference;
+ serviceReference_getProperty(reference, OSGI_FRAMEWORK_SERVICE_ID, &serviceId);
+ srvIds[nrFound++] = (char*)serviceId;
+ }
+ }
+ }
+
+ hashMapIterator_destroy(exportedServicesIterator);
+ celixThreadMutex_unlock(&manager->exportedServicesLock);
+
+ if (nrFound > 0) {
+ for (int i = 0; i < nrFound; i++) {
+ // Question: can srvRefs become invalid meanwhile??
+ const char* export = NULL;
+ serviceReference_getProperty(srvRefs[i], (char *) OSGI_RSA_SERVICE_EXPORTED_INTERFACES, &export);
+
+ if (export) {
+ celix_status_t substatus = topologyManager_removeExportedService(manager, srvRefs[i], srvIds[i]);
+
+ if (substatus != CELIX_SUCCESS) {
+ logHelper_log(manager->loghelper, OSGI_LOGSERVICE_ERROR, "TOPOLOGY_MANAGER: Removal of exported service (%s) failed.", srvIds[i]);
+ } else {
+ substatus = topologyManager_addExportedService(manager, srvRefs[i], srvIds[i]);
+ }
+
+ if (substatus != CELIX_SUCCESS) {
+ status = substatus;
+ }
+ }
+ }
+ }
+
+ free(srvRefs);
+ free(srvIds);
+ }
+
+ filter_destroy(filter);
+
+ return status;
+}
+
+celix_status_t topologyManager_importScopeChanged(void *handle, char *service_name) {
+ celix_status_t status = CELIX_SUCCESS;
+ endpoint_description_pt endpoint;
+ topology_manager_pt manager = (topology_manager_pt) handle;
+ bool found = false;
+
+ // add already exported services to new rsa
+ if (celixThreadMutex_lock(&manager->importedServicesLock) == CELIX_SUCCESS) {
+ hash_map_iterator_pt importedServicesIterator = hashMapIterator_create(manager->importedServices);
+ while (!found && hashMapIterator_hasNext(importedServicesIterator)) {
+ hash_map_entry_pt entry = hashMapIterator_nextEntry(importedServicesIterator);
+ endpoint = hashMapEntry_getKey(entry);
+
+ entry = hashMap_getEntry(endpoint->properties, (void *) OSGI_FRAMEWORK_OBJECTCLASS);
+ char* name = (char *) hashMapEntry_getValue(entry);
+ // Test if a service with the same name is imported
+ if (strcmp(name, service_name) == 0) {
+ found = true;
+ }
+ }
+ hashMapIterator_destroy(importedServicesIterator);
+ celixThreadMutex_unlock(&manager->importedServicesLock);
+ }
+
+ if (found) {
+ status = topologyManager_removeImportedService(manager, endpoint, NULL);
+
+ if (status != CELIX_SUCCESS) {
+ logHelper_log(manager->loghelper, OSGI_LOGSERVICE_ERROR, "TOPOLOGY_MANAGER: Removal of imported service (%s; %s) failed.", endpoint->service, endpoint->id);
+ } else {
+ status = topologyManager_addImportedService(manager, endpoint, NULL);
+ }
+ }
+ return status;
+}
+
+celix_status_t topologyManager_addImportedService(void *handle, endpoint_description_pt endpoint, char *matchedFilter) {
+ celix_status_t status = CELIX_SUCCESS;
+ topology_manager_pt manager = handle;
+
+ logHelper_log(manager->loghelper, OSGI_LOGSERVICE_INFO, "TOPOLOGY_MANAGER: Add imported service (%s; %s).", endpoint->service, endpoint->id);
+
+ if (celixThreadMutex_lock(&manager->importedServicesLock) == CELIX_SUCCESS) {
+
+ hash_map_pt imports = hashMap_create(NULL, NULL, NULL, NULL);
+ hashMap_put(manager->importedServices, endpoint, imports);
+
+ if (scope_allowImport(manager->scope, endpoint)) {
+ if (celixThreadMutex_lock(&manager->rsaListLock) == CELIX_SUCCESS) {
+ int size = arrayList_size(manager->rsaList);
+
+ for (int iter = 0; iter < size; iter++) {
+ import_registration_pt import = NULL;
+ remote_service_admin_service_pt rsa = arrayList_get(manager->rsaList, iter);
+ celix_status_t substatus = rsa->importService(rsa->admin, endpoint, &import);
+ if (substatus == CELIX_SUCCESS) {
+ hashMap_put(imports, rsa, import);
+ } else {
+ status = substatus;
+ }
+ }
+ celixThreadMutex_unlock(&manager->rsaListLock);
+ }
+
+ }
+
+ celixThreadMutex_unlock(&manager->importedServicesLock);
+ }
+
+
+ return status;
+}
+
+celix_status_t topologyManager_removeImportedService(void *handle, endpoint_description_pt endpoint, char *matchedFilter) {
+ celix_status_t status = CELIX_SUCCESS;
+ topology_manager_pt manager = handle;
+
+ logHelper_log(manager->loghelper, OSGI_LOGSERVICE_INFO, "TOPOLOGY_MANAGER: Remove imported service (%s; %s).", endpoint->service, endpoint->id);
+
+ if (celixThreadMutex_lock(&manager->importedServicesLock) == CELIX_SUCCESS) {
+
+ hash_map_iterator_pt iter = hashMapIterator_create(manager->importedServices);
+ while (hashMapIterator_hasNext(iter)) {
+ hash_map_entry_pt entry = hashMapIterator_nextEntry(iter);
+ endpoint_description_pt ep = hashMapEntry_getKey(entry);
+ hash_map_pt imports = hashMapEntry_getValue(entry);
+
+ if (imports != NULL && strcmp(endpoint->id, ep->id) == 0) {
+ hash_map_iterator_pt importsIter = hashMapIterator_create(imports);
+
+ while (hashMapIterator_hasNext(importsIter)) {
+ hash_map_entry_pt entry = hashMapIterator_nextEntry(importsIter);
+ remote_service_admin_service_pt rsa = hashMapEntry_getKey(entry);
+ import_registration_pt import = hashMapEntry_getValue(entry);
+ celix_status_t substatus = rsa->importRegistration_close(rsa->admin, import);
+ if (substatus == CELIX_SUCCESS) {
+ hashMapIterator_remove(importsIter);
+ } else {
+ status = substatus;
+ }
+ }
+ hashMapIterator_destroy(importsIter);
+ hashMapIterator_remove(iter);
+
+ hashMap_destroy(imports, false, false);
+ }
+ }
+ hashMapIterator_destroy(iter);
+ celixThreadMutex_unlock(&manager->importedServicesLock);
+ }
+
+ return status;
+}
+
+celix_status_t topologyManager_addExportedService(topology_manager_pt manager, service_reference_pt reference, char *serviceId) {
+ celix_status_t status = CELIX_SUCCESS;
+ properties_pt serviceProperties = NULL;
+
+ logHelper_log(manager->loghelper, OSGI_LOGSERVICE_INFO, "TOPOLOGY_MANAGER: Add exported service (%s).", serviceId);
+
+ if (celixThreadMutex_lock(&manager->exportedServicesLock) == CELIX_SUCCESS) {
+ scope_getExportProperties(manager->scope, reference, &serviceProperties);
+ hash_map_pt exports = hashMap_create(NULL, NULL, NULL, NULL);
+ hashMap_put(manager->exportedServices, reference, exports);
+
+ if (celixThreadMutex_lock(&manager->rsaListLock) == CELIX_SUCCESS) {
+ int size = arrayList_size(manager->rsaList);
+
+ if (size == 0) {
+ logHelper_log(manager->loghelper, OSGI_LOGSERVICE_WARNING, "TOPOLOGY_MANAGER: No RSA available yet.");
+ }
+
+ for (int iter = 0; iter < size; iter++) {
+ remote_service_admin_service_pt rsa = arrayList_get(manager->rsaList, iter);
+
+ array_list_pt endpoints = NULL;
+ celix_status_t substatus = rsa->exportService(rsa->admin, serviceId, serviceProperties, &endpoints);
+
+ if (substatus == CELIX_SUCCESS) {
+ hashMap_put(exports, rsa, endpoints);
+ topologyManager_notifyListenersEndpointAdded(manager, rsa, endpoints);
+ } else {
+ status = substatus;
+ }
+ }
+ celixThreadMutex_unlock(&manager->rsaListLock);
+ }
+ celixThreadMutex_unlock(&manager->exportedServicesLock);
+ }
+
+ return status;
+}
+
+celix_status_t topologyManager_removeExportedService(topology_manager_pt manager, service_reference_pt reference, char *serviceId) {
+ celix_status_t status = CELIX_SUCCESS;
+
+ logHelper_log(manager->loghelper, OSGI_LOGSERVICE_INFO, "TOPOLOGY_MANAGER: Remove exported service (%s).", serviceId);
+
+ if (celixThreadMutex_lock(&manager->exportedServicesLock) == CELIX_SUCCESS) {
+ hash_map_pt exports = hashMap_get(manager->exportedServices, reference);
+ if (exports) {
+ hash_map_iterator_pt iter = hashMapIterator_create(exports);
+ while (hashMapIterator_hasNext(iter)) {
+ hash_map_entry_pt entry = hashMapIterator_nextEntry(iter);
+ remote_service_admin_service_pt rsa = hashMapEntry_getKey(entry);
+ array_list_pt exportRegistrations = hashMapEntry_getValue(entry);
+
+ int size = arrayList_size(exportRegistrations);
+
+ for (int exportsIter = 0; exportsIter < size; exportsIter++) {
+ export_registration_pt export = arrayList_get(exportRegistrations, exportsIter);
+ topologyManager_notifyListenersEndpointRemoved(manager, rsa, export);
+ rsa->exportRegistration_close(rsa->admin, export);
+ }
+
+ hashMap_remove(exports, rsa);
+ //arrayList_destroy(exportRegistrations);
+ hashMapIterator_destroy(iter);
+ iter = hashMapIterator_create(exports);
+
+ }
+ hashMapIterator_destroy(iter);
+ }
+ exports = hashMap_remove(manager->exportedServices, reference);
+
+ if (exports != NULL) {
+ hashMap_destroy(exports, false, false);
+ }
+
+ celixThreadMutex_unlock(&manager->exportedServicesLock);
+ }
+
+ return status;
+}
+
+celix_status_t topologyManager_getEndpointDescriptionForExportRegistration(remote_service_admin_service_pt rsa, export_registration_pt export, endpoint_description_pt *endpoint) {
+ celix_status_t status;
+
+ export_reference_pt reference = NULL;
+ status = rsa->exportRegistration_getExportReference(export, &reference);
+
+ if (status == CELIX_SUCCESS) {
+ status = rsa->exportReference_getExportedEndpoint(reference, endpoint);
+ }
+
+ free(reference);
+
+ return status;
+}
+
+celix_status_t topologyManager_endpointListenerAdding(void* handle, service_reference_pt reference, void** service) {
+ celix_status_t status = CELIX_SUCCESS;
+ topology_manager_pt manager = (topology_manager_pt) handle;
+
+ bundleContext_getService(manager->context, reference, service);
+
+ return status;
+}
+
+celix_status_t topologyManager_endpointListenerAdded(void* handle, service_reference_pt reference, void* service) {
+ celix_status_t status = CELIX_SUCCESS;
+ topology_manager_pt manager = handle;
+ const char* scope = NULL;
+
+ logHelper_log(manager->loghelper, OSGI_LOGSERVICE_INFO, "TOPOLOGY_MANAGER: Added ENDPOINT_LISTENER");
+
+ if (celixThreadMutex_lock(&manager->listenerListLock) == CELIX_SUCCESS) {
+ hashMap_put(manager->listenerList, reference, NULL);
+ celixThreadMutex_unlock(&manager->listenerListLock);
+
+ serviceReference_getProperty(reference, OSGI_ENDPOINT_LISTENER_SCOPE, &scope);
+
+ filter_pt filter = filter_create(scope);
+ hash_map_iterator_pt refIter = hashMapIterator_create(manager->exportedServices);
+
+ while (hashMapIterator_hasNext(refIter)) {
+ hash_map_pt rsaExports = hashMapIterator_nextValue(refIter);
+ hash_map_iterator_pt rsaIter = hashMapIterator_create(rsaExports);
+
+ while (hashMapIterator_hasNext(rsaIter)) {
+ hash_map_entry_pt entry = hashMapIterator_nextEntry(rsaIter);
+ remote_service_admin_service_pt rsa = hashMapEntry_getKey(entry);
+ array_list_pt registrations = hashMapEntry_getValue(entry);
+
+ int arrayListSize = arrayList_size(registrations);
+ int cnt = 0;
+
+ for (; cnt < arrayListSize; cnt++) {
+ export_registration_pt export = arrayList_get(registrations, cnt);
+ endpoint_description_pt endpoint = NULL;
+
+ status = topologyManager_getEndpointDescriptionForExportRegistration(rsa, export, &endpoint);
+ if (status == CELIX_SUCCESS) {
+ bool matchResult = false;
+ filter_match(filter, endpoint->properties, &matchResult);
+ if (matchResult) {
+ endpoint_listener_pt listener = (endpoint_listener_pt) service;
+ status = listener->endpointAdded(listener->handle, endpoint, (char*)scope);
+ }
+ }
+ }
+ }
+ hashMapIterator_destroy(rsaIter);
+ }
+ hashMapIterator_destroy(refIter);
+
+ filter_destroy(filter);
+ }
+
+ return status;
+}
+
+celix_status_t topologyManager_endpointListenerModified(void * handle, service_reference_pt reference, void * service) {
+ celix_status_t status;
+
+ status = topologyManager_endpointListenerRemoved(handle, reference, service);
+
+ if (status == CELIX_SUCCESS) {
+ status = topologyManager_endpointListenerAdded(handle, reference, service);
+ }
+
+ return status;
+}
+
+celix_status_t topologyManager_endpointListenerRemoved(void * handle, service_reference_pt reference, void * service) {
+ celix_status_t status = CELIX_SUCCESS;
+ topology_manager_pt manager = handle;
+
+ if (celixThreadMutex_lock(&manager->listenerListLock) == CELIX_SUCCESS) {
+
+ if (hashMap_remove(manager->listenerList, reference)) {
+ logHelper_log(manager->loghelper, OSGI_LOGSERVICE_INFO, "EndpointListener Removed");
+ }
+
+ celixThreadMutex_unlock(&manager->listenerListLock);
+ }
+
+ return status;
+}
+
+celix_status_t topologyManager_notifyListenersEndpointAdded(topology_manager_pt manager, remote_service_admin_service_pt rsa, array_list_pt registrations) {
+ celix_status_t status = CELIX_SUCCESS;
+
+ if (celixThreadMutex_lock(&manager->listenerListLock) == CELIX_SUCCESS) {
+
+ hash_map_iterator_pt iter = hashMapIterator_create(manager->listenerList);
+ while (hashMapIterator_hasNext(iter)) {
+ const char* scope = NULL;
+ endpoint_listener_pt epl = NULL;
+ service_reference_pt reference = hashMapIterator_nextKey(iter);
+
+ serviceReference_getProperty(reference, OSGI_ENDPOINT_LISTENER_SCOPE, &scope);
+
+ status = bundleContext_getService(manager->context, reference, (void **) &epl);
+ if (status == CELIX_SUCCESS) {
+ filter_pt filter = filter_create(scope);
+
+ int regSize = arrayList_size(registrations);
+ for (int regIt = 0; regIt < regSize; regIt++) {
+ export_registration_pt export = arrayList_get(registrations, regIt);
+ endpoint_description_pt endpoint = NULL;
+ celix_status_t substatus = topologyManager_getEndpointDescriptionForExportRegistration(rsa, export, &endpoint);
+ if (substatus == CELIX_SUCCESS) {
+ bool matchResult = false;
+ filter_match(filter, endpoint->properties, &matchResult);
+ if (matchResult) {
+ status = epl->endpointAdded(epl->handle, endpoint, (char*)scope);
+ }
+ } else {
+ status = substatus;
+ }
+ }
+ filter_destroy(filter);
+ }
+ }
+ hashMapIterator_destroy(iter);
+ celixThreadMutex_unlock(&manager->listenerListLock);
+ }
+
+ return status;
+}
+
+celix_status_t topologyManager_notifyListenersEndpointRemoved(topology_manager_pt manager, remote_service_admin_service_pt rsa, export_registration_pt export) {
+ celix_status_t status = CELIX_SUCCESS;
+
+ if (celixThreadMutex_lock(&manager->listenerListLock) == CELIX_SUCCESS) {
+ hash_map_iterator_pt iter = hashMapIterator_create(manager->listenerList);
+ while (hashMapIterator_hasNext(iter)) {
+ endpoint_description_pt endpoint = NULL;
+ endpoint_listener_pt epl = NULL;
+ celix_status_t substatus;
+ const char* scope = NULL;
+
+ service_reference_pt reference = hashMapIterator_nextKey(iter);
+ serviceReference_getProperty(reference, OSGI_ENDPOINT_LISTENER_SCOPE, &scope);
+
+ substatus = bundleContext_getService(manager->context, reference, (void **) &epl);
+
+ if (substatus == CELIX_SUCCESS) {
+ substatus = topologyManager_getEndpointDescriptionForExportRegistration(rsa, export, &endpoint);
+ }
+
+ if (substatus == CELIX_SUCCESS) {
+ substatus = epl->endpointRemoved(epl->handle, endpoint, NULL);
+ }
+
+ /* if (substatus != CELIX_SUCCESS) {
+ status = substatus;
+
+ }
+ */
+ }
+ hashMapIterator_destroy(iter);
+ celixThreadMutex_unlock(&manager->listenerListLock);
+ }
+
+ return status;
+}
+
+celix_status_t topologyManager_extendFilter(topology_manager_pt manager, char *filter, char **updatedFilter) {
+ celix_status_t status;
+ bundle_context_pt context = manager->context;
+ const char* uuid = NULL;
+
+ status = bundleContext_getProperty(context, OSGI_FRAMEWORK_FRAMEWORK_UUID, &uuid);
+
+ if (!uuid) {
+ logHelper_log(manager->loghelper, OSGI_LOGSERVICE_ERROR, "TOPOLOGY_MANAGER: no framework UUID defined?!");
+ return CELIX_BUNDLE_EXCEPTION;
+ }
+
+ int len = 10 + strlen(filter) + strlen(OSGI_RSA_ENDPOINT_FRAMEWORK_UUID) + strlen(uuid);
+ *updatedFilter = malloc(len);
+ if (!*updatedFilter) {
+ return CELIX_ENOMEM;
+ }
+
+ snprintf(*updatedFilter, len, "(&%s(!(%s=%s)))", filter, OSGI_RSA_ENDPOINT_FRAMEWORK_UUID, uuid);
+
+ return status;
+}
+
+celix_status_t topologyManager_listenerAdded(void *handle, array_list_pt listeners) {
+ celix_status_t status = CELIX_SUCCESS;
+ topology_manager_pt manager = handle;
+
+ for (int i = 0; i < arrayList_size(listeners); i++) {
+ listener_hook_info_pt info = arrayList_get(listeners, i);
+ bundle_pt bundle = NULL, self = NULL;
+ bundleContext_getBundle(info->context, &bundle);
+ bundleContext_getBundle(manager->context, &self);
+ if (bundle == self) {
+ logHelper_log(manager->loghelper, OSGI_LOGSERVICE_DEBUG, "TOPOLOGY_MANAGER: Ignore myself.");
+ continue;
+ }
+
+ logHelper_log(manager->loghelper, OSGI_LOGSERVICE_INFO, "TOPOLOGY_MANAGER: listener with filter \"%s\" added", info->filter);
+
+ char *filter = NULL;
+ bool free_filter = true;
+ status = topologyManager_extendFilter(manager, info->filter, &filter);
+#if 0
+ if(filter != NULL){
+ // TODO: add status handling
+ status = celixThreadMutex_lock(&manager->importScopesLock);
+
+ struct scope *interest = hashMap_get(manager->importScopes, filter);
+ if (interest) {
+ interest->refs++;
+ free(filter);
+ filter = NULL;
+ } else {
+ interest = malloc(sizeof(*interest));
+ interest->filter = filter;
+ interest->refs = 1;
+ hashMap_put(manager->importScopes, filter, interest);
+ free_filter = false;
+ }
+
+ status = celixThreadMutex_unlock(&manager->importScopesLock);
+ }
+#endif
+
+ if (filter != NULL && free_filter) {
+ free(filter);
+ }
+
+ }
+
+ return status;
+}
+
+celix_status_t topologyManager_listenerRemoved(void *handle, array_list_pt listeners) {
+ celix_status_t status = CELIX_SUCCESS;
+ topology_manager_pt manager = handle;
+
+ for (int i = 0; i < arrayList_size(listeners); i++) {
+ listener_hook_info_pt info = arrayList_get(listeners, i);
+
+ bundle_pt bundle = NULL, self = NULL;
+ bundleContext_getBundle(info->context, &bundle);
+ bundleContext_getBundle(manager->context, &self);
+ if (bundle == self) {
+ logHelper_log(manager->loghelper, OSGI_LOGSERVICE_DEBUG, "TOPOLOGY_MANAGER: Ignore myself.");
+ continue;
+ }
+
+ logHelper_log(manager->loghelper, OSGI_LOGSERVICE_INFO, "TOPOLOGY_MANAGER: listener with filter \"%s\" removed.", info->filter);
+
+ char *filter = NULL;
+ topologyManager_extendFilter(manager, info->filter, &filter);
+#if 0
+ status = celixThreadMutex_lock(&manager->importScopesLock);
+
+ struct scope *interest = hashMap_get(manager->importScopes, filter);
+ if (interest != NULL && --interest->refs <= 0) {
+ // last reference, remove from scope
+ hash_map_entry_pt entry = hashMap_getEntry(manager->importScopes, filter);
+ char* key = (char*) hashMapEntry_getKey(entry);
+ interest = hashMap_remove(manager->importScopes, filter);
+ free(key);
+ free(interest);
+ }
+#endif
+
+ if (filter != NULL) {
+ free(filter);
+ }
+#if 0
+ status = celixThreadMutex_unlock(&manager->importScopesLock);
+#endif
+ }
+
+ return status;
+}
+
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/topology_manager/src/topology_manager.h
----------------------------------------------------------------------
diff --git a/remote_services/topology_manager/src/topology_manager.h b/remote_services/topology_manager/src/topology_manager.h
new file mode 100644
index 0000000..7e5e917
--- /dev/null
+++ b/remote_services/topology_manager/src/topology_manager.h
@@ -0,0 +1,65 @@
+/**
+ *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.
+ */
+/*
+ * topology_manager.h
+ *
+ * \date Sep 29, 2011
+ * \author <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ * \copyright Apache License, Version 2.0
+ */
+
+#ifndef TOPOLOGY_MANAGER_H_
+#define TOPOLOGY_MANAGER_H_
+
+#include "endpoint_listener.h"
+#include "service_reference.h"
+#include "bundle_context.h"
+#include "log_helper.h"
+#include "scope.h"
+
+#define OSGI_RSA_REMOTE_SERVICE_ADMIN "remote_service_admin"
+
+typedef struct topology_manager *topology_manager_pt;
+
+celix_status_t topologyManager_create(bundle_context_pt context, log_helper_pt logHelper, topology_manager_pt *manager, void **scope);
+celix_status_t topologyManager_destroy(topology_manager_pt manager);
+celix_status_t topologyManager_closeImports(topology_manager_pt manager);
+
+celix_status_t topologyManager_rsaAdding(void *handle, service_reference_pt reference, void **service);
+celix_status_t topologyManager_rsaAdded(void *handle, service_reference_pt reference, void *service);
+celix_status_t topologyManager_rsaModified(void *handle, service_reference_pt reference, void *service);
+celix_status_t topologyManager_rsaRemoved(void *handle, service_reference_pt reference, void *service);
+
+celix_status_t topologyManager_endpointListenerAdding(void* handle, service_reference_pt reference, void** service);
+celix_status_t topologyManager_endpointListenerAdded(void* handle, service_reference_pt reference, void* service);
+celix_status_t topologyManager_endpointListenerModified(void * handle, service_reference_pt reference, void* service);
+celix_status_t topologyManager_endpointListenerRemoved(void * handle, service_reference_pt reference, void* service);
+
+celix_status_t topologyManager_serviceChanged(void *listener, service_event_pt event);
+
+celix_status_t topologyManager_addImportedService(void *handle, endpoint_description_pt endpoint, char *matchedFilter);
+celix_status_t topologyManager_removeImportedService(void *handle, endpoint_description_pt endpoint, char *matchedFilter);
+
+celix_status_t topologyManager_addExportedService(topology_manager_pt manager, service_reference_pt reference, char *serviceId);
+celix_status_t topologyManager_removeExportedService(topology_manager_pt manager, service_reference_pt reference, char *serviceId);
+
+celix_status_t topologyManager_listenerAdded(void *handle, array_list_pt listeners);
+celix_status_t topologyManager_listenerRemoved(void *handle, array_list_pt listeners);
+
+#endif /* TOPOLOGY_MANAGER_H_ */
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/topology_manager/tms_tst/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/remote_services/topology_manager/tms_tst/CMakeLists.txt b/remote_services/topology_manager/tms_tst/CMakeLists.txt
index dc671e4..6d0713c 100644
--- a/remote_services/topology_manager/tms_tst/CMakeLists.txt
+++ b/remote_services/topology_manager/tms_tst/CMakeLists.txt
@@ -36,10 +36,8 @@ SET(CMAKE_INSTALL_RPATH "${PROJECT_BINARY_DIR}/framework" "${PROJECT_BINARY_DIR}
add_executable(test_tm_scoped
run_tests.cpp
tms_tests.cpp
-
- ${PROJECT_SOURCE_DIR}/remote_services/remote_service_admin/private/src/endpoint_description.c
)
-target_link_libraries(test_tm_scoped Celix::framework ${CPPUTEST_LIBRARY} ${JANSSON_LIBRARY} Celix::log_helper)
+target_link_libraries(test_tm_scoped Celix::framework ${CPPUTEST_LIBRARY} ${JANSSON_LIBRARY} Celix::log_helper remote_service_admin_common)
add_dependencies(test_tm_scoped remote_service_admin_dfi topology_manager calculator)
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/topology_manager/tms_tst/bundle/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/remote_services/topology_manager/tms_tst/bundle/CMakeLists.txt b/remote_services/topology_manager/tms_tst/bundle/CMakeLists.txt
index 9e36e4c..fc9d9bf 100644
--- a/remote_services/topology_manager/tms_tst/bundle/CMakeLists.txt
+++ b/remote_services/topology_manager/tms_tst/bundle/CMakeLists.txt
@@ -32,4 +32,4 @@ bundle_files(topology_manager_test_bundle
DESTINATION .
)
-target_link_libraries(topology_manager_test_bundle PRIVATE ${CPPUTEST_LIBRARY})
+target_link_libraries(topology_manager_test_bundle PRIVATE ${CPPUTEST_LIBRARY} remote_service_admin calculator_api)
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/topology_manager/tms_tst/disc_mock/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/remote_services/topology_manager/tms_tst/disc_mock/CMakeLists.txt b/remote_services/topology_manager/tms_tst/disc_mock/CMakeLists.txt
index b961de7..bfd7fc1 100644
--- a/remote_services/topology_manager/tms_tst/disc_mock/CMakeLists.txt
+++ b/remote_services/topology_manager/tms_tst/disc_mock/CMakeLists.txt
@@ -15,14 +15,6 @@
# specific language governing permissions and limitations
# under the License.
-include_directories(
- ${CPPUTEST_INCLUDE_DIR}
- ${PROJECT_SOURCE_DIR}/framework/public/include
- ${PROJECT_SOURCE_DIR}/utils/public/include
- ${PROJECT_SOURCE_DIR}/remote_services/discovery/private/include
-)
-
-
add_bundle(topology_manager_disc_mock_bundle
VERSION 0.0.1
SOURCES
@@ -30,4 +22,5 @@ add_bundle(topology_manager_disc_mock_bundle
disc_mock_service.c
)
-target_link_libraries(topology_manager_disc_mock_bundle PRIVATE ${CPPUTEST_LIBRARY} Celix::framework)
+target_include_directories(topology_manager_disc_mock_bundle PRIVATE ${CPPUTEST_INCLUDE_DIR})
+target_link_libraries(topology_manager_disc_mock_bundle PRIVATE ${CPPUTEST_LIBRARY} Celix::framework discovery_common)
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/utils/private/include/civetweb.h
----------------------------------------------------------------------
diff --git a/remote_services/utils/private/include/civetweb.h b/remote_services/utils/private/include/civetweb.h
deleted file mode 100644
index 61a8e98..0000000
--- a/remote_services/utils/private/include/civetweb.h
+++ /dev/null
@@ -1,657 +0,0 @@
-/* Copyright (c) 2013-2014 the Civetweb developers
- * Copyright (c) 2004-2013 Sergey Lyubka
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#ifndef CIVETWEB_HEADER_INCLUDED
-#define CIVETWEB_HEADER_INCLUDED
-
-#ifndef CIVETWEB_VERSION
-#define CIVETWEB_VERSION "1.7"
-#endif
-
-#ifndef CIVETWEB_API
- #if defined(_WIN32)
- #if defined(CIVETWEB_DLL_EXPORTS)
- #define CIVETWEB_API __declspec(dllexport)
- #elif defined(CIVETWEB_DLL_IMPORTS)
- #define CIVETWEB_API __declspec(dllimport)
- #else
- #define CIVETWEB_API
- #endif
- #else
- #define CIVETWEB_API
- #endif
-#endif
-
-#include <stdio.h>
-#include <stddef.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif /* __cplusplus */
-
-struct mg_context; /* Handle for the HTTP service itself */
-struct mg_connection; /* Handle for the individual connection */
-
-
-/* This structure contains information about the HTTP request. */
-struct mg_request_info {
- const char *request_method; /* "GET", "POST", etc */
- const char *uri; /* URL-decoded URI */
- const char *http_version; /* E.g. "1.0", "1.1" */
- const char *query_string; /* URL part after '?', not including '?', or
- NULL */
- const char *remote_user; /* Authenticated user, or NULL if no auth
- used */
- char remote_addr[48]; /* Client's IP address as a string. */
- long remote_ip; /* Client's IP address. Deprecated: use remote_addr instead */
-
- long long content_length; /* Length (in bytes) of the request body,
- can be -1 if no length was given. */
- int remote_port; /* Client's port */
- int is_ssl; /* 1 if SSL-ed, 0 if not */
- void *user_data; /* User data pointer passed to mg_start() */
- void *conn_data; /* Connection-specific user data */
-
- int num_headers; /* Number of HTTP headers */
- struct mg_header {
- const char *name; /* HTTP header name */
- const char *value; /* HTTP header value */
- } http_headers[64]; /* Maximum 64 headers */
-};
-
-
-/* This structure needs to be passed to mg_start(), to let civetweb know
- which callbacks to invoke. For a detailed description, see
- https://github.com/bel2125/civetweb/blob/master/docs/UserManual.md */
-struct mg_callbacks {
- /* Called when civetweb has received new HTTP request.
- If the callback returns one, it must process the request
- by sending valid HTTP headers and a body. Civetweb will not do
- any further processing. Otherwise it must return zero.
- Note that since V1.7 the "begin_request" function is called
- before an authorization check. If an authorization check is
- required, use a request_handler instead.
- Return value:
- 0: civetweb will process the request itself. In this case,
- the callback must not send any data to the client.
- 1: callback already processed the request. Civetweb will
- not send any data after the callback returned. */
- int (*begin_request)(struct mg_connection *);
-
- /* Called when civetweb has finished processing request. */
- void (*end_request)(const struct mg_connection *, int reply_status_code);
-
- /* Called when civetweb is about to log a message. If callback returns
- non-zero, civetweb does not log anything. */
- int (*log_message)(const struct mg_connection *, const char *message);
-
- /* Called when civetweb initializes SSL library.
- Parameters:
- user_data: parameter user_data passed when starting the server.
- Return value:
- 0: civetweb will set up the SSL certificate.
- 1: civetweb assumes the callback already set up the certificate.
- -1: initializing ssl fails. */
- int (*init_ssl)(void *ssl_context, void *user_data);
-
- /* Called when websocket request is received, before websocket handshake.
- Return value:
- 0: civetweb proceeds with websocket handshake.
- 1: connection is closed immediately. */
- int (*websocket_connect)(const struct mg_connection *);
-
- /* Called when websocket handshake is successfully completed, and
- connection is ready for data exchange. */
- void (*websocket_ready)(struct mg_connection *);
-
- /* Called when data frame has been received from the client.
- Parameters:
- bits: first byte of the websocket frame, see websocket RFC at
- http://tools.ietf.org/html/rfc6455, section 5.2
- data, data_len: payload, with mask (if any) already applied.
- Return value:
- 1: keep this websocket connection open.
- 0: close this websocket connection. */
- int (*websocket_data)(struct mg_connection *, int bits,
- char *data, size_t data_len);
-
- /* Called when civetweb is closing a connection. The per-context mutex is
- locked when this is invoked. This is primarily useful for noting when
- a websocket is closing and removing it from any application-maintained
- list of clients. */
- void (*connection_close)(struct mg_connection *);
-
- /* Called when civetweb tries to open a file. Used to intercept file open
- calls, and serve file data from memory instead.
- Parameters:
- path: Full path to the file to open.
- data_len: Placeholder for the file size, if file is served from
- memory.
- Return value:
- NULL: do not serve file from memory, proceed with normal file open.
- non-NULL: pointer to the file contents in memory. data_len must be
- initilized with the size of the memory block. */
- const char * (*open_file)(const struct mg_connection *,
- const char *path, size_t *data_len);
-
- /* Called when civetweb is about to serve Lua server page, if
- Lua support is enabled.
- Parameters:
- lua_context: "lua_State *" pointer. */
- void (*init_lua)(struct mg_connection *, void *lua_context);
-
- /* Called when civetweb has uploaded a file to a temporary directory as a
- result of mg_upload() call.
- Parameters:
- file_name: full path name to the uploaded file. */
- void (*upload)(struct mg_connection *, const char *file_name);
-
- /* Called when civetweb is about to send HTTP error to the client.
- Implementing this callback allows to create custom error pages.
- Parameters:
- status: HTTP error status code.
- Return value:
- 1: run civetweb error handler.
- 0: callback already handled the error. */
- int (*http_error)(struct mg_connection *, int status);
-
- /* Called after civetweb context has been created, before requests
- are processed.
- Parameters:
- ctx: context handle */
- void (*init_context)(struct mg_context * ctx);
-
- /* Called when civetweb context is deleted.
- Parameters:
- ctx: context handle */
- void (*exit_context)(struct mg_context * ctx);
-};
-
-
-/* Start web server.
-
- Parameters:
- callbacks: mg_callbacks structure with user-defined callbacks.
- options: NULL terminated list of option_name, option_value pairs that
- specify Civetweb configuration parameters.
-
- Side-effects: on UNIX, ignores SIGCHLD and SIGPIPE signals. If custom
- processing is required for these, signal handlers must be set up
- after calling mg_start().
-
-
- Example:
- const char *options[] = {
- "document_root", "/var/www",
- "listening_ports", "80,443s",
- NULL
- };
- struct mg_context *ctx = mg_start(&my_func, NULL, options);
-
- Refer to https://github.com/bel2125/civetweb/blob/master/docs/UserManual.md
- for the list of valid option and their possible values.
-
- Return:
- web server context, or NULL on error. */
-CIVETWEB_API struct mg_context *mg_start(const struct mg_callbacks *callbacks,
- void *user_data,
- const char **configuration_options);
-
-
-/* Stop the web server.
-
- Must be called last, when an application wants to stop the web server and
- release all associated resources. This function blocks until all Civetweb
- threads are stopped. Context pointer becomes invalid. */
-CIVETWEB_API void mg_stop(struct mg_context *);
-
-
-/* mg_request_handler
-
- Called when a new request comes in. This callback is URI based
- and configured with mg_set_request_handler().
-
- Parameters:
- conn: current connection information.
- cbdata: the callback data configured with mg_set_request_handler().
- Returns:
- 0: the handler could not handle the request, so fall through.
- 1: the handler processed the request. */
-typedef int (* mg_request_handler)(struct mg_connection *conn, void *cbdata);
-
-
-/* mg_set_request_handler
-
- Sets or removes a URI mapping for a request handler.
-
- URI's are ordered and prefixed URI's are supported. For example,
- consider two URIs: /a/b and /a
- /a matches /a
- /a/b matches /a/b
- /a/c matches /a
-
- Parameters:
- ctx: server context
- uri: the URI to configure
- handler: the callback handler to use when the URI is requested.
- If NULL, the URI will be removed.
- cbdata: the callback data to give to the handler when it s requested. */
-CIVETWEB_API void mg_set_request_handler(struct mg_context *ctx, const char *uri, mg_request_handler handler, void *cbdata);
-
-
-/* Get the value of particular configuration parameter.
- The value returned is read-only. Civetweb does not allow changing
- configuration at run time.
- If given parameter name is not valid, NULL is returned. For valid
- names, return value is guaranteed to be non-NULL. If parameter is not
- set, zero-length string is returned. */
-CIVETWEB_API const char *mg_get_option(const struct mg_context *ctx, const char *name);
-
-
-/* Get context from connection. */
-CIVETWEB_API struct mg_context *mg_get_context(struct mg_connection *conn);
-
-
-/* Get user data passed to mg_start from context. */
-CIVETWEB_API void *mg_get_user_data(struct mg_context *ctx);
-
-
-#if defined(MG_LEGACY_INTERFACE)
-/* Return array of strings that represent valid configuration options.
- For each option, option name and default value is returned, i.e. the
- number of entries in the array equals to number_of_options x 2.
- Array is NULL terminated. */
-/* Deprecated: Use mg_get_valid_options instead. */
-CIVETWEB_API const char **mg_get_valid_option_names(void);
-#endif
-
-
-struct mg_option {
- const char * name;
- int type;
- const char * default_value;
-};
-
-enum {
- CONFIG_TYPE_UNKNOWN = 0x0,
- CONFIG_TYPE_NUMBER = 0x1,
- CONFIG_TYPE_STRING = 0x2,
- CONFIG_TYPE_FILE = 0x3,
- CONFIG_TYPE_DIRECTORY = 0x4,
- CONFIG_TYPE_BOOLEAN = 0x5,
- CONFIG_TYPE_EXT_PATTERN = 0x6
-};
-
-
-/* Return array of struct mg_option, representing all valid configuration
- options of civetweb.c.
- The array is terminated by a NULL name option. */
-CIVETWEB_API const struct mg_option *mg_get_valid_options(void);
-
-
-/* Get the list of ports that civetweb is listening on.
- size is the size of the ports int array and ssl int array to fill.
- It is the caller's responsibility to make sure ports and ssl each
- contain at least size int elements worth of memory to write into.
- Return value is the number of ports and ssl information filled in.
- The value returned is read-only. Civetweb does not allow changing
- configuration at run time. */
-CIVETWEB_API size_t mg_get_ports(const struct mg_context *ctx, size_t size, int* ports, int* ssl);
-
-
-/* Add, edit or delete the entry in the passwords file.
-
- This function allows an application to manipulate .htpasswd files on the
- fly by adding, deleting and changing user records. This is one of the
- several ways of implementing authentication on the server side. For another,
- cookie-based way please refer to the examples/chat in the source tree.
-
- If password is not NULL, entry is added (or modified if already exists).
- If password is NULL, entry is deleted.
-
- Return:
- 1 on success, 0 on error. */
-CIVETWEB_API int mg_modify_passwords_file(const char *passwords_file_name,
- const char *domain,
- const char *user,
- const char *password);
-
-
-/* Return information associated with the request. */
-CIVETWEB_API struct mg_request_info *mg_get_request_info(struct mg_connection *);
-
-
-/* Send data to the client.
- Return:
- 0 when the connection has been closed
- -1 on error
- >0 number of bytes written on success */
-CIVETWEB_API int mg_write(struct mg_connection *, const void *buf, size_t len);
-
-
-/* Send data to a websocket client wrapped in a websocket frame. Uses mg_lock
- to ensure that the transmission is not interrupted, i.e., when the
- application is proactively communicating and responding to a request
- simultaneously.
-
- Send data to a websocket client wrapped in a websocket frame.
- This function is available when civetweb is compiled with -DUSE_WEBSOCKET
-
- Return:
- 0 when the connection has been closed
- -1 on error
- >0 number of bytes written on success */
-CIVETWEB_API int mg_websocket_write(struct mg_connection* conn, int opcode,
- const char *data, size_t data_len);
-
-
-/* Blocks until unique access is obtained to this connection. Intended for use
- with websockets only.
- Invoke this before mg_write or mg_printf when communicating with a
- websocket if your code has server-initiated communication as well as
- communication in direct response to a message. */
-CIVETWEB_API void mg_lock_connection(struct mg_connection* conn);
-CIVETWEB_API void mg_unlock_connection(struct mg_connection* conn);
-
-#if defined(MG_LEGACY_INTERFACE)
-#define mg_lock mg_lock_connection
-#define mg_unlock mg_unlock_connection
-#endif
-
-/* Lock server context. This lock may be used to protect ressources
- that are shared between different connection/worker threads. */
-CIVETWEB_API void mg_lock_context(struct mg_context* ctx);
-CIVETWEB_API void mg_unlock_context(struct mg_context* ctx);
-
-
-/* Opcodes, from http://tools.ietf.org/html/rfc6455 */
-enum {
- WEBSOCKET_OPCODE_CONTINUATION = 0x0,
- WEBSOCKET_OPCODE_TEXT = 0x1,
- WEBSOCKET_OPCODE_BINARY = 0x2,
- WEBSOCKET_OPCODE_CONNECTION_CLOSE = 0x8,
- WEBSOCKET_OPCODE_PING = 0x9,
- WEBSOCKET_OPCODE_PONG = 0xa
-};
-
-
-/* Macros for enabling compiler-specific checks forprintf-like arguments. */
-#undef PRINTF_FORMAT_STRING
-#if defined(_MSC_VER) && _MSC_VER >= 1400
-#include <sal.h>
-#if defined(_MSC_VER) && _MSC_VER > 1400
-#define PRINTF_FORMAT_STRING(s) _Printf_format_string_ s
-#else
-#define PRINTF_FORMAT_STRING(s) __format_string s
-#endif
-#else
-#define PRINTF_FORMAT_STRING(s) s
-#endif
-
-#ifdef __GNUC__
-#define PRINTF_ARGS(x, y) __attribute__((format(printf, x, y)))
-#else
-#define PRINTF_ARGS(x, y)
-#endif
-
-/* Send data to the client usingprintf() semantics.
- Works exactly like mg_write(), but allows to do message formatting. */
-CIVETWEB_API int mg_printf(struct mg_connection *,
- PRINTF_FORMAT_STRING(const char *fmt), ...) PRINTF_ARGS(2, 3);
-
-
-/* Send contents of the entire file together with HTTP headers. */
-CIVETWEB_API void mg_send_file(struct mg_connection *conn, const char *path);
-
-
-/* Read data from the remote end, return number of bytes read.
- Return:
- 0 connection has been closed by peer. No more data could be read.
- < 0 read error. No more data could be read from the connection.
- > 0 number of bytes read into the buffer. */
-CIVETWEB_API int mg_read(struct mg_connection *, void *buf, size_t len);
-
-
-/* Get the value of particular HTTP header.
-
- This is a helper function. It traverses request_info->http_headers array,
- and if the header is present in the array, returns its value. If it is
- not present, NULL is returned. */
-CIVETWEB_API const char *mg_get_header(const struct mg_connection *, const char *name);
-
-
-/* Get a value of particular form variable.
-
- Parameters:
- data: pointer to form-uri-encoded buffer. This could be either POST data,
- or request_info.query_string.
- data_len: length of the encoded data.
- var_name: variable name to decode from the buffer
- dst: destination buffer for the decoded variable
- dst_len: length of the destination buffer
-
- Return:
- On success, length of the decoded variable.
- On error:
- -1 (variable not found).
- -2 (destination buffer is NULL, zero length or too small to hold the
- decoded variable).
-
- Destination buffer is guaranteed to be '\0' - terminated if it is not
- NULL or zero length. */
-CIVETWEB_API int mg_get_var(const char *data, size_t data_len,
- const char *var_name, char *dst, size_t dst_len);
-
-
-/* Get a value of particular form variable.
-
- Parameters:
- data: pointer to form-uri-encoded buffer. This could be either POST data,
- or request_info.query_string.
- data_len: length of the encoded data.
- var_name: variable name to decode from the buffer
- dst: destination buffer for the decoded variable
- dst_len: length of the destination buffer
- occurrence: which occurrence of the variable, 0 is the first, 1 the
- second...
- this makes it possible to parse a query like
- b=x&a=y&a=z which will have occurrence values b:0, a:0 and a:1
-
- Return:
- On success, length of the decoded variable.
- On error:
- -1 (variable not found).
- -2 (destination buffer is NULL, zero length or too small to hold the
- decoded variable).
-
- Destination buffer is guaranteed to be '\0' - terminated if it is not
- NULL or zero length. */
-CIVETWEB_API int mg_get_var2(const char *data, size_t data_len,
- const char *var_name, char *dst, size_t dst_len, size_t occurrence);
-
-
-/* Fetch value of certain cookie variable into the destination buffer.
-
- Destination buffer is guaranteed to be '\0' - terminated. In case of
- failure, dst[0] == '\0'. Note that RFC allows many occurrences of the same
- parameter. This function returns only first occurrence.
-
- Return:
- On success, value length.
- On error:
- -1 (either "Cookie:" header is not present at all or the requested
- parameter is not found).
- -2 (destination buffer is NULL, zero length or too small to hold the
- value). */
-CIVETWEB_API int mg_get_cookie(const char *cookie, const char *var_name,
- char *buf, size_t buf_len);
-
-
-/* Download data from the remote web server.
- host: host name to connect to, e.g. "foo.com", or "10.12.40.1".
- port: port number, e.g. 80.
- use_ssl: wether to use SSL connection.
- error_buffer, error_buffer_size: error message placeholder.
- request_fmt,...: HTTP request.
- Return:
- On success, valid pointer to the new connection, suitable for mg_read().
- On error, NULL. error_buffer contains error message.
- Example:
- char ebuf[100];
- struct mg_connection *conn;
- conn = mg_download("google.com", 80, 0, ebuf, sizeof(ebuf),
- "%s", "GET / HTTP/1.0\r\nHost: google.com\r\n\r\n");
- */
-CIVETWEB_API struct mg_connection *mg_download(const char *host, int port, int use_ssl,
- char *error_buffer, size_t error_buffer_size,
- PRINTF_FORMAT_STRING(const char *request_fmt),
- ...) PRINTF_ARGS(6, 7);
-
-
-/* Close the connection opened by mg_download(). */
-CIVETWEB_API void mg_close_connection(struct mg_connection *conn);
-
-
-/* File upload functionality. Each uploaded file gets saved into a temporary
- file and MG_UPLOAD event is sent.
- Return number of uploaded files. */
-CIVETWEB_API int mg_upload(struct mg_connection *conn, const char *destination_dir);
-
-
-/* Convenience function -- create detached thread.
- Return: 0 on success, non-0 on error. */
-typedef void * (*mg_thread_func_t)(void *);
-CIVETWEB_API int mg_start_thread(mg_thread_func_t f, void *p);
-
-
-/* Return builtin mime type for the given file name.
- For unrecognized extensions, "text/plain" is returned. */
-CIVETWEB_API const char *mg_get_builtin_mime_type(const char *file_name);
-
-
-/* Return Civetweb version. */
-CIVETWEB_API const char *mg_version(void);
-
-
-/* URL-decode input buffer into destination buffer.
- 0-terminate the destination buffer.
- form-url-encoded data differs from URI encoding in a way that it
- uses '+' as character for space, see RFC 1866 section 8.2.1
- http://ftp.ics.uci.edu/pub/ietf/html/rfc1866.txt
- Return: length of the decoded data, or -1 if dst buffer is too small. */
-CIVETWEB_API int mg_url_decode(const char *src, int src_len, char *dst,
- int dst_len, int is_form_url_encoded);
-
-
-/* URL-encode input buffer into destination buffer.
- returns the length of the resulting buffer or -1
- is the buffer is too small. */
-CIVETWEB_API int mg_url_encode(const char *src, char *dst, size_t dst_len);
-
-
-/* MD5 hash given strings.
- Buffer 'buf' must be 33 bytes long. Varargs is a NULL terminated list of
- ASCIIz strings. When function returns, buf will contain human-readable
- MD5 hash. Example:
- char buf[33];
- mg_md5(buf, "aa", "bb", NULL); */
-CIVETWEB_API char *mg_md5(char buf[33], ...);
-
-
-/* Print error message to the opened error log stream.
- This utilizes the provided logging configuration.
- conn: connection
- fmt: format string without the line return
- ...: variable argument list
- Example:
- mg_cry(conn,"i like %s", "logging"); */
-CIVETWEB_API void mg_cry(struct mg_connection *conn,
- PRINTF_FORMAT_STRING(const char *fmt), ...) PRINTF_ARGS(2, 3);
-
-
-/* utility method to compare two buffers, case incensitive. */
-CIVETWEB_API int mg_strncasecmp(const char *s1, const char *s2, size_t len);
-
-/* Connect to a websocket as a client
- Parameters:
- host: host to connect to, i.e. "echo.websocket.org" or "192.168.1.1" or "localhost"
- port: server port
- use_ssl: make a secure connection to server
- error_buffer, error_buffer_size: buffer for an error message
- path: server path you are trying to connect to, i.e. if connection to localhost/app, path should be "/app"
- origin: value of the Origin HTTP header
- data_func: callback that should be used when data is received from the server
- user_data: user supplied argument
-
- Return:
- On success, valid mg_connection object.
- On error, NULL. Se error_buffer for details.
-*/
-
-typedef int (*websocket_data_func)(struct mg_connection *, int bits,
- char *data, size_t data_len);
-
-typedef void (*websocket_close_func)(struct mg_connection *);
-
-CIVETWEB_API struct mg_connection *mg_connect_websocket_client(const char *host, int port, int use_ssl,
- char *error_buffer, size_t error_buffer_size,
- const char *path, const char *origin,
- websocket_data_func data_func, websocket_close_func close_func,
- void * user_data);
-
-/* Connect to a TCP server as a client (can be used to connect to a HTTP server)
- Parameters:
- host: host to connect to, i.e. "www.wikipedia.org" or "192.168.1.1" or "localhost"
- port: server port
- use_ssl: make a secure connection to server
- error_buffer, error_buffer_size: buffer for an error message
-
- Return:
- On success, valid mg_connection object.
- On error, NULL. Se error_buffer for details.
-*/
-CIVETWEB_API struct mg_connection *mg_connect_client(const char *host, int port, int use_ssl,
- char *error_buffer, size_t error_buffer_size);
-
-
-enum {
- TIMEOUT_INFINITE = -1
-};
-
-/* Wait for a response from the server
- Parameters:
- conn: connection
- ebuf, ebuf_len: error message placeholder.
- timeout: time to wait for a response in milliseconds (if < 0 then wait forever)
-
- Return:
- On success, >= 0
- On error/timeout, < 0
-*/
-CIVETWEB_API int mg_get_response(struct mg_connection *conn, char *ebuf, size_t ebuf_len, int timeout);
-
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#endif /* CIVETWEB_HEADER_INCLUDED */
[08/19] celix git commit: CELIX-417: Refactor for CMake usage in RSA,
PSA and Docker. mostly trying to identify the api and common libraries
Posted by pn...@apache.org.
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/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
deleted file mode 100644
index 1c684e7..0000000
--- a/remote_services/remote_service_admin/private/src/export_registration_impl.c
+++ /dev/null
@@ -1,257 +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.
- */
-/*
- * export_registration_impl.c
- *
- * \date Oct 6, 2011
- * \author <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- * \copyright Apache License, Version 2.0
- */
-#include <stdlib.h>
-
-#include "constants.h"
-
-#include "celix_errno.h"
-
-#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);
-celix_status_t exportRegistration_endpointRemoved(void * handle, service_reference_pt reference, void *service);
-
-celix_status_t exportRegistration_createEndpointTracker(export_registration_pt registration, service_tracker_pt *tracker);
-
-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 status = CELIX_SUCCESS;
-
- *registration = calloc(1, sizeof(**registration));
- if (!*registration) {
- status = CELIX_ENOMEM;
- } else {
- (*registration)->context = context;
- (*registration)->closed = false;
- (*registration)->endpointDescription = endpoint;
- (*registration)->reference = reference;
- (*registration)->rsa = rsa;
- (*registration)->tracker = NULL;
- (*registration)->endpoint = NULL;
- (*registration)->endpointTracker = NULL;
- (*registration)->exportReference = NULL;
- (*registration)->bundle = NULL;
- (*registration)->loghelper = helper;
- }
-
- return status;
-}
-
-celix_status_t exportRegistration_destroy(export_registration_pt *registration) {
- celix_status_t status = CELIX_SUCCESS;
-
- remoteServiceAdmin_destroyEndpointDescription(&(*registration)->endpointDescription);
- free(*registration);
-
- return status;
-}
-
-celix_status_t exportRegistration_startTracking(export_registration_pt registration) {
- celix_status_t status = CELIX_SUCCESS;
-
- if (registration->endpointTracker == NULL) {
- status = exportRegistration_createEndpointTracker(registration, ®istration->endpointTracker);
- if (status == CELIX_SUCCESS) {
- status = serviceTracker_open(registration->endpointTracker);
- }
- }
-
- return status;
-}
-
-celix_status_t exportRegistration_stopTracking(export_registration_pt registration) {
- celix_status_t status = CELIX_SUCCESS;
-
- if (registration->endpointTracker != NULL) {
- status = serviceTracker_close(registration->endpointTracker);
- if (status != CELIX_SUCCESS) {
- logHelper_log(registration->loghelper, OSGI_LOGSERVICE_ERROR, "EXPORT_REGISTRATION: Could not close endpoint tracker");
- }
- else {
- status = serviceTracker_destroy(registration->endpointTracker);
- }
- }
- if (registration->tracker != NULL) {
- status = serviceTracker_close(registration->tracker);
- if (status != CELIX_SUCCESS) {
- logHelper_log(registration->loghelper, OSGI_LOGSERVICE_ERROR, "EXPORT_REGISTRATION: Could not close service tracker");
- }
- else {
- status = serviceTracker_destroy(registration->tracker);
- }
- }
-
- return status;
-}
-
-celix_status_t exportRegistration_createEndpointTracker(export_registration_pt registration, service_tracker_pt *tracker) {
- celix_status_t status;
-
- service_tracker_customizer_pt customizer = NULL;
-
- status = serviceTrackerCustomizer_create(registration, exportRegistration_endpointAdding,
- exportRegistration_endpointAdded, exportRegistration_endpointModified, exportRegistration_endpointRemoved, &customizer);
-
- if (status == CELIX_SUCCESS) {
- char filter[512];
-
- snprintf(filter, 512, "(&(%s=%s)(remote.interface=%s))", (char*) OSGI_FRAMEWORK_OBJECTCLASS, (char*) OSGI_RSA_REMOTE_ENDPOINT, registration->endpointDescription->service);
- status = serviceTracker_createWithFilter(registration->context, filter, customizer, tracker);
- }
-
- return status;
-}
-
-celix_status_t exportRegistration_endpointAdding(void * handle, service_reference_pt reference, void **service) {
- celix_status_t status;
- export_registration_pt registration = handle;
-
- status = bundleContext_getService(registration->context, reference, service);
-
- return status;
-}
-
-celix_status_t exportRegistration_endpointAdded(void * handle, service_reference_pt reference, void *endpoint_service) {
- celix_status_t status = CELIX_SUCCESS;
- export_registration_pt registration = handle;
-
- remote_endpoint_service_pt endpoint = endpoint_service;
- if (registration->endpoint == NULL) {
- registration->endpoint = endpoint;
- void *service = NULL;
- status = bundleContext_getService(registration->context, registration->reference, &service);
- if (status == CELIX_SUCCESS) {
- endpoint->setService(endpoint->endpoint, service);
- }
- }
-
- return status;
-}
-
-celix_status_t exportRegistration_endpointModified(void * handle, service_reference_pt reference, void *service) {
- celix_status_t status = CELIX_SUCCESS;
-
- return status;
-}
-
-celix_status_t exportRegistration_endpointRemoved(void * handle, service_reference_pt reference, void *service) {
- celix_status_t status = CELIX_SUCCESS;
- export_registration_pt registration = handle;
-
- remote_endpoint_service_pt endpoint = service;
- if (registration->endpoint != NULL) {
- endpoint->setService(endpoint->endpoint, NULL);
- }
-
- return status;
-}
-
-celix_status_t exportRegistration_open(export_registration_pt registration) {
- celix_status_t status = CELIX_SUCCESS;
- const char *bundleStore = NULL;
-
- bundleContext_getProperty(registration->context, BUNDLE_STORE_PROPERTY_NAME, &bundleStore);
-
- if (bundleStore == NULL) {
- bundleStore = DEFAULT_BUNDLE_STORE;
- }
- char name[256];
-
- snprintf(name, 256, "%s/%s_endpoint.zip", bundleStore, registration->endpointDescription->service);
-
- status = bundleContext_installBundle(registration->context, name, ®istration->bundle);
- if (status == CELIX_SUCCESS) {
- status = bundle_start(registration->bundle);
- if (status == CELIX_SUCCESS) {
- }
- }
-
- return status;
-}
-
-celix_status_t exportRegistration_close(export_registration_pt registration) {
- celix_status_t status = CELIX_SUCCESS;
-
- exportRegistration_stopTracking(registration);
-
- bundle_uninstall(registration->bundle);
-
-
- return status;
-}
-
-celix_status_t exportRegistration_getException(export_registration_pt registration) {
- celix_status_t status = CELIX_SUCCESS;
- return status;
-}
-
-celix_status_t exportRegistration_getExportReference(export_registration_pt registration, export_reference_pt *reference) {
- celix_status_t status = CELIX_SUCCESS;
-
- registration->exportReference = calloc(1, sizeof(*registration->exportReference));
-
- if (registration->exportReference == NULL) {
- status = CELIX_ENOMEM;
- } else {
- registration->exportReference->endpoint = registration->endpointDescription;
- registration->exportReference->reference = registration->reference;
- }
-
- *reference = registration->exportReference;
-
- return status;
-}
-
-celix_status_t exportRegistration_setEndpointDescription(export_registration_pt registration, endpoint_description_pt endpointDescription) {
- celix_status_t status = CELIX_SUCCESS;
-
- registration->endpointDescription = endpointDescription;
-
- 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, service_reference_pt *service) {
- celix_status_t status = CELIX_SUCCESS;
- *service = reference->reference;
- return status;
-}
-
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/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
deleted file mode 100644
index 9a84327..0000000
--- a/remote_services/remote_service_admin/private/src/import_registration_impl.c
+++ /dev/null
@@ -1,274 +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.
- */
-/*
- * import_registration_impl.c
- *
- * \date Oct 14, 2011
- * \author <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- * \copyright Apache License, Version 2.0
- */
-
-#include <stdlib.h>
-#include <string.h>
-
-#include <constants.h>
-
-#include "celix_errno.h"
-
-#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);
-celix_status_t importRegistration_proxyFactoryModified(void * handle, service_reference_pt reference, void *service);
-celix_status_t importRegistration_proxyFactoryRemoved(void * handle, service_reference_pt reference, void *service);
-
-celix_status_t importRegistration_create(endpoint_description_pt endpoint, remote_service_admin_pt rsa, sendToHandle sendToCallback, bundle_context_pt context, import_registration_pt *registration) {
- celix_status_t status = CELIX_SUCCESS;
-
- *registration = calloc(1, sizeof(**registration));
- if (!*registration) {
- status = CELIX_ENOMEM;
- } else {
- (*registration)->context = context;
- (*registration)->closed = false;
- (*registration)->endpointDescription = endpoint;
- (*registration)->rsa = rsa;
- (*registration)->sendToCallback = sendToCallback;
- (*registration)->reference = NULL;
- (*registration)->importReference = NULL;
- }
-
- return status;
-}
-
-celix_status_t importRegistration_destroy(import_registration_pt registration)
-{
- free(registration);
-
- return CELIX_SUCCESS;
-}
-
-
-celix_status_t importRegistrationFactory_create(log_helper_pt helper, char* serviceName, bundle_context_pt context, import_registration_factory_pt *registration_factory) {
- celix_status_t status = CELIX_SUCCESS;
-
- *registration_factory = calloc(1, sizeof(**registration_factory));
- if (!*registration_factory) {
- status = CELIX_ENOMEM;
- } else {
- (*registration_factory)->serviceName = strdup(serviceName);
- (*registration_factory)->context = context;
- (*registration_factory)->bundle = NULL;
- (*registration_factory)->loghelper = helper;
-
- arrayList_create(&(*registration_factory)->registrations);
- }
-
- return status;
-}
-
-
-
-celix_status_t importRegistrationFactory_destroy(import_registration_factory_pt* registration_factory) {
- celix_status_t status = CELIX_SUCCESS;
-
- if (*registration_factory != NULL)
- {
- free((*registration_factory)->serviceName);
- arrayList_destroy((*registration_factory)->registrations);
-
- serviceTracker_destroy((*registration_factory)->proxyFactoryTracker);
- free(*registration_factory);
-
- *registration_factory = NULL;
- }
-
-
- return status;
-}
-
-
-celix_status_t importRegistrationFactory_open(import_registration_factory_pt registration_factory)
-{
- celix_status_t status;
-
- const char *bundleStore = NULL;
- bundleContext_getProperty(registration_factory->context, BUNDLE_STORE_PROPERTY_NAME, &bundleStore);
-
- if (bundleStore == NULL) {
- bundleStore = DEFAULT_BUNDLE_STORE;
- }
-
- char name[256];
- snprintf(name, 256, "%s/%s_proxy.zip", bundleStore, registration_factory->serviceName);
-
- status = bundleContext_installBundle(registration_factory->context, name, ®istration_factory->bundle);
-
- if (status == CELIX_SUCCESS) {
- status = bundle_start(registration_factory->bundle);
- if (status == CELIX_SUCCESS) {
- logHelper_log(registration_factory->loghelper, OSGI_LOGSERVICE_INFO, "%s successfully started.", name);
- }
- }
- else {
- logHelper_log(registration_factory->loghelper, OSGI_LOGSERVICE_ERROR, "%s could not be installed.", name);
- }
-
- return status;
-}
-
-celix_status_t importRegistrationFactory_close(import_registration_factory_pt registration_factory)
-{
- celix_status_t status = CELIX_SUCCESS;
-
-
- if (registration_factory->proxyFactoryTracker != NULL) {
- serviceTracker_close(registration_factory->proxyFactoryTracker);
- }
-
- if (registration_factory->bundle != NULL) {
- bundle_uninstall(registration_factory->bundle);
- }
-
- return status;
-}
-
-
-celix_status_t importRegistration_createProxyFactoryTracker(import_registration_factory_pt registration_factory, service_tracker_pt *tracker) {
- celix_status_t status;
- service_tracker_customizer_pt customizer = NULL;
-
- status = serviceTrackerCustomizer_create(registration_factory, importRegistration_proxyFactoryAdding, importRegistration_proxyFactoryAdded, importRegistration_proxyFactoryModified, importRegistration_proxyFactoryRemoved, &customizer);
-
- if (status == CELIX_SUCCESS) {
- char filter[512];
-
- snprintf(filter, 512, "(&(%s=%s)(proxy.interface=%s))", (char*) OSGI_FRAMEWORK_OBJECTCLASS, (char*) OSGI_RSA_REMOTE_PROXY_FACTORY, registration_factory->serviceName);
- status = serviceTracker_createWithFilter(registration_factory->context, filter, customizer, tracker);
-
- if (status == CELIX_SUCCESS)
- {
- serviceTracker_open(*tracker);
- }
- }
-
- return status;
-}
-
-celix_status_t importRegistration_proxyFactoryAdding(void * handle, service_reference_pt reference, void **service) {
- celix_status_t status = CELIX_SUCCESS;
- import_registration_factory_pt registration_factory = (import_registration_factory_pt) handle;
-
- bundleContext_getService(registration_factory->context, reference, service);
-
- return status;
-}
-
-celix_status_t importRegistration_proxyFactoryAdded(void * handle, service_reference_pt reference, void *service) {
- celix_status_t status = CELIX_SUCCESS;
-
- import_registration_factory_pt registration_factory = (import_registration_factory_pt) handle;
- registration_factory->trackedFactory = (remote_proxy_factory_service_pt) service;
-
- return status;
-}
-
-celix_status_t importRegistration_proxyFactoryModified(void * handle, service_reference_pt reference, void *service) {
- celix_status_t status = CELIX_SUCCESS;
-
- return status;
-}
-
-celix_status_t importRegistration_proxyFactoryRemoved(void * handle, service_reference_pt reference, void *service) {
- celix_status_t status = CELIX_SUCCESS;
-
- import_registration_factory_pt registration_factory = (import_registration_factory_pt) handle;
- registration_factory->trackedFactory = NULL;
-
- return status;
-}
-
-
-
-celix_status_t importRegistrationFactory_install(log_helper_pt helper, char* serviceName, bundle_context_pt context, import_registration_factory_pt *registration_factory)
-{
- celix_status_t status;
-
- if ( (status = importRegistrationFactory_create(helper, serviceName, context, registration_factory)) == CELIX_SUCCESS) {
- // starting the proxy tracker first allows us to pick up already available proxy factories
- importRegistration_createProxyFactoryTracker(*registration_factory, &((*registration_factory)->proxyFactoryTracker));
- logHelper_log((*registration_factory)->loghelper, OSGI_LOGSERVICE_INFO, "remoteServiceAdmin_importService: new registration_factory added for %s at %p", serviceName, (*registration_factory)->proxyFactoryTracker);
-
- // check whether factory is available
- if (((*registration_factory)->trackedFactory == NULL) && ((status = importRegistrationFactory_open(*registration_factory)) != CELIX_SUCCESS)) {
- logHelper_log((*registration_factory)->loghelper, OSGI_LOGSERVICE_ERROR, "remoteServiceAdmin_importService: cannot open registration_factory for %s.", serviceName);
-
- importRegistrationFactory_close(*registration_factory);
- importRegistrationFactory_destroy(registration_factory);
- }
- }
-
- return status;
-}
-
-
-
-
-celix_status_t importRegistration_getException(import_registration_pt registration) {
- celix_status_t status = CELIX_SUCCESS;
- return status;
-}
-
-
-celix_status_t importRegistration_getImportReference(import_registration_pt registration, import_reference_pt *reference) {
- celix_status_t status = CELIX_SUCCESS;
-
- if (registration->importReference == NULL) {
- registration->importReference = calloc(1, sizeof(*registration->importReference));
- if (registration->importReference == NULL) {
- status = CELIX_ENOMEM;
- } else {
- registration->importReference->endpoint = registration->endpointDescription;
- registration->importReference->reference = registration->reference;
- }
- }
-
- *reference = registration->importReference;
-
- 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/2a670f26/remote_services/remote_service_admin/private/src/remote_proxy_factory_impl.c
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin/private/src/remote_proxy_factory_impl.c b/remote_services/remote_service_admin/private/src/remote_proxy_factory_impl.c
deleted file mode 100644
index 9f996d6..0000000
--- a/remote_services/remote_service_admin/private/src/remote_proxy_factory_impl.c
+++ /dev/null
@@ -1,252 +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_proxy_factory_impl.c
- *
- * \date 22 Dec 2014
- * \author <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- * \copyright Apache License, Version 2.0
- */
-
-#include <stdlib.h>
-#include <string.h>
-
-#include "remote_proxy.h"
-
-typedef struct proxy_instance {
- service_registration_pt registration_ptr;
- void *service;
- properties_pt properties;
-} *proxy_instance_pt;
-
-static celix_status_t remoteProxyFactory_registerProxyService(remote_proxy_factory_pt remote_proxy_factory_ptr, endpoint_description_pt endpointDescription, remote_service_admin_pt rsa, sendToHandle sendToCallback);
-static celix_status_t remoteProxyFactory_unregisterProxyService(remote_proxy_factory_pt remote_proxy_factory_ptr, endpoint_description_pt endpointDescription);
-
-celix_status_t remoteProxyFactory_create(bundle_context_pt context, char *service, void *handle,
- createProxyService create, destroyProxyService destroy,
- remote_proxy_factory_pt *remote_proxy_factory_ptr) {
- celix_status_t status = CELIX_SUCCESS;
-
- *remote_proxy_factory_ptr = calloc(1, sizeof(**remote_proxy_factory_ptr));
- if (!*remote_proxy_factory_ptr) {
- status = CELIX_ENOMEM;
- }
-
- if (status == CELIX_SUCCESS) {
- (*remote_proxy_factory_ptr)->context_ptr = context;
- (*remote_proxy_factory_ptr)->service = strdup(service);
-
- (*remote_proxy_factory_ptr)->remote_proxy_factory_service_ptr = NULL;
- (*remote_proxy_factory_ptr)->properties = NULL;
- (*remote_proxy_factory_ptr)->registration = NULL;
-
- (*remote_proxy_factory_ptr)->proxy_instances = hashMap_create(NULL, NULL, NULL, NULL);
-
- (*remote_proxy_factory_ptr)->handle = handle;
-
- (*remote_proxy_factory_ptr)->create_proxy_service_ptr = create;
- (*remote_proxy_factory_ptr)->destroy_proxy_service_ptr = destroy;
- }
-
- return status;
-}
-
-celix_status_t remoteProxyFactory_destroy(remote_proxy_factory_pt *remote_proxy_factory_ptr) {
- celix_status_t status = CELIX_SUCCESS;
-
- if (!*remote_proxy_factory_ptr) {
- status = CELIX_ILLEGAL_ARGUMENT;
- }
-
- if (status == CELIX_SUCCESS) {
- if ((*remote_proxy_factory_ptr)->proxy_instances) {
- hashMap_destroy((*remote_proxy_factory_ptr)->proxy_instances, false, false);
- (*remote_proxy_factory_ptr)->proxy_instances = NULL;
- }
- if ((*remote_proxy_factory_ptr)->service) {
- free((*remote_proxy_factory_ptr)->service);
- (*remote_proxy_factory_ptr)->service = NULL;
- }
- free(*remote_proxy_factory_ptr);
- *remote_proxy_factory_ptr = NULL;
- }
-
- return status;
-}
-
-celix_status_t remoteProxyFactory_register(remote_proxy_factory_pt remote_proxy_factory_ptr) {
- celix_status_t status = CELIX_SUCCESS;
-
- remote_proxy_factory_ptr->remote_proxy_factory_service_ptr = calloc(1, sizeof(*remote_proxy_factory_ptr->remote_proxy_factory_service_ptr));
- if (!remote_proxy_factory_ptr->remote_proxy_factory_service_ptr) {
- status = CELIX_ENOMEM;
- }
-
- if (status == CELIX_SUCCESS) {
- remote_proxy_factory_ptr->remote_proxy_factory_service_ptr->factory = remote_proxy_factory_ptr;
- remote_proxy_factory_ptr->remote_proxy_factory_service_ptr->registerProxyService = remoteProxyFactory_registerProxyService;
- remote_proxy_factory_ptr->remote_proxy_factory_service_ptr->unregisterProxyService = remoteProxyFactory_unregisterProxyService;
-
- remote_proxy_factory_ptr->properties = properties_create();
- if (!remote_proxy_factory_ptr->properties) {
- status = CELIX_BUNDLE_EXCEPTION;
- } else {
- properties_set(remote_proxy_factory_ptr->properties, "proxy.interface", remote_proxy_factory_ptr->service);
- }
- }
-
- if (status == CELIX_SUCCESS) {
- status = bundleContext_registerService(remote_proxy_factory_ptr->context_ptr, OSGI_RSA_REMOTE_PROXY_FACTORY,
- remote_proxy_factory_ptr->remote_proxy_factory_service_ptr, remote_proxy_factory_ptr->properties, &remote_proxy_factory_ptr->registration);
- }
-
- return status;
-}
-
-celix_status_t remoteProxyFactory_unregister(remote_proxy_factory_pt remote_proxy_factory_ptr) {
- celix_status_t status = CELIX_SUCCESS;
-
- if (!remote_proxy_factory_ptr) {
- status = CELIX_ILLEGAL_ARGUMENT;
- }
-
- // #TODO Remove proxy registrations
- if (status == CELIX_SUCCESS) {
-
- hash_map_iterator_pt iter = hashMapIterator_create(remote_proxy_factory_ptr->proxy_instances);
- while(hashMapIterator_hasNext(iter)){
- proxy_instance_pt proxy_instance_ptr = (proxy_instance_pt)hashMapIterator_nextValue(iter);
-
- if (proxy_instance_ptr->service) {
- remote_proxy_factory_ptr->destroy_proxy_service_ptr(remote_proxy_factory_ptr->handle, proxy_instance_ptr->service);
- }
- free(proxy_instance_ptr);
- }
- hashMapIterator_destroy(iter);
-
- if (remote_proxy_factory_ptr->registration) {
- status = serviceRegistration_unregister(remote_proxy_factory_ptr->registration);
- remote_proxy_factory_ptr->properties = NULL;
- }
- if (remote_proxy_factory_ptr->properties) {
- properties_destroy(remote_proxy_factory_ptr->properties);
- }
- if (remote_proxy_factory_ptr->remote_proxy_factory_service_ptr) {
- free(remote_proxy_factory_ptr->remote_proxy_factory_service_ptr);
- }
- }
-
- return status;
-}
-
-
-static celix_status_t remoteProxyFactory_registerProxyService(remote_proxy_factory_pt remote_proxy_factory_ptr, endpoint_description_pt endpointDescription, remote_service_admin_pt rsa, sendToHandle sendToCallback) {
- celix_status_t status = CELIX_SUCCESS;
- proxy_instance_pt proxy_instance_ptr = NULL;
-
- if (!remote_proxy_factory_ptr || !remote_proxy_factory_ptr->create_proxy_service_ptr) {
- status = CELIX_ILLEGAL_ARGUMENT;
- }
-
- if (status == CELIX_SUCCESS) {
- proxy_instance_ptr = calloc(1, sizeof(*proxy_instance_ptr));
- if (!proxy_instance_ptr) {
- status = CELIX_ENOMEM;
- }
- }
-
- if (status == CELIX_SUCCESS) {
- proxy_instance_ptr->properties = properties_create();
- if (!proxy_instance_ptr->properties) {
- status = CELIX_ENOMEM;
- }
- }
-
- if (status == CELIX_SUCCESS) {
- status = remote_proxy_factory_ptr->create_proxy_service_ptr(remote_proxy_factory_ptr->handle, endpointDescription, rsa, sendToCallback, proxy_instance_ptr->properties, &proxy_instance_ptr->service);
- }
-
- if (status == CELIX_SUCCESS) {
- properties_set(proxy_instance_ptr->properties, "proxy.interface", remote_proxy_factory_ptr->service);
-
- hash_map_iterator_pt iter = hashMapIterator_create(endpointDescription->properties);
- while (hashMapIterator_hasNext(iter)) {
- hash_map_entry_pt entry = hashMapIterator_nextEntry(iter);
- char *key = hashMapEntry_getKey(entry);
- char *value = hashMapEntry_getValue(entry);
-
- properties_set(proxy_instance_ptr->properties, key, value);
- }
- hashMapIterator_destroy(iter);
- }
-
- if (status == CELIX_SUCCESS) {
- status = bundleContext_registerService(remote_proxy_factory_ptr->context_ptr, remote_proxy_factory_ptr->service, proxy_instance_ptr->service, proxy_instance_ptr->properties, &proxy_instance_ptr->registration_ptr);
- }
-
- if (status == CELIX_SUCCESS) {
- hashMap_put(remote_proxy_factory_ptr->proxy_instances, endpointDescription, proxy_instance_ptr);
- }
-
- if(status!=CELIX_SUCCESS){
- if(proxy_instance_ptr != NULL){
- if(proxy_instance_ptr->properties != NULL){
- properties_destroy(proxy_instance_ptr->properties);
- }
- free(proxy_instance_ptr);
- }
- }
-
- return status;
-}
-
-static celix_status_t remoteProxyFactory_unregisterProxyService(remote_proxy_factory_pt remote_proxy_factory_ptr, endpoint_description_pt endpointDescription) {
- celix_status_t status = CELIX_SUCCESS;
- proxy_instance_pt proxy_instance_ptr = NULL;
-
- if (!remote_proxy_factory_ptr || !endpointDescription || !remote_proxy_factory_ptr->proxy_instances || !remote_proxy_factory_ptr->handle) {
- status = CELIX_ILLEGAL_ARGUMENT;
- }
-
- if (status == CELIX_SUCCESS) {
- proxy_instance_ptr = hashMap_remove(remote_proxy_factory_ptr->proxy_instances, endpointDescription);
- if (proxy_instance_ptr == NULL) {
- status = CELIX_BUNDLE_EXCEPTION;
- }
- }
-
- if (status == CELIX_SUCCESS) {
- if (proxy_instance_ptr->registration_ptr) {
- status = serviceRegistration_unregister(proxy_instance_ptr->registration_ptr);
- proxy_instance_ptr->properties = NULL;
- }
- if (proxy_instance_ptr->service) {
- status = remote_proxy_factory_ptr->destroy_proxy_service_ptr(remote_proxy_factory_ptr->handle, proxy_instance_ptr->service);
- }
- if (proxy_instance_ptr->properties) {
- properties_destroy(proxy_instance_ptr->properties);
- }
- free(proxy_instance_ptr);
- }
-
- return status;
-}
-
-
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/remote_service_admin/public/include/endpoint_description.h
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin/public/include/endpoint_description.h b/remote_services/remote_service_admin/public/include/endpoint_description.h
deleted file mode 100644
index de27d2e..0000000
--- a/remote_services/remote_service_admin/public/include/endpoint_description.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/**
- *Licensed to the Apache Software Foundation (ASF) under one
- *or more contributor license agreements. See the NOTICE file
- *distributed with this work for additional information
- *regarding copyright ownership. The ASF licenses this file
- *to you under the Apache License, Version 2.0 (the
- *"License"); you may not use this file except in compliance
- *with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- *Unless required by applicable law or agreed to in writing,
- *software distributed under the License is distributed on an
- *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- *specific language governing permissions and limitations
- *under the License.
- */
-/*
- * endpoint_description.h
- *
- * \date 25 Jul 2014
- * \author <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- * \copyright Apache License, Version 2.0
- */
-
-#ifndef ENDPOINT_DESCRIPTION_H_
-#define ENDPOINT_DESCRIPTION_H_
-
-#include "properties.h"
-#include "array_list.h"
-
-struct endpoint_description {
- char *frameworkUUID;
- char *id;
- // array_list_pt intents;
- char *service;
- // HASH_MAP packageVersions;
- properties_pt properties;
- unsigned long serviceId;
-};
-
-typedef struct endpoint_description endpoint_description_t;
-typedef endpoint_description_t* endpoint_description_pt;
-
-celix_status_t endpointDescription_create(properties_pt properties, endpoint_description_pt *endpointDescription);
-celix_status_t endpointDescription_destroy(endpoint_description_pt description);
-
-
-#endif /* ENDPOINT_DESCRIPTION_H_ */
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/remote_service_admin/public/include/endpoint_listener.h
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin/public/include/endpoint_listener.h b/remote_services/remote_service_admin/public/include/endpoint_listener.h
deleted file mode 100644
index 2e6359f..0000000
--- a/remote_services/remote_service_admin/public/include/endpoint_listener.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/**
- *Licensed to the Apache Software Foundation (ASF) under one
- *or more contributor license agreements. See the NOTICE file
- *distributed with this work for additional information
- *regarding copyright ownership. The ASF licenses this file
- *to you under the Apache License, Version 2.0 (the
- *"License"); you may not use this file except in compliance
- *with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- *Unless required by applicable law or agreed to in writing,
- *software distributed under the License is distributed on an
- *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- *specific language governing permissions and limitations
- *under the License.
- */
-/*
- * endpoint_listener.h
- *
- * \date Sep 29, 2011
- * \author <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- * \copyright Apache License, Version 2.0
- */
-
-#ifndef ENDPOINT_LISTENER_H_
-#define ENDPOINT_LISTENER_H_
-
-#include "array_list.h"
-#include "properties.h"
-
-#include "endpoint_description.h"
-
-static const char * const OSGI_ENDPOINT_LISTENER_SERVICE = "endpoint_listener";
-
-static const char * const OSGI_ENDPOINT_LISTENER_SCOPE = "endpoint.listener.scope";
-
-struct endpoint_listener {
- void *handle;
- celix_status_t (*endpointAdded)(void *handle, endpoint_description_pt endpoint, char *machtedFilter);
- celix_status_t (*endpointRemoved)(void *handle, endpoint_description_pt endpoint, char *machtedFilter);
-};
-
-typedef struct endpoint_listener endpoint_listener_t;
-typedef endpoint_listener_t *endpoint_listener_pt;
-
-
-#endif /* ENDPOINT_LISTENER_H_ */
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/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
deleted file mode 100644
index dc3882b..0000000
--- a/remote_services/remote_service_admin/public/include/export_registration.h
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * 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, service_reference_pt *service);
-
-#endif //CELIX_EXPORT_REGISTRATION_H
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/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
deleted file mode 100644
index ef8193f..0000000
--- a/remote_services/remote_service_admin/public/include/import_registration.h
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * 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/2a670f26/remote_services/remote_service_admin/public/include/remote_constants.h
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin/public/include/remote_constants.h b/remote_services/remote_service_admin/public/include/remote_constants.h
deleted file mode 100644
index 0736685..0000000
--- a/remote_services/remote_service_admin/public/include/remote_constants.h
+++ /dev/null
@@ -1,38 +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_constants.h
- *
- * \date Sep 30, 2011
- * \author <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- * \copyright Apache License, Version 2.0
- */
-
-#ifndef REMOTE_CONSTANTS_H_
-#define REMOTE_CONSTANTS_H_
-
-static const char * const OSGI_RSA_SERVICE_EXPORTED_INTERFACES = "service.exported.interfaces";
-static const char * const OSGI_RSA_ENDPOINT_FRAMEWORK_UUID = "endpoint.framework.uuid";
-static const char * const OSGI_RSA_ENDPOINT_SERVICE_ID = "endpoint.service.id";
-static const char * const OSGI_RSA_ENDPOINT_ID = "endpoint.id";
-static const char * const OSGI_RSA_SERVICE_IMPORTED = "service.imported";
-static const char * const OSGI_RSA_SERVICE_IMPORTED_CONFIGS = "service.imported.configs";
-static const char * const OSGI_RSA_SERVICE_LOCATION = "service.location";
-
-#endif /* REMOTE_CONSTANTS_H_ */
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/remote_service_admin/public/include/remote_endpoint.h
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin/public/include/remote_endpoint.h b/remote_services/remote_service_admin/public/include/remote_endpoint.h
deleted file mode 100644
index ab80abb..0000000
--- a/remote_services/remote_service_admin/public/include/remote_endpoint.h
+++ /dev/null
@@ -1,44 +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_endpoint.h
- *
- * \date Oct 7, 2011
- * \author <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- * \copyright Apache License, Version 2.0
- */
-
-#ifndef REMOTE_ENDPOINT_H_
-#define REMOTE_ENDPOINT_H_
-
-#define OSGI_RSA_REMOTE_ENDPOINT "remote_endpoint"
-
-typedef struct remote_endpoint remote_endpoint_t;
-typedef remote_endpoint_t* remote_endpoint_pt;
-
-struct remote_endpoint_service {
- remote_endpoint_pt endpoint;
- celix_status_t (*setService)(remote_endpoint_pt endpoint, void *service);
- celix_status_t (*handleRequest)(remote_endpoint_pt endpoint, char *data, char **reply);
-};
-
-typedef struct remote_endpoint_service *remote_endpoint_service_pt;
-
-
-#endif /* REMOTE_ENDPOINT_H_ */
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/remote_service_admin/public/include/remote_endpoint_impl.h
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin/public/include/remote_endpoint_impl.h b/remote_services/remote_service_admin/public/include/remote_endpoint_impl.h
deleted file mode 100644
index 3782d62..0000000
--- a/remote_services/remote_service_admin/public/include/remote_endpoint_impl.h
+++ /dev/null
@@ -1,38 +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_endpoint_impl.h
- *
- * \date Oct 11, 2011
- * \author <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- * \copyright Apache License, Version 2.0
- */
-
-#ifndef REMOTE_ENDPOINT_IMPL_H_
-#define REMOTE_ENDPOINT_IMPL_H_
-
-#include "remote_endpoint.h"
-#include "celix_threads.h"
-
-struct remote_endpoint {
- celix_thread_mutex_t serviceLock;
- void *service;
-};
-
-#endif /* REMOTE_ENDPOINT_IMPL_H_ */
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/remote_service_admin/public/include/remote_proxy.h
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin/public/include/remote_proxy.h b/remote_services/remote_service_admin/public/include/remote_proxy.h
deleted file mode 100644
index 4c3f5c3..0000000
--- a/remote_services/remote_service_admin/public/include/remote_proxy.h
+++ /dev/null
@@ -1,76 +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_proxy.h
- *
- * \date Oct 13, 2011
- * \author <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- * \copyright Apache License, Version 2.0
- */
-
-#ifndef REMOTE_PROXY_H_
-#define REMOTE_PROXY_H_
-
-#include "endpoint_listener.h"
-#include "remote_service_admin.h"
-
-#define OSGI_RSA_REMOTE_PROXY_FACTORY "remote_proxy_factory"
-#define OSGI_RSA_REMOTE_PROXY_TIMEOUT "remote_proxy_timeout"
-
-typedef celix_status_t (*sendToHandle)(remote_service_admin_pt remote_service_admin_ptr, endpoint_description_pt endpointDescription, char *request, char **reply, int* replyStatus);
-typedef celix_status_t (*createProxyService)(void *handle, endpoint_description_pt endpointDescription, remote_service_admin_pt rsa, sendToHandle sendToCallback, properties_pt properties, void **service);
-typedef celix_status_t (*destroyProxyService)(void *handle, void *service);
-
-typedef struct remote_proxy_factory *remote_proxy_factory_pt;
-typedef struct remote_proxy_factory_service *remote_proxy_factory_service_pt;
-
-struct remote_proxy_factory {
- bundle_context_pt context_ptr;
- char *service;
-
- remote_proxy_factory_service_pt remote_proxy_factory_service_ptr;
- properties_pt properties;
- service_registration_pt registration;
-
- hash_map_pt proxy_instances;
-
- void *handle;
-
- createProxyService create_proxy_service_ptr;
- destroyProxyService destroy_proxy_service_ptr;
-};
-
-struct remote_proxy_factory_service {
- remote_proxy_factory_pt factory;
- celix_status_t (*registerProxyService)(remote_proxy_factory_pt proxyFactoryService, endpoint_description_pt endpoint, remote_service_admin_pt remote_service_admin_ptr, sendToHandle callback);
- celix_status_t (*unregisterProxyService)(remote_proxy_factory_pt proxyFactoryService, endpoint_description_pt endpoint);
-};
-
-celix_status_t remoteProxyFactory_create(bundle_context_pt context, char *service, void *handle,
- createProxyService create, destroyProxyService destroy,
- remote_proxy_factory_pt *remote_proxy_factory_ptr);
-celix_status_t remoteProxyFactory_destroy(remote_proxy_factory_pt *remote_proxy_factory_ptr);
-
-celix_status_t remoteProxyFactory_register(remote_proxy_factory_pt remote_proxy_factory_ptr);
-celix_status_t remoteProxyFactory_unregister(remote_proxy_factory_pt remote_proxy_factory_ptr);
-
-
-
-
-#endif /* REMOTE_PROXY_H_ */
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/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
deleted file mode 100644
index cc7fd98..0000000
--- a/remote_services/remote_service_admin/public/include/remote_service_admin.h
+++ /dev/null
@@ -1,73 +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.h
- *
- * \date Sep 30, 2011
- * \author <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- * \copyright Apache License, Version 2.0
- */
-
-#ifndef REMOTE_SERVICE_ADMIN_H_
-#define REMOTE_SERVICE_ADMIN_H_
-
-#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 import_registration_factory import_registration_factory_t;
-typedef import_registration_factory_t* import_registration_factory_pt;
-
-typedef struct remote_service_admin remote_service_admin_t;
-typedef remote_service_admin_t* remote_service_admin_pt;
-
-struct remote_service_admin_service {
- remote_service_admin_pt admin;
- celix_status_t (*exportService)(remote_service_admin_pt admin, char *serviceId, properties_pt properties, array_list_pt *registrations);
- celix_status_t (*removeExportedService)(remote_service_admin_pt admin, export_registration_pt registration);
- celix_status_t (*getExportedServices)(remote_service_admin_pt admin, array_list_pt *services);
- celix_status_t (*getImportedEndpoints)(remote_service_admin_pt admin, array_list_pt *services);
- celix_status_t (*importService)(remote_service_admin_pt admin, endpoint_description_pt endpoint, 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, service_reference_pt *service);
-
- celix_status_t (*exportRegistration_close)(remote_service_admin_pt admin, 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_freeExportReference)(export_reference_pt *reference);
- celix_status_t (*exportRegistration_getEndpointDescription)(export_registration_pt registration, endpoint_description_pt endpointDescription);
-
- celix_status_t (*importReference_getImportedEndpoint)(import_reference_pt reference);
- celix_status_t (*importReference_getImportedService)(import_reference_pt reference);
-
- celix_status_t (*importRegistration_close)(remote_service_admin_pt admin, 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);
-
-};
-
-typedef struct remote_service_admin_service remote_service_admin_service_t;
-typedef remote_service_admin_service_t* remote_service_admin_service_pt;
-
-
-#endif /* REMOTE_SERVICE_ADMIN_H_ */
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/remote_service_admin_api/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_api/CMakeLists.txt b/remote_services/remote_service_admin_api/CMakeLists.txt
new file mode 100644
index 0000000..a7d0640
--- /dev/null
+++ b/remote_services/remote_service_admin_api/CMakeLists.txt
@@ -0,0 +1,45 @@
+# 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.
+
+add_library(remote_service_admin_api INTERFACE)
+target_include_directories(remote_service_admin_api INTERFACE include)
+
+install (FILES
+ include/remote_endpoint_impl.h
+ include/remote_endpoint.h
+ include/remote_proxy.h
+ include/remote_service_admin.h
+ include/export_registration.h
+ include/import_registration.h
+ include/endpoint_description.h
+ include/endpoint_listener.h
+ include/remote_constants.h
+ DESTINATION
+ include/celix/remote_service_admin
+ COMPONENT
+ remote_service_admin
+)
+install (FILES
+ public/include/endpoint_listener.h
+ DESTINATION
+ include/celix/endpoint_listener
+ COMPONENT
+ remote_service_admin
+)
+
+#Setup target aliases to match external usage
+add_library(Celix::remote_service_admin_api ALIAS remote_service_admin_api)
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/remote_service_admin_api/README.md
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_api/README.md b/remote_services/remote_service_admin_api/README.md
new file mode 100644
index 0000000..2e3d268
--- /dev/null
+++ b/remote_services/remote_service_admin_api/README.md
@@ -0,0 +1,11 @@
+# Remote Service Admin
+
+The Remote Service Admin (RSA) provides the mechanisms to import and export services when instructed to do so by the Topology Manager.
+
+To delegate method calls to the actual service implementation, the RSA_SHM and the RSA_HTTP are using "endpoint/proxy" bundles, which has all the knowledge about the marshalling and unmarshalling of data for the service. The RSA_DFI implementation combines a [foreign function interface](https://en.wikipedia.org/wiki/Foreign_function_interface) technique together with manualy created descriptors.
+
+Note that this folder contains code commonly used by the RSA implementations and therefore does not include any CMAKE configuration.
+
+## Properties
+ ENDPOINTS defines the relative directory where endpoints and proxys can be found (default: endpoints)
+ CELIX_FRAMEWORK_EXTENDER_PATH Used in RSA_DFI only. Can be used to define a path to use as an extender path point for the framework bundle. For normal bundles the bundle cache is used.
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/remote_service_admin_api/include/endpoint_description.h
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_api/include/endpoint_description.h b/remote_services/remote_service_admin_api/include/endpoint_description.h
new file mode 100644
index 0000000..de27d2e
--- /dev/null
+++ b/remote_services/remote_service_admin_api/include/endpoint_description.h
@@ -0,0 +1,50 @@
+/**
+ *Licensed to the Apache Software Foundation (ASF) under one
+ *or more contributor license agreements. See the NOTICE file
+ *distributed with this work for additional information
+ *regarding copyright ownership. The ASF licenses this file
+ *to you under the Apache License, Version 2.0 (the
+ *"License"); you may not use this file except in compliance
+ *with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *Unless required by applicable law or agreed to in writing,
+ *software distributed under the License is distributed on an
+ *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *specific language governing permissions and limitations
+ *under the License.
+ */
+/*
+ * endpoint_description.h
+ *
+ * \date 25 Jul 2014
+ * \author <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ * \copyright Apache License, Version 2.0
+ */
+
+#ifndef ENDPOINT_DESCRIPTION_H_
+#define ENDPOINT_DESCRIPTION_H_
+
+#include "properties.h"
+#include "array_list.h"
+
+struct endpoint_description {
+ char *frameworkUUID;
+ char *id;
+ // array_list_pt intents;
+ char *service;
+ // HASH_MAP packageVersions;
+ properties_pt properties;
+ unsigned long serviceId;
+};
+
+typedef struct endpoint_description endpoint_description_t;
+typedef endpoint_description_t* endpoint_description_pt;
+
+celix_status_t endpointDescription_create(properties_pt properties, endpoint_description_pt *endpointDescription);
+celix_status_t endpointDescription_destroy(endpoint_description_pt description);
+
+
+#endif /* ENDPOINT_DESCRIPTION_H_ */
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/remote_service_admin_api/include/endpoint_listener.h
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_api/include/endpoint_listener.h b/remote_services/remote_service_admin_api/include/endpoint_listener.h
new file mode 100644
index 0000000..2e6359f
--- /dev/null
+++ b/remote_services/remote_service_admin_api/include/endpoint_listener.h
@@ -0,0 +1,49 @@
+/**
+ *Licensed to the Apache Software Foundation (ASF) under one
+ *or more contributor license agreements. See the NOTICE file
+ *distributed with this work for additional information
+ *regarding copyright ownership. The ASF licenses this file
+ *to you under the Apache License, Version 2.0 (the
+ *"License"); you may not use this file except in compliance
+ *with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *Unless required by applicable law or agreed to in writing,
+ *software distributed under the License is distributed on an
+ *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *specific language governing permissions and limitations
+ *under the License.
+ */
+/*
+ * endpoint_listener.h
+ *
+ * \date Sep 29, 2011
+ * \author <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ * \copyright Apache License, Version 2.0
+ */
+
+#ifndef ENDPOINT_LISTENER_H_
+#define ENDPOINT_LISTENER_H_
+
+#include "array_list.h"
+#include "properties.h"
+
+#include "endpoint_description.h"
+
+static const char * const OSGI_ENDPOINT_LISTENER_SERVICE = "endpoint_listener";
+
+static const char * const OSGI_ENDPOINT_LISTENER_SCOPE = "endpoint.listener.scope";
+
+struct endpoint_listener {
+ void *handle;
+ celix_status_t (*endpointAdded)(void *handle, endpoint_description_pt endpoint, char *machtedFilter);
+ celix_status_t (*endpointRemoved)(void *handle, endpoint_description_pt endpoint, char *machtedFilter);
+};
+
+typedef struct endpoint_listener endpoint_listener_t;
+typedef endpoint_listener_t *endpoint_listener_pt;
+
+
+#endif /* ENDPOINT_LISTENER_H_ */
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/remote_service_admin_api/include/export_registration.h
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_api/include/export_registration.h b/remote_services/remote_service_admin_api/include/export_registration.h
new file mode 100644
index 0000000..dc3882b
--- /dev/null
+++ b/remote_services/remote_service_admin_api/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, service_reference_pt *service);
+
+#endif //CELIX_EXPORT_REGISTRATION_H
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/remote_service_admin_api/include/import_registration.h
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_api/include/import_registration.h b/remote_services/remote_service_admin_api/include/import_registration.h
new file mode 100644
index 0000000..ef8193f
--- /dev/null
+++ b/remote_services/remote_service_admin_api/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/2a670f26/remote_services/remote_service_admin_api/include/remote_constants.h
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_api/include/remote_constants.h b/remote_services/remote_service_admin_api/include/remote_constants.h
new file mode 100644
index 0000000..0736685
--- /dev/null
+++ b/remote_services/remote_service_admin_api/include/remote_constants.h
@@ -0,0 +1,38 @@
+/**
+ *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_constants.h
+ *
+ * \date Sep 30, 2011
+ * \author <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ * \copyright Apache License, Version 2.0
+ */
+
+#ifndef REMOTE_CONSTANTS_H_
+#define REMOTE_CONSTANTS_H_
+
+static const char * const OSGI_RSA_SERVICE_EXPORTED_INTERFACES = "service.exported.interfaces";
+static const char * const OSGI_RSA_ENDPOINT_FRAMEWORK_UUID = "endpoint.framework.uuid";
+static const char * const OSGI_RSA_ENDPOINT_SERVICE_ID = "endpoint.service.id";
+static const char * const OSGI_RSA_ENDPOINT_ID = "endpoint.id";
+static const char * const OSGI_RSA_SERVICE_IMPORTED = "service.imported";
+static const char * const OSGI_RSA_SERVICE_IMPORTED_CONFIGS = "service.imported.configs";
+static const char * const OSGI_RSA_SERVICE_LOCATION = "service.location";
+
+#endif /* REMOTE_CONSTANTS_H_ */
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/remote_service_admin_api/include/remote_endpoint.h
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_api/include/remote_endpoint.h b/remote_services/remote_service_admin_api/include/remote_endpoint.h
new file mode 100644
index 0000000..ab80abb
--- /dev/null
+++ b/remote_services/remote_service_admin_api/include/remote_endpoint.h
@@ -0,0 +1,44 @@
+/**
+ *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_endpoint.h
+ *
+ * \date Oct 7, 2011
+ * \author <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ * \copyright Apache License, Version 2.0
+ */
+
+#ifndef REMOTE_ENDPOINT_H_
+#define REMOTE_ENDPOINT_H_
+
+#define OSGI_RSA_REMOTE_ENDPOINT "remote_endpoint"
+
+typedef struct remote_endpoint remote_endpoint_t;
+typedef remote_endpoint_t* remote_endpoint_pt;
+
+struct remote_endpoint_service {
+ remote_endpoint_pt endpoint;
+ celix_status_t (*setService)(remote_endpoint_pt endpoint, void *service);
+ celix_status_t (*handleRequest)(remote_endpoint_pt endpoint, char *data, char **reply);
+};
+
+typedef struct remote_endpoint_service *remote_endpoint_service_pt;
+
+
+#endif /* REMOTE_ENDPOINT_H_ */
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/remote_service_admin_api/include/remote_endpoint_impl.h
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_api/include/remote_endpoint_impl.h b/remote_services/remote_service_admin_api/include/remote_endpoint_impl.h
new file mode 100644
index 0000000..3782d62
--- /dev/null
+++ b/remote_services/remote_service_admin_api/include/remote_endpoint_impl.h
@@ -0,0 +1,38 @@
+/**
+ *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_endpoint_impl.h
+ *
+ * \date Oct 11, 2011
+ * \author <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ * \copyright Apache License, Version 2.0
+ */
+
+#ifndef REMOTE_ENDPOINT_IMPL_H_
+#define REMOTE_ENDPOINT_IMPL_H_
+
+#include "remote_endpoint.h"
+#include "celix_threads.h"
+
+struct remote_endpoint {
+ celix_thread_mutex_t serviceLock;
+ void *service;
+};
+
+#endif /* REMOTE_ENDPOINT_IMPL_H_ */
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/remote_service_admin_api/include/remote_proxy.h
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_api/include/remote_proxy.h b/remote_services/remote_service_admin_api/include/remote_proxy.h
new file mode 100644
index 0000000..4c3f5c3
--- /dev/null
+++ b/remote_services/remote_service_admin_api/include/remote_proxy.h
@@ -0,0 +1,76 @@
+/**
+ *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_proxy.h
+ *
+ * \date Oct 13, 2011
+ * \author <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ * \copyright Apache License, Version 2.0
+ */
+
+#ifndef REMOTE_PROXY_H_
+#define REMOTE_PROXY_H_
+
+#include "endpoint_listener.h"
+#include "remote_service_admin.h"
+
+#define OSGI_RSA_REMOTE_PROXY_FACTORY "remote_proxy_factory"
+#define OSGI_RSA_REMOTE_PROXY_TIMEOUT "remote_proxy_timeout"
+
+typedef celix_status_t (*sendToHandle)(remote_service_admin_pt remote_service_admin_ptr, endpoint_description_pt endpointDescription, char *request, char **reply, int* replyStatus);
+typedef celix_status_t (*createProxyService)(void *handle, endpoint_description_pt endpointDescription, remote_service_admin_pt rsa, sendToHandle sendToCallback, properties_pt properties, void **service);
+typedef celix_status_t (*destroyProxyService)(void *handle, void *service);
+
+typedef struct remote_proxy_factory *remote_proxy_factory_pt;
+typedef struct remote_proxy_factory_service *remote_proxy_factory_service_pt;
+
+struct remote_proxy_factory {
+ bundle_context_pt context_ptr;
+ char *service;
+
+ remote_proxy_factory_service_pt remote_proxy_factory_service_ptr;
+ properties_pt properties;
+ service_registration_pt registration;
+
+ hash_map_pt proxy_instances;
+
+ void *handle;
+
+ createProxyService create_proxy_service_ptr;
+ destroyProxyService destroy_proxy_service_ptr;
+};
+
+struct remote_proxy_factory_service {
+ remote_proxy_factory_pt factory;
+ celix_status_t (*registerProxyService)(remote_proxy_factory_pt proxyFactoryService, endpoint_description_pt endpoint, remote_service_admin_pt remote_service_admin_ptr, sendToHandle callback);
+ celix_status_t (*unregisterProxyService)(remote_proxy_factory_pt proxyFactoryService, endpoint_description_pt endpoint);
+};
+
+celix_status_t remoteProxyFactory_create(bundle_context_pt context, char *service, void *handle,
+ createProxyService create, destroyProxyService destroy,
+ remote_proxy_factory_pt *remote_proxy_factory_ptr);
+celix_status_t remoteProxyFactory_destroy(remote_proxy_factory_pt *remote_proxy_factory_ptr);
+
+celix_status_t remoteProxyFactory_register(remote_proxy_factory_pt remote_proxy_factory_ptr);
+celix_status_t remoteProxyFactory_unregister(remote_proxy_factory_pt remote_proxy_factory_ptr);
+
+
+
+
+#endif /* REMOTE_PROXY_H_ */
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/remote_service_admin_api/include/remote_service_admin.h
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_api/include/remote_service_admin.h b/remote_services/remote_service_admin_api/include/remote_service_admin.h
new file mode 100644
index 0000000..cc7fd98
--- /dev/null
+++ b/remote_services/remote_service_admin_api/include/remote_service_admin.h
@@ -0,0 +1,73 @@
+/**
+ *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.h
+ *
+ * \date Sep 30, 2011
+ * \author <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ * \copyright Apache License, Version 2.0
+ */
+
+#ifndef REMOTE_SERVICE_ADMIN_H_
+#define REMOTE_SERVICE_ADMIN_H_
+
+#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 import_registration_factory import_registration_factory_t;
+typedef import_registration_factory_t* import_registration_factory_pt;
+
+typedef struct remote_service_admin remote_service_admin_t;
+typedef remote_service_admin_t* remote_service_admin_pt;
+
+struct remote_service_admin_service {
+ remote_service_admin_pt admin;
+ celix_status_t (*exportService)(remote_service_admin_pt admin, char *serviceId, properties_pt properties, array_list_pt *registrations);
+ celix_status_t (*removeExportedService)(remote_service_admin_pt admin, export_registration_pt registration);
+ celix_status_t (*getExportedServices)(remote_service_admin_pt admin, array_list_pt *services);
+ celix_status_t (*getImportedEndpoints)(remote_service_admin_pt admin, array_list_pt *services);
+ celix_status_t (*importService)(remote_service_admin_pt admin, endpoint_description_pt endpoint, 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, service_reference_pt *service);
+
+ celix_status_t (*exportRegistration_close)(remote_service_admin_pt admin, 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_freeExportReference)(export_reference_pt *reference);
+ celix_status_t (*exportRegistration_getEndpointDescription)(export_registration_pt registration, endpoint_description_pt endpointDescription);
+
+ celix_status_t (*importReference_getImportedEndpoint)(import_reference_pt reference);
+ celix_status_t (*importReference_getImportedService)(import_reference_pt reference);
+
+ celix_status_t (*importRegistration_close)(remote_service_admin_pt admin, 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);
+
+};
+
+typedef struct remote_service_admin_service remote_service_admin_service_t;
+typedef remote_service_admin_service_t* remote_service_admin_service_pt;
+
+
+#endif /* REMOTE_SERVICE_ADMIN_H_ */
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/remote_service_admin_common/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_common/CMakeLists.txt b/remote_services/remote_service_admin_common/CMakeLists.txt
new file mode 100644
index 0000000..1813211
--- /dev/null
+++ b/remote_services/remote_service_admin_common/CMakeLists.txt
@@ -0,0 +1,24 @@
+# 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.
+
+add_library(remote_service_admin_common STATIC
+ src/endpoint_description.c
+ src/export_registration_impl.c
+ src/import_registration_impl.c
+)
+target_include_directories(remote_service_admin_common PRIVATE src)
+target_link_libraries(remote_service_admin_common PUBLIC Celix::framework Celix::remote_service_admin_api Celix::log_helper)
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/remote_service_admin_common/src/endpoint_description.c
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_common/src/endpoint_description.c b/remote_services/remote_service_admin_common/src/endpoint_description.c
new file mode 100644
index 0000000..0d8b684
--- /dev/null
+++ b/remote_services/remote_service_admin_common/src/endpoint_description.c
@@ -0,0 +1,89 @@
+/**
+ *Licensed to the Apache Software Foundation (ASF) under one
+ *or more contributor license agreements. See the NOTICE file
+ *distributed with this work for additional information
+ *regarding copyright ownership. The ASF licenses this file
+ *to you under the Apache License, Version 2.0 (the
+ *"License"); you may not use this file except in compliance
+ *with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *Unless required by applicable law or agreed to in writing,
+ *software distributed under the License is distributed on an
+ *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *specific language governing permissions and limitations
+ *under the License.
+ */
+/*
+ * endpoint_description.c
+ *
+ * \date 25 Jul 2014
+ * \author <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ * \copyright Apache License, Version 2.0
+ */
+#include <stdlib.h>
+#include <string.h>
+
+#include "celix_errno.h"
+#include "celix_log.h"
+
+#include "endpoint_description.h"
+#include "remote_constants.h"
+#include "constants.h"
+
+static celix_status_t endpointDescription_verifyLongProperty(properties_pt properties, char *propertyName, unsigned long *longProperty);
+
+celix_status_t endpointDescription_create(properties_pt properties, endpoint_description_pt *endpointDescription) {
+ celix_status_t status = CELIX_SUCCESS;
+
+ unsigned long serviceId = 0UL;
+ status = endpointDescription_verifyLongProperty(properties, (char *) OSGI_RSA_ENDPOINT_SERVICE_ID, &serviceId);
+ if (status != CELIX_SUCCESS) {
+ return status;
+ }
+
+ endpoint_description_pt ep = calloc(1,sizeof(*ep));
+
+ ep->properties = properties;
+ ep->frameworkUUID = (char*)properties_get(properties, OSGI_RSA_ENDPOINT_FRAMEWORK_UUID);
+ ep->id = (char*)properties_get(properties, OSGI_RSA_ENDPOINT_ID);
+ ep->service = strndup(properties_get(properties, OSGI_FRAMEWORK_OBJECTCLASS), 1024*10);
+ ep->serviceId = serviceId;
+
+ if (!(ep->frameworkUUID) || !(ep->id) || !(ep->service) ) {
+ fw_log(logger, OSGI_FRAMEWORK_LOG_ERROR, "ENDPOINT_DESCRIPTION: incomplete description!.");
+ status = CELIX_BUNDLE_EXCEPTION;
+ }
+
+ if(status == CELIX_SUCCESS){
+ *endpointDescription = ep;
+ }
+ else{
+ *endpointDescription = NULL;
+ free(ep);
+ }
+
+ return status;
+}
+
+celix_status_t endpointDescription_destroy(endpoint_description_pt description) {
+ properties_destroy(description->properties);
+ free(description->service);
+ free(description);
+ return CELIX_SUCCESS;
+}
+
+static celix_status_t endpointDescription_verifyLongProperty(properties_pt properties, char *propertyName, unsigned long *longProperty) {
+ celix_status_t status = CELIX_SUCCESS;
+
+ const char *value = properties_get(properties, propertyName);
+ if (value == NULL) {
+ *longProperty = 0UL;
+ } else {
+ *longProperty = strtoul(value,NULL,10);
+ }
+
+ return status;
+}
[19/19] celix git commit: CELIX-417: Refactor for CMake usage in RSA,
PSA and Docker. mostly trying to identify the api and common libraries
Posted by pn...@apache.org.
CELIX-417: Refactor for CMake usage in RSA, PSA and Docker. mostly trying to identify the api and common libraries
Project: http://git-wip-us.apache.org/repos/asf/celix/repo
Commit: http://git-wip-us.apache.org/repos/asf/celix/commit/2a670f26
Tree: http://git-wip-us.apache.org/repos/asf/celix/tree/2a670f26
Diff: http://git-wip-us.apache.org/repos/asf/celix/diff/2a670f26
Branch: refs/heads/feature/CELIX-417-cmake-refactor
Commit: 2a670f26579d89e5404979d7fffb4ed27040441c
Parents: a1c3088
Author: Pepijn Noltes <pe...@gmail.com>
Authored: Tue Nov 21 21:07:44 2017 +0100
Committer: Pepijn Noltes <pe...@gmail.com>
Committed: Tue Nov 21 21:07:44 2017 +0100
----------------------------------------------------------------------
cmake/cmake_celix/BundlePackaging.cmake | 2 +-
cmake/cmake_celix/DockerPackaging.cmake | 17 +-
deployment_admin/CMakeLists.txt | 2 +-
examples/dm_example_cxx/CMakeLists.txt | 16 +-
examples/dm_example_cxx/phase1/CMakeLists.txt | 4 +-
examples/hello_world/CMakeLists.txt | 8 +-
examples/services_example_c/bar/CMakeLists.txt | 4 +-
log_writer/CMakeLists.txt | 6 +-
log_writer/README.md | 10 +-
log_writer/log_writer_stdout/CMakeLists.txt | 10 +-
log_writer/log_writer_syslog/CMakeLists.txt | 4 -
pubsub/CMakeLists.txt | 2 +-
pubsub/deploy/CMakeLists.txt | 2 +-
.../examples/mp_pubsub/publisher/CMakeLists.txt | 2 +-
.../mp_pubsub/subscriber/CMakeLists.txt | 2 +-
pubsub/examples/pubsub/publisher/CMakeLists.txt | 2 +-
.../examples/pubsub/publisher2/CMakeLists.txt | 2 +-
.../examples/pubsub/subscriber/CMakeLists.txt | 2 +-
pubsub/pubsub_admin_udp_mc/CMakeLists.txt | 28 +-
.../private/include/large_udp.h | 45 -
.../private/include/pubsub_admin_impl.h | 93 -
.../private/include/topic_publication.h | 57 -
.../private/include/topic_subscription.h | 60 -
.../pubsub_admin_udp_mc/private/src/large_udp.c | 372 -
.../private/src/psa_activator.c | 141 -
.../private/src/pubsub_admin_impl.c | 1039 ---
.../private/src/topic_publication.c | 444 -
.../private/src/topic_subscription.c | 635 --
pubsub/pubsub_admin_udp_mc/src/large_udp.c | 372 +
pubsub/pubsub_admin_udp_mc/src/large_udp.h | 45 +
pubsub/pubsub_admin_udp_mc/src/psa_activator.c | 141 +
.../pubsub_admin_udp_mc/src/pubsub_admin_impl.c | 1039 +++
.../pubsub_admin_udp_mc/src/pubsub_admin_impl.h | 93 +
.../pubsub_admin_udp_mc/src/topic_publication.c | 444 +
.../pubsub_admin_udp_mc/src/topic_publication.h | 57 +
.../src/topic_subscription.c | 635 ++
.../src/topic_subscription.h | 60 +
pubsub/pubsub_admin_zmq/CMakeLists.txt | 5 +-
pubsub/pubsub_discovery/CMakeLists.txt | 27 +-
.../private/include/etcd_common.h | 28 -
.../private/include/etcd_watcher.h | 38 -
.../private/include/etcd_writer.h | 39 -
.../private/include/pubsub_discovery_impl.h | 72 -
.../pubsub_discovery/private/src/etcd_common.c | 82 -
.../pubsub_discovery/private/src/etcd_watcher.c | 290 -
.../pubsub_discovery/private/src/etcd_writer.c | 189 -
.../private/src/psd_activator.c | 171 -
.../private/src/pubsub_discovery_impl.c | 457 -
.../public/include/pubsub_discovery.h | 26 -
pubsub/pubsub_discovery/src/etcd_common.c | 82 +
pubsub/pubsub_discovery/src/etcd_common.h | 28 +
pubsub/pubsub_discovery/src/etcd_watcher.c | 290 +
pubsub/pubsub_discovery/src/etcd_watcher.h | 38 +
pubsub/pubsub_discovery/src/etcd_writer.c | 189 +
pubsub/pubsub_discovery/src/etcd_writer.h | 39 +
pubsub/pubsub_discovery/src/psd_activator.c | 171 +
pubsub/pubsub_discovery/src/pubsub_discovery.h | 26 +
.../src/pubsub_discovery_impl.c | 457 +
.../src/pubsub_discovery_impl.h | 72 +
pubsub/pubsub_serializer_json/CMakeLists.txt | 20 +-
.../private/include/pubsub_serializer_impl.h | 55 -
.../private/src/ps_activator.c | 107 -
.../private/src/pubsub_serializer_impl.c | 295 -
.../pubsub_serializer_json/src/ps_activator.c | 107 +
.../src/pubsub_serializer_impl.c | 295 +
.../src/pubsub_serializer_impl.h | 55 +
pubsub/pubsub_topology_manager/CMakeLists.txt | 12 +-
pubsub/test/CMakeLists.txt | 6 +-
remote_services/CMakeLists.txt | 6 +-
.../discovery/private/include/discovery.h | 67 -
.../include/endpoint_descriptor_common.h | 61 -
.../include/endpoint_descriptor_reader.h | 42 -
.../include/endpoint_descriptor_writer.h | 39 -
.../private/include/endpoint_discovery_poller.h | 56 -
.../private/include/endpoint_discovery_server.h | 81 -
remote_services/discovery/private/src/desc.xml | 41 -
.../discovery/private/src/discovery.c | 233 -
.../discovery/private/src/discovery_activator.c | 186 -
.../private/src/endpoint_descriptor_reader.c | 387 -
.../private/src/endpoint_descriptor_writer.c | 233 -
.../private/src/endpoint_discovery_poller.c | 403 -
.../private/src/endpoint_discovery_server.c | 450 -
remote_services/discovery_common/CMakeLists.txt | 33 +
.../discovery_common/include/civetweb.h | 657 ++
.../discovery_common/include/discovery.h | 67 +
.../include/endpoint_descriptor_common.h | 61 +
.../include/endpoint_descriptor_reader.h | 42 +
.../include/endpoint_descriptor_writer.h | 39 +
.../include/endpoint_discovery_poller.h | 56 +
.../include/endpoint_discovery_server.h | 81 +
remote_services/discovery_common/src/civetweb.c | 7907 ++++++++++++++++++
remote_services/discovery_common/src/desc.xml | 41 +
.../discovery_common/src/discovery.c | 234 +
.../discovery_common/src/discovery_activator.c | 186 +
.../src/endpoint_descriptor_reader.c | 387 +
.../src/endpoint_descriptor_writer.c | 233 +
.../src/endpoint_discovery_poller.c | 403 +
.../src/endpoint_discovery_server.c | 450 +
remote_services/discovery_common/src/md5.inl | 461 +
.../discovery_configured/CMakeLists.txt | 36 +-
.../private/include/discovery_impl.h | 62 -
.../discovery_configured/private/src/desc.xml | 41 -
.../private/src/discovery_impl.c | 123 -
.../discovery_configured/src/desc.xml | 41 +
.../discovery_configured/src/discovery_impl.c | 123 +
.../discovery_configured/src/discovery_impl.h | 62 +
remote_services/discovery_etcd/CMakeLists.txt | 33 +-
remote_services/discovery_shm/CMakeLists.txt | 35 +-
.../private/include/discovery_impl.h | 66 -
.../private/include/discovery_shm.h | 56 -
.../private/include/discovery_shmWatcher.h | 40 -
.../discovery_shm/private/src/discovery_impl.c | 163 -
.../discovery_shm/private/src/discovery_shm.c | 284 -
.../private/src/discovery_shmWatcher.c | 246 -
.../discovery_shm/src/discovery_impl.c | 163 +
.../discovery_shm/src/discovery_impl.h | 66 +
.../discovery_shm/src/discovery_shm.c | 284 +
.../discovery_shm/src/discovery_shm.h | 56 +
.../discovery_shm/src/discovery_shmWatcher.c | 246 +
.../discovery_shm/src/discovery_shmWatcher.h | 40 +
remote_services/examples/CMakeLists.txt | 5 +-
.../examples/calculator_api/CMakeLists.txt | 22 +
.../calculator_api/include/calculator_service.h | 56 +
...apache.celix.calc.api.Calculator2.descriptor | 11 +
.../examples/calculator_service/CMakeLists.txt | 22 +-
.../private/include/calculator_impl.h | 43 -
.../private/src/calculator_activator.c | 110 -
.../private/src/calculator_impl.c | 79 -
.../public/include/calculator_service.h | 56 -
...apache.celix.calc.api.Calculator2.descriptor | 11 -
.../src/calculator_activator.c | 110 +
.../calculator_service/src/calculator_impl.c | 79 +
.../calculator_service/src/calculator_impl.h | 43 +
.../examples/calculator_shell/CMakeLists.txt | 28 +-
.../private/include/add_command.h | 32 -
...apache.celix.calc.api.Calculator2.descriptor | 11 -
.../private/include/sqrt_command.h | 32 -
.../private/include/sub_command.h | 32 -
.../calculator_shell/private/src/add_command.c | 101 -
.../private/src/calculator_shell_activator.c | 125 -
.../calculator_shell/private/src/sqrt_command.c | 96 -
.../calculator_shell/private/src/sub_command.c | 99 -
.../examples/calculator_shell/src/add_command.c | 101 +
.../examples/calculator_shell/src/add_command.h | 32 +
.../src/calculator_shell_activator.c | 125 +
...apache.celix.calc.api.Calculator2.descriptor | 11 +
.../calculator_shell/src/sqrt_command.c | 96 +
.../calculator_shell/src/sqrt_command.h | 32 +
.../examples/calculator_shell/src/sub_command.c | 99 +
.../examples/calculator_shell/src/sub_command.h | 32 +
.../remote_service_admin/CMakeLists.txt | 46 -
remote_services/remote_service_admin/README.md | 11 -
.../private/include/export_registration_impl.h | 61 -
.../private/include/import_registration_impl.h | 81 -
.../private/include/remote_service_admin_impl.h | 49 -
.../private/src/endpoint_description.c | 89 -
.../private/src/export_registration_impl.c | 257 -
.../private/src/import_registration_impl.c | 274 -
.../private/src/remote_proxy_factory_impl.c | 252 -
.../public/include/endpoint_description.h | 50 -
.../public/include/endpoint_listener.h | 49 -
.../public/include/export_registration.h | 22 -
.../public/include/import_registration.h | 22 -
.../public/include/remote_constants.h | 38 -
.../public/include/remote_endpoint.h | 44 -
.../public/include/remote_endpoint_impl.h | 38 -
.../public/include/remote_proxy.h | 76 -
.../public/include/remote_service_admin.h | 73 -
.../remote_service_admin_api/CMakeLists.txt | 45 +
.../remote_service_admin_api/README.md | 11 +
.../include/endpoint_description.h | 50 +
.../include/endpoint_listener.h | 49 +
.../include/export_registration.h | 22 +
.../include/import_registration.h | 22 +
.../include/remote_constants.h | 38 +
.../include/remote_endpoint.h | 44 +
.../include/remote_endpoint_impl.h | 38 +
.../include/remote_proxy.h | 76 +
.../include/remote_service_admin.h | 73 +
.../remote_service_admin_common/CMakeLists.txt | 24 +
.../src/endpoint_description.c | 89 +
.../src/export_registration_impl.c | 257 +
.../src/export_registration_impl.h | 61 +
.../src/import_registration_impl.c | 274 +
.../src/import_registration_impl.h | 81 +
.../src/remote_proxy_factory_impl.c | 252 +
.../src/remote_service_admin_impl.h | 49 +
.../remote_service_admin_dfi/rsa/CMakeLists.txt | 31 +-
.../rsa/private/include/dfi_utils.h | 30 -
.../private/include/export_registration_dfi.h | 38 -
.../private/include/import_registration_dfi.h | 44 -
.../private/include/remote_service_admin_dfi.h | 57 -
.../rsa/private/src/dfi_utils.c | 98 -
.../rsa/private/src/export_registration_dfi.c | 251 -
.../rsa/private/src/import_registration_dfi.c | 402 -
.../src/remote_service_admin_activator.c | 124 -
.../rsa/private/src/remote_service_admin_dfi.c | 775 --
.../rsa/src/dfi_utils.c | 98 +
.../rsa/src/dfi_utils.h | 30 +
.../rsa/src/export_registration_dfi.c | 251 +
.../rsa/src/export_registration_dfi.h | 38 +
.../rsa/src/import_registration_dfi.c | 402 +
.../rsa/src/import_registration_dfi.h | 44 +
.../rsa/src/remote_service_admin_activator.c | 124 +
.../rsa/src/remote_service_admin_dfi.c | 775 ++
.../rsa/src/remote_service_admin_dfi.h | 57 +
.../rsa_tst/CMakeLists.txt | 4 +-
.../rsa_tst/bundle/CMakeLists.txt | 14 +-
remote_services/topology_manager/CMakeLists.txt | 26 +-
.../topology_manager/include/tm_scope.h | 46 +
.../topology_manager/private/include/scope.h | 150 -
.../private/include/topology_manager.h | 65 -
.../topology_manager/private/src/activator.c | 289 -
.../topology_manager/private/src/scope.c | 326 -
.../private/src/topology_manager.c | 985 ---
.../topology_manager/public/include/tm_scope.h | 46 -
.../topology_manager/src/activator.c | 289 +
remote_services/topology_manager/src/scope.c | 326 +
remote_services/topology_manager/src/scope.h | 150 +
.../topology_manager/src/topology_manager.c | 985 +++
.../topology_manager/src/topology_manager.h | 65 +
.../topology_manager/tms_tst/CMakeLists.txt | 4 +-
.../tms_tst/bundle/CMakeLists.txt | 2 +-
.../tms_tst/disc_mock/CMakeLists.txt | 11 +-
.../utils/private/include/civetweb.h | 657 --
remote_services/utils/private/src/civetweb.c | 7907 ------------------
remote_services/utils/private/src/md5.inl | 461 -
shell/CMakeLists.txt | 2 +-
shell/README.md | 3 +-
229 files changed, 23404 insertions(+), 23450 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/cmake/cmake_celix/BundlePackaging.cmake
----------------------------------------------------------------------
diff --git a/cmake/cmake_celix/BundlePackaging.cmake b/cmake/cmake_celix/BundlePackaging.cmake
index 2071fca..c5d75d6 100644
--- a/cmake/cmake_celix/BundlePackaging.cmake
+++ b/cmake/cmake_celix/BundlePackaging.cmake
@@ -371,7 +371,7 @@ function(bundle_import_libs)
list(APPEND LIBS "$<TARGET_SONAME_FILE_NAME:${LIB}>")
endif()
- target_link_libraries(${BUNDLE} ${LIB})
+ target_link_libraries(${BUNDLE} PRIVATE ${LIB})
endforeach()
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/cmake/cmake_celix/DockerPackaging.cmake
----------------------------------------------------------------------
diff --git a/cmake/cmake_celix/DockerPackaging.cmake b/cmake/cmake_celix/DockerPackaging.cmake
index 7cce6dd..b85da11 100644
--- a/cmake/cmake_celix/DockerPackaging.cmake
+++ b/cmake/cmake_celix/DockerPackaging.cmake
@@ -116,22 +116,16 @@ function(add_celix_docker)
DEPENDS ${TIMESTAMP_FILE}
)
- #Setting CELIX_LIB_DIRS, CELIX_BIN_DIR and CELIX_LAUNCHER
- if (EXISTS ${CELIX_FRAMEWORK_LIBRARY})
- #CELIX_FRAMEWORK_LIBRARY set by FindCelix.cmake -> Celix Based Project
- #CELIX_LAUNCHER is set by FindCelix.cmake
- else()
- set(CELIX_LAUNCHER "$<TARGET_FILE:celix>")
- endif()
+ set(CELIX_LAUNCHER "$<TARGET_FILE:Celix::launcher>")
#setup dependencies based on timestamp
if (DOCKER_CREATE_FS)
add_custom_command(OUTPUT "${TIMESTAMP_FILE}"
COMMAND ${CMAKE_COMMAND} -E touch ${TIMESTAMP_FILE}
- COMMAND ${CMAKE_COMMAND} -E make_directory $<TARGET_PROPERTY:${DOCKER_TARGET},DOCKER_LOC>
- COMMAND cd $<TARGET_PROPERTY:${DOCKER_TARGET},DOCKER_LOC> && /bin/bash ${CELIX_CMAKE_DIRECTORY}/cmake_celix/create_target_filesystem.sh -e ${CELIX_LAUNCHER} -l $<TARGET_FILE:${DOCKER_DEPSLIB}> > /dev/null
+ COMMAND ${CMAKE_COMMAND} -E make_directory $<TARGET_PROPERTY:${DOCKER_TARGET},DOCKER_LOC>
+ COMMAND cd $<TARGET_PROPERTY:${DOCKER_TARGET},DOCKER_LOC> && /bin/bash ${CELIX_CMAKE_DIRECTORY}/cmake_celix/create_target_filesystem.sh -e ${CELIX_LAUNCHER} -l $<TARGET_FILE:${DOCKER_DEPSLIB}> > /dev/null
DEPENDS "$<TARGET_PROPERTY:${DOCKER_TARGET},DOCKER_DEPS>" ${DOCKERFILE} ${DOCKER_DEPSLIB}
- WORKING_DIRECTORY "${DOCKER_LOC}"
+ WORKING_DIRECTORY "${DOCKER_LOC}"
COMMENT "Creating docker dir for ${DOCKER_TARGET}" VERBATIM
)
else ()
@@ -248,7 +242,8 @@ function(celix_docker_bundles)
COMMENT "Copying bundle '${BUNDLE}' to '${OUT}'"
DEPENDS ${BUNDLE}
)
- add_dependencies(${DOCKER_TARGET} ${BUNDLE}_bundle) #ensure the the deploy depends on the _bundle target, custom_command depends on add_library
+ get_target_property(BUILD_BUNDLE_TARGET ${BUNDLE} BUNDLE_BUILD_BUNDLE_TARGET)
+ add_dependencies(${DOCKER_TARGET} ${BUILD_BUNDLE_TARGET}) #ensure the the deploy depends on the _bundle target, custom_command depends on add_library
endif()
list(APPEND DEPS "${OUT}")
endforeach()
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/deployment_admin/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/deployment_admin/CMakeLists.txt b/deployment_admin/CMakeLists.txt
index 4a06be5..3eb38ec 100644
--- a/deployment_admin/CMakeLists.txt
+++ b/deployment_admin/CMakeLists.txt
@@ -57,7 +57,7 @@ if (DEPLOYMENT_ADMIN)
add_library(Celix::deployment_admin ALIAS deployment_admin)
add_deploy(deployment-admin
- BUNDLES Celix::deployment_admin Celix::shell Celix::shell_tui log_service log_writer
+ BUNDLES Celix::deployment_admin Celix::shell Celix::shell_tui Celix::log_service Celix::log_writer_stdout
PROPERTIES
"deployment_admin_url=http://localhost:8080"
"deployment_admin_identification=celix"
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/examples/dm_example_cxx/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/examples/dm_example_cxx/CMakeLists.txt b/examples/dm_example_cxx/CMakeLists.txt
index 1a47113..012f706 100644
--- a/examples/dm_example_cxx/CMakeLists.txt
+++ b/examples/dm_example_cxx/CMakeLists.txt
@@ -36,9 +36,9 @@ if (BUILD_DEPENDENCY_MANAGER_CXX)
BUNDLES
Celix::shell
Celix::shell_tui
- dm_shell
- log_service
- log_writer
+ Celix::dm_shell
+ Celix::log_service
+ Celix::log_writer_stdout
phase1_cxx
phase2a_cxx
@@ -55,11 +55,11 @@ if (BUILD_DEPENDENCY_MANAGER_CXX)
BUNDLES_DIR /usr/share/bundles
WORKDIR /workspace
BUNDLES
- celix_shell
- shell_tui
- dm_shell
- log_service
- log_writer
+ Celix::shell
+ Celix::shell_tui
+ Celix::dm_shell
+ Celix::log_service
+ Celix::log_writer_stdout
phase1_cxx
phase2a_cxx
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/examples/dm_example_cxx/phase1/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/examples/dm_example_cxx/phase1/CMakeLists.txt b/examples/dm_example_cxx/phase1/CMakeLists.txt
index 728278b..62b1658 100644
--- a/examples/dm_example_cxx/phase1/CMakeLists.txt
+++ b/examples/dm_example_cxx/phase1/CMakeLists.txt
@@ -35,8 +35,8 @@ IF(APPLE)
else()
if(ENABLE_ADDRESS_SANITIZER)
#With asan there can be undefined symbols
- target_link_libraries(phase1_cxx -Wl,--whole-archive dependency_manager_cxx_static -Wl,--no-whole-archive Celix::shell_api)
+ target_link_libraries(phase1_cxx PRIVATE -Wl,--whole-archive dependency_manager_cxx_static -Wl,--no-whole-archive Celix::shell_api)
else()
- target_link_libraries(phase1_cxx -Wl,--no-undefined -Wl,--whole-archive dependency_manager_cxx_static -Wl,--no-whole-archive Celix::shell_api)
+ target_link_libraries(phase1_cxx PRIVATE -Wl,--no-undefined -Wl,--whole-archive dependency_manager_cxx_static -Wl,--no-whole-archive Celix::shell_api)
endif()
endif()
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/examples/hello_world/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/examples/hello_world/CMakeLists.txt b/examples/hello_world/CMakeLists.txt
index 7cb590f..ca72eec 100644
--- a/examples/hello_world/CMakeLists.txt
+++ b/examples/hello_world/CMakeLists.txt
@@ -32,7 +32,7 @@ add_library(hello_test2lib SHARED
)
set_library_version(hello_test2lib "3.3.3")
-add_bundle(hello
+add_bundle(hello_bundle
VERSION "1.2"
SOURCES
private/src/activator.c
@@ -45,19 +45,19 @@ add_bundle(hello_export
EXPORT_LIBRARIES hello_test2lib
)
-bundle_private_libs(hello
+bundle_private_libs(hello_bundle
hello_testlib
)
add_deploy(helloworld_byref
GROUP hello
- BUNDLES hello_export hello ${CELIX_SHELL_BUNDLE} ${CELIX_SHELL_TUI_BUNDLE}
+ BUNDLES hello_export hello_bundle ${CELIX_SHELL_BUNDLE} ${CELIX_SHELL_TUI_BUNDLE}
)
add_deploy(helloworld_withcopy
GROUP hello
COPY #Ensures that bundles are copied in the deploy location
- BUNDLES hello_export hello ${SHELL_BUNDLE} ${SHELL_TUI_BUNDLE}
+ BUNDLES hello_export hello_bundle ${SHELL_BUNDLE} ${SHELL_TUI_BUNDLE}
)
endif()
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/examples/services_example_c/bar/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/examples/services_example_c/bar/CMakeLists.txt b/examples/services_example_c/bar/CMakeLists.txt
index 2332931..0633c06 100644
--- a/examples/services_example_c/bar/CMakeLists.txt
+++ b/examples/services_example_c/bar/CMakeLists.txt
@@ -32,8 +32,8 @@ IF(APPLE)
else()
if(ENABLE_ADDRESS_SANITIZER)
#With asan there can be undefined symbols
- target_link_libraries(bar -Wl,--whole-archive dependency_manager_static -Wl,--no-whole-archive Celix::framework )
+ target_link_libraries(bar PRIVATE -Wl,--whole-archive dependency_manager_static -Wl,--no-whole-archive Celix::framework )
else()
- target_link_libraries(bar -Wl,--no-undefined -Wl,--whole-archive dependency_manager_static -Wl,--no-whole-archive Celix::framework )
+ target_link_libraries(bar PRIVATE -Wl,--no-undefined -Wl,--whole-archive dependency_manager_static -Wl,--no-whole-archive Celix::framework )
endif()
endif()
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/log_writer/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/log_writer/CMakeLists.txt b/log_writer/CMakeLists.txt
index a742af2..340af15 100644
--- a/log_writer/CMakeLists.txt
+++ b/log_writer/CMakeLists.txt
@@ -19,5 +19,9 @@ celix_subproject(LOG_WRITER "Option to enable building the Log Writer bundles" O
if (LOG_WRITER)
add_subdirectory(log_writer)
add_subdirectory(log_writer_stdout)
- add_subdirectory(log_writer_syslog)
+ add_subdirectory(log_writer_syslog)
+
+ #Setup target aliases to match external usage
+ add_library(Celix::log_writer_stdout ALIAS log_writer_stdout)
+ add_library(Celix::log_writer_syslog ALIAS log_writer_syslog)
endif (LOG_WRITER)
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/log_writer/README.md
----------------------------------------------------------------------
diff --git a/log_writer/README.md b/log_writer/README.md
index 6de181d..29aebcc 100644
--- a/log_writer/README.md
+++ b/log_writer/README.md
@@ -1,7 +1,13 @@
-## Log Writer
+# Log Writer
The Celix Log Writers are components that read/listen to the Log Service and print the Log entries to the console or syslog, respectively.
-###### CMake options
+## CMake options
BUILD_LOG_WRITER=ON
BUILD_LOG_WRITER_SYSLOG=ON
+
+## Using info
+
+If the Celix Log Writers is installed The `FindCelix.cmake` will set:
+ - The `Celix::log_writer_stdout` bundle target
+ - The `Celix::log_writer_syslog` bundle target
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/log_writer/log_writer_stdout/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/log_writer/log_writer_stdout/CMakeLists.txt b/log_writer/log_writer_stdout/CMakeLists.txt
index 11734cc..6070b2e 100644
--- a/log_writer/log_writer_stdout/CMakeLists.txt
+++ b/log_writer/log_writer_stdout/CMakeLists.txt
@@ -15,18 +15,14 @@
# specific language governing permissions and limitations
# under the License.
-add_bundle(log_writer
+add_bundle(log_writer_stdout
SYMBOLIC_NAME "apache_celix_log_writer"
VERSION "1.1.0"
NAME "Apache Celix Log Writer"
SOURCES
- #${PROJECT_SOURCE_DIR}/log_writer/log_writer/private/src/log_writer_activator
- #${PROJECT_SOURCE_DIR}/log_writer/log_writer/private/src/log_writer
- #${PROJECT_SOURCE_DIR}/log_writer/log_writer/private/include/log_writer.h
-
src/log_writer_stdout
)
-install_bundle(log_writer)
+install_bundle(log_writer_stdout)
-target_link_libraries(log_writer PRIVATE Celix::log_service_api log_writer_common)
\ No newline at end of file
+target_link_libraries(log_writer_stdout PRIVATE Celix::log_service_api log_writer_common)
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/log_writer/log_writer_syslog/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/log_writer/log_writer_syslog/CMakeLists.txt b/log_writer/log_writer_syslog/CMakeLists.txt
index caad713..b98b914 100644
--- a/log_writer/log_writer_syslog/CMakeLists.txt
+++ b/log_writer/log_writer_syslog/CMakeLists.txt
@@ -23,10 +23,6 @@ if (LOG_WRITER_SYSLOG)
SYMBOLIC_NAME "apache_celix_log_writer_syslog"
NAME "Apache Celix Log Writer Syslog"
SOURCES
-
- #${PROJECT_SOURCE_DIR}/log_writer/log_writer/private/src/log_writer_activator
- #${PROJECT_SOURCE_DIR}/log_writer/log_writer/private/src/log_writer
- #${PROJECT_SOURCE_DIR}/log_writer/log_writer/private/include/log_writer.h
private/src/log_writer_syslog
)
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/pubsub/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/pubsub/CMakeLists.txt b/pubsub/CMakeLists.txt
index a866ba4..9d18175 100644
--- a/pubsub/CMakeLists.txt
+++ b/pubsub/CMakeLists.txt
@@ -43,7 +43,7 @@ if (PUBSUB)
endif()
#api target
- add_libary(pubsub_api INTERFACE)
+ add_library(pubsub_api INTERFACE)
target_include_directories(pubsub_api INTERFACE api)
#install api
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/pubsub/deploy/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/pubsub/deploy/CMakeLists.txt b/pubsub/deploy/CMakeLists.txt
index 6f9234d..e76f91b 100644
--- a/pubsub/deploy/CMakeLists.txt
+++ b/pubsub/deploy/CMakeLists.txt
@@ -165,7 +165,7 @@ if (BUILD_PUBSUB_PSA_ZMQ)
add_deploy("pubsub_mp_subscriber_zmq"
GROUP "pubsub"
BUNDLES
- Celix::hell
+ Celix::shell
Celix::shell_tui
org.apache.celix.pubsub_serializer.PubSubSerializerJson
org.apache.celix.pubsub_discovery.etcd.PubsubDiscovery
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/pubsub/examples/mp_pubsub/publisher/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/pubsub/examples/mp_pubsub/publisher/CMakeLists.txt b/pubsub/examples/mp_pubsub/publisher/CMakeLists.txt
index 76a01f1..1ef8645 100644
--- a/pubsub/examples/mp_pubsub/publisher/CMakeLists.txt
+++ b/pubsub/examples/mp_pubsub/publisher/CMakeLists.txt
@@ -47,4 +47,4 @@ bundle_files(org.apache.celix.pubsub_publisher.MpPublisher
DESTINATION "META-INF/keys/subscriber"
)
-target_link_libraries(org.apache.celix.pubsub_publisher.MpPublisher celix_framework celix_utils)
+target_link_libraries(org.apache.celix.pubsub_publisher.MpPublisher PRIVATE Celix::framework)
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/pubsub/examples/mp_pubsub/subscriber/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/pubsub/examples/mp_pubsub/subscriber/CMakeLists.txt b/pubsub/examples/mp_pubsub/subscriber/CMakeLists.txt
index a480a73..e281ab1 100644
--- a/pubsub/examples/mp_pubsub/subscriber/CMakeLists.txt
+++ b/pubsub/examples/mp_pubsub/subscriber/CMakeLists.txt
@@ -47,4 +47,4 @@ bundle_files(org.apache.celix.pubsub_subscriber.MpSubscriber
DESTINATION "META-INF/keys/publisher"
)
-target_link_libraries(org.apache.celix.pubsub_subscriber.MpSubscriber celix_framework celix_utils)
+target_link_libraries(org.apache.celix.pubsub_subscriber.MpSubscriber PRIVATE Celix::framework)
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/pubsub/examples/pubsub/publisher/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/pubsub/examples/pubsub/publisher/CMakeLists.txt b/pubsub/examples/pubsub/publisher/CMakeLists.txt
index e35c137..fcf50c7 100644
--- a/pubsub/examples/pubsub/publisher/CMakeLists.txt
+++ b/pubsub/examples/pubsub/publisher/CMakeLists.txt
@@ -51,4 +51,4 @@ bundle_files(org.apache.celix.pubsub_publisher.PoiPublisher
DESTINATION "META-INF/keys/subscriber"
)
-target_link_libraries(org.apache.celix.pubsub_publisher.PoiPublisher celix_framework celix_utils)
+target_link_libraries(org.apache.celix.pubsub_publisher.PoiPublisher PRIVATE Celix::framework)
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/pubsub/examples/pubsub/publisher2/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/pubsub/examples/pubsub/publisher2/CMakeLists.txt b/pubsub/examples/pubsub/publisher2/CMakeLists.txt
index b83f7dd..82ffb75 100644
--- a/pubsub/examples/pubsub/publisher2/CMakeLists.txt
+++ b/pubsub/examples/pubsub/publisher2/CMakeLists.txt
@@ -51,4 +51,4 @@ bundle_files(org.apache.celix.pubsub_publisher.PoiPublisher2
DESTINATION "META-INF/keys/subscriber"
)
-target_link_libraries(org.apache.celix.pubsub_publisher.PoiPublisher2 celix_framework celix_utils)
+target_link_libraries(org.apache.celix.pubsub_publisher.PoiPublisher2 PRIVATE Celix::framework)
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/pubsub/examples/pubsub/subscriber/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/pubsub/examples/pubsub/subscriber/CMakeLists.txt b/pubsub/examples/pubsub/subscriber/CMakeLists.txt
index 7fd9fae..28569b0 100644
--- a/pubsub/examples/pubsub/subscriber/CMakeLists.txt
+++ b/pubsub/examples/pubsub/subscriber/CMakeLists.txt
@@ -52,4 +52,4 @@ bundle_files(org.apache.celix.pubsub_subscriber.PoiSubscriber
DESTINATION "META-INF/keys/publisher"
)
-target_link_libraries(org.apache.celix.pubsub_subscriber.PoiSubscriber celix_framework celix_utils)
+target_link_libraries(org.apache.celix.pubsub_subscriber.PoiSubscriber PRIVATE Celix::framework)
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/pubsub/pubsub_admin_udp_mc/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_admin_udp_mc/CMakeLists.txt b/pubsub/pubsub_admin_udp_mc/CMakeLists.txt
index 3ab0c54..a57693f 100644
--- a/pubsub/pubsub_admin_udp_mc/CMakeLists.txt
+++ b/pubsub/pubsub_admin_udp_mc/CMakeLists.txt
@@ -17,32 +17,28 @@
find_package(Jansson REQUIRED)
-include_directories("${PROJECT_SOURCE_DIR}/utils/public/include")
-include_directories("${PROJECT_SOURCE_DIR}/log_service/public/include")
-include_directories("${PROJECT_SOURCE_DIR}/dfi/public/include")
-include_directories("${PROJECT_SOURCE_DIR}/pubsub/pubsub_common/public/include")
-include_directories("${PROJECT_SOURCE_DIR}/pubsub/api/pubsub")
-include_directories("private/include")
-include_directories("public/include")
-include_directories("${JANSSON_INCLUDE_DIR}")
-
add_bundle(org.apache.celix.pubsub_admin.PubSubAdminUdpMc
BUNDLE_SYMBOLICNAME "apache_celix_pubsub_admin_udp_multicast"
VERSION "1.0.0"
SOURCES
- private/src/psa_activator.c
- private/src/pubsub_admin_impl.c
- private/src/topic_subscription.c
- private/src/topic_publication.c
- private/src/large_udp.c
- ${PROJECT_SOURCE_DIR}/log_service/public/src/log_helper.c
+ src/psa_activator.c
+ src/pubsub_admin_impl.c
+ src/topic_subscription.c
+ src/topic_publication.c
+ src/large_udp.c
${PROJECT_SOURCE_DIR}/pubsub/pubsub_common/public/src/pubsub_endpoint.c
${PROJECT_SOURCE_DIR}/pubsub/pubsub_common/public/src/pubsub_admin_match.c
${PROJECT_SOURCE_DIR}/pubsub/pubsub_common/public/src/pubsub_utils.c
)
+
+target_include_directories(org.apache.celix.pubsub_admin.PubSubAdminUdpMc PRIVATE
+ src
+ ${JANSSON_INCLUDE_DIR}
+)
+
set_target_properties(org.apache.celix.pubsub_admin.PubSubAdminUdpMc PROPERTIES INSTALL_RPATH "$ORIGIN")
-target_link_libraries(org.apache.celix.pubsub_admin.PubSubAdminUdpMc celix_framework celix_utils celix_dfi)
+target_link_libraries(org.apache.celix.pubsub_admin.PubSubAdminUdpMc PRIVATE Celix::framework Celix::dfi Celix::log_helper)
install_bundle(org.apache.celix.pubsub_admin.PubSubAdminUdpMc)
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/pubsub/pubsub_admin_udp_mc/private/include/large_udp.h
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_admin_udp_mc/private/include/large_udp.h b/pubsub/pubsub_admin_udp_mc/private/include/large_udp.h
deleted file mode 100644
index a21e654..0000000
--- a/pubsub/pubsub_admin_udp_mc/private/include/large_udp.h
+++ /dev/null
@@ -1,45 +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.
- */
-/*
- * large_udp.h
- *
- * \date Mar 1, 2016
- * \author <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- * \copyright Apache License, Version 2.0
- */
-
-#ifndef _LARGE_UDP_H_
-#define _LARGE_UDP_H_
-#include <stdbool.h>
-#include <stdlib.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-
-typedef struct largeUdp *largeUdp_pt;
-
-largeUdp_pt largeUdp_create(unsigned int maxNrUdpReceptions);
-void largeUdp_destroy(largeUdp_pt handle);
-
-int largeUdp_sendto(largeUdp_pt handle, int fd, void *buf, size_t count, int flags, struct sockaddr_in *dest_addr, size_t addrlen);
-int largeUdp_sendmsg(largeUdp_pt handle, int fd, struct iovec *largeMsg_iovec, int len, int flags, struct sockaddr_in *dest_addr, size_t addrlen);
-bool largeUdp_dataAvailable(largeUdp_pt handle, int fd, unsigned int *index, unsigned int *size);
-int largeUdp_read(largeUdp_pt handle, unsigned int index, void ** buffer, unsigned int size);
-
-#endif /* _LARGE_UDP_H_ */
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/pubsub/pubsub_admin_udp_mc/private/include/pubsub_admin_impl.h
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_admin_udp_mc/private/include/pubsub_admin_impl.h b/pubsub/pubsub_admin_udp_mc/private/include/pubsub_admin_impl.h
deleted file mode 100644
index de4b813..0000000
--- a/pubsub/pubsub_admin_udp_mc/private/include/pubsub_admin_impl.h
+++ /dev/null
@@ -1,93 +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.
- */
-/*
- * pubsub_admin_impl.h
- *
- * \date Dec 5, 2013
- * \author <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- * \copyright Apache License, Version 2.0
- */
-
-#ifndef PUBSUB_ADMIN_UDP_MC_IMPL_H_
-#define PUBSUB_ADMIN_UDP_MC_IMPL_H_
-
-#include "pubsub_admin.h"
-#include "log_helper.h"
-
-#define PUBSUB_ADMIN_TYPE "udp_mc"
-
-struct pubsub_admin {
-
- bundle_context_pt bundle_context;
- log_helper_pt loghelper;
-
- /* List of the available serializers */
- celix_thread_mutex_t serializerListLock; // List<serializers>
- array_list_pt serializerList;
-
- celix_thread_mutex_t localPublicationsLock;
- hash_map_pt localPublications;//<topic(string),service_factory_pt>
-
- celix_thread_mutex_t externalPublicationsLock;
- hash_map_pt externalPublications;//<topic(string),List<pubsub_ep>>
-
- celix_thread_mutex_t subscriptionsLock;
- hash_map_pt subscriptions; //<topic(string),topic_subscription>
-
- celix_thread_mutex_t pendingSubscriptionsLock;
- celix_thread_mutexattr_t pendingSubscriptionsAttr;
- hash_map_pt pendingSubscriptions; //<topic(string),List<pubsub_ep>>
-
- /* Those are used to keep track of valid subscriptions/publications that still have no valid serializer */
- celix_thread_mutex_t noSerializerPendingsLock;
- celix_thread_mutexattr_t noSerializerPendingsAttr;
- array_list_pt noSerializerSubscriptions; // List<pubsub_ep>
- array_list_pt noSerializerPublications; // List<pubsub_ep>
-
- celix_thread_mutex_t usedSerializersLock;
- hash_map_pt topicSubscriptionsPerSerializer; // <serializer,List<topicSubscription>>
- hash_map_pt topicPublicationsPerSerializer; // <serializer,List<topicPublications>>
-
- char* ifIpAddress; // The local interface which is used for multicast communication
- char* mcIpAddress; // The multicast IP address
-
- int sendSocket;
- void* zmq_context; // to be removed
-
-};
-
-celix_status_t pubsubAdmin_create(bundle_context_pt context, pubsub_admin_pt *admin);
-celix_status_t pubsubAdmin_destroy(pubsub_admin_pt admin);
-
-celix_status_t pubsubAdmin_addSubscription(pubsub_admin_pt admin,pubsub_endpoint_pt subEP);
-celix_status_t pubsubAdmin_removeSubscription(pubsub_admin_pt admin,pubsub_endpoint_pt subEP);
-
-celix_status_t pubsubAdmin_addPublication(pubsub_admin_pt admin,pubsub_endpoint_pt pubEP);
-celix_status_t pubsubAdmin_removePublication(pubsub_admin_pt admin,pubsub_endpoint_pt pubEP);
-
-celix_status_t pubsubAdmin_closeAllPublications(pubsub_admin_pt admin,char* scope, char* topic);
-celix_status_t pubsubAdmin_closeAllSubscriptions(pubsub_admin_pt admin,char* scope, char* topic);
-
-celix_status_t pubsubAdmin_serializerAdded(void * handle, service_reference_pt reference, void * service);
-celix_status_t pubsubAdmin_serializerRemoved(void * handle, service_reference_pt reference, void * service);
-
-celix_status_t pubsubAdmin_matchEndpoint(pubsub_admin_pt admin, pubsub_endpoint_pt endpoint, double* score);
-
-
-#endif /* PUBSUB_ADMIN_UDP_MC_IMPL_H_ */
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/pubsub/pubsub_admin_udp_mc/private/include/topic_publication.h
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_admin_udp_mc/private/include/topic_publication.h b/pubsub/pubsub_admin_udp_mc/private/include/topic_publication.h
deleted file mode 100644
index 4363d71..0000000
--- a/pubsub/pubsub_admin_udp_mc/private/include/topic_publication.h
+++ /dev/null
@@ -1,57 +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.
- */
-/*
- * topic_publication.h
- *
- * \date Sep 24, 2015
- * \author <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- * \copyright Apache License, Version 2.0
- */
-
-#ifndef TOPIC_PUBLICATION_H_
-#define TOPIC_PUBLICATION_H_
-
-#include "publisher.h"
-#include "pubsub_endpoint.h"
-#include "pubsub_common.h"
-
-#include "pubsub_serializer.h"
-
-#define UDP_BASE_PORT 49152
-#define UDP_MAX_PORT 65000
-
-typedef struct pubsub_udp_msg {
- struct pubsub_msg_header header;
- unsigned int payloadSize;
- char payload[];
-} pubsub_udp_msg_t;
-
-typedef struct topic_publication *topic_publication_pt;
-celix_status_t pubsub_topicPublicationCreate(int sendSocket, pubsub_endpoint_pt pubEP, pubsub_serializer_service_t *best_serializer, char* bindIP, topic_publication_pt *out);
-celix_status_t pubsub_topicPublicationDestroy(topic_publication_pt pub);
-
-celix_status_t pubsub_topicPublicationAddPublisherEP(topic_publication_pt pub,pubsub_endpoint_pt ep);
-celix_status_t pubsub_topicPublicationRemovePublisherEP(topic_publication_pt pub,pubsub_endpoint_pt ep);
-
-celix_status_t pubsub_topicPublicationStart(bundle_context_pt bundle_context,topic_publication_pt pub,service_factory_pt* svcFactory);
-celix_status_t pubsub_topicPublicationStop(topic_publication_pt pub);
-
-array_list_pt pubsub_topicPublicationGetPublisherList(topic_publication_pt pub);
-
-#endif /* TOPIC_PUBLICATION_H_ */
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/pubsub/pubsub_admin_udp_mc/private/include/topic_subscription.h
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_admin_udp_mc/private/include/topic_subscription.h b/pubsub/pubsub_admin_udp_mc/private/include/topic_subscription.h
deleted file mode 100644
index 475416a..0000000
--- a/pubsub/pubsub_admin_udp_mc/private/include/topic_subscription.h
+++ /dev/null
@@ -1,60 +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.
- */
-/*
- * topic_subscription.h
- *
- * \date Sep 22, 2015
- * \author <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- * \copyright Apache License, Version 2.0
- */
-
-#ifndef TOPIC_SUBSCRIPTION_H_
-#define TOPIC_SUBSCRIPTION_H_
-
-#include "celix_threads.h"
-#include "array_list.h"
-#include "celixbool.h"
-#include "service_tracker.h"
-
-#include "pubsub_endpoint.h"
-#include "pubsub_common.h"
-#include "pubsub_serializer.h"
-
-typedef struct topic_subscription* topic_subscription_pt;
-
-celix_status_t pubsub_topicSubscriptionCreate(bundle_context_pt bundle_context, char* ifIp,char* scope, char* topic ,pubsub_serializer_service_t *best_serializer, topic_subscription_pt* out);
-celix_status_t pubsub_topicSubscriptionDestroy(topic_subscription_pt ts);
-celix_status_t pubsub_topicSubscriptionStart(topic_subscription_pt ts);
-celix_status_t pubsub_topicSubscriptionStop(topic_subscription_pt ts);
-
-celix_status_t pubsub_topicSubscriptionAddConnectPublisherToPendingList(topic_subscription_pt ts, char* pubURL);
-celix_status_t pubsub_topicSubscriptionAddDisconnectPublisherToPendingList(topic_subscription_pt ts, char* pubURL);
-
-celix_status_t pubsub_topicSubscriptionConnectPublisher(topic_subscription_pt ts, char* pubURL);
-celix_status_t pubsub_topicSubscriptionDisconnectPublisher(topic_subscription_pt ts, char* pubURL);
-
-celix_status_t pubsub_topicSubscriptionAddSubscriber(topic_subscription_pt ts, pubsub_endpoint_pt subEP);
-celix_status_t pubsub_topicSubscriptionRemoveSubscriber(topic_subscription_pt ts, pubsub_endpoint_pt subEP);
-
-array_list_pt pubsub_topicSubscriptionGetSubscribersList(topic_subscription_pt sub);
-celix_status_t pubsub_topicIncreaseNrSubscribers(topic_subscription_pt subscription);
-celix_status_t pubsub_topicDecreaseNrSubscribers(topic_subscription_pt subscription);
-unsigned int pubsub_topicGetNrSubscribers(topic_subscription_pt subscription);
-
-#endif /*TOPIC_SUBSCRIPTION_H_ */
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/pubsub/pubsub_admin_udp_mc/private/src/large_udp.c
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_admin_udp_mc/private/src/large_udp.c b/pubsub/pubsub_admin_udp_mc/private/src/large_udp.c
deleted file mode 100644
index 7455925..0000000
--- a/pubsub/pubsub_admin_udp_mc/private/src/large_udp.c
+++ /dev/null
@@ -1,372 +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.
- */
-/*
- * large_udp.c
- *
- * \date Mar 1, 2016
- * \author <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- * \copyright Apache License, Version 2.0
- */
-
-#include "large_udp.h"
-
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <array_list.h>
-#include <pthread.h>
-
-#define MAX_UDP_MSG_SIZE 65535 /* 2^16 -1 */
-#define IP_HEADER_SIZE 20
-#define UDP_HEADER_SIZE 8
-//#define MTU_SIZE 1500
-#define MTU_SIZE 8000
-#define MAX_MSG_VECTOR_LEN 64
-
-//#define NO_IP_FRAGMENTATION
-
-struct largeUdp {
- unsigned int maxNrLists;
- array_list_pt udpPartLists;
- pthread_mutex_t dbLock;
-};
-
-typedef struct udpPartList {
- unsigned int msg_ident;
- unsigned int msg_size;
- unsigned int nrPartsRemaining;
- char *data;
-} *udpPartList_pt;
-
-
-typedef struct msg_part_header {
- unsigned int msg_ident;
- unsigned int total_msg_size;
- unsigned int part_msg_size;
- unsigned int offset;
-} msg_part_header_t;
-
-#ifdef NO_IP_FRAGMENTATION
-#define MAX_PART_SIZE (MTU_SIZE - (IP_HEADER_SIZE + UDP_HEADER_SIZE + sizeof(struct msg_part_header) ))
-#else
-#define MAX_PART_SIZE (MAX_UDP_MSG_SIZE - (IP_HEADER_SIZE + UDP_HEADER_SIZE + sizeof(struct msg_part_header) ))
-#endif
-
-typedef struct msg_part {
- msg_part_header_t header;
- char data[MAX_PART_SIZE];
-} msg_part_t;
-
-//
-// Create a handle
-//
-largeUdp_pt largeUdp_create(unsigned int maxNrUdpReceptions)
-{
- printf("## Creating large UDP\n");
- largeUdp_pt handle = calloc(sizeof(*handle), 1);
- if(handle != NULL) {
- handle->maxNrLists = maxNrUdpReceptions;
- if(arrayList_create(&handle->udpPartLists) != CELIX_SUCCESS) {
- free(handle);
- handle = NULL;
- }
- pthread_mutex_init(&handle->dbLock, 0);
- }
-
- return handle;
-}
-
-//
-// Destroys the handle
-//
-void largeUdp_destroy(largeUdp_pt handle)
-{
- printf("### Destroying large UDP\n");
- if(handle != NULL) {
- pthread_mutex_lock(&handle->dbLock);
- int nrUdpLists = arrayList_size(handle->udpPartLists);
- int i;
- for(i=0; i < nrUdpLists; i++) {
- udpPartList_pt udpPartList = arrayList_remove(handle->udpPartLists, i);
- if(udpPartList) {
- if(udpPartList->data) {
- free(udpPartList->data);
- udpPartList->data = NULL;
- }
- free(udpPartList);
- }
- }
- arrayList_destroy(handle->udpPartLists);
- handle->udpPartLists = NULL;
- pthread_mutex_unlock(&handle->dbLock);
- pthread_mutex_destroy(&handle->dbLock);
- free(handle);
- }
-}
-
-//
-// Write large data to UDP. This function splits the data in chunks and sends these chunks with a header over UDP.
-//
-int largeUdp_sendmsg(largeUdp_pt handle, int fd, struct iovec *largeMsg_iovec, int len, int flags, struct sockaddr_in *dest_addr, size_t addrlen)
-{
- int n;
- int result = 0;
- msg_part_header_t header;
-
- int written = 0;
- header.msg_ident = (unsigned int)random();
- header.total_msg_size = 0;
- for(n = 0; n < len ;n++) {
- header.total_msg_size += largeMsg_iovec[n].iov_len;
- }
- int nr_buffers = (header.total_msg_size / MAX_PART_SIZE) + 1;
-
- struct iovec msg_iovec[MAX_MSG_VECTOR_LEN];
- struct msghdr msg;
- msg.msg_name = dest_addr;
- msg.msg_namelen = addrlen;
- msg.msg_flags = 0;
- msg.msg_iov = msg_iovec;
- msg.msg_iovlen = 2; // header and payload;
- msg.msg_control = NULL;
- msg.msg_controllen = 0;
-
- msg.msg_iov[0].iov_base = &header;
- msg.msg_iov[0].iov_len = sizeof(header);
-
- for(n = 0; n < nr_buffers; n++) {
-
- header.part_msg_size = (((header.total_msg_size - n * MAX_PART_SIZE) > MAX_PART_SIZE) ? MAX_PART_SIZE : (header.total_msg_size - n * MAX_PART_SIZE));
- header.offset = n * MAX_PART_SIZE;
- int remainingOffset = header.offset;
- int recvPart = 0;
- // find the start of the part
- while(remainingOffset > largeMsg_iovec[recvPart].iov_len) {
- remainingOffset -= largeMsg_iovec[recvPart].iov_len;
- recvPart++;
- }
- int remainingData = header.part_msg_size;
- int sendPart = 1;
- msg.msg_iovlen = 1;
-
- // fill in the output iovec from the input iovec in such a way that all UDP frames are filled maximal.
- while(remainingData > 0) {
- int partLen = ( (largeMsg_iovec[recvPart].iov_len - remainingOffset) <= remainingData ? (largeMsg_iovec[recvPart].iov_len -remainingOffset) : remainingData);
- msg.msg_iov[sendPart].iov_base = largeMsg_iovec[recvPart].iov_base + remainingOffset;
- msg.msg_iov[sendPart].iov_len = partLen;
- remainingData -= partLen;
- remainingOffset = 0;
- sendPart++;
- recvPart++;
- msg.msg_iovlen++;
- }
- int tmp, tmptot;
- for(tmp = 0, tmptot=0; tmp < msg.msg_iovlen; tmp++) {
- tmptot += msg.msg_iov[tmp].iov_len;
- }
-
- int w = sendmsg(fd, &msg, 0);
- if(w == -1) {
- perror("send()");
- result = -1;
- break;
- }
- written += w;
- }
-
- return (result == 0 ? written : result);
-}
-
-//
-// Write large data to UDP. This function splits the data in chunks and sends these chunks with a header over UDP.
-//
-int largeUdp_sendto(largeUdp_pt handle, int fd, void *buf, size_t count, int flags, struct sockaddr_in *dest_addr, size_t addrlen)
-{
- int n;
- int nr_buffers = (count / MAX_PART_SIZE) + 1;
- int result = 0;
- msg_part_header_t header;
-
- int written = 0;
- header.msg_ident = (unsigned int)random();
- header.total_msg_size = count;
- char *databuf = buf;
-
- struct iovec msg_iovec[2];
- struct msghdr msg;
- msg.msg_name = dest_addr;
- msg.msg_namelen = addrlen;
- msg.msg_flags = 0;
- msg.msg_iov = msg_iovec;
- msg.msg_iovlen = 2; // header and payload;
- msg.msg_control = NULL;
- msg.msg_controllen = 0;
-
- msg.msg_iov[0].iov_base = &header;
- msg.msg_iov[0].iov_len = sizeof(header);
-
- for(n = 0; n < nr_buffers; n++) {
-
- header.part_msg_size = (((header.total_msg_size - n * MAX_PART_SIZE) > MAX_PART_SIZE) ? MAX_PART_SIZE : (header.total_msg_size - n * MAX_PART_SIZE));
- header.offset = n * MAX_PART_SIZE;
- msg.msg_iov[1].iov_base = &databuf[header.offset];
- msg.msg_iov[1].iov_len = header.part_msg_size;
- int w = sendmsg(fd, &msg, 0);
- if(w == -1) {
- perror("send()");
- result = -1;
- break;
- }
- written += w;
- //usleep(1000); // TODO: If not slept a UDP buffer overflow occurs and parts are missing at the reception side (at least via localhost)
- }
-
- return (result == 0 ? written : result);
-}
-
-//
-// Reads data from the filedescriptor which has date (determined by epoll()) and stores it in the internal structure
-// If the message is completely reassembled true is returned and the index and size have valid values
-//
-bool largeUdp_dataAvailable(largeUdp_pt handle, int fd, unsigned int *index, unsigned int *size) {
- msg_part_header_t header;
- int result = false;
- // Only read the header, we don't know yet where to store the payload
- if(recv(fd, &header, sizeof(header), MSG_PEEK) < 0) {
- perror("read()");
- return false;
- }
-
- struct iovec msg_vec[2];
- struct msghdr msg;
- msg.msg_name = NULL;
- msg.msg_namelen = 0;
- msg.msg_flags = 0;
- msg.msg_iov = msg_vec;
- msg.msg_iovlen = 2; // header and payload;
- msg.msg_control = NULL;
- msg.msg_controllen = 0;
-
- msg.msg_iov[0].iov_base = &header;
- msg.msg_iov[0].iov_len = sizeof(header);
-
- pthread_mutex_lock(&handle->dbLock);
-
- int nrUdpLists = arrayList_size(handle->udpPartLists);
- int i;
- bool found = false;
- for(i = 0; i < nrUdpLists; i++) {
- udpPartList_pt udpPartList = arrayList_get(handle->udpPartLists, i);
- if(udpPartList->msg_ident == header.msg_ident) {
- found = true;
-
- //sanity check
- if(udpPartList->msg_size != header.total_msg_size) {
- // Corruption occurred. Remove the existing administration and build up a new one.
- arrayList_remove(handle->udpPartLists, i);
- free(udpPartList->data);
- free(udpPartList);
- found = false;
- break;
- }
-
- msg.msg_iov[1].iov_base = &udpPartList->data[header.offset];
- msg.msg_iov[1].iov_len = header.part_msg_size;
- if(recvmsg(fd, &msg, 0)<0){
- found=true;
- result=false;
- break;
- }
-
- udpPartList->nrPartsRemaining--;
- if(udpPartList->nrPartsRemaining == 0) {
- *index = i;
- *size = udpPartList->msg_size;
- result = true;
- break;
- } else {
- result = false; // not complete
- break;
- }
- }
- }
-
- if(found == false) {
- udpPartList_pt udpPartList = NULL;
- if(nrUdpLists == handle->maxNrLists) {
- // remove list at index 0
- udpPartList = arrayList_remove(handle->udpPartLists, 0);
- fprintf(stderr, "ERROR: Removing entry for id %d: %d parts not received\n",udpPartList->msg_ident, udpPartList->nrPartsRemaining );
- free(udpPartList->data);
- free(udpPartList);
- nrUdpLists--;
- }
- udpPartList = calloc(sizeof(*udpPartList), 1);
- udpPartList->msg_ident = header.msg_ident;
- udpPartList->msg_size = header.total_msg_size;
- udpPartList->nrPartsRemaining = header.total_msg_size / MAX_PART_SIZE;
- udpPartList->data = calloc(sizeof(char), header.total_msg_size);
-
- msg.msg_iov[1].iov_base = &udpPartList->data[header.offset];
- msg.msg_iov[1].iov_len = header.part_msg_size;
- if(recvmsg(fd, &msg, 0)<0){
- free(udpPartList->data);
- free(udpPartList);
- result=false;
- }
- else{
- arrayList_add(handle->udpPartLists, udpPartList);
-
- if(udpPartList->nrPartsRemaining == 0) {
- *index = nrUdpLists;
- *size = udpPartList->msg_size;
- result = true;
- } else {
- result = false;
- }
- }
-
- }
-
- pthread_mutex_unlock(&handle->dbLock);
-
- return result;
-}
-
-//
-// Read out the message which is indicated available by the largeUdp_dataAvailable function
-//
-int largeUdp_read(largeUdp_pt handle, unsigned int index, void ** buffer, unsigned int size)
-{
- int result = 0;
- pthread_mutex_lock(&handle->dbLock);
-
- udpPartList_pt udpPartList = arrayList_remove(handle->udpPartLists, index);
- if(udpPartList) {
- *buffer = udpPartList->data;
- free(udpPartList);
- } else {
- result = -1;
- }
- pthread_mutex_unlock(&handle->dbLock);
-
- return result;
-}
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/pubsub/pubsub_admin_udp_mc/private/src/psa_activator.c
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_admin_udp_mc/private/src/psa_activator.c b/pubsub/pubsub_admin_udp_mc/private/src/psa_activator.c
deleted file mode 100644
index cd4ee07..0000000
--- a/pubsub/pubsub_admin_udp_mc/private/src/psa_activator.c
+++ /dev/null
@@ -1,141 +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.
- */
-/*
- * psa_activator.c
- *
- * \date Sep 30, 2011
- * \author <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- * \copyright Apache License, Version 2.0
- */
-
-#include <stdlib.h>
-
-#include "bundle_activator.h"
-#include "service_registration.h"
-#include "service_tracker.h"
-
-#include "pubsub_admin_impl.h"
-
-struct activator {
- pubsub_admin_pt admin;
- pubsub_admin_service_pt adminService;
- service_registration_pt registration;
- service_tracker_pt serializerTracker;
-};
-
-celix_status_t bundleActivator_create(bundle_context_pt context, void **userData) {
- celix_status_t status = CELIX_SUCCESS;
- struct activator *activator;
-
- activator = calloc(1, sizeof(*activator));
- if (!activator) {
- status = CELIX_ENOMEM;
- }
- else{
- *userData = activator;
-
- status = pubsubAdmin_create(context, &(activator->admin));
-
- if(status == CELIX_SUCCESS){
- service_tracker_customizer_pt customizer = NULL;
- status = serviceTrackerCustomizer_create(activator->admin,
- NULL,
- pubsubAdmin_serializerAdded,
- NULL,
- pubsubAdmin_serializerRemoved,
- &customizer);
- if(status == CELIX_SUCCESS){
- status = serviceTracker_create(context, PUBSUB_SERIALIZER_SERVICE, customizer, &(activator->serializerTracker));
- if(status != CELIX_SUCCESS){
- serviceTrackerCustomizer_destroy(customizer);
- pubsubAdmin_destroy(activator->admin);
- }
- }
- else{
- pubsubAdmin_destroy(activator->admin);
- }
- }
- }
-
- return status;
-}
-
-celix_status_t bundleActivator_start(void * userData, bundle_context_pt context) {
- celix_status_t status = CELIX_SUCCESS;
- struct activator *activator = userData;
- pubsub_admin_service_pt pubsubAdminSvc = calloc(1, sizeof(*pubsubAdminSvc));
-
- if (!pubsubAdminSvc) {
- status = CELIX_ENOMEM;
- }
- else{
- pubsubAdminSvc->admin = activator->admin;
-
- pubsubAdminSvc->addPublication = pubsubAdmin_addPublication;
- pubsubAdminSvc->removePublication = pubsubAdmin_removePublication;
-
- pubsubAdminSvc->addSubscription = pubsubAdmin_addSubscription;
- pubsubAdminSvc->removeSubscription = pubsubAdmin_removeSubscription;
-
- pubsubAdminSvc->closeAllPublications = pubsubAdmin_closeAllPublications;
- pubsubAdminSvc->closeAllSubscriptions = pubsubAdmin_closeAllSubscriptions;
-
- pubsubAdminSvc->matchEndpoint = pubsubAdmin_matchEndpoint;
-
- activator->adminService = pubsubAdminSvc;
-
- status = bundleContext_registerService(context, PUBSUB_ADMIN_SERVICE, pubsubAdminSvc, NULL, &activator->registration);
-
- status += serviceTracker_open(activator->serializerTracker);
-
- }
-
-
- return status;
-}
-
-celix_status_t bundleActivator_stop(void * userData, bundle_context_pt context) {
- celix_status_t status = CELIX_SUCCESS;
- struct activator *activator = userData;
-
- status += serviceTracker_close(activator->serializerTracker);
- status += serviceRegistration_unregister(activator->registration);
-
- activator->registration = NULL;
-
- free(activator->adminService);
- activator->adminService = NULL;
-
- return status;
-}
-
-celix_status_t bundleActivator_destroy(void * userData, bundle_context_pt context) {
- celix_status_t status = CELIX_SUCCESS;
- struct activator *activator = userData;
-
- serviceTracker_destroy(activator->serializerTracker);
- pubsubAdmin_destroy(activator->admin);
- activator->admin = NULL;
-
- free(activator);
-
- return status;
-}
-
-
[07/19] celix git commit: CELIX-417: Refactor for CMake usage in RSA,
PSA and Docker. mostly trying to identify the api and common libraries
Posted by pn...@apache.org.
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/remote_service_admin_common/src/export_registration_impl.c
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_common/src/export_registration_impl.c b/remote_services/remote_service_admin_common/src/export_registration_impl.c
new file mode 100644
index 0000000..1c684e7
--- /dev/null
+++ b/remote_services/remote_service_admin_common/src/export_registration_impl.c
@@ -0,0 +1,257 @@
+/**
+ *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.
+ */
+/*
+ * export_registration_impl.c
+ *
+ * \date Oct 6, 2011
+ * \author <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ * \copyright Apache License, Version 2.0
+ */
+#include <stdlib.h>
+
+#include "constants.h"
+
+#include "celix_errno.h"
+
+#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);
+celix_status_t exportRegistration_endpointRemoved(void * handle, service_reference_pt reference, void *service);
+
+celix_status_t exportRegistration_createEndpointTracker(export_registration_pt registration, service_tracker_pt *tracker);
+
+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 status = CELIX_SUCCESS;
+
+ *registration = calloc(1, sizeof(**registration));
+ if (!*registration) {
+ status = CELIX_ENOMEM;
+ } else {
+ (*registration)->context = context;
+ (*registration)->closed = false;
+ (*registration)->endpointDescription = endpoint;
+ (*registration)->reference = reference;
+ (*registration)->rsa = rsa;
+ (*registration)->tracker = NULL;
+ (*registration)->endpoint = NULL;
+ (*registration)->endpointTracker = NULL;
+ (*registration)->exportReference = NULL;
+ (*registration)->bundle = NULL;
+ (*registration)->loghelper = helper;
+ }
+
+ return status;
+}
+
+celix_status_t exportRegistration_destroy(export_registration_pt *registration) {
+ celix_status_t status = CELIX_SUCCESS;
+
+ remoteServiceAdmin_destroyEndpointDescription(&(*registration)->endpointDescription);
+ free(*registration);
+
+ return status;
+}
+
+celix_status_t exportRegistration_startTracking(export_registration_pt registration) {
+ celix_status_t status = CELIX_SUCCESS;
+
+ if (registration->endpointTracker == NULL) {
+ status = exportRegistration_createEndpointTracker(registration, ®istration->endpointTracker);
+ if (status == CELIX_SUCCESS) {
+ status = serviceTracker_open(registration->endpointTracker);
+ }
+ }
+
+ return status;
+}
+
+celix_status_t exportRegistration_stopTracking(export_registration_pt registration) {
+ celix_status_t status = CELIX_SUCCESS;
+
+ if (registration->endpointTracker != NULL) {
+ status = serviceTracker_close(registration->endpointTracker);
+ if (status != CELIX_SUCCESS) {
+ logHelper_log(registration->loghelper, OSGI_LOGSERVICE_ERROR, "EXPORT_REGISTRATION: Could not close endpoint tracker");
+ }
+ else {
+ status = serviceTracker_destroy(registration->endpointTracker);
+ }
+ }
+ if (registration->tracker != NULL) {
+ status = serviceTracker_close(registration->tracker);
+ if (status != CELIX_SUCCESS) {
+ logHelper_log(registration->loghelper, OSGI_LOGSERVICE_ERROR, "EXPORT_REGISTRATION: Could not close service tracker");
+ }
+ else {
+ status = serviceTracker_destroy(registration->tracker);
+ }
+ }
+
+ return status;
+}
+
+celix_status_t exportRegistration_createEndpointTracker(export_registration_pt registration, service_tracker_pt *tracker) {
+ celix_status_t status;
+
+ service_tracker_customizer_pt customizer = NULL;
+
+ status = serviceTrackerCustomizer_create(registration, exportRegistration_endpointAdding,
+ exportRegistration_endpointAdded, exportRegistration_endpointModified, exportRegistration_endpointRemoved, &customizer);
+
+ if (status == CELIX_SUCCESS) {
+ char filter[512];
+
+ snprintf(filter, 512, "(&(%s=%s)(remote.interface=%s))", (char*) OSGI_FRAMEWORK_OBJECTCLASS, (char*) OSGI_RSA_REMOTE_ENDPOINT, registration->endpointDescription->service);
+ status = serviceTracker_createWithFilter(registration->context, filter, customizer, tracker);
+ }
+
+ return status;
+}
+
+celix_status_t exportRegistration_endpointAdding(void * handle, service_reference_pt reference, void **service) {
+ celix_status_t status;
+ export_registration_pt registration = handle;
+
+ status = bundleContext_getService(registration->context, reference, service);
+
+ return status;
+}
+
+celix_status_t exportRegistration_endpointAdded(void * handle, service_reference_pt reference, void *endpoint_service) {
+ celix_status_t status = CELIX_SUCCESS;
+ export_registration_pt registration = handle;
+
+ remote_endpoint_service_pt endpoint = endpoint_service;
+ if (registration->endpoint == NULL) {
+ registration->endpoint = endpoint;
+ void *service = NULL;
+ status = bundleContext_getService(registration->context, registration->reference, &service);
+ if (status == CELIX_SUCCESS) {
+ endpoint->setService(endpoint->endpoint, service);
+ }
+ }
+
+ return status;
+}
+
+celix_status_t exportRegistration_endpointModified(void * handle, service_reference_pt reference, void *service) {
+ celix_status_t status = CELIX_SUCCESS;
+
+ return status;
+}
+
+celix_status_t exportRegistration_endpointRemoved(void * handle, service_reference_pt reference, void *service) {
+ celix_status_t status = CELIX_SUCCESS;
+ export_registration_pt registration = handle;
+
+ remote_endpoint_service_pt endpoint = service;
+ if (registration->endpoint != NULL) {
+ endpoint->setService(endpoint->endpoint, NULL);
+ }
+
+ return status;
+}
+
+celix_status_t exportRegistration_open(export_registration_pt registration) {
+ celix_status_t status = CELIX_SUCCESS;
+ const char *bundleStore = NULL;
+
+ bundleContext_getProperty(registration->context, BUNDLE_STORE_PROPERTY_NAME, &bundleStore);
+
+ if (bundleStore == NULL) {
+ bundleStore = DEFAULT_BUNDLE_STORE;
+ }
+ char name[256];
+
+ snprintf(name, 256, "%s/%s_endpoint.zip", bundleStore, registration->endpointDescription->service);
+
+ status = bundleContext_installBundle(registration->context, name, ®istration->bundle);
+ if (status == CELIX_SUCCESS) {
+ status = bundle_start(registration->bundle);
+ if (status == CELIX_SUCCESS) {
+ }
+ }
+
+ return status;
+}
+
+celix_status_t exportRegistration_close(export_registration_pt registration) {
+ celix_status_t status = CELIX_SUCCESS;
+
+ exportRegistration_stopTracking(registration);
+
+ bundle_uninstall(registration->bundle);
+
+
+ return status;
+}
+
+celix_status_t exportRegistration_getException(export_registration_pt registration) {
+ celix_status_t status = CELIX_SUCCESS;
+ return status;
+}
+
+celix_status_t exportRegistration_getExportReference(export_registration_pt registration, export_reference_pt *reference) {
+ celix_status_t status = CELIX_SUCCESS;
+
+ registration->exportReference = calloc(1, sizeof(*registration->exportReference));
+
+ if (registration->exportReference == NULL) {
+ status = CELIX_ENOMEM;
+ } else {
+ registration->exportReference->endpoint = registration->endpointDescription;
+ registration->exportReference->reference = registration->reference;
+ }
+
+ *reference = registration->exportReference;
+
+ return status;
+}
+
+celix_status_t exportRegistration_setEndpointDescription(export_registration_pt registration, endpoint_description_pt endpointDescription) {
+ celix_status_t status = CELIX_SUCCESS;
+
+ registration->endpointDescription = endpointDescription;
+
+ 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, service_reference_pt *service) {
+ celix_status_t status = CELIX_SUCCESS;
+ *service = reference->reference;
+ return status;
+}
+
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/remote_service_admin_common/src/export_registration_impl.h
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_common/src/export_registration_impl.h b/remote_services/remote_service_admin_common/src/export_registration_impl.h
new file mode 100644
index 0000000..bb276f9
--- /dev/null
+++ b/remote_services/remote_service_admin_common/src/export_registration_impl.h
@@ -0,0 +1,61 @@
+/**
+ *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.
+ */
+/*
+ * export_registration_impl.h
+ *
+ * \date Oct 6, 2011
+ * \author <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ * \copyright Apache License, Version 2.0
+ */
+
+#ifndef EXPORT_REGISTRATION_IMPL_H_
+#define EXPORT_REGISTRATION_IMPL_H_
+
+#include "remote_service_admin.h"
+#include "remote_endpoint.h"
+#include "service_tracker.h"
+#include "log_helper.h"
+
+struct export_registration {
+ bundle_context_pt context;
+ remote_service_admin_pt rsa;
+ endpoint_description_pt endpointDescription;
+ service_reference_pt reference;
+ log_helper_pt loghelper;
+
+ service_tracker_pt tracker;
+ service_tracker_pt endpointTracker;
+
+ remote_endpoint_service_pt endpoint;
+
+ export_reference_pt exportReference;
+ bundle_pt bundle;
+
+ bool closed;
+};
+
+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_setEndpointDescription(export_registration_pt registration, endpoint_description_pt endpointDescription);
+celix_status_t exportRegistration_startTracking(export_registration_pt registration);
+celix_status_t exportRegistration_stopTracking(export_registration_pt registration);
+
+#endif /* EXPORT_REGISTRATION_IMPL_H_ */
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/remote_service_admin_common/src/import_registration_impl.c
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_common/src/import_registration_impl.c b/remote_services/remote_service_admin_common/src/import_registration_impl.c
new file mode 100644
index 0000000..9a84327
--- /dev/null
+++ b/remote_services/remote_service_admin_common/src/import_registration_impl.c
@@ -0,0 +1,274 @@
+/**
+ *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.
+ */
+/*
+ * import_registration_impl.c
+ *
+ * \date Oct 14, 2011
+ * \author <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ * \copyright Apache License, Version 2.0
+ */
+
+#include <stdlib.h>
+#include <string.h>
+
+#include <constants.h>
+
+#include "celix_errno.h"
+
+#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);
+celix_status_t importRegistration_proxyFactoryModified(void * handle, service_reference_pt reference, void *service);
+celix_status_t importRegistration_proxyFactoryRemoved(void * handle, service_reference_pt reference, void *service);
+
+celix_status_t importRegistration_create(endpoint_description_pt endpoint, remote_service_admin_pt rsa, sendToHandle sendToCallback, bundle_context_pt context, import_registration_pt *registration) {
+ celix_status_t status = CELIX_SUCCESS;
+
+ *registration = calloc(1, sizeof(**registration));
+ if (!*registration) {
+ status = CELIX_ENOMEM;
+ } else {
+ (*registration)->context = context;
+ (*registration)->closed = false;
+ (*registration)->endpointDescription = endpoint;
+ (*registration)->rsa = rsa;
+ (*registration)->sendToCallback = sendToCallback;
+ (*registration)->reference = NULL;
+ (*registration)->importReference = NULL;
+ }
+
+ return status;
+}
+
+celix_status_t importRegistration_destroy(import_registration_pt registration)
+{
+ free(registration);
+
+ return CELIX_SUCCESS;
+}
+
+
+celix_status_t importRegistrationFactory_create(log_helper_pt helper, char* serviceName, bundle_context_pt context, import_registration_factory_pt *registration_factory) {
+ celix_status_t status = CELIX_SUCCESS;
+
+ *registration_factory = calloc(1, sizeof(**registration_factory));
+ if (!*registration_factory) {
+ status = CELIX_ENOMEM;
+ } else {
+ (*registration_factory)->serviceName = strdup(serviceName);
+ (*registration_factory)->context = context;
+ (*registration_factory)->bundle = NULL;
+ (*registration_factory)->loghelper = helper;
+
+ arrayList_create(&(*registration_factory)->registrations);
+ }
+
+ return status;
+}
+
+
+
+celix_status_t importRegistrationFactory_destroy(import_registration_factory_pt* registration_factory) {
+ celix_status_t status = CELIX_SUCCESS;
+
+ if (*registration_factory != NULL)
+ {
+ free((*registration_factory)->serviceName);
+ arrayList_destroy((*registration_factory)->registrations);
+
+ serviceTracker_destroy((*registration_factory)->proxyFactoryTracker);
+ free(*registration_factory);
+
+ *registration_factory = NULL;
+ }
+
+
+ return status;
+}
+
+
+celix_status_t importRegistrationFactory_open(import_registration_factory_pt registration_factory)
+{
+ celix_status_t status;
+
+ const char *bundleStore = NULL;
+ bundleContext_getProperty(registration_factory->context, BUNDLE_STORE_PROPERTY_NAME, &bundleStore);
+
+ if (bundleStore == NULL) {
+ bundleStore = DEFAULT_BUNDLE_STORE;
+ }
+
+ char name[256];
+ snprintf(name, 256, "%s/%s_proxy.zip", bundleStore, registration_factory->serviceName);
+
+ status = bundleContext_installBundle(registration_factory->context, name, ®istration_factory->bundle);
+
+ if (status == CELIX_SUCCESS) {
+ status = bundle_start(registration_factory->bundle);
+ if (status == CELIX_SUCCESS) {
+ logHelper_log(registration_factory->loghelper, OSGI_LOGSERVICE_INFO, "%s successfully started.", name);
+ }
+ }
+ else {
+ logHelper_log(registration_factory->loghelper, OSGI_LOGSERVICE_ERROR, "%s could not be installed.", name);
+ }
+
+ return status;
+}
+
+celix_status_t importRegistrationFactory_close(import_registration_factory_pt registration_factory)
+{
+ celix_status_t status = CELIX_SUCCESS;
+
+
+ if (registration_factory->proxyFactoryTracker != NULL) {
+ serviceTracker_close(registration_factory->proxyFactoryTracker);
+ }
+
+ if (registration_factory->bundle != NULL) {
+ bundle_uninstall(registration_factory->bundle);
+ }
+
+ return status;
+}
+
+
+celix_status_t importRegistration_createProxyFactoryTracker(import_registration_factory_pt registration_factory, service_tracker_pt *tracker) {
+ celix_status_t status;
+ service_tracker_customizer_pt customizer = NULL;
+
+ status = serviceTrackerCustomizer_create(registration_factory, importRegistration_proxyFactoryAdding, importRegistration_proxyFactoryAdded, importRegistration_proxyFactoryModified, importRegistration_proxyFactoryRemoved, &customizer);
+
+ if (status == CELIX_SUCCESS) {
+ char filter[512];
+
+ snprintf(filter, 512, "(&(%s=%s)(proxy.interface=%s))", (char*) OSGI_FRAMEWORK_OBJECTCLASS, (char*) OSGI_RSA_REMOTE_PROXY_FACTORY, registration_factory->serviceName);
+ status = serviceTracker_createWithFilter(registration_factory->context, filter, customizer, tracker);
+
+ if (status == CELIX_SUCCESS)
+ {
+ serviceTracker_open(*tracker);
+ }
+ }
+
+ return status;
+}
+
+celix_status_t importRegistration_proxyFactoryAdding(void * handle, service_reference_pt reference, void **service) {
+ celix_status_t status = CELIX_SUCCESS;
+ import_registration_factory_pt registration_factory = (import_registration_factory_pt) handle;
+
+ bundleContext_getService(registration_factory->context, reference, service);
+
+ return status;
+}
+
+celix_status_t importRegistration_proxyFactoryAdded(void * handle, service_reference_pt reference, void *service) {
+ celix_status_t status = CELIX_SUCCESS;
+
+ import_registration_factory_pt registration_factory = (import_registration_factory_pt) handle;
+ registration_factory->trackedFactory = (remote_proxy_factory_service_pt) service;
+
+ return status;
+}
+
+celix_status_t importRegistration_proxyFactoryModified(void * handle, service_reference_pt reference, void *service) {
+ celix_status_t status = CELIX_SUCCESS;
+
+ return status;
+}
+
+celix_status_t importRegistration_proxyFactoryRemoved(void * handle, service_reference_pt reference, void *service) {
+ celix_status_t status = CELIX_SUCCESS;
+
+ import_registration_factory_pt registration_factory = (import_registration_factory_pt) handle;
+ registration_factory->trackedFactory = NULL;
+
+ return status;
+}
+
+
+
+celix_status_t importRegistrationFactory_install(log_helper_pt helper, char* serviceName, bundle_context_pt context, import_registration_factory_pt *registration_factory)
+{
+ celix_status_t status;
+
+ if ( (status = importRegistrationFactory_create(helper, serviceName, context, registration_factory)) == CELIX_SUCCESS) {
+ // starting the proxy tracker first allows us to pick up already available proxy factories
+ importRegistration_createProxyFactoryTracker(*registration_factory, &((*registration_factory)->proxyFactoryTracker));
+ logHelper_log((*registration_factory)->loghelper, OSGI_LOGSERVICE_INFO, "remoteServiceAdmin_importService: new registration_factory added for %s at %p", serviceName, (*registration_factory)->proxyFactoryTracker);
+
+ // check whether factory is available
+ if (((*registration_factory)->trackedFactory == NULL) && ((status = importRegistrationFactory_open(*registration_factory)) != CELIX_SUCCESS)) {
+ logHelper_log((*registration_factory)->loghelper, OSGI_LOGSERVICE_ERROR, "remoteServiceAdmin_importService: cannot open registration_factory for %s.", serviceName);
+
+ importRegistrationFactory_close(*registration_factory);
+ importRegistrationFactory_destroy(registration_factory);
+ }
+ }
+
+ return status;
+}
+
+
+
+
+celix_status_t importRegistration_getException(import_registration_pt registration) {
+ celix_status_t status = CELIX_SUCCESS;
+ return status;
+}
+
+
+celix_status_t importRegistration_getImportReference(import_registration_pt registration, import_reference_pt *reference) {
+ celix_status_t status = CELIX_SUCCESS;
+
+ if (registration->importReference == NULL) {
+ registration->importReference = calloc(1, sizeof(*registration->importReference));
+ if (registration->importReference == NULL) {
+ status = CELIX_ENOMEM;
+ } else {
+ registration->importReference->endpoint = registration->endpointDescription;
+ registration->importReference->reference = registration->reference;
+ }
+ }
+
+ *reference = registration->importReference;
+
+ 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/2a670f26/remote_services/remote_service_admin_common/src/import_registration_impl.h
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_common/src/import_registration_impl.h b/remote_services/remote_service_admin_common/src/import_registration_impl.h
new file mode 100644
index 0000000..7aa397f
--- /dev/null
+++ b/remote_services/remote_service_admin_common/src/import_registration_impl.h
@@ -0,0 +1,81 @@
+/**
+ *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.
+ */
+/*
+ * import_registration_impl.h
+ *
+ * \date Oct 14, 2011
+ * \author <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ * \copyright Apache License, Version 2.0
+ */
+
+#ifndef IMPORT_REGISTRATION_IMPL_H_
+#define IMPORT_REGISTRATION_IMPL_H_
+
+#include "remote_service_admin.h"
+#include "remote_proxy.h"
+#include "service_tracker.h"
+#include "log_helper.h"
+
+struct import_registration {
+ bundle_context_pt context;
+ endpoint_description_pt endpointDescription;
+
+ service_reference_pt reference;
+ import_reference_pt importReference;
+
+ remote_service_admin_pt rsa;
+ sendToHandle sendToCallback;
+
+ bool closed;
+};
+
+
+
+struct import_registration_factory
+{
+ char* serviceName;
+ log_helper_pt loghelper;
+ remote_proxy_factory_service_pt trackedFactory;
+ service_tracker_pt proxyFactoryTracker;
+ bundle_context_pt context;
+ array_list_pt registrations;
+ bundle_pt bundle;
+};
+
+
+celix_status_t importRegistration_create(endpoint_description_pt endpoint, remote_service_admin_pt rsa, sendToHandle callback, bundle_context_pt context, import_registration_pt *registration);
+celix_status_t importRegistration_destroy(import_registration_pt registration);
+
+celix_status_t importRegistration_setEndpointDescription(import_registration_pt registration, endpoint_description_pt endpointDescription);
+celix_status_t importRegistration_setHandler(import_registration_pt registration, void * handler);
+celix_status_t importRegistration_setCallback(import_registration_pt registration, sendToHandle callback);
+
+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 importRegistration_createProxyFactoryTracker(import_registration_factory_pt registration_factory, service_tracker_pt *tracker);
+
+celix_status_t importRegistrationFactory_destroy(import_registration_factory_pt* registration_factory);
+//celix_status_t importRegistrationFactory_open(import_registration_factory_pt registration_factory);
+celix_status_t importRegistrationFactory_close(import_registration_factory_pt registration_factory);
+celix_status_t importRegistrationFactory_install(log_helper_pt helper, char* serviceName, bundle_context_pt context, import_registration_factory_pt *registration_factory);
+
+
+
+#endif /* IMPORT_REGISTRATION_IMPL_H_ */
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/remote_service_admin_common/src/remote_proxy_factory_impl.c
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_common/src/remote_proxy_factory_impl.c b/remote_services/remote_service_admin_common/src/remote_proxy_factory_impl.c
new file mode 100644
index 0000000..9f996d6
--- /dev/null
+++ b/remote_services/remote_service_admin_common/src/remote_proxy_factory_impl.c
@@ -0,0 +1,252 @@
+/**
+ * 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_proxy_factory_impl.c
+ *
+ * \date 22 Dec 2014
+ * \author <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ * \copyright Apache License, Version 2.0
+ */
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "remote_proxy.h"
+
+typedef struct proxy_instance {
+ service_registration_pt registration_ptr;
+ void *service;
+ properties_pt properties;
+} *proxy_instance_pt;
+
+static celix_status_t remoteProxyFactory_registerProxyService(remote_proxy_factory_pt remote_proxy_factory_ptr, endpoint_description_pt endpointDescription, remote_service_admin_pt rsa, sendToHandle sendToCallback);
+static celix_status_t remoteProxyFactory_unregisterProxyService(remote_proxy_factory_pt remote_proxy_factory_ptr, endpoint_description_pt endpointDescription);
+
+celix_status_t remoteProxyFactory_create(bundle_context_pt context, char *service, void *handle,
+ createProxyService create, destroyProxyService destroy,
+ remote_proxy_factory_pt *remote_proxy_factory_ptr) {
+ celix_status_t status = CELIX_SUCCESS;
+
+ *remote_proxy_factory_ptr = calloc(1, sizeof(**remote_proxy_factory_ptr));
+ if (!*remote_proxy_factory_ptr) {
+ status = CELIX_ENOMEM;
+ }
+
+ if (status == CELIX_SUCCESS) {
+ (*remote_proxy_factory_ptr)->context_ptr = context;
+ (*remote_proxy_factory_ptr)->service = strdup(service);
+
+ (*remote_proxy_factory_ptr)->remote_proxy_factory_service_ptr = NULL;
+ (*remote_proxy_factory_ptr)->properties = NULL;
+ (*remote_proxy_factory_ptr)->registration = NULL;
+
+ (*remote_proxy_factory_ptr)->proxy_instances = hashMap_create(NULL, NULL, NULL, NULL);
+
+ (*remote_proxy_factory_ptr)->handle = handle;
+
+ (*remote_proxy_factory_ptr)->create_proxy_service_ptr = create;
+ (*remote_proxy_factory_ptr)->destroy_proxy_service_ptr = destroy;
+ }
+
+ return status;
+}
+
+celix_status_t remoteProxyFactory_destroy(remote_proxy_factory_pt *remote_proxy_factory_ptr) {
+ celix_status_t status = CELIX_SUCCESS;
+
+ if (!*remote_proxy_factory_ptr) {
+ status = CELIX_ILLEGAL_ARGUMENT;
+ }
+
+ if (status == CELIX_SUCCESS) {
+ if ((*remote_proxy_factory_ptr)->proxy_instances) {
+ hashMap_destroy((*remote_proxy_factory_ptr)->proxy_instances, false, false);
+ (*remote_proxy_factory_ptr)->proxy_instances = NULL;
+ }
+ if ((*remote_proxy_factory_ptr)->service) {
+ free((*remote_proxy_factory_ptr)->service);
+ (*remote_proxy_factory_ptr)->service = NULL;
+ }
+ free(*remote_proxy_factory_ptr);
+ *remote_proxy_factory_ptr = NULL;
+ }
+
+ return status;
+}
+
+celix_status_t remoteProxyFactory_register(remote_proxy_factory_pt remote_proxy_factory_ptr) {
+ celix_status_t status = CELIX_SUCCESS;
+
+ remote_proxy_factory_ptr->remote_proxy_factory_service_ptr = calloc(1, sizeof(*remote_proxy_factory_ptr->remote_proxy_factory_service_ptr));
+ if (!remote_proxy_factory_ptr->remote_proxy_factory_service_ptr) {
+ status = CELIX_ENOMEM;
+ }
+
+ if (status == CELIX_SUCCESS) {
+ remote_proxy_factory_ptr->remote_proxy_factory_service_ptr->factory = remote_proxy_factory_ptr;
+ remote_proxy_factory_ptr->remote_proxy_factory_service_ptr->registerProxyService = remoteProxyFactory_registerProxyService;
+ remote_proxy_factory_ptr->remote_proxy_factory_service_ptr->unregisterProxyService = remoteProxyFactory_unregisterProxyService;
+
+ remote_proxy_factory_ptr->properties = properties_create();
+ if (!remote_proxy_factory_ptr->properties) {
+ status = CELIX_BUNDLE_EXCEPTION;
+ } else {
+ properties_set(remote_proxy_factory_ptr->properties, "proxy.interface", remote_proxy_factory_ptr->service);
+ }
+ }
+
+ if (status == CELIX_SUCCESS) {
+ status = bundleContext_registerService(remote_proxy_factory_ptr->context_ptr, OSGI_RSA_REMOTE_PROXY_FACTORY,
+ remote_proxy_factory_ptr->remote_proxy_factory_service_ptr, remote_proxy_factory_ptr->properties, &remote_proxy_factory_ptr->registration);
+ }
+
+ return status;
+}
+
+celix_status_t remoteProxyFactory_unregister(remote_proxy_factory_pt remote_proxy_factory_ptr) {
+ celix_status_t status = CELIX_SUCCESS;
+
+ if (!remote_proxy_factory_ptr) {
+ status = CELIX_ILLEGAL_ARGUMENT;
+ }
+
+ // #TODO Remove proxy registrations
+ if (status == CELIX_SUCCESS) {
+
+ hash_map_iterator_pt iter = hashMapIterator_create(remote_proxy_factory_ptr->proxy_instances);
+ while(hashMapIterator_hasNext(iter)){
+ proxy_instance_pt proxy_instance_ptr = (proxy_instance_pt)hashMapIterator_nextValue(iter);
+
+ if (proxy_instance_ptr->service) {
+ remote_proxy_factory_ptr->destroy_proxy_service_ptr(remote_proxy_factory_ptr->handle, proxy_instance_ptr->service);
+ }
+ free(proxy_instance_ptr);
+ }
+ hashMapIterator_destroy(iter);
+
+ if (remote_proxy_factory_ptr->registration) {
+ status = serviceRegistration_unregister(remote_proxy_factory_ptr->registration);
+ remote_proxy_factory_ptr->properties = NULL;
+ }
+ if (remote_proxy_factory_ptr->properties) {
+ properties_destroy(remote_proxy_factory_ptr->properties);
+ }
+ if (remote_proxy_factory_ptr->remote_proxy_factory_service_ptr) {
+ free(remote_proxy_factory_ptr->remote_proxy_factory_service_ptr);
+ }
+ }
+
+ return status;
+}
+
+
+static celix_status_t remoteProxyFactory_registerProxyService(remote_proxy_factory_pt remote_proxy_factory_ptr, endpoint_description_pt endpointDescription, remote_service_admin_pt rsa, sendToHandle sendToCallback) {
+ celix_status_t status = CELIX_SUCCESS;
+ proxy_instance_pt proxy_instance_ptr = NULL;
+
+ if (!remote_proxy_factory_ptr || !remote_proxy_factory_ptr->create_proxy_service_ptr) {
+ status = CELIX_ILLEGAL_ARGUMENT;
+ }
+
+ if (status == CELIX_SUCCESS) {
+ proxy_instance_ptr = calloc(1, sizeof(*proxy_instance_ptr));
+ if (!proxy_instance_ptr) {
+ status = CELIX_ENOMEM;
+ }
+ }
+
+ if (status == CELIX_SUCCESS) {
+ proxy_instance_ptr->properties = properties_create();
+ if (!proxy_instance_ptr->properties) {
+ status = CELIX_ENOMEM;
+ }
+ }
+
+ if (status == CELIX_SUCCESS) {
+ status = remote_proxy_factory_ptr->create_proxy_service_ptr(remote_proxy_factory_ptr->handle, endpointDescription, rsa, sendToCallback, proxy_instance_ptr->properties, &proxy_instance_ptr->service);
+ }
+
+ if (status == CELIX_SUCCESS) {
+ properties_set(proxy_instance_ptr->properties, "proxy.interface", remote_proxy_factory_ptr->service);
+
+ hash_map_iterator_pt iter = hashMapIterator_create(endpointDescription->properties);
+ while (hashMapIterator_hasNext(iter)) {
+ hash_map_entry_pt entry = hashMapIterator_nextEntry(iter);
+ char *key = hashMapEntry_getKey(entry);
+ char *value = hashMapEntry_getValue(entry);
+
+ properties_set(proxy_instance_ptr->properties, key, value);
+ }
+ hashMapIterator_destroy(iter);
+ }
+
+ if (status == CELIX_SUCCESS) {
+ status = bundleContext_registerService(remote_proxy_factory_ptr->context_ptr, remote_proxy_factory_ptr->service, proxy_instance_ptr->service, proxy_instance_ptr->properties, &proxy_instance_ptr->registration_ptr);
+ }
+
+ if (status == CELIX_SUCCESS) {
+ hashMap_put(remote_proxy_factory_ptr->proxy_instances, endpointDescription, proxy_instance_ptr);
+ }
+
+ if(status!=CELIX_SUCCESS){
+ if(proxy_instance_ptr != NULL){
+ if(proxy_instance_ptr->properties != NULL){
+ properties_destroy(proxy_instance_ptr->properties);
+ }
+ free(proxy_instance_ptr);
+ }
+ }
+
+ return status;
+}
+
+static celix_status_t remoteProxyFactory_unregisterProxyService(remote_proxy_factory_pt remote_proxy_factory_ptr, endpoint_description_pt endpointDescription) {
+ celix_status_t status = CELIX_SUCCESS;
+ proxy_instance_pt proxy_instance_ptr = NULL;
+
+ if (!remote_proxy_factory_ptr || !endpointDescription || !remote_proxy_factory_ptr->proxy_instances || !remote_proxy_factory_ptr->handle) {
+ status = CELIX_ILLEGAL_ARGUMENT;
+ }
+
+ if (status == CELIX_SUCCESS) {
+ proxy_instance_ptr = hashMap_remove(remote_proxy_factory_ptr->proxy_instances, endpointDescription);
+ if (proxy_instance_ptr == NULL) {
+ status = CELIX_BUNDLE_EXCEPTION;
+ }
+ }
+
+ if (status == CELIX_SUCCESS) {
+ if (proxy_instance_ptr->registration_ptr) {
+ status = serviceRegistration_unregister(proxy_instance_ptr->registration_ptr);
+ proxy_instance_ptr->properties = NULL;
+ }
+ if (proxy_instance_ptr->service) {
+ status = remote_proxy_factory_ptr->destroy_proxy_service_ptr(remote_proxy_factory_ptr->handle, proxy_instance_ptr->service);
+ }
+ if (proxy_instance_ptr->properties) {
+ properties_destroy(proxy_instance_ptr->properties);
+ }
+ free(proxy_instance_ptr);
+ }
+
+ return status;
+}
+
+
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/remote_service_admin_common/src/remote_service_admin_impl.h
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_common/src/remote_service_admin_impl.h b/remote_services/remote_service_admin_common/src/remote_service_admin_impl.h
new file mode 100644
index 0000000..e8a5e1f
--- /dev/null
+++ b/remote_services/remote_service_admin_common/src/remote_service_admin_impl.h
@@ -0,0 +1,49 @@
+/**
+ *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.h
+ *
+ * \date Dec 5, 2013
+ * \author <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ * \copyright Apache License, Version 2.0
+ */
+
+#ifndef REMOTE_SERVICE_ADMIN_IMPL_H_
+#define REMOTE_SERVICE_ADMIN_IMPL_H_
+
+#include "remote_service_admin.h"
+
+#define BUNDLE_STORE_PROPERTY_NAME "ENDPOINTS"
+#define DEFAULT_BUNDLE_STORE "endpoints"
+
+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_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(remote_service_admin_pt admin, 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 remoteServiceAdmin_destroyEndpointDescription(endpoint_description_pt *description);
+
+#endif /* REMOTE_SERVICE_ADMIN_IMPL_H_ */
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/remote_service_admin_dfi/rsa/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/rsa/CMakeLists.txt b/remote_services/remote_service_admin_dfi/rsa/CMakeLists.txt
index 01ab9bd..3efabf8 100644
--- a/remote_services/remote_service_admin_dfi/rsa/CMakeLists.txt
+++ b/remote_services/remote_service_admin_dfi/rsa/CMakeLists.txt
@@ -15,33 +15,20 @@
# specific language governing permissions and limitations
# under the License.
-include_directories(
- private/include
- ${PROJECT_SOURCE_DIR}/utils/public/include
- ${PROJECT_SOURCE_DIR}/log_service/public/include
- ${PROJECT_SOURCE_DIR}/remote_services/utils/private/include
- ${PROJECT_SOURCE_DIR}/remote_services/remote_service_admin/public/include
- ${PROJECT_SOURCE_DIR}/remote_services/remote_service_admin/private/include
- ${PROJECT_SOURCE_DIR}/remote_services/remote_service_admin_http/private/include
- ${PROJECT_SOURCE_DIR}/dfi/public/include
- ${PROJECT_SOURCE_DIR}/remote_services/examples/calculator_service/public/include
-)
-
add_bundle(remote_service_admin_dfi
VERSION 0.9.0
SYMBOLIC_NAME "apache_celix_remote_service_admin_dfi"
NAME "Apache Celix Remote Service Admin Dynamic Function Interface (DFI)"
SOURCES
- 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
- private/src/dfi_utils.c
-
- ${PROJECT_SOURCE_DIR}/remote_services/remote_service_admin/private/src/endpoint_description.c
-
- ${PROJECT_SOURCE_DIR}/remote_services/utils/private/src/civetweb.c
+ src/remote_service_admin_dfi.c
+ src/remote_service_admin_activator.c
+ src/export_registration_dfi.c
+ src/import_registration_dfi.c
+ src/dfi_utils.c
)
-target_link_libraries(remote_service_admin_dfi PRIVATE Celix::dfi Celix::log_helper ${CURL_LIBRARIES} ${JANSSON_LIBRARIES})
+target_include_directories(remote_service_admin_dfi PRIVATE src)
+target_link_libraries(remote_service_admin_dfi PRIVATE
+ Celix::dfi Celix::log_helper remote_service_admin_common
+ ${CURL_LIBRARIES} ${JANSSON_LIBRARIES})
install_bundle(remote_service_admin_dfi)
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/remote_service_admin_dfi/rsa/private/include/dfi_utils.h
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/rsa/private/include/dfi_utils.h b/remote_services/remote_service_admin_dfi/rsa/private/include/dfi_utils.h
deleted file mode 100644
index cec8aa1..0000000
--- a/remote_services/remote_service_admin_dfi/rsa/private/include/dfi_utils.h
+++ /dev/null
@@ -1,30 +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.
- */
-#ifndef DFI_UTILS_H_
-#define DFI_UTILS_H_
-
-#include "bundle.h"
-#include "bundle_context.h"
-#include <stdio.h>
-#include "celix_errno.h"
-
-
-celix_status_t dfi_findDescriptor(bundle_context_pt context, bundle_pt bundle, const char *name, FILE **out);
-
-#endif
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/remote_service_admin_dfi/rsa/private/include/export_registration_dfi.h
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/rsa/private/include/export_registration_dfi.h b/remote_services/remote_service_admin_dfi/rsa/private/include/export_registration_dfi.h
deleted file mode 100644
index 93f37ba..0000000
--- a/remote_services/remote_service_admin_dfi/rsa/private/include/export_registration_dfi.h
+++ /dev/null
@@ -1,38 +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.
- */
-
-#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_close(export_registration_pt registration);
-void 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/2a670f26/remote_services/remote_service_admin_dfi/rsa/private/include/import_registration_dfi.h
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/rsa/private/include/import_registration_dfi.h b/remote_services/remote_service_admin_dfi/rsa/private/include/import_registration_dfi.h
deleted file mode 100644
index aac4bc7..0000000
--- a/remote_services/remote_service_admin_dfi/rsa/private/include/import_registration_dfi.h
+++ /dev/null
@@ -1,44 +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.
- */
-
-#ifndef CELIX_IMPORT_REGISTRATION_DFI_H
-#define CELIX_IMPORT_REGISTRATION_DFI_H
-
-#include "import_registration.h"
-#include "dfi_utils.h"
-
-#include <celix_errno.h>
-
-typedef void (*send_func_type)(void *handle, endpoint_description_pt endpointDescription, char *request, char **reply, int* replyStatus);
-
-celix_status_t importRegistration_create(bundle_context_pt context, endpoint_description_pt description, const char *classObject, const char* serviceVersion,
- import_registration_pt *import);
-celix_status_t importRegistration_close(import_registration_pt import);
-void importRegistration_destroy(import_registration_pt import);
-
-celix_status_t importRegistration_setSendFn(import_registration_pt reg,
- send_func_type,
- void *handle);
-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/2a670f26/remote_services/remote_service_admin_dfi/rsa/private/include/remote_service_admin_dfi.h
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/rsa/private/include/remote_service_admin_dfi.h b/remote_services/remote_service_admin_dfi/rsa/private/include/remote_service_admin_dfi.h
deleted file mode 100644
index 8b282f1..0000000
--- a/remote_services/remote_service_admin_dfi/rsa/private/include/remote_service_admin_dfi.h
+++ /dev/null
@@ -1,57 +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_http_impl.h
- *
- * \date Sep 30, 2011
- * \author <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- * \copyright Apache License, Version 2.0
- */
-
-#ifndef REMOTE_SERVICE_ADMIN_HTTP_IMPL_H_
-#define REMOTE_SERVICE_ADMIN_HTTP_IMPL_H_
-
-
-#include "bundle_context.h"
-#include "endpoint_description.h"
-
-//typedef struct remote_service_admin *remote_service_admin_pt;
-
-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_exportService(remote_service_admin_pt admin, char *serviceId, properties_pt properties, array_list_pt *registrations);
-celix_status_t remoteServiceAdmin_removeExportedService(remote_service_admin_pt admin, 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, service_reference_pt *service);
-
-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/2a670f26/remote_services/remote_service_admin_dfi/rsa/private/src/dfi_utils.c
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/rsa/private/src/dfi_utils.c b/remote_services/remote_service_admin_dfi/rsa/private/src/dfi_utils.c
deleted file mode 100644
index 1b1eb36..0000000
--- a/remote_services/remote_service_admin_dfi/rsa/private/src/dfi_utils.c
+++ /dev/null
@@ -1,98 +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.
- */
-
-#include "dfi_utils.h"
-#include <stdlib.h>
-#include <unistd.h>
-
-static celix_status_t dfi_findFileForFramework(bundle_context_pt context, const char *fileName, FILE **out) {
- celix_status_t status;
-
- char pwd[1024];
- char path[1024];
- const char *extPath = NULL;
-
- status = bundleContext_getProperty(context, "CELIX_FRAMEWORK_EXTENDER_PATH", &extPath);
- if (status != CELIX_SUCCESS || extPath == NULL) {
- getcwd(pwd, sizeof(pwd));
- extPath = pwd;
- }
-
- snprintf(path, sizeof(path), "%s/%s", extPath, fileName);
-
- if (status == CELIX_SUCCESS) {
- FILE *df = fopen(path, "r");
- if (df == NULL) {
- status = CELIX_FILE_IO_EXCEPTION;
- } else {
- *out = df;
- }
- }
-
- return status;
-}
-
-static celix_status_t dfi_findFileForBundle(bundle_pt bundle, const char *fileName, FILE **out) {
- celix_status_t status;
-
- char *path = NULL;
- char metaInfFileName[512];
- snprintf(metaInfFileName, sizeof(metaInfFileName), "META-INF/descriptors/%s", fileName);
-
- status = bundle_getEntry(bundle, fileName, &path);
-
- if (status != CELIX_SUCCESS || path == NULL) {
- status = bundle_getEntry(bundle, metaInfFileName, &path);
- }
-
- if (status == CELIX_SUCCESS && path != NULL) {
- FILE *df = fopen(path, "r");
- if (df == NULL) {
- status = CELIX_FILE_IO_EXCEPTION;
- } else {
- *out = df;
- }
-
- }
-
- free(path);
- return status;
-}
-
-celix_status_t dfi_findDescriptor(bundle_context_pt context, bundle_pt bundle, const char *name, FILE **out) {
- celix_status_t status;
- char fileName[128];
-
- snprintf(fileName, 128, "%s.descriptor", name);
-
- long id;
- status = bundle_getBundleId(bundle, &id);
-
- if (status == CELIX_SUCCESS) {
- if (id == 0) {
- //framework bundle
- status = dfi_findFileForFramework(context, fileName, out);
- } else {
- //normal bundle
- status = dfi_findFileForBundle(bundle, fileName, out);
- }
- }
-
- return status;
-}
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/remote_service_admin_dfi/rsa/private/src/export_registration_dfi.c
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/rsa/private/src/export_registration_dfi.c b/remote_services/remote_service_admin_dfi/rsa/private/src/export_registration_dfi.c
deleted file mode 100644
index b83b5a8..0000000
--- a/remote_services/remote_service_admin_dfi/rsa/private/src/export_registration_dfi.c
+++ /dev/null
@@ -1,251 +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.
- */
-
-#include <jansson.h>
-#include <dyn_interface.h>
-#include <json_serializer.h>
-#include <remote_constants.h>
-#include <remote_service_admin.h>
-#include <service_tracker_customizer.h>
-#include <service_tracker.h>
-#include <json_rpc.h>
-#include "constants.h"
-#include "export_registration_dfi.h"
-#include "dfi_utils.h"
-
-struct export_reference {
- endpoint_description_pt endpoint; //owner
- service_reference_pt reference;
-};
-
-struct export_registration {
- bundle_context_pt context;
- struct export_reference exportReference;
- char *servId;
- dyn_interface_type *intf; //owner
- service_tracker_pt tracker;
-
- celix_thread_mutex_t mutex;
- void *service; //protected by mutex
-
- //TODO add tracker and lock
- bool closed;
-};
-
-static void exportRegistration_addServ(export_registration_pt reg, service_reference_pt ref, void *service);
-static void exportRegistration_removeServ(export_registration_pt reg, service_reference_pt ref, void *service);
-
-celix_status_t exportRegistration_create(log_helper_pt helper, service_reference_pt reference, endpoint_description_pt endpoint, bundle_context_pt context, export_registration_pt *out) {
- celix_status_t status = CELIX_SUCCESS;
-
- const char *servId = NULL;
- status = serviceReference_getProperty(reference, "service.id", &servId);
- if (status != CELIX_SUCCESS) {
- logHelper_log(helper, OSGI_LOGSERVICE_WARNING, "Cannot find service.id for ref");
- }
-
- export_registration_pt reg = NULL;
- if (status == CELIX_SUCCESS) {
- reg = calloc(1, sizeof(*reg));
- if (reg == NULL) {
- status = CELIX_ENOMEM;
- }
- }
-
-
- if (status == CELIX_SUCCESS) {
- reg->context = context;
- reg->exportReference.endpoint = endpoint;
- reg->exportReference.reference = reference;
- reg->closed = false;
-
- celixThreadMutex_create(®->mutex, NULL);
- }
-
- const char *exports = NULL;
- CELIX_DO_IF(status, serviceReference_getProperty(reference, (char *) OSGI_RSA_SERVICE_EXPORTED_INTERFACES, &exports));
-
- bundle_pt bundle = NULL;
- CELIX_DO_IF(status, serviceReference_getBundle(reference, &bundle));
-
- FILE *descriptor = NULL;
- if (status == CELIX_SUCCESS) {
- status = dfi_findDescriptor(context, bundle, exports, &descriptor);
- }
-
- if (status != CELIX_SUCCESS || descriptor == NULL) {
- status = CELIX_BUNDLE_EXCEPTION;
- logHelper_log(helper, OSGI_LOGSERVICE_ERROR, "Cannot find/open descriptor for '%s'", exports);
- }
-
- if (status == CELIX_SUCCESS) {
- int rc = dynInterface_parse(descriptor, ®->intf);
- fclose(descriptor);
- if (rc != 0) {
- status = CELIX_BUNDLE_EXCEPTION;
- logHelper_log(helper, OSGI_LOGSERVICE_WARNING, "RSA: Error parsing service descriptor.");
- }
- else{
- /* Add the interface version as a property in the properties_map */
- char* intfVersion = NULL;
- dynInterface_getVersionString(reg->intf, &intfVersion);
- const char *serviceVersion = properties_get(endpoint->properties,(char*) CELIX_FRAMEWORK_SERVICE_VERSION);
- if(serviceVersion!=NULL){
- if(strcmp(serviceVersion,intfVersion)!=0){
- logHelper_log(helper, OSGI_LOGSERVICE_WARNING, "Service version (%s) and interface version from the descriptor (%s) are not the same!",serviceVersion,intfVersion);
- }
- }
- else{
- properties_set(endpoint->properties, (char*) CELIX_FRAMEWORK_SERVICE_VERSION, intfVersion);
- }
- }
- }
-
- if (status == CELIX_SUCCESS) {
- service_tracker_customizer_pt cust = NULL;
- status = serviceTrackerCustomizer_create(reg, NULL, (void *) exportRegistration_addServ, NULL,
- (void *) exportRegistration_removeServ, &cust);
- if (status == CELIX_SUCCESS) {
- char filter[32];
- snprintf(filter, 32, "(service.id=%s)", servId);
- status = serviceTracker_createWithFilter(reg->context, filter, cust, ®->tracker);
- }
- }
-
- if (status == CELIX_SUCCESS) {
- *out = reg;
- } else {
- logHelper_log(helper, OSGI_LOGSERVICE_ERROR, "Error creating export registration");
- exportRegistration_destroy(reg);
- }
-
- return status;
-}
-
-celix_status_t exportRegistration_call(export_registration_pt export, char *data, int datalength, char **responseOut, int *responseLength) {
- int status = CELIX_SUCCESS;
-
- //printf("calling for '%s'\n");
-
- *responseLength = -1;
- celixThreadMutex_lock(&export->mutex);
- status = jsonRpc_call(export->intf, export->service, data, responseOut);
- celixThreadMutex_unlock(&export->mutex);
-
- return status;
-}
-
-void exportRegistration_destroy(export_registration_pt reg) {
- if (reg != NULL) {
- if (reg->intf != NULL) {
- dyn_interface_type *intf = reg->intf;
- reg->intf = NULL;
- dynInterface_destroy(intf);
- }
-
- if (reg->exportReference.endpoint != NULL) {
- endpoint_description_pt ep = reg->exportReference.endpoint;
- reg->exportReference.endpoint = NULL;
- endpointDescription_destroy(ep);
- }
- if (reg->tracker != NULL) {
- serviceTracker_destroy(reg->tracker);
- }
- celixThreadMutex_destroy(®->mutex);
-
- free(reg);
- }
-}
-
-celix_status_t exportRegistration_start(export_registration_pt reg) {
- celix_status_t status = CELIX_SUCCESS;
-
- serviceTracker_open(reg->tracker);
- return status;
-}
-
-
-celix_status_t exportRegistration_stop(export_registration_pt reg) {
- celix_status_t status = CELIX_SUCCESS;
- if (status == CELIX_SUCCESS) {
- status = bundleContext_ungetServiceReference(reg->context, reg->exportReference.reference);
- serviceTracker_close(reg->tracker);
- }
- return status;
-}
-
-static void exportRegistration_addServ(export_registration_pt reg, service_reference_pt ref, void *service) {
- celixThreadMutex_lock(®->mutex);
- reg->service = service;
- celixThreadMutex_unlock(®->mutex);
-}
-
-static void exportRegistration_removeServ(export_registration_pt reg, service_reference_pt ref, void *service) {
- celixThreadMutex_lock(®->mutex);
- if (reg->service == service) {
- reg->service = NULL;
- }
- celixThreadMutex_unlock(®->mutex);
-}
-
-
-celix_status_t exportRegistration_close(export_registration_pt reg) {
- celix_status_t status = CELIX_SUCCESS;
- exportRegistration_stop(reg);
- 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 *out) {
- celix_status_t status = CELIX_SUCCESS;
- export_reference_pt ref = calloc(1, sizeof(*ref));
- if (ref != NULL) {
- ref->endpoint = registration->exportReference.endpoint;
- ref->reference = registration->exportReference.reference;
- } else {
- status = CELIX_ENOMEM;
- }
-
- if (status == CELIX_SUCCESS) {
- *out = ref;
- }
-
- 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, service_reference_pt *ref) {
- celix_status_t status = CELIX_SUCCESS;
- *ref = reference->reference;
- return status;
-}
-
-
-
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/remote_service_admin_dfi/rsa/private/src/import_registration_dfi.c
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/rsa/private/src/import_registration_dfi.c b/remote_services/remote_service_admin_dfi/rsa/private/src/import_registration_dfi.c
deleted file mode 100644
index 0b8dcf7..0000000
--- a/remote_services/remote_service_admin_dfi/rsa/private/src/import_registration_dfi.c
+++ /dev/null
@@ -1,402 +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.
- */
-
-#include <stdlib.h>
-#include <jansson.h>
-#include <json_rpc.h>
-#include <assert.h>
-#include "version.h"
-#include "json_serializer.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
- version_pt version;
-
- celix_thread_mutex_t mutex; //protects send & sendhandle
- send_func_type send;
- void *sendHandle;
-
- service_factory_pt factory;
- service_registration_pt factoryReg;
-
- hash_map_pt proxies; //key -> bundle, value -> service_proxy
- celix_thread_mutex_t proxiesMutex; //protects proxies
-};
-
-struct service_proxy {
- dyn_interface_type *intf;
- void *service;
- size_t 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);
-static void importRegistration_clearProxies(import_registration_pt import);
-
-celix_status_t importRegistration_create(bundle_context_pt context, endpoint_description_pt endpoint, const char *classObject, const char* serviceVersion,
- 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);
-
- celixThreadMutex_create(®->mutex, NULL);
- celixThreadMutex_create(®->proxiesMutex, NULL);
- status = version_createVersionFromString((char*)serviceVersion,&(reg->version));
-
- reg->factory->handle = reg;
- reg->factory->getService = (void *)importRegistration_getService;
- reg->factory->ungetService = (void *)importRegistration_ungetService;
- } else {
- status = CELIX_ENOMEM;
- }
-
- if (status == CELIX_SUCCESS) {
- //printf("IMPORT REGISTRATION IS %p\n", reg);
- *out = reg;
- }
- else{
- importRegistration_destroy(reg);
- }
-
- return status;
-}
-
-
-celix_status_t importRegistration_setSendFn(import_registration_pt reg,
- send_func_type send,
- void *handle) {
- celixThreadMutex_lock(®->mutex);
- reg->send = send;
- reg->sendHandle = handle;
- celixThreadMutex_unlock(®->mutex);
-
- return CELIX_SUCCESS;
-}
-
-static void importRegistration_clearProxies(import_registration_pt import) {
- if (import != NULL) {
- pthread_mutex_lock(&import->proxiesMutex);
- if (import->proxies != NULL) {
- hash_map_iterator_pt iter = hashMapIterator_create(import->proxies);
- while (hashMapIterator_hasNext(iter)) {
- hash_map_entry_pt entry = hashMapIterator_nextEntry(iter);
- struct service_proxy *proxy = hashMapEntry_getValue(entry);
- importRegistration_destroyProxy(proxy);
- }
- hashMapIterator_destroy(iter);
- }
- pthread_mutex_unlock(&import->proxiesMutex);
- }
-}
-
-void importRegistration_destroy(import_registration_pt import) {
- if (import != NULL) {
- if (import->proxies != NULL) {
- hashMap_destroy(import->proxies, false, false);
- import->proxies = NULL;
- }
-
- pthread_mutex_destroy(&import->mutex);
- pthread_mutex_destroy(&import->proxiesMutex);
-
- if (import->factory != NULL) {
- free(import->factory);
- }
-
- if(import->version!=NULL){
- version_destroy(import->version);
- }
- free(import);
- }
-}
-
-celix_status_t importRegistration_start(import_registration_pt import) {
- celix_status_t status = CELIX_SUCCESS;
- if (import->factoryReg == NULL && import->factory != NULL) {
- properties_pt props = NULL;
- properties_copy(import->endpoint->properties, &props);
- status = bundleContext_registerServiceFactory(import->context, (char *)import->classObject, import->factory, props, &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);
- import->factoryReg = NULL;
- }
-
- importRegistration_clearProxies(import);
-
- 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;
-
- /*
- module_pt module = NULL;
- char *name = NULL;
- bundle_getCurrentModule(bundle, &module);
- module_getSymbolicName(module, &name);
- printf("getting service for bundle '%s'\n", name);
- */
-
-
- pthread_mutex_lock(&import->proxiesMutex);
- struct service_proxy *proxy = hashMap_get(import->proxies, bundle);
- if (proxy == NULL) {
- status = importRegistration_createProxy(import, bundle, &proxy);
- if (status == CELIX_SUCCESS) {
- hashMap_put(import->proxies, bundle, proxy);
- }
- }
-
- if (status == CELIX_SUCCESS) {
- proxy->count += 1;
- *out = proxy->service;
- }
- pthread_mutex_unlock(&import->proxiesMutex);
-
- return status;
-}
-
-static celix_status_t importRegistration_createProxy(import_registration_pt import, bundle_pt bundle, struct service_proxy **out) {
- celix_status_t status;
- dyn_interface_type* intf = NULL;
- FILE *descriptor = NULL;
-
- status = dfi_findDescriptor(import->context, bundle, import->classObject, &descriptor);
-
- if (status != CELIX_SUCCESS || descriptor == NULL) {
- //TODO use log helper logHelper_log(helper, OSGI_LOGSERVICE_ERROR, "Cannot find/open descriptor for '%s'", import->classObject);
- fprintf(stderr, "RSA_DFI: Cannot find/open descriptor for '%s'", import->classObject);
- return CELIX_BUNDLE_EXCEPTION;
- }
-
- if (status == CELIX_SUCCESS) {
- int rc = dynInterface_parse(descriptor, &intf);
- fclose(descriptor);
- if (rc != 0 || intf==NULL) {
- return CELIX_BUNDLE_EXCEPTION;
- }
- }
-
- /* Check if the imported service version is compatible with the one in the consumer descriptor */
- version_pt consumerVersion = NULL;
- bool isCompatible = false;
- dynInterface_getVersion(intf,&consumerVersion);
- version_isCompatible(consumerVersion,import->version,&isCompatible);
-
- if(!isCompatible){
- char* cVerString = NULL;
- char* pVerString = NULL;
- version_toString(consumerVersion,&cVerString);
- version_toString(import->version,&pVerString);
- printf("Service version mismatch: consumer has %s, provider has %s. NOT creating proxy.\n",cVerString,pVerString);
- dynInterface_destroy(intf);
- free(cVerString);
- free(pVerString);
- status = CELIX_SERVICE_EXCEPTION;
- }
-
- struct service_proxy *proxy = NULL;
- if (status == CELIX_SUCCESS) {
- proxy = calloc(1, sizeof(*proxy));
- if (proxy == NULL) {
- status = CELIX_ENOMEM;
- }
- }
-
- if (status == CELIX_SUCCESS) {
- proxy->intf = intf;
- size_t count = dynInterface_nrOfMethods(proxy->intf);
- proxy->service = calloc(1 + count, sizeof(void *));
- if (proxy->service == NULL) {
- status = CELIX_ENOMEM;
- }
- }
-
- if (status == CELIX_SUCCESS) {
- void **serv = proxy->service;
- serv[0] = import;
-
- struct methods_head *list = NULL;
- dynInterface_methods(proxy->intf, &list);
- struct method_entry *entry = NULL;
- void (*fn)(void) = NULL;
- 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) {
- *out = proxy;
- } else if (proxy != NULL) {
- if (proxy->intf != NULL) {
- dynInterface_destroy(proxy->intf);
- proxy->intf = NULL;
- }
- free(proxy->service);
- free(proxy);
- }
-
- return status;
-}
-
-static void importRegistration_proxyFunc(void *userData, void *args[], void *returnVal) {
- int status = CELIX_SUCCESS;
- struct method_entry *entry = userData;
- import_registration_pt import = *((void **)args[0]);
-
- if (import == NULL || import->send == NULL) {
- status = CELIX_ILLEGAL_ARGUMENT;
- }
-
-
- char *invokeRequest = NULL;
- if (status == CELIX_SUCCESS) {
- status = jsonRpc_prepareInvokeRequest(entry->dynFunc, entry->id, args, &invokeRequest);
- //printf("Need to send following json '%s'\n", invokeRequest);
- }
-
-
- if (status == CELIX_SUCCESS) {
- char *reply = NULL;
- int rc = 0;
- //printf("sending request\n");
- celixThreadMutex_lock(&import->mutex);
- if (import->send != NULL) {
- import->send(import->sendHandle, import->endpoint, invokeRequest, &reply, &rc);
- }
- celixThreadMutex_unlock(&import->mutex);
- //printf("request sended. got reply '%s' with status %i\n", reply, rc);
-
- if (rc == 0) {
- //fjprintf("Handling reply '%s'\n", reply);
- status = jsonRpc_handleReply(entry->dynFunc, reply, args);
- }
-
- *(int *) returnVal = rc;
-
- free(invokeRequest); //Allocated by json_dumps in jsonRpc_prepareInvokeRequest
- free(reply); //Allocated by json_dumps in remoteServiceAdmin_send through curl call
- }
-
- if (status != CELIX_SUCCESS) {
- //TODO log error
- }
-}
-
-celix_status_t importRegistration_ungetService(import_registration_pt import, bundle_pt bundle, service_registration_pt registration, void **out) {
- celix_status_t status = CELIX_SUCCESS;
-
- assert(import != NULL);
- assert(import->proxies != NULL);
-
- pthread_mutex_lock(&import->proxiesMutex);
-
- struct service_proxy *proxy = hashMap_get(import->proxies, bundle);
- if (proxy != NULL) {
- if (*out == proxy->service) {
- proxy->count -= 1;
- } else {
- status = CELIX_ILLEGAL_ARGUMENT;
- }
-
- if (proxy->count == 0) {
- hashMap_remove(import->proxies, bundle);
- importRegistration_destroyProxy(proxy);
- }
- }
-
- pthread_mutex_unlock(&import->proxiesMutex);
-
- return status;
-}
-
-static void importRegistration_destroyProxy(struct service_proxy *proxy) {
- if (proxy != NULL) {
- if (proxy->intf != NULL) {
- dynInterface_destroy(proxy->intf);
- }
- if (proxy->service != NULL) {
- free(proxy->service);
- }
- free(proxy);
- }
-}
-
-
-celix_status_t importRegistration_close(import_registration_pt registration) {
- celix_status_t status = CELIX_SUCCESS;
- importRegistration_stop(registration);
- 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;
-}
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/remote_service_admin_dfi/rsa/private/src/remote_service_admin_activator.c
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/rsa/private/src/remote_service_admin_activator.c b/remote_services/remote_service_admin_dfi/rsa/private/src/remote_service_admin_activator.c
deleted file mode 100644
index d4cc765..0000000
--- a/remote_services/remote_service_admin_dfi/rsa/private/src/remote_service_admin_activator.c
+++ /dev/null
@@ -1,124 +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_activator.c
- *
- * \date Sep 30, 2011
- * \author <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- * \copyright Apache License, Version 2.0
- */
-#include <stdlib.h>
-#include <remote_service_admin.h>
-
-#include "remote_service_admin_dfi.h"
-
-#include "bundle_activator.h"
-#include "service_registration.h"
-
-#include "export_registration_dfi.h"
-#include "import_registration_dfi.h"
-
-struct activator {
- remote_service_admin_pt admin;
- remote_service_admin_service_pt adminService;
- service_registration_pt registration;
-};
-
-celix_status_t bundleActivator_create(bundle_context_pt context, void **userData) {
- celix_status_t status = CELIX_SUCCESS;
- struct activator *activator;
-
- activator = calloc(1, sizeof(*activator));
- if (!activator) {
- status = CELIX_ENOMEM;
- } else {
- activator->admin = NULL;
- activator->registration = NULL;
-
- *userData = activator;
- }
-
- return status;
-}
-
-celix_status_t bundleActivator_start(void * userData, bundle_context_pt context) {
- celix_status_t status = CELIX_SUCCESS;
- struct activator *activator = userData;
- remote_service_admin_service_pt remoteServiceAdmin = NULL;
-
- status = remoteServiceAdmin_create(context, &activator->admin);
- if (status == CELIX_SUCCESS) {
- remoteServiceAdmin = calloc(1, sizeof(*remoteServiceAdmin));
- if (!remoteServiceAdmin) {
- status = CELIX_ENOMEM;
- } else {
- remoteServiceAdmin->admin = activator->admin;
- remoteServiceAdmin->exportService = remoteServiceAdmin_exportService;
-
- remoteServiceAdmin->getExportedServices = remoteServiceAdmin_getExportedServices;
- remoteServiceAdmin->getImportedEndpoints = remoteServiceAdmin_getImportedEndpoints;
- remoteServiceAdmin->importService = remoteServiceAdmin_importService;
-
- remoteServiceAdmin->exportReference_getExportedEndpoint = exportReference_getExportedEndpoint;
- remoteServiceAdmin->exportReference_getExportedService = exportReference_getExportedService;
-
- remoteServiceAdmin->exportRegistration_close = remoteServiceAdmin_removeExportedService;
- remoteServiceAdmin->exportRegistration_getException = exportRegistration_getException;
- remoteServiceAdmin->exportRegistration_getExportReference = exportRegistration_getExportReference;
-
- remoteServiceAdmin->importReference_getImportedEndpoint = importReference_getImportedEndpoint;
- remoteServiceAdmin->importReference_getImportedService = importReference_getImportedService;
-
- remoteServiceAdmin->importRegistration_close = remoteServiceAdmin_removeImportedService;
- remoteServiceAdmin->importRegistration_getException = importRegistration_getException;
- remoteServiceAdmin->importRegistration_getImportReference = importRegistration_getImportReference;
-
- status = bundleContext_registerService(context, OSGI_RSA_REMOTE_SERVICE_ADMIN, remoteServiceAdmin, NULL, &activator->registration);
- activator->adminService = remoteServiceAdmin;
- }
- }
-
- return status;
-}
-
-celix_status_t bundleActivator_stop(void * userData, bundle_context_pt context) {
- celix_status_t status = CELIX_SUCCESS;
- struct activator *activator = userData;
-
- serviceRegistration_unregister(activator->registration);
- activator->registration = NULL;
-
- remoteServiceAdmin_stop(activator->admin);
- remoteServiceAdmin_destroy(&activator->admin);
-
- free(activator->adminService);
-
- return status;
-}
-
-celix_status_t bundleActivator_destroy(void * userData, bundle_context_pt context) {
- celix_status_t status = CELIX_SUCCESS;
- struct activator *activator = userData;
-
- free(activator);
-
- return status;
-}
-
-
[15/19] celix git commit: CELIX-417: Refactor for CMake usage in RSA,
PSA and Docker. mostly trying to identify the api and common libraries
Posted by pn...@apache.org.
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/pubsub/pubsub_discovery/src/pubsub_discovery_impl.c
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_discovery/src/pubsub_discovery_impl.c b/pubsub/pubsub_discovery/src/pubsub_discovery_impl.c
new file mode 100644
index 0000000..94a8e11
--- /dev/null
+++ b/pubsub/pubsub_discovery/src/pubsub_discovery_impl.c
@@ -0,0 +1,457 @@
+/**
+ *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.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <stdbool.h>
+#include <netdb.h>
+#include <netinet/in.h>
+
+#include "constants.h"
+#include "celix_threads.h"
+#include "bundle_context.h"
+#include "array_list.h"
+#include "utils.h"
+#include "celix_errno.h"
+#include "filter.h"
+#include "service_reference.h"
+#include "service_registration.h"
+
+#include "publisher_endpoint_announce.h"
+#include "etcd_common.h"
+#include "etcd_watcher.h"
+#include "etcd_writer.h"
+#include "pubsub_endpoint.h"
+#include "pubsub_discovery_impl.h"
+
+/* Discovery activator functions */
+celix_status_t pubsub_discovery_create(bundle_context_pt context, pubsub_discovery_pt *ps_discovery) {
+ celix_status_t status = CELIX_SUCCESS;
+
+ *ps_discovery = calloc(1, sizeof(**ps_discovery));
+
+ if (*ps_discovery == NULL) {
+ status = CELIX_ENOMEM;
+ }
+ else{
+ (*ps_discovery)->context = context;
+ (*ps_discovery)->discoveredPubs = hashMap_create(utils_stringHash, NULL, utils_stringEquals, NULL);
+ (*ps_discovery)->listenerReferences = hashMap_create(serviceReference_hashCode, NULL, serviceReference_equals2, NULL);
+ (*ps_discovery)->watchers = hashMap_create(utils_stringHash,NULL,utils_stringEquals, NULL);
+ celixThreadMutex_create(&(*ps_discovery)->listenerReferencesMutex, NULL);
+ celixThreadMutex_create(&(*ps_discovery)->discoveredPubsMutex, NULL);
+ celixThreadMutex_create(&(*ps_discovery)->watchersMutex, NULL);
+ }
+
+ return status;
+}
+
+celix_status_t pubsub_discovery_destroy(pubsub_discovery_pt ps_discovery) {
+ celix_status_t status = CELIX_SUCCESS;
+
+ celixThreadMutex_lock(&ps_discovery->discoveredPubsMutex);
+
+ hash_map_iterator_pt iter = hashMapIterator_create(ps_discovery->discoveredPubs);
+
+ while (hashMapIterator_hasNext(iter)) {
+ array_list_pt pubEP_list = (array_list_pt) hashMapIterator_nextValue(iter);
+
+ for(int i=0; i < arrayList_size(pubEP_list); i++) {
+ pubsubEndpoint_destroy(((pubsub_endpoint_pt)arrayList_get(pubEP_list,i)));
+ }
+ arrayList_destroy(pubEP_list);
+ }
+
+ hashMapIterator_destroy(iter);
+
+ hashMap_destroy(ps_discovery->discoveredPubs, true, false);
+ ps_discovery->discoveredPubs = NULL;
+
+ celixThreadMutex_unlock(&ps_discovery->discoveredPubsMutex);
+
+ celixThreadMutex_destroy(&ps_discovery->discoveredPubsMutex);
+
+
+ celixThreadMutex_lock(&ps_discovery->listenerReferencesMutex);
+
+ hashMap_destroy(ps_discovery->listenerReferences, false, false);
+ ps_discovery->listenerReferences = NULL;
+
+ celixThreadMutex_unlock(&ps_discovery->listenerReferencesMutex);
+
+ celixThreadMutex_destroy(&ps_discovery->listenerReferencesMutex);
+
+ free(ps_discovery);
+
+ return status;
+}
+
+celix_status_t pubsub_discovery_start(pubsub_discovery_pt ps_discovery) {
+ celix_status_t status = CELIX_SUCCESS;
+ status = etcdCommon_init(ps_discovery->context);
+ ps_discovery->writer = etcdWriter_create(ps_discovery);
+
+ return status;
+}
+
+celix_status_t pubsub_discovery_stop(pubsub_discovery_pt ps_discovery) {
+ celix_status_t status = CELIX_SUCCESS;
+
+ const char* fwUUID = NULL;
+
+ bundleContext_getProperty(ps_discovery->context, OSGI_FRAMEWORK_FRAMEWORK_UUID, &fwUUID);
+ if (fwUUID == NULL) {
+ printf("PSD: Cannot retrieve fwUUID.\n");
+ return CELIX_INVALID_BUNDLE_CONTEXT;
+ }
+
+ celixThreadMutex_lock(&ps_discovery->watchersMutex);
+
+ hash_map_iterator_pt iter = hashMapIterator_create(ps_discovery->watchers);
+ while (hashMapIterator_hasNext(iter)) {
+ struct watcher_info * wi = hashMapIterator_nextValue(iter);
+ etcdWatcher_stop(wi->watcher);
+ }
+ hashMapIterator_destroy(iter);
+
+ celixThreadMutex_lock(&ps_discovery->discoveredPubsMutex);
+
+ /* Unexport all publishers for the local framework, and also delete from ETCD publisher belonging to the local framework */
+
+ iter = hashMapIterator_create(ps_discovery->discoveredPubs);
+ while (hashMapIterator_hasNext(iter)) {
+ array_list_pt pubEP_list = (array_list_pt) hashMapIterator_nextValue(iter);
+
+ int i;
+ for (i = 0; i < arrayList_size(pubEP_list); i++) {
+ pubsub_endpoint_pt pubEP = (pubsub_endpoint_pt) arrayList_get(pubEP_list, i);
+ if (strcmp(pubEP->frameworkUUID, fwUUID) == 0) {
+ etcdWriter_deletePublisherEndpoint(ps_discovery->writer, pubEP);
+ } else {
+ pubsub_discovery_informPublishersListeners(ps_discovery, pubEP, false);
+ arrayList_remove(pubEP_list, i);
+ pubsubEndpoint_destroy(pubEP);
+ i--;
+ }
+ }
+ }
+
+ hashMapIterator_destroy(iter);
+
+ celixThreadMutex_unlock(&ps_discovery->discoveredPubsMutex);
+ etcdWriter_destroy(ps_discovery->writer);
+
+ iter = hashMapIterator_create(ps_discovery->watchers);
+ while (hashMapIterator_hasNext(iter)) {
+ struct watcher_info * wi = hashMapIterator_nextValue(iter);
+ etcdWatcher_destroy(wi->watcher);
+ }
+ hashMapIterator_destroy(iter);
+ hashMap_destroy(ps_discovery->watchers, true, true);
+ celixThreadMutex_unlock(&ps_discovery->watchersMutex);
+ return status;
+}
+
+/* Functions called by the etcd_watcher */
+
+celix_status_t pubsub_discovery_addNode(pubsub_discovery_pt pubsub_discovery, pubsub_endpoint_pt pubEP) {
+ celix_status_t status = CELIX_SUCCESS;
+ bool inform=false;
+ celixThreadMutex_lock(&pubsub_discovery->discoveredPubsMutex);
+
+ char *pubs_key = createScopeTopicKey(pubEP->scope, pubEP->topic);
+ array_list_pt pubEP_list = (array_list_pt)hashMap_get(pubsub_discovery->discoveredPubs,pubs_key);
+ if(pubEP_list==NULL){
+ arrayList_create(&pubEP_list);
+ arrayList_add(pubEP_list,pubEP);
+ hashMap_put(pubsub_discovery->discoveredPubs,strdup(pubs_key),pubEP_list);
+ inform=true;
+ }
+ else{
+ int i;
+ bool found = false;
+ for(i=0;i<arrayList_size(pubEP_list) && !found;i++){
+ found = pubsubEndpoint_equals(pubEP,(pubsub_endpoint_pt)arrayList_get(pubEP_list,i));
+ }
+ if(found){
+ pubsubEndpoint_destroy(pubEP);
+ }
+ else{
+ arrayList_add(pubEP_list,pubEP);
+ inform=true;
+ }
+ }
+ free(pubs_key);
+
+ celixThreadMutex_unlock(&pubsub_discovery->discoveredPubsMutex);
+
+ if(inform){
+ status = pubsub_discovery_informPublishersListeners(pubsub_discovery,pubEP,true);
+ }
+
+ return status;
+}
+
+celix_status_t pubsub_discovery_removeNode(pubsub_discovery_pt pubsub_discovery, pubsub_endpoint_pt pubEP) {
+ celix_status_t status = CELIX_SUCCESS;
+ pubsub_endpoint_pt p = NULL;
+ bool found = false;
+
+ celixThreadMutex_lock(&pubsub_discovery->discoveredPubsMutex);
+ char *pubs_key = createScopeTopicKey(pubEP->scope, pubEP->topic);
+ array_list_pt pubEP_list = (array_list_pt) hashMap_get(pubsub_discovery->discoveredPubs, pubs_key);
+ free(pubs_key);
+ if (pubEP_list == NULL) {
+ printf("PSD: Cannot find any registered publisher for topic %s. Something is not consistent.\n", pubEP->topic);
+ status = CELIX_ILLEGAL_STATE;
+ } else {
+ int i;
+
+ for (i = 0; !found && i < arrayList_size(pubEP_list); i++) {
+ p = arrayList_get(pubEP_list, i);
+ found = pubsubEndpoint_equals(pubEP, p);
+ if (found) {
+ arrayList_remove(pubEP_list, i);
+ pubsubEndpoint_destroy(p);
+ }
+ }
+ }
+
+ celixThreadMutex_unlock(&pubsub_discovery->discoveredPubsMutex);
+ if (found) {
+ status = pubsub_discovery_informPublishersListeners(pubsub_discovery, pubEP, false);
+ }
+ pubsubEndpoint_destroy(pubEP);
+
+ return status;
+}
+
+/* Callback to the pubsub_topology_manager */
+celix_status_t pubsub_discovery_informPublishersListeners(pubsub_discovery_pt pubsub_discovery, pubsub_endpoint_pt pubEP, bool epAdded) {
+ celix_status_t status = CELIX_SUCCESS;
+
+ // Inform listeners of new publisher endpoint
+ celixThreadMutex_lock(&pubsub_discovery->listenerReferencesMutex);
+
+ if (pubsub_discovery->listenerReferences != NULL) {
+ hash_map_iterator_pt iter = hashMapIterator_create(pubsub_discovery->listenerReferences);
+ while (hashMapIterator_hasNext(iter)) {
+ service_reference_pt reference = hashMapIterator_nextKey(iter);
+
+ publisher_endpoint_announce_pt listener = NULL;
+
+ bundleContext_getService(pubsub_discovery->context, reference, (void**) &listener);
+ if (epAdded) {
+ listener->announcePublisher(listener->handle, pubEP);
+ } else {
+ listener->removePublisher(listener->handle, pubEP);
+ }
+ bundleContext_ungetService(pubsub_discovery->context, reference, NULL);
+ }
+ hashMapIterator_destroy(iter);
+ }
+
+ celixThreadMutex_unlock(&pubsub_discovery->listenerReferencesMutex);
+
+ return status;
+}
+
+
+/* Service's functions implementation */
+celix_status_t pubsub_discovery_announcePublisher(void *handle, pubsub_endpoint_pt pubEP) {
+ celix_status_t status = CELIX_SUCCESS;
+ printf("pubsub_discovery_announcePublisher : %s / %s\n", pubEP->topic, pubEP->endpoint);
+ pubsub_discovery_pt pubsub_discovery = (pubsub_discovery_pt) handle;
+
+ celixThreadMutex_lock(&pubsub_discovery->discoveredPubsMutex);
+
+ char *pub_key = createScopeTopicKey(pubEP->scope,pubEP->topic);
+ array_list_pt pubEP_list = (array_list_pt)hashMap_get(pubsub_discovery->discoveredPubs,pub_key);
+
+ if(pubEP_list==NULL){
+ arrayList_create(&pubEP_list);
+ hashMap_put(pubsub_discovery->discoveredPubs,strdup(pub_key),pubEP_list);
+ }
+ free(pub_key);
+ pubsub_endpoint_pt p = NULL;
+ pubsubEndpoint_clone(pubEP, &p);
+
+ arrayList_add(pubEP_list,p);
+
+ status = etcdWriter_addPublisherEndpoint(pubsub_discovery->writer,p,true);
+
+ celixThreadMutex_unlock(&pubsub_discovery->discoveredPubsMutex);
+
+ return status;
+}
+
+celix_status_t pubsub_discovery_removePublisher(void *handle, pubsub_endpoint_pt pubEP) {
+ celix_status_t status = CELIX_SUCCESS;
+
+ pubsub_discovery_pt pubsub_discovery = (pubsub_discovery_pt) handle;
+
+ celixThreadMutex_lock(&pubsub_discovery->discoveredPubsMutex);
+
+ char *pub_key = createScopeTopicKey(pubEP->scope,pubEP->topic);
+ array_list_pt pubEP_list = (array_list_pt)hashMap_get(pubsub_discovery->discoveredPubs,pub_key);
+ free(pub_key);
+ if(pubEP_list==NULL){
+ printf("PSD: Cannot find any registered publisher for topic %s. Something is not consistent.\n",pubEP->topic);
+ status = CELIX_ILLEGAL_STATE;
+ }
+ else{
+
+ int i;
+ bool found = false;
+ pubsub_endpoint_pt p = NULL;
+
+ for(i=0;!found && i<arrayList_size(pubEP_list);i++){
+ p = (pubsub_endpoint_pt)arrayList_get(pubEP_list,i);
+ found = pubsubEndpoint_equals(pubEP,p);
+ }
+
+ if(!found){
+ printf("PSD: Trying to remove a not existing endpoint. Something is not consistent.\n");
+ status = CELIX_ILLEGAL_STATE;
+ }
+ else{
+
+ arrayList_removeElement(pubEP_list,p);
+
+ status = etcdWriter_deletePublisherEndpoint(pubsub_discovery->writer,p);
+
+ pubsubEndpoint_destroy(p);
+ }
+ }
+
+ celixThreadMutex_unlock(&pubsub_discovery->discoveredPubsMutex);
+
+ return status;
+}
+
+celix_status_t pubsub_discovery_interestedInTopic(void *handle, const char* scope, const char* topic) {
+ pubsub_discovery_pt pubsub_discovery = (pubsub_discovery_pt) handle;
+
+ char *scope_topic_key = createScopeTopicKey(scope, topic);
+ celixThreadMutex_lock(&pubsub_discovery->watchersMutex);
+ struct watcher_info * wi = hashMap_get(pubsub_discovery->watchers, scope_topic_key);
+ if(wi) {
+ wi->nr_references++;
+ free(scope_topic_key);
+ } else {
+ wi = calloc(1, sizeof(*wi));
+ etcdWatcher_create(pubsub_discovery, pubsub_discovery->context, scope, topic, &wi->watcher);
+ wi->nr_references = 1;
+ hashMap_put(pubsub_discovery->watchers, scope_topic_key, wi);
+ }
+
+ celixThreadMutex_unlock(&pubsub_discovery->watchersMutex);
+
+ return CELIX_SUCCESS;
+}
+
+celix_status_t pubsub_discovery_uninterestedInTopic(void *handle, const char* scope, const char* topic) {
+ pubsub_discovery_pt pubsub_discovery = (pubsub_discovery_pt) handle;
+
+ char *scope_topic_key = createScopeTopicKey(scope, topic);
+ celixThreadMutex_lock(&pubsub_discovery->watchersMutex);
+
+ hash_map_entry_pt entry = hashMap_getEntry(pubsub_discovery->watchers, scope_topic_key);
+ if(entry) {
+ struct watcher_info * wi = hashMapEntry_getValue(entry);
+ wi->nr_references--;
+ if(wi->nr_references == 0) {
+ char *key = hashMapEntry_getKey(entry);
+ hashMap_remove(pubsub_discovery->watchers, scope_topic_key);
+ free(key);
+ free(scope_topic_key);
+ etcdWatcher_stop(wi->watcher);
+ etcdWatcher_destroy(wi->watcher);
+ free(wi);
+ }
+ } else {
+ fprintf(stderr, "[DISC] Inconsistency error: Removing unknown topic %s\n", topic);
+ }
+ celixThreadMutex_unlock(&pubsub_discovery->watchersMutex);
+ return CELIX_SUCCESS;
+}
+
+/* pubsub_topology_manager tracker callbacks */
+
+celix_status_t pubsub_discovery_tmPublisherAnnounceAdded(void * handle, service_reference_pt reference, void * service) {
+ celix_status_t status = CELIX_SUCCESS;
+
+ pubsub_discovery_pt pubsub_discovery = (pubsub_discovery_pt)handle;
+ publisher_endpoint_announce_pt listener = (publisher_endpoint_announce_pt)service;
+
+ celixThreadMutex_lock(&pubsub_discovery->discoveredPubsMutex);
+ celixThreadMutex_lock(&pubsub_discovery->listenerReferencesMutex);
+
+ /* Notify the PSTM about discovered publisher endpoints */
+ hash_map_iterator_pt iter = hashMapIterator_create(pubsub_discovery->discoveredPubs);
+ while(hashMapIterator_hasNext(iter)){
+ array_list_pt pubEP_list = (array_list_pt)hashMapIterator_nextValue(iter);
+ int i;
+ for(i=0;i<arrayList_size(pubEP_list);i++){
+ pubsub_endpoint_pt pubEP = (pubsub_endpoint_pt)arrayList_get(pubEP_list,i);
+ status += listener->announcePublisher(listener->handle, pubEP);
+ }
+ }
+
+ hashMapIterator_destroy(iter);
+
+ hashMap_put(pubsub_discovery->listenerReferences, reference, NULL);
+
+ celixThreadMutex_unlock(&pubsub_discovery->listenerReferencesMutex);
+ celixThreadMutex_unlock(&pubsub_discovery->discoveredPubsMutex);
+
+ printf("PSD: pubsub_tm_announce_publisher added.\n");
+
+ return status;
+}
+
+celix_status_t pubsub_discovery_tmPublisherAnnounceModified(void * handle, service_reference_pt reference, void * service) {
+ celix_status_t status = CELIX_SUCCESS;
+
+ status = pubsub_discovery_tmPublisherAnnounceRemoved(handle, reference, service);
+ if (status == CELIX_SUCCESS) {
+ status = pubsub_discovery_tmPublisherAnnounceAdded(handle, reference, service);
+ }
+
+ return status;
+}
+
+celix_status_t pubsub_discovery_tmPublisherAnnounceRemoved(void * handle, service_reference_pt reference, void * service) {
+ celix_status_t status = CELIX_SUCCESS;
+ pubsub_discovery_pt pubsub_discovery = handle;
+
+ celixThreadMutex_lock(&pubsub_discovery->listenerReferencesMutex);
+
+ if (pubsub_discovery->listenerReferences != NULL) {
+ if (hashMap_remove(pubsub_discovery->listenerReferences, reference)) {
+ printf("PSD: pubsub_tm_announce_publisher removed.\n");
+ }
+ }
+ celixThreadMutex_unlock(&pubsub_discovery->listenerReferencesMutex);
+
+ return status;
+}
+
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/pubsub/pubsub_discovery/src/pubsub_discovery_impl.h
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_discovery/src/pubsub_discovery_impl.h b/pubsub/pubsub_discovery/src/pubsub_discovery_impl.h
new file mode 100644
index 0000000..676a6ab
--- /dev/null
+++ b/pubsub/pubsub_discovery/src/pubsub_discovery_impl.h
@@ -0,0 +1,72 @@
+/**
+ *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.
+ */
+
+#ifndef PUBSUB_DISCOVERY_IMPL_H_
+#define PUBSUB_DISCOVERY_IMPL_H_
+
+#include "bundle_context.h"
+#include "service_reference.h"
+
+#include "etcd_watcher.h"
+#include "etcd_writer.h"
+#include "pubsub_endpoint.h"
+
+#define FREE_MEM(ptr) if(ptr) {free(ptr); ptr = NULL;}
+
+struct watcher_info {
+ etcd_watcher_pt watcher;
+ int nr_references;
+};
+
+struct pubsub_discovery {
+ bundle_context_pt context;
+
+ celix_thread_mutex_t discoveredPubsMutex;
+ hash_map_pt discoveredPubs; //<topic,List<pubsub_endpoint_pt>>
+
+ celix_thread_mutex_t listenerReferencesMutex;
+ hash_map_pt listenerReferences; //key=serviceReference, value=nop
+
+ celix_thread_mutex_t watchersMutex;
+ hash_map_pt watchers; //key = topicname, value = struct watcher_info
+
+ etcd_writer_pt writer;
+};
+
+
+celix_status_t pubsub_discovery_create(bundle_context_pt context, pubsub_discovery_pt* node_discovery);
+celix_status_t pubsub_discovery_destroy(pubsub_discovery_pt node_discovery);
+celix_status_t pubsub_discovery_start(pubsub_discovery_pt node_discovery);
+celix_status_t pubsub_discovery_stop(pubsub_discovery_pt node_discovery);
+
+celix_status_t pubsub_discovery_addNode(pubsub_discovery_pt node_discovery, pubsub_endpoint_pt pubEP);
+celix_status_t pubsub_discovery_removeNode(pubsub_discovery_pt node_discovery, pubsub_endpoint_pt pubEP);
+
+celix_status_t pubsub_discovery_tmPublisherAnnounceAdded(void * handle, service_reference_pt reference, void * service);
+celix_status_t pubsub_discovery_tmPublisherAnnounceModified(void * handle, service_reference_pt reference, void * service);
+celix_status_t pubsub_discovery_tmPublisherAnnounceRemoved(void * handle, service_reference_pt reference, void * service);
+
+celix_status_t pubsub_discovery_announcePublisher(void *handle, pubsub_endpoint_pt pubEP);
+celix_status_t pubsub_discovery_removePublisher(void *handle, pubsub_endpoint_pt pubEP);
+celix_status_t pubsub_discovery_interestedInTopic(void *handle, const char* scope, const char* topic);
+celix_status_t pubsub_discovery_uninterestedInTopic(void *handle, const char* scope, const char* topic);
+
+celix_status_t pubsub_discovery_informPublishersListeners(pubsub_discovery_pt discovery, pubsub_endpoint_pt endpoint, bool endpointAdded);
+
+#endif /* PUBSUB_DISCOVERY_IMPL_H_ */
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/pubsub/pubsub_serializer_json/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_serializer_json/CMakeLists.txt b/pubsub/pubsub_serializer_json/CMakeLists.txt
index 147873a..b86f30e 100644
--- a/pubsub/pubsub_serializer_json/CMakeLists.txt
+++ b/pubsub/pubsub_serializer_json/CMakeLists.txt
@@ -17,27 +17,23 @@
find_package(Jansson REQUIRED)
-include_directories("private/include")
-include_directories("public/include")
-include_directories("${PROJECT_SOURCE_DIR}/utils/public/include")
-include_directories("${PROJECT_SOURCE_DIR}/log_service/public/include")
-include_directories("${PROJECT_SOURCE_DIR}/dfi/public/include")
-include_directories("${PROJECT_SOURCE_DIR}/pubsub/pubsub_common/public/include")
-include_directories("${PROJECT_SOURCE_DIR}/pubsub/api/pubsub")
-include_directories("${JANSSON_INCLUDE_DIR}")
add_bundle(org.apache.celix.pubsub_serializer.PubSubSerializerJson
BUNDLE_SYMBOLICNAME "apache_celix_pubsub_serializer_json"
VERSION "1.0.0"
SOURCES
- private/src/ps_activator.c
- private/src/pubsub_serializer_impl.c
- ${PROJECT_SOURCE_DIR}/log_service/public/src/log_helper.c
+ src/ps_activator.c
+ src/pubsub_serializer_impl.c
${PROJECT_SOURCE_DIR}/pubsub/pubsub_common/public/src/pubsub_utils.c
)
+target_include_directories(org.apache.celix.pubsub_serializer.PubSubSerializerJson PRIVATE
+ src
+ ${JANSSON_INCLUDE_DIR}
+)
+
set_target_properties(org.apache.celix.pubsub_serializer.PubSubSerializerJson PROPERTIES INSTALL_RPATH "$ORIGIN")
-target_link_libraries(org.apache.celix.pubsub_serializer.PubSubSerializerJson celix_framework celix_utils celix_dfi ${JANSSON_LIBRARIES})
+target_link_libraries(org.apache.celix.pubsub_serializer.PubSubSerializerJson PRIVATE Celix::framework Celix::dfi ${JANSSON_LIBRARIES} Celix::log_helper)
install_bundle(org.apache.celix.pubsub_serializer.PubSubSerializerJson)
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/pubsub/pubsub_serializer_json/private/include/pubsub_serializer_impl.h
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_serializer_json/private/include/pubsub_serializer_impl.h b/pubsub/pubsub_serializer_json/private/include/pubsub_serializer_impl.h
deleted file mode 100644
index c36f20e..0000000
--- a/pubsub/pubsub_serializer_json/private/include/pubsub_serializer_impl.h
+++ /dev/null
@@ -1,55 +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.
- */
-/*
- * pubsub_serializer_impl.h
- *
- * \date Mar 24, 2017
- * \author <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- * \copyright Apache License, Version 2.0
- */
-
-#ifndef PUBSUB_SERIALIZER_JSON_H_
-#define PUBSUB_SERIALIZER_JSON_H_
-
-#include "dyn_common.h"
-#include "dyn_type.h"
-#include "dyn_message.h"
-#include "log_helper.h"
-
-#include "pubsub_serializer.h"
-
-#define PUBSUB_SERIALIZER_TYPE "json"
-
-typedef struct pubsub_serializer {
- bundle_context_pt bundle_context;
- log_helper_pt loghelper;
-} pubsub_serializer_t;
-
-celix_status_t pubsubSerializer_create(bundle_context_pt context, pubsub_serializer_t* *serializer);
-celix_status_t pubsubSerializer_destroy(pubsub_serializer_t* serializer);
-
-celix_status_t pubsubSerializer_createSerializerMap(pubsub_serializer_t* serializer, bundle_pt bundle, hash_map_pt* serializerMap);
-celix_status_t pubsubSerializer_destroySerializerMap(pubsub_serializer_t*, hash_map_pt serializerMap);
-
-/* Start of serializer specific functions */
-celix_status_t pubsubMsgSerializer_serialize(pubsub_msg_serializer_t* msgSerializer, const void* msg, void** out, size_t *outLen);
-celix_status_t pubsubMsgSerializer_deserialize(pubsub_msg_serializer_t* msgSerializer, const void* input, size_t inputLen, void **out);
-void pubsubMsgSerializer_freeMsg(pubsub_msg_serializer_t* msgSerializer, void *msg);
-
-#endif /* PUBSUB_SERIALIZER_JSON_H_ */
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/pubsub/pubsub_serializer_json/private/src/ps_activator.c
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_serializer_json/private/src/ps_activator.c b/pubsub/pubsub_serializer_json/private/src/ps_activator.c
deleted file mode 100644
index fec5892..0000000
--- a/pubsub/pubsub_serializer_json/private/src/ps_activator.c
+++ /dev/null
@@ -1,107 +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.
- */
-/*
- * ps_activator.c
- *
- * \date Mar 24, 2017
- * \author <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- * \copyright Apache License, Version 2.0
- */
-
-#include <stdlib.h>
-
-#include "bundle_activator.h"
-#include "service_registration.h"
-
-#include "pubsub_serializer_impl.h"
-
-struct activator {
- pubsub_serializer_t* serializer;
- pubsub_serializer_service_t* serializerService;
- service_registration_pt registration;
-};
-
-celix_status_t bundleActivator_create(bundle_context_pt context, void **userData) {
- celix_status_t status = CELIX_SUCCESS;
- struct activator *activator;
-
- activator = calloc(1, sizeof(*activator));
- if (!activator) {
- status = CELIX_ENOMEM;
- }
- else{
- *userData = activator;
- status = pubsubSerializer_create(context, &(activator->serializer));
- }
-
- return status;
-}
-
-celix_status_t bundleActivator_start(void * userData, bundle_context_pt context) {
- celix_status_t status = CELIX_SUCCESS;
- struct activator *activator = userData;
- pubsub_serializer_service_t* pubsubSerializerSvc = calloc(1, sizeof(*pubsubSerializerSvc));
-
- if (!pubsubSerializerSvc) {
- status = CELIX_ENOMEM;
- }
- else{
- pubsubSerializerSvc->handle = activator->serializer;
-
- pubsubSerializerSvc->createSerializerMap = (void*)pubsubSerializer_createSerializerMap;
- pubsubSerializerSvc->destroySerializerMap = (void*)pubsubSerializer_destroySerializerMap;
- activator->serializerService = pubsubSerializerSvc;
-
- /* Set serializer type */
- properties_pt props = properties_create();
- properties_set(props,PUBSUB_SERIALIZER_TYPE_KEY,PUBSUB_SERIALIZER_TYPE);
-
- status = bundleContext_registerService(context, PUBSUB_SERIALIZER_SERVICE, pubsubSerializerSvc, props, &activator->registration);
-
- }
-
- return status;
-}
-
-celix_status_t bundleActivator_stop(void * userData, bundle_context_pt context) {
- celix_status_t status = CELIX_SUCCESS;
- struct activator *activator = userData;
-
- serviceRegistration_unregister(activator->registration);
- activator->registration = NULL;
-
- free(activator->serializerService);
- activator->serializerService = NULL;
-
- return status;
-}
-
-celix_status_t bundleActivator_destroy(void * userData, bundle_context_pt context) {
- celix_status_t status = CELIX_SUCCESS;
- struct activator *activator = userData;
-
- pubsubSerializer_destroy(activator->serializer);
- activator->serializer = NULL;
-
- free(activator);
-
- return status;
-}
-
-
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/pubsub/pubsub_serializer_json/private/src/pubsub_serializer_impl.c
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_serializer_json/private/src/pubsub_serializer_impl.c b/pubsub/pubsub_serializer_json/private/src/pubsub_serializer_impl.c
deleted file mode 100644
index 685d499..0000000
--- a/pubsub/pubsub_serializer_json/private/src/pubsub_serializer_impl.c
+++ /dev/null
@@ -1,295 +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.
- */
-/*
- * pubsub_serializer_impl.c
- *
- * \date Mar 24, 2017
- * \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 <string.h>
-#include <unistd.h>
-#include <dirent.h>
-#include <inttypes.h>
-
-#include "utils.h"
-#include "hash_map.h"
-#include "bundle_context.h"
-
-#include "log_helper.h"
-
-#include "json_serializer.h"
-
-#include "pubsub_serializer_impl.h"
-
-#define SYSTEM_BUNDLE_ARCHIVE_PATH "CELIX_FRAMEWORK_EXTENDER_PATH"
-#define MAX_PATH_LEN 1024
-
-static char* pubsubSerializer_getMsgDescriptionDir(bundle_pt bundle);
-static void pubsubSerializer_addMsgSerializerFromBundle(const char *root, bundle_pt bundle, hash_map_pt msgTypesMap);
-static void pubsubSerializer_fillMsgSerializerMap(hash_map_pt msgTypesMap,bundle_pt bundle);
-
-celix_status_t pubsubSerializer_create(bundle_context_pt context, pubsub_serializer_t** serializer) {
- celix_status_t status = CELIX_SUCCESS;
-
- *serializer = calloc(1, sizeof(**serializer));
-
- if (!*serializer) {
- status = CELIX_ENOMEM;
- }
- else{
-
- (*serializer)->bundle_context= context;
-
- if (logHelper_create(context, &(*serializer)->loghelper) == CELIX_SUCCESS) {
- logHelper_start((*serializer)->loghelper);
- }
-
- }
-
- return status;
-}
-
-celix_status_t pubsubSerializer_destroy(pubsub_serializer_t* serializer) {
- celix_status_t status = CELIX_SUCCESS;
-
- logHelper_stop(serializer->loghelper);
- logHelper_destroy(&serializer->loghelper);
-
- free(serializer);
-
- return status;
-}
-
-celix_status_t pubsubSerializer_createSerializerMap(pubsub_serializer_t* serializer, bundle_pt bundle, hash_map_pt* serializerMap) {
- celix_status_t status = CELIX_SUCCESS;
-
- hash_map_pt map = hashMap_create(NULL, NULL, NULL, NULL);
-
- if (map != NULL) {
- pubsubSerializer_fillMsgSerializerMap(map, bundle);
- } else {
- logHelper_log(serializer->loghelper, OSGI_LOGSERVICE_ERROR, "Cannot allocate memory for msg map");
- status = CELIX_ENOMEM;
- }
-
- if (status == CELIX_SUCCESS) {
- *serializerMap = map;
- }
- return status;
-}
-
-celix_status_t pubsubSerializer_destroySerializerMap(pubsub_serializer_t* serializer, hash_map_pt serializerMap) {
- celix_status_t status = CELIX_SUCCESS;
- if (serializerMap == NULL) {
- return CELIX_ILLEGAL_ARGUMENT;
- }
-
- hash_map_iterator_t iter = hashMapIterator_construct(serializerMap);
- while (hashMapIterator_hasNext(&iter)) {
- pubsub_msg_serializer_t* msgSerializer = hashMapIterator_nextValue(&iter);
- dyn_message_type *dynMsg = (dyn_message_type*)msgSerializer->handle;
- dynMessage_destroy(dynMsg); //note msgSer->name and msgSer->version owned by dynType
- free(msgSerializer); //also contains the service struct.
- }
-
- hashMap_destroy(serializerMap, false, false);
-
- return status;
-}
-
-
-celix_status_t pubsubMsgSerializer_serialize(pubsub_msg_serializer_t* msgSerializer, const void* msg, void** out, size_t *outLen) {
- celix_status_t status = CELIX_SUCCESS;
-
- char *jsonOutput = NULL;
- dyn_type* dynType = NULL;
- dyn_message_type *dynMsg = (dyn_message_type*)msgSerializer->handle;
- dynMessage_getMessageType(dynMsg, &dynType);
-
- if (jsonSerializer_serialize(dynType, msg, &jsonOutput) != 0){
- status = CELIX_BUNDLE_EXCEPTION;
- }
-
- if (status == CELIX_SUCCESS) {
- *out = jsonOutput;
- *outLen = strlen(jsonOutput) + 1;
- }
-
- return status;
-}
-
-celix_status_t pubsubMsgSerializer_deserialize(pubsub_msg_serializer_t* msgSerializer, const void* input, size_t inputLen, void **out) {
-
- celix_status_t status = CELIX_SUCCESS;
- void *msg = NULL;
- dyn_type* dynType = NULL;
- dyn_message_type *dynMsg = (dyn_message_type*)msgSerializer->handle;
- dynMessage_getMessageType(dynMsg, &dynType);
-
- if (jsonSerializer_deserialize(dynType, (const char*)input, &msg) != 0) {
- status = CELIX_BUNDLE_EXCEPTION;
- }
- else{
- *out = msg;
- }
-
- return status;
-}
-
-void pubsubMsgSerializer_freeMsg(pubsub_msg_serializer_t* msgSerializer, void *msg) {
- dyn_type* dynType = NULL;
- dyn_message_type *dynMsg = (dyn_message_type*)msgSerializer->handle;
- dynMessage_getMessageType(dynMsg, &dynType);
- if (dynType != NULL) {
- dynType_free(dynType, msg);
- }
-}
-
-
-static void pubsubSerializer_fillMsgSerializerMap(hash_map_pt msgSerializers, bundle_pt bundle) {
- char* root = NULL;
- char* metaInfPath = NULL;
-
- root = pubsubSerializer_getMsgDescriptionDir(bundle);
-
- if(root != NULL){
- asprintf(&metaInfPath, "%s/META-INF/descriptors", root);
-
- pubsubSerializer_addMsgSerializerFromBundle(root, bundle, msgSerializers);
- pubsubSerializer_addMsgSerializerFromBundle(metaInfPath, bundle, msgSerializers);
-
- free(metaInfPath);
- free(root);
- }
-}
-
-static char* pubsubSerializer_getMsgDescriptionDir(bundle_pt bundle)
-{
- char *root = NULL;
-
- bool isSystemBundle = false;
- bundle_isSystemBundle(bundle, &isSystemBundle);
-
- if(isSystemBundle == true) {
- bundle_context_pt context;
- bundle_getContext(bundle, &context);
-
- const char *prop = NULL;
-
- bundleContext_getProperty(context, SYSTEM_BUNDLE_ARCHIVE_PATH, &prop);
-
- if(prop != NULL) {
- root = strdup(prop);
- } else {
- root = getcwd(NULL, 0);
- }
- } else {
- bundle_getEntry(bundle, ".", &root);
- }
-
- return root;
-}
-
-
-static void pubsubSerializer_addMsgSerializerFromBundle(const char *root, bundle_pt bundle, hash_map_pt msgSerializers)
-{
- char path[MAX_PATH_LEN];
- struct dirent *entry = NULL;
- DIR *dir = opendir(root);
-
- if(dir) {
- entry = readdir(dir);
- }
-
- while (entry != NULL) {
-
- if (strstr(entry->d_name, ".descriptor") != NULL) {
-
- printf("DMU: Parsing entry '%s'\n", entry->d_name);
-
- snprintf(path, MAX_PATH_LEN, "%s/%s", root, entry->d_name);
- FILE *stream = fopen(path,"r");
-
- if (stream != NULL){
- dyn_message_type* msgType = NULL;
-
- int rc = dynMessage_parse(stream, &msgType);
- if (rc == 0 && msgType != NULL) {
-
- char* msgName = NULL;
- rc += dynMessage_getName(msgType,&msgName);
-
- version_pt msgVersion = NULL;
- rc += dynMessage_getVersion(msgType, &msgVersion);
-
- if(rc == 0 && msgName != NULL && msgVersion != NULL){
-
- unsigned int msgId = utils_stringHash(msgName);
-
- pubsub_msg_serializer_t *msgSerializer = calloc(1,sizeof(pubsub_msg_serializer_t));
-
- msgSerializer->handle = msgType;
- msgSerializer->msgId = msgId;
- msgSerializer->msgName = msgName;
- msgSerializer->msgVersion = msgVersion;
- msgSerializer->serialize = (void*) pubsubMsgSerializer_serialize;
- msgSerializer->deserialize = (void*) pubsubMsgSerializer_deserialize;
- msgSerializer->freeMsg = (void*) pubsubMsgSerializer_freeMsg;
-
- bool clash = hashMap_containsKey(msgSerializers, (void*)(uintptr_t)msgId);
- if (clash){
- printf("Cannot add msg %s. clash in msg id %d!!\n", msgName, msgId);
- free(msgSerializer);
- dynMessage_destroy(msgType);
- }
- else if (msgId != 0){
- printf("Adding %u : %s\n", msgId, msgName);
- hashMap_put(msgSerializers, (void*)(uintptr_t)msgId, msgSerializer);
- }
- else{
- printf("Error creating msg serializer\n");
- free(msgSerializer);
- dynMessage_destroy(msgType);
- }
-
- }
- else{
- printf("Cannot retrieve name and/or version from msg\n");
- }
-
- } else{
- printf("DMU: cannot parse message from descriptor %s\n.",path);
- }
- fclose(stream);
- }else{
- printf("DMU: cannot open descriptor file %s\n.",path);
- }
-
- }
- entry = readdir(dir);
- }
-
- if(dir) {
- closedir(dir);
- }
-}
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/pubsub/pubsub_serializer_json/src/ps_activator.c
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_serializer_json/src/ps_activator.c b/pubsub/pubsub_serializer_json/src/ps_activator.c
new file mode 100644
index 0000000..fec5892
--- /dev/null
+++ b/pubsub/pubsub_serializer_json/src/ps_activator.c
@@ -0,0 +1,107 @@
+/**
+ *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.
+ */
+/*
+ * ps_activator.c
+ *
+ * \date Mar 24, 2017
+ * \author <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ * \copyright Apache License, Version 2.0
+ */
+
+#include <stdlib.h>
+
+#include "bundle_activator.h"
+#include "service_registration.h"
+
+#include "pubsub_serializer_impl.h"
+
+struct activator {
+ pubsub_serializer_t* serializer;
+ pubsub_serializer_service_t* serializerService;
+ service_registration_pt registration;
+};
+
+celix_status_t bundleActivator_create(bundle_context_pt context, void **userData) {
+ celix_status_t status = CELIX_SUCCESS;
+ struct activator *activator;
+
+ activator = calloc(1, sizeof(*activator));
+ if (!activator) {
+ status = CELIX_ENOMEM;
+ }
+ else{
+ *userData = activator;
+ status = pubsubSerializer_create(context, &(activator->serializer));
+ }
+
+ return status;
+}
+
+celix_status_t bundleActivator_start(void * userData, bundle_context_pt context) {
+ celix_status_t status = CELIX_SUCCESS;
+ struct activator *activator = userData;
+ pubsub_serializer_service_t* pubsubSerializerSvc = calloc(1, sizeof(*pubsubSerializerSvc));
+
+ if (!pubsubSerializerSvc) {
+ status = CELIX_ENOMEM;
+ }
+ else{
+ pubsubSerializerSvc->handle = activator->serializer;
+
+ pubsubSerializerSvc->createSerializerMap = (void*)pubsubSerializer_createSerializerMap;
+ pubsubSerializerSvc->destroySerializerMap = (void*)pubsubSerializer_destroySerializerMap;
+ activator->serializerService = pubsubSerializerSvc;
+
+ /* Set serializer type */
+ properties_pt props = properties_create();
+ properties_set(props,PUBSUB_SERIALIZER_TYPE_KEY,PUBSUB_SERIALIZER_TYPE);
+
+ status = bundleContext_registerService(context, PUBSUB_SERIALIZER_SERVICE, pubsubSerializerSvc, props, &activator->registration);
+
+ }
+
+ return status;
+}
+
+celix_status_t bundleActivator_stop(void * userData, bundle_context_pt context) {
+ celix_status_t status = CELIX_SUCCESS;
+ struct activator *activator = userData;
+
+ serviceRegistration_unregister(activator->registration);
+ activator->registration = NULL;
+
+ free(activator->serializerService);
+ activator->serializerService = NULL;
+
+ return status;
+}
+
+celix_status_t bundleActivator_destroy(void * userData, bundle_context_pt context) {
+ celix_status_t status = CELIX_SUCCESS;
+ struct activator *activator = userData;
+
+ pubsubSerializer_destroy(activator->serializer);
+ activator->serializer = NULL;
+
+ free(activator);
+
+ return status;
+}
+
+
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/pubsub/pubsub_serializer_json/src/pubsub_serializer_impl.c
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_serializer_json/src/pubsub_serializer_impl.c b/pubsub/pubsub_serializer_json/src/pubsub_serializer_impl.c
new file mode 100644
index 0000000..685d499
--- /dev/null
+++ b/pubsub/pubsub_serializer_json/src/pubsub_serializer_impl.c
@@ -0,0 +1,295 @@
+/**
+ *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.
+ */
+/*
+ * pubsub_serializer_impl.c
+ *
+ * \date Mar 24, 2017
+ * \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 <string.h>
+#include <unistd.h>
+#include <dirent.h>
+#include <inttypes.h>
+
+#include "utils.h"
+#include "hash_map.h"
+#include "bundle_context.h"
+
+#include "log_helper.h"
+
+#include "json_serializer.h"
+
+#include "pubsub_serializer_impl.h"
+
+#define SYSTEM_BUNDLE_ARCHIVE_PATH "CELIX_FRAMEWORK_EXTENDER_PATH"
+#define MAX_PATH_LEN 1024
+
+static char* pubsubSerializer_getMsgDescriptionDir(bundle_pt bundle);
+static void pubsubSerializer_addMsgSerializerFromBundle(const char *root, bundle_pt bundle, hash_map_pt msgTypesMap);
+static void pubsubSerializer_fillMsgSerializerMap(hash_map_pt msgTypesMap,bundle_pt bundle);
+
+celix_status_t pubsubSerializer_create(bundle_context_pt context, pubsub_serializer_t** serializer) {
+ celix_status_t status = CELIX_SUCCESS;
+
+ *serializer = calloc(1, sizeof(**serializer));
+
+ if (!*serializer) {
+ status = CELIX_ENOMEM;
+ }
+ else{
+
+ (*serializer)->bundle_context= context;
+
+ if (logHelper_create(context, &(*serializer)->loghelper) == CELIX_SUCCESS) {
+ logHelper_start((*serializer)->loghelper);
+ }
+
+ }
+
+ return status;
+}
+
+celix_status_t pubsubSerializer_destroy(pubsub_serializer_t* serializer) {
+ celix_status_t status = CELIX_SUCCESS;
+
+ logHelper_stop(serializer->loghelper);
+ logHelper_destroy(&serializer->loghelper);
+
+ free(serializer);
+
+ return status;
+}
+
+celix_status_t pubsubSerializer_createSerializerMap(pubsub_serializer_t* serializer, bundle_pt bundle, hash_map_pt* serializerMap) {
+ celix_status_t status = CELIX_SUCCESS;
+
+ hash_map_pt map = hashMap_create(NULL, NULL, NULL, NULL);
+
+ if (map != NULL) {
+ pubsubSerializer_fillMsgSerializerMap(map, bundle);
+ } else {
+ logHelper_log(serializer->loghelper, OSGI_LOGSERVICE_ERROR, "Cannot allocate memory for msg map");
+ status = CELIX_ENOMEM;
+ }
+
+ if (status == CELIX_SUCCESS) {
+ *serializerMap = map;
+ }
+ return status;
+}
+
+celix_status_t pubsubSerializer_destroySerializerMap(pubsub_serializer_t* serializer, hash_map_pt serializerMap) {
+ celix_status_t status = CELIX_SUCCESS;
+ if (serializerMap == NULL) {
+ return CELIX_ILLEGAL_ARGUMENT;
+ }
+
+ hash_map_iterator_t iter = hashMapIterator_construct(serializerMap);
+ while (hashMapIterator_hasNext(&iter)) {
+ pubsub_msg_serializer_t* msgSerializer = hashMapIterator_nextValue(&iter);
+ dyn_message_type *dynMsg = (dyn_message_type*)msgSerializer->handle;
+ dynMessage_destroy(dynMsg); //note msgSer->name and msgSer->version owned by dynType
+ free(msgSerializer); //also contains the service struct.
+ }
+
+ hashMap_destroy(serializerMap, false, false);
+
+ return status;
+}
+
+
+celix_status_t pubsubMsgSerializer_serialize(pubsub_msg_serializer_t* msgSerializer, const void* msg, void** out, size_t *outLen) {
+ celix_status_t status = CELIX_SUCCESS;
+
+ char *jsonOutput = NULL;
+ dyn_type* dynType = NULL;
+ dyn_message_type *dynMsg = (dyn_message_type*)msgSerializer->handle;
+ dynMessage_getMessageType(dynMsg, &dynType);
+
+ if (jsonSerializer_serialize(dynType, msg, &jsonOutput) != 0){
+ status = CELIX_BUNDLE_EXCEPTION;
+ }
+
+ if (status == CELIX_SUCCESS) {
+ *out = jsonOutput;
+ *outLen = strlen(jsonOutput) + 1;
+ }
+
+ return status;
+}
+
+celix_status_t pubsubMsgSerializer_deserialize(pubsub_msg_serializer_t* msgSerializer, const void* input, size_t inputLen, void **out) {
+
+ celix_status_t status = CELIX_SUCCESS;
+ void *msg = NULL;
+ dyn_type* dynType = NULL;
+ dyn_message_type *dynMsg = (dyn_message_type*)msgSerializer->handle;
+ dynMessage_getMessageType(dynMsg, &dynType);
+
+ if (jsonSerializer_deserialize(dynType, (const char*)input, &msg) != 0) {
+ status = CELIX_BUNDLE_EXCEPTION;
+ }
+ else{
+ *out = msg;
+ }
+
+ return status;
+}
+
+void pubsubMsgSerializer_freeMsg(pubsub_msg_serializer_t* msgSerializer, void *msg) {
+ dyn_type* dynType = NULL;
+ dyn_message_type *dynMsg = (dyn_message_type*)msgSerializer->handle;
+ dynMessage_getMessageType(dynMsg, &dynType);
+ if (dynType != NULL) {
+ dynType_free(dynType, msg);
+ }
+}
+
+
+static void pubsubSerializer_fillMsgSerializerMap(hash_map_pt msgSerializers, bundle_pt bundle) {
+ char* root = NULL;
+ char* metaInfPath = NULL;
+
+ root = pubsubSerializer_getMsgDescriptionDir(bundle);
+
+ if(root != NULL){
+ asprintf(&metaInfPath, "%s/META-INF/descriptors", root);
+
+ pubsubSerializer_addMsgSerializerFromBundle(root, bundle, msgSerializers);
+ pubsubSerializer_addMsgSerializerFromBundle(metaInfPath, bundle, msgSerializers);
+
+ free(metaInfPath);
+ free(root);
+ }
+}
+
+static char* pubsubSerializer_getMsgDescriptionDir(bundle_pt bundle)
+{
+ char *root = NULL;
+
+ bool isSystemBundle = false;
+ bundle_isSystemBundle(bundle, &isSystemBundle);
+
+ if(isSystemBundle == true) {
+ bundle_context_pt context;
+ bundle_getContext(bundle, &context);
+
+ const char *prop = NULL;
+
+ bundleContext_getProperty(context, SYSTEM_BUNDLE_ARCHIVE_PATH, &prop);
+
+ if(prop != NULL) {
+ root = strdup(prop);
+ } else {
+ root = getcwd(NULL, 0);
+ }
+ } else {
+ bundle_getEntry(bundle, ".", &root);
+ }
+
+ return root;
+}
+
+
+static void pubsubSerializer_addMsgSerializerFromBundle(const char *root, bundle_pt bundle, hash_map_pt msgSerializers)
+{
+ char path[MAX_PATH_LEN];
+ struct dirent *entry = NULL;
+ DIR *dir = opendir(root);
+
+ if(dir) {
+ entry = readdir(dir);
+ }
+
+ while (entry != NULL) {
+
+ if (strstr(entry->d_name, ".descriptor") != NULL) {
+
+ printf("DMU: Parsing entry '%s'\n", entry->d_name);
+
+ snprintf(path, MAX_PATH_LEN, "%s/%s", root, entry->d_name);
+ FILE *stream = fopen(path,"r");
+
+ if (stream != NULL){
+ dyn_message_type* msgType = NULL;
+
+ int rc = dynMessage_parse(stream, &msgType);
+ if (rc == 0 && msgType != NULL) {
+
+ char* msgName = NULL;
+ rc += dynMessage_getName(msgType,&msgName);
+
+ version_pt msgVersion = NULL;
+ rc += dynMessage_getVersion(msgType, &msgVersion);
+
+ if(rc == 0 && msgName != NULL && msgVersion != NULL){
+
+ unsigned int msgId = utils_stringHash(msgName);
+
+ pubsub_msg_serializer_t *msgSerializer = calloc(1,sizeof(pubsub_msg_serializer_t));
+
+ msgSerializer->handle = msgType;
+ msgSerializer->msgId = msgId;
+ msgSerializer->msgName = msgName;
+ msgSerializer->msgVersion = msgVersion;
+ msgSerializer->serialize = (void*) pubsubMsgSerializer_serialize;
+ msgSerializer->deserialize = (void*) pubsubMsgSerializer_deserialize;
+ msgSerializer->freeMsg = (void*) pubsubMsgSerializer_freeMsg;
+
+ bool clash = hashMap_containsKey(msgSerializers, (void*)(uintptr_t)msgId);
+ if (clash){
+ printf("Cannot add msg %s. clash in msg id %d!!\n", msgName, msgId);
+ free(msgSerializer);
+ dynMessage_destroy(msgType);
+ }
+ else if (msgId != 0){
+ printf("Adding %u : %s\n", msgId, msgName);
+ hashMap_put(msgSerializers, (void*)(uintptr_t)msgId, msgSerializer);
+ }
+ else{
+ printf("Error creating msg serializer\n");
+ free(msgSerializer);
+ dynMessage_destroy(msgType);
+ }
+
+ }
+ else{
+ printf("Cannot retrieve name and/or version from msg\n");
+ }
+
+ } else{
+ printf("DMU: cannot parse message from descriptor %s\n.",path);
+ }
+ fclose(stream);
+ }else{
+ printf("DMU: cannot open descriptor file %s\n.",path);
+ }
+
+ }
+ entry = readdir(dir);
+ }
+
+ if(dir) {
+ closedir(dir);
+ }
+}
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/pubsub/pubsub_serializer_json/src/pubsub_serializer_impl.h
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_serializer_json/src/pubsub_serializer_impl.h b/pubsub/pubsub_serializer_json/src/pubsub_serializer_impl.h
new file mode 100644
index 0000000..c36f20e
--- /dev/null
+++ b/pubsub/pubsub_serializer_json/src/pubsub_serializer_impl.h
@@ -0,0 +1,55 @@
+/**
+ *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.
+ */
+/*
+ * pubsub_serializer_impl.h
+ *
+ * \date Mar 24, 2017
+ * \author <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ * \copyright Apache License, Version 2.0
+ */
+
+#ifndef PUBSUB_SERIALIZER_JSON_H_
+#define PUBSUB_SERIALIZER_JSON_H_
+
+#include "dyn_common.h"
+#include "dyn_type.h"
+#include "dyn_message.h"
+#include "log_helper.h"
+
+#include "pubsub_serializer.h"
+
+#define PUBSUB_SERIALIZER_TYPE "json"
+
+typedef struct pubsub_serializer {
+ bundle_context_pt bundle_context;
+ log_helper_pt loghelper;
+} pubsub_serializer_t;
+
+celix_status_t pubsubSerializer_create(bundle_context_pt context, pubsub_serializer_t* *serializer);
+celix_status_t pubsubSerializer_destroy(pubsub_serializer_t* serializer);
+
+celix_status_t pubsubSerializer_createSerializerMap(pubsub_serializer_t* serializer, bundle_pt bundle, hash_map_pt* serializerMap);
+celix_status_t pubsubSerializer_destroySerializerMap(pubsub_serializer_t*, hash_map_pt serializerMap);
+
+/* Start of serializer specific functions */
+celix_status_t pubsubMsgSerializer_serialize(pubsub_msg_serializer_t* msgSerializer, const void* msg, void** out, size_t *outLen);
+celix_status_t pubsubMsgSerializer_deserialize(pubsub_msg_serializer_t* msgSerializer, const void* input, size_t inputLen, void **out);
+void pubsubMsgSerializer_freeMsg(pubsub_msg_serializer_t* msgSerializer, void *msg);
+
+#endif /* PUBSUB_SERIALIZER_JSON_H_ */
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/pubsub/pubsub_topology_manager/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_topology_manager/CMakeLists.txt b/pubsub/pubsub_topology_manager/CMakeLists.txt
index b6eb796..784ca21 100644
--- a/pubsub/pubsub_topology_manager/CMakeLists.txt
+++ b/pubsub/pubsub_topology_manager/CMakeLists.txt
@@ -15,21 +15,12 @@
# specific language governing permissions and limitations
# under the License.
-include_directories("${PROJECT_SOURCE_DIR}/log_service/public/include")
-include_directories("${PROJECT_SOURCE_DIR}/remote_services/remote_service_admin/public/include")
-include_directories("${PROJECT_SOURCE_DIR}/pubsub/pubsub_common/public/include")
-include_directories("${PROJECT_SOURCE_DIR}/pubsub/pubsub_admin/public/include")
-include_directories("${PROJECT_SOURCE_DIR}/pubsub/api/pubsub")
-include_directories("private/include")
-include_directories("public/include")
-
add_bundle(org.apache.celix.pubsub_topology_manager.PubSubTopologyManager
BUNDLE_SYMBOLICNAME "apache_celix_pubsub_topology_manager"
VERSION "1.0.0"
SOURCES
private/src/pstm_activator.c
private/src/pubsub_topology_manager.c
- ${PROJECT_SOURCE_DIR}/log_service/public/src/log_helper.c
${PROJECT_SOURCE_DIR}/pubsub/pubsub_common/public/src/pubsub_endpoint.c
${PROJECT_SOURCE_DIR}/pubsub/pubsub_common/public/src/pubsub_utils.c
)
@@ -38,7 +29,8 @@ bundle_files(org.apache.celix.pubsub_topology_manager.PubSubTopologyManager
${PROJECT_SOURCE_DIR}/pubsub/pubsub_common/public/include/pubsub_topic_info.descriptor
DESTINATION "META-INF/descriptors/services"
)
+target_link_libraries(org.apache.celix.pubsub_topology_manager.PubSubTopologyManager PRIVATE Celix::framework Celix::log_helper)
+
-target_link_libraries(org.apache.celix.pubsub_topology_manager.PubSubTopologyManager celix_framework celix_utils)
install_bundle(org.apache.celix.pubsub_topology_manager.PubSubTopologyManager)
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/pubsub/test/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/pubsub/test/CMakeLists.txt b/pubsub/test/CMakeLists.txt
index 8279c0c..65e22e5 100644
--- a/pubsub/test/CMakeLists.txt
+++ b/pubsub/test/CMakeLists.txt
@@ -31,7 +31,7 @@ add_bundle(pubsub_sut
test/sut_activator.c
VERSION 1.0.0
)
-target_link_libraries(pubsub_sut celix_framework celix_utils)
+target_link_libraries(pubsub_sut PRIVATE Celix::framework)
bundle_files(pubsub_sut
msg_descriptors/msg.descriptor
msg_descriptors/sync.descriptor
@@ -66,9 +66,9 @@ add_bundle(pubsub_tst
)
if (APPLE)
#Note that the launcher celix_test_runner is linked with CppuTest, not the bundle libs. Default libCppUTest.a is not compiled for relocation
- target_link_libraries(pubsub_tst celix_framework celix_utils -Wl,-undefined -Wl,dynamic_lookup)
+ target_link_libraries(pubsub_tst PRIVATE Celix::framework -Wl,-undefined -Wl,dynamic_lookup)
else ()
- target_link_libraries(pubsub_tst celix_framework celix_utils)
+ target_link_libraries(pubsub_tst PRIVATE Celix::framework)
endif ()
bundle_files(pubsub_tst
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/remote_services/CMakeLists.txt b/remote_services/CMakeLists.txt
index 767ece7..7ca1c44 100644
--- a/remote_services/CMakeLists.txt
+++ b/remote_services/CMakeLists.txt
@@ -21,14 +21,16 @@ if (REMOTE_SERVICE_ADMIN)
add_subdirectory(examples)
add_subdirectory(topology_manager)
-
+
+ add_subdirectory(discovery_common)
add_subdirectory(discovery_configured)
add_subdirectory(discovery_etcd)
add_subdirectory(discovery_shm)
#TODO refactor shm rsa to use dfi
+ add_subdirectory(remote_service_admin_api)
+ add_subdirectory(remote_service_admin_common)
#add_subdirectory(remote_service_admin_shm)
- add_subdirectory(remote_service_admin)
add_subdirectory(remote_service_admin_dfi)
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/discovery/private/include/discovery.h
----------------------------------------------------------------------
diff --git a/remote_services/discovery/private/include/discovery.h b/remote_services/discovery/private/include/discovery.h
deleted file mode 100644
index ee79caf..0000000
--- a/remote_services/discovery/private/include/discovery.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/**
- *Licensed to the Apache Software Foundation (ASF) under one
- *or more contributor license agreements. See the NOTICE file
- *distributed with this work for additional information
- *regarding copyright ownership. The ASF licenses this file
- *to you under the Apache License, Version 2.0 (the
- *"License"); you may not use this file except in compliance
- *with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- *Unless required by applicable law or agreed to in writing,
- *software distributed under the License is distributed on an
- *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- *specific language governing permissions and limitations
- *under the License.
- */
-/*
- * discovery.h
- *
- * \date Sep 29, 2011
- * \author <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- * \copyright Apache License, Version 2.0
- */
-
-#ifndef DISCOVERY_H_
-#define DISCOVERY_H_
-
-#include "bundle_context.h"
-#include "service_reference.h"
-
-#include "endpoint_description.h"
-#include "endpoint_listener.h"
-
-#define DISCOVERY_SERVER_INTERFACE "DISCOVERY_CFG_SERVER_INTERFACE"
-#define DISCOVERY_SERVER_IP "DISCOVERY_CFG_SERVER_IP"
-#define DISCOVERY_SERVER_PORT "DISCOVERY_CFG_SERVER_PORT"
-#define DISCOVERY_SERVER_PATH "DISCOVERY_CFG_SERVER_PATH"
-#define DISCOVERY_POLL_ENDPOINTS "DISCOVERY_CFG_POLL_ENDPOINTS"
-#define DISCOVERY_SERVER_MAX_EP "DISCOVERY_CFG_SERVER_MAX_EP"
-
-typedef struct discovery *discovery_pt;
-
-
-/* those one could be put into a general discovery.h - file */
-celix_status_t discovery_create(bundle_context_pt context, discovery_pt *discovery);
-celix_status_t discovery_destroy(discovery_pt discovery);
-
-celix_status_t discovery_start(discovery_pt discovery);
-celix_status_t discovery_stop(discovery_pt discovery);
-
-celix_status_t discovery_endpointAdded(void *handle, endpoint_description_pt endpoint, char *machtedFilter);
-celix_status_t discovery_endpointRemoved(void *handle, endpoint_description_pt endpoint, char *machtedFilter);
-
-celix_status_t discovery_endpointListenerAdding(void * handle, service_reference_pt reference, void **service);
-celix_status_t discovery_endpointListenerAdded(void * handle, service_reference_pt reference, void * service);
-celix_status_t discovery_endpointListenerModified(void * handle, service_reference_pt reference, void * service);
-celix_status_t discovery_endpointListenerRemoved(void * handle, service_reference_pt reference, void * service);
-
-celix_status_t discovery_informEndpointListeners(discovery_pt discovery, endpoint_description_pt endpoint, bool endpointAdded);
-celix_status_t discovery_updateEndpointListener(discovery_pt discovery, service_reference_pt reference, endpoint_listener_pt service);
-
-celix_status_t discovery_addDiscoveredEndpoint(discovery_pt discovery, endpoint_description_pt endpoint);
-celix_status_t discovery_removeDiscoveredEndpoint(discovery_pt discovery, endpoint_description_pt endpoint);
-
-#endif /* DISCOVERY_H_ */
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/discovery/private/include/endpoint_descriptor_common.h
----------------------------------------------------------------------
diff --git a/remote_services/discovery/private/include/endpoint_descriptor_common.h b/remote_services/discovery/private/include/endpoint_descriptor_common.h
deleted file mode 100644
index a186a18..0000000
--- a/remote_services/discovery/private/include/endpoint_descriptor_common.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-/*
- * endpoint_descriptor_common.h
- *
- * \date Aug 8, 2014
- * \author <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- * \copyright Apache License, Version 2.0
- */
-
-#ifndef ENDPOINT_DESCRIPTOR_COMMON_H_
-#define ENDPOINT_DESCRIPTOR_COMMON_H_
-
-/*
- * Private constant & enum definitions for endpoint descriptor reader and writer, not needed for normal usage of the reader and writer.
- */
-
-typedef enum {
- VALUE_TYPE_STRING,
- VALUE_TYPE_LONG,
- VALUE_TYPE_DOUBLE,
- VALUE_TYPE_FLOAT,
- VALUE_TYPE_INTEGER,
- VALUE_TYPE_BYTE,
- VALUE_TYPE_CHAR,
- VALUE_TYPE_BOOLEAN,
- VALUE_TYPE_SHORT,
-} valueType;
-
-static const __attribute__((unused)) xmlChar* XML = (const xmlChar*) "xml";
-static const __attribute__((unused)) xmlChar* XMLNS = (const xmlChar*) "http://www.osgi.org/xmlns/rsa/v1.0.0";
-
-static const __attribute__((unused)) xmlChar* ENDPOINT_DESCRIPTIONS = (const xmlChar*) "endpoint-descriptions";
-static const xmlChar* ENDPOINT_DESCRIPTION = (const xmlChar*) "endpoint-description";
-
-static const xmlChar* ARRAY = (const xmlChar*) "array";
-static const __attribute__((unused)) xmlChar* LIST = (const xmlChar*) "list";
-static const __attribute__((unused)) xmlChar* SET = (const xmlChar*) "set";
-
-static const xmlChar* PROPERTY = (const xmlChar*) "property";
-static const xmlChar* NAME = (const xmlChar*) "name";
-static const xmlChar* VALUE = (const xmlChar*) "value";
-static const xmlChar* VALUE_TYPE = (const xmlChar*) "value-type";
-
-#endif /* ENDPOINT_DESCRIPTOR_COMMON_H_ */
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/discovery/private/include/endpoint_descriptor_reader.h
----------------------------------------------------------------------
diff --git a/remote_services/discovery/private/include/endpoint_descriptor_reader.h b/remote_services/discovery/private/include/endpoint_descriptor_reader.h
deleted file mode 100644
index 7a05d9e..0000000
--- a/remote_services/discovery/private/include/endpoint_descriptor_reader.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/**
- *Licensed to the Apache Software Foundation (ASF) under one
- *or more contributor license agreements. See the NOTICE file
- *distributed with this work for additional information
- *regarding copyright ownership. The ASF licenses this file
- *to you under the Apache License, Version 2.0 (the
- *"License"); you may not use this file except in compliance
- *with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- *Unless required by applicable law or agreed to in writing,
- *software distributed under the License is distributed on an
- *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- *specific language governing permissions and limitations
- *under the License.
- */
-/*
- * endpoint_descriptor_reader.h
- *
- * \date 26 Jul 2014
- * \author <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- * \copyright Apache License, Version 2.0
- */
-
-#ifndef ENDPOINT_DESCRIPTOR_READER_H_
-#define ENDPOINT_DESCRIPTOR_READER_H_
-
-#include "endpoint_discovery_poller.h"
-#include "celix_errno.h"
-#include "array_list.h"
-
-typedef struct endpoint_descriptor_reader *endpoint_descriptor_reader_pt;
-
-celix_status_t endpointDescriptorReader_create(endpoint_discovery_poller_pt poller, endpoint_descriptor_reader_pt *reader);
-celix_status_t endpointDescriptorReader_destroy(endpoint_descriptor_reader_pt reader);
-
-celix_status_t endpointDescriptorReader_parseDocument(endpoint_descriptor_reader_pt reader, char *document, array_list_pt *endpoints);
-
-
-#endif /* ENDPOINT_DESCRIPTOR_READER_H_ */
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/discovery/private/include/endpoint_descriptor_writer.h
----------------------------------------------------------------------
diff --git a/remote_services/discovery/private/include/endpoint_descriptor_writer.h b/remote_services/discovery/private/include/endpoint_descriptor_writer.h
deleted file mode 100644
index 3c5a9be..0000000
--- a/remote_services/discovery/private/include/endpoint_descriptor_writer.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/**
- *Licensed to the Apache Software Foundation (ASF) under one
- *or more contributor license agreements. See the NOTICE file
- *distributed with this work for additional information
- *regarding copyright ownership. The ASF licenses this file
- *to you under the Apache License, Version 2.0 (the
- *"License"); you may not use this file except in compliance
- *with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- *Unless required by applicable law or agreed to in writing,
- *software distributed under the License is distributed on an
- *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- *specific language governing permissions and limitations
- *under the License.
- */
-/*
- * endpoint_descriptor_writer.h
- *
- * \date 26 Jul 2014
- * \author <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- * \copyright Apache License, Version 2.0
- */
-
-#ifndef ENDPOINT_DESCRIPTOR_WRITER_H_
-#define ENDPOINT_DESCRIPTOR_WRITER_H_
-
-#include "celix_errno.h"
-#include "array_list.h"
-
-typedef struct endpoint_descriptor_writer *endpoint_descriptor_writer_pt;
-
-celix_status_t endpointDescriptorWriter_create(endpoint_descriptor_writer_pt *writer);
-celix_status_t endpointDescriptorWriter_destroy(endpoint_descriptor_writer_pt writer);
-celix_status_t endpointDescriptorWriter_writeDocument(endpoint_descriptor_writer_pt writer, array_list_pt endpoints, char **document);
-
-#endif /* ENDPOINT_DESCRIPTOR_WRITER_H_ */
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/discovery/private/include/endpoint_discovery_poller.h
----------------------------------------------------------------------
diff --git a/remote_services/discovery/private/include/endpoint_discovery_poller.h b/remote_services/discovery/private/include/endpoint_discovery_poller.h
deleted file mode 100644
index d344e55..0000000
--- a/remote_services/discovery/private/include/endpoint_discovery_poller.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-/*
- * endpoint_discovery_poller.h
- *
- * \date 3 Jul 2014
- * \author <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- * \copyright Apache License, Version 2.0
- */
-
-#ifndef ENDPOINT_DISCOVERY_POLLER_H_
-#define ENDPOINT_DISCOVERY_POLLER_H_
-
-#include "celix_errno.h"
-#include "discovery.h"
-#include "log_helper.h"
-
-struct endpoint_discovery_poller {
- discovery_pt discovery;
- hash_map_pt entries;
- log_helper_pt* loghelper;
-
- celix_thread_mutex_t pollerLock;
- celix_thread_t pollerThread;
-
- unsigned int poll_interval;
- volatile bool running;
-};
-
-typedef struct endpoint_discovery_poller *endpoint_discovery_poller_pt;
-
-celix_status_t endpointDiscoveryPoller_create(discovery_pt discovery, bundle_context_pt context, endpoint_discovery_poller_pt *poller);
-celix_status_t endpointDiscoveryPoller_destroy(endpoint_discovery_poller_pt poller);
-
-celix_status_t endpointDiscoveryPoller_addDiscoveryEndpoint(endpoint_discovery_poller_pt poller, char *url);
-celix_status_t endpointDiscoveryPoller_removeDiscoveryEndpoint(endpoint_discovery_poller_pt poller, char *url);
-
-celix_status_t endpointDiscoveryPoller_getDiscoveryEndpoints(endpoint_discovery_poller_pt poller, array_list_pt urls);
-
-#endif /* ENDPOINT_DISCOVERY_POLLER_H_ */
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/discovery/private/include/endpoint_discovery_server.h
----------------------------------------------------------------------
diff --git a/remote_services/discovery/private/include/endpoint_discovery_server.h b/remote_services/discovery/private/include/endpoint_discovery_server.h
deleted file mode 100644
index 51082b5..0000000
--- a/remote_services/discovery/private/include/endpoint_discovery_server.h
+++ /dev/null
@@ -1,81 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-/*
- * endpoint_discovery_server.h
- *
- * \date Aug 12, 2014
- * \author <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- * \copyright Apache License, Version 2.0
- */
-
-#ifndef ENDPOINT_DISCOVERY_SERVER_H_
-#define ENDPOINT_DISCOVERY_SERVER_H_
-
-#include "celix_errno.h"
-#include "discovery.h"
-
-typedef struct endpoint_discovery_server *endpoint_discovery_server_pt;
-
-/**
- * Creates and starts a new instance of an endpoint discovery server.
- *
- * @param discovery [in] the discovery service itself;
- * @param context [in] the bundle context;
- * @param server [out] the pointer to the created instance.
- * @return CELIX_SUCCESS when successful.
- */
-celix_status_t endpointDiscoveryServer_create(discovery_pt discovery, bundle_context_pt context, endpoint_discovery_server_pt *server);
-
-/**
- * Stops and destroys a given instance of an endpoint discovery server.
- *
- * @param server [in] the pointer to the instance to destroy.
- * @return CELIX_SUCCESS when successful.
- */
-celix_status_t endpointDiscoveryServer_destroy(endpoint_discovery_server_pt server);
-
-/**
- * Adds a given endpoint description to expose through the given discovery server.
- *
- * @param server [in] the endpoint discovery server to expose the endpoint through;
- * @param endpoint [in] the endpoint description to expose.
- * @return CELIX_SUCCESS when successful.
- */
-celix_status_t endpointDiscoveryServer_addEndpoint(endpoint_discovery_server_pt server, endpoint_description_pt endpoint);
-
-/**
- * Removes a given endpoint description from exposure through the given discovery server.
- *
- * @param server [in] the endpoint discovery server to remove the endpoint from;
- * @param endpoint [in] the endpoint description to remove.
- * @return CELIX_SUCCESS when successful.
- */
-celix_status_t endpointDiscoveryServer_removeEndpoint( endpoint_discovery_server_pt server, endpoint_description_pt endpoint);
-
-/**
- * Returns the url, which is used by the discovery server to announce the endpoints
- *
- * @param server [in] the endpoint discovery server to retrieve the url from
- * @param url [out] url which is used to announce the endpoints.
- * @return CELIX_SUCCESS when successful.
- */
-celix_status_t endpointDiscoveryServer_getUrl(endpoint_discovery_server_pt server, char* url);
-
-
-#endif /* ENDPOINT_DISCOVERY_SERVER_H_ */
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/discovery/private/src/desc.xml
----------------------------------------------------------------------
diff --git a/remote_services/discovery/private/src/desc.xml b/remote_services/discovery/private/src/desc.xml
deleted file mode 100644
index 5998992..0000000
--- a/remote_services/discovery/private/src/desc.xml
+++ /dev/null
@@ -1,41 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- *Licensed to the Apache Software Foundation (ASF) under one
- *or more contributor license agreements. See the NOTICE file
- *distributed with this work for additional information
- *regarding copyright ownership. The ASF licenses this file
- *to you under the Apache License, Version 2.0 (the
- *"License"); you may not use this file except in compliance
- *with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- *Unless required by applicable law or agreed to in writing,
- *software distributed under the License is distributed on an
- *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- *specific language governing permissions and limitations
- *under the License.
- -->
-<endpoint-descriptions xmlns="http://www.osgi.org/xmlns/rsa/v1.0.0">
- <endpoint-description>
- <property name="service.intents">
- <list>
- <value>SOAP</value>
- <value>HTTP</value>
- </list>
- </property>
- <property name="endpoint.id" value="http://ws.acme.com:9000/hello" />
- <property name="objectClass" value="com.acme.Foo" />
- <property name="endpoint.package.version.com.acme" value="4.2" />
- <property name="service.imported.configs" value="com.acme" />
- <property name="com.acme.ws.xml">
- <xml>
- <config xmlns="http://acme.com/defs">
- <port>1029</port>
- <host>www.acme.com</host>
- </config>
- </xml>
- </property>
- </endpoint-description>
-</endpoint-descriptions>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/discovery/private/src/discovery.c
----------------------------------------------------------------------
diff --git a/remote_services/discovery/private/src/discovery.c b/remote_services/discovery/private/src/discovery.c
deleted file mode 100644
index e40a887..0000000
--- a/remote_services/discovery/private/src/discovery.c
+++ /dev/null
@@ -1,233 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-/*
- * discovery.c
- *
- * \date Aug 8, 2014
- * \author <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- * \copyright Apache License, Version 2.0
- */
-#include <stdio.h>
-#include <stdbool.h>
-#include <netdb.h>
-#include <string.h>
-
-#include "celix_threads.h"
-#include "bundle_context.h"
-#include "log_helper.h"
-#include "discovery.h"
-#include "discovery_impl.h"
-
-
-celix_status_t discovery_endpointAdded(void *handle, endpoint_description_pt endpoint, char *matchedFilter) {
- celix_status_t status;
- discovery_pt discovery = handle;
-
- logHelper_log(discovery->loghelper, OSGI_LOGSERVICE_INFO, "Endpoint for %s, with filter \"%s\" added...", endpoint->service, matchedFilter);
-
- status = endpointDiscoveryServer_addEndpoint(discovery->server, endpoint);
-
- return status;
-}
-
-celix_status_t discovery_endpointRemoved(void *handle, endpoint_description_pt endpoint, char *matchedFilter) {
- celix_status_t status;
- discovery_pt discovery = handle;
-
- logHelper_log(discovery->loghelper, OSGI_LOGSERVICE_INFO, "Endpoint for %s, with filter \"%s\" removed...", endpoint->service, matchedFilter);
-
- status = endpointDiscoveryServer_removeEndpoint(discovery->server, endpoint);
-
- return status;
-}
-
-celix_status_t discovery_endpointListenerAdding(void* handle, service_reference_pt reference, void** service) {
- celix_status_t status = CELIX_SUCCESS;
- discovery_pt discovery = handle;
-
- bundleContext_getService(discovery->context, reference, service);
-
- return status;
-}
-
-celix_status_t discovery_endpointListenerAdded(void* handle, service_reference_pt reference, void* service) {
- celix_status_t status = CELIX_SUCCESS;
- discovery_pt discovery = handle;
-
- const char *discoveryListener = NULL;
- serviceReference_getProperty(reference, "DISCOVERY", &discoveryListener);
- const char *scope = NULL;
- serviceReference_getProperty(reference, OSGI_ENDPOINT_LISTENER_SCOPE, &scope);
-
- filter_pt filter = filter_create(scope);
-
- if (discoveryListener != NULL && strcmp(discoveryListener, "true") == 0) {
- logHelper_log(discovery->loghelper, OSGI_LOGSERVICE_INFO, "EndpointListener Ignored - Discovery listener");
- } else {
- celixThreadMutex_lock(&discovery->discoveredServicesMutex);
-
- hash_map_iterator_pt iter = hashMapIterator_create(discovery->discoveredServices);
- while (hashMapIterator_hasNext(iter)) {
- endpoint_description_pt endpoint = hashMapIterator_nextValue(iter);
-
- bool matchResult = false;
- filter_match(filter, endpoint->properties, &matchResult);
- if (matchResult) {
- endpoint_listener_pt listener = service;
-
- logHelper_log(discovery->loghelper, OSGI_LOGSERVICE_INFO, "EndpointListener Added - Add Scope");
-
- listener->endpointAdded(listener->handle, endpoint, NULL);
- }
- }
- hashMapIterator_destroy(iter);
-
- celixThreadMutex_unlock(&discovery->discoveredServicesMutex);
-
- celixThreadMutex_lock(&discovery->listenerReferencesMutex);
-
- hashMap_put(discovery->listenerReferences, reference, NULL);
-
- celixThreadMutex_unlock(&discovery->listenerReferencesMutex);
- }
-
- filter_destroy(filter);
-
- return status;
-}
-
-celix_status_t discovery_endpointListenerModified(void * handle, service_reference_pt reference, void * service) {
- celix_status_t status;
-
- status = discovery_endpointListenerRemoved(handle, reference, service);
- if (status == CELIX_SUCCESS) {
- status = discovery_endpointListenerAdded(handle, reference, service);
- }
-
- return status;
-}
-
-celix_status_t discovery_endpointListenerRemoved(void * handle, service_reference_pt reference, void * service) {
- celix_status_t status;
- discovery_pt discovery = handle;
-
- status = celixThreadMutex_lock(&discovery->listenerReferencesMutex);
-
- if (status == CELIX_SUCCESS) {
- if (discovery->listenerReferences != NULL) {
- if (hashMap_remove(discovery->listenerReferences, reference)) {
- logHelper_log(discovery->loghelper, OSGI_LOGSERVICE_INFO, "EndpointListener Removed");
- }
- }
-
- status = celixThreadMutex_unlock(&discovery->listenerReferencesMutex);
- }
-
- return status;
-}
-
-celix_status_t discovery_informEndpointListeners(discovery_pt discovery, endpoint_description_pt endpoint, bool endpointAdded) {
- celix_status_t status;
-
- // Inform listeners of new endpoint
- status = celixThreadMutex_lock(&discovery->listenerReferencesMutex);
-
- if (status == CELIX_SUCCESS) {
- if (discovery->listenerReferences != NULL) {
- hash_map_iterator_pt iter = hashMapIterator_create(discovery->listenerReferences);
- while (hashMapIterator_hasNext(iter)) {
- hash_map_entry_pt entry = hashMapIterator_nextEntry(iter);
-
- service_reference_pt reference = hashMapEntry_getKey(entry);
- endpoint_listener_pt listener = NULL;
-
- const char* scope = NULL;
- serviceReference_getProperty(reference, OSGI_ENDPOINT_LISTENER_SCOPE, &scope);
-
- filter_pt filter = filter_create(scope);
- bool matchResult = false;
-
- status = filter_match(filter, endpoint->properties, &matchResult);
- if (status == CELIX_SUCCESS) {
- if (matchResult) {
- bundleContext_getService(discovery->context, reference, (void **) &listener);
- if (endpointAdded) {
- logHelper_log(discovery->loghelper, OSGI_LOGSERVICE_INFO, "Adding service (%s)", endpoint->service);
-
- listener->endpointAdded(listener->handle, endpoint, (char*)scope);
- } else {
- logHelper_log(discovery->loghelper, OSGI_LOGSERVICE_INFO, "Removing service (%s)", endpoint->service);
-
- listener->endpointRemoved(listener->handle, endpoint, (char*)scope);
- }
- }
-
- filter_destroy(filter);
- }
- }
- hashMapIterator_destroy(iter);
- }
-
- status = celixThreadMutex_unlock(&discovery->listenerReferencesMutex);
- }
-
- return status;
-}
-
-celix_status_t discovery_addDiscoveredEndpoint(discovery_pt discovery, endpoint_description_pt endpoint) {
- celix_status_t status;
-
- status = celixThreadMutex_lock(&discovery->discoveredServicesMutex);
-
- if (status == CELIX_SUCCESS) {
- char *endpointId = endpoint->id;
- bool exists = hashMap_get(discovery->discoveredServices, endpointId) != NULL;
- if (!exists) {
- hashMap_put(discovery->discoveredServices, endpointId, endpoint);
- }
-
- status = celixThreadMutex_unlock(&discovery->discoveredServicesMutex);
-
- if (!exists) {
- // notify our listeners that a new endpoint is available...
- discovery_informEndpointListeners(discovery, endpoint, true /* addingService */);
- }
- }
-
- return status;
-}
-
-celix_status_t discovery_removeDiscoveredEndpoint(discovery_pt discovery, endpoint_description_pt endpoint) {
- celix_status_t status;
-
- status = celixThreadMutex_lock(&discovery->discoveredServicesMutex);
-
- if (status == CELIX_SUCCESS) {
- char *endpointId = endpoint->id;
- void *oldValue = hashMap_remove(discovery->discoveredServices, endpointId);
-
- status = celixThreadMutex_unlock(&discovery->discoveredServicesMutex);
-
- if (oldValue) {
- status = discovery_informEndpointListeners(discovery, endpoint, false /* removeService */);
- }
- }
-
- return status;
-}
[14/19] celix git commit: CELIX-417: Refactor for CMake usage in RSA,
PSA and Docker. mostly trying to identify the api and common libraries
Posted by pn...@apache.org.
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/discovery/private/src/discovery_activator.c
----------------------------------------------------------------------
diff --git a/remote_services/discovery/private/src/discovery_activator.c b/remote_services/discovery/private/src/discovery_activator.c
deleted file mode 100644
index 3267d25..0000000
--- a/remote_services/discovery/private/src/discovery_activator.c
+++ /dev/null
@@ -1,186 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-/*
- * discovery_activator.c
- *
- * \date Aug 8, 2014
- * \author <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- * \copyright Apache License, Version 2.0
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-
-#include "bundle_activator.h"
-#include "service_tracker.h"
-#include "constants.h"
-
-#include "log_helper.h"
-#include "discovery.h"
-#include "remote_constants.h"
-
-struct activator {
- bundle_context_pt context;
- discovery_pt discovery;
- log_helper_pt loghelper;
-
- service_tracker_pt endpointListenerTracker;
- endpoint_listener_pt endpointListener;
- service_registration_pt endpointListenerService;
-};
-
-celix_status_t bundleActivator_createEPLTracker(struct activator *activator, service_tracker_pt *tracker) {
- celix_status_t status;
-
- service_tracker_customizer_pt customizer = NULL;
-
- status = serviceTrackerCustomizer_create(activator->discovery, discovery_endpointListenerAdding, discovery_endpointListenerAdded, discovery_endpointListenerModified,
- discovery_endpointListenerRemoved, &customizer);
-
- if (status == CELIX_SUCCESS) {
- status = serviceTracker_create(activator->context, (char *) OSGI_ENDPOINT_LISTENER_SERVICE, customizer, tracker);
- }
-
- return status;
-}
-
-celix_status_t bundleActivator_create(bundle_context_pt context, void **userData) {
- celix_status_t status;
-
- struct activator* activator = calloc(1,sizeof(struct activator));
- if (!activator) {
- return CELIX_ENOMEM;
- }
-
- status = discovery_create(context, &activator->discovery);
- if (status == CELIX_SUCCESS) {
- activator->context = context;
-
- logHelper_create(context, &activator->loghelper);
-
- status = bundleActivator_createEPLTracker(activator, &activator->endpointListenerTracker);
- if(status==CELIX_SUCCESS){
- *userData = activator;
- }
- else{
- bundleActivator_destroy(activator,context);
- }
- }
- else{
- free(activator);
- }
-
- return status;
-}
-
-celix_status_t bundleActivator_start(void * userData, bundle_context_pt context) {
- celix_status_t status;
- struct activator *activator = userData;
- const char *uuid = NULL;
-
- logHelper_start(activator->loghelper);
-
- status = bundleContext_getProperty(context, OSGI_FRAMEWORK_FRAMEWORK_UUID, &uuid);
- if (!uuid) {
- logHelper_log(activator->loghelper, OSGI_LOGSERVICE_DEBUG, "no framework UUID defined?!");
- return CELIX_ILLEGAL_STATE;
- }
-
- size_t len = 11 + strlen(OSGI_FRAMEWORK_OBJECTCLASS) + strlen(OSGI_RSA_ENDPOINT_FRAMEWORK_UUID) + strlen(uuid);
- char *scope = malloc(len + 1);
- if (!scope) {
- return CELIX_ENOMEM;
- }
-
- sprintf(scope, "(&(%s=*)(%s=%s))", OSGI_FRAMEWORK_OBJECTCLASS, OSGI_RSA_ENDPOINT_FRAMEWORK_UUID, uuid);
- scope[len] = 0;
-
- logHelper_log(activator->loghelper, OSGI_LOGSERVICE_DEBUG, "using scope %s.", scope);
-
- properties_pt props = properties_create();
- properties_set(props, "DISCOVERY", "true");
- properties_set(props, (char *) OSGI_ENDPOINT_LISTENER_SCOPE, scope);
-
- if (status == CELIX_SUCCESS) {
- status = serviceTracker_open(activator->endpointListenerTracker);
- }
-
- if (status == CELIX_SUCCESS) {
- status = discovery_start(activator->discovery);
- }
-
- if (status == CELIX_SUCCESS) {
- endpoint_listener_pt endpointListener = calloc(1, sizeof(struct endpoint_listener));
-
- if (endpointListener) {
- endpointListener->handle = activator->discovery;
- endpointListener->endpointAdded = discovery_endpointAdded;
- endpointListener->endpointRemoved = discovery_endpointRemoved;
-
- status = bundleContext_registerService(context, (char *) OSGI_ENDPOINT_LISTENER_SERVICE, endpointListener, props, &activator->endpointListenerService);
-
- if (status == CELIX_SUCCESS) {
- activator->endpointListener = endpointListener;
- }
- }
- }
- // We can release the scope, as properties_set makes a copy of the key & value...
- free(scope);
-
- return status;
-}
-
-celix_status_t bundleActivator_stop(void * userData, bundle_context_pt context) {
- celix_status_t status;
- struct activator *activator = userData;
-
- status = discovery_stop(activator->discovery);
-
- status = serviceTracker_close(activator->endpointListenerTracker);
-
- status = serviceRegistration_unregister(activator->endpointListenerService);
- free(activator->endpointListener);
-
- logHelper_stop(activator->loghelper);
-
- return status;
-}
-
-celix_status_t bundleActivator_destroy(void * userData, bundle_context_pt context) {
- celix_status_t status;
- struct activator *activator = userData;
-
- status = serviceTracker_destroy(activator->endpointListenerTracker);
-
- status = discovery_destroy(activator->discovery);
-
- logHelper_destroy(&activator->loghelper);
-
- activator->loghelper = NULL;
- activator->endpointListenerTracker = NULL;
- activator->endpointListenerService = NULL;
- activator->discovery = NULL;
- activator->context = NULL;
-
- free(activator);
-
- return status;
-}
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/discovery/private/src/endpoint_descriptor_reader.c
----------------------------------------------------------------------
diff --git a/remote_services/discovery/private/src/endpoint_descriptor_reader.c b/remote_services/discovery/private/src/endpoint_descriptor_reader.c
deleted file mode 100644
index ea176bf..0000000
--- a/remote_services/discovery/private/src/endpoint_descriptor_reader.c
+++ /dev/null
@@ -1,387 +0,0 @@
-/**
- *Licensed to the Apache Software Foundation (ASF) under one
- *or more contributor license agreements. See the NOTICE file
- *distributed with this work for additional information
- *regarding copyright ownership. The ASF licenses this file
- *to you under the Apache License, Version 2.0 (the
- *"License"); you may not use this file except in compliance
- *with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- *Unless required by applicable law or agreed to in writing,
- *software distributed under the License is distributed on an
- *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- *specific language governing permissions and limitations
- *under the License.
- */
-/*
- * endpoint_descriptor_reader.c
- *
- * \date 24 Jul 2014
- * \author <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- * \copyright Apache License, Version 2.0
- */
-
-#include <stdbool.h>
-#include <string.h>
-#include <libxml/xmlreader.h>
-
-#include "log_helper.h"
-#include "remote_constants.h"
-
-#include "endpoint_description.h"
-#include "endpoint_descriptor_common.h"
-#include "endpoint_descriptor_reader.h"
-
-struct endpoint_descriptor_reader {
- xmlTextReaderPtr reader;
- log_helper_pt* loghelper;
-};
-
-static valueType valueTypeFromString(char *name);
-
-celix_status_t endpointDescriptorReader_create(endpoint_discovery_poller_pt poller, endpoint_descriptor_reader_pt *reader) {
- celix_status_t status = CELIX_SUCCESS;
-
- *reader = malloc(sizeof(**reader));
- if (!*reader) {
- status = CELIX_ENOMEM;
- } else {
- (*reader)->reader = NULL;
- (*reader)->loghelper = poller->loghelper;
- }
-
- return status;
-}
-
-celix_status_t endpointDescriptorReader_destroy(endpoint_descriptor_reader_pt reader) {
- celix_status_t status = CELIX_SUCCESS;
-
- reader->loghelper = NULL;
-
- free(reader);
-
- return status;
-}
-
-void endpointDescriptorReader_addSingleValuedProperty(properties_pt properties, const xmlChar* name, const xmlChar* value) {
- properties_set(properties, (char *) name, (char*) value);
-}
-
-void endpointDescriptorReader_addMultiValuedProperty(properties_pt properties, const xmlChar* name, array_list_pt values) {
- char *value = calloc(256, sizeof(*value));
- if (value) {
- unsigned int size = arrayList_size(values);
- unsigned int i;
- for (i = 0; i < size; i++) {
- char* item = (char*) arrayList_get(values, i);
- if (i > 0) {
- value = strcat(value, ",");
- }
- value = strcat(value, item);
- }
-
- properties_set(properties, (char *) name, value);
-
- free(value);
- }
-}
-
-celix_status_t endpointDescriptorReader_parseDocument(endpoint_descriptor_reader_pt reader, char *document, array_list_pt *endpoints) {
- celix_status_t status = CELIX_SUCCESS;
-
- reader->reader = xmlReaderForMemory(document, (int) strlen(document), NULL, "UTF-8", 0);
- if (reader->reader == NULL) {
- status = CELIX_BUNDLE_EXCEPTION;
- } else {
- bool inProperty = false;
- bool inXml = false;
- bool inArray = false;
- bool inList = false;
- bool inSet = false;
- bool inValue = false;
-
- const xmlChar *propertyName = NULL;
- const xmlChar *propertyValue = NULL;
- valueType propertyType = VALUE_TYPE_STRING;
- xmlChar *valueBuffer = xmlMalloc(256);
- valueBuffer[0] = '\0';
-
- array_list_pt propertyValues = NULL;
- arrayList_create(&propertyValues);
-
- array_list_pt endpointDescriptions = NULL;
- if (*endpoints) {
- // use the given arraylist...
- endpointDescriptions = *endpoints;
- } else {
- arrayList_create(&endpointDescriptions);
- // return the read endpoints...
- *endpoints = endpointDescriptions;
- }
-
- properties_pt endpointProperties = NULL;
-
- int read = xmlTextReaderRead(reader->reader);
- while (read == XML_TEXTREADER_MODE_INTERACTIVE) {
- int type = xmlTextReaderNodeType(reader->reader);
-
- if (type == XML_READER_TYPE_ELEMENT) {
- const xmlChar *localname = xmlTextReaderConstLocalName(reader->reader);
-
- if (inXml) {
- valueBuffer = xmlStrcat(valueBuffer, BAD_CAST "<");
- valueBuffer = xmlStrcat(valueBuffer, localname);
-
- int i = xmlTextReaderMoveToFirstAttribute(reader->reader);
- while (i == 1) {
- const xmlChar *name = xmlTextReaderConstName(reader->reader);
- const xmlChar *value = xmlTextReaderConstValue(reader->reader);
-
- valueBuffer = xmlStrcat(valueBuffer, BAD_CAST " ");
- valueBuffer = xmlStrcat(valueBuffer, name);
- valueBuffer = xmlStrcat(valueBuffer, BAD_CAST "=\"");
- valueBuffer = xmlStrcat(valueBuffer, BAD_CAST value);
- valueBuffer = xmlStrcat(valueBuffer, BAD_CAST "\"");
-
- i = xmlTextReaderMoveToNextAttribute(reader->reader);
- }
-
- valueBuffer = xmlStrcat(valueBuffer, BAD_CAST ">");
- } else if (xmlStrcmp(localname, ENDPOINT_DESCRIPTION) == 0) {
-
- if (endpointProperties != NULL)
- properties_destroy(endpointProperties);
-
- endpointProperties = properties_create();
- } else if (xmlStrcmp(localname, PROPERTY) == 0) {
- inProperty = true;
-
- propertyName = xmlTextReaderGetAttribute(reader->reader, NAME);
- propertyValue = xmlTextReaderGetAttribute(reader->reader, VALUE);
- xmlChar *vtype = xmlTextReaderGetAttribute(reader->reader, VALUE_TYPE);
- propertyType = valueTypeFromString((char*) vtype);
- arrayList_clear(propertyValues);
-
- if (xmlTextReaderIsEmptyElement(reader->reader)) {
- inProperty = false;
-
- if (propertyValue != NULL) {
- endpointDescriptorReader_addSingleValuedProperty(endpointProperties, propertyName, propertyValue);
- }
-
- xmlFree((void *) propertyName);
- xmlFree((void *) propertyValue);
- xmlFree((void *) vtype);
- }
- } else {
- valueBuffer[0] = 0;
- inArray |= inProperty && xmlStrcmp(localname, ARRAY) == 0;
- inList |= inProperty && xmlStrcmp(localname, LIST) == 0;
- inSet |= inProperty && xmlStrcmp(localname, SET) == 0;
- inXml |= inProperty && xmlStrcmp(localname, XML) == 0;
- inValue |= inProperty && xmlStrcmp(localname, VALUE) == 0;
- }
- } else if (type == XML_READER_TYPE_END_ELEMENT) {
- const xmlChar *localname = xmlTextReaderConstLocalName(reader->reader);
-
- if (inXml) {
- if (xmlStrcmp(localname, XML) != 0) {
- valueBuffer = xmlStrcat(valueBuffer, BAD_CAST "</");
- valueBuffer = xmlStrcat(valueBuffer, localname);
- valueBuffer = xmlStrcat(valueBuffer, BAD_CAST ">");
- }
- else {
- inXml = false;
- }
- } else if (xmlStrcmp(localname, ENDPOINT_DESCRIPTION) == 0) {
- endpoint_description_pt endpointDescription = NULL;
- // Completely parsed endpoint description, add it to our list of results...
- if(endpointDescription_create(endpointProperties, &endpointDescription) == CELIX_SUCCESS){
- arrayList_add(endpointDescriptions, endpointDescription);
- }
-
- endpointProperties = properties_create();
- } else if (xmlStrcmp(localname, PROPERTY) == 0) {
- inProperty = false;
-
- if (inArray || inList || inSet) {
- endpointDescriptorReader_addMultiValuedProperty(endpointProperties, propertyName, propertyValues);
- }
- else if (propertyValue != NULL) {
- if (propertyType != VALUE_TYPE_STRING) {
- logHelper_log(*reader->loghelper, OSGI_LOGSERVICE_WARNING, "ENDPOINT_DESCRIPTOR_READER: Only string support for %s\n", propertyName);
- }
- endpointDescriptorReader_addSingleValuedProperty(endpointProperties, propertyName, propertyValue);
-
- xmlFree((void *) propertyValue);
- }
- else {
- endpointDescriptorReader_addSingleValuedProperty(endpointProperties, propertyName, valueBuffer);
- }
-
- xmlFree((void *) propertyName);
- unsigned int k=0;
- for(;k<arrayList_size(propertyValues);k++){
- free(arrayList_get(propertyValues,k));
- }
- arrayList_clear(propertyValues);
-
- propertyType = VALUE_TYPE_STRING;
- inArray = false;
- inList = false;
- inSet = false;
- inXml = false;
- } else if (xmlStrcmp(localname, VALUE) == 0) {
- arrayList_add(propertyValues, strdup((char*) valueBuffer));
- valueBuffer[0] = 0;
- inValue = false;
- }
- } else if (type == XML_READER_TYPE_TEXT) {
- if (inValue || inXml) {
- const xmlChar *value = xmlTextReaderValue(reader->reader);
- valueBuffer = xmlStrcat(valueBuffer, value);
- xmlFree((void *)value);
- }
- }
-
- read = xmlTextReaderRead(reader->reader);
- }
-
- if(endpointProperties!=NULL){
- properties_destroy(endpointProperties);
- }
-
- unsigned int k=0;
- for(;k<arrayList_size(propertyValues);k++){
- free(arrayList_get(propertyValues,k));
- }
- arrayList_destroy(propertyValues);
- xmlFree(valueBuffer);
-
- xmlFreeTextReader(reader->reader);
- }
-
- return status;
-}
-
-static valueType valueTypeFromString(char *name) {
- if (name == NULL || strcmp(name, "") == 0 || strcmp(name, "String") == 0) {
- return VALUE_TYPE_STRING;
- } else if (strcmp(name, "long") == 0 || strcmp(name, "Long") == 0) {
- return VALUE_TYPE_LONG;
- } else if (strcmp(name, "double") == 0 || strcmp(name, "Double") == 0) {
- return VALUE_TYPE_DOUBLE;
- } else if (strcmp(name, "float") == 0 || strcmp(name, "Float") == 0) {
- return VALUE_TYPE_FLOAT;
- } else if (strcmp(name, "int") == 0 || strcmp(name, "integer") == 0 || strcmp(name, "Integer") == 0) {
- return VALUE_TYPE_INTEGER;
- } else if (strcmp(name, "short") == 0 || strcmp(name, "Short") == 0) {
- return VALUE_TYPE_SHORT;
- } else if (strcmp(name, "byte") == 0 || strcmp(name, "Byte") == 0) {
- return VALUE_TYPE_BYTE;
- } else if (strcmp(name, "char") == 0 || strcmp(name, "Character") == 0) {
- return VALUE_TYPE_CHAR;
- } else if (strcmp(name, "boolean") == 0 || strcmp(name, "Boolean") == 0) {
- return VALUE_TYPE_BOOLEAN;
- } else {
- return VALUE_TYPE_STRING;
- }
-}
-
-#ifdef RSA_ENDPOINT_TEST_READER
-int main() {
- array_list_pt list = NULL;
- endpoint_descriptor_reader_pt reader = NULL;
-
- char *doc = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
-"<endpoint-descriptions xmlns=\"http://www.osgi.org/xmlns/rsa/v1.0.0\">"
- "<endpoint-description>"
- "<property name=\"endpoint.service.id\" value-type=\"long\" value=\"6\"/>"
- "<property name=\"endpoint.framework.uuid\" value=\"2983D849-93B1-4C2C-AC6D-5BCDA93ACB96\"/>"
- "<property name=\"service.intents\">"
- "<list>"
- "<value>SOAP</value>"
- "<value>HTTP</value>"
- "</list>"
- "</property>"
- "<property name=\"endpoint.id\" value=\"11111111-1111-1111-1111-111111111111\" />"
- "<property name=\"objectClass\"><array><value>com.acme.Foo</value></array></property>"
- "<property name=\"endpoint.package.version.com.acme\" value=\"4.2\" />"
- "<property name=\"service.imported.configs\" value=\"com.acme\" />"
- "<property name=\"service.imported\" value=\"true\"/>"
- "<property name=\"com.acme.ws.xml\">"
- "<xml>"
- "<config xmlns=\"http://acme.com/defs\">"
- "<port>1029</port>"
- "<host>www.acme.com</host>"
- "</config>"
- "</xml>"
- "</property>"
- "</endpoint-description>"
- "<endpoint-description>"
- "<property name=\"endpoint.service.id\" value-type=\"long\" value=\"5\"/>"
- "<property name=\"endpoint.framework.uuid\" value=\"2983D849-93B1-4C2C-AC6D-5BCDA93ACB96\"/>"
- "<property name=\"service.intents\">"
- "<list>"
- "<value>SOAP</value>"
- "<value>HTTP</value>"
- "</list>"
- "</property>"
- "<property name=\"endpoint.id\" value=\"22222222-2222-2222-2222-222222222222\" />"
- "<property name=\"objectClass\"><array><value>com.acme.Bar</value></array></property>"
- "<property name=\"endpoint.package.version.com.acme\" value=\"4.2\" />"
- "<property name=\"service.imported.configs\" value=\"com.acme\" />"
- "<property name=\"com.acme.ws.xml\">"
- "<xml>"
- "<config xmlns=\"http://acme.com/defs\">"
- "<port>1029</port>"
- "<host>www.acme.com</host>"
- "</config>"
- "</xml>"
- "</property>"
- "</endpoint-description>"
- "</endpoint-descriptions>";
-
- endpointDescriptorReader_create(&reader);
-
- endpointDescriptorReader_parseDocument(reader, doc, &list);
-
- int i;
- for (i = 0; i < arrayList_size(list); i++) {
- printf("\nEndpoint description #%d:\n", (i+1));
- endpoint_description_pt edp = arrayList_get(list, i);
- printf("Id: %s\n", edp->id);
- printf("Service Id: %lu\n", edp->serviceId);
- printf("Framework UUID: %s\n", edp->frameworkUUID);
- printf("Service: %s\n", edp->service);
-
- properties_pt props = edp->properties;
- if (props) {
- printf("Service properties:\n");
- hash_map_iterator_pt iter = hashMapIterator_create(props);
- while (hashMapIterator_hasNext(iter)) {
- hash_map_entry_pt entry = hashMapIterator_nextEntry(iter);
-
- printf("- %s => '%s'\n", hashMapEntry_getKey(entry), hashMapEntry_getValue(entry));
- }
- hashMapIterator_destroy(iter);
- } else {
- printf("No service properties...\n");
- }
-
-
- endpointDescription_destroy(edp);
- }
-
- if (list != NULL) {
- arrayList_destroy(list);
- }
-
- endpointDescriptorReader_destroy(reader);
-
- return 0;
-}
-#endif
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/discovery/private/src/endpoint_descriptor_writer.c
----------------------------------------------------------------------
diff --git a/remote_services/discovery/private/src/endpoint_descriptor_writer.c b/remote_services/discovery/private/src/endpoint_descriptor_writer.c
deleted file mode 100644
index 71b07b4..0000000
--- a/remote_services/discovery/private/src/endpoint_descriptor_writer.c
+++ /dev/null
@@ -1,233 +0,0 @@
-/**
- *Licensed to the Apache Software Foundation (ASF) under one
- *or more contributor license agreements. See the NOTICE file
- *distributed with this work for additional information
- *regarding copyright ownership. The ASF licenses this file
- *to you under the Apache License, Version 2.0 (the
- *"License"); you may not use this file except in compliance
- *with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- *Unless required by applicable law or agreed to in writing,
- *software distributed under the License is distributed on an
- *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- *specific language governing permissions and limitations
- *under the License.
- */
-/*
- * endpoint_descriptor_writer.c
- *
- * \date 26 Jul 2014
- * \author <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- * \copyright Apache License, Version 2.0
- */
-#include <stdlib.h>
-#include <string.h>
-#include <libxml/xmlwriter.h>
-
-#include "constants.h"
-#include "remote_constants.h"
-
-#include "endpoint_description.h"
-#include "endpoint_descriptor_common.h"
-#include "endpoint_descriptor_writer.h"
-
-struct endpoint_descriptor_writer {
- xmlBufferPtr buffer;
- xmlTextWriterPtr writer;
-};
-
-static celix_status_t endpointDescriptorWriter_writeEndpoint(endpoint_descriptor_writer_pt writer, endpoint_description_pt endpoint);
-
-static char* valueTypeToString(valueType type);
-
-celix_status_t endpointDescriptorWriter_create(endpoint_descriptor_writer_pt *writer) {
- celix_status_t status = CELIX_SUCCESS;
-
- *writer = malloc(sizeof(**writer));
- if (!*writer) {
- status = CELIX_ENOMEM;
- } else {
- (*writer)->buffer = xmlBufferCreate();
- if ((*writer)->buffer == NULL) {
- status = CELIX_BUNDLE_EXCEPTION;
- } else {
- (*writer)->writer = xmlNewTextWriterMemory((*writer)->buffer, 0);
- if ((*writer)->writer == NULL) {
- status = CELIX_BUNDLE_EXCEPTION;
- }
- }
- }
-
- return status;
-}
-
-celix_status_t endpointDescriptorWriter_destroy(endpoint_descriptor_writer_pt writer) {
- xmlFreeTextWriter(writer->writer);
- xmlBufferFree(writer->buffer);
- free(writer);
- return CELIX_SUCCESS;
-}
-
-celix_status_t endpointDescriptorWriter_writeDocument(endpoint_descriptor_writer_pt writer, array_list_pt endpoints, char **document) {
- celix_status_t status = CELIX_SUCCESS;
- int rc;
-
- rc = xmlTextWriterStartDocument(writer->writer, NULL, "UTF-8", NULL);
- if (rc < 0) {
- status = CELIX_BUNDLE_EXCEPTION;
- } else {
- rc = xmlTextWriterStartElementNS(writer->writer, NULL, ENDPOINT_DESCRIPTIONS, XMLNS);
- if (rc < 0) {
- status = CELIX_BUNDLE_EXCEPTION;
- } else {
- unsigned int i;
- for (i = 0; i < arrayList_size(endpoints); i++) {
- endpoint_description_pt endpoint = arrayList_get(endpoints, i);
- status = endpointDescriptorWriter_writeEndpoint(writer, endpoint);
- }
- if (status == CELIX_SUCCESS) {
- rc = xmlTextWriterEndElement(writer->writer);
- if (rc < 0) {
- status = CELIX_BUNDLE_EXCEPTION;
- } else {
- rc = xmlTextWriterEndDocument(writer->writer);
- if (rc < 0) {
- status = CELIX_BUNDLE_EXCEPTION;
- } else {
- *document = (char *) writer->buffer->content;
- }
- }
- }
- }
- }
-
- return status;
-}
-
-static celix_status_t endpointDescriptorWriter_writeArrayValue(xmlTextWriterPtr writer, const xmlChar* value) {
- xmlTextWriterStartElement(writer, ARRAY);
- xmlTextWriterStartElement(writer, VALUE);
- xmlTextWriterWriteString(writer, value);
- xmlTextWriterEndElement(writer); // value
- xmlTextWriterEndElement(writer); // array
-
- return CELIX_SUCCESS;
-}
-
-static celix_status_t endpointDescriptorWriter_writeTypedValue(xmlTextWriterPtr writer, valueType type, const xmlChar* value) {
- xmlTextWriterWriteAttribute(writer, VALUE_TYPE, (const xmlChar*) valueTypeToString(type));
- xmlTextWriterWriteAttribute(writer, VALUE, value);
-
- return CELIX_SUCCESS;
-}
-
-static celix_status_t endpointDescriptorWriter_writeUntypedValue(xmlTextWriterPtr writer, const xmlChar* value) {
- xmlTextWriterWriteAttribute(writer, VALUE, value);
-
- return CELIX_SUCCESS;
-}
-
-static celix_status_t endpointDescriptorWriter_writeEndpoint(endpoint_descriptor_writer_pt writer, endpoint_description_pt endpoint) {
- celix_status_t status = CELIX_SUCCESS;
-
- if (endpoint == NULL || writer == NULL) {
- status = CELIX_ILLEGAL_ARGUMENT;
- } else {
- xmlTextWriterStartElement(writer->writer, ENDPOINT_DESCRIPTION);
-
- hash_map_iterator_pt iter = hashMapIterator_create(endpoint->properties);
- while (hashMapIterator_hasNext(iter)) {
- hash_map_entry_pt entry = hashMapIterator_nextEntry(iter);
-
- void* propertyName = hashMapEntry_getKey(entry);
- const xmlChar* propertyValue = (const xmlChar*) hashMapEntry_getValue(entry);
-
- xmlTextWriterStartElement(writer->writer, PROPERTY);
- xmlTextWriterWriteAttribute(writer->writer, NAME, propertyName);
-
- if (strcmp(OSGI_FRAMEWORK_OBJECTCLASS, (char*) propertyName) == 0) {
- // objectClass *must* be represented as array of string values...
- endpointDescriptorWriter_writeArrayValue(writer->writer, propertyValue);
- } else if (strcmp(OSGI_RSA_ENDPOINT_SERVICE_ID, (char*) propertyName) == 0) {
- // endpoint.service.id *must* be represented as long value...
- endpointDescriptorWriter_writeTypedValue(writer->writer, VALUE_TYPE_LONG, propertyValue);
- } else {
- // represent all other values as plain string values...
- endpointDescriptorWriter_writeUntypedValue(writer->writer, propertyValue);
- }
-
- xmlTextWriterEndElement(writer->writer);
- }
- hashMapIterator_destroy(iter);
-
- xmlTextWriterEndElement(writer->writer);
- }
-
- return status;
-}
-
-
-static char* valueTypeToString(valueType type) {
- switch (type) {
- case VALUE_TYPE_BOOLEAN:
- return "boolean";
- case VALUE_TYPE_BYTE:
- return "byte";
- case VALUE_TYPE_CHAR:
- return "char";
- case VALUE_TYPE_DOUBLE:
- return "double";
- case VALUE_TYPE_FLOAT:
- return "float";
- case VALUE_TYPE_INTEGER:
- return "int";
- case VALUE_TYPE_LONG:
- return "long";
- case VALUE_TYPE_SHORT:
- return "short";
- case VALUE_TYPE_STRING:
- // FALL-THROUGH!
- default:
- return "string";
- }
-}
-
-#ifdef RSA_ENDPOINT_TEST_WRITER
-int main() {
- endpoint_descriptor_writer_pt writer = NULL;
- endpointDescriptorWriter_create(&writer);
- array_list_pt list = NULL;
- arrayList_create(&list);
-
- properties_pt props = properties_create();
- properties_set(props, "objectClass", "com.acme.Foo");
- properties_set(props, "endpoint.service.id", "3");
- properties_set(props, "endpoint.id", "abcdefghijklmnopqrstuvwxyz");
- properties_set(props, "endpoint.framework.uuid", "2983D849-93B1-4C2C-AC6D-5BCDA93ACB96");
- endpoint_description_pt epd = NULL;
- endpointDescription_create(props, &epd);
- arrayList_add(list, epd);
-
- properties_pt props2 = properties_create();
- properties_set(props2, "objectClass", "com.acme.Bar");
- properties_set(props, "endpoint.service.id", "4");
- properties_set(props, "endpoint.id", "abcdefghijklmnopqrstuvwxyz");
- properties_set(props, "endpoint.framework.uuid", "2983D849-93B1-4C2C-AC6D-5BCDA93ACB96");
- endpoint_description_pt epd2 = NULL;
- endpointDescription_create(props2, &epd2);
- arrayList_add(list, epd2);
-
- char *buffer = NULL;
- endpointDescriptorWriter_writeDocument(writer, list, &buffer);
-
- arrayList_destroy(list);
- endpointDescription_destroy(epd);
- endpointDescription_destroy(epd2);
- endpointDescriptorWriter_destroy(writer);
-
- printf("%s\n", buffer);
-}
-#endif
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/discovery/private/src/endpoint_discovery_poller.c
----------------------------------------------------------------------
diff --git a/remote_services/discovery/private/src/endpoint_discovery_poller.c b/remote_services/discovery/private/src/endpoint_discovery_poller.c
deleted file mode 100644
index 73fb7ba..0000000
--- a/remote_services/discovery/private/src/endpoint_discovery_poller.c
+++ /dev/null
@@ -1,403 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-/*
- * endpoint_discovery_poller.c
- *
- * \date 3 Jul 2014
- * \author <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- * \copyright Apache License, Version 2.0
- */
-#include <stdbool.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-
-#include <curl/curl.h>
-
-#include "bundle_context.h"
-#include "log_helper.h"
-#include "utils.h"
-
-#include "discovery_impl.h"
-
-#include "endpoint_descriptor_reader.h"
-
-
-#define DISCOVERY_POLL_INTERVAL "DISCOVERY_CFG_POLL_INTERVAL"
-#define DEFAULT_POLL_INTERVAL "10"
-
-
-static void *endpointDiscoveryPoller_performPeriodicPoll(void *data);
-celix_status_t endpointDiscoveryPoller_poll(endpoint_discovery_poller_pt poller, char *url, array_list_pt currentEndpoints);
-static celix_status_t endpointDiscoveryPoller_getEndpoints(endpoint_discovery_poller_pt poller, char *url, array_list_pt *updatedEndpoints);
-static celix_status_t endpointDiscoveryPoller_endpointDescriptionEquals(const void *endpointPtr, const void *comparePtr, bool *equals);
-
-/**
- * Allocates memory and initializes a new endpoint_discovery_poller instance.
- */
-celix_status_t endpointDiscoveryPoller_create(discovery_pt discovery, bundle_context_pt context, endpoint_discovery_poller_pt *poller) {
- celix_status_t status;
-
- *poller = malloc(sizeof(struct endpoint_discovery_poller));
- if (!*poller) {
- return CELIX_ENOMEM;
- }
-
- (*poller)->loghelper = &discovery->loghelper;
-
- status = celixThreadMutex_create(&(*poller)->pollerLock, NULL);
- if (status != CELIX_SUCCESS) {
- return status;
- }
-
- const char* interval = NULL;
- status = bundleContext_getProperty(context, DISCOVERY_POLL_INTERVAL, &interval);
- if (!interval) {
- interval = DEFAULT_POLL_INTERVAL;
- }
-
- const char* endpointsProp = NULL;
- status = bundleContext_getProperty(context, DISCOVERY_POLL_ENDPOINTS, &endpointsProp);
- if (!endpointsProp) {
- endpointsProp = DEFAULT_POLL_ENDPOINTS;
- }
- // we're going to mutate the string with strtok, so create a copy...
- char* endpoints = strdup(endpointsProp);
-
- (*poller)->poll_interval = atoi(interval);
- (*poller)->discovery = discovery;
- (*poller)->running = false;
- (*poller)->entries = hashMap_create(utils_stringHash, NULL, utils_stringEquals, NULL);
-
- const char* sep = ",";
- char *save_ptr = NULL;
- char* tok = strtok_r(endpoints, sep, &save_ptr);
- while (tok) {
- endpointDiscoveryPoller_addDiscoveryEndpoint(*poller, utils_stringTrim(tok));
- tok = strtok_r(NULL, sep, &save_ptr);
- }
- // Clean up after ourselves...
- free(endpoints);
-
- status = celixThreadMutex_lock(&(*poller)->pollerLock);
- if (status != CELIX_SUCCESS) {
- return CELIX_BUNDLE_EXCEPTION;
- }
-
- (*poller)->running = true;
-
- status += celixThread_create(&(*poller)->pollerThread, NULL, endpointDiscoveryPoller_performPeriodicPoll, *poller);
- status += celixThreadMutex_unlock(&(*poller)->pollerLock);
-
- if(status != CELIX_SUCCESS){
- status = CELIX_BUNDLE_EXCEPTION;
- }
-
- return status;
-}
-
-/**
- * Destroys and frees up memory for a given endpoint_discovery_poller struct.
- */
-celix_status_t endpointDiscoveryPoller_destroy(endpoint_discovery_poller_pt poller) {
- celix_status_t status;
-
- poller->running = false;
-
- celixThread_join(poller->pollerThread, NULL);
-
- hash_map_iterator_pt iterator = hashMapIterator_create(poller->entries);
- while (hashMapIterator_hasNext(iterator)) {
- hash_map_entry_pt entry = hashMapIterator_nextEntry(iterator);
-
- if ( endpointDiscoveryPoller_removeDiscoveryEndpoint(poller, (char*) hashMapEntry_getKey(entry)) == CELIX_SUCCESS) {
- hashMapIterator_destroy(iterator);
- iterator = hashMapIterator_create(poller->entries);
- }
- }
- hashMapIterator_destroy(iterator);
-
- status = celixThreadMutex_lock(&poller->pollerLock);
-
- if (status != CELIX_SUCCESS) {
- return CELIX_BUNDLE_EXCEPTION;
- }
-
- hashMap_destroy(poller->entries, true, false);
-
- status = celixThreadMutex_unlock(&poller->pollerLock);
-
- poller->loghelper = NULL;
-
- free(poller);
-
- return status;
-}
-
-
-celix_status_t endpointDiscoveryPoller_getDiscoveryEndpoints(endpoint_discovery_poller_pt poller, array_list_pt urls) {
- celixThreadMutex_lock(&(poller)->pollerLock);
-
- hash_map_iterator_pt iterator = hashMapIterator_create(poller->entries);
-
- while(hashMapIterator_hasNext(iterator)) {
- hash_map_entry_pt entry = hashMapIterator_nextEntry(iterator);
- char* toAdd = strdup((char*) hashMapEntry_getKey(entry));
- arrayList_add(urls, toAdd);
- }
-
- hashMapIterator_destroy(iterator);
-
- celixThreadMutex_unlock(&(poller)->pollerLock);
-
- return CELIX_SUCCESS;
-}
-
-/**
- * Adds a new endpoint URL to the list of polled endpoints.
- */
-celix_status_t endpointDiscoveryPoller_addDiscoveryEndpoint(endpoint_discovery_poller_pt poller, char *url) {
- celix_status_t status;
-
- status = celixThreadMutex_lock(&(poller)->pollerLock);
- if (status != CELIX_SUCCESS) {
- return CELIX_BUNDLE_EXCEPTION;
- }
-
- // Avoid memory leaks when adding an already existing URL...
- array_list_pt endpoints = hashMap_get(poller->entries, url);
- if (endpoints == NULL) {
- status = arrayList_createWithEquals(endpointDiscoveryPoller_endpointDescriptionEquals, &endpoints);
-
- if (status == CELIX_SUCCESS) {
- logHelper_log(*poller->loghelper, OSGI_LOGSERVICE_DEBUG, "ENDPOINT_POLLER: add new discovery endpoint with url %s", url);
- hashMap_put(poller->entries, strdup(url), endpoints);
- endpointDiscoveryPoller_poll(poller, url, endpoints);
- }
- }
-
- status = celixThreadMutex_unlock(&poller->pollerLock);
-
- return status;
-}
-
-/**
- * Removes an endpoint URL from the list of polled endpoints.
- */
-celix_status_t endpointDiscoveryPoller_removeDiscoveryEndpoint(endpoint_discovery_poller_pt poller, char *url) {
- celix_status_t status = CELIX_SUCCESS;
-
- if (celixThreadMutex_lock(&poller->pollerLock) != CELIX_SUCCESS) {
- status = CELIX_BUNDLE_EXCEPTION;
- } else {
- hash_map_entry_pt entry = hashMap_getEntry(poller->entries, url);
-
- if (entry == NULL) {
- logHelper_log(*poller->loghelper, OSGI_LOGSERVICE_DEBUG, "ENDPOINT_POLLER: There was no entry found belonging to url %s - maybe already removed?", url);
- } else {
- char* origKey = hashMapEntry_getKey(entry);
-
- logHelper_log(*poller->loghelper, OSGI_LOGSERVICE_DEBUG, "ENDPOINT_POLLER: remove discovery endpoint with url %s", url);
-
- array_list_pt entries = hashMap_remove(poller->entries, url);
-
- if (entries != NULL) {
- for (unsigned int i = arrayList_size(entries); i > 0; i--) {
- endpoint_description_pt endpoint = arrayList_get(entries, i - 1);
- discovery_removeDiscoveredEndpoint(poller->discovery, endpoint);
- arrayList_remove(entries, i - 1);
- endpointDescription_destroy(endpoint);
- }
- arrayList_destroy(entries);
- }
-
- free(origKey);
- }
- status = celixThreadMutex_unlock(&poller->pollerLock);
- }
-
- return status;
-}
-
-
-
-
-celix_status_t endpointDiscoveryPoller_poll(endpoint_discovery_poller_pt poller, char *url, array_list_pt currentEndpoints) {
- celix_status_t status;
- array_list_pt updatedEndpoints = NULL;
-
- // create an arraylist with a custom equality test to ensure we can find endpoints properly...
- arrayList_createWithEquals(endpointDiscoveryPoller_endpointDescriptionEquals, &updatedEndpoints);
- status = endpointDiscoveryPoller_getEndpoints(poller, url, &updatedEndpoints);
-
- if (status == CELIX_SUCCESS) {
- if (updatedEndpoints!=NULL) {
- for (unsigned int i = arrayList_size(currentEndpoints); i > 0; i--) {
- endpoint_description_pt endpoint = arrayList_get(currentEndpoints, i - 1);
-
- if (!arrayList_contains(updatedEndpoints, endpoint)) {
- status = discovery_removeDiscoveredEndpoint(poller->discovery, endpoint);
- arrayList_remove(currentEndpoints, i - 1);
- endpointDescription_destroy(endpoint);
- }
- }
-
- for (int i = arrayList_size(updatedEndpoints); i > 0; i--) {
- endpoint_description_pt endpoint = arrayList_remove(updatedEndpoints, 0);
-
- if (!arrayList_contains(currentEndpoints, endpoint)) {
- arrayList_add(currentEndpoints, endpoint);
- status = discovery_addDiscoveredEndpoint(poller->discovery, endpoint);
- } else {
- endpointDescription_destroy(endpoint);
-
- }
- }
- }
- }
-
- if(updatedEndpoints!=NULL){
- arrayList_destroy(updatedEndpoints);
- }
-
- return status;
-}
-
-static void *endpointDiscoveryPoller_performPeriodicPoll(void *data) {
- endpoint_discovery_poller_pt poller = (endpoint_discovery_poller_pt) data;
-
- useconds_t interval = (useconds_t) (poller->poll_interval * 1000000L);
-
- while (poller->running) {
- usleep(interval);
- celix_status_t status = celixThreadMutex_lock(&poller->pollerLock);
-
- if (status != CELIX_SUCCESS) {
- logHelper_log(*poller->loghelper, OSGI_LOGSERVICE_WARNING, "ENDPOINT_POLLER: failed to obtain lock; retrying...");
- } else {
- hash_map_iterator_pt iterator = hashMapIterator_create(poller->entries);
-
- while (hashMapIterator_hasNext(iterator)) {
- hash_map_entry_pt entry = hashMapIterator_nextEntry(iterator);
-
- char *url = hashMapEntry_getKey(entry);
- array_list_pt currentEndpoints = hashMapEntry_getValue(entry);
-
- endpointDiscoveryPoller_poll(poller, url, currentEndpoints);
- }
-
- hashMapIterator_destroy(iterator);
- }
-
- status = celixThreadMutex_unlock(&poller->pollerLock);
- if (status != CELIX_SUCCESS) {
- logHelper_log(*poller->loghelper, OSGI_LOGSERVICE_WARNING, "ENDPOINT_POLLER: failed to release lock; retrying...");
- }
- }
-
- return NULL;
-}
-
-
-
-struct MemoryStruct {
- char *memory;
- size_t size;
-};
-
-static size_t endpointDiscoveryPoller_writeMemory(void *contents, size_t size, size_t nmemb, void *memoryPtr) {
- size_t realsize = size * nmemb;
- struct MemoryStruct *mem = (struct MemoryStruct *)memoryPtr;
-
- mem->memory = realloc(mem->memory, mem->size + realsize + 1);
- if(mem->memory == NULL) {
- printf("ENDPOINT_POLLER: not enough memory (realloc returned NULL)!");
- return 0;
- }
-
- memcpy(&(mem->memory[mem->size]), contents, realsize);
- mem->size += realsize;
- mem->memory[mem->size] = 0;
-
- return realsize;
-}
-
-static celix_status_t endpointDiscoveryPoller_getEndpoints(endpoint_discovery_poller_pt poller, char *url, array_list_pt *updatedEndpoints) {
- celix_status_t status = CELIX_SUCCESS;
-
-
- CURL *curl = NULL;
- CURLcode res = CURLE_OK;
-
- struct MemoryStruct chunk;
- chunk.memory = malloc(1);
- chunk.size = 0;
-
- curl = curl_easy_init();
- if (!curl) {
- status = CELIX_ILLEGAL_STATE;
- } else {
- curl_easy_setopt(curl, CURLOPT_URL, url);
- curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1);
- curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, endpointDiscoveryPoller_writeMemory);
- curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&chunk);
- curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 5L);
- curl_easy_setopt(curl, CURLOPT_TIMEOUT, 10L);
- res = curl_easy_perform(curl);
-
- curl_easy_cleanup(curl);
- }
-
- // process endpoints file
- if (res == CURLE_OK) {
- endpoint_descriptor_reader_pt reader = NULL;
-
- status = endpointDescriptorReader_create(poller, &reader);
- if (status == CELIX_SUCCESS) {
- status = endpointDescriptorReader_parseDocument(reader, chunk.memory, updatedEndpoints);
- }
-
- if (reader) {
- endpointDescriptorReader_destroy(reader);
- }
- } else {
- logHelper_log(*poller->loghelper, OSGI_LOGSERVICE_ERROR, "ENDPOINT_POLLER: unable to read endpoints from %s, reason: %s", url, curl_easy_strerror(res));
- }
-
- // clean up endpoints file
- if (chunk.memory) {
- free(chunk.memory);
- }
-
- return status;
-}
-
-static celix_status_t endpointDiscoveryPoller_endpointDescriptionEquals(const void *endpointPtr, const void *comparePtr, bool *equals) {
- endpoint_description_pt endpoint = (endpoint_description_pt) endpointPtr;
- endpoint_description_pt compare = (endpoint_description_pt) comparePtr;
-
- if (strcmp(endpoint->id, compare->id) == 0) {
- *equals = true;
- } else {
- *equals = false;
- }
-
- return CELIX_SUCCESS;
-}
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/discovery/private/src/endpoint_discovery_server.c
----------------------------------------------------------------------
diff --git a/remote_services/discovery/private/src/endpoint_discovery_server.c b/remote_services/discovery/private/src/endpoint_discovery_server.c
deleted file mode 100644
index f5f82af..0000000
--- a/remote_services/discovery/private/src/endpoint_discovery_server.c
+++ /dev/null
@@ -1,450 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-/*
- * endpoint_discovery_server.c
- *
- * \date Aug 12, 2014
- * \author <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- * \copyright Apache License, Version 2.0
- */
-#include <stdlib.h>
-#include <string.h>
-#include <arpa/inet.h>
-#include <netdb.h>
-#ifndef ANDROID
-#include <ifaddrs.h>
-#endif
-#include "civetweb.h"
-#include "celix_errno.h"
-#include "utils.h"
-#include "log_helper.h"
-#include "discovery.h"
-#include "discovery_impl.h"
-
-#include "endpoint_descriptor_writer.h"
-
-// defines how often the webserver is restarted (with an increased port number)
-#define MAX_NUMBER_OF_RESTARTS 15
-#define DEFAULT_SERVER_THREADS "1"
-
-#define CIVETWEB_REQUEST_NOT_HANDLED 0
-#define CIVETWEB_REQUEST_HANDLED 1
-
-static const char *response_headers =
- "HTTP/1.1 200 OK\r\n"
- "Cache: no-cache\r\n"
- "Content-Type: application/xml;charset=utf-8\r\n"
- "\r\n";
-
-struct endpoint_discovery_server {
- log_helper_pt* loghelper;
- hash_map_pt entries; // key = endpointId, value = endpoint_descriptor_pt
-
- celix_thread_mutex_t serverLock;
-
- const char* path;
- const char *port;
- const char* ip;
- struct mg_context* ctx;
-};
-
-// Forward declarations...
-static int endpointDiscoveryServer_callback(struct mg_connection *conn);
-static char* format_path(const char* path);
-
-#ifndef ANDROID
-static celix_status_t endpointDiscoveryServer_getIpAdress(char* interface, char** ip);
-#endif
-
-celix_status_t endpointDiscoveryServer_create(discovery_pt discovery, bundle_context_pt context, endpoint_discovery_server_pt *server) {
- celix_status_t status;
-
- const char *port = NULL;
- const char *ip = NULL;
- char *detectedIp = NULL;
- const char *path = NULL;
- const char *retries = NULL;
-
- int max_ep_num = MAX_NUMBER_OF_RESTARTS;
-
- *server = malloc(sizeof(struct endpoint_discovery_server));
- if (!*server) {
- return CELIX_ENOMEM;
- }
-
- (*server)->loghelper = &discovery->loghelper;
- (*server)->entries = hashMap_create(&utils_stringHash, NULL, &utils_stringEquals, NULL);
- if (!(*server)->entries) {
- return CELIX_ENOMEM;
- }
-
- status = celixThreadMutex_create(&(*server)->serverLock, NULL);
- if (status != CELIX_SUCCESS) {
- return CELIX_BUNDLE_EXCEPTION;
- }
-
- bundleContext_getProperty(context, DISCOVERY_SERVER_IP, &ip);
-#ifndef ANDROID
- if (ip == NULL) {
- const char *interface = NULL;
-
- bundleContext_getProperty(context, DISCOVERY_SERVER_INTERFACE, &interface);
- if ((interface != NULL) && (endpointDiscoveryServer_getIpAdress((char*)interface, &detectedIp) != CELIX_SUCCESS)) {
- logHelper_log(*(*server)->loghelper, OSGI_LOGSERVICE_WARNING, "Could not retrieve IP adress for interface %s", interface);
- }
-
- if (detectedIp == NULL) {
- endpointDiscoveryServer_getIpAdress(NULL, &detectedIp);
- }
-
- ip = detectedIp;
- }
-#endif
-
- if (ip != NULL) {
- logHelper_log(*(*server)->loghelper, OSGI_LOGSERVICE_INFO, "Using %s for service annunciation", ip);
- (*server)->ip = strdup(ip);
- }
- else {
- logHelper_log(*(*server)->loghelper, OSGI_LOGSERVICE_WARNING, "No IP address for service annunciation set. Using %s", DEFAULT_SERVER_IP);
- (*server)->ip = strdup((char*) DEFAULT_SERVER_IP);
- }
-
- if (detectedIp != NULL) {
- free(detectedIp);
- }
-
- bundleContext_getProperty(context, DISCOVERY_SERVER_PORT, &port);
- if (port == NULL) {
- port = DEFAULT_SERVER_PORT;
- }
-
- bundleContext_getProperty(context, DISCOVERY_SERVER_PATH, &path);
- if (path == NULL) {
- path = DEFAULT_SERVER_PATH;
- }
-
- bundleContext_getProperty(context, DISCOVERY_SERVER_MAX_EP, &retries);
- if (retries != NULL) {
- errno=0;
- max_ep_num = strtol(retries,NULL,10);
- if(errno!=0 || max_ep_num<=0){
- max_ep_num=MAX_NUMBER_OF_RESTARTS;
- }
- }
-
- (*server)->path = format_path(path);
-
- const struct mg_callbacks callbacks = {
- .begin_request = endpointDiscoveryServer_callback,
- };
-
- unsigned int port_counter = 0;
- char newPort[10];
-
- do {
- const char *options[] = {
- "listening_ports", port,
- "num_threads", DEFAULT_SERVER_THREADS,
- NULL
- };
-
- (*server)->ctx = mg_start(&callbacks, (*server), options);
-
- if ((*server)->ctx != NULL)
- {
- logHelper_log(discovery->loghelper, OSGI_LOGSERVICE_INFO, "Starting discovery server on port %s...", port);
- }
- else {
- errno = 0;
- char* endptr = (char*)port;
- long currentPort = strtol(port, &endptr, 10);
-
- if (*endptr || errno != 0) {
- currentPort = strtol(DEFAULT_SERVER_PORT, NULL, 10);
- }
-
- port_counter++;
- snprintf(&newPort[0], 10, "%ld", (currentPort+1));
-
- logHelper_log(discovery->loghelper, OSGI_LOGSERVICE_ERROR, "Error while starting discovery server on port %s - retrying on port %s...", port, newPort);
- port = newPort;
-
- }
-
- } while(((*server)->ctx == NULL) && (port_counter < max_ep_num));
-
- (*server)->port = strdup(port);
-
- return status;
-}
-
-celix_status_t endpointDiscoveryServer_getUrl(endpoint_discovery_server_pt server, char* url)
-{
- celix_status_t status = CELIX_BUNDLE_EXCEPTION;
-
- if (server->ip && server->port && server->path) {
- sprintf(url, "http://%s:%s/%s", server->ip, server->port, server->path);
- status = CELIX_SUCCESS;
- }
-
- return status;
-}
-
-celix_status_t endpointDiscoveryServer_destroy(endpoint_discovery_server_pt server) {
- celix_status_t status;
-
- // stop & block until the actual server is shut down...
- if (server->ctx != NULL) {
- mg_stop(server->ctx);
- server->ctx = NULL;
- }
-
- status = celixThreadMutex_lock(&server->serverLock);
-
- hashMap_destroy(server->entries, true /* freeKeys */, false /* freeValues */);
-
- status = celixThreadMutex_unlock(&server->serverLock);
- status = celixThreadMutex_destroy(&server->serverLock);
-
- free((void*) server->path);
- free((void*) server->port);
- free((void*) server->ip);
-
- free(server);
-
- return status;
-}
-
-celix_status_t endpointDiscoveryServer_addEndpoint(endpoint_discovery_server_pt server, endpoint_description_pt endpoint) {
- celix_status_t status;
-
- status = celixThreadMutex_lock(&server->serverLock);
- if (status != CELIX_SUCCESS) {
- return CELIX_BUNDLE_EXCEPTION;
- }
-
- // create a local copy of the endpointId which we can control...
- char* endpointId = strdup(endpoint->id);
- endpoint_description_pt cur_value = hashMap_get(server->entries, endpointId);
- if (!cur_value) {
- logHelper_log(*server->loghelper, OSGI_LOGSERVICE_INFO, "exposing new endpoint \"%s\"...", endpointId);
-
- hashMap_put(server->entries, endpointId, endpoint);
- }
-
- status = celixThreadMutex_unlock(&server->serverLock);
- if (status != CELIX_SUCCESS) {
- return CELIX_BUNDLE_EXCEPTION;
- }
-
- return status;
-}
-
-celix_status_t endpointDiscoveryServer_removeEndpoint(endpoint_discovery_server_pt server, endpoint_description_pt endpoint) {
- celix_status_t status;
-
- status = celixThreadMutex_lock(&server->serverLock);
- if (status != CELIX_SUCCESS) {
- return CELIX_BUNDLE_EXCEPTION;
- }
-
- hash_map_entry_pt entry = hashMap_getEntry(server->entries, endpoint->id);
- if (entry) {
- char* key = hashMapEntry_getKey(entry);
-
- logHelper_log(*server->loghelper, OSGI_LOGSERVICE_INFO, "removing endpoint \"%s\"...\n", key);
-
- hashMap_remove(server->entries, key);
-
- // we've made this key, see _addEnpoint above...
- free((void*) key);
- }
-
- status = celixThreadMutex_unlock(&server->serverLock);
- if (status != CELIX_SUCCESS) {
- return CELIX_BUNDLE_EXCEPTION;
- }
-
- return status;
-}
-
-static char* format_path(const char* path) {
- char* result = strdup(path);
- result = utils_stringTrim(result);
- // check whether the path starts with a leading slash...
- if (result[0] != '/') {
- size_t len = strlen(result);
- result = realloc(result, len + 2);
- memmove(result + 1, result, len);
- result[0] = '/';
- result[len + 1] = 0;
- }
- return result;
-}
-
-static celix_status_t endpointDiscoveryServer_getEndpoints(endpoint_discovery_server_pt server, const char* the_endpoint_id, array_list_pt *endpoints) {
- celix_status_t status;
-
- status = arrayList_create(endpoints);
- if (status != CELIX_SUCCESS) {
- return CELIX_ENOMEM;
- }
-
-
- hash_map_iterator_pt iter = hashMapIterator_create(server->entries);
- while (hashMapIterator_hasNext(iter)) {
- hash_map_entry_pt entry = hashMapIterator_nextEntry(iter);
-
- char* endpoint_id = hashMapEntry_getKey(entry);
- if (the_endpoint_id == NULL || strcmp(the_endpoint_id, endpoint_id) == 0) {
- endpoint_description_pt endpoint = hashMapEntry_getValue(entry);
-
- arrayList_add(*endpoints, endpoint);
- }
- }
- hashMapIterator_destroy(iter);
-
- return status;
-}
-
-static int endpointDiscoveryServer_writeEndpoints(struct mg_connection* conn, array_list_pt endpoints) {
- celix_status_t status;
- int rv = CIVETWEB_REQUEST_NOT_HANDLED;
-
- endpoint_descriptor_writer_pt writer = NULL;
- status = endpointDescriptorWriter_create(&writer);
- if (status == CELIX_SUCCESS) {
-
- char *buffer = NULL;
- status = endpointDescriptorWriter_writeDocument(writer, endpoints, &buffer);
- if (buffer) {
- mg_write(conn, response_headers, strlen(response_headers));
- mg_write(conn, buffer, strlen(buffer));
- }
-
- rv = CIVETWEB_REQUEST_HANDLED;
- }
-
- if(writer!=NULL){
- endpointDescriptorWriter_destroy(writer);
- }
-
- return rv;
-}
-
-// returns all endpoints as XML...
-static int endpointDiscoveryServer_returnAllEndpoints(endpoint_discovery_server_pt server, struct mg_connection* conn) {
- int status = CIVETWEB_REQUEST_NOT_HANDLED;
-
- array_list_pt endpoints = NULL;
-
- if (celixThreadMutex_lock(&server->serverLock) == CELIX_SUCCESS) {
- endpointDiscoveryServer_getEndpoints(server, NULL, &endpoints);
- if (endpoints) {
- status = endpointDiscoveryServer_writeEndpoints(conn, endpoints);
-
- arrayList_destroy(endpoints);
- }
-
-
- celixThreadMutex_unlock(&server->serverLock);
- }
-
- return status;
-}
-
-// returns a single endpoint as XML...
-static int endpointDiscoveryServer_returnEndpoint(endpoint_discovery_server_pt server, struct mg_connection* conn, const char* endpoint_id) {
- int status = CIVETWEB_REQUEST_NOT_HANDLED;
-
- array_list_pt endpoints = NULL;
-
- if (celixThreadMutex_lock(&server->serverLock) == CELIX_SUCCESS) {
- endpointDiscoveryServer_getEndpoints(server, endpoint_id, &endpoints);
- if (endpoints) {
- status = endpointDiscoveryServer_writeEndpoints(conn, endpoints);
-
- arrayList_destroy(endpoints);
- }
-
- celixThreadMutex_unlock(&server->serverLock);
- }
-
- return status;
-}
-
-static int endpointDiscoveryServer_callback(struct mg_connection* conn) {
- int status = CIVETWEB_REQUEST_NOT_HANDLED;
-
- const struct mg_request_info *request_info = mg_get_request_info(conn);
- if (request_info->uri != NULL && strcmp("GET", request_info->request_method) == 0) {
- endpoint_discovery_server_pt server = request_info->user_data;
-
- const char *uri = request_info->uri;
- const size_t path_len = strlen(server->path);
- const size_t uri_len = strlen(uri);
-
- if (strncmp(server->path, uri, strlen(server->path)) == 0) {
- // Be lenient when it comes to the trailing slash...
- if (path_len == uri_len || (uri_len == (path_len + 1) && uri[path_len] == '/')) {
- status = endpointDiscoveryServer_returnAllEndpoints(server, conn);
- } else {
- const char* endpoint_id = uri + path_len + 1; // right after the slash...
-
- status = endpointDiscoveryServer_returnEndpoint(server, conn, endpoint_id);
- }
- }
- }
-
- return status;
-}
-
-#ifndef ANDROID
-static celix_status_t endpointDiscoveryServer_getIpAdress(char* interface, char** ip) {
- celix_status_t status = CELIX_BUNDLE_EXCEPTION;
-
- struct ifaddrs *ifaddr, *ifa;
- char host[NI_MAXHOST];
-
- if (getifaddrs(&ifaddr) != -1)
- {
- for (ifa = ifaddr; ifa != NULL && status != CELIX_SUCCESS; ifa = ifa->ifa_next)
- {
- if (ifa->ifa_addr == NULL)
- continue;
-
- if ((getnameinfo(ifa->ifa_addr,sizeof(struct sockaddr_in), host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST) == 0) && (ifa->ifa_addr->sa_family == AF_INET)) {
- if (interface == NULL) {
- *ip = strdup(host);
- status = CELIX_SUCCESS;
- }
- else if (strcmp(ifa->ifa_name, interface) == 0) {
- *ip = strdup(host);
- status = CELIX_SUCCESS;
- }
- }
- }
-
- freeifaddrs(ifaddr);
- }
-
- return status;
-}
-#endif
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/discovery_common/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/remote_services/discovery_common/CMakeLists.txt b/remote_services/discovery_common/CMakeLists.txt
new file mode 100644
index 0000000..9388c90
--- /dev/null
+++ b/remote_services/discovery_common/CMakeLists.txt
@@ -0,0 +1,33 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+
+find_package(LibXml2 REQUIRED)
+
+add_library(discovery_common STATIC
+ src/discovery.c
+ src/discovery_activator.c
+ src/endpoint_descriptor_reader.c
+ src/endpoint_descriptor_writer.c
+ src/endpoint_discovery_poller.c
+ src/endpoint_discovery_server.c
+ src/civetweb.c
+)
+target_include_directories(discovery_common PUBLIC include)
+target_include_directories(discovery_common PRIVATE src ${LIBXML2_INCLUDE_DIR})
+target_link_libraries(discovery_common PRIVATE ${LIBXML2_LIBRARIES} Celix::framework)
+target_link_libraries(discovery_common PUBLIC Celix::log_helper Celix::remote_service_admin_api)
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/discovery_common/include/civetweb.h
----------------------------------------------------------------------
diff --git a/remote_services/discovery_common/include/civetweb.h b/remote_services/discovery_common/include/civetweb.h
new file mode 100644
index 0000000..61a8e98
--- /dev/null
+++ b/remote_services/discovery_common/include/civetweb.h
@@ -0,0 +1,657 @@
+/* Copyright (c) 2013-2014 the Civetweb developers
+ * Copyright (c) 2004-2013 Sergey Lyubka
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef CIVETWEB_HEADER_INCLUDED
+#define CIVETWEB_HEADER_INCLUDED
+
+#ifndef CIVETWEB_VERSION
+#define CIVETWEB_VERSION "1.7"
+#endif
+
+#ifndef CIVETWEB_API
+ #if defined(_WIN32)
+ #if defined(CIVETWEB_DLL_EXPORTS)
+ #define CIVETWEB_API __declspec(dllexport)
+ #elif defined(CIVETWEB_DLL_IMPORTS)
+ #define CIVETWEB_API __declspec(dllimport)
+ #else
+ #define CIVETWEB_API
+ #endif
+ #else
+ #define CIVETWEB_API
+ #endif
+#endif
+
+#include <stdio.h>
+#include <stddef.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+struct mg_context; /* Handle for the HTTP service itself */
+struct mg_connection; /* Handle for the individual connection */
+
+
+/* This structure contains information about the HTTP request. */
+struct mg_request_info {
+ const char *request_method; /* "GET", "POST", etc */
+ const char *uri; /* URL-decoded URI */
+ const char *http_version; /* E.g. "1.0", "1.1" */
+ const char *query_string; /* URL part after '?', not including '?', or
+ NULL */
+ const char *remote_user; /* Authenticated user, or NULL if no auth
+ used */
+ char remote_addr[48]; /* Client's IP address as a string. */
+ long remote_ip; /* Client's IP address. Deprecated: use remote_addr instead */
+
+ long long content_length; /* Length (in bytes) of the request body,
+ can be -1 if no length was given. */
+ int remote_port; /* Client's port */
+ int is_ssl; /* 1 if SSL-ed, 0 if not */
+ void *user_data; /* User data pointer passed to mg_start() */
+ void *conn_data; /* Connection-specific user data */
+
+ int num_headers; /* Number of HTTP headers */
+ struct mg_header {
+ const char *name; /* HTTP header name */
+ const char *value; /* HTTP header value */
+ } http_headers[64]; /* Maximum 64 headers */
+};
+
+
+/* This structure needs to be passed to mg_start(), to let civetweb know
+ which callbacks to invoke. For a detailed description, see
+ https://github.com/bel2125/civetweb/blob/master/docs/UserManual.md */
+struct mg_callbacks {
+ /* Called when civetweb has received new HTTP request.
+ If the callback returns one, it must process the request
+ by sending valid HTTP headers and a body. Civetweb will not do
+ any further processing. Otherwise it must return zero.
+ Note that since V1.7 the "begin_request" function is called
+ before an authorization check. If an authorization check is
+ required, use a request_handler instead.
+ Return value:
+ 0: civetweb will process the request itself. In this case,
+ the callback must not send any data to the client.
+ 1: callback already processed the request. Civetweb will
+ not send any data after the callback returned. */
+ int (*begin_request)(struct mg_connection *);
+
+ /* Called when civetweb has finished processing request. */
+ void (*end_request)(const struct mg_connection *, int reply_status_code);
+
+ /* Called when civetweb is about to log a message. If callback returns
+ non-zero, civetweb does not log anything. */
+ int (*log_message)(const struct mg_connection *, const char *message);
+
+ /* Called when civetweb initializes SSL library.
+ Parameters:
+ user_data: parameter user_data passed when starting the server.
+ Return value:
+ 0: civetweb will set up the SSL certificate.
+ 1: civetweb assumes the callback already set up the certificate.
+ -1: initializing ssl fails. */
+ int (*init_ssl)(void *ssl_context, void *user_data);
+
+ /* Called when websocket request is received, before websocket handshake.
+ Return value:
+ 0: civetweb proceeds with websocket handshake.
+ 1: connection is closed immediately. */
+ int (*websocket_connect)(const struct mg_connection *);
+
+ /* Called when websocket handshake is successfully completed, and
+ connection is ready for data exchange. */
+ void (*websocket_ready)(struct mg_connection *);
+
+ /* Called when data frame has been received from the client.
+ Parameters:
+ bits: first byte of the websocket frame, see websocket RFC at
+ http://tools.ietf.org/html/rfc6455, section 5.2
+ data, data_len: payload, with mask (if any) already applied.
+ Return value:
+ 1: keep this websocket connection open.
+ 0: close this websocket connection. */
+ int (*websocket_data)(struct mg_connection *, int bits,
+ char *data, size_t data_len);
+
+ /* Called when civetweb is closing a connection. The per-context mutex is
+ locked when this is invoked. This is primarily useful for noting when
+ a websocket is closing and removing it from any application-maintained
+ list of clients. */
+ void (*connection_close)(struct mg_connection *);
+
+ /* Called when civetweb tries to open a file. Used to intercept file open
+ calls, and serve file data from memory instead.
+ Parameters:
+ path: Full path to the file to open.
+ data_len: Placeholder for the file size, if file is served from
+ memory.
+ Return value:
+ NULL: do not serve file from memory, proceed with normal file open.
+ non-NULL: pointer to the file contents in memory. data_len must be
+ initilized with the size of the memory block. */
+ const char * (*open_file)(const struct mg_connection *,
+ const char *path, size_t *data_len);
+
+ /* Called when civetweb is about to serve Lua server page, if
+ Lua support is enabled.
+ Parameters:
+ lua_context: "lua_State *" pointer. */
+ void (*init_lua)(struct mg_connection *, void *lua_context);
+
+ /* Called when civetweb has uploaded a file to a temporary directory as a
+ result of mg_upload() call.
+ Parameters:
+ file_name: full path name to the uploaded file. */
+ void (*upload)(struct mg_connection *, const char *file_name);
+
+ /* Called when civetweb is about to send HTTP error to the client.
+ Implementing this callback allows to create custom error pages.
+ Parameters:
+ status: HTTP error status code.
+ Return value:
+ 1: run civetweb error handler.
+ 0: callback already handled the error. */
+ int (*http_error)(struct mg_connection *, int status);
+
+ /* Called after civetweb context has been created, before requests
+ are processed.
+ Parameters:
+ ctx: context handle */
+ void (*init_context)(struct mg_context * ctx);
+
+ /* Called when civetweb context is deleted.
+ Parameters:
+ ctx: context handle */
+ void (*exit_context)(struct mg_context * ctx);
+};
+
+
+/* Start web server.
+
+ Parameters:
+ callbacks: mg_callbacks structure with user-defined callbacks.
+ options: NULL terminated list of option_name, option_value pairs that
+ specify Civetweb configuration parameters.
+
+ Side-effects: on UNIX, ignores SIGCHLD and SIGPIPE signals. If custom
+ processing is required for these, signal handlers must be set up
+ after calling mg_start().
+
+
+ Example:
+ const char *options[] = {
+ "document_root", "/var/www",
+ "listening_ports", "80,443s",
+ NULL
+ };
+ struct mg_context *ctx = mg_start(&my_func, NULL, options);
+
+ Refer to https://github.com/bel2125/civetweb/blob/master/docs/UserManual.md
+ for the list of valid option and their possible values.
+
+ Return:
+ web server context, or NULL on error. */
+CIVETWEB_API struct mg_context *mg_start(const struct mg_callbacks *callbacks,
+ void *user_data,
+ const char **configuration_options);
+
+
+/* Stop the web server.
+
+ Must be called last, when an application wants to stop the web server and
+ release all associated resources. This function blocks until all Civetweb
+ threads are stopped. Context pointer becomes invalid. */
+CIVETWEB_API void mg_stop(struct mg_context *);
+
+
+/* mg_request_handler
+
+ Called when a new request comes in. This callback is URI based
+ and configured with mg_set_request_handler().
+
+ Parameters:
+ conn: current connection information.
+ cbdata: the callback data configured with mg_set_request_handler().
+ Returns:
+ 0: the handler could not handle the request, so fall through.
+ 1: the handler processed the request. */
+typedef int (* mg_request_handler)(struct mg_connection *conn, void *cbdata);
+
+
+/* mg_set_request_handler
+
+ Sets or removes a URI mapping for a request handler.
+
+ URI's are ordered and prefixed URI's are supported. For example,
+ consider two URIs: /a/b and /a
+ /a matches /a
+ /a/b matches /a/b
+ /a/c matches /a
+
+ Parameters:
+ ctx: server context
+ uri: the URI to configure
+ handler: the callback handler to use when the URI is requested.
+ If NULL, the URI will be removed.
+ cbdata: the callback data to give to the handler when it s requested. */
+CIVETWEB_API void mg_set_request_handler(struct mg_context *ctx, const char *uri, mg_request_handler handler, void *cbdata);
+
+
+/* Get the value of particular configuration parameter.
+ The value returned is read-only. Civetweb does not allow changing
+ configuration at run time.
+ If given parameter name is not valid, NULL is returned. For valid
+ names, return value is guaranteed to be non-NULL. If parameter is not
+ set, zero-length string is returned. */
+CIVETWEB_API const char *mg_get_option(const struct mg_context *ctx, const char *name);
+
+
+/* Get context from connection. */
+CIVETWEB_API struct mg_context *mg_get_context(struct mg_connection *conn);
+
+
+/* Get user data passed to mg_start from context. */
+CIVETWEB_API void *mg_get_user_data(struct mg_context *ctx);
+
+
+#if defined(MG_LEGACY_INTERFACE)
+/* Return array of strings that represent valid configuration options.
+ For each option, option name and default value is returned, i.e. the
+ number of entries in the array equals to number_of_options x 2.
+ Array is NULL terminated. */
+/* Deprecated: Use mg_get_valid_options instead. */
+CIVETWEB_API const char **mg_get_valid_option_names(void);
+#endif
+
+
+struct mg_option {
+ const char * name;
+ int type;
+ const char * default_value;
+};
+
+enum {
+ CONFIG_TYPE_UNKNOWN = 0x0,
+ CONFIG_TYPE_NUMBER = 0x1,
+ CONFIG_TYPE_STRING = 0x2,
+ CONFIG_TYPE_FILE = 0x3,
+ CONFIG_TYPE_DIRECTORY = 0x4,
+ CONFIG_TYPE_BOOLEAN = 0x5,
+ CONFIG_TYPE_EXT_PATTERN = 0x6
+};
+
+
+/* Return array of struct mg_option, representing all valid configuration
+ options of civetweb.c.
+ The array is terminated by a NULL name option. */
+CIVETWEB_API const struct mg_option *mg_get_valid_options(void);
+
+
+/* Get the list of ports that civetweb is listening on.
+ size is the size of the ports int array and ssl int array to fill.
+ It is the caller's responsibility to make sure ports and ssl each
+ contain at least size int elements worth of memory to write into.
+ Return value is the number of ports and ssl information filled in.
+ The value returned is read-only. Civetweb does not allow changing
+ configuration at run time. */
+CIVETWEB_API size_t mg_get_ports(const struct mg_context *ctx, size_t size, int* ports, int* ssl);
+
+
+/* Add, edit or delete the entry in the passwords file.
+
+ This function allows an application to manipulate .htpasswd files on the
+ fly by adding, deleting and changing user records. This is one of the
+ several ways of implementing authentication on the server side. For another,
+ cookie-based way please refer to the examples/chat in the source tree.
+
+ If password is not NULL, entry is added (or modified if already exists).
+ If password is NULL, entry is deleted.
+
+ Return:
+ 1 on success, 0 on error. */
+CIVETWEB_API int mg_modify_passwords_file(const char *passwords_file_name,
+ const char *domain,
+ const char *user,
+ const char *password);
+
+
+/* Return information associated with the request. */
+CIVETWEB_API struct mg_request_info *mg_get_request_info(struct mg_connection *);
+
+
+/* Send data to the client.
+ Return:
+ 0 when the connection has been closed
+ -1 on error
+ >0 number of bytes written on success */
+CIVETWEB_API int mg_write(struct mg_connection *, const void *buf, size_t len);
+
+
+/* Send data to a websocket client wrapped in a websocket frame. Uses mg_lock
+ to ensure that the transmission is not interrupted, i.e., when the
+ application is proactively communicating and responding to a request
+ simultaneously.
+
+ Send data to a websocket client wrapped in a websocket frame.
+ This function is available when civetweb is compiled with -DUSE_WEBSOCKET
+
+ Return:
+ 0 when the connection has been closed
+ -1 on error
+ >0 number of bytes written on success */
+CIVETWEB_API int mg_websocket_write(struct mg_connection* conn, int opcode,
+ const char *data, size_t data_len);
+
+
+/* Blocks until unique access is obtained to this connection. Intended for use
+ with websockets only.
+ Invoke this before mg_write or mg_printf when communicating with a
+ websocket if your code has server-initiated communication as well as
+ communication in direct response to a message. */
+CIVETWEB_API void mg_lock_connection(struct mg_connection* conn);
+CIVETWEB_API void mg_unlock_connection(struct mg_connection* conn);
+
+#if defined(MG_LEGACY_INTERFACE)
+#define mg_lock mg_lock_connection
+#define mg_unlock mg_unlock_connection
+#endif
+
+/* Lock server context. This lock may be used to protect ressources
+ that are shared between different connection/worker threads. */
+CIVETWEB_API void mg_lock_context(struct mg_context* ctx);
+CIVETWEB_API void mg_unlock_context(struct mg_context* ctx);
+
+
+/* Opcodes, from http://tools.ietf.org/html/rfc6455 */
+enum {
+ WEBSOCKET_OPCODE_CONTINUATION = 0x0,
+ WEBSOCKET_OPCODE_TEXT = 0x1,
+ WEBSOCKET_OPCODE_BINARY = 0x2,
+ WEBSOCKET_OPCODE_CONNECTION_CLOSE = 0x8,
+ WEBSOCKET_OPCODE_PING = 0x9,
+ WEBSOCKET_OPCODE_PONG = 0xa
+};
+
+
+/* Macros for enabling compiler-specific checks forprintf-like arguments. */
+#undef PRINTF_FORMAT_STRING
+#if defined(_MSC_VER) && _MSC_VER >= 1400
+#include <sal.h>
+#if defined(_MSC_VER) && _MSC_VER > 1400
+#define PRINTF_FORMAT_STRING(s) _Printf_format_string_ s
+#else
+#define PRINTF_FORMAT_STRING(s) __format_string s
+#endif
+#else
+#define PRINTF_FORMAT_STRING(s) s
+#endif
+
+#ifdef __GNUC__
+#define PRINTF_ARGS(x, y) __attribute__((format(printf, x, y)))
+#else
+#define PRINTF_ARGS(x, y)
+#endif
+
+/* Send data to the client usingprintf() semantics.
+ Works exactly like mg_write(), but allows to do message formatting. */
+CIVETWEB_API int mg_printf(struct mg_connection *,
+ PRINTF_FORMAT_STRING(const char *fmt), ...) PRINTF_ARGS(2, 3);
+
+
+/* Send contents of the entire file together with HTTP headers. */
+CIVETWEB_API void mg_send_file(struct mg_connection *conn, const char *path);
+
+
+/* Read data from the remote end, return number of bytes read.
+ Return:
+ 0 connection has been closed by peer. No more data could be read.
+ < 0 read error. No more data could be read from the connection.
+ > 0 number of bytes read into the buffer. */
+CIVETWEB_API int mg_read(struct mg_connection *, void *buf, size_t len);
+
+
+/* Get the value of particular HTTP header.
+
+ This is a helper function. It traverses request_info->http_headers array,
+ and if the header is present in the array, returns its value. If it is
+ not present, NULL is returned. */
+CIVETWEB_API const char *mg_get_header(const struct mg_connection *, const char *name);
+
+
+/* Get a value of particular form variable.
+
+ Parameters:
+ data: pointer to form-uri-encoded buffer. This could be either POST data,
+ or request_info.query_string.
+ data_len: length of the encoded data.
+ var_name: variable name to decode from the buffer
+ dst: destination buffer for the decoded variable
+ dst_len: length of the destination buffer
+
+ Return:
+ On success, length of the decoded variable.
+ On error:
+ -1 (variable not found).
+ -2 (destination buffer is NULL, zero length or too small to hold the
+ decoded variable).
+
+ Destination buffer is guaranteed to be '\0' - terminated if it is not
+ NULL or zero length. */
+CIVETWEB_API int mg_get_var(const char *data, size_t data_len,
+ const char *var_name, char *dst, size_t dst_len);
+
+
+/* Get a value of particular form variable.
+
+ Parameters:
+ data: pointer to form-uri-encoded buffer. This could be either POST data,
+ or request_info.query_string.
+ data_len: length of the encoded data.
+ var_name: variable name to decode from the buffer
+ dst: destination buffer for the decoded variable
+ dst_len: length of the destination buffer
+ occurrence: which occurrence of the variable, 0 is the first, 1 the
+ second...
+ this makes it possible to parse a query like
+ b=x&a=y&a=z which will have occurrence values b:0, a:0 and a:1
+
+ Return:
+ On success, length of the decoded variable.
+ On error:
+ -1 (variable not found).
+ -2 (destination buffer is NULL, zero length or too small to hold the
+ decoded variable).
+
+ Destination buffer is guaranteed to be '\0' - terminated if it is not
+ NULL or zero length. */
+CIVETWEB_API int mg_get_var2(const char *data, size_t data_len,
+ const char *var_name, char *dst, size_t dst_len, size_t occurrence);
+
+
+/* Fetch value of certain cookie variable into the destination buffer.
+
+ Destination buffer is guaranteed to be '\0' - terminated. In case of
+ failure, dst[0] == '\0'. Note that RFC allows many occurrences of the same
+ parameter. This function returns only first occurrence.
+
+ Return:
+ On success, value length.
+ On error:
+ -1 (either "Cookie:" header is not present at all or the requested
+ parameter is not found).
+ -2 (destination buffer is NULL, zero length or too small to hold the
+ value). */
+CIVETWEB_API int mg_get_cookie(const char *cookie, const char *var_name,
+ char *buf, size_t buf_len);
+
+
+/* Download data from the remote web server.
+ host: host name to connect to, e.g. "foo.com", or "10.12.40.1".
+ port: port number, e.g. 80.
+ use_ssl: wether to use SSL connection.
+ error_buffer, error_buffer_size: error message placeholder.
+ request_fmt,...: HTTP request.
+ Return:
+ On success, valid pointer to the new connection, suitable for mg_read().
+ On error, NULL. error_buffer contains error message.
+ Example:
+ char ebuf[100];
+ struct mg_connection *conn;
+ conn = mg_download("google.com", 80, 0, ebuf, sizeof(ebuf),
+ "%s", "GET / HTTP/1.0\r\nHost: google.com\r\n\r\n");
+ */
+CIVETWEB_API struct mg_connection *mg_download(const char *host, int port, int use_ssl,
+ char *error_buffer, size_t error_buffer_size,
+ PRINTF_FORMAT_STRING(const char *request_fmt),
+ ...) PRINTF_ARGS(6, 7);
+
+
+/* Close the connection opened by mg_download(). */
+CIVETWEB_API void mg_close_connection(struct mg_connection *conn);
+
+
+/* File upload functionality. Each uploaded file gets saved into a temporary
+ file and MG_UPLOAD event is sent.
+ Return number of uploaded files. */
+CIVETWEB_API int mg_upload(struct mg_connection *conn, const char *destination_dir);
+
+
+/* Convenience function -- create detached thread.
+ Return: 0 on success, non-0 on error. */
+typedef void * (*mg_thread_func_t)(void *);
+CIVETWEB_API int mg_start_thread(mg_thread_func_t f, void *p);
+
+
+/* Return builtin mime type for the given file name.
+ For unrecognized extensions, "text/plain" is returned. */
+CIVETWEB_API const char *mg_get_builtin_mime_type(const char *file_name);
+
+
+/* Return Civetweb version. */
+CIVETWEB_API const char *mg_version(void);
+
+
+/* URL-decode input buffer into destination buffer.
+ 0-terminate the destination buffer.
+ form-url-encoded data differs from URI encoding in a way that it
+ uses '+' as character for space, see RFC 1866 section 8.2.1
+ http://ftp.ics.uci.edu/pub/ietf/html/rfc1866.txt
+ Return: length of the decoded data, or -1 if dst buffer is too small. */
+CIVETWEB_API int mg_url_decode(const char *src, int src_len, char *dst,
+ int dst_len, int is_form_url_encoded);
+
+
+/* URL-encode input buffer into destination buffer.
+ returns the length of the resulting buffer or -1
+ is the buffer is too small. */
+CIVETWEB_API int mg_url_encode(const char *src, char *dst, size_t dst_len);
+
+
+/* MD5 hash given strings.
+ Buffer 'buf' must be 33 bytes long. Varargs is a NULL terminated list of
+ ASCIIz strings. When function returns, buf will contain human-readable
+ MD5 hash. Example:
+ char buf[33];
+ mg_md5(buf, "aa", "bb", NULL); */
+CIVETWEB_API char *mg_md5(char buf[33], ...);
+
+
+/* Print error message to the opened error log stream.
+ This utilizes the provided logging configuration.
+ conn: connection
+ fmt: format string without the line return
+ ...: variable argument list
+ Example:
+ mg_cry(conn,"i like %s", "logging"); */
+CIVETWEB_API void mg_cry(struct mg_connection *conn,
+ PRINTF_FORMAT_STRING(const char *fmt), ...) PRINTF_ARGS(2, 3);
+
+
+/* utility method to compare two buffers, case incensitive. */
+CIVETWEB_API int mg_strncasecmp(const char *s1, const char *s2, size_t len);
+
+/* Connect to a websocket as a client
+ Parameters:
+ host: host to connect to, i.e. "echo.websocket.org" or "192.168.1.1" or "localhost"
+ port: server port
+ use_ssl: make a secure connection to server
+ error_buffer, error_buffer_size: buffer for an error message
+ path: server path you are trying to connect to, i.e. if connection to localhost/app, path should be "/app"
+ origin: value of the Origin HTTP header
+ data_func: callback that should be used when data is received from the server
+ user_data: user supplied argument
+
+ Return:
+ On success, valid mg_connection object.
+ On error, NULL. Se error_buffer for details.
+*/
+
+typedef int (*websocket_data_func)(struct mg_connection *, int bits,
+ char *data, size_t data_len);
+
+typedef void (*websocket_close_func)(struct mg_connection *);
+
+CIVETWEB_API struct mg_connection *mg_connect_websocket_client(const char *host, int port, int use_ssl,
+ char *error_buffer, size_t error_buffer_size,
+ const char *path, const char *origin,
+ websocket_data_func data_func, websocket_close_func close_func,
+ void * user_data);
+
+/* Connect to a TCP server as a client (can be used to connect to a HTTP server)
+ Parameters:
+ host: host to connect to, i.e. "www.wikipedia.org" or "192.168.1.1" or "localhost"
+ port: server port
+ use_ssl: make a secure connection to server
+ error_buffer, error_buffer_size: buffer for an error message
+
+ Return:
+ On success, valid mg_connection object.
+ On error, NULL. Se error_buffer for details.
+*/
+CIVETWEB_API struct mg_connection *mg_connect_client(const char *host, int port, int use_ssl,
+ char *error_buffer, size_t error_buffer_size);
+
+
+enum {
+ TIMEOUT_INFINITE = -1
+};
+
+/* Wait for a response from the server
+ Parameters:
+ conn: connection
+ ebuf, ebuf_len: error message placeholder.
+ timeout: time to wait for a response in milliseconds (if < 0 then wait forever)
+
+ Return:
+ On success, >= 0
+ On error/timeout, < 0
+*/
+CIVETWEB_API int mg_get_response(struct mg_connection *conn, char *ebuf, size_t ebuf_len, int timeout);
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* CIVETWEB_HEADER_INCLUDED */
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/discovery_common/include/discovery.h
----------------------------------------------------------------------
diff --git a/remote_services/discovery_common/include/discovery.h b/remote_services/discovery_common/include/discovery.h
new file mode 100644
index 0000000..ee79caf
--- /dev/null
+++ b/remote_services/discovery_common/include/discovery.h
@@ -0,0 +1,67 @@
+/**
+ *Licensed to the Apache Software Foundation (ASF) under one
+ *or more contributor license agreements. See the NOTICE file
+ *distributed with this work for additional information
+ *regarding copyright ownership. The ASF licenses this file
+ *to you under the Apache License, Version 2.0 (the
+ *"License"); you may not use this file except in compliance
+ *with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *Unless required by applicable law or agreed to in writing,
+ *software distributed under the License is distributed on an
+ *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *specific language governing permissions and limitations
+ *under the License.
+ */
+/*
+ * discovery.h
+ *
+ * \date Sep 29, 2011
+ * \author <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ * \copyright Apache License, Version 2.0
+ */
+
+#ifndef DISCOVERY_H_
+#define DISCOVERY_H_
+
+#include "bundle_context.h"
+#include "service_reference.h"
+
+#include "endpoint_description.h"
+#include "endpoint_listener.h"
+
+#define DISCOVERY_SERVER_INTERFACE "DISCOVERY_CFG_SERVER_INTERFACE"
+#define DISCOVERY_SERVER_IP "DISCOVERY_CFG_SERVER_IP"
+#define DISCOVERY_SERVER_PORT "DISCOVERY_CFG_SERVER_PORT"
+#define DISCOVERY_SERVER_PATH "DISCOVERY_CFG_SERVER_PATH"
+#define DISCOVERY_POLL_ENDPOINTS "DISCOVERY_CFG_POLL_ENDPOINTS"
+#define DISCOVERY_SERVER_MAX_EP "DISCOVERY_CFG_SERVER_MAX_EP"
+
+typedef struct discovery *discovery_pt;
+
+
+/* those one could be put into a general discovery.h - file */
+celix_status_t discovery_create(bundle_context_pt context, discovery_pt *discovery);
+celix_status_t discovery_destroy(discovery_pt discovery);
+
+celix_status_t discovery_start(discovery_pt discovery);
+celix_status_t discovery_stop(discovery_pt discovery);
+
+celix_status_t discovery_endpointAdded(void *handle, endpoint_description_pt endpoint, char *machtedFilter);
+celix_status_t discovery_endpointRemoved(void *handle, endpoint_description_pt endpoint, char *machtedFilter);
+
+celix_status_t discovery_endpointListenerAdding(void * handle, service_reference_pt reference, void **service);
+celix_status_t discovery_endpointListenerAdded(void * handle, service_reference_pt reference, void * service);
+celix_status_t discovery_endpointListenerModified(void * handle, service_reference_pt reference, void * service);
+celix_status_t discovery_endpointListenerRemoved(void * handle, service_reference_pt reference, void * service);
+
+celix_status_t discovery_informEndpointListeners(discovery_pt discovery, endpoint_description_pt endpoint, bool endpointAdded);
+celix_status_t discovery_updateEndpointListener(discovery_pt discovery, service_reference_pt reference, endpoint_listener_pt service);
+
+celix_status_t discovery_addDiscoveredEndpoint(discovery_pt discovery, endpoint_description_pt endpoint);
+celix_status_t discovery_removeDiscoveredEndpoint(discovery_pt discovery, endpoint_description_pt endpoint);
+
+#endif /* DISCOVERY_H_ */
[05/19] celix git commit: CELIX-417: Refactor for CMake usage in RSA,
PSA and Docker. mostly trying to identify the api and common libraries
Posted by pn...@apache.org.
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/remote_service_admin_dfi/rsa/src/remote_service_admin_dfi.c
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/rsa/src/remote_service_admin_dfi.c b/remote_services/remote_service_admin_dfi/rsa/src/remote_service_admin_dfi.c
new file mode 100644
index 0000000..9feab9f
--- /dev/null
+++ b/remote_services/remote_service_admin_dfi/rsa/src/remote_service_admin_dfi.c
@@ -0,0 +1,775 @@
+/**
+ *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 <netdb.h>
+#include <ifaddrs.h>
+#include <string.h>
+#include <uuid/uuid.h>
+#include <curl/curl.h>
+
+#include <jansson.h>
+#include "json_serializer.h"
+#include "remote_service_admin.h"
+#include "celix_threads.h"
+#include "hash_map.h"
+#include "array_list.h"
+
+#include "import_registration_dfi.h"
+#include "export_registration_dfi.h"
+#include "remote_service_admin_dfi.h"
+#include "dyn_interface.h"
+#include "json_rpc.h"
+
+#include "remote_constants.h"
+#include "constants.h"
+#include "civetweb.h"
+
+// defines how often the webserver is restarted (with an increased port number)
+#define MAX_NUMBER_OF_RESTARTS 5
+
+
+#define RSA_LOG_ERROR(admin, msg, ...) \
+ logHelper_log((admin)->loghelper, OSGI_LOGSERVICE_ERROR, (msg), ##__VA_ARGS__)
+
+#define RSA_LOG_WARNING(admin, msg, ...) \
+ logHelper_log((admin)->loghelper, OSGI_LOGSERVICE_ERROR, (msg), ##__VA_ARGS__)
+
+#define RSA_LOG_DEBUG(admin, msg, ...) \
+ logHelper_log((admin)->loghelper, OSGI_LOGSERVICE_ERROR, (msg), ##__VA_ARGS__)
+
+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;
+ array_list_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, properties_pt props, char *interface, endpoint_description_pt *description);
+static celix_status_t remoteServiceAdmin_send(void *handle, endpoint_description_pt endpointDescription, char *request, char **reply, int* replyStatus);
+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;
+ const char *port = NULL;
+ const char *ip = NULL;
+ char *detectedIp = NULL;
+ (*admin)->context = context;
+ (*admin)->exportedServices = hashMap_create(NULL, NULL, NULL, NULL);
+ arrayList_create(&(*admin)->importedServices);
+
+ 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, 1);
+ dynType_logSetup((void *)remoteServiceAdmin_log, *admin, 1);
+ dynFunction_logSetup((void *)remoteServiceAdmin_log, *admin, 1);
+ dynInterface_logSetup((void *)remoteServiceAdmin_log, *admin, 1);
+ jsonSerializer_logSetup((void *)remoteServiceAdmin_log, *admin, 1);
+ jsonRpc_logSetup((void *)remoteServiceAdmin_log, *admin, 1);
+ }
+
+ bundleContext_getProperty(context, "RSA_PORT", &port);
+ if (port == NULL) {
+ port = (char *)DEFAULT_PORT;
+ }
+
+ bundleContext_getProperty(context, "RSA_IP", &ip);
+ if (ip == NULL) {
+ const char *interface = NULL;
+
+ bundleContext_getProperty(context, "RSA_INTERFACE", &interface);
+ if ((interface != NULL) && (remoteServiceAdmin_getIpAdress((char*)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 = strdup((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;
+
+ char newPort[10];
+
+ do {
+
+ const char *options[] = { "listening_ports", port, "num_threads", "5", 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 {
+ errno = 0;
+ char* endptr = (char*)port;
+ int currentPort = strtol(port, &endptr, 10);
+
+ 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);
+ exportRegistration_destroy(export);
+ }
+ }
+ arrayList_destroy(exports);
+ }
+ hashMapIterator_destroy(iter);
+ celixThreadMutex_unlock(&admin->exportedServicesLock);
+
+ celixThreadMutex_lock(&admin->importedServicesLock);
+ int i;
+ int size = arrayList_size(admin->importedServices);
+ for (i = 0; i < size ; i += 1) {
+ import_registration_pt import = arrayList_get(admin->importedServices, i);
+ if (import != NULL) {
+ importRegistration_stop(import);
+ importRegistration_destroy(import);
+ }
+ }
+ 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);
+ arrayList_destroy(admin->importedServices);
+
+ 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 = 1; // 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';
+ unsigned long serviceId = strtoul(service,NULL,10);
+
+ 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;
+ free(ref);
+ break;
+ }
+ free(ref);
+ }
+ }
+ 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);
+ if (rc != CELIX_SUCCESS) {
+ RSA_LOG_ERROR(rsa, "Error trying to invoke remove service, got error %i\n", rc);
+ }
+
+ if (rc == CELIX_SUCCESS && response != NULL) {
+ mg_write(conn, data_response_headers, strlen(data_response_headers));
+ mg_write(conn, response, strlen(response));
+ free(response);
+ } else {
+ mg_write(conn, no_content_response_headers, strlen(no_content_response_headers));
+ }
+ result = 1;
+
+ free(data);
+ } else {
+ result = 0;
+ RSA_LOG_WARNING(rsa, "NO export registration found for service id %lu", serviceId);
+ }
+
+ 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;
+
+ 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);
+
+ int i;
+ int size = arrayList_size(references);
+ for (i = 0; i < size; i += 1) {
+ if (i == 0) {
+ reference = arrayList_get(references, i);
+ } else {
+ bundleContext_ungetServiceReference(admin->context, arrayList_get(references, i));
+ }
+ }
+ 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;
+ }
+
+ const char *exports = NULL;
+ const 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;
+ } else {
+ logHelper_log(admin->loghelper, OSGI_LOGSERVICE_INFO, "RSA: Export service (%s)", provided);
+ }
+ }
+
+ if (status == CELIX_SUCCESS) {
+ const char *interface = provided;
+ endpoint_description_pt endpoint = NULL;
+ export_registration_pt registration = NULL;
+
+ remoteServiceAdmin_createEndpointDescription(admin, reference, properties, (char*)interface, &endpoint);
+ //TODO precheck if descriptor exists
+ status = exportRegistration_create(admin->loghelper, reference, endpoint, admin->context, ®istration);
+ 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);
+ }
+ else{
+ arrayList_destroy(*registrations);
+ *registrations = NULL;
+ }
+
+ return status;
+}
+
+celix_status_t remoteServiceAdmin_removeExportedService(remote_service_admin_pt admin, export_registration_pt registration) {
+ celix_status_t status;
+
+ logHelper_log(admin->loghelper, OSGI_LOGSERVICE_INFO, "RSA_DFI: Removing exported service");
+
+ export_reference_pt ref = NULL;
+ status = exportRegistration_getExportReference(registration, &ref);
+
+ if (status == CELIX_SUCCESS && ref != NULL) {
+ service_reference_pt servRef;
+ celixThreadMutex_lock(&admin->exportedServicesLock);
+ exportReference_getExportedService(ref, &servRef);
+
+ array_list_pt exports = (array_list_pt)hashMap_remove(admin->exportedServices, servRef);
+ if(exports!=NULL){
+ arrayList_destroy(exports);
+ }
+
+ exportRegistration_close(registration);
+ exportRegistration_destroy(registration);
+
+ celixThreadMutex_unlock(&admin->exportedServicesLock);
+
+ free(ref);
+
+ } else {
+ logHelper_log(admin->loghelper, OSGI_LOGSERVICE_ERROR, "Cannot find reference for registration");
+ }
+
+ return status;
+}
+
+static celix_status_t remoteServiceAdmin_createEndpointDescription(remote_service_admin_pt admin, service_reference_pt reference, properties_pt props, 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];
+ const 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);
+ }
+ }
+
+ 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);
+ const 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);
+
+ if (props != NULL) {
+ hash_map_iterator_pt propIter = hashMapIterator_create(props);
+ while (hashMapIterator_hasNext(propIter)) {
+ hash_map_entry_pt entry = hashMapIterator_nextEntry(propIter);
+ properties_set(endpointProperties, (char*)hashMapEntry_getKey(entry), (char*)hashMapEntry_getValue(entry));
+ }
+ hashMapIterator_destroy(propIter);
+ }
+
+ *endpoint = calloc(1, sizeof(**endpoint));
+ if (!*endpoint) {
+ status = CELIX_ENOMEM;
+ } else {
+ (*endpoint)->id = (char*)properties_get(endpointProperties, (char*) OSGI_RSA_ENDPOINT_ID);
+ const char *serviceId = NULL;
+ serviceReference_getProperty(reference, (char*) OSGI_FRAMEWORK_SERVICE_ID, &serviceId);
+ (*endpoint)->serviceId = strtoull(serviceId, NULL, 0);
+ (*endpoint)->frameworkUUID = (char*) properties_get(endpointProperties, (char*) OSGI_RSA_ENDPOINT_FRAMEWORK_UUID);
+ (*endpoint)->service = strndup(interface, 1024*10);
+ (*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)->service);
+ 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;
+ import_registration_pt import = NULL;
+
+ const char *objectClass = properties_get(endpointDescription->properties, "objectClass");
+ const char *serviceVersion = properties_get(endpointDescription->properties, (char*) CELIX_FRAMEWORK_SERVICE_VERSION);
+
+ logHelper_log(admin->loghelper, OSGI_LOGSERVICE_INFO, "RSA: Import service %s", endpointDescription->service);
+ logHelper_log(admin->loghelper, OSGI_LOGSERVICE_INFO, "Registering service factory (proxy) for service '%s'\n", objectClass);
+
+ if (objectClass != NULL) {
+ status = importRegistration_create(admin->context, endpointDescription, objectClass, serviceVersion, &import);
+ }
+ if (status == CELIX_SUCCESS && import != NULL) {
+ importRegistration_setSendFn(import, (send_func_type) remoteServiceAdmin_send, admin);
+ }
+
+ if (status == CELIX_SUCCESS && import != NULL) {
+ status = importRegistration_start(import);
+ }
+
+ celixThreadMutex_lock(&admin->importedServicesLock);
+ arrayList_add(admin->importedServices, import);
+ 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;
+ logHelper_log(admin->loghelper, OSGI_LOGSERVICE_INFO, "RSA_DFI: Removing imported service");
+
+ celixThreadMutex_lock(&admin->importedServicesLock);
+ int i;
+ int size = arrayList_size(admin->importedServices);
+ import_registration_pt current = NULL;
+ for (i = 0; i < size; i += 1) {
+ current = arrayList_get(admin->importedServices, i);
+ if (current == registration) {
+ arrayList_remove(admin->importedServices, i);
+ importRegistration_close(current);
+ importRegistration_destroy(current);
+ break;
+ }
+ }
+ celixThreadMutex_unlock(&admin->importedServicesLock);
+
+ return status;
+}
+
+
+static celix_status_t remoteServiceAdmin_send(void *handle, endpoint_description_pt endpointDescription, char *request, char **reply, int* replyStatus) {
+ remote_service_admin_pt rsa = handle;
+ struct post post;
+ post.readptr = request;
+ post.size = strlen(request);
+
+ struct get get;
+ get.size = 0;
+ get.writeptr = malloc(1);
+
+ char *serviceUrl = (char*)properties_get(endpointDescription->properties, (char*) ENDPOINT_URL);
+ char url[256];
+ snprintf(url, 256, "%s", serviceUrl);
+
+ // assume the default timeout
+ int timeout = DEFAULT_TIMEOUT;
+
+ const char *timeoutStr = NULL;
+ // Check if the endpoint has a timeout, if so, use it.
+ timeoutStr = (char*) 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_NOSIGNAL, 1);
+ curl_easy_setopt(curl, CURLOPT_TIMEOUT, timeout);
+ curl_easy_setopt(curl, CURLOPT_URL, url);
+ 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);
+ logHelper_log(rsa->loghelper, OSGI_LOGSERVICE_DEBUG, "RSA: Performing curl post\n");
+ res = curl_easy_perform(curl);
+
+ *reply = get.writeptr;
+ *replyStatus = res;
+
+ curl_easy_cleanup(curl);
+ }
+
+ 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);
+ va_end(ap);
+}
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/remote_service_admin_dfi/rsa/src/remote_service_admin_dfi.h
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/rsa/src/remote_service_admin_dfi.h b/remote_services/remote_service_admin_dfi/rsa/src/remote_service_admin_dfi.h
new file mode 100644
index 0000000..8b282f1
--- /dev/null
+++ b/remote_services/remote_service_admin_dfi/rsa/src/remote_service_admin_dfi.h
@@ -0,0 +1,57 @@
+/**
+ *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_http_impl.h
+ *
+ * \date Sep 30, 2011
+ * \author <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ * \copyright Apache License, Version 2.0
+ */
+
+#ifndef REMOTE_SERVICE_ADMIN_HTTP_IMPL_H_
+#define REMOTE_SERVICE_ADMIN_HTTP_IMPL_H_
+
+
+#include "bundle_context.h"
+#include "endpoint_description.h"
+
+//typedef struct remote_service_admin *remote_service_admin_pt;
+
+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_exportService(remote_service_admin_pt admin, char *serviceId, properties_pt properties, array_list_pt *registrations);
+celix_status_t remoteServiceAdmin_removeExportedService(remote_service_admin_pt admin, 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, service_reference_pt *service);
+
+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/2a670f26/remote_services/remote_service_admin_dfi/rsa_tst/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/rsa_tst/CMakeLists.txt b/remote_services/remote_service_admin_dfi/rsa_tst/CMakeLists.txt
index 543d5a1..b3b272e 100644
--- a/remote_services/remote_service_admin_dfi/rsa_tst/CMakeLists.txt
+++ b/remote_services/remote_service_admin_dfi/rsa_tst/CMakeLists.txt
@@ -31,10 +31,8 @@ add_executable(test_rsa_dfi
run_tests.cpp
rsa_tests.cpp
rsa_client_server_tests.cpp
-
- ${PROJECT_SOURCE_DIR}/remote_services/remote_service_admin/private/src/endpoint_description.c
)
-target_link_libraries(test_rsa_dfi Celix::framework ${CURL_LIBRARIES} ${CPPUTEST_LIBRARY})
+target_link_libraries(test_rsa_dfi PRIVATE Celix::framework ${CURL_LIBRARIES} ${CPPUTEST_LIBRARY} remote_service_admin_common)
get_property(rsa_bundle_file TARGET remote_service_admin_dfi PROPERTY BUNDLE_FILE)
get_property(calc_bundle_file TARGET calculator PROPERTY BUNDLE_FILE)
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/remote_service_admin_dfi/rsa_tst/bundle/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/rsa_tst/bundle/CMakeLists.txt b/remote_services/remote_service_admin_dfi/rsa_tst/bundle/CMakeLists.txt
index 27c3804..65b18e8 100644
--- a/remote_services/remote_service_admin_dfi/rsa_tst/bundle/CMakeLists.txt
+++ b/remote_services/remote_service_admin_dfi/rsa_tst/bundle/CMakeLists.txt
@@ -15,14 +15,6 @@
# specific language governing permissions and limitations
# under the License.
-include_directories(
- ${CPPUTEST_INCLUDE_DIR}
- ${PROJECT_SOURCE_DIR}/framework/public/include
- ${PROJECT_SOURCE_DIR}/utils/public/include
- ${PROJECT_SOURCE_DIR}/remote_services/examples/calculator_service/public/include
-)
-
-
add_bundle(rsa_dfi_tst_bundle
VERSION 0.0.1
SOURCES
@@ -30,8 +22,8 @@ add_bundle(rsa_dfi_tst_bundle
)
bundle_files(rsa_dfi_tst_bundle
- ${PROJECT_SOURCE_DIR}/remote_services/examples/calculator_service/public/include/org.apache.celix.calc.api.Calculator2.descriptor
+ ${PROJECT_SOURCE_DIR}/remote_services/examples/calculator_api/include/org.apache.celix.calc.api.Calculator2.descriptor
DESTINATION .
)
-
-target_link_libraries(rsa_dfi_tst_bundle PRIVATE ${CPPUTEST_LIBRARY} )
+target_include_directories(rsa_dfi_tst_bundle PRIVATE calculator)
+target_link_libraries(rsa_dfi_tst_bundle PRIVATE ${CPPUTEST_LIBRARY} calculator_api)
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/topology_manager/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/remote_services/topology_manager/CMakeLists.txt b/remote_services/topology_manager/CMakeLists.txt
index 4bac4fd..defee5c 100644
--- a/remote_services/topology_manager/CMakeLists.txt
+++ b/remote_services/topology_manager/CMakeLists.txt
@@ -16,27 +16,19 @@
# under the License.
celix_subproject(RSA_TOPOLOGY_MANAGER "Option to enable building the Remote Service Admin Service SHM bundle" ON DEPS REMOTE_SERVICE_ADMIN_DFI)
if (RSA_TOPOLOGY_MANAGER)
- include_directories("${PROJECT_SOURCE_DIR}/utils/public/include")
- include_directories("${PROJECT_SOURCE_DIR}/remote_services/utils/public/include")
- include_directories("${PROJECT_SOURCE_DIR}/remote_services/topology_manager/private/include")
- include_directories("${PROJECT_SOURCE_DIR}/remote_services/endpoint_listener/public/include")
- include_directories("${PROJECT_SOURCE_DIR}/remote_services/remote_service_admin/public/include")
- include_directories("${PROJECT_SOURCE_DIR}/log_service/public/include")
- include_directories("${PROJECT_SOURCE_DIR}/remote_services/topology_manager/public/include")
- add_bundle(topology_manager SOURCES
- private/src/topology_manager
- private/src/scope
- private/src/activator
-
- private/include/topology_manager.h
- public/include/tm_scope.h
+ add_bundle(topology_manager
+ SOURCES
+ src/topology_manager
+ src/scope
+ src/activator
VERSION 0.9.0
SYMBOLIC_NAME "apache_celix_rs_topology_manager"
- NAME
- "Apache Celix RS Topology Manager"
+ NAME "Apache Celix RS Topology Manager"
)
- target_link_libraries(topology_manager PRIVATE Celix::log_helper)
+ target_include_directories(topology_manager PRIVATE src)
+ target_include_directories(topology_manager PUBLIC include)
+ target_link_libraries(topology_manager PRIVATE Celix::log_helper remote_service_admin_api)
install_bundle(topology_manager)
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/topology_manager/include/tm_scope.h
----------------------------------------------------------------------
diff --git a/remote_services/topology_manager/include/tm_scope.h b/remote_services/topology_manager/include/tm_scope.h
new file mode 100644
index 0000000..d4f60ca
--- /dev/null
+++ b/remote_services/topology_manager/include/tm_scope.h
@@ -0,0 +1,46 @@
+/**
+ *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.
+ */
+/*
+ * tm_scope.h
+ *
+ * \date Oct 29, 2015
+ * \author <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ * \copyright Apache License, Version 2.0
+ */
+
+#ifndef TM_SCOPE_H_
+#define TM_SCOPE_H_
+
+#include "celix_errno.h"
+
+#define TOPOLOGYMANAGER_SCOPE_SERVICE "tm_scope"
+
+
+struct tm_scope_service {
+ void *handle; // scope_pt
+ celix_status_t (*addExportScope)(void *handle, char *filter, properties_pt props);
+ celix_status_t (*removeExportScope)(void *handle, char *filter);
+ celix_status_t (*addImportScope)(void *handle, char *filter);
+ celix_status_t (*removeImportScope)(void *handle, char *filter);
+};
+
+typedef struct tm_scope_service tm_scope_service_t;
+typedef tm_scope_service_t *tm_scope_service_pt;
+
+#endif /* TM_SCOPE_H_ */
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/topology_manager/private/include/scope.h
----------------------------------------------------------------------
diff --git a/remote_services/topology_manager/private/include/scope.h b/remote_services/topology_manager/private/include/scope.h
deleted file mode 100644
index 4035e2c..0000000
--- a/remote_services/topology_manager/private/include/scope.h
+++ /dev/null
@@ -1,150 +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.
- */
-/*
- * scope.h
- *
- * \date Sep 29, 2015
- * \author <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- * \copyright Apache License, Version 2.0
- */
-
-#ifndef TOPOLOGY_SCOPE_H_
-#define TOPOLOGY_SCOPE_H_
-
-#include "celixbool.h"
-#include "celix_errno.h"
-#include "celix_threads.h"
-#include "hash_map.h"
-#include "endpoint_description.h"
-#include "properties.h"
-#include "service_reference.h"
-#include "tm_scope.h"
-
-typedef struct scope *scope_pt;
-
-
-
-/* \brief create scope structure
- *
- * \param owning component pointer
- * \param scope to be created
- *
- * \return CELIX_SUCCESS
- * CELIX_ENOMEM
- */
-celix_status_t scope_scopeCreate(void *handle, scope_pt *scope);
-
-/* \brief destroy scope structure
- *
- * \param scope to be destroyed
- *
- * \return CELIX_SUCCESS
- */
-celix_status_t scope_scopeDestroy(scope_pt scope);
-
-/* \brief register export scope change callback of topology manager
- *
- * \param scope structure
- * \param changed function pointer
- *
- * \return -
- */
-void scope_setExportScopeChangedCallback(scope_pt scope, celix_status_t (*changed)(void *handle, char *servName));
-
-/* \brief register import scope change callback of topology manager
- *
- * \param scope structure
- * \param changed function pointer
- *
- * \return -
- */
-void scope_setImportScopeChangedCallback(scope_pt scope, celix_status_t (*changed)(void *handle, char *servName));
-
-
-/* \brief Test if scope allows import of service
- *
- * \param scope containing import rules
- * \param endpoint import service endpoint description
- *
- * \return true import allowed
- * false import not allowed
- */
-bool scope_allowImport(scope_pt scope, endpoint_description_pt endpoint);
-
-/* \brief Test if scope allows import of service
- *
- * \param scope containing export rules
- * \param reference to service
- * \param props, additional properties defining restrictions for the exported service
- * NULL if no additional restrictions found
- *
- * \return CELIX_SUCCESS
- *
- */
-celix_status_t scope_getExportProperties(scope_pt scope, service_reference_pt reference, properties_pt *props);
-
-/* \brief add restricted scope for specified exported service
- *
- * \param handle pointer to scope
- * \param filter, filter string
- * \param props additional properties defining restrictions for the exported service
- *
- * \return CELIX_SUCCESS if added to scope
- * CELIX_ILLEGAL_ARGUMENT if service scope is already restricted before
- *
- */
-celix_status_t tm_addExportScope(void *handle, char *filter, properties_pt props);
-
-/* \brief remove restricted scope for specified exported service
- *
- * \param handle pointer to scope
- * \param filter, filter string
- *
- * \return CELIX_SUCCESS if removed
- * CELIX_ILLEGAL_ARGUMENT if service not found in scope
- *
- */
-celix_status_t tm_removeExportScope(void *handle, char *filter);
-
-/* \brief add restricted scope for specified imported service
- *
- * \param handle pointer to scope
- * \param filter, filter string
- * \param props additional properties defining restrictions for the imported service
- *
- * \return CELIX_SUCCESS if added to scope
- * CELIX_ILLEGAL_ARGUMENT if service scope is already restricted before
- *
- */
-celix_status_t tm_addImportScope(void *handle, char *filter);
-
-
-/* \brief remove restricted scope for specified imported service
- *
- * \param handle pointer to scope
- * \param filter, filter string
- *
- * \return CELIX_SUCCESS if removed
- * CELIX_ILLEGAL_ARGUMENT if service not found in scope
- *
- */
-celix_status_t tm_removeImportScope(void *handle, char *filter);
-
-
-#endif // TOPOLOGY_SCOPE_H_
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/topology_manager/private/include/topology_manager.h
----------------------------------------------------------------------
diff --git a/remote_services/topology_manager/private/include/topology_manager.h b/remote_services/topology_manager/private/include/topology_manager.h
deleted file mode 100644
index 7e5e917..0000000
--- a/remote_services/topology_manager/private/include/topology_manager.h
+++ /dev/null
@@ -1,65 +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.
- */
-/*
- * topology_manager.h
- *
- * \date Sep 29, 2011
- * \author <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- * \copyright Apache License, Version 2.0
- */
-
-#ifndef TOPOLOGY_MANAGER_H_
-#define TOPOLOGY_MANAGER_H_
-
-#include "endpoint_listener.h"
-#include "service_reference.h"
-#include "bundle_context.h"
-#include "log_helper.h"
-#include "scope.h"
-
-#define OSGI_RSA_REMOTE_SERVICE_ADMIN "remote_service_admin"
-
-typedef struct topology_manager *topology_manager_pt;
-
-celix_status_t topologyManager_create(bundle_context_pt context, log_helper_pt logHelper, topology_manager_pt *manager, void **scope);
-celix_status_t topologyManager_destroy(topology_manager_pt manager);
-celix_status_t topologyManager_closeImports(topology_manager_pt manager);
-
-celix_status_t topologyManager_rsaAdding(void *handle, service_reference_pt reference, void **service);
-celix_status_t topologyManager_rsaAdded(void *handle, service_reference_pt reference, void *service);
-celix_status_t topologyManager_rsaModified(void *handle, service_reference_pt reference, void *service);
-celix_status_t topologyManager_rsaRemoved(void *handle, service_reference_pt reference, void *service);
-
-celix_status_t topologyManager_endpointListenerAdding(void* handle, service_reference_pt reference, void** service);
-celix_status_t topologyManager_endpointListenerAdded(void* handle, service_reference_pt reference, void* service);
-celix_status_t topologyManager_endpointListenerModified(void * handle, service_reference_pt reference, void* service);
-celix_status_t topologyManager_endpointListenerRemoved(void * handle, service_reference_pt reference, void* service);
-
-celix_status_t topologyManager_serviceChanged(void *listener, service_event_pt event);
-
-celix_status_t topologyManager_addImportedService(void *handle, endpoint_description_pt endpoint, char *matchedFilter);
-celix_status_t topologyManager_removeImportedService(void *handle, endpoint_description_pt endpoint, char *matchedFilter);
-
-celix_status_t topologyManager_addExportedService(topology_manager_pt manager, service_reference_pt reference, char *serviceId);
-celix_status_t topologyManager_removeExportedService(topology_manager_pt manager, service_reference_pt reference, char *serviceId);
-
-celix_status_t topologyManager_listenerAdded(void *handle, array_list_pt listeners);
-celix_status_t topologyManager_listenerRemoved(void *handle, array_list_pt listeners);
-
-#endif /* TOPOLOGY_MANAGER_H_ */
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/topology_manager/private/src/activator.c
----------------------------------------------------------------------
diff --git a/remote_services/topology_manager/private/src/activator.c b/remote_services/topology_manager/private/src/activator.c
deleted file mode 100644
index 7f39a25..0000000
--- a/remote_services/topology_manager/private/src/activator.c
+++ /dev/null
@@ -1,289 +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.
- */
-/*
- * activator.c
- *
- * \date Sep 29, 2011
- * \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 <string.h>
-
-#include "constants.h"
-#include "bundle_activator.h"
-#include "service_tracker.h"
-#include "service_registration.h"
-
-#include "topology_manager.h"
-#include "endpoint_listener.h"
-#include "remote_constants.h"
-#include "listener_hook_service.h"
-#include "log_service.h"
-#include "log_helper.h"
-#include "scope.h"
-#include "tm_scope.h"
-#include "topology_manager.h"
-
-struct activator {
- bundle_context_pt context;
-
- topology_manager_pt manager;
-
- service_tracker_pt endpointListenerTracker;
- service_tracker_pt remoteServiceAdminTracker;
- service_listener_pt serviceListener;
-
- endpoint_listener_pt endpointListener;
- service_registration_pt endpointListenerService;
-
- listener_hook_service_pt hookService;
- service_registration_pt hook;
-
- tm_scope_service_pt scopeService;
- service_registration_pt scopeReg;
-
- log_helper_pt loghelper;
-};
-
-
-static celix_status_t bundleActivator_createEPLTracker(struct activator *activator, service_tracker_pt *tracker);
-static celix_status_t bundleActivator_createRSATracker(struct activator *activator, service_tracker_pt *tracker);
-static celix_status_t bundleActivator_createServiceListener(struct activator *activator, service_listener_pt *listener);
-
-celix_status_t bundleActivator_create(bundle_context_pt context, void **userData) {
- celix_status_t status = CELIX_SUCCESS;
- struct activator *activator = NULL;
- void *scope;
-
- activator = calloc(1, sizeof(struct activator));
-
- if (!activator) {
- return CELIX_ENOMEM;
- }
-
- activator->context = context;
- activator->endpointListenerService = NULL;
- activator->endpointListenerTracker = NULL;
- activator->hook = NULL;
- activator->manager = NULL;
- activator->remoteServiceAdminTracker = NULL;
- activator->serviceListener = NULL;
- activator->scopeService = calloc(1, sizeof(*(activator->scopeService)));
- if (activator->scopeService == NULL)
- {
- free(activator);
- return CELIX_ENOMEM;
- }
-
- activator->scopeService->addExportScope = tm_addExportScope;
- activator->scopeService->removeExportScope = tm_removeExportScope;
- activator->scopeService->addImportScope = tm_addImportScope;
- activator->scopeService->removeImportScope = tm_removeImportScope;
- activator->scopeReg = NULL; // explicitly needed, otherwise exception
-
- logHelper_create(context, &activator->loghelper);
- logHelper_start(activator->loghelper);
-
- status = topologyManager_create(context, activator->loghelper, &activator->manager, &scope);
- activator->scopeService->handle = scope;
-
- if (status == CELIX_SUCCESS) {
- status = bundleActivator_createEPLTracker(activator, &activator->endpointListenerTracker);
- if (status == CELIX_SUCCESS) {
- status = bundleActivator_createRSATracker(activator, &activator->remoteServiceAdminTracker);
- if (status == CELIX_SUCCESS) {
- status = bundleActivator_createServiceListener(activator, &activator->serviceListener);
- if (status == CELIX_SUCCESS) {
- *userData = activator;
- }
- }
- }
- }
-
- if(status != CELIX_SUCCESS){
- bundleActivator_destroy(activator,context);
- }
-
- return status;
-}
-
-static celix_status_t bundleActivator_createEPLTracker(struct activator *activator, service_tracker_pt *tracker) {
- celix_status_t status;
-
- service_tracker_customizer_pt customizer = NULL;
-
- status = serviceTrackerCustomizer_create(activator->manager, topologyManager_endpointListenerAdding, topologyManager_endpointListenerAdded, topologyManager_endpointListenerModified,
- topologyManager_endpointListenerRemoved, &customizer);
-
- if (status == CELIX_SUCCESS) {
- status = serviceTracker_create(activator->context, (char *) OSGI_ENDPOINT_LISTENER_SERVICE, customizer, tracker);
- }
-
- return status;
-}
-
-static celix_status_t bundleActivator_createRSATracker(struct activator *activator, service_tracker_pt *tracker) {
- celix_status_t status;
-
- service_tracker_customizer_pt customizer = NULL;
-
- status = serviceTrackerCustomizer_create(activator->manager, topologyManager_rsaAdding, topologyManager_rsaAdded, topologyManager_rsaModified, topologyManager_rsaRemoved, &customizer);
-
- if (status == CELIX_SUCCESS) {
- status = serviceTracker_create(activator->context, OSGI_RSA_REMOTE_SERVICE_ADMIN, customizer, tracker);
- }
-
- return status;
-}
-
-static celix_status_t bundleActivator_createServiceListener(struct activator *activator, service_listener_pt *listener) {
- celix_status_t status = CELIX_SUCCESS;
-
- *listener = malloc(sizeof(**listener));
- if (!*listener) {
- return CELIX_ENOMEM;
- }
-
- (*listener)->handle = activator->manager;
- (*listener)->serviceChanged = topologyManager_serviceChanged;
-
- return status;
-}
-
-celix_status_t bundleActivator_start(void * userData, bundle_context_pt context) {
- celix_status_t status;
- struct activator *activator = userData;
-
- endpoint_listener_pt endpointListener = malloc(sizeof(*endpointListener));
- endpointListener->handle = activator->manager;
- endpointListener->endpointAdded = topologyManager_addImportedService;
- endpointListener->endpointRemoved = topologyManager_removeImportedService;
- activator->endpointListener = endpointListener;
-
- const char *uuid = NULL;
- status = bundleContext_getProperty(activator->context, OSGI_FRAMEWORK_FRAMEWORK_UUID, &uuid);
- if (!uuid) {
- logHelper_log(activator->loghelper, OSGI_LOGSERVICE_ERROR, "TOPOLOGY_MANAGER: no framework UUID defined?!");
- return CELIX_ILLEGAL_STATE;
- }
-
- size_t len = 14 + strlen(OSGI_FRAMEWORK_OBJECTCLASS) + strlen(OSGI_RSA_ENDPOINT_FRAMEWORK_UUID) + strlen(uuid);
- char *scope = malloc(len);
- if (!scope) {
- return CELIX_ENOMEM;
- }
-
- snprintf(scope, len, "(&(%s=*)(!(%s=%s)))", OSGI_FRAMEWORK_OBJECTCLASS, OSGI_RSA_ENDPOINT_FRAMEWORK_UUID, uuid);
-
- logHelper_log(activator->loghelper, OSGI_LOGSERVICE_INFO, "TOPOLOGY_MANAGER: endpoint listener scope is %s", scope);
-
- properties_pt props = properties_create();
- properties_set(props, (char *) OSGI_ENDPOINT_LISTENER_SCOPE, scope);
-
- // We can release the scope, as properties_set makes a copy of the key & value...
- free(scope);
-
- bundleContext_registerService(context, (char *) OSGI_ENDPOINT_LISTENER_SERVICE, endpointListener, props, &activator->endpointListenerService);
-
- listener_hook_service_pt hookService = malloc(sizeof(*hookService));
- hookService->handle = activator->manager;
- hookService->added = topologyManager_listenerAdded;
- hookService->removed = topologyManager_listenerRemoved;
- activator->hookService = hookService;
-
- bundleContext_registerService(context, (char *) OSGI_FRAMEWORK_LISTENER_HOOK_SERVICE_NAME, hookService, NULL, &activator->hook);
- bundleContext_addServiceListener(context, activator->serviceListener, "(service.exported.interfaces=*)");
-
- if (status == CELIX_SUCCESS) {
- serviceTracker_open(activator->remoteServiceAdminTracker);
- }
-
- if (status == CELIX_SUCCESS) {
- status = serviceTracker_open(activator->endpointListenerTracker);
- }
-
- bundleContext_registerService(context, (char *) TOPOLOGYMANAGER_SCOPE_SERVICE, activator->scopeService, NULL, &activator->scopeReg);
-
- array_list_pt references = NULL;
- bundleContext_getServiceReferences(context, NULL, "(service.exported.interfaces=*)", &references);
- int i;
- for (i = 0; i < arrayList_size(references); i++) {
- service_reference_pt reference = arrayList_get(references, i);
- const char* serviceId = NULL;
- status = CELIX_DO_IF(status, serviceReference_getProperty(reference, OSGI_FRAMEWORK_SERVICE_ID, &serviceId));
-
- CELIX_DO_IF(status, topologyManager_addExportedService(activator->manager, reference, (char*)serviceId));
- }
- arrayList_destroy(references);
-
- return status;
-}
-
-celix_status_t bundleActivator_stop(void * userData, bundle_context_pt context) {
- celix_status_t status = CELIX_SUCCESS;
- struct activator *activator = userData;
-
- if (serviceTracker_close(activator->remoteServiceAdminTracker) == CELIX_SUCCESS) {
- serviceTracker_destroy(activator->remoteServiceAdminTracker);
- }
-
- if (serviceTracker_close(activator->endpointListenerTracker) == CELIX_SUCCESS) {
- serviceTracker_destroy(activator->endpointListenerTracker);
- }
-
- bundleContext_removeServiceListener(context, activator->serviceListener);
- free(activator->serviceListener);
-
- serviceRegistration_unregister(activator->hook);
- free(activator->hookService);
-
- serviceRegistration_unregister(activator->endpointListenerService);
- free(activator->endpointListener);
-
- serviceRegistration_unregister(activator->scopeReg);
-
- topologyManager_closeImports(activator->manager);
-
- return status;
-}
-
-celix_status_t bundleActivator_destroy(void * userData, bundle_context_pt context) {
- celix_status_t status = CELIX_SUCCESS;
-
- struct activator *activator = userData;
- if (!activator || !activator->manager) {
- status = CELIX_BUNDLE_EXCEPTION;
- } else {
- logHelper_stop(activator->loghelper);
- logHelper_destroy(&activator->loghelper);
-
- status = topologyManager_destroy(activator->manager);
-
- if (activator->scopeService) {
- free(activator->scopeService);
- }
-
- free(activator);
- }
-
- return status;
-}
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/topology_manager/private/src/scope.c
----------------------------------------------------------------------
diff --git a/remote_services/topology_manager/private/src/scope.c b/remote_services/topology_manager/private/src/scope.c
deleted file mode 100644
index b81d050..0000000
--- a/remote_services/topology_manager/private/src/scope.c
+++ /dev/null
@@ -1,326 +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.
- */
-/*
- * scope.c
- *
- * \date Sep 29, 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 <string.h>
-#include "scope.h"
-#include "tm_scope.h"
-#include "topology_manager.h"
-#include "utils.h"
-
-struct scope_item {
- properties_pt props;
-};
-
-struct scope {
- void *manager; // owner of the scope datastructure
- celix_thread_mutex_t exportScopeLock;
- hash_map_pt exportScopes; // key is filter, value is scope_item (properties set)
-
- celix_thread_mutex_t importScopeLock;
- array_list_pt importScopes; // list of filters
-
- celix_status_t (*exportScopeChangedHandler)(void* manager, char *filter);
- celix_status_t (*importScopeChangedHandler)(void* manager, char *filter);
-};
-
-static celix_status_t import_equal(const void *, const void *, bool *equals);
-
-/*
- * SERVICES
- */
-
-celix_status_t tm_addExportScope(void *handle, char *filter, properties_pt props) {
- celix_status_t status = CELIX_SUCCESS;
- scope_pt scope = (scope_pt) handle;
- properties_pt present;
-
- if (handle == NULL)
- return CELIX_ILLEGAL_ARGUMENT;
-
- if (celixThreadMutex_lock(&scope->exportScopeLock) == CELIX_SUCCESS) {
- // For now we just don't allow two exactly the same filters
- // TODO: What we actually need is the following
- // If part of the new filter is already present in any of the filters in exportScopes
- // we have to assure that the new filter defines other property keys than the property keys
- // in the already defined filter!
- present = (properties_pt) hashMap_get(scope->exportScopes, filter);
- if (present == NULL) {
- struct scope_item *item = calloc(1, sizeof(*item));
- if (item == NULL) {
- status = CELIX_ENOMEM;
- } else {
- item->props = props;
- hashMap_put(scope->exportScopes, (void*) strdup(filter), (void*) item);
- }
- } else {
- // don't allow the same filter twice
- properties_destroy(props);
- status = CELIX_ILLEGAL_ARGUMENT;
- }
- celixThreadMutex_unlock(&scope->exportScopeLock);
- }
-
- if (scope->exportScopeChangedHandler != NULL) {
- status = CELIX_DO_IF(status, scope->exportScopeChangedHandler(scope->manager, filter));
- }
-
- return status;
-}
-
-celix_status_t tm_removeExportScope(void *handle, char *filter) {
- celix_status_t status = CELIX_SUCCESS;
- scope_pt scope = (scope_pt) handle;
-
- if (handle == NULL)
- return CELIX_ILLEGAL_ARGUMENT;
-
- if (celixThreadMutex_lock(&scope->exportScopeLock) == CELIX_SUCCESS) {
- struct scope_item *present = (struct scope_item *) hashMap_get(scope->exportScopes, filter);
- if (present == NULL) {
- status = CELIX_ILLEGAL_ARGUMENT;
- } else {
- properties_destroy(present->props);
- hashMap_remove(scope->exportScopes, filter); // frees also the item!
- }
- celixThreadMutex_unlock(&scope->exportScopeLock);
- }
- if (scope->exportScopeChangedHandler != NULL) {
- status = CELIX_DO_IF(status, scope->exportScopeChangedHandler(scope->manager, filter));
- }
- return status;
-}
-
-celix_status_t tm_addImportScope(void *handle, char *filter) {
- celix_status_t status = CELIX_SUCCESS;
- scope_pt scope = (scope_pt) handle;
-
- filter_pt new;
-
- if (handle == NULL)
- return CELIX_ILLEGAL_ARGUMENT;
- new = filter_create(filter);
- if (new == NULL) {
- return CELIX_ILLEGAL_ARGUMENT; // filter not parseble
- }
- if (celixThreadMutex_lock(&scope->importScopeLock) == CELIX_SUCCESS) {
- int index = arrayList_indexOf(scope->importScopes, new);
- filter_pt present = (filter_pt) arrayList_get(scope->importScopes, index);
- if (present == NULL) {
- arrayList_add(scope->importScopes, new);
- } else {
- filter_destroy(new);
- status = CELIX_ILLEGAL_ARGUMENT;
- }
-
- celixThreadMutex_unlock(&scope->importScopeLock);
- }
- if (scope->importScopeChangedHandler != NULL) {
- status = CELIX_DO_IF(status, scope->importScopeChangedHandler(scope->manager, filter));
- }
- return status;
-}
-
-celix_status_t tm_removeImportScope(void *handle, char *filter) {
- celix_status_t status = CELIX_SUCCESS;
- scope_pt scope = (scope_pt) handle;
- filter_pt new;
-
- if (handle == NULL)
- return CELIX_ILLEGAL_ARGUMENT;
-
- new = filter_create(filter);
- if (new == NULL) {
- return CELIX_ILLEGAL_ARGUMENT; // filter not parseble
- }
-
- if (celixThreadMutex_lock(&scope->importScopeLock) == CELIX_SUCCESS) {
- int index = arrayList_indexOf(scope->importScopes, new);
- filter_pt present = (filter_pt) arrayList_get(scope->importScopes, index);
- if (present == NULL)
- status = CELIX_ILLEGAL_ARGUMENT;
- else {
- arrayList_removeElement(scope->importScopes, present);
- filter_destroy(present);
- }
- celixThreadMutex_unlock(&scope->importScopeLock);
- }
- if (scope->importScopeChangedHandler != NULL) {
- status = CELIX_DO_IF(status, scope->importScopeChangedHandler(scope->manager, filter));
- }
- filter_destroy(new);
- return status;
-}
-
-/*****************************************************************************
- * GLOBAL FUNCTIONS
- *****************************************************************************/
-
-void scope_setExportScopeChangedCallback(scope_pt scope, celix_status_t (*changed)(void *handle, char *servName)) {
- scope->exportScopeChangedHandler = changed;
-}
-
-void scope_setImportScopeChangedCallback(scope_pt scope, celix_status_t (*changed)(void *handle, char *servName)) {
- scope->importScopeChangedHandler = changed;
-}
-
-celix_status_t scope_scopeCreate(void *handle, scope_pt *scope) {
- celix_status_t status = CELIX_SUCCESS;
-
- *scope = calloc(1, sizeof **scope);
-
- if (*scope == NULL) {
- return CELIX_ENOMEM;
- }
-
- (*scope)->manager = handle;
- celixThreadMutex_create(&(*scope)->exportScopeLock, NULL);
- celixThreadMutex_create(&(*scope)->importScopeLock, NULL);
-
- (*scope)->exportScopes = hashMap_create(utils_stringHash, NULL, utils_stringEquals, NULL);
- arrayList_createWithEquals(import_equal, &((*scope)->importScopes));
- (*scope)->exportScopeChangedHandler = NULL;
-
- return status;
-}
-
-celix_status_t scope_scopeDestroy(scope_pt scope) {
- celix_status_t status = CELIX_SUCCESS;
-
- if (celixThreadMutex_lock(&scope->exportScopeLock) == CELIX_SUCCESS) {
- hash_map_iterator_pt iter = hashMapIterator_create(scope->exportScopes);
- while (hashMapIterator_hasNext(iter)) {
- hash_map_entry_pt scopedEntry = hashMapIterator_nextEntry(iter);
- struct scope_item *item = (struct scope_item*) hashMapEntry_getValue(scopedEntry);
- properties_destroy(item->props);
- }
- hashMapIterator_destroy(iter);
- hashMap_destroy(scope->exportScopes, true, true); // free keys, free values
- celixThreadMutex_unlock(&scope->exportScopeLock);
- }
-
- if (celixThreadMutex_lock(&scope->importScopeLock) == CELIX_SUCCESS) {
- array_list_iterator_pt imp_iter = arrayListIterator_create(scope->importScopes);
- while (arrayListIterator_hasNext(imp_iter)) {
- filter_pt element = (filter_pt) arrayListIterator_next(imp_iter);
- filter_destroy(element);
- // no need to call arrayList_removeElement(element) because complete list is destroyed
- }
- arrayListIterator_destroy(imp_iter);
- arrayList_destroy(scope->importScopes);
- celixThreadMutex_unlock(&scope->importScopeLock);
- }
-
- celixThreadMutex_destroy(&scope->exportScopeLock);
- celixThreadMutex_destroy(&scope->importScopeLock);
- free(scope);
- return status;
-}
-
-/*****************************************************************************
- * STATIC FUNCTIONS
- *****************************************************************************/
-static celix_status_t import_equal(const void *src, const void *dest, bool *equals) {
- celix_status_t status;
-
- filter_pt src_filter = (filter_pt) src;
- filter_pt dest_filter = (filter_pt) dest;
- status = filter_match_filter(src_filter, dest_filter, equals);
- return status;
-}
-
-bool scope_allowImport(scope_pt scope, endpoint_description_pt endpoint) {
- bool allowImport = false;
- array_list_iterator_pt iter;
-
- if (celixThreadMutex_lock(&(scope->importScopeLock)) == CELIX_SUCCESS) {
- if (arrayList_size(scope->importScopes) == 0) {
- allowImport = true;
- } else {
- iter = arrayListIterator_create(scope->importScopes);
- while ((allowImport == false) && arrayListIterator_hasNext(iter)) {
- filter_pt element = (filter_pt) arrayListIterator_next(iter);
- filter_match(element, endpoint->properties, &allowImport);
- }
- arrayListIterator_destroy(iter);
- }
- celixThreadMutex_unlock(&scope->importScopeLock);
- }
- return allowImport;
-}
-
-celix_status_t scope_getExportProperties(scope_pt scope, service_reference_pt reference, properties_pt *props) {
- celix_status_t status = CELIX_SUCCESS;
- unsigned int size = 0;
- char **keys;
- bool found = false;
-
- *props = NULL;
- properties_pt serviceProperties = properties_create(); // GB: not sure if a copy is needed
- // or serviceReference_getProperties() is
- // is acceptable
-
- serviceReference_getPropertyKeys(reference, &keys, &size);
- for (int i = 0; i < size; i++) {
- char *key = keys[i];
- const 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(serviceProperties, key, value);
- }
-
- }
-
- free(keys);
-
- if (celixThreadMutex_lock(&(scope->exportScopeLock)) == CELIX_SUCCESS) {
- hash_map_iterator_pt scopedPropIter = hashMapIterator_create(scope->exportScopes);
- // TODO: now stopping if first filter matches, alternatively we could build up
- // the additional output properties for each filter that matches?
- while ((!found) && hashMapIterator_hasNext(scopedPropIter)) {
- hash_map_entry_pt scopedEntry = hashMapIterator_nextEntry(scopedPropIter);
- char *filterStr = (char *) hashMapEntry_getKey(scopedEntry);
- filter_pt filter = filter_create(filterStr);
- if (filter != NULL) {
- // test if the scope filter matches the exported service properties
- status = filter_match(filter, serviceProperties, &found);
- if (found) {
- struct scope_item *item = (struct scope_item *) hashMapEntry_getValue(scopedEntry);
- *props = item->props;
- }
- }
- filter_destroy(filter);
- }
- hashMapIterator_destroy(scopedPropIter);
- properties_destroy(serviceProperties);
-
- celixThreadMutex_unlock(&(scope->exportScopeLock));
- }
-
- return status;
-}
[09/19] celix git commit: CELIX-417: Refactor for CMake usage in RSA,
PSA and Docker. mostly trying to identify the api and common libraries
Posted by pn...@apache.org.
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/examples/calculator_service/private/include/calculator_impl.h
----------------------------------------------------------------------
diff --git a/remote_services/examples/calculator_service/private/include/calculator_impl.h b/remote_services/examples/calculator_service/private/include/calculator_impl.h
deleted file mode 100644
index 5e075e4..0000000
--- a/remote_services/examples/calculator_service/private/include/calculator_impl.h
+++ /dev/null
@@ -1,43 +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.
- */
-/*
- * calculator_impl.h
- *
- * \date Oct 5, 2011
- * \author <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- * \copyright Apache License, Version 2.0
- */
-
-#ifndef CALCULATOR_IMPL_H_
-#define CALCULATOR_IMPL_H_
-
-#include "celix_errno.h"
-
-#include "calculator_service.h"
-
-struct calculator {
-};
-
-celix_status_t calculator_create(calculator_pt *calcuator);
-celix_status_t calculator_destroy(calculator_pt *calcuator);
-celix_status_t calculator_add(calculator_pt calcuator, double a, double b, double *result);
-celix_status_t calculator_sub(calculator_pt calcuator, double a, double b, double *result);
-celix_status_t calculator_sqrt(calculator_pt calcuator, double a, double *result);
-
-#endif /* CALCULATOR_IMPL_H_ */
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/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
deleted file mode 100644
index 688a7b0..0000000
--- a/remote_services/examples/calculator_service/private/src/calculator_activator.c
+++ /dev/null
@@ -1,110 +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.
- */
-/*
- * calculator_activator.c
- *
- * \date Oct 5, 2011
- * \author <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- * \copyright Apache License, Version 2.0
- */
-#include <stdlib.h>
-
-#include "bundle_activator.h"
-#include "bundle_context.h"
-#include "service_registration.h"
-
-#include "calculator_impl.h"
-#include "remote_constants.h"
-
-struct activator {
- calculator_pt calculator;
- calculator_service_pt service;
-
- service_registration_pt calculatorReg;
- service_registration_pt calculatorReg2;
-};
-
-celix_status_t bundleActivator_create(bundle_context_pt context, void **userData) {
- celix_status_t status = CELIX_SUCCESS;
- struct activator *activator;
-
- activator = calloc(1, sizeof(*activator));
- if (!activator) {
- status = CELIX_ENOMEM;
- } else {
- activator->calculatorReg = NULL;
- activator->calculatorReg2 = NULL;
-
- *userData = activator;
- }
-
- return status;
-}
-
-celix_status_t bundleActivator_start(void * userData, bundle_context_pt context) {
- celix_status_t status = CELIX_SUCCESS;
- struct activator *activator = userData;
- properties_pt properties = NULL;
-
- status = calculator_create(&activator->calculator);
- if (status == CELIX_SUCCESS) {
- activator->service = calloc(1, sizeof(*activator->service));
- if (!activator->service) {
- status = CELIX_ENOMEM;
- } else {
- activator->service->calculator = activator->calculator;
- activator->service->add = calculator_add;
- activator->service->sub = calculator_sub;
- activator->service->sqrt = calculator_sqrt;
-
- properties = properties_create();
- properties_set(properties, (char *) OSGI_RSA_SERVICE_EXPORTED_INTERFACES, (char *) CALCULATOR_SERVICE);
-
- bundleContext_registerService(context, (char *) CALCULATOR_SERVICE, activator->service, properties, &activator->calculatorReg);
-
- properties_pt properties2 = properties_create();
- properties_set(properties2, (char *) OSGI_RSA_SERVICE_EXPORTED_INTERFACES, (char *) CALCULATOR2_SERVICE);
- bundleContext_registerService(context, CALCULATOR2_SERVICE, activator->service, properties2, &activator->calculatorReg2);
- }
- }
-
- return status;
-}
-
-celix_status_t bundleActivator_stop(void * userData, bundle_context_pt context) {
- celix_status_t status = CELIX_SUCCESS;
- struct activator *activator = userData;
-
- serviceRegistration_unregister(activator->calculatorReg);
- serviceRegistration_unregister(activator->calculatorReg2);
-
- free(activator->service);
-
- calculator_destroy(&activator->calculator);
-
- return status;
-}
-
-celix_status_t bundleActivator_destroy(void * userData, bundle_context_pt context) {
- celix_status_t status = CELIX_SUCCESS;
-
- free(userData);
-
- return status;
-}
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/examples/calculator_service/private/src/calculator_impl.c
----------------------------------------------------------------------
diff --git a/remote_services/examples/calculator_service/private/src/calculator_impl.c b/remote_services/examples/calculator_service/private/src/calculator_impl.c
deleted file mode 100644
index adccb52..0000000
--- a/remote_services/examples/calculator_service/private/src/calculator_impl.c
+++ /dev/null
@@ -1,79 +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.
- */
-/*
- * calculator_impl.c
- *
- * \date Oct 5, 2011
- * \author <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- * \copyright Apache License, Version 2.0
- */
-#include <math.h>
-
-#include <stdlib.h>
-#include <stdio.h>
-
-#include "calculator_impl.h"
-
-celix_status_t calculator_create(calculator_pt *calculator) {
- celix_status_t status = CELIX_SUCCESS;
-
- *calculator = calloc(1, sizeof(**calculator));
- if (!*calculator) {
- status = CELIX_ENOMEM;
- }
-
- return status;
-}
-
-celix_status_t calculator_destroy(calculator_pt *calculator) {
- free(*calculator);
- return CELIX_SUCCESS;
-}
-
-celix_status_t calculator_add(calculator_pt calculator, double a, double b, double *result) {
- celix_status_t status = CELIX_SUCCESS;
-
- *result = a + b;
- printf("CALCULATOR: Add: %f + %f = %f\n", a, b, *result);
-
- return status;
-}
-
-celix_status_t calculator_sub(calculator_pt calculator, double a, double b, double *result) {
- celix_status_t status = CELIX_SUCCESS;
-
- *result = a - b;
- printf("CALCULATOR: Sub: %f + %f = %f\n", a, b, *result);
-
- return status;
-}
-
-celix_status_t calculator_sqrt(calculator_pt calculator, double a, double *result) {
- celix_status_t status = CELIX_SUCCESS;
-
- if (a > 0) {
- *result = sqrt(a);
- printf("CALCULATOR: Sqrt: %f = %f\n", a, *result);
- } else {
- printf("CALCULATOR: Sqrt: %f = ERR\n", a);
- status = CELIX_ILLEGAL_ARGUMENT;
- }
-
- return status;
-}
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/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
deleted file mode 100644
index 8e2f0dc..0000000
--- a/remote_services/examples/calculator_service/public/include/calculator_service.h
+++ /dev/null
@@ -1,56 +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.
- */
-/*
- * calculator_service.h
- *
- * \date Oct 5, 2011
- * \author <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- * \copyright Apache License, Version 2.0
- */
-
-#ifndef CALCULATOR_SERVICE_H_
-#define CALCULATOR_SERVICE_H_
-
-#define CALCULATOR_SERVICE "org.apache.celix.calc.api.Calculator"
-#define CALCULATOR2_SERVICE "org.apache.celix.calc.api.Calculator2"
-
-
-typedef struct calculator *calculator_pt;
-
-typedef struct calculator_service *calculator_service_pt;
-
-/*
- * The calculator service definition corresponds to the following Java interface:
- *
- * interface Calculator {
- * double add(double a, double b);
- * double sub(double a, double b);
- * double sqrt(double a);
- * }
- */
-struct calculator_service {
- calculator_pt calculator;
- int (*add)(calculator_pt calculator, double a, double b, double *result);
- int (*sub)(calculator_pt calculator, double a, double b, double *result);
- int (*sqrt)(calculator_pt calculator, double a, double *result);
-};
-
-
-
-#endif /* CALCULATOR_SERVICE_H_ */
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/examples/calculator_service/public/include/org.apache.celix.calc.api.Calculator2.descriptor
----------------------------------------------------------------------
diff --git a/remote_services/examples/calculator_service/public/include/org.apache.celix.calc.api.Calculator2.descriptor b/remote_services/examples/calculator_service/public/include/org.apache.celix.calc.api.Calculator2.descriptor
deleted file mode 100644
index b784838..0000000
--- a/remote_services/examples/calculator_service/public/include/org.apache.celix.calc.api.Calculator2.descriptor
+++ /dev/null
@@ -1,11 +0,0 @@
-:header
-type=interface
-name=calculator
-version=1.3.0
-:annotations
-classname=org.example.Calculator
-:types
-:methods
-add(DD)D=add(#am=handle;PDD#am=pre;*D)N
-sub(DD)D=sub(#am=handle;PDD#am=pre;*D)N
-sqrt(D)D=sqrt(#am=handle;PD#am=pre;*D)N
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/examples/calculator_service/src/calculator_activator.c
----------------------------------------------------------------------
diff --git a/remote_services/examples/calculator_service/src/calculator_activator.c b/remote_services/examples/calculator_service/src/calculator_activator.c
new file mode 100644
index 0000000..688a7b0
--- /dev/null
+++ b/remote_services/examples/calculator_service/src/calculator_activator.c
@@ -0,0 +1,110 @@
+/**
+ *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.
+ */
+/*
+ * calculator_activator.c
+ *
+ * \date Oct 5, 2011
+ * \author <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ * \copyright Apache License, Version 2.0
+ */
+#include <stdlib.h>
+
+#include "bundle_activator.h"
+#include "bundle_context.h"
+#include "service_registration.h"
+
+#include "calculator_impl.h"
+#include "remote_constants.h"
+
+struct activator {
+ calculator_pt calculator;
+ calculator_service_pt service;
+
+ service_registration_pt calculatorReg;
+ service_registration_pt calculatorReg2;
+};
+
+celix_status_t bundleActivator_create(bundle_context_pt context, void **userData) {
+ celix_status_t status = CELIX_SUCCESS;
+ struct activator *activator;
+
+ activator = calloc(1, sizeof(*activator));
+ if (!activator) {
+ status = CELIX_ENOMEM;
+ } else {
+ activator->calculatorReg = NULL;
+ activator->calculatorReg2 = NULL;
+
+ *userData = activator;
+ }
+
+ return status;
+}
+
+celix_status_t bundleActivator_start(void * userData, bundle_context_pt context) {
+ celix_status_t status = CELIX_SUCCESS;
+ struct activator *activator = userData;
+ properties_pt properties = NULL;
+
+ status = calculator_create(&activator->calculator);
+ if (status == CELIX_SUCCESS) {
+ activator->service = calloc(1, sizeof(*activator->service));
+ if (!activator->service) {
+ status = CELIX_ENOMEM;
+ } else {
+ activator->service->calculator = activator->calculator;
+ activator->service->add = calculator_add;
+ activator->service->sub = calculator_sub;
+ activator->service->sqrt = calculator_sqrt;
+
+ properties = properties_create();
+ properties_set(properties, (char *) OSGI_RSA_SERVICE_EXPORTED_INTERFACES, (char *) CALCULATOR_SERVICE);
+
+ bundleContext_registerService(context, (char *) CALCULATOR_SERVICE, activator->service, properties, &activator->calculatorReg);
+
+ properties_pt properties2 = properties_create();
+ properties_set(properties2, (char *) OSGI_RSA_SERVICE_EXPORTED_INTERFACES, (char *) CALCULATOR2_SERVICE);
+ bundleContext_registerService(context, CALCULATOR2_SERVICE, activator->service, properties2, &activator->calculatorReg2);
+ }
+ }
+
+ return status;
+}
+
+celix_status_t bundleActivator_stop(void * userData, bundle_context_pt context) {
+ celix_status_t status = CELIX_SUCCESS;
+ struct activator *activator = userData;
+
+ serviceRegistration_unregister(activator->calculatorReg);
+ serviceRegistration_unregister(activator->calculatorReg2);
+
+ free(activator->service);
+
+ calculator_destroy(&activator->calculator);
+
+ return status;
+}
+
+celix_status_t bundleActivator_destroy(void * userData, bundle_context_pt context) {
+ celix_status_t status = CELIX_SUCCESS;
+
+ free(userData);
+
+ return status;
+}
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/examples/calculator_service/src/calculator_impl.c
----------------------------------------------------------------------
diff --git a/remote_services/examples/calculator_service/src/calculator_impl.c b/remote_services/examples/calculator_service/src/calculator_impl.c
new file mode 100644
index 0000000..adccb52
--- /dev/null
+++ b/remote_services/examples/calculator_service/src/calculator_impl.c
@@ -0,0 +1,79 @@
+/**
+ *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.
+ */
+/*
+ * calculator_impl.c
+ *
+ * \date Oct 5, 2011
+ * \author <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ * \copyright Apache License, Version 2.0
+ */
+#include <math.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "calculator_impl.h"
+
+celix_status_t calculator_create(calculator_pt *calculator) {
+ celix_status_t status = CELIX_SUCCESS;
+
+ *calculator = calloc(1, sizeof(**calculator));
+ if (!*calculator) {
+ status = CELIX_ENOMEM;
+ }
+
+ return status;
+}
+
+celix_status_t calculator_destroy(calculator_pt *calculator) {
+ free(*calculator);
+ return CELIX_SUCCESS;
+}
+
+celix_status_t calculator_add(calculator_pt calculator, double a, double b, double *result) {
+ celix_status_t status = CELIX_SUCCESS;
+
+ *result = a + b;
+ printf("CALCULATOR: Add: %f + %f = %f\n", a, b, *result);
+
+ return status;
+}
+
+celix_status_t calculator_sub(calculator_pt calculator, double a, double b, double *result) {
+ celix_status_t status = CELIX_SUCCESS;
+
+ *result = a - b;
+ printf("CALCULATOR: Sub: %f + %f = %f\n", a, b, *result);
+
+ return status;
+}
+
+celix_status_t calculator_sqrt(calculator_pt calculator, double a, double *result) {
+ celix_status_t status = CELIX_SUCCESS;
+
+ if (a > 0) {
+ *result = sqrt(a);
+ printf("CALCULATOR: Sqrt: %f = %f\n", a, *result);
+ } else {
+ printf("CALCULATOR: Sqrt: %f = ERR\n", a);
+ status = CELIX_ILLEGAL_ARGUMENT;
+ }
+
+ return status;
+}
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/examples/calculator_service/src/calculator_impl.h
----------------------------------------------------------------------
diff --git a/remote_services/examples/calculator_service/src/calculator_impl.h b/remote_services/examples/calculator_service/src/calculator_impl.h
new file mode 100644
index 0000000..5e075e4
--- /dev/null
+++ b/remote_services/examples/calculator_service/src/calculator_impl.h
@@ -0,0 +1,43 @@
+/**
+ *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.
+ */
+/*
+ * calculator_impl.h
+ *
+ * \date Oct 5, 2011
+ * \author <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ * \copyright Apache License, Version 2.0
+ */
+
+#ifndef CALCULATOR_IMPL_H_
+#define CALCULATOR_IMPL_H_
+
+#include "celix_errno.h"
+
+#include "calculator_service.h"
+
+struct calculator {
+};
+
+celix_status_t calculator_create(calculator_pt *calcuator);
+celix_status_t calculator_destroy(calculator_pt *calcuator);
+celix_status_t calculator_add(calculator_pt calcuator, double a, double b, double *result);
+celix_status_t calculator_sub(calculator_pt calcuator, double a, double b, double *result);
+celix_status_t calculator_sqrt(calculator_pt calcuator, double a, double *result);
+
+#endif /* CALCULATOR_IMPL_H_ */
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/examples/calculator_shell/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/remote_services/examples/calculator_shell/CMakeLists.txt b/remote_services/examples/calculator_shell/CMakeLists.txt
index 980fa1a..78c0737 100644
--- a/remote_services/examples/calculator_shell/CMakeLists.txt
+++ b/remote_services/examples/calculator_shell/CMakeLists.txt
@@ -15,28 +15,22 @@
# specific language governing permissions and limitations
# under the License.
-include_directories("private/include")
-include_directories("../../../utils/public/include")
-include_directories("../calculator_service/public/include")
-
-add_bundle(calculator_shell SOURCES
- private/src/add_command
- private/src/sub_command
- private/src/sqrt_command
- private/src/calculator_shell_activator
-
- private/include/add_command.h
- private/include/sqrt_command.h
- private/include/sub_command.h
-
+add_bundle(calculator_shell
+ SOURCES
+ src/add_command
+ src/sub_command
+ src/sqrt_command
+ src/calculator_shell_activator
VERSION 0.0.1
SYMBOLIC_NAME "apache_celix_remoting_calculator_shell"
)
+target_include_directories(calculator_shell PRIVATE src)
+target_link_libraries(calculator_shell PRIVATE Celix::shell_api calculator_api)
bundle_files(calculator_shell
- ../calculator_service/public/include/org.apache.celix.calc.api.Calculator2.descriptor
- #private/include/org.apache.celix.calc.api.Calculator2.descriptor ##Use this descriptor in case you want to try out versioning!
+ ../calculator_api/include/org.apache.celix.calc.api.Calculator2.descriptor
+ #src/org.apache.celix.calc.api.Calculator2.descriptor ##Use this descriptor in case you want to try out versioning!
DESTINATION .
)
-target_link_libraries(calculator_shell PRIVATE Celix::shell_api)
+
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/examples/calculator_shell/private/include/add_command.h
----------------------------------------------------------------------
diff --git a/remote_services/examples/calculator_shell/private/include/add_command.h b/remote_services/examples/calculator_shell/private/include/add_command.h
deleted file mode 100644
index 58a7bda..0000000
--- a/remote_services/examples/calculator_shell/private/include/add_command.h
+++ /dev/null
@@ -1,32 +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.
- */
-/*
- * add_command.h
- *
- * \date Oct 13, 2011
- * \author <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- * \copyright Apache License, Version 2.0
- */
-
-#ifndef ADD_COMMAND_H_
-#define ADD_COMMAND_H_
-
-void addCommand_execute(bundle_context_pt context, char *line, FILE *out, FILE *err);
-
-#endif /* ADD_COMMAND_H_ */
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/examples/calculator_shell/private/include/org.apache.celix.calc.api.Calculator2.descriptor
----------------------------------------------------------------------
diff --git a/remote_services/examples/calculator_shell/private/include/org.apache.celix.calc.api.Calculator2.descriptor b/remote_services/examples/calculator_shell/private/include/org.apache.celix.calc.api.Calculator2.descriptor
deleted file mode 100644
index 789af9a..0000000
--- a/remote_services/examples/calculator_shell/private/include/org.apache.celix.calc.api.Calculator2.descriptor
+++ /dev/null
@@ -1,11 +0,0 @@
-+:header
-+type=interface
-+name=calculator
-+version=1.2.3
-+:annotations
-+classname=org.example.Calculator
-+:types
-+:methods
-+add(DD)D=add(#am=handle;PDD#am=pre;*D)N
-+sub(DD)D=sub(#am=handle;PDD#am=pre;*D)N
-+sqrt(D)D=sqrt(#am=handle;PD#am=pre;*D)N
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/examples/calculator_shell/private/include/sqrt_command.h
----------------------------------------------------------------------
diff --git a/remote_services/examples/calculator_shell/private/include/sqrt_command.h b/remote_services/examples/calculator_shell/private/include/sqrt_command.h
deleted file mode 100644
index c9d07d2..0000000
--- a/remote_services/examples/calculator_shell/private/include/sqrt_command.h
+++ /dev/null
@@ -1,32 +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.
- */
-/*
- * sqrt_command.h
- *
- * \date Oct 13, 2011
- * \author <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- * \copyright Apache License, Version 2.0
- */
-
-#ifndef SQRT_COMMAND_H_
-#define SQRT_COMMAND_H_
-
-void sqrtCommand_execute(bundle_context_pt context, char *line, FILE *out, FILE *err);
-
-#endif /* SQRT_COMMAND_H_ */
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/examples/calculator_shell/private/include/sub_command.h
----------------------------------------------------------------------
diff --git a/remote_services/examples/calculator_shell/private/include/sub_command.h b/remote_services/examples/calculator_shell/private/include/sub_command.h
deleted file mode 100644
index cf13616..0000000
--- a/remote_services/examples/calculator_shell/private/include/sub_command.h
+++ /dev/null
@@ -1,32 +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.
- */
-/*
- * sub_command.h
- *
- * \date Oct 13, 2011
- * \author <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- * \copyright Apache License, Version 2.0
- */
-
-#ifndef SUB_COMMAND_H_
-#define SUB_COMMAND_H_
-
-void subCommand_execute(bundle_context_pt context, char *line, FILE *out, FILE *err);
-
-#endif /* SUB_COMMAND_H_ */
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/examples/calculator_shell/private/src/add_command.c
----------------------------------------------------------------------
diff --git a/remote_services/examples/calculator_shell/private/src/add_command.c b/remote_services/examples/calculator_shell/private/src/add_command.c
deleted file mode 100644
index b2520ae..0000000
--- a/remote_services/examples/calculator_shell/private/src/add_command.c
+++ /dev/null
@@ -1,101 +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.
- */
-/*
- * add_command.c
- *
- * \date Oct 13, 2011
- * \author <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- * \copyright Apache License, Version 2.0
- */
-
-#include <stdlib.h>
-#include <ctype.h>
-#include <string.h>
-#include <command.h>
-
-#include "array_list.h"
-#include "bundle_context.h"
-#include "add_command.h"
-#include "calculator_service.h"
-
-
-static celix_status_t addCommand_isNumeric(char *number, bool *ret);
-
-void addCommand_execute(bundle_context_pt context, char *line, FILE *out, FILE *err) {
- celix_status_t status = CELIX_SUCCESS;
- service_reference_pt calculatorService = NULL;
-
- status = bundleContext_getServiceReference(context, (char *) CALCULATOR_SERVICE, &calculatorService);
- if (calculatorService == NULL) {
- fprintf(err, "ADD: Cannot get reference for %s. Trying to get one for %s\n", CALCULATOR_SERVICE, CALCULATOR2_SERVICE);
- status = bundleContext_getServiceReference(context, (char *) CALCULATOR2_SERVICE, &calculatorService);
- if (calculatorService == NULL) {
- fprintf(err, "ADD: Cannot get reference even for %s.\n", CALCULATOR2_SERVICE);
- }
- }
- if (status == CELIX_SUCCESS) {
- char *token = line;
- strtok_r(line, " ", &token);
- char *aStr = strtok_r(NULL, " ", &token);
- char *bStr = strtok_r(NULL, " ", &token);
- bool aNumeric, bNumeric;
- if (aStr != NULL && bStr != NULL) {
- addCommand_isNumeric(aStr, &aNumeric);
- addCommand_isNumeric(bStr, &bNumeric);
- if(aNumeric && bNumeric){
- calculator_service_pt calculator = NULL;
- status = bundleContext_getService(context, calculatorService, (void *) &calculator);
- if (status == CELIX_SUCCESS && calculator != NULL) {
- double a = atof(aStr);
- double b = atof(bStr);
- double result = 0;
- status = calculator->add(calculator->calculator, a, b, &result);
- if (status == CELIX_SUCCESS) {
- fprintf(out, "CALCULATOR_SHELL: Add: %f + %f = %f\n", a, b, result);
- } else {
- fprintf(err, "ADD: Unexpected exception in Calc service\n");
- }
- } else {
- fprintf(err, "No calc service available\n");
- }
- } else {
- fprintf(err, "ADD: Requires 2 numerical parameter\n");
- }
- } else {
- fprintf(err, "ADD: Requires 2 numerical parameter\n");
- }
- } else {
- fprintf(err, "No calc service available\n");
- }
-
- //return status;
-}
-
-static celix_status_t addCommand_isNumeric(char *number, bool *ret) {
- celix_status_t status = CELIX_SUCCESS;
- *ret = true;
- while(*number) {
- if(!isdigit(*number) && *number != '.') {
- *ret = false;
- break;
- }
- number++;
- }
- return status;
-}
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/examples/calculator_shell/private/src/calculator_shell_activator.c
----------------------------------------------------------------------
diff --git a/remote_services/examples/calculator_shell/private/src/calculator_shell_activator.c b/remote_services/examples/calculator_shell/private/src/calculator_shell_activator.c
deleted file mode 100644
index d6b561b..0000000
--- a/remote_services/examples/calculator_shell/private/src/calculator_shell_activator.c
+++ /dev/null
@@ -1,125 +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.
- */
-/*
- * calculator_shell_activator.c
- *
- * \date Oct 13, 2011
- * \author <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- * \copyright Apache License, Version 2.0
- */
-#include <stdlib.h>
-#include <string.h>
-#include <command.h>
-
-#include "bundle_activator.h"
-#include "bundle_context.h"
-#include "service_registration.h"
-
-#include "add_command.h"
-#include "sub_command.h"
-#include "sqrt_command.h"
-
-struct activator {
- service_registration_pt addCommand;
- command_service_pt addCmd;
- command_service_pt addCmdSrv;
-
- service_registration_pt subCommand;
- command_service_pt subCmd;
- command_service_pt subCmdSrv;
-
- service_registration_pt sqrtCommand;
- command_service_pt sqrtCmd;
- command_service_pt sqrtCmdSrv;
-};
-
-celix_status_t bundleActivator_create(bundle_context_pt context, void **userData) {
- celix_status_t status = CELIX_SUCCESS;
- if (status == CELIX_SUCCESS) {
- *userData = calloc(1, sizeof(struct activator));
- if (!*userData) {
- status = CELIX_ENOMEM;
- } else {
- ((struct activator *) (*userData))->addCommand = NULL;
- ((struct activator *) (*userData))->subCommand = NULL;
- ((struct activator *) (*userData))->sqrtCommand = NULL;
-
- ((struct activator *) (*userData))->addCmd = NULL;
- ((struct activator *) (*userData))->subCmd = NULL;
- ((struct activator *) (*userData))->sqrtCmd = NULL;
-
- ((struct activator *) (*userData))->addCmdSrv = NULL;
- ((struct activator *) (*userData))->subCmdSrv = NULL;
- ((struct activator *) (*userData))->sqrtCmdSrv = NULL;
- }
- }
-
- return CELIX_SUCCESS;
-}
-
-celix_status_t bundleActivator_start(void * userData, bundle_context_pt context) {
- celix_status_t status = CELIX_SUCCESS;
-
- struct activator * activator = (struct activator *) userData;
-
- activator->addCmdSrv = calloc(1, sizeof(*activator->addCmdSrv));
- activator->addCmdSrv->handle = context;
- activator->addCmdSrv->executeCommand = (void *)addCommand_execute;
- properties_pt props = properties_create();
- properties_set(props, OSGI_SHELL_COMMAND_NAME, "add");
- bundleContext_registerService(context, (char *)OSGI_SHELL_COMMAND_SERVICE_NAME, activator->addCmdSrv, props, &activator->addCommand);
-
-
- activator->sqrtCmdSrv = calloc(1, sizeof(*activator->sqrtCmdSrv));
- activator->sqrtCmdSrv->handle = context;
- activator->sqrtCmdSrv->executeCommand = (void *)sqrtCommand_execute;
- props = properties_create();
- properties_set(props, OSGI_SHELL_COMMAND_NAME, "sqrt");
- bundleContext_registerService(context, (char *)OSGI_SHELL_COMMAND_SERVICE_NAME, activator->sqrtCmdSrv, props, &activator->sqrtCommand);
-
- activator->subCmdSrv = calloc(1, sizeof(*activator->subCmdSrv));
- activator->subCmdSrv->handle = context;
- activator->subCmdSrv->executeCommand = (void *)subCommand_execute;
- props = properties_create();
- properties_set(props, OSGI_SHELL_COMMAND_NAME, "sub");
- bundleContext_registerService(context, (char *)OSGI_SHELL_COMMAND_SERVICE_NAME, activator->subCmdSrv, props, &activator->subCommand);
-
- return status;
-}
-
-
-celix_status_t bundleActivator_stop(void * userData, bundle_context_pt context) {
- celix_status_t status = CELIX_SUCCESS;
- struct activator * activator = (struct activator *) userData;
- serviceRegistration_unregister(activator->addCommand);
- serviceRegistration_unregister(activator->subCommand);
- serviceRegistration_unregister(activator->sqrtCommand);
-
- free(activator->addCmdSrv);
- free(activator->subCmdSrv);
- free(activator->sqrtCmdSrv);
-
- return status;
-}
-
-celix_status_t bundleActivator_destroy(void * userData, bundle_context_pt context) {
- free(userData);
- return CELIX_SUCCESS;
-}
-
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/examples/calculator_shell/private/src/sqrt_command.c
----------------------------------------------------------------------
diff --git a/remote_services/examples/calculator_shell/private/src/sqrt_command.c b/remote_services/examples/calculator_shell/private/src/sqrt_command.c
deleted file mode 100644
index 2e7238c..0000000
--- a/remote_services/examples/calculator_shell/private/src/sqrt_command.c
+++ /dev/null
@@ -1,96 +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.
- */
-/*
- * sqrt_command.c
- *
- * \date Oct 13, 2011
- * \author <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- * \copyright Apache License, Version 2.0
- */
-
-#include <stdlib.h>
-#include <ctype.h>
-#include <string.h>
-
-#include "array_list.h"
-#include "bundle_context.h"
-#include "sqrt_command.h"
-#include "calculator_service.h"
-
-static celix_status_t sqrtCommand_isNumeric(char *number, bool *ret);
-
-void sqrtCommand_execute(bundle_context_pt context, char *line, FILE *out, FILE *err) {
- celix_status_t status = CELIX_SUCCESS;
- service_reference_pt calculatorService = NULL;
-
- status = bundleContext_getServiceReference(context, (char *) CALCULATOR_SERVICE, &calculatorService);
- if (calculatorService == NULL) {
- fprintf(err, "SQRT: Cannot get reference for %s. Trying to get one for %s\n", CALCULATOR_SERVICE, CALCULATOR2_SERVICE);
- status = bundleContext_getServiceReference(context, (char *) CALCULATOR2_SERVICE, &calculatorService);
- if (calculatorService == NULL) {
- fprintf(err, "SQRT: Cannot get reference even for %s.\n", CALCULATOR2_SERVICE);
- }
- }
- if (status == CELIX_SUCCESS) {
- char *token = line;
- strtok_r(line, " ", &token);
- char *aStr = strtok_r(NULL, " ", &token);
- if(aStr != NULL){
- bool numeric;
- sqrtCommand_isNumeric(aStr, &numeric);
- if (numeric) {
- calculator_service_pt calculator = NULL;
- status = bundleContext_getService(context, calculatorService, (void *) &calculator);
- if (status == CELIX_SUCCESS && calculator != NULL) {
- double a = atof(aStr);
- double result = 0;
- status = calculator->sqrt(calculator->calculator, a, &result);
- if (status == CELIX_SUCCESS) {
- fprintf(out, "CALCULATOR_SHELL: Sqrt: %f = %f\n", a, result);
- } else {
- fprintf(err, "SQRT: Unexpected exception in Calc service\n");
- }
- } else {
- fprintf(err, "No calc service available\n");
- }
- } else {
- fprintf(err, "SQRT: Requires 1 numerical parameter\n");
- }
- } else {
- fprintf(err, "SQRT: Requires 1 numerical parameter\n");
- }
- } else {
- fprintf(err, "No calc service available\n");
- }
-
- //return status;
-}
-
-static celix_status_t sqrtCommand_isNumeric(char *number, bool *ret) {
- celix_status_t status = CELIX_SUCCESS;
- *ret = true;
- while(*number) {
- if(!isdigit(*number) && *number != '.') {
- *ret = false;
- break;
- }
- number++;
- }
- return status;
-}
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/examples/calculator_shell/private/src/sub_command.c
----------------------------------------------------------------------
diff --git a/remote_services/examples/calculator_shell/private/src/sub_command.c b/remote_services/examples/calculator_shell/private/src/sub_command.c
deleted file mode 100644
index 672ea4c..0000000
--- a/remote_services/examples/calculator_shell/private/src/sub_command.c
+++ /dev/null
@@ -1,99 +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.
- */
-/*
- * sub_command.c
- *
- * \date Oct 13, 2011
- * \author <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- * \copyright Apache License, Version 2.0
- */
-
-#include <stdlib.h>
-#include <ctype.h>
-#include <string.h>
-
-#include "array_list.h"
-#include "bundle_context.h"
-#include "sub_command.h"
-#include "calculator_service.h"
-
-static celix_status_t subCommand_isNumeric(char *number, bool *ret);
-
-void subCommand_execute(bundle_context_pt context, char *line, FILE *out, FILE *err) {
- celix_status_t status = CELIX_SUCCESS;
- service_reference_pt calculatorService = NULL;
-
- status = bundleContext_getServiceReference(context, (char *) CALCULATOR_SERVICE, &calculatorService);
- if (calculatorService == NULL) {
- fprintf(err, "SUB: Cannot get reference for %s. Trying to get one for %s\n", CALCULATOR_SERVICE, CALCULATOR2_SERVICE);
- status = bundleContext_getServiceReference(context, (char *) CALCULATOR2_SERVICE, &calculatorService);
- if (calculatorService == NULL) {
- fprintf(err, "SUB: Cannot get reference even for %s.\n", CALCULATOR2_SERVICE);
- }
- }
- if (status == CELIX_SUCCESS) {
- char *token = line;
- strtok_r(line, " ", &token);
- char *aStr = strtok_r(NULL, " ", &token);
- char *bStr = strtok_r(NULL, " ", &token);
- if(aStr != NULL && bStr != NULL ){
- bool aNumeric, bNumeric;
- subCommand_isNumeric(aStr, &aNumeric);
- subCommand_isNumeric(bStr, &bNumeric);
- if (aNumeric && bNumeric) {
- calculator_service_pt calculator = NULL;
- status = bundleContext_getService(context, calculatorService, (void *) &calculator);
- if (status == CELIX_SUCCESS && calculator != NULL) {
- double a = atof(aStr);
- double b = atof(bStr);
- double result = 0;
- status = calculator->sub(calculator->calculator, a, b, &result);
- if (status == CELIX_SUCCESS) {
- fprintf(out, "CALCULATOR_SHELL: Sub: %f - %f = %f\n", a, b, result);
- } else {
- fprintf(err, "SUB: Unexpected exception in Calc service\n");
- }
- } else {
- fprintf(err, "No calc service available\n");
- }
- } else {
- fprintf(err, "SUB: Requires 2 numerical parameter\n");
- }
- } else {
- fprintf(err, "SUB: Requires 2 numerical parameter\n");
- }
- } else {
- fprintf(err, "No calc service available\n");
- }
-
- //return status;
-}
-
-static celix_status_t subCommand_isNumeric(char *number, bool *ret) {
- celix_status_t status = CELIX_SUCCESS;
- *ret = true;
- while(*number) {
- if(!isdigit(*number) && *number != '.') {
- *ret = false;
- break;
- }
- number++;
- }
- return status;
-}
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/examples/calculator_shell/src/add_command.c
----------------------------------------------------------------------
diff --git a/remote_services/examples/calculator_shell/src/add_command.c b/remote_services/examples/calculator_shell/src/add_command.c
new file mode 100644
index 0000000..b2520ae
--- /dev/null
+++ b/remote_services/examples/calculator_shell/src/add_command.c
@@ -0,0 +1,101 @@
+/**
+ *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.
+ */
+/*
+ * add_command.c
+ *
+ * \date Oct 13, 2011
+ * \author <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ * \copyright Apache License, Version 2.0
+ */
+
+#include <stdlib.h>
+#include <ctype.h>
+#include <string.h>
+#include <command.h>
+
+#include "array_list.h"
+#include "bundle_context.h"
+#include "add_command.h"
+#include "calculator_service.h"
+
+
+static celix_status_t addCommand_isNumeric(char *number, bool *ret);
+
+void addCommand_execute(bundle_context_pt context, char *line, FILE *out, FILE *err) {
+ celix_status_t status = CELIX_SUCCESS;
+ service_reference_pt calculatorService = NULL;
+
+ status = bundleContext_getServiceReference(context, (char *) CALCULATOR_SERVICE, &calculatorService);
+ if (calculatorService == NULL) {
+ fprintf(err, "ADD: Cannot get reference for %s. Trying to get one for %s\n", CALCULATOR_SERVICE, CALCULATOR2_SERVICE);
+ status = bundleContext_getServiceReference(context, (char *) CALCULATOR2_SERVICE, &calculatorService);
+ if (calculatorService == NULL) {
+ fprintf(err, "ADD: Cannot get reference even for %s.\n", CALCULATOR2_SERVICE);
+ }
+ }
+ if (status == CELIX_SUCCESS) {
+ char *token = line;
+ strtok_r(line, " ", &token);
+ char *aStr = strtok_r(NULL, " ", &token);
+ char *bStr = strtok_r(NULL, " ", &token);
+ bool aNumeric, bNumeric;
+ if (aStr != NULL && bStr != NULL) {
+ addCommand_isNumeric(aStr, &aNumeric);
+ addCommand_isNumeric(bStr, &bNumeric);
+ if(aNumeric && bNumeric){
+ calculator_service_pt calculator = NULL;
+ status = bundleContext_getService(context, calculatorService, (void *) &calculator);
+ if (status == CELIX_SUCCESS && calculator != NULL) {
+ double a = atof(aStr);
+ double b = atof(bStr);
+ double result = 0;
+ status = calculator->add(calculator->calculator, a, b, &result);
+ if (status == CELIX_SUCCESS) {
+ fprintf(out, "CALCULATOR_SHELL: Add: %f + %f = %f\n", a, b, result);
+ } else {
+ fprintf(err, "ADD: Unexpected exception in Calc service\n");
+ }
+ } else {
+ fprintf(err, "No calc service available\n");
+ }
+ } else {
+ fprintf(err, "ADD: Requires 2 numerical parameter\n");
+ }
+ } else {
+ fprintf(err, "ADD: Requires 2 numerical parameter\n");
+ }
+ } else {
+ fprintf(err, "No calc service available\n");
+ }
+
+ //return status;
+}
+
+static celix_status_t addCommand_isNumeric(char *number, bool *ret) {
+ celix_status_t status = CELIX_SUCCESS;
+ *ret = true;
+ while(*number) {
+ if(!isdigit(*number) && *number != '.') {
+ *ret = false;
+ break;
+ }
+ number++;
+ }
+ return status;
+}
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/examples/calculator_shell/src/add_command.h
----------------------------------------------------------------------
diff --git a/remote_services/examples/calculator_shell/src/add_command.h b/remote_services/examples/calculator_shell/src/add_command.h
new file mode 100644
index 0000000..58a7bda
--- /dev/null
+++ b/remote_services/examples/calculator_shell/src/add_command.h
@@ -0,0 +1,32 @@
+/**
+ *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.
+ */
+/*
+ * add_command.h
+ *
+ * \date Oct 13, 2011
+ * \author <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ * \copyright Apache License, Version 2.0
+ */
+
+#ifndef ADD_COMMAND_H_
+#define ADD_COMMAND_H_
+
+void addCommand_execute(bundle_context_pt context, char *line, FILE *out, FILE *err);
+
+#endif /* ADD_COMMAND_H_ */
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/examples/calculator_shell/src/calculator_shell_activator.c
----------------------------------------------------------------------
diff --git a/remote_services/examples/calculator_shell/src/calculator_shell_activator.c b/remote_services/examples/calculator_shell/src/calculator_shell_activator.c
new file mode 100644
index 0000000..d6b561b
--- /dev/null
+++ b/remote_services/examples/calculator_shell/src/calculator_shell_activator.c
@@ -0,0 +1,125 @@
+/**
+ *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.
+ */
+/*
+ * calculator_shell_activator.c
+ *
+ * \date Oct 13, 2011
+ * \author <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ * \copyright Apache License, Version 2.0
+ */
+#include <stdlib.h>
+#include <string.h>
+#include <command.h>
+
+#include "bundle_activator.h"
+#include "bundle_context.h"
+#include "service_registration.h"
+
+#include "add_command.h"
+#include "sub_command.h"
+#include "sqrt_command.h"
+
+struct activator {
+ service_registration_pt addCommand;
+ command_service_pt addCmd;
+ command_service_pt addCmdSrv;
+
+ service_registration_pt subCommand;
+ command_service_pt subCmd;
+ command_service_pt subCmdSrv;
+
+ service_registration_pt sqrtCommand;
+ command_service_pt sqrtCmd;
+ command_service_pt sqrtCmdSrv;
+};
+
+celix_status_t bundleActivator_create(bundle_context_pt context, void **userData) {
+ celix_status_t status = CELIX_SUCCESS;
+ if (status == CELIX_SUCCESS) {
+ *userData = calloc(1, sizeof(struct activator));
+ if (!*userData) {
+ status = CELIX_ENOMEM;
+ } else {
+ ((struct activator *) (*userData))->addCommand = NULL;
+ ((struct activator *) (*userData))->subCommand = NULL;
+ ((struct activator *) (*userData))->sqrtCommand = NULL;
+
+ ((struct activator *) (*userData))->addCmd = NULL;
+ ((struct activator *) (*userData))->subCmd = NULL;
+ ((struct activator *) (*userData))->sqrtCmd = NULL;
+
+ ((struct activator *) (*userData))->addCmdSrv = NULL;
+ ((struct activator *) (*userData))->subCmdSrv = NULL;
+ ((struct activator *) (*userData))->sqrtCmdSrv = NULL;
+ }
+ }
+
+ return CELIX_SUCCESS;
+}
+
+celix_status_t bundleActivator_start(void * userData, bundle_context_pt context) {
+ celix_status_t status = CELIX_SUCCESS;
+
+ struct activator * activator = (struct activator *) userData;
+
+ activator->addCmdSrv = calloc(1, sizeof(*activator->addCmdSrv));
+ activator->addCmdSrv->handle = context;
+ activator->addCmdSrv->executeCommand = (void *)addCommand_execute;
+ properties_pt props = properties_create();
+ properties_set(props, OSGI_SHELL_COMMAND_NAME, "add");
+ bundleContext_registerService(context, (char *)OSGI_SHELL_COMMAND_SERVICE_NAME, activator->addCmdSrv, props, &activator->addCommand);
+
+
+ activator->sqrtCmdSrv = calloc(1, sizeof(*activator->sqrtCmdSrv));
+ activator->sqrtCmdSrv->handle = context;
+ activator->sqrtCmdSrv->executeCommand = (void *)sqrtCommand_execute;
+ props = properties_create();
+ properties_set(props, OSGI_SHELL_COMMAND_NAME, "sqrt");
+ bundleContext_registerService(context, (char *)OSGI_SHELL_COMMAND_SERVICE_NAME, activator->sqrtCmdSrv, props, &activator->sqrtCommand);
+
+ activator->subCmdSrv = calloc(1, sizeof(*activator->subCmdSrv));
+ activator->subCmdSrv->handle = context;
+ activator->subCmdSrv->executeCommand = (void *)subCommand_execute;
+ props = properties_create();
+ properties_set(props, OSGI_SHELL_COMMAND_NAME, "sub");
+ bundleContext_registerService(context, (char *)OSGI_SHELL_COMMAND_SERVICE_NAME, activator->subCmdSrv, props, &activator->subCommand);
+
+ return status;
+}
+
+
+celix_status_t bundleActivator_stop(void * userData, bundle_context_pt context) {
+ celix_status_t status = CELIX_SUCCESS;
+ struct activator * activator = (struct activator *) userData;
+ serviceRegistration_unregister(activator->addCommand);
+ serviceRegistration_unregister(activator->subCommand);
+ serviceRegistration_unregister(activator->sqrtCommand);
+
+ free(activator->addCmdSrv);
+ free(activator->subCmdSrv);
+ free(activator->sqrtCmdSrv);
+
+ return status;
+}
+
+celix_status_t bundleActivator_destroy(void * userData, bundle_context_pt context) {
+ free(userData);
+ return CELIX_SUCCESS;
+}
+
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/examples/calculator_shell/src/org.apache.celix.calc.api.Calculator2.descriptor
----------------------------------------------------------------------
diff --git a/remote_services/examples/calculator_shell/src/org.apache.celix.calc.api.Calculator2.descriptor b/remote_services/examples/calculator_shell/src/org.apache.celix.calc.api.Calculator2.descriptor
new file mode 100644
index 0000000..789af9a
--- /dev/null
+++ b/remote_services/examples/calculator_shell/src/org.apache.celix.calc.api.Calculator2.descriptor
@@ -0,0 +1,11 @@
++:header
++type=interface
++name=calculator
++version=1.2.3
++:annotations
++classname=org.example.Calculator
++:types
++:methods
++add(DD)D=add(#am=handle;PDD#am=pre;*D)N
++sub(DD)D=sub(#am=handle;PDD#am=pre;*D)N
++sqrt(D)D=sqrt(#am=handle;PD#am=pre;*D)N
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/examples/calculator_shell/src/sqrt_command.c
----------------------------------------------------------------------
diff --git a/remote_services/examples/calculator_shell/src/sqrt_command.c b/remote_services/examples/calculator_shell/src/sqrt_command.c
new file mode 100644
index 0000000..2e7238c
--- /dev/null
+++ b/remote_services/examples/calculator_shell/src/sqrt_command.c
@@ -0,0 +1,96 @@
+/**
+ *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.
+ */
+/*
+ * sqrt_command.c
+ *
+ * \date Oct 13, 2011
+ * \author <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ * \copyright Apache License, Version 2.0
+ */
+
+#include <stdlib.h>
+#include <ctype.h>
+#include <string.h>
+
+#include "array_list.h"
+#include "bundle_context.h"
+#include "sqrt_command.h"
+#include "calculator_service.h"
+
+static celix_status_t sqrtCommand_isNumeric(char *number, bool *ret);
+
+void sqrtCommand_execute(bundle_context_pt context, char *line, FILE *out, FILE *err) {
+ celix_status_t status = CELIX_SUCCESS;
+ service_reference_pt calculatorService = NULL;
+
+ status = bundleContext_getServiceReference(context, (char *) CALCULATOR_SERVICE, &calculatorService);
+ if (calculatorService == NULL) {
+ fprintf(err, "SQRT: Cannot get reference for %s. Trying to get one for %s\n", CALCULATOR_SERVICE, CALCULATOR2_SERVICE);
+ status = bundleContext_getServiceReference(context, (char *) CALCULATOR2_SERVICE, &calculatorService);
+ if (calculatorService == NULL) {
+ fprintf(err, "SQRT: Cannot get reference even for %s.\n", CALCULATOR2_SERVICE);
+ }
+ }
+ if (status == CELIX_SUCCESS) {
+ char *token = line;
+ strtok_r(line, " ", &token);
+ char *aStr = strtok_r(NULL, " ", &token);
+ if(aStr != NULL){
+ bool numeric;
+ sqrtCommand_isNumeric(aStr, &numeric);
+ if (numeric) {
+ calculator_service_pt calculator = NULL;
+ status = bundleContext_getService(context, calculatorService, (void *) &calculator);
+ if (status == CELIX_SUCCESS && calculator != NULL) {
+ double a = atof(aStr);
+ double result = 0;
+ status = calculator->sqrt(calculator->calculator, a, &result);
+ if (status == CELIX_SUCCESS) {
+ fprintf(out, "CALCULATOR_SHELL: Sqrt: %f = %f\n", a, result);
+ } else {
+ fprintf(err, "SQRT: Unexpected exception in Calc service\n");
+ }
+ } else {
+ fprintf(err, "No calc service available\n");
+ }
+ } else {
+ fprintf(err, "SQRT: Requires 1 numerical parameter\n");
+ }
+ } else {
+ fprintf(err, "SQRT: Requires 1 numerical parameter\n");
+ }
+ } else {
+ fprintf(err, "No calc service available\n");
+ }
+
+ //return status;
+}
+
+static celix_status_t sqrtCommand_isNumeric(char *number, bool *ret) {
+ celix_status_t status = CELIX_SUCCESS;
+ *ret = true;
+ while(*number) {
+ if(!isdigit(*number) && *number != '.') {
+ *ret = false;
+ break;
+ }
+ number++;
+ }
+ return status;
+}
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/examples/calculator_shell/src/sqrt_command.h
----------------------------------------------------------------------
diff --git a/remote_services/examples/calculator_shell/src/sqrt_command.h b/remote_services/examples/calculator_shell/src/sqrt_command.h
new file mode 100644
index 0000000..c9d07d2
--- /dev/null
+++ b/remote_services/examples/calculator_shell/src/sqrt_command.h
@@ -0,0 +1,32 @@
+/**
+ *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.
+ */
+/*
+ * sqrt_command.h
+ *
+ * \date Oct 13, 2011
+ * \author <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ * \copyright Apache License, Version 2.0
+ */
+
+#ifndef SQRT_COMMAND_H_
+#define SQRT_COMMAND_H_
+
+void sqrtCommand_execute(bundle_context_pt context, char *line, FILE *out, FILE *err);
+
+#endif /* SQRT_COMMAND_H_ */
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/examples/calculator_shell/src/sub_command.c
----------------------------------------------------------------------
diff --git a/remote_services/examples/calculator_shell/src/sub_command.c b/remote_services/examples/calculator_shell/src/sub_command.c
new file mode 100644
index 0000000..672ea4c
--- /dev/null
+++ b/remote_services/examples/calculator_shell/src/sub_command.c
@@ -0,0 +1,99 @@
+/**
+ *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.
+ */
+/*
+ * sub_command.c
+ *
+ * \date Oct 13, 2011
+ * \author <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ * \copyright Apache License, Version 2.0
+ */
+
+#include <stdlib.h>
+#include <ctype.h>
+#include <string.h>
+
+#include "array_list.h"
+#include "bundle_context.h"
+#include "sub_command.h"
+#include "calculator_service.h"
+
+static celix_status_t subCommand_isNumeric(char *number, bool *ret);
+
+void subCommand_execute(bundle_context_pt context, char *line, FILE *out, FILE *err) {
+ celix_status_t status = CELIX_SUCCESS;
+ service_reference_pt calculatorService = NULL;
+
+ status = bundleContext_getServiceReference(context, (char *) CALCULATOR_SERVICE, &calculatorService);
+ if (calculatorService == NULL) {
+ fprintf(err, "SUB: Cannot get reference for %s. Trying to get one for %s\n", CALCULATOR_SERVICE, CALCULATOR2_SERVICE);
+ status = bundleContext_getServiceReference(context, (char *) CALCULATOR2_SERVICE, &calculatorService);
+ if (calculatorService == NULL) {
+ fprintf(err, "SUB: Cannot get reference even for %s.\n", CALCULATOR2_SERVICE);
+ }
+ }
+ if (status == CELIX_SUCCESS) {
+ char *token = line;
+ strtok_r(line, " ", &token);
+ char *aStr = strtok_r(NULL, " ", &token);
+ char *bStr = strtok_r(NULL, " ", &token);
+ if(aStr != NULL && bStr != NULL ){
+ bool aNumeric, bNumeric;
+ subCommand_isNumeric(aStr, &aNumeric);
+ subCommand_isNumeric(bStr, &bNumeric);
+ if (aNumeric && bNumeric) {
+ calculator_service_pt calculator = NULL;
+ status = bundleContext_getService(context, calculatorService, (void *) &calculator);
+ if (status == CELIX_SUCCESS && calculator != NULL) {
+ double a = atof(aStr);
+ double b = atof(bStr);
+ double result = 0;
+ status = calculator->sub(calculator->calculator, a, b, &result);
+ if (status == CELIX_SUCCESS) {
+ fprintf(out, "CALCULATOR_SHELL: Sub: %f - %f = %f\n", a, b, result);
+ } else {
+ fprintf(err, "SUB: Unexpected exception in Calc service\n");
+ }
+ } else {
+ fprintf(err, "No calc service available\n");
+ }
+ } else {
+ fprintf(err, "SUB: Requires 2 numerical parameter\n");
+ }
+ } else {
+ fprintf(err, "SUB: Requires 2 numerical parameter\n");
+ }
+ } else {
+ fprintf(err, "No calc service available\n");
+ }
+
+ //return status;
+}
+
+static celix_status_t subCommand_isNumeric(char *number, bool *ret) {
+ celix_status_t status = CELIX_SUCCESS;
+ *ret = true;
+ while(*number) {
+ if(!isdigit(*number) && *number != '.') {
+ *ret = false;
+ break;
+ }
+ number++;
+ }
+ return status;
+}
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/examples/calculator_shell/src/sub_command.h
----------------------------------------------------------------------
diff --git a/remote_services/examples/calculator_shell/src/sub_command.h b/remote_services/examples/calculator_shell/src/sub_command.h
new file mode 100644
index 0000000..cf13616
--- /dev/null
+++ b/remote_services/examples/calculator_shell/src/sub_command.h
@@ -0,0 +1,32 @@
+/**
+ *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.
+ */
+/*
+ * sub_command.h
+ *
+ * \date Oct 13, 2011
+ * \author <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ * \copyright Apache License, Version 2.0
+ */
+
+#ifndef SUB_COMMAND_H_
+#define SUB_COMMAND_H_
+
+void subCommand_execute(bundle_context_pt context, char *line, FILE *out, FILE *err);
+
+#endif /* SUB_COMMAND_H_ */
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/remote_service_admin/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin/CMakeLists.txt b/remote_services/remote_service_admin/CMakeLists.txt
deleted file mode 100644
index ac703e2..0000000
--- a/remote_services/remote_service_admin/CMakeLists.txt
+++ /dev/null
@@ -1,46 +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.
-
-install (FILES
- public/include/remote_endpoint_impl.h
- public/include/remote_endpoint.h
- public/include/remote_proxy.h
- public/include/remote_service_admin.h
- public/include/export_registration.h
- public/include/import_registration.h
- public/include/endpoint_description.h
- public/include/endpoint_listener.h
- public/include/remote_constants.h
- DESTINATION
- include/celix/remote_service_admin
- COMPONENT
- remote_service_admin
-)
-install (FILES
- private/src/remote_proxy_factory_impl.c
- DESTINATION
- share/celix/remote_service_admin
- COMPONENT
- remote_service_admin
-)
-install (FILES
- public/include/endpoint_listener.h
- DESTINATION
- include/celix/endpoint_listener
- COMPONENT
- remote_service_admin
-)
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/remote_service_admin/README.md
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin/README.md b/remote_services/remote_service_admin/README.md
deleted file mode 100644
index c4bdebd..0000000
--- a/remote_services/remote_service_admin/README.md
+++ /dev/null
@@ -1,11 +0,0 @@
-## Remote Service Admin
-
-The Remote Service Admin (RSA) provides the mechanisms to import and export services when instructed to do so by the Topology Manager.
-
-To delegate method calls to the actual service implementation, the RSA_SHM and the RSA_HTTP are using "endpoint/proxy" bundles, which has all the knowledge about the marshalling and unmarshalling of data for the service. The RSA_DFI implementation combines a [foreign function interface](https://en.wikipedia.org/wiki/Foreign_function_interface) technique together with manualy created descriptors.
-
-Note that this folder contains code commonly used by the RSA implementations and therefore does not include any CMAKE configuration.
-
-###### Properties
- ENDPOINTS defines the relative directory where endpoints and proxys can be found (default: endpoints)
- CELIX_FRAMEWORK_EXTENDER_PATH Used in RSA_DFI only. Can be used to define a path to use as an extender path point for the framework bundle. For normal bundles the bundle cache is used.
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/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
deleted file mode 100644
index bb276f9..0000000
--- a/remote_services/remote_service_admin/private/include/export_registration_impl.h
+++ /dev/null
@@ -1,61 +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.
- */
-/*
- * export_registration_impl.h
- *
- * \date Oct 6, 2011
- * \author <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- * \copyright Apache License, Version 2.0
- */
-
-#ifndef EXPORT_REGISTRATION_IMPL_H_
-#define EXPORT_REGISTRATION_IMPL_H_
-
-#include "remote_service_admin.h"
-#include "remote_endpoint.h"
-#include "service_tracker.h"
-#include "log_helper.h"
-
-struct export_registration {
- bundle_context_pt context;
- remote_service_admin_pt rsa;
- endpoint_description_pt endpointDescription;
- service_reference_pt reference;
- log_helper_pt loghelper;
-
- service_tracker_pt tracker;
- service_tracker_pt endpointTracker;
-
- remote_endpoint_service_pt endpoint;
-
- export_reference_pt exportReference;
- bundle_pt bundle;
-
- bool closed;
-};
-
-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_setEndpointDescription(export_registration_pt registration, endpoint_description_pt endpointDescription);
-celix_status_t exportRegistration_startTracking(export_registration_pt registration);
-celix_status_t exportRegistration_stopTracking(export_registration_pt registration);
-
-#endif /* EXPORT_REGISTRATION_IMPL_H_ */
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/remote_service_admin/private/include/import_registration_impl.h
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin/private/include/import_registration_impl.h b/remote_services/remote_service_admin/private/include/import_registration_impl.h
deleted file mode 100644
index 7aa397f..0000000
--- a/remote_services/remote_service_admin/private/include/import_registration_impl.h
+++ /dev/null
@@ -1,81 +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.
- */
-/*
- * import_registration_impl.h
- *
- * \date Oct 14, 2011
- * \author <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- * \copyright Apache License, Version 2.0
- */
-
-#ifndef IMPORT_REGISTRATION_IMPL_H_
-#define IMPORT_REGISTRATION_IMPL_H_
-
-#include "remote_service_admin.h"
-#include "remote_proxy.h"
-#include "service_tracker.h"
-#include "log_helper.h"
-
-struct import_registration {
- bundle_context_pt context;
- endpoint_description_pt endpointDescription;
-
- service_reference_pt reference;
- import_reference_pt importReference;
-
- remote_service_admin_pt rsa;
- sendToHandle sendToCallback;
-
- bool closed;
-};
-
-
-
-struct import_registration_factory
-{
- char* serviceName;
- log_helper_pt loghelper;
- remote_proxy_factory_service_pt trackedFactory;
- service_tracker_pt proxyFactoryTracker;
- bundle_context_pt context;
- array_list_pt registrations;
- bundle_pt bundle;
-};
-
-
-celix_status_t importRegistration_create(endpoint_description_pt endpoint, remote_service_admin_pt rsa, sendToHandle callback, bundle_context_pt context, import_registration_pt *registration);
-celix_status_t importRegistration_destroy(import_registration_pt registration);
-
-celix_status_t importRegistration_setEndpointDescription(import_registration_pt registration, endpoint_description_pt endpointDescription);
-celix_status_t importRegistration_setHandler(import_registration_pt registration, void * handler);
-celix_status_t importRegistration_setCallback(import_registration_pt registration, sendToHandle callback);
-
-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 importRegistration_createProxyFactoryTracker(import_registration_factory_pt registration_factory, service_tracker_pt *tracker);
-
-celix_status_t importRegistrationFactory_destroy(import_registration_factory_pt* registration_factory);
-//celix_status_t importRegistrationFactory_open(import_registration_factory_pt registration_factory);
-celix_status_t importRegistrationFactory_close(import_registration_factory_pt registration_factory);
-celix_status_t importRegistrationFactory_install(log_helper_pt helper, char* serviceName, bundle_context_pt context, import_registration_factory_pt *registration_factory);
-
-
-
-#endif /* IMPORT_REGISTRATION_IMPL_H_ */
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/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
deleted file mode 100644
index e8a5e1f..0000000
--- a/remote_services/remote_service_admin/private/include/remote_service_admin_impl.h
+++ /dev/null
@@ -1,49 +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.h
- *
- * \date Dec 5, 2013
- * \author <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- * \copyright Apache License, Version 2.0
- */
-
-#ifndef REMOTE_SERVICE_ADMIN_IMPL_H_
-#define REMOTE_SERVICE_ADMIN_IMPL_H_
-
-#include "remote_service_admin.h"
-
-#define BUNDLE_STORE_PROPERTY_NAME "ENDPOINTS"
-#define DEFAULT_BUNDLE_STORE "endpoints"
-
-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_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(remote_service_admin_pt admin, 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 remoteServiceAdmin_destroyEndpointDescription(endpoint_description_pt *description);
-
-#endif /* REMOTE_SERVICE_ADMIN_IMPL_H_ */
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/remote_service_admin/private/src/endpoint_description.c
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin/private/src/endpoint_description.c b/remote_services/remote_service_admin/private/src/endpoint_description.c
deleted file mode 100644
index 0d8b684..0000000
--- a/remote_services/remote_service_admin/private/src/endpoint_description.c
+++ /dev/null
@@ -1,89 +0,0 @@
-/**
- *Licensed to the Apache Software Foundation (ASF) under one
- *or more contributor license agreements. See the NOTICE file
- *distributed with this work for additional information
- *regarding copyright ownership. The ASF licenses this file
- *to you under the Apache License, Version 2.0 (the
- *"License"); you may not use this file except in compliance
- *with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- *Unless required by applicable law or agreed to in writing,
- *software distributed under the License is distributed on an
- *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- *specific language governing permissions and limitations
- *under the License.
- */
-/*
- * endpoint_description.c
- *
- * \date 25 Jul 2014
- * \author <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- * \copyright Apache License, Version 2.0
- */
-#include <stdlib.h>
-#include <string.h>
-
-#include "celix_errno.h"
-#include "celix_log.h"
-
-#include "endpoint_description.h"
-#include "remote_constants.h"
-#include "constants.h"
-
-static celix_status_t endpointDescription_verifyLongProperty(properties_pt properties, char *propertyName, unsigned long *longProperty);
-
-celix_status_t endpointDescription_create(properties_pt properties, endpoint_description_pt *endpointDescription) {
- celix_status_t status = CELIX_SUCCESS;
-
- unsigned long serviceId = 0UL;
- status = endpointDescription_verifyLongProperty(properties, (char *) OSGI_RSA_ENDPOINT_SERVICE_ID, &serviceId);
- if (status != CELIX_SUCCESS) {
- return status;
- }
-
- endpoint_description_pt ep = calloc(1,sizeof(*ep));
-
- ep->properties = properties;
- ep->frameworkUUID = (char*)properties_get(properties, OSGI_RSA_ENDPOINT_FRAMEWORK_UUID);
- ep->id = (char*)properties_get(properties, OSGI_RSA_ENDPOINT_ID);
- ep->service = strndup(properties_get(properties, OSGI_FRAMEWORK_OBJECTCLASS), 1024*10);
- ep->serviceId = serviceId;
-
- if (!(ep->frameworkUUID) || !(ep->id) || !(ep->service) ) {
- fw_log(logger, OSGI_FRAMEWORK_LOG_ERROR, "ENDPOINT_DESCRIPTION: incomplete description!.");
- status = CELIX_BUNDLE_EXCEPTION;
- }
-
- if(status == CELIX_SUCCESS){
- *endpointDescription = ep;
- }
- else{
- *endpointDescription = NULL;
- free(ep);
- }
-
- return status;
-}
-
-celix_status_t endpointDescription_destroy(endpoint_description_pt description) {
- properties_destroy(description->properties);
- free(description->service);
- free(description);
- return CELIX_SUCCESS;
-}
-
-static celix_status_t endpointDescription_verifyLongProperty(properties_pt properties, char *propertyName, unsigned long *longProperty) {
- celix_status_t status = CELIX_SUCCESS;
-
- const char *value = properties_get(properties, propertyName);
- if (value == NULL) {
- *longProperty = 0UL;
- } else {
- *longProperty = strtoul(value,NULL,10);
- }
-
- return status;
-}
[10/19] celix git commit: CELIX-417: Refactor for CMake usage in RSA,
PSA and Docker. mostly trying to identify the api and common libraries
Posted by pn...@apache.org.
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/discovery_configured/private/include/discovery_impl.h
----------------------------------------------------------------------
diff --git a/remote_services/discovery_configured/private/include/discovery_impl.h b/remote_services/discovery_configured/private/include/discovery_impl.h
deleted file mode 100644
index 0414eac..0000000
--- a/remote_services/discovery_configured/private/include/discovery_impl.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/**
- *Licensed to the Apache Software Foundation (ASF) under one
- *or more contributor license agreements. See the NOTICE file
- *distributed with this work for additional information
- *regarding copyright ownership. The ASF licenses this file
- *to you under the Apache License, Version 2.0 (the
- *"License"); you may not use this file except in compliance
- *with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- *Unless required by applicable law or agreed to in writing,
- *software distributed under the License is distributed on an
- *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- *specific language governing permissions and limitations
- *under the License.
- */
-/*
- * discovery_impl.h
- *
- * \date Sep 29, 2011
- * \author <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- * \copyright Apache License, Version 2.0
- */
-
-#ifndef DISCOVERY_IMPL_H_
-#define DISCOVERY_IMPL_H_
-
-#include "bundle_context.h"
-#include "service_reference.h"
-
-#include "endpoint_description.h"
-#include "endpoint_listener.h"
-
-#include "endpoint_discovery_poller.h"
-#include "endpoint_discovery_server.h"
-
-#include "log_helper.h"
-
-#define DEFAULT_SERVER_IP "127.0.0.1"
-#define DEFAULT_SERVER_PORT "9999"
-#define DEFAULT_SERVER_PATH "/org.apache.celix.discovery.configured"
-#define DEFAULT_POLL_ENDPOINTS "http://localhost:9999/org.apache.celix.discovery.configured"
-
-
-struct discovery {
- bundle_context_pt context;
-
- celix_thread_mutex_t listenerReferencesMutex;
- celix_thread_mutex_t discoveredServicesMutex;
-
- hash_map_pt listenerReferences; //key=serviceReference, value=nop
- hash_map_pt discoveredServices; //key=endpointId (string), value=endpoint_description_pt
-
- endpoint_discovery_poller_pt poller;
- endpoint_discovery_server_pt server;
-
- log_helper_pt loghelper;
-};
-
-#endif /* DISCOVERY_IMPL_H_ */
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/discovery_configured/private/src/desc.xml
----------------------------------------------------------------------
diff --git a/remote_services/discovery_configured/private/src/desc.xml b/remote_services/discovery_configured/private/src/desc.xml
deleted file mode 100644
index 5998992..0000000
--- a/remote_services/discovery_configured/private/src/desc.xml
+++ /dev/null
@@ -1,41 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- *Licensed to the Apache Software Foundation (ASF) under one
- *or more contributor license agreements. See the NOTICE file
- *distributed with this work for additional information
- *regarding copyright ownership. The ASF licenses this file
- *to you under the Apache License, Version 2.0 (the
- *"License"); you may not use this file except in compliance
- *with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- *Unless required by applicable law or agreed to in writing,
- *software distributed under the License is distributed on an
- *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- *specific language governing permissions and limitations
- *under the License.
- -->
-<endpoint-descriptions xmlns="http://www.osgi.org/xmlns/rsa/v1.0.0">
- <endpoint-description>
- <property name="service.intents">
- <list>
- <value>SOAP</value>
- <value>HTTP</value>
- </list>
- </property>
- <property name="endpoint.id" value="http://ws.acme.com:9000/hello" />
- <property name="objectClass" value="com.acme.Foo" />
- <property name="endpoint.package.version.com.acme" value="4.2" />
- <property name="service.imported.configs" value="com.acme" />
- <property name="com.acme.ws.xml">
- <xml>
- <config xmlns="http://acme.com/defs">
- <port>1029</port>
- <host>www.acme.com</host>
- </config>
- </xml>
- </property>
- </endpoint-description>
-</endpoint-descriptions>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/discovery_configured/private/src/discovery_impl.c
----------------------------------------------------------------------
diff --git a/remote_services/discovery_configured/private/src/discovery_impl.c b/remote_services/discovery_configured/private/src/discovery_impl.c
deleted file mode 100644
index 35a0c71..0000000
--- a/remote_services/discovery_configured/private/src/discovery_impl.c
+++ /dev/null
@@ -1,123 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-/*
- * discovery_impl.c
- *
- * \date Aug 8, 2014
- * \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 <stdbool.h>
-#include <netdb.h>
-
-#include "celix_threads.h"
-#include "bundle_context.h"
-#include "utils.h"
-#include "log_helper.h"
-
-#include "discovery.h"
-#include "discovery_impl.h"
-
-
-celix_status_t discovery_create(bundle_context_pt context, discovery_pt *discovery) {
- celix_status_t status;
-
- *discovery = malloc(sizeof(struct discovery));
- if (!*discovery) {
- status = CELIX_ENOMEM;
- }
- else {
- (*discovery)->context = context;
- (*discovery)->poller = NULL;
- (*discovery)->server = NULL;
-
- (*discovery)->listenerReferences = hashMap_create(serviceReference_hashCode, NULL, serviceReference_equals2, NULL);
- (*discovery)->discoveredServices = hashMap_create(utils_stringHash, NULL, utils_stringEquals, NULL);
-
- status = celixThreadMutex_create(&(*discovery)->listenerReferencesMutex, NULL);
- status = celixThreadMutex_create(&(*discovery)->discoveredServicesMutex, NULL);
-
- logHelper_create(context, &(*discovery)->loghelper);
- }
-
- return status;
-}
-
-celix_status_t discovery_start(discovery_pt discovery) {
- celix_status_t status;
-
- logHelper_start(discovery->loghelper);
-
- status = endpointDiscoveryPoller_create(discovery, discovery->context, &discovery->poller);
- if (status != CELIX_SUCCESS) {
- return CELIX_BUNDLE_EXCEPTION;
- }
-
- status = endpointDiscoveryServer_create(discovery, discovery->context, &discovery->server);
- if (status != CELIX_SUCCESS) {
- return CELIX_BUNDLE_EXCEPTION;
- }
-
- return status;
-}
-
-celix_status_t discovery_stop(discovery_pt discovery) {
- celix_status_t status;
-
- status = endpointDiscoveryServer_destroy(discovery->server);
- status = endpointDiscoveryPoller_destroy(discovery->poller);
-
- logHelper_stop(discovery->loghelper);
-
- return status;
-}
-
-celix_status_t discovery_destroy(discovery_pt discovery) {
- celix_status_t status = CELIX_SUCCESS;
-
- discovery->context = NULL;
- discovery->poller = NULL;
- discovery->server = NULL;
-
- celixThreadMutex_lock(&discovery->discoveredServicesMutex);
-
- hashMap_destroy(discovery->discoveredServices, false, false);
- discovery->discoveredServices = NULL;
-
- celixThreadMutex_unlock(&discovery->discoveredServicesMutex);
-
- celixThreadMutex_destroy(&discovery->discoveredServicesMutex);
-
- celixThreadMutex_lock(&discovery->listenerReferencesMutex);
-
- hashMap_destroy(discovery->listenerReferences, false, false);
- discovery->listenerReferences = NULL;
-
- celixThreadMutex_unlock(&discovery->listenerReferencesMutex);
-
- celixThreadMutex_destroy(&discovery->listenerReferencesMutex);
-
- logHelper_destroy(&discovery->loghelper);
-
- free(discovery);
-
- return status;
-}
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/discovery_configured/src/desc.xml
----------------------------------------------------------------------
diff --git a/remote_services/discovery_configured/src/desc.xml b/remote_services/discovery_configured/src/desc.xml
new file mode 100644
index 0000000..5998992
--- /dev/null
+++ b/remote_services/discovery_configured/src/desc.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ *Licensed to the Apache Software Foundation (ASF) under one
+ *or more contributor license agreements. See the NOTICE file
+ *distributed with this work for additional information
+ *regarding copyright ownership. The ASF licenses this file
+ *to you under the Apache License, Version 2.0 (the
+ *"License"); you may not use this file except in compliance
+ *with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *Unless required by applicable law or agreed to in writing,
+ *software distributed under the License is distributed on an
+ *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *specific language governing permissions and limitations
+ *under the License.
+ -->
+<endpoint-descriptions xmlns="http://www.osgi.org/xmlns/rsa/v1.0.0">
+ <endpoint-description>
+ <property name="service.intents">
+ <list>
+ <value>SOAP</value>
+ <value>HTTP</value>
+ </list>
+ </property>
+ <property name="endpoint.id" value="http://ws.acme.com:9000/hello" />
+ <property name="objectClass" value="com.acme.Foo" />
+ <property name="endpoint.package.version.com.acme" value="4.2" />
+ <property name="service.imported.configs" value="com.acme" />
+ <property name="com.acme.ws.xml">
+ <xml>
+ <config xmlns="http://acme.com/defs">
+ <port>1029</port>
+ <host>www.acme.com</host>
+ </config>
+ </xml>
+ </property>
+ </endpoint-description>
+</endpoint-descriptions>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/discovery_configured/src/discovery_impl.c
----------------------------------------------------------------------
diff --git a/remote_services/discovery_configured/src/discovery_impl.c b/remote_services/discovery_configured/src/discovery_impl.c
new file mode 100644
index 0000000..35a0c71
--- /dev/null
+++ b/remote_services/discovery_configured/src/discovery_impl.c
@@ -0,0 +1,123 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+/*
+ * discovery_impl.c
+ *
+ * \date Aug 8, 2014
+ * \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 <stdbool.h>
+#include <netdb.h>
+
+#include "celix_threads.h"
+#include "bundle_context.h"
+#include "utils.h"
+#include "log_helper.h"
+
+#include "discovery.h"
+#include "discovery_impl.h"
+
+
+celix_status_t discovery_create(bundle_context_pt context, discovery_pt *discovery) {
+ celix_status_t status;
+
+ *discovery = malloc(sizeof(struct discovery));
+ if (!*discovery) {
+ status = CELIX_ENOMEM;
+ }
+ else {
+ (*discovery)->context = context;
+ (*discovery)->poller = NULL;
+ (*discovery)->server = NULL;
+
+ (*discovery)->listenerReferences = hashMap_create(serviceReference_hashCode, NULL, serviceReference_equals2, NULL);
+ (*discovery)->discoveredServices = hashMap_create(utils_stringHash, NULL, utils_stringEquals, NULL);
+
+ status = celixThreadMutex_create(&(*discovery)->listenerReferencesMutex, NULL);
+ status = celixThreadMutex_create(&(*discovery)->discoveredServicesMutex, NULL);
+
+ logHelper_create(context, &(*discovery)->loghelper);
+ }
+
+ return status;
+}
+
+celix_status_t discovery_start(discovery_pt discovery) {
+ celix_status_t status;
+
+ logHelper_start(discovery->loghelper);
+
+ status = endpointDiscoveryPoller_create(discovery, discovery->context, &discovery->poller);
+ if (status != CELIX_SUCCESS) {
+ return CELIX_BUNDLE_EXCEPTION;
+ }
+
+ status = endpointDiscoveryServer_create(discovery, discovery->context, &discovery->server);
+ if (status != CELIX_SUCCESS) {
+ return CELIX_BUNDLE_EXCEPTION;
+ }
+
+ return status;
+}
+
+celix_status_t discovery_stop(discovery_pt discovery) {
+ celix_status_t status;
+
+ status = endpointDiscoveryServer_destroy(discovery->server);
+ status = endpointDiscoveryPoller_destroy(discovery->poller);
+
+ logHelper_stop(discovery->loghelper);
+
+ return status;
+}
+
+celix_status_t discovery_destroy(discovery_pt discovery) {
+ celix_status_t status = CELIX_SUCCESS;
+
+ discovery->context = NULL;
+ discovery->poller = NULL;
+ discovery->server = NULL;
+
+ celixThreadMutex_lock(&discovery->discoveredServicesMutex);
+
+ hashMap_destroy(discovery->discoveredServices, false, false);
+ discovery->discoveredServices = NULL;
+
+ celixThreadMutex_unlock(&discovery->discoveredServicesMutex);
+
+ celixThreadMutex_destroy(&discovery->discoveredServicesMutex);
+
+ celixThreadMutex_lock(&discovery->listenerReferencesMutex);
+
+ hashMap_destroy(discovery->listenerReferences, false, false);
+ discovery->listenerReferences = NULL;
+
+ celixThreadMutex_unlock(&discovery->listenerReferencesMutex);
+
+ celixThreadMutex_destroy(&discovery->listenerReferencesMutex);
+
+ logHelper_destroy(&discovery->loghelper);
+
+ free(discovery);
+
+ return status;
+}
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/discovery_configured/src/discovery_impl.h
----------------------------------------------------------------------
diff --git a/remote_services/discovery_configured/src/discovery_impl.h b/remote_services/discovery_configured/src/discovery_impl.h
new file mode 100644
index 0000000..0414eac
--- /dev/null
+++ b/remote_services/discovery_configured/src/discovery_impl.h
@@ -0,0 +1,62 @@
+/**
+ *Licensed to the Apache Software Foundation (ASF) under one
+ *or more contributor license agreements. See the NOTICE file
+ *distributed with this work for additional information
+ *regarding copyright ownership. The ASF licenses this file
+ *to you under the Apache License, Version 2.0 (the
+ *"License"); you may not use this file except in compliance
+ *with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *Unless required by applicable law or agreed to in writing,
+ *software distributed under the License is distributed on an
+ *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *specific language governing permissions and limitations
+ *under the License.
+ */
+/*
+ * discovery_impl.h
+ *
+ * \date Sep 29, 2011
+ * \author <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ * \copyright Apache License, Version 2.0
+ */
+
+#ifndef DISCOVERY_IMPL_H_
+#define DISCOVERY_IMPL_H_
+
+#include "bundle_context.h"
+#include "service_reference.h"
+
+#include "endpoint_description.h"
+#include "endpoint_listener.h"
+
+#include "endpoint_discovery_poller.h"
+#include "endpoint_discovery_server.h"
+
+#include "log_helper.h"
+
+#define DEFAULT_SERVER_IP "127.0.0.1"
+#define DEFAULT_SERVER_PORT "9999"
+#define DEFAULT_SERVER_PATH "/org.apache.celix.discovery.configured"
+#define DEFAULT_POLL_ENDPOINTS "http://localhost:9999/org.apache.celix.discovery.configured"
+
+
+struct discovery {
+ bundle_context_pt context;
+
+ celix_thread_mutex_t listenerReferencesMutex;
+ celix_thread_mutex_t discoveredServicesMutex;
+
+ hash_map_pt listenerReferences; //key=serviceReference, value=nop
+ hash_map_pt discoveredServices; //key=endpointId (string), value=endpoint_description_pt
+
+ endpoint_discovery_poller_pt poller;
+ endpoint_discovery_server_pt server;
+
+ log_helper_pt loghelper;
+};
+
+#endif /* DISCOVERY_IMPL_H_ */
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/discovery_etcd/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/remote_services/discovery_etcd/CMakeLists.txt b/remote_services/discovery_etcd/CMakeLists.txt
index b8955de..4168281 100644
--- a/remote_services/discovery_etcd/CMakeLists.txt
+++ b/remote_services/discovery_etcd/CMakeLists.txt
@@ -20,42 +20,19 @@ if (RSA_DISCOVERY_ETCD)
find_package(CURL REQUIRED)
find_package(LibXml2 REQUIRED)
find_package(Jansson REQUIRED)
-
- include_directories("${CURL_INCLUDE_DIR}")
- include_directories("${JANSSON_INCLUDE_DIR}")
- include_directories("${LIBXML2_INCLUDE_DIR}")
- include_directories("${PROJECT_SOURCE_DIR}/etcdlib/public/include")
- include_directories("${PROJECT_SOURCE_DIR}/utils/public/include")
- include_directories("${PROJECT_SOURCE_DIR}/remote_services/utils/private/include")
- include_directories("${PROJECT_SOURCE_DIR}/remote_services/utils/public/include")
- include_directories("${PROJECT_SOURCE_DIR}/remote_services/discovery/private/include")
- include_directories("${PROJECT_SOURCE_DIR}/remote_services/discovery_etcd/private/include")
- include_directories("${PROJECT_SOURCE_DIR}/remote_services/endpoint_listener/public/include")
- include_directories("${PROJECT_SOURCE_DIR}/remote_services/remote_service_admin/public/include")
- include_directories("${PROJECT_SOURCE_DIR}/log_service/public/include")
- include_directories("private/include")
add_bundle(discovery_etcd
VERSION 0.9.0
SYMBOLIC_NAME "apache_celix_rsa_discovery_etcd"
NAME "Apache Celix RSA Discovery ETCD"
SOURCES
- src/discovery_impl.c
- src/etcd_watcher.c
- ${PROJECT_SOURCE_DIR}/remote_services/discovery/private/src/discovery_activator.c
- ${PROJECT_SOURCE_DIR}/remote_services/discovery/private/src/discovery.c
- ${PROJECT_SOURCE_DIR}/remote_services/discovery/private/src/endpoint_descriptor_reader.c
- ${PROJECT_SOURCE_DIR}/remote_services/discovery/private/src/endpoint_descriptor_writer.c
- ${PROJECT_SOURCE_DIR}/remote_services/discovery/private/src/endpoint_discovery_poller.c
- ${PROJECT_SOURCE_DIR}/remote_services/discovery/private/src/endpoint_discovery_server.c
- ${PROJECT_SOURCE_DIR}/remote_services/remote_service_admin/private/src/endpoint_description.c
- ${PROJECT_SOURCE_DIR}/remote_services/utils/private/src/civetweb.c
+ src/discovery_impl.c
+ src/etcd_watcher.c
)
target_link_libraries(discovery_etcd PRIVATE Celix::log_helper)
- target_include_directories(discovery_etcd PRIVATE src ../discovery/private/include)
+ target_include_directories(discovery_etcd PRIVATE src )
+ target_include_directories(discovery_etcd PRIVATE ${CURL_INCLUDE_DIR} ${JANSSON_INCLUDE_DIR} ${LIBXML2_INCLUDE_DIR})
+ target_link_libraries(discovery_etcd PRIVATE ${CURL_LIBRARIES} ${LIBXML2_LIBRARIES} ${JANSSON_LIBRARIES} discovery_common)
install_bundle(discovery_etcd)
-
- target_link_libraries(discovery_etcd PRIVATE Celix::etcdlib ${CURL_LIBRARIES} ${LIBXML2_LIBRARIES} ${JANSSON_LIBRARIES})
-
endif (RSA_DISCOVERY_ETCD)
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/discovery_shm/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/remote_services/discovery_shm/CMakeLists.txt b/remote_services/discovery_shm/CMakeLists.txt
index 862096c..dff403d 100644
--- a/remote_services/discovery_shm/CMakeLists.txt
+++ b/remote_services/discovery_shm/CMakeLists.txt
@@ -19,40 +19,25 @@ celix_subproject(RSA_DISCOVERY_SHM "Option to enable building the Discovery (SHM
if (RSA_DISCOVERY_SHM)
find_package(CURL REQUIRED)
find_package(LibXml2 REQUIRED)
-
- include_directories("${CURL_INCLUDE_DIR}")
- include_directories("${LIBXML2_INCLUDE_DIR}")
- include_directories("${PROJECT_SOURCE_DIR}/utils/public/include")
- include_directories("${PROJECT_SOURCE_DIR}/remote_services/utils/private/include")
- include_directories("${PROJECT_SOURCE_DIR}/remote_services/utils/public/include")
- include_directories("${PROJECT_SOURCE_DIR}/remote_services/discovery/private/include")
- include_directories("${PROJECT_SOURCE_DIR}/remote_services/discovery_shm/private/include")
- include_directories("${PROJECT_SOURCE_DIR}/remote_services/endpoint_listener/public/include")
- include_directories("${PROJECT_SOURCE_DIR}/remote_services/remote_service_admin/public/include")
- include_directories("${PROJECT_SOURCE_DIR}/log_service/public/include")
- include_directories("private/include")
add_bundle(discovery_shm
VERSION 0.0.1
SYMBOLIC_NAME "apache_celix_rsa_discovery_shm"
NAME "Apache Celix RSA Discovery SHM"
SOURCES
- private/src/discovery_shm
- private/src/discovery_shmWatcher
- private/src/discovery_impl
- ${PROJECT_SOURCE_DIR}/remote_services/discovery/private/src/discovery_activator.c
- ${PROJECT_SOURCE_DIR}/remote_services/discovery/private/src/discovery.c
- ${PROJECT_SOURCE_DIR}/remote_services/discovery/private/src/endpoint_descriptor_reader.c
- ${PROJECT_SOURCE_DIR}/remote_services/discovery/private/src/endpoint_descriptor_writer.c
- ${PROJECT_SOURCE_DIR}/remote_services/discovery/private/src/endpoint_discovery_poller.c
- ${PROJECT_SOURCE_DIR}/remote_services/discovery/private/src/endpoint_discovery_server.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
+ src/discovery_shm.c
+ src/discovery_shmWatcher.c
+ src/discovery_impl.c
)
+ target_include_directories(discovery_shm PRIVATE
+ src
+ ${LIBXML2_INCLUDE_DIR}
+ ${CURL_INCLUDE_DIR}
+ )
+ target_link_libraries(discovery_shm PRIVATE Celix::framework ${CURL_LIBRARIES} ${LIBXML2_LIBRARIES} discovery_common)
install_bundle(discovery_shm)
- target_link_libraries(discovery_shm celix_framework ${CURL_LIBRARIES} ${LIBXML2_LIBRARIES})
+
endif (RSA_DISCOVERY_SHM)
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/discovery_shm/private/include/discovery_impl.h
----------------------------------------------------------------------
diff --git a/remote_services/discovery_shm/private/include/discovery_impl.h b/remote_services/discovery_shm/private/include/discovery_impl.h
deleted file mode 100644
index c7206bd..0000000
--- a/remote_services/discovery_shm/private/include/discovery_impl.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/**
- *Licensed to the Apache Software Foundation (ASF) under one
- *or more contributor license agreements. See the NOTICE file
- *distributed with this work for additional information
- *regarding copyright ownership. The ASF licenses this file
- *to you under the Apache License, Version 2.0 (the
- *"License"); you may not use this file except in compliance
- *with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- *Unless required by applicable law or agreed to in writing,
- *software distributed under the License is distributed on an
- *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- *specific language governing permissions and limitations
- *under the License.
- */
-/*
- * discovery_impl.h
- *
- * \date Oct 01, 2014
- * \author <a href="mailto:celix-dev@celix.apache.org">Apache Celix Project Team</a>
- * \copyright Apache License, Version 2.0
- */
-
-#ifndef DISCOVERY_IMPL_H_
-#define DISCOVERY_IMPL_H_
-
-#include "bundle_context.h"
-#include "service_reference.h"
-
-#include "endpoint_description.h"
-#include "endpoint_listener.h"
-
-#include "endpoint_discovery_poller.h"
-#include "endpoint_discovery_server.h"
-#include "discovery_shmWatcher.h"
-
-
-#define DEFAULT_SERVER_IP "127.0.0.1"
-#define DEFAULT_SERVER_PORT "9999"
-#define DEFAULT_SERVER_PATH "/org.apache.celix.discovery.shm"
-#define DEFAULT_POLL_ENDPOINTS "http://localhost:9999/org.apache.celix.discovery.shm"
-
-#define MAX_ROOTNODE_LENGTH 64
-#define MAX_LOCALNODE_LENGTH 256
-
-
-struct discovery {
- bundle_context_pt context;
-
- celix_thread_mutex_t listenerReferencesMutex;
- celix_thread_mutex_t discoveredServicesMutex;
-
- hash_map_pt listenerReferences; //key=serviceReference, value=nop
- hash_map_pt discoveredServices; //key=endpointId (string), value=endpoint_description_pt
-
- shm_watcher_pt watcher;
- endpoint_discovery_poller_pt poller;
- endpoint_discovery_server_pt server;
-
- log_helper_pt loghelper;
-};
-
-#endif /* DISCOVERY_H_ */
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/discovery_shm/private/include/discovery_shm.h
----------------------------------------------------------------------
diff --git a/remote_services/discovery_shm/private/include/discovery_shm.h b/remote_services/discovery_shm/private/include/discovery_shm.h
deleted file mode 100644
index 9c4593b..0000000
--- a/remote_services/discovery_shm/private/include/discovery_shm.h
+++ /dev/null
@@ -1,56 +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.
- */
-
-/*
- * shm.h
- *
- * \date 26 Jul 2014
- * \author <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- * \copyright Apache License, Version 2.0
- */
-
-
-
-#ifndef _DISCOVERY_SHM_H_
-#define _DISCOVERY_SHM_H_
-
-#include <celix_errno.h>
-
-#define SHM_ENTRY_MAX_KEY_LENGTH 256
-#define SHM_ENTRY_MAX_VALUE_LENGTH 256
-
-// defines the time-to-live in seconds
-#define SHM_ENTRY_DEFAULT_TTL 60
-
-// we currently support 64 separate discovery instances
-#define SHM_DATA_MAX_ENTRIES 64
-
-typedef struct shmData* shmData_pt;
-
-/* creates a new shared memory block */
-celix_status_t discoveryShm_create(shmData_pt* data);
-celix_status_t discoveryShm_attach(shmData_pt* data);
-celix_status_t discoveryShm_set(shmData_pt data, char *key, char* value);
-celix_status_t discoveryShm_get(shmData_pt data, char* key, char* value);
-celix_status_t discoveryShm_getKeys(shmData_pt data, char** keys, int* size);
-celix_status_t discoveryShm_remove(shmData_pt data, char* key);
-celix_status_t discoveryShm_detach(shmData_pt data);
-celix_status_t discoveryShm_destroy(shmData_pt data);
-
-#endif
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/discovery_shm/private/include/discovery_shmWatcher.h
----------------------------------------------------------------------
diff --git a/remote_services/discovery_shm/private/include/discovery_shmWatcher.h b/remote_services/discovery_shm/private/include/discovery_shmWatcher.h
deleted file mode 100644
index ff70f72..0000000
--- a/remote_services/discovery_shm/private/include/discovery_shmWatcher.h
+++ /dev/null
@@ -1,40 +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.
- */
-/*
- * shm_watcher.h
- *
- * \date 30 Sep 2014
- * \author <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- * \copyright Apache License, Version 2.0
- */
-
-#ifndef DISCOVERY_SHM_WATCHER_H_
-#define DISCOVERY_SHM_WATCHER_H_
-
-#include "celix_errno.h"
-#include "discovery.h"
-#include "endpoint_discovery_poller.h"
-
-typedef struct shm_watcher *shm_watcher_pt;
-
-celix_status_t discoveryShmWatcher_create(discovery_pt discovery);
-celix_status_t discoveryShmWatcher_destroy(discovery_pt discovery);
-
-
-#endif /* DISCOVERY_SHM_WATCHER_H_ */
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/discovery_shm/private/src/discovery_impl.c
----------------------------------------------------------------------
diff --git a/remote_services/discovery_shm/private/src/discovery_impl.c b/remote_services/discovery_shm/private/src/discovery_impl.c
deleted file mode 100644
index 2604595..0000000
--- a/remote_services/discovery_shm/private/src/discovery_impl.c
+++ /dev/null
@@ -1,163 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-/*
- * discovery_impl.c
- *
- * \date Aug 8, 2014
- * \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 <unistd.h>
-#include <stdbool.h>
-#include <netdb.h>
-#include <netinet/in.h>
-
-#include "constants.h"
-#include "celix_threads.h"
-#include "bundle_context.h"
-#include "array_list.h"
-#include "utils.h"
-#include "celix_errno.h"
-#include "filter.h"
-#include "service_reference.h"
-#include "service_registration.h"
-#include "remote_constants.h"
-
-
-#include "discovery.h"
-#include "discovery_impl.h"
-#include "discovery_shmWatcher.h"
-#include "endpoint_discovery_poller.h"
-#include "endpoint_discovery_server.h"
-
-
-
-celix_status_t discovery_create(bundle_context_pt context, discovery_pt *discovery) {
- celix_status_t status = CELIX_SUCCESS;
-
- *discovery = calloc(1, sizeof(struct discovery));
- if (!*discovery) {
- status = CELIX_ENOMEM;
- } else {
- (*discovery)->context = context;
- (*discovery)->poller = NULL;
- (*discovery)->server = NULL;
-
- (*discovery)->listenerReferences = hashMap_create(serviceReference_hashCode, NULL, serviceReference_equals2, NULL);
- (*discovery)->discoveredServices = hashMap_create(utils_stringHash, NULL, utils_stringEquals, NULL);
-
- celixThreadMutex_create(&(*discovery)->listenerReferencesMutex, NULL);
- celixThreadMutex_create(&(*discovery)->discoveredServicesMutex, NULL);
-
- if (logHelper_create(context, &(*discovery)->loghelper) == CELIX_SUCCESS) {
- logHelper_start((*discovery)->loghelper);
- }
- }
-
- return status;
-}
-
-
-
-celix_status_t discovery_destroy(discovery_pt discovery) {
- celix_status_t status = CELIX_SUCCESS;
-
- discovery->context = NULL;
- discovery->poller = NULL;
- discovery->server = NULL;
-
- celixThreadMutex_lock(&discovery->discoveredServicesMutex);
-
- hashMap_destroy(discovery->discoveredServices, false, false);
- discovery->discoveredServices = NULL;
-
- celixThreadMutex_unlock(&discovery->discoveredServicesMutex);
-
- celixThreadMutex_destroy(&discovery->discoveredServicesMutex);
-
- celixThreadMutex_lock(&discovery->listenerReferencesMutex);
-
- hashMap_destroy(discovery->listenerReferences, false, false);
- discovery->listenerReferences = NULL;
-
- celixThreadMutex_unlock(&discovery->listenerReferencesMutex);
-
- celixThreadMutex_destroy(&discovery->listenerReferencesMutex);
-
-
-
-
- free(discovery);
-
- return status;
-}
-
-celix_status_t discovery_start(discovery_pt discovery) {
- celix_status_t status;
-
- status = endpointDiscoveryPoller_create(discovery, discovery->context, &discovery->poller);
- if (status == CELIX_SUCCESS) {
- status = endpointDiscoveryServer_create(discovery, discovery->context, &discovery->server);
- }
-
- if (status == CELIX_SUCCESS) {
- status = discoveryShmWatcher_create(discovery);
- }
-
- return status;
-}
-
-celix_status_t discovery_stop(discovery_pt discovery) {
- celix_status_t status;
-
- status = discoveryShmWatcher_destroy(discovery);
-
- if (status == CELIX_SUCCESS) {
- status = endpointDiscoveryServer_destroy(discovery->server);
- }
-
- endpointDiscoveryPoller_destroy(discovery->poller);
-
- if (status == CELIX_SUCCESS) {
- hash_map_iterator_pt iter;
-
- celixThreadMutex_lock(&discovery->discoveredServicesMutex);
-
- iter = hashMapIterator_create(discovery->discoveredServices);
- while (hashMapIterator_hasNext(iter)) {
- hash_map_entry_pt entry = hashMapIterator_nextEntry(iter);
- endpoint_description_pt endpoint = hashMapEntry_getValue(entry);
-
- discovery_informEndpointListeners(discovery, endpoint, false);
- }
- hashMapIterator_destroy(iter);
-
- celixThreadMutex_unlock(&discovery->discoveredServicesMutex);
-
- logHelper_stop(discovery->loghelper);
- logHelper_destroy(&discovery->loghelper);
- }
-
- return status;
-}
-
-
-
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/discovery_shm/private/src/discovery_shm.c
----------------------------------------------------------------------
diff --git a/remote_services/discovery_shm/private/src/discovery_shm.c b/remote_services/discovery_shm/private/src/discovery_shm.c
deleted file mode 100644
index 1b1170e..0000000
--- a/remote_services/discovery_shm/private/src/discovery_shm.c
+++ /dev/null
@@ -1,284 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-/*
- * discovery_shm.c
- *
- * \date 26 Jul 2014
- * \author <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- * \copyright Apache License, Version 2.0
- */
-
-
-
-#include <stdio.h>
-#include <pthread.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-
-#include <sys/types.h>
-#include <sys/sem.h>
-#include <sys/shm.h>
-
-#include <celix_errno.h>
-#include <celix_threads.h>
-
-#include "discovery_shm.h"
-
-#define DISCOVERY_SHM_MEMSIZE 262144
-#define DISCOVERY_SHM_FILENAME "/dev/null"
-#define DISCOVERY_SHM_FTOK_ID 50
-#define DISCOVERY_SEM_FILENAME "/dev/null"
-#define DISCOVERY_SEM_FTOK_ID 54
-
-struct shmEntry {
- char key[SHM_ENTRY_MAX_KEY_LENGTH];
- char value[SHM_ENTRY_MAX_VALUE_LENGTH];
-
- time_t expires;
-};
-
-typedef struct shmEntry shmEntry;
-
-struct shmData {
- shmEntry entries[SHM_DATA_MAX_ENTRIES];
- int numOfEntries;
- int shmId;
-
- celix_thread_mutex_t globalLock;
-};
-
-void* shmAdress;
-
-static celix_status_t discoveryShm_removeWithIndex(shmData_pt data, int index);
-
-/* returns the ftok key to identify shared memory*/
-static key_t discoveryShm_getKey() {
- return ftok(DISCOVERY_SHM_FILENAME, DISCOVERY_SHM_FTOK_ID);
-}
-
-/* creates a new shared memory block */
-celix_status_t discoveryShm_create(shmData_pt* data) {
- celix_status_t status;
-
- shmData_pt shmData = calloc(1, sizeof(*shmData));
- key_t shmKey = discoveryShm_getKey();
-
- if (!shmData) {
- status = CELIX_ENOMEM;
- } else if ((shmData->shmId = shmget(shmKey, DISCOVERY_SHM_MEMSIZE, IPC_CREAT | 0666)) < 0) {
- status = CELIX_BUNDLE_EXCEPTION;
- } else if ((shmAdress = shmat(shmData->shmId, 0, 0)) == (char*) -1) {
- status = CELIX_BUNDLE_EXCEPTION;
- } else {
- celix_thread_mutexattr_t threadAttr;
-
- shmData->numOfEntries = 0;
-
- status = celixThreadMutexAttr_create(&threadAttr);
-
-#ifdef LINUX
- if (status == CELIX_SUCCESS) {
- // This is Linux specific
- status = pthread_mutexattr_setrobust(&threadAttr, PTHREAD_MUTEX_ROBUST);
- }
-#endif
-
- if (status == CELIX_SUCCESS) {
- status = celixThreadMutex_create(&shmData->globalLock, &threadAttr);
- }
-
- if (status == CELIX_SUCCESS) {
- memcpy(shmAdress, shmData, sizeof(struct shmData));
- (*data) = shmAdress;
- }
- }
-
- free(shmData);
-
- return status;
-}
-
-celix_status_t discoveryShm_attach(shmData_pt* data) {
- celix_status_t status = CELIX_SUCCESS;
- key_t shmKey = ftok(DISCOVERY_SHM_FILENAME, DISCOVERY_SHM_FTOK_ID);
- int shmId = -1;
-
- if ((shmId = shmget(shmKey, DISCOVERY_SHM_MEMSIZE, 0666)) < 0) {
- status = CELIX_BUNDLE_EXCEPTION;
- }
-
- /* shmat has a curious return value of (void*)-1 in case of error */
- void *mem=shmat(shmId, 0, 0);
- if(mem==((void*)-1)){
- status = CELIX_BUNDLE_EXCEPTION;
- }
- else{
- (*data)=mem;
- }
-
- return status;
-}
-
-static celix_status_t discoveryShm_getwithIndex(shmData_pt data, char* key, char* value, int* index) {
- celix_status_t status = CELIX_BUNDLE_EXCEPTION;
- time_t currentTime = time(NULL);
- unsigned int i;
-
- for (i = 0; i < data->numOfEntries && status != CELIX_SUCCESS; i++) {
- shmEntry entry = data->entries[i];
- // check if entry is still valid
- if (data->entries[i].expires < currentTime) {
- discoveryShm_removeWithIndex(data, i);
- } else if (strcmp(entry.key, key) == 0) {
- if (value) {
- strcpy(value, entry.value);
- }
- if (index) {
- (*index) = i;
- }
- status = CELIX_SUCCESS;
- }
- }
-
- return status;
-}
-
-celix_status_t discoveryShm_getKeys(shmData_pt data, char** keys, int* size) {
- celix_status_t status;
-
- status = celixThreadMutex_lock(&data->globalLock);
-
- if (status == CELIX_SUCCESS) {
- unsigned int i = 0;
- for (i = 0; i < data->numOfEntries; i++) {
- shmEntry entry = data->entries[i];
-
- if (strlen(entry.key)>0) {
- snprintf(keys[i], SHM_ENTRY_MAX_KEY_LENGTH, "%s", entry.key);
- }
- }
-
- (*size) = i;
-
- celixThreadMutex_unlock(&data->globalLock);
- }
-
- return status;
-}
-
-celix_status_t discoveryShm_set(shmData_pt data, char *key, char* value) {
- celix_status_t status;
- int index = -1;
-
- if (data->numOfEntries >= SHM_DATA_MAX_ENTRIES) {
- status = CELIX_ILLEGAL_STATE;
- } else {
- status = celixThreadMutex_lock(&data->globalLock);
-
- if (status == CELIX_SUCCESS) {
- // check if key already there
- status = discoveryShm_getwithIndex(data, key, NULL, &index);
- if (status != CELIX_SUCCESS) {
- index = data->numOfEntries;
-
- snprintf(data->entries[index].key, SHM_ENTRY_MAX_KEY_LENGTH, "%s", key);
- data->numOfEntries++;
-
- status = CELIX_SUCCESS;
- }
-
- snprintf(data->entries[index].value, SHM_ENTRY_MAX_VALUE_LENGTH, "%s", value);
- data->entries[index].expires = (time(NULL) + SHM_ENTRY_DEFAULT_TTL);
-
- celixThreadMutex_unlock(&data->globalLock);
- }
- }
-
- return status;
-}
-
-celix_status_t discoveryShm_get(shmData_pt data, char* key, char* value) {
- celix_status_t status;
-
- status = celixThreadMutex_lock(&data->globalLock);
-
- if (status == CELIX_SUCCESS) {
- status = discoveryShm_getwithIndex(data, key, value, NULL);
-
- celixThreadMutex_unlock(&data->globalLock);
- }
-
- return status;
-}
-
-static celix_status_t discoveryShm_removeWithIndex(shmData_pt data, int index) {
- celix_status_t status = CELIX_SUCCESS;
-
- data->numOfEntries--;
- if (index < data->numOfEntries) {
- memcpy((void*) &data->entries[index], (void*) &data->entries[index + 1], ((data->numOfEntries - index) * sizeof(struct shmEntry)));
- }
-
- return status;
-}
-
-celix_status_t discoveryShm_remove(shmData_pt data, char* key) {
- celix_status_t status;
- int index = -1;
-
- status = celixThreadMutex_lock(&data->globalLock);
-
- if (status == CELIX_SUCCESS) {
- status = discoveryShm_getwithIndex(data, key, NULL, &index);
-
- if (status == CELIX_SUCCESS) {
- status = discoveryShm_removeWithIndex(data, index);
- }
-
- celixThreadMutex_unlock(&data->globalLock);
- }
-
- return status;
-}
-
-celix_status_t discoveryShm_detach(shmData_pt data) {
- celix_status_t status = CELIX_BUNDLE_EXCEPTION;
-
- if (data->numOfEntries == 0) {
- status = discoveryShm_destroy(data);
- }
- else if (shmdt(shmAdress) == 0) {
- status = CELIX_SUCCESS;
- }
-
- return status;
-}
-
-celix_status_t discoveryShm_destroy(shmData_pt data) {
- celix_status_t status = CELIX_BUNDLE_EXCEPTION;
-
- if (shmctl(data->shmId, IPC_RMID, 0) == 0) {
- status = CELIX_SUCCESS;
- }
-
- return status;
-
-}
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/discovery_shm/private/src/discovery_shmWatcher.c
----------------------------------------------------------------------
diff --git a/remote_services/discovery_shm/private/src/discovery_shmWatcher.c b/remote_services/discovery_shm/private/src/discovery_shmWatcher.c
deleted file mode 100644
index 6460de8..0000000
--- a/remote_services/discovery_shm/private/src/discovery_shmWatcher.c
+++ /dev/null
@@ -1,246 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-/*
- * discovery_shmWatcher.c
- *
- * \date 16 Sep 2014
- * \author <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- * \copyright Apache License, Version 2.0
- */
-
-#include <stdbool.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <stdio.h>
-
-
-#include "celix_log.h"
-#include "constants.h"
-#include "discovery_impl.h"
-
-#include "discovery_shm.h"
-#include "discovery_shmWatcher.h"
-
-#include "endpoint_discovery_poller.h"
-
-struct shm_watcher {
- shmData_pt shmData;
- celix_thread_t watcherThread;
- celix_thread_mutex_t watcherLock;
-
- volatile bool running;
-};
-
-// note that the rootNode shouldn't have a leading slash
-static celix_status_t discoveryShmWatcher_getRootPath(char* rootNode) {
- celix_status_t status = CELIX_SUCCESS;
-
- strcpy(rootNode, "discovery");
-
- return status;
-}
-
-static celix_status_t discoveryShmWatcher_getLocalNodePath(bundle_context_pt context, char* localNodePath) {
- celix_status_t status;
- char rootPath[MAX_ROOTNODE_LENGTH];
- const char* uuid = NULL;
-
- status = discoveryShmWatcher_getRootPath(&rootPath[0]);
-
- if (status == CELIX_SUCCESS) {
- status = bundleContext_getProperty(context, OSGI_FRAMEWORK_FRAMEWORK_UUID, &uuid);
- }
-
- if (status == CELIX_SUCCESS) {
- if (rootPath[strlen(&rootPath[0]) - 1] == '/') {
- snprintf(localNodePath, MAX_LOCALNODE_LENGTH, "%s%s", &rootPath[0], uuid);
- } else {
- snprintf(localNodePath, MAX_LOCALNODE_LENGTH, "%s/%s", &rootPath[0], uuid);
- }
- }
-
- return status;
-}
-
-/* retrieves all endpoints from shm and syncs them with the ones already available */
-static celix_status_t discoveryShmWatcher_syncEndpoints(discovery_pt discovery) {
- celix_status_t status = CELIX_SUCCESS;
- shm_watcher_pt watcher = discovery->watcher;
- char** shmKeyArr = calloc(SHM_DATA_MAX_ENTRIES, sizeof(*shmKeyArr));
- array_list_pt registeredKeyArr = NULL;
-
- int i, j, shmSize;
-
- for (i = 0; i < SHM_DATA_MAX_ENTRIES; i++) {
- shmKeyArr[i] = calloc(SHM_ENTRY_MAX_KEY_LENGTH, sizeof(*shmKeyArr[i]));
- }
-
- arrayList_create(®isteredKeyArr);
-
- // get all urls available in shm
- discoveryShm_getKeys(watcher->shmData, shmKeyArr, &shmSize);
-
- // get all locally registered endpoints
- endpointDiscoveryPoller_getDiscoveryEndpoints(discovery->poller, registeredKeyArr);
-
- // add discovery points which are in shm, but not local yet
- for (i = 0; i < shmSize; i++) {
- char url[SHM_ENTRY_MAX_VALUE_LENGTH];
-
- if (discoveryShm_get(watcher->shmData, shmKeyArr[i], &url[0]) == CELIX_SUCCESS) {
- bool elementFound = false;
-
- for (j = 0; j < arrayList_size(registeredKeyArr) && elementFound == false; j++) {
-
- if (strcmp(url, (char*) arrayList_get(registeredKeyArr, j)) == 0) {
- free(arrayList_remove(registeredKeyArr, j));
- elementFound = true;
- }
- }
-
- if (elementFound == false) {
- endpointDiscoveryPoller_addDiscoveryEndpoint(discovery->poller, url);
- }
- }
- }
-
- // remove those which are not in shm
- for (i = 0; i < arrayList_size(registeredKeyArr); i++) {
- char* regUrl = arrayList_get(registeredKeyArr, i);
-
- if (regUrl != NULL) {
- endpointDiscoveryPoller_removeDiscoveryEndpoint(discovery->poller, regUrl);
- }
- }
-
- for (i = 0; i < SHM_DATA_MAX_ENTRIES; i++) {
- free(shmKeyArr[i]);
- }
-
- free(shmKeyArr);
-
- for (j = 0; j < arrayList_size(registeredKeyArr); j++) {
- free(arrayList_get(registeredKeyArr, j));
- }
-
- arrayList_destroy(registeredKeyArr);
-
- return status;
-}
-
-static void* discoveryShmWatcher_run(void* data) {
- discovery_pt discovery = (discovery_pt) data;
- shm_watcher_pt watcher = discovery->watcher;
- char localNodePath[MAX_LOCALNODE_LENGTH];
- char url[MAX_LOCALNODE_LENGTH];
-
- if (discoveryShmWatcher_getLocalNodePath(discovery->context, &localNodePath[0]) != CELIX_SUCCESS) {
- logHelper_log(discovery->loghelper, OSGI_LOGSERVICE_WARNING, "Cannot retrieve local discovery path.");
- }
-
- if (endpointDiscoveryServer_getUrl(discovery->server, &url[0]) != CELIX_SUCCESS) {
- snprintf(url, MAX_LOCALNODE_LENGTH, "http://%s:%s/%s", DEFAULT_SERVER_IP, DEFAULT_SERVER_PORT, DEFAULT_SERVER_PATH);
- }
-
- while (watcher->running) {
- // register own framework
- if (discoveryShm_set(watcher->shmData, localNodePath, url) != CELIX_SUCCESS) {
- logHelper_log(discovery->loghelper, OSGI_LOGSERVICE_WARNING, "Cannot set local discovery registration.");
- }
-
- discoveryShmWatcher_syncEndpoints(discovery);
- sleep(5);
- }
-
- return NULL;
-}
-
-celix_status_t discoveryShmWatcher_create(discovery_pt discovery) {
- celix_status_t status = CELIX_SUCCESS;
- shm_watcher_pt watcher = NULL;
-
- watcher = calloc(1, sizeof(*watcher));
-
- if (!watcher) {
- status = CELIX_ENOMEM;
- } else {
- status = discoveryShm_attach(&(watcher->shmData));
-
- if (status != CELIX_SUCCESS) {
- logHelper_log(discovery->loghelper, OSGI_LOGSERVICE_DEBUG, "Attaching to Shared Memory Failed. Trying to create.");
-
- status = discoveryShm_create(&(watcher->shmData));
-
- if (status != CELIX_SUCCESS) {
- logHelper_log(discovery->loghelper, OSGI_LOGSERVICE_ERROR, "Failed to create Shared Memory Segment.");
- }
- }
-
- if (status == CELIX_SUCCESS) {
- discovery->watcher = watcher;
- }
- else{
- discovery->watcher = NULL;
- free(watcher);
- }
-
- }
-
- if (status == CELIX_SUCCESS) {
- status += celixThreadMutex_create(&watcher->watcherLock, NULL);
- status += celixThreadMutex_lock(&watcher->watcherLock);
- watcher->running = true;
- status += celixThread_create(&watcher->watcherThread, NULL, discoveryShmWatcher_run, discovery);
- status += celixThreadMutex_unlock(&watcher->watcherLock);
- }
-
- return status;
-}
-
-celix_status_t discoveryShmWatcher_destroy(discovery_pt discovery) {
- celix_status_t status;
- shm_watcher_pt watcher = discovery->watcher;
- char localNodePath[MAX_LOCALNODE_LENGTH];
-
- celixThreadMutex_lock(&watcher->watcherLock);
- watcher->running = false;
- celixThreadMutex_unlock(&watcher->watcherLock);
-
- celixThread_join(watcher->watcherThread, NULL);
-
- // remove own framework
- status = discoveryShmWatcher_getLocalNodePath(discovery->context, &localNodePath[0]);
-
- if (status == CELIX_SUCCESS) {
- status = discoveryShm_remove(watcher->shmData, localNodePath);
- }
-
- if (status == CELIX_SUCCESS) {
- discoveryShm_detach(watcher->shmData);
- free(watcher);
- }
- else {
- logHelper_log(discovery->loghelper, OSGI_LOGSERVICE_WARNING, "Cannot remove local discovery registration.");
- }
-
-
- return status;
-}
-
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/discovery_shm/src/discovery_impl.c
----------------------------------------------------------------------
diff --git a/remote_services/discovery_shm/src/discovery_impl.c b/remote_services/discovery_shm/src/discovery_impl.c
new file mode 100644
index 0000000..2604595
--- /dev/null
+++ b/remote_services/discovery_shm/src/discovery_impl.c
@@ -0,0 +1,163 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+/*
+ * discovery_impl.c
+ *
+ * \date Aug 8, 2014
+ * \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 <unistd.h>
+#include <stdbool.h>
+#include <netdb.h>
+#include <netinet/in.h>
+
+#include "constants.h"
+#include "celix_threads.h"
+#include "bundle_context.h"
+#include "array_list.h"
+#include "utils.h"
+#include "celix_errno.h"
+#include "filter.h"
+#include "service_reference.h"
+#include "service_registration.h"
+#include "remote_constants.h"
+
+
+#include "discovery.h"
+#include "discovery_impl.h"
+#include "discovery_shmWatcher.h"
+#include "endpoint_discovery_poller.h"
+#include "endpoint_discovery_server.h"
+
+
+
+celix_status_t discovery_create(bundle_context_pt context, discovery_pt *discovery) {
+ celix_status_t status = CELIX_SUCCESS;
+
+ *discovery = calloc(1, sizeof(struct discovery));
+ if (!*discovery) {
+ status = CELIX_ENOMEM;
+ } else {
+ (*discovery)->context = context;
+ (*discovery)->poller = NULL;
+ (*discovery)->server = NULL;
+
+ (*discovery)->listenerReferences = hashMap_create(serviceReference_hashCode, NULL, serviceReference_equals2, NULL);
+ (*discovery)->discoveredServices = hashMap_create(utils_stringHash, NULL, utils_stringEquals, NULL);
+
+ celixThreadMutex_create(&(*discovery)->listenerReferencesMutex, NULL);
+ celixThreadMutex_create(&(*discovery)->discoveredServicesMutex, NULL);
+
+ if (logHelper_create(context, &(*discovery)->loghelper) == CELIX_SUCCESS) {
+ logHelper_start((*discovery)->loghelper);
+ }
+ }
+
+ return status;
+}
+
+
+
+celix_status_t discovery_destroy(discovery_pt discovery) {
+ celix_status_t status = CELIX_SUCCESS;
+
+ discovery->context = NULL;
+ discovery->poller = NULL;
+ discovery->server = NULL;
+
+ celixThreadMutex_lock(&discovery->discoveredServicesMutex);
+
+ hashMap_destroy(discovery->discoveredServices, false, false);
+ discovery->discoveredServices = NULL;
+
+ celixThreadMutex_unlock(&discovery->discoveredServicesMutex);
+
+ celixThreadMutex_destroy(&discovery->discoveredServicesMutex);
+
+ celixThreadMutex_lock(&discovery->listenerReferencesMutex);
+
+ hashMap_destroy(discovery->listenerReferences, false, false);
+ discovery->listenerReferences = NULL;
+
+ celixThreadMutex_unlock(&discovery->listenerReferencesMutex);
+
+ celixThreadMutex_destroy(&discovery->listenerReferencesMutex);
+
+
+
+
+ free(discovery);
+
+ return status;
+}
+
+celix_status_t discovery_start(discovery_pt discovery) {
+ celix_status_t status;
+
+ status = endpointDiscoveryPoller_create(discovery, discovery->context, &discovery->poller);
+ if (status == CELIX_SUCCESS) {
+ status = endpointDiscoveryServer_create(discovery, discovery->context, &discovery->server);
+ }
+
+ if (status == CELIX_SUCCESS) {
+ status = discoveryShmWatcher_create(discovery);
+ }
+
+ return status;
+}
+
+celix_status_t discovery_stop(discovery_pt discovery) {
+ celix_status_t status;
+
+ status = discoveryShmWatcher_destroy(discovery);
+
+ if (status == CELIX_SUCCESS) {
+ status = endpointDiscoveryServer_destroy(discovery->server);
+ }
+
+ endpointDiscoveryPoller_destroy(discovery->poller);
+
+ if (status == CELIX_SUCCESS) {
+ hash_map_iterator_pt iter;
+
+ celixThreadMutex_lock(&discovery->discoveredServicesMutex);
+
+ iter = hashMapIterator_create(discovery->discoveredServices);
+ while (hashMapIterator_hasNext(iter)) {
+ hash_map_entry_pt entry = hashMapIterator_nextEntry(iter);
+ endpoint_description_pt endpoint = hashMapEntry_getValue(entry);
+
+ discovery_informEndpointListeners(discovery, endpoint, false);
+ }
+ hashMapIterator_destroy(iter);
+
+ celixThreadMutex_unlock(&discovery->discoveredServicesMutex);
+
+ logHelper_stop(discovery->loghelper);
+ logHelper_destroy(&discovery->loghelper);
+ }
+
+ return status;
+}
+
+
+
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/discovery_shm/src/discovery_impl.h
----------------------------------------------------------------------
diff --git a/remote_services/discovery_shm/src/discovery_impl.h b/remote_services/discovery_shm/src/discovery_impl.h
new file mode 100644
index 0000000..c7206bd
--- /dev/null
+++ b/remote_services/discovery_shm/src/discovery_impl.h
@@ -0,0 +1,66 @@
+/**
+ *Licensed to the Apache Software Foundation (ASF) under one
+ *or more contributor license agreements. See the NOTICE file
+ *distributed with this work for additional information
+ *regarding copyright ownership. The ASF licenses this file
+ *to you under the Apache License, Version 2.0 (the
+ *"License"); you may not use this file except in compliance
+ *with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *Unless required by applicable law or agreed to in writing,
+ *software distributed under the License is distributed on an
+ *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *specific language governing permissions and limitations
+ *under the License.
+ */
+/*
+ * discovery_impl.h
+ *
+ * \date Oct 01, 2014
+ * \author <a href="mailto:celix-dev@celix.apache.org">Apache Celix Project Team</a>
+ * \copyright Apache License, Version 2.0
+ */
+
+#ifndef DISCOVERY_IMPL_H_
+#define DISCOVERY_IMPL_H_
+
+#include "bundle_context.h"
+#include "service_reference.h"
+
+#include "endpoint_description.h"
+#include "endpoint_listener.h"
+
+#include "endpoint_discovery_poller.h"
+#include "endpoint_discovery_server.h"
+#include "discovery_shmWatcher.h"
+
+
+#define DEFAULT_SERVER_IP "127.0.0.1"
+#define DEFAULT_SERVER_PORT "9999"
+#define DEFAULT_SERVER_PATH "/org.apache.celix.discovery.shm"
+#define DEFAULT_POLL_ENDPOINTS "http://localhost:9999/org.apache.celix.discovery.shm"
+
+#define MAX_ROOTNODE_LENGTH 64
+#define MAX_LOCALNODE_LENGTH 256
+
+
+struct discovery {
+ bundle_context_pt context;
+
+ celix_thread_mutex_t listenerReferencesMutex;
+ celix_thread_mutex_t discoveredServicesMutex;
+
+ hash_map_pt listenerReferences; //key=serviceReference, value=nop
+ hash_map_pt discoveredServices; //key=endpointId (string), value=endpoint_description_pt
+
+ shm_watcher_pt watcher;
+ endpoint_discovery_poller_pt poller;
+ endpoint_discovery_server_pt server;
+
+ log_helper_pt loghelper;
+};
+
+#endif /* DISCOVERY_H_ */
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/discovery_shm/src/discovery_shm.c
----------------------------------------------------------------------
diff --git a/remote_services/discovery_shm/src/discovery_shm.c b/remote_services/discovery_shm/src/discovery_shm.c
new file mode 100644
index 0000000..1b1170e
--- /dev/null
+++ b/remote_services/discovery_shm/src/discovery_shm.c
@@ -0,0 +1,284 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/*
+ * discovery_shm.c
+ *
+ * \date 26 Jul 2014
+ * \author <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ * \copyright Apache License, Version 2.0
+ */
+
+
+
+#include <stdio.h>
+#include <pthread.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+
+#include <sys/types.h>
+#include <sys/sem.h>
+#include <sys/shm.h>
+
+#include <celix_errno.h>
+#include <celix_threads.h>
+
+#include "discovery_shm.h"
+
+#define DISCOVERY_SHM_MEMSIZE 262144
+#define DISCOVERY_SHM_FILENAME "/dev/null"
+#define DISCOVERY_SHM_FTOK_ID 50
+#define DISCOVERY_SEM_FILENAME "/dev/null"
+#define DISCOVERY_SEM_FTOK_ID 54
+
+struct shmEntry {
+ char key[SHM_ENTRY_MAX_KEY_LENGTH];
+ char value[SHM_ENTRY_MAX_VALUE_LENGTH];
+
+ time_t expires;
+};
+
+typedef struct shmEntry shmEntry;
+
+struct shmData {
+ shmEntry entries[SHM_DATA_MAX_ENTRIES];
+ int numOfEntries;
+ int shmId;
+
+ celix_thread_mutex_t globalLock;
+};
+
+void* shmAdress;
+
+static celix_status_t discoveryShm_removeWithIndex(shmData_pt data, int index);
+
+/* returns the ftok key to identify shared memory*/
+static key_t discoveryShm_getKey() {
+ return ftok(DISCOVERY_SHM_FILENAME, DISCOVERY_SHM_FTOK_ID);
+}
+
+/* creates a new shared memory block */
+celix_status_t discoveryShm_create(shmData_pt* data) {
+ celix_status_t status;
+
+ shmData_pt shmData = calloc(1, sizeof(*shmData));
+ key_t shmKey = discoveryShm_getKey();
+
+ if (!shmData) {
+ status = CELIX_ENOMEM;
+ } else if ((shmData->shmId = shmget(shmKey, DISCOVERY_SHM_MEMSIZE, IPC_CREAT | 0666)) < 0) {
+ status = CELIX_BUNDLE_EXCEPTION;
+ } else if ((shmAdress = shmat(shmData->shmId, 0, 0)) == (char*) -1) {
+ status = CELIX_BUNDLE_EXCEPTION;
+ } else {
+ celix_thread_mutexattr_t threadAttr;
+
+ shmData->numOfEntries = 0;
+
+ status = celixThreadMutexAttr_create(&threadAttr);
+
+#ifdef LINUX
+ if (status == CELIX_SUCCESS) {
+ // This is Linux specific
+ status = pthread_mutexattr_setrobust(&threadAttr, PTHREAD_MUTEX_ROBUST);
+ }
+#endif
+
+ if (status == CELIX_SUCCESS) {
+ status = celixThreadMutex_create(&shmData->globalLock, &threadAttr);
+ }
+
+ if (status == CELIX_SUCCESS) {
+ memcpy(shmAdress, shmData, sizeof(struct shmData));
+ (*data) = shmAdress;
+ }
+ }
+
+ free(shmData);
+
+ return status;
+}
+
+celix_status_t discoveryShm_attach(shmData_pt* data) {
+ celix_status_t status = CELIX_SUCCESS;
+ key_t shmKey = ftok(DISCOVERY_SHM_FILENAME, DISCOVERY_SHM_FTOK_ID);
+ int shmId = -1;
+
+ if ((shmId = shmget(shmKey, DISCOVERY_SHM_MEMSIZE, 0666)) < 0) {
+ status = CELIX_BUNDLE_EXCEPTION;
+ }
+
+ /* shmat has a curious return value of (void*)-1 in case of error */
+ void *mem=shmat(shmId, 0, 0);
+ if(mem==((void*)-1)){
+ status = CELIX_BUNDLE_EXCEPTION;
+ }
+ else{
+ (*data)=mem;
+ }
+
+ return status;
+}
+
+static celix_status_t discoveryShm_getwithIndex(shmData_pt data, char* key, char* value, int* index) {
+ celix_status_t status = CELIX_BUNDLE_EXCEPTION;
+ time_t currentTime = time(NULL);
+ unsigned int i;
+
+ for (i = 0; i < data->numOfEntries && status != CELIX_SUCCESS; i++) {
+ shmEntry entry = data->entries[i];
+ // check if entry is still valid
+ if (data->entries[i].expires < currentTime) {
+ discoveryShm_removeWithIndex(data, i);
+ } else if (strcmp(entry.key, key) == 0) {
+ if (value) {
+ strcpy(value, entry.value);
+ }
+ if (index) {
+ (*index) = i;
+ }
+ status = CELIX_SUCCESS;
+ }
+ }
+
+ return status;
+}
+
+celix_status_t discoveryShm_getKeys(shmData_pt data, char** keys, int* size) {
+ celix_status_t status;
+
+ status = celixThreadMutex_lock(&data->globalLock);
+
+ if (status == CELIX_SUCCESS) {
+ unsigned int i = 0;
+ for (i = 0; i < data->numOfEntries; i++) {
+ shmEntry entry = data->entries[i];
+
+ if (strlen(entry.key)>0) {
+ snprintf(keys[i], SHM_ENTRY_MAX_KEY_LENGTH, "%s", entry.key);
+ }
+ }
+
+ (*size) = i;
+
+ celixThreadMutex_unlock(&data->globalLock);
+ }
+
+ return status;
+}
+
+celix_status_t discoveryShm_set(shmData_pt data, char *key, char* value) {
+ celix_status_t status;
+ int index = -1;
+
+ if (data->numOfEntries >= SHM_DATA_MAX_ENTRIES) {
+ status = CELIX_ILLEGAL_STATE;
+ } else {
+ status = celixThreadMutex_lock(&data->globalLock);
+
+ if (status == CELIX_SUCCESS) {
+ // check if key already there
+ status = discoveryShm_getwithIndex(data, key, NULL, &index);
+ if (status != CELIX_SUCCESS) {
+ index = data->numOfEntries;
+
+ snprintf(data->entries[index].key, SHM_ENTRY_MAX_KEY_LENGTH, "%s", key);
+ data->numOfEntries++;
+
+ status = CELIX_SUCCESS;
+ }
+
+ snprintf(data->entries[index].value, SHM_ENTRY_MAX_VALUE_LENGTH, "%s", value);
+ data->entries[index].expires = (time(NULL) + SHM_ENTRY_DEFAULT_TTL);
+
+ celixThreadMutex_unlock(&data->globalLock);
+ }
+ }
+
+ return status;
+}
+
+celix_status_t discoveryShm_get(shmData_pt data, char* key, char* value) {
+ celix_status_t status;
+
+ status = celixThreadMutex_lock(&data->globalLock);
+
+ if (status == CELIX_SUCCESS) {
+ status = discoveryShm_getwithIndex(data, key, value, NULL);
+
+ celixThreadMutex_unlock(&data->globalLock);
+ }
+
+ return status;
+}
+
+static celix_status_t discoveryShm_removeWithIndex(shmData_pt data, int index) {
+ celix_status_t status = CELIX_SUCCESS;
+
+ data->numOfEntries--;
+ if (index < data->numOfEntries) {
+ memcpy((void*) &data->entries[index], (void*) &data->entries[index + 1], ((data->numOfEntries - index) * sizeof(struct shmEntry)));
+ }
+
+ return status;
+}
+
+celix_status_t discoveryShm_remove(shmData_pt data, char* key) {
+ celix_status_t status;
+ int index = -1;
+
+ status = celixThreadMutex_lock(&data->globalLock);
+
+ if (status == CELIX_SUCCESS) {
+ status = discoveryShm_getwithIndex(data, key, NULL, &index);
+
+ if (status == CELIX_SUCCESS) {
+ status = discoveryShm_removeWithIndex(data, index);
+ }
+
+ celixThreadMutex_unlock(&data->globalLock);
+ }
+
+ return status;
+}
+
+celix_status_t discoveryShm_detach(shmData_pt data) {
+ celix_status_t status = CELIX_BUNDLE_EXCEPTION;
+
+ if (data->numOfEntries == 0) {
+ status = discoveryShm_destroy(data);
+ }
+ else if (shmdt(shmAdress) == 0) {
+ status = CELIX_SUCCESS;
+ }
+
+ return status;
+}
+
+celix_status_t discoveryShm_destroy(shmData_pt data) {
+ celix_status_t status = CELIX_BUNDLE_EXCEPTION;
+
+ if (shmctl(data->shmId, IPC_RMID, 0) == 0) {
+ status = CELIX_SUCCESS;
+ }
+
+ return status;
+
+}
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/discovery_shm/src/discovery_shm.h
----------------------------------------------------------------------
diff --git a/remote_services/discovery_shm/src/discovery_shm.h b/remote_services/discovery_shm/src/discovery_shm.h
new file mode 100644
index 0000000..9c4593b
--- /dev/null
+++ b/remote_services/discovery_shm/src/discovery_shm.h
@@ -0,0 +1,56 @@
+/**
+ * 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.
+ */
+
+/*
+ * shm.h
+ *
+ * \date 26 Jul 2014
+ * \author <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ * \copyright Apache License, Version 2.0
+ */
+
+
+
+#ifndef _DISCOVERY_SHM_H_
+#define _DISCOVERY_SHM_H_
+
+#include <celix_errno.h>
+
+#define SHM_ENTRY_MAX_KEY_LENGTH 256
+#define SHM_ENTRY_MAX_VALUE_LENGTH 256
+
+// defines the time-to-live in seconds
+#define SHM_ENTRY_DEFAULT_TTL 60
+
+// we currently support 64 separate discovery instances
+#define SHM_DATA_MAX_ENTRIES 64
+
+typedef struct shmData* shmData_pt;
+
+/* creates a new shared memory block */
+celix_status_t discoveryShm_create(shmData_pt* data);
+celix_status_t discoveryShm_attach(shmData_pt* data);
+celix_status_t discoveryShm_set(shmData_pt data, char *key, char* value);
+celix_status_t discoveryShm_get(shmData_pt data, char* key, char* value);
+celix_status_t discoveryShm_getKeys(shmData_pt data, char** keys, int* size);
+celix_status_t discoveryShm_remove(shmData_pt data, char* key);
+celix_status_t discoveryShm_detach(shmData_pt data);
+celix_status_t discoveryShm_destroy(shmData_pt data);
+
+#endif
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/discovery_shm/src/discovery_shmWatcher.c
----------------------------------------------------------------------
diff --git a/remote_services/discovery_shm/src/discovery_shmWatcher.c b/remote_services/discovery_shm/src/discovery_shmWatcher.c
new file mode 100644
index 0000000..6460de8
--- /dev/null
+++ b/remote_services/discovery_shm/src/discovery_shmWatcher.c
@@ -0,0 +1,246 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+/*
+ * discovery_shmWatcher.c
+ *
+ * \date 16 Sep 2014
+ * \author <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ * \copyright Apache License, Version 2.0
+ */
+
+#include <stdbool.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdio.h>
+
+
+#include "celix_log.h"
+#include "constants.h"
+#include "discovery_impl.h"
+
+#include "discovery_shm.h"
+#include "discovery_shmWatcher.h"
+
+#include "endpoint_discovery_poller.h"
+
+struct shm_watcher {
+ shmData_pt shmData;
+ celix_thread_t watcherThread;
+ celix_thread_mutex_t watcherLock;
+
+ volatile bool running;
+};
+
+// note that the rootNode shouldn't have a leading slash
+static celix_status_t discoveryShmWatcher_getRootPath(char* rootNode) {
+ celix_status_t status = CELIX_SUCCESS;
+
+ strcpy(rootNode, "discovery");
+
+ return status;
+}
+
+static celix_status_t discoveryShmWatcher_getLocalNodePath(bundle_context_pt context, char* localNodePath) {
+ celix_status_t status;
+ char rootPath[MAX_ROOTNODE_LENGTH];
+ const char* uuid = NULL;
+
+ status = discoveryShmWatcher_getRootPath(&rootPath[0]);
+
+ if (status == CELIX_SUCCESS) {
+ status = bundleContext_getProperty(context, OSGI_FRAMEWORK_FRAMEWORK_UUID, &uuid);
+ }
+
+ if (status == CELIX_SUCCESS) {
+ if (rootPath[strlen(&rootPath[0]) - 1] == '/') {
+ snprintf(localNodePath, MAX_LOCALNODE_LENGTH, "%s%s", &rootPath[0], uuid);
+ } else {
+ snprintf(localNodePath, MAX_LOCALNODE_LENGTH, "%s/%s", &rootPath[0], uuid);
+ }
+ }
+
+ return status;
+}
+
+/* retrieves all endpoints from shm and syncs them with the ones already available */
+static celix_status_t discoveryShmWatcher_syncEndpoints(discovery_pt discovery) {
+ celix_status_t status = CELIX_SUCCESS;
+ shm_watcher_pt watcher = discovery->watcher;
+ char** shmKeyArr = calloc(SHM_DATA_MAX_ENTRIES, sizeof(*shmKeyArr));
+ array_list_pt registeredKeyArr = NULL;
+
+ int i, j, shmSize;
+
+ for (i = 0; i < SHM_DATA_MAX_ENTRIES; i++) {
+ shmKeyArr[i] = calloc(SHM_ENTRY_MAX_KEY_LENGTH, sizeof(*shmKeyArr[i]));
+ }
+
+ arrayList_create(®isteredKeyArr);
+
+ // get all urls available in shm
+ discoveryShm_getKeys(watcher->shmData, shmKeyArr, &shmSize);
+
+ // get all locally registered endpoints
+ endpointDiscoveryPoller_getDiscoveryEndpoints(discovery->poller, registeredKeyArr);
+
+ // add discovery points which are in shm, but not local yet
+ for (i = 0; i < shmSize; i++) {
+ char url[SHM_ENTRY_MAX_VALUE_LENGTH];
+
+ if (discoveryShm_get(watcher->shmData, shmKeyArr[i], &url[0]) == CELIX_SUCCESS) {
+ bool elementFound = false;
+
+ for (j = 0; j < arrayList_size(registeredKeyArr) && elementFound == false; j++) {
+
+ if (strcmp(url, (char*) arrayList_get(registeredKeyArr, j)) == 0) {
+ free(arrayList_remove(registeredKeyArr, j));
+ elementFound = true;
+ }
+ }
+
+ if (elementFound == false) {
+ endpointDiscoveryPoller_addDiscoveryEndpoint(discovery->poller, url);
+ }
+ }
+ }
+
+ // remove those which are not in shm
+ for (i = 0; i < arrayList_size(registeredKeyArr); i++) {
+ char* regUrl = arrayList_get(registeredKeyArr, i);
+
+ if (regUrl != NULL) {
+ endpointDiscoveryPoller_removeDiscoveryEndpoint(discovery->poller, regUrl);
+ }
+ }
+
+ for (i = 0; i < SHM_DATA_MAX_ENTRIES; i++) {
+ free(shmKeyArr[i]);
+ }
+
+ free(shmKeyArr);
+
+ for (j = 0; j < arrayList_size(registeredKeyArr); j++) {
+ free(arrayList_get(registeredKeyArr, j));
+ }
+
+ arrayList_destroy(registeredKeyArr);
+
+ return status;
+}
+
+static void* discoveryShmWatcher_run(void* data) {
+ discovery_pt discovery = (discovery_pt) data;
+ shm_watcher_pt watcher = discovery->watcher;
+ char localNodePath[MAX_LOCALNODE_LENGTH];
+ char url[MAX_LOCALNODE_LENGTH];
+
+ if (discoveryShmWatcher_getLocalNodePath(discovery->context, &localNodePath[0]) != CELIX_SUCCESS) {
+ logHelper_log(discovery->loghelper, OSGI_LOGSERVICE_WARNING, "Cannot retrieve local discovery path.");
+ }
+
+ if (endpointDiscoveryServer_getUrl(discovery->server, &url[0]) != CELIX_SUCCESS) {
+ snprintf(url, MAX_LOCALNODE_LENGTH, "http://%s:%s/%s", DEFAULT_SERVER_IP, DEFAULT_SERVER_PORT, DEFAULT_SERVER_PATH);
+ }
+
+ while (watcher->running) {
+ // register own framework
+ if (discoveryShm_set(watcher->shmData, localNodePath, url) != CELIX_SUCCESS) {
+ logHelper_log(discovery->loghelper, OSGI_LOGSERVICE_WARNING, "Cannot set local discovery registration.");
+ }
+
+ discoveryShmWatcher_syncEndpoints(discovery);
+ sleep(5);
+ }
+
+ return NULL;
+}
+
+celix_status_t discoveryShmWatcher_create(discovery_pt discovery) {
+ celix_status_t status = CELIX_SUCCESS;
+ shm_watcher_pt watcher = NULL;
+
+ watcher = calloc(1, sizeof(*watcher));
+
+ if (!watcher) {
+ status = CELIX_ENOMEM;
+ } else {
+ status = discoveryShm_attach(&(watcher->shmData));
+
+ if (status != CELIX_SUCCESS) {
+ logHelper_log(discovery->loghelper, OSGI_LOGSERVICE_DEBUG, "Attaching to Shared Memory Failed. Trying to create.");
+
+ status = discoveryShm_create(&(watcher->shmData));
+
+ if (status != CELIX_SUCCESS) {
+ logHelper_log(discovery->loghelper, OSGI_LOGSERVICE_ERROR, "Failed to create Shared Memory Segment.");
+ }
+ }
+
+ if (status == CELIX_SUCCESS) {
+ discovery->watcher = watcher;
+ }
+ else{
+ discovery->watcher = NULL;
+ free(watcher);
+ }
+
+ }
+
+ if (status == CELIX_SUCCESS) {
+ status += celixThreadMutex_create(&watcher->watcherLock, NULL);
+ status += celixThreadMutex_lock(&watcher->watcherLock);
+ watcher->running = true;
+ status += celixThread_create(&watcher->watcherThread, NULL, discoveryShmWatcher_run, discovery);
+ status += celixThreadMutex_unlock(&watcher->watcherLock);
+ }
+
+ return status;
+}
+
+celix_status_t discoveryShmWatcher_destroy(discovery_pt discovery) {
+ celix_status_t status;
+ shm_watcher_pt watcher = discovery->watcher;
+ char localNodePath[MAX_LOCALNODE_LENGTH];
+
+ celixThreadMutex_lock(&watcher->watcherLock);
+ watcher->running = false;
+ celixThreadMutex_unlock(&watcher->watcherLock);
+
+ celixThread_join(watcher->watcherThread, NULL);
+
+ // remove own framework
+ status = discoveryShmWatcher_getLocalNodePath(discovery->context, &localNodePath[0]);
+
+ if (status == CELIX_SUCCESS) {
+ status = discoveryShm_remove(watcher->shmData, localNodePath);
+ }
+
+ if (status == CELIX_SUCCESS) {
+ discoveryShm_detach(watcher->shmData);
+ free(watcher);
+ }
+ else {
+ logHelper_log(discovery->loghelper, OSGI_LOGSERVICE_WARNING, "Cannot remove local discovery registration.");
+ }
+
+
+ return status;
+}
+
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/discovery_shm/src/discovery_shmWatcher.h
----------------------------------------------------------------------
diff --git a/remote_services/discovery_shm/src/discovery_shmWatcher.h b/remote_services/discovery_shm/src/discovery_shmWatcher.h
new file mode 100644
index 0000000..ff70f72
--- /dev/null
+++ b/remote_services/discovery_shm/src/discovery_shmWatcher.h
@@ -0,0 +1,40 @@
+/**
+ * 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.
+ */
+/*
+ * shm_watcher.h
+ *
+ * \date 30 Sep 2014
+ * \author <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ * \copyright Apache License, Version 2.0
+ */
+
+#ifndef DISCOVERY_SHM_WATCHER_H_
+#define DISCOVERY_SHM_WATCHER_H_
+
+#include "celix_errno.h"
+#include "discovery.h"
+#include "endpoint_discovery_poller.h"
+
+typedef struct shm_watcher *shm_watcher_pt;
+
+celix_status_t discoveryShmWatcher_create(discovery_pt discovery);
+celix_status_t discoveryShmWatcher_destroy(discovery_pt discovery);
+
+
+#endif /* DISCOVERY_SHM_WATCHER_H_ */
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/examples/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/remote_services/examples/CMakeLists.txt b/remote_services/examples/CMakeLists.txt
index c7c5444..2b1f35f 100644
--- a/remote_services/examples/CMakeLists.txt
+++ b/remote_services/examples/CMakeLists.txt
@@ -17,6 +17,7 @@
celix_subproject(RSA_EXAMPLES "Option to enable building the RSA examples" ON DEPS LAUNCHER shell_tui log_writer RSA_TOPOLOGY_MANAGER)
if (RSA_EXAMPLES)
+ add_subdirectory(calculator_api)
add_subdirectory(calculator_service)
add_subdirectory(calculator_shell)
@@ -47,13 +48,13 @@ if (RSA_EXAMPLES)
add_deploy(remote-services-dfi
NAME "server"
GROUP "remote-services/remote-services-dfi"
- BUNDLES discovery_etcd topology_manager remote_service_admin_dfi calculator Celix::shell Celix::shell_tui log_service log_writer
+ BUNDLES discovery_etcd topology_manager remote_service_admin_dfi calculator Celix::shell Celix::shell_tui Celix::log_service Celix::log_writer_stdout
)
add_deploy("remote-services-dfi-client"
NAME "client"
GROUP "remote-services/remote-services-dfi"
- BUNDLES topology_manager remote_service_admin_dfi Celix::shell Celix::shell_tui log_service log_writer calculator_shell discovery_etcd
+ BUNDLES topology_manager remote_service_admin_dfi Celix::shell Celix::shell_tui Celix::log_service Celix::log_writer_stdout calculator_shell discovery_etcd
)
endif ()
endif (RSA_EXAMPLES)
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/examples/calculator_api/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/remote_services/examples/calculator_api/CMakeLists.txt b/remote_services/examples/calculator_api/CMakeLists.txt
new file mode 100644
index 0000000..76acfa7
--- /dev/null
+++ b/remote_services/examples/calculator_api/CMakeLists.txt
@@ -0,0 +1,22 @@
+# 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.
+
+add_library(calculator_api INTERFACE)
+target_include_directories(calculator_api INTERFACE include)
+set_target_properties(calculator_api PROPERTIES
+ "INTERFACE_CALCULATOR_DESCRIPTOR"
+ "${CMAKE_CURRENT_LIST_DIR}/include/org.apache.celix.calc.api.Calculator2.descriptor")
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/examples/calculator_api/include/calculator_service.h
----------------------------------------------------------------------
diff --git a/remote_services/examples/calculator_api/include/calculator_service.h b/remote_services/examples/calculator_api/include/calculator_service.h
new file mode 100644
index 0000000..8e2f0dc
--- /dev/null
+++ b/remote_services/examples/calculator_api/include/calculator_service.h
@@ -0,0 +1,56 @@
+/**
+ *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.
+ */
+/*
+ * calculator_service.h
+ *
+ * \date Oct 5, 2011
+ * \author <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ * \copyright Apache License, Version 2.0
+ */
+
+#ifndef CALCULATOR_SERVICE_H_
+#define CALCULATOR_SERVICE_H_
+
+#define CALCULATOR_SERVICE "org.apache.celix.calc.api.Calculator"
+#define CALCULATOR2_SERVICE "org.apache.celix.calc.api.Calculator2"
+
+
+typedef struct calculator *calculator_pt;
+
+typedef struct calculator_service *calculator_service_pt;
+
+/*
+ * The calculator service definition corresponds to the following Java interface:
+ *
+ * interface Calculator {
+ * double add(double a, double b);
+ * double sub(double a, double b);
+ * double sqrt(double a);
+ * }
+ */
+struct calculator_service {
+ calculator_pt calculator;
+ int (*add)(calculator_pt calculator, double a, double b, double *result);
+ int (*sub)(calculator_pt calculator, double a, double b, double *result);
+ int (*sqrt)(calculator_pt calculator, double a, double *result);
+};
+
+
+
+#endif /* CALCULATOR_SERVICE_H_ */
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/examples/calculator_api/include/org.apache.celix.calc.api.Calculator2.descriptor
----------------------------------------------------------------------
diff --git a/remote_services/examples/calculator_api/include/org.apache.celix.calc.api.Calculator2.descriptor b/remote_services/examples/calculator_api/include/org.apache.celix.calc.api.Calculator2.descriptor
new file mode 100644
index 0000000..b784838
--- /dev/null
+++ b/remote_services/examples/calculator_api/include/org.apache.celix.calc.api.Calculator2.descriptor
@@ -0,0 +1,11 @@
+:header
+type=interface
+name=calculator
+version=1.3.0
+:annotations
+classname=org.example.Calculator
+:types
+:methods
+add(DD)D=add(#am=handle;PDD#am=pre;*D)N
+sub(DD)D=sub(#am=handle;PDD#am=pre;*D)N
+sqrt(D)D=sqrt(#am=handle;PD#am=pre;*D)N
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/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 5e8040c..ff4d2d7 100644
--- a/remote_services/examples/calculator_service/CMakeLists.txt
+++ b/remote_services/examples/calculator_service/CMakeLists.txt
@@ -15,21 +15,15 @@
# specific language governing permissions and limitations
# under the License.
-include_directories("../../../utils/public/include")
-include_directories("../../utils/public/include")
-include_directories("../../remote_service_admin/public/include")
-include_directories("private/include")
-include_directories("public/include")
-
-add_bundle(calculator SOURCES
- private/src/calculator_impl
- private/src/calculator_activator
-
- private/include/calculator_impl.h
-
+add_bundle(calculator
+ SOURCES
+ src/calculator_impl
+ src/calculator_activator
SYMBOLIC_NAME "apache_celix_remoting_calculator_impl"
VERSION 0.0.1
)
+target_include_directories(calculator PRIVATE src)
+target_link_libraries(calculator PRIVATE Celix::remote_service_admin_api calculator_api)
-bundle_files(calculator public/include/org.apache.celix.calc.api.Calculator2.descriptor
- DESTINATION .)
+get_target_property(DESCR calculator_api INTERFACE_CALCULATOR_DESCRIPTOR)
+bundle_files(calculator ${DESCR} DESTINATION .)
[13/19] celix git commit: CELIX-417: Refactor for CMake usage in RSA,
PSA and Docker. mostly trying to identify the api and common libraries
Posted by pn...@apache.org.
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/discovery_common/include/endpoint_descriptor_common.h
----------------------------------------------------------------------
diff --git a/remote_services/discovery_common/include/endpoint_descriptor_common.h b/remote_services/discovery_common/include/endpoint_descriptor_common.h
new file mode 100644
index 0000000..a186a18
--- /dev/null
+++ b/remote_services/discovery_common/include/endpoint_descriptor_common.h
@@ -0,0 +1,61 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+/*
+ * endpoint_descriptor_common.h
+ *
+ * \date Aug 8, 2014
+ * \author <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ * \copyright Apache License, Version 2.0
+ */
+
+#ifndef ENDPOINT_DESCRIPTOR_COMMON_H_
+#define ENDPOINT_DESCRIPTOR_COMMON_H_
+
+/*
+ * Private constant & enum definitions for endpoint descriptor reader and writer, not needed for normal usage of the reader and writer.
+ */
+
+typedef enum {
+ VALUE_TYPE_STRING,
+ VALUE_TYPE_LONG,
+ VALUE_TYPE_DOUBLE,
+ VALUE_TYPE_FLOAT,
+ VALUE_TYPE_INTEGER,
+ VALUE_TYPE_BYTE,
+ VALUE_TYPE_CHAR,
+ VALUE_TYPE_BOOLEAN,
+ VALUE_TYPE_SHORT,
+} valueType;
+
+static const __attribute__((unused)) xmlChar* XML = (const xmlChar*) "xml";
+static const __attribute__((unused)) xmlChar* XMLNS = (const xmlChar*) "http://www.osgi.org/xmlns/rsa/v1.0.0";
+
+static const __attribute__((unused)) xmlChar* ENDPOINT_DESCRIPTIONS = (const xmlChar*) "endpoint-descriptions";
+static const xmlChar* ENDPOINT_DESCRIPTION = (const xmlChar*) "endpoint-description";
+
+static const xmlChar* ARRAY = (const xmlChar*) "array";
+static const __attribute__((unused)) xmlChar* LIST = (const xmlChar*) "list";
+static const __attribute__((unused)) xmlChar* SET = (const xmlChar*) "set";
+
+static const xmlChar* PROPERTY = (const xmlChar*) "property";
+static const xmlChar* NAME = (const xmlChar*) "name";
+static const xmlChar* VALUE = (const xmlChar*) "value";
+static const xmlChar* VALUE_TYPE = (const xmlChar*) "value-type";
+
+#endif /* ENDPOINT_DESCRIPTOR_COMMON_H_ */
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/discovery_common/include/endpoint_descriptor_reader.h
----------------------------------------------------------------------
diff --git a/remote_services/discovery_common/include/endpoint_descriptor_reader.h b/remote_services/discovery_common/include/endpoint_descriptor_reader.h
new file mode 100644
index 0000000..7a05d9e
--- /dev/null
+++ b/remote_services/discovery_common/include/endpoint_descriptor_reader.h
@@ -0,0 +1,42 @@
+/**
+ *Licensed to the Apache Software Foundation (ASF) under one
+ *or more contributor license agreements. See the NOTICE file
+ *distributed with this work for additional information
+ *regarding copyright ownership. The ASF licenses this file
+ *to you under the Apache License, Version 2.0 (the
+ *"License"); you may not use this file except in compliance
+ *with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *Unless required by applicable law or agreed to in writing,
+ *software distributed under the License is distributed on an
+ *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *specific language governing permissions and limitations
+ *under the License.
+ */
+/*
+ * endpoint_descriptor_reader.h
+ *
+ * \date 26 Jul 2014
+ * \author <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ * \copyright Apache License, Version 2.0
+ */
+
+#ifndef ENDPOINT_DESCRIPTOR_READER_H_
+#define ENDPOINT_DESCRIPTOR_READER_H_
+
+#include "endpoint_discovery_poller.h"
+#include "celix_errno.h"
+#include "array_list.h"
+
+typedef struct endpoint_descriptor_reader *endpoint_descriptor_reader_pt;
+
+celix_status_t endpointDescriptorReader_create(endpoint_discovery_poller_pt poller, endpoint_descriptor_reader_pt *reader);
+celix_status_t endpointDescriptorReader_destroy(endpoint_descriptor_reader_pt reader);
+
+celix_status_t endpointDescriptorReader_parseDocument(endpoint_descriptor_reader_pt reader, char *document, array_list_pt *endpoints);
+
+
+#endif /* ENDPOINT_DESCRIPTOR_READER_H_ */
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/discovery_common/include/endpoint_descriptor_writer.h
----------------------------------------------------------------------
diff --git a/remote_services/discovery_common/include/endpoint_descriptor_writer.h b/remote_services/discovery_common/include/endpoint_descriptor_writer.h
new file mode 100644
index 0000000..3c5a9be
--- /dev/null
+++ b/remote_services/discovery_common/include/endpoint_descriptor_writer.h
@@ -0,0 +1,39 @@
+/**
+ *Licensed to the Apache Software Foundation (ASF) under one
+ *or more contributor license agreements. See the NOTICE file
+ *distributed with this work for additional information
+ *regarding copyright ownership. The ASF licenses this file
+ *to you under the Apache License, Version 2.0 (the
+ *"License"); you may not use this file except in compliance
+ *with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *Unless required by applicable law or agreed to in writing,
+ *software distributed under the License is distributed on an
+ *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *specific language governing permissions and limitations
+ *under the License.
+ */
+/*
+ * endpoint_descriptor_writer.h
+ *
+ * \date 26 Jul 2014
+ * \author <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ * \copyright Apache License, Version 2.0
+ */
+
+#ifndef ENDPOINT_DESCRIPTOR_WRITER_H_
+#define ENDPOINT_DESCRIPTOR_WRITER_H_
+
+#include "celix_errno.h"
+#include "array_list.h"
+
+typedef struct endpoint_descriptor_writer *endpoint_descriptor_writer_pt;
+
+celix_status_t endpointDescriptorWriter_create(endpoint_descriptor_writer_pt *writer);
+celix_status_t endpointDescriptorWriter_destroy(endpoint_descriptor_writer_pt writer);
+celix_status_t endpointDescriptorWriter_writeDocument(endpoint_descriptor_writer_pt writer, array_list_pt endpoints, char **document);
+
+#endif /* ENDPOINT_DESCRIPTOR_WRITER_H_ */
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/discovery_common/include/endpoint_discovery_poller.h
----------------------------------------------------------------------
diff --git a/remote_services/discovery_common/include/endpoint_discovery_poller.h b/remote_services/discovery_common/include/endpoint_discovery_poller.h
new file mode 100644
index 0000000..d344e55
--- /dev/null
+++ b/remote_services/discovery_common/include/endpoint_discovery_poller.h
@@ -0,0 +1,56 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+/*
+ * endpoint_discovery_poller.h
+ *
+ * \date 3 Jul 2014
+ * \author <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ * \copyright Apache License, Version 2.0
+ */
+
+#ifndef ENDPOINT_DISCOVERY_POLLER_H_
+#define ENDPOINT_DISCOVERY_POLLER_H_
+
+#include "celix_errno.h"
+#include "discovery.h"
+#include "log_helper.h"
+
+struct endpoint_discovery_poller {
+ discovery_pt discovery;
+ hash_map_pt entries;
+ log_helper_pt* loghelper;
+
+ celix_thread_mutex_t pollerLock;
+ celix_thread_t pollerThread;
+
+ unsigned int poll_interval;
+ volatile bool running;
+};
+
+typedef struct endpoint_discovery_poller *endpoint_discovery_poller_pt;
+
+celix_status_t endpointDiscoveryPoller_create(discovery_pt discovery, bundle_context_pt context, endpoint_discovery_poller_pt *poller);
+celix_status_t endpointDiscoveryPoller_destroy(endpoint_discovery_poller_pt poller);
+
+celix_status_t endpointDiscoveryPoller_addDiscoveryEndpoint(endpoint_discovery_poller_pt poller, char *url);
+celix_status_t endpointDiscoveryPoller_removeDiscoveryEndpoint(endpoint_discovery_poller_pt poller, char *url);
+
+celix_status_t endpointDiscoveryPoller_getDiscoveryEndpoints(endpoint_discovery_poller_pt poller, array_list_pt urls);
+
+#endif /* ENDPOINT_DISCOVERY_POLLER_H_ */
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/discovery_common/include/endpoint_discovery_server.h
----------------------------------------------------------------------
diff --git a/remote_services/discovery_common/include/endpoint_discovery_server.h b/remote_services/discovery_common/include/endpoint_discovery_server.h
new file mode 100644
index 0000000..51082b5
--- /dev/null
+++ b/remote_services/discovery_common/include/endpoint_discovery_server.h
@@ -0,0 +1,81 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+/*
+ * endpoint_discovery_server.h
+ *
+ * \date Aug 12, 2014
+ * \author <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ * \copyright Apache License, Version 2.0
+ */
+
+#ifndef ENDPOINT_DISCOVERY_SERVER_H_
+#define ENDPOINT_DISCOVERY_SERVER_H_
+
+#include "celix_errno.h"
+#include "discovery.h"
+
+typedef struct endpoint_discovery_server *endpoint_discovery_server_pt;
+
+/**
+ * Creates and starts a new instance of an endpoint discovery server.
+ *
+ * @param discovery [in] the discovery service itself;
+ * @param context [in] the bundle context;
+ * @param server [out] the pointer to the created instance.
+ * @return CELIX_SUCCESS when successful.
+ */
+celix_status_t endpointDiscoveryServer_create(discovery_pt discovery, bundle_context_pt context, endpoint_discovery_server_pt *server);
+
+/**
+ * Stops and destroys a given instance of an endpoint discovery server.
+ *
+ * @param server [in] the pointer to the instance to destroy.
+ * @return CELIX_SUCCESS when successful.
+ */
+celix_status_t endpointDiscoveryServer_destroy(endpoint_discovery_server_pt server);
+
+/**
+ * Adds a given endpoint description to expose through the given discovery server.
+ *
+ * @param server [in] the endpoint discovery server to expose the endpoint through;
+ * @param endpoint [in] the endpoint description to expose.
+ * @return CELIX_SUCCESS when successful.
+ */
+celix_status_t endpointDiscoveryServer_addEndpoint(endpoint_discovery_server_pt server, endpoint_description_pt endpoint);
+
+/**
+ * Removes a given endpoint description from exposure through the given discovery server.
+ *
+ * @param server [in] the endpoint discovery server to remove the endpoint from;
+ * @param endpoint [in] the endpoint description to remove.
+ * @return CELIX_SUCCESS when successful.
+ */
+celix_status_t endpointDiscoveryServer_removeEndpoint( endpoint_discovery_server_pt server, endpoint_description_pt endpoint);
+
+/**
+ * Returns the url, which is used by the discovery server to announce the endpoints
+ *
+ * @param server [in] the endpoint discovery server to retrieve the url from
+ * @param url [out] url which is used to announce the endpoints.
+ * @return CELIX_SUCCESS when successful.
+ */
+celix_status_t endpointDiscoveryServer_getUrl(endpoint_discovery_server_pt server, char* url);
+
+
+#endif /* ENDPOINT_DISCOVERY_SERVER_H_ */
[17/19] celix git commit: CELIX-417: Refactor for CMake usage in RSA,
PSA and Docker. mostly trying to identify the api and common libraries
Posted by pn...@apache.org.
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/pubsub/pubsub_admin_udp_mc/src/psa_activator.c
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_admin_udp_mc/src/psa_activator.c b/pubsub/pubsub_admin_udp_mc/src/psa_activator.c
new file mode 100644
index 0000000..cd4ee07
--- /dev/null
+++ b/pubsub/pubsub_admin_udp_mc/src/psa_activator.c
@@ -0,0 +1,141 @@
+/**
+ *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.
+ */
+/*
+ * psa_activator.c
+ *
+ * \date Sep 30, 2011
+ * \author <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ * \copyright Apache License, Version 2.0
+ */
+
+#include <stdlib.h>
+
+#include "bundle_activator.h"
+#include "service_registration.h"
+#include "service_tracker.h"
+
+#include "pubsub_admin_impl.h"
+
+struct activator {
+ pubsub_admin_pt admin;
+ pubsub_admin_service_pt adminService;
+ service_registration_pt registration;
+ service_tracker_pt serializerTracker;
+};
+
+celix_status_t bundleActivator_create(bundle_context_pt context, void **userData) {
+ celix_status_t status = CELIX_SUCCESS;
+ struct activator *activator;
+
+ activator = calloc(1, sizeof(*activator));
+ if (!activator) {
+ status = CELIX_ENOMEM;
+ }
+ else{
+ *userData = activator;
+
+ status = pubsubAdmin_create(context, &(activator->admin));
+
+ if(status == CELIX_SUCCESS){
+ service_tracker_customizer_pt customizer = NULL;
+ status = serviceTrackerCustomizer_create(activator->admin,
+ NULL,
+ pubsubAdmin_serializerAdded,
+ NULL,
+ pubsubAdmin_serializerRemoved,
+ &customizer);
+ if(status == CELIX_SUCCESS){
+ status = serviceTracker_create(context, PUBSUB_SERIALIZER_SERVICE, customizer, &(activator->serializerTracker));
+ if(status != CELIX_SUCCESS){
+ serviceTrackerCustomizer_destroy(customizer);
+ pubsubAdmin_destroy(activator->admin);
+ }
+ }
+ else{
+ pubsubAdmin_destroy(activator->admin);
+ }
+ }
+ }
+
+ return status;
+}
+
+celix_status_t bundleActivator_start(void * userData, bundle_context_pt context) {
+ celix_status_t status = CELIX_SUCCESS;
+ struct activator *activator = userData;
+ pubsub_admin_service_pt pubsubAdminSvc = calloc(1, sizeof(*pubsubAdminSvc));
+
+ if (!pubsubAdminSvc) {
+ status = CELIX_ENOMEM;
+ }
+ else{
+ pubsubAdminSvc->admin = activator->admin;
+
+ pubsubAdminSvc->addPublication = pubsubAdmin_addPublication;
+ pubsubAdminSvc->removePublication = pubsubAdmin_removePublication;
+
+ pubsubAdminSvc->addSubscription = pubsubAdmin_addSubscription;
+ pubsubAdminSvc->removeSubscription = pubsubAdmin_removeSubscription;
+
+ pubsubAdminSvc->closeAllPublications = pubsubAdmin_closeAllPublications;
+ pubsubAdminSvc->closeAllSubscriptions = pubsubAdmin_closeAllSubscriptions;
+
+ pubsubAdminSvc->matchEndpoint = pubsubAdmin_matchEndpoint;
+
+ activator->adminService = pubsubAdminSvc;
+
+ status = bundleContext_registerService(context, PUBSUB_ADMIN_SERVICE, pubsubAdminSvc, NULL, &activator->registration);
+
+ status += serviceTracker_open(activator->serializerTracker);
+
+ }
+
+
+ return status;
+}
+
+celix_status_t bundleActivator_stop(void * userData, bundle_context_pt context) {
+ celix_status_t status = CELIX_SUCCESS;
+ struct activator *activator = userData;
+
+ status += serviceTracker_close(activator->serializerTracker);
+ status += serviceRegistration_unregister(activator->registration);
+
+ activator->registration = NULL;
+
+ free(activator->adminService);
+ activator->adminService = NULL;
+
+ return status;
+}
+
+celix_status_t bundleActivator_destroy(void * userData, bundle_context_pt context) {
+ celix_status_t status = CELIX_SUCCESS;
+ struct activator *activator = userData;
+
+ serviceTracker_destroy(activator->serializerTracker);
+ pubsubAdmin_destroy(activator->admin);
+ activator->admin = NULL;
+
+ free(activator);
+
+ return status;
+}
+
+
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/pubsub/pubsub_admin_udp_mc/src/pubsub_admin_impl.c
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_admin_udp_mc/src/pubsub_admin_impl.c b/pubsub/pubsub_admin_udp_mc/src/pubsub_admin_impl.c
new file mode 100644
index 0000000..1fbdb08
--- /dev/null
+++ b/pubsub/pubsub_admin_udp_mc/src/pubsub_admin_impl.c
@@ -0,0 +1,1039 @@
+/**
+ *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.
+ */
+/*
+ * pubsub_admin_impl.c
+ *
+ * \date Sep 30, 2011
+ * \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>
+
+#ifndef ANDROID
+#include <ifaddrs.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+
+#include "constants.h"
+#include "utils.h"
+#include "hash_map.h"
+#include "array_list.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 "service_factory.h"
+
+#include "pubsub_admin_impl.h"
+#include "topic_subscription.h"
+#include "topic_publication.h"
+#include "pubsub_endpoint.h"
+#include "subscriber.h"
+#include "pubsub_admin_match.h"
+
+static const char *DEFAULT_MC_IP = "224.100.1.1";
+static char *DEFAULT_MC_PREFIX = "224.100";
+
+static celix_status_t pubsubAdmin_getIpAddress(const char* interface, char** ip);
+static celix_status_t pubsubAdmin_addSubscriptionToPendingList(pubsub_admin_pt admin,pubsub_endpoint_pt subEP);
+static celix_status_t pubsubAdmin_addAnySubscription(pubsub_admin_pt admin,pubsub_endpoint_pt subEP);
+
+static celix_status_t pubsubAdmin_getBestSerializer(pubsub_admin_pt admin,pubsub_endpoint_pt ep, pubsub_serializer_service_t **serSvc);
+static void connectTopicPubSubToSerializer(pubsub_admin_pt admin,pubsub_serializer_service_t *serializer,void *topicPubSub,bool isPublication);
+static void disconnectTopicPubSubFromSerializer(pubsub_admin_pt admin,void *topicPubSub,bool isPublication);
+
+celix_status_t pubsubAdmin_create(bundle_context_pt context, pubsub_admin_pt *admin) {
+ celix_status_t status = CELIX_SUCCESS;
+
+ *admin = calloc(1, sizeof(**admin));
+
+ if (!*admin) {
+ return CELIX_ENOMEM;
+ }
+
+ char *mc_ip = NULL;
+ char *if_ip = NULL;
+ int sendSocket = -1;
+
+ if (logHelper_create(context, &(*admin)->loghelper) == CELIX_SUCCESS) {
+ logHelper_start((*admin)->loghelper);
+ }
+ const char *mc_ip_prop = NULL;
+ bundleContext_getProperty(context,PSA_IP , &mc_ip_prop);
+ if(mc_ip_prop) {
+ mc_ip = strdup(mc_ip_prop);
+ }
+
+#ifndef ANDROID
+ if (mc_ip == NULL) {
+ const char *mc_prefix = NULL;
+ const char *interface = NULL;
+ int b0 = 0, b1 = 0, b2 = 0, b3 = 0;
+ bundleContext_getProperty(context,PSA_MULTICAST_IP_PREFIX , &mc_prefix);
+ if(mc_prefix == NULL) {
+ mc_prefix = DEFAULT_MC_PREFIX;
+ }
+
+ bundleContext_getProperty(context, PSA_ITF, &interface);
+ if (pubsubAdmin_getIpAddress(interface, &if_ip) != CELIX_SUCCESS) {
+ logHelper_log((*admin)->loghelper, OSGI_LOGSERVICE_WARNING, "PSA_UDP_MC: Could not retrieve IP address for interface %s", interface);
+ }
+
+ printf("IP Detected : %s\n", if_ip);
+ if(if_ip && sscanf(if_ip, "%i.%i.%i.%i", &b0, &b1, &b2, &b3) != 4) {
+ logHelper_log((*admin)->loghelper, OSGI_LOGSERVICE_WARNING, "PSA_UDP_MC: Could not parse IP address %s", if_ip);
+ b2 = 1;
+ b3 = 1;
+ }
+
+ asprintf(&mc_ip, "%s.%d.%d",mc_prefix, b2, b3);
+
+ sendSocket = socket(AF_INET, SOCK_DGRAM, 0);
+ if(sendSocket == -1) {
+ perror("pubsubAdmin_create:socket");
+ status = CELIX_SERVICE_EXCEPTION;
+ }
+
+ if(status == CELIX_SUCCESS){
+ char loop = 1;
+ if(setsockopt(sendSocket, IPPROTO_IP, IP_MULTICAST_LOOP, &loop, sizeof(loop)) != 0) {
+ perror("pubsubAdmin_create:setsockopt(IP_MULTICAST_LOOP)");
+ status = CELIX_SERVICE_EXCEPTION;
+ }
+ }
+
+ if(status == CELIX_SUCCESS){
+ struct in_addr multicast_interface;
+ inet_aton(if_ip, &multicast_interface);
+ if(setsockopt(sendSocket, IPPROTO_IP, IP_MULTICAST_IF, &multicast_interface, sizeof(multicast_interface)) != 0) {
+ perror("pubsubAdmin_create:setsockopt(IP_MULTICAST_IF)");
+ status = CELIX_SERVICE_EXCEPTION;
+ }
+ }
+
+ }
+
+
+ if(status != CELIX_SUCCESS){
+ logHelper_stop((*admin)->loghelper);
+ logHelper_destroy(&((*admin)->loghelper));
+ if(sendSocket >=0){
+ close(sendSocket);
+ }
+ if(if_ip != NULL){
+ free(if_ip);
+ }
+ if(mc_ip != NULL){
+ free(mc_ip);
+ }
+ return status;
+ }
+ else{
+ (*admin)->sendSocket = sendSocket;
+ }
+
+#endif
+
+ (*admin)->bundle_context= context;
+ (*admin)->localPublications = hashMap_create(utils_stringHash, NULL, utils_stringEquals, NULL);
+ (*admin)->subscriptions = hashMap_create(utils_stringHash, NULL, utils_stringEquals, NULL);
+ (*admin)->pendingSubscriptions = hashMap_create(utils_stringHash, NULL, utils_stringEquals, NULL);
+ (*admin)->externalPublications = hashMap_create(utils_stringHash, NULL, utils_stringEquals, NULL);
+ (*admin)->topicSubscriptionsPerSerializer = hashMap_create(NULL, NULL, NULL, NULL);
+ (*admin)->topicPublicationsPerSerializer = hashMap_create(NULL, NULL, NULL, NULL);
+ arrayList_create(&((*admin)->noSerializerSubscriptions));
+ arrayList_create(&((*admin)->noSerializerPublications));
+ arrayList_create(&((*admin)->serializerList));
+
+ celixThreadMutex_create(&(*admin)->localPublicationsLock, NULL);
+ celixThreadMutex_create(&(*admin)->subscriptionsLock, NULL);
+ celixThreadMutex_create(&(*admin)->externalPublicationsLock, NULL);
+ celixThreadMutex_create(&(*admin)->serializerListLock, NULL);
+ celixThreadMutex_create(&(*admin)->usedSerializersLock, NULL);
+
+ celixThreadMutexAttr_create(&(*admin)->noSerializerPendingsAttr);
+ celixThreadMutexAttr_settype(&(*admin)->noSerializerPendingsAttr, CELIX_THREAD_MUTEX_RECURSIVE);
+ celixThreadMutex_create(&(*admin)->noSerializerPendingsLock, &(*admin)->noSerializerPendingsAttr);
+
+ celixThreadMutexAttr_create(&(*admin)->pendingSubscriptionsAttr);
+ celixThreadMutexAttr_settype(&(*admin)->pendingSubscriptionsAttr, CELIX_THREAD_MUTEX_RECURSIVE);
+ celixThreadMutex_create(&(*admin)->pendingSubscriptionsLock, &(*admin)->pendingSubscriptionsAttr);
+
+ if (if_ip != NULL) {
+ logHelper_log((*admin)->loghelper, OSGI_LOGSERVICE_INFO, "PSA_UDP_MC: Using %s as interface for multicast communication", if_ip);
+ (*admin)->ifIpAddress = if_ip;
+ } else {
+ (*admin)->ifIpAddress = strdup("127.0.0.1");
+ }
+
+ if (mc_ip != NULL) {
+ logHelper_log((*admin)->loghelper, OSGI_LOGSERVICE_INFO, "PSA_UDP_MC: Using %s for service annunciation", mc_ip);
+ (*admin)->mcIpAddress = mc_ip;
+ }
+ else {
+ logHelper_log((*admin)->loghelper, OSGI_LOGSERVICE_WARNING, "PSA_UDP_MC: No IP address for service annunciation set. Using %s", DEFAULT_MC_IP);
+ (*admin)->mcIpAddress = strdup(DEFAULT_MC_IP);
+ }
+
+ return status;
+}
+
+
+celix_status_t pubsubAdmin_destroy(pubsub_admin_pt admin)
+{
+ celix_status_t status = CELIX_SUCCESS;
+
+ free(admin->mcIpAddress);
+ free(admin->ifIpAddress);
+
+ celixThreadMutex_lock(&admin->pendingSubscriptionsLock);
+ hash_map_iterator_pt iter = hashMapIterator_create(admin->pendingSubscriptions);
+ while(hashMapIterator_hasNext(iter)){
+ hash_map_entry_pt entry = hashMapIterator_nextEntry(iter);
+ free((char*)hashMapEntry_getKey(entry));
+ arrayList_destroy((array_list_pt)hashMapEntry_getValue(entry));
+ }
+ hashMapIterator_destroy(iter);
+ hashMap_destroy(admin->pendingSubscriptions,false,false);
+ celixThreadMutex_unlock(&admin->pendingSubscriptionsLock);
+
+ celixThreadMutex_lock(&admin->subscriptionsLock);
+ hashMap_destroy(admin->subscriptions,false,false);
+ celixThreadMutex_unlock(&admin->subscriptionsLock);
+
+ celixThreadMutex_lock(&admin->localPublicationsLock);
+ hashMap_destroy(admin->localPublications,true,false);
+ celixThreadMutex_unlock(&admin->localPublicationsLock);
+
+ celixThreadMutex_lock(&admin->externalPublicationsLock);
+ iter = hashMapIterator_create(admin->externalPublications);
+ while(hashMapIterator_hasNext(iter)){
+ hash_map_entry_pt entry = hashMapIterator_nextEntry(iter);
+ free((char*)hashMapEntry_getKey(entry));
+ arrayList_destroy((array_list_pt)hashMapEntry_getValue(entry));
+ }
+ hashMapIterator_destroy(iter);
+ hashMap_destroy(admin->externalPublications,false,false);
+ celixThreadMutex_unlock(&admin->externalPublicationsLock);
+
+ celixThreadMutex_lock(&admin->serializerListLock);
+ arrayList_destroy(admin->serializerList);
+ celixThreadMutex_unlock(&admin->serializerListLock);
+
+ celixThreadMutex_lock(&admin->noSerializerPendingsLock);
+ arrayList_destroy(admin->noSerializerSubscriptions);
+ arrayList_destroy(admin->noSerializerPublications);
+ celixThreadMutex_unlock(&admin->noSerializerPendingsLock);
+
+ celixThreadMutex_lock(&admin->usedSerializersLock);
+
+ iter = hashMapIterator_create(admin->topicSubscriptionsPerSerializer);
+ while(hashMapIterator_hasNext(iter)){
+ arrayList_destroy((array_list_pt)hashMapIterator_nextValue(iter));
+ }
+ hashMapIterator_destroy(iter);
+ hashMap_destroy(admin->topicSubscriptionsPerSerializer,false,false);
+
+ iter = hashMapIterator_create(admin->topicPublicationsPerSerializer);
+ while(hashMapIterator_hasNext(iter)){
+ arrayList_destroy((array_list_pt)hashMapIterator_nextValue(iter));
+ }
+ hashMapIterator_destroy(iter);
+ hashMap_destroy(admin->topicPublicationsPerSerializer,false,false);
+
+ celixThreadMutex_unlock(&admin->usedSerializersLock);
+
+ celixThreadMutex_destroy(&admin->usedSerializersLock);
+ celixThreadMutex_destroy(&admin->serializerListLock);
+
+ celixThreadMutexAttr_destroy(&admin->noSerializerPendingsAttr);
+ celixThreadMutex_destroy(&admin->noSerializerPendingsLock);
+
+ celixThreadMutex_destroy(&admin->pendingSubscriptionsLock);
+ celixThreadMutexAttr_destroy(&admin->pendingSubscriptionsAttr);
+
+ celixThreadMutex_destroy(&admin->subscriptionsLock);
+ celixThreadMutex_destroy(&admin->localPublicationsLock);
+ celixThreadMutex_destroy(&admin->externalPublicationsLock);
+
+ logHelper_stop(admin->loghelper);
+
+ logHelper_destroy(&admin->loghelper);
+
+ free(admin);
+
+ return status;
+}
+
+static celix_status_t pubsubAdmin_addAnySubscription(pubsub_admin_pt admin,pubsub_endpoint_pt subEP){
+ celix_status_t status = CELIX_SUCCESS;
+
+ celixThreadMutex_lock(&admin->subscriptionsLock);
+
+ topic_subscription_pt any_sub = hashMap_get(admin->subscriptions,PUBSUB_ANY_SUB_TOPIC);
+
+ if(any_sub==NULL){
+
+ int i;
+ pubsub_serializer_service_t *best_serializer = NULL;
+ if( (status=pubsubAdmin_getBestSerializer(admin, subEP, &best_serializer)) == CELIX_SUCCESS){
+ status = pubsub_topicSubscriptionCreate(admin->bundle_context, admin->ifIpAddress, PUBSUB_SUBSCRIBER_SCOPE_DEFAULT, PUBSUB_ANY_SUB_TOPIC, best_serializer, &any_sub);
+ }
+ else{
+ printf("PSA_UDP_MC: Cannot find a serializer for subscribing topic %s. Adding it to pending list.\n",subEP->topic);
+ celixThreadMutex_lock(&admin->noSerializerPendingsLock);
+ arrayList_add(admin->noSerializerSubscriptions,subEP);
+ celixThreadMutex_unlock(&admin->noSerializerPendingsLock);
+ }
+
+ if (status == CELIX_SUCCESS){
+
+ /* Connect all internal publishers */
+ celixThreadMutex_lock(&admin->localPublicationsLock);
+ hash_map_iterator_pt lp_iter =hashMapIterator_create(admin->localPublications);
+ while(hashMapIterator_hasNext(lp_iter)){
+ service_factory_pt factory = (service_factory_pt)hashMapIterator_nextValue(lp_iter);
+ topic_publication_pt topic_pubs = (topic_publication_pt)factory->handle;
+ array_list_pt topic_publishers = pubsub_topicPublicationGetPublisherList(topic_pubs);
+
+ if(topic_publishers!=NULL){
+ for(i=0;i<arrayList_size(topic_publishers);i++){
+ pubsub_endpoint_pt pubEP = (pubsub_endpoint_pt)arrayList_get(topic_publishers,i);
+ if(pubEP->endpoint !=NULL){
+ status += pubsub_topicSubscriptionConnectPublisher(any_sub,pubEP->endpoint);
+ }
+ }
+ arrayList_destroy(topic_publishers);
+ }
+ }
+ hashMapIterator_destroy(lp_iter);
+ celixThreadMutex_unlock(&admin->localPublicationsLock);
+
+ /* Connect also all external publishers */
+ celixThreadMutex_lock(&admin->externalPublicationsLock);
+ hash_map_iterator_pt extp_iter =hashMapIterator_create(admin->externalPublications);
+ while(hashMapIterator_hasNext(extp_iter)){
+ array_list_pt ext_pub_list = (array_list_pt)hashMapIterator_nextValue(extp_iter);
+ if(ext_pub_list!=NULL){
+ for(i=0;i<arrayList_size(ext_pub_list);i++){
+ pubsub_endpoint_pt pubEP = (pubsub_endpoint_pt)arrayList_get(ext_pub_list,i);
+ if(pubEP->endpoint !=NULL){
+ status += pubsub_topicSubscriptionConnectPublisher(any_sub,pubEP->endpoint);
+ }
+ }
+ }
+ }
+ hashMapIterator_destroy(extp_iter);
+ celixThreadMutex_unlock(&admin->externalPublicationsLock);
+
+
+ pubsub_topicSubscriptionAddSubscriber(any_sub,subEP);
+
+ status += pubsub_topicSubscriptionStart(any_sub);
+
+ }
+
+ if (status == CELIX_SUCCESS){
+ hashMap_put(admin->subscriptions,strdup(PUBSUB_ANY_SUB_TOPIC),any_sub);
+ connectTopicPubSubToSerializer(admin, best_serializer, any_sub, false);
+ }
+
+ }
+
+ celixThreadMutex_unlock(&admin->subscriptionsLock);
+
+ return status;
+}
+
+celix_status_t pubsubAdmin_addSubscription(pubsub_admin_pt admin,pubsub_endpoint_pt subEP){
+ celix_status_t status = CELIX_SUCCESS;
+
+ printf("PSA_UDP_MC: Received subscription [FWUUID=%s bundleID=%ld scope=%s, topic=%s]\n",subEP->frameworkUUID,subEP->serviceID,subEP->scope,subEP->topic);
+
+ if(strcmp(subEP->topic,PUBSUB_ANY_SUB_TOPIC)==0){
+ return pubsubAdmin_addAnySubscription(admin,subEP);
+ }
+
+ /* Check if we already know some publisher about this topic, otherwise let's put the subscription in the pending hashmap */
+ celixThreadMutex_lock(&admin->pendingSubscriptionsLock);
+ celixThreadMutex_lock(&admin->subscriptionsLock);
+ celixThreadMutex_lock(&admin->localPublicationsLock);
+ celixThreadMutex_lock(&admin->externalPublicationsLock);
+
+ char* scope_topic = createScopeTopicKey(subEP->scope,subEP->topic);
+
+ service_factory_pt factory = (service_factory_pt)hashMap_get(admin->localPublications,scope_topic);
+ array_list_pt ext_pub_list = (array_list_pt)hashMap_get(admin->externalPublications,scope_topic);
+
+ if(factory==NULL && ext_pub_list==NULL){ //No (local or external) publishers yet for this topic
+ pubsubAdmin_addSubscriptionToPendingList(admin,subEP);
+ }
+ else{
+ int i;
+ topic_subscription_pt subscription = hashMap_get(admin->subscriptions, scope_topic);
+
+ if(subscription == NULL) {
+ pubsub_serializer_service_t *best_serializer = NULL;
+ if( (status=pubsubAdmin_getBestSerializer(admin, subEP, &best_serializer)) == CELIX_SUCCESS){
+ status += pubsub_topicSubscriptionCreate(admin->bundle_context,admin->ifIpAddress, subEP->scope, subEP->topic, best_serializer, &subscription);
+ }
+ else{
+ printf("PSA_UDP_MC: Cannot find a serializer for subscribing topic %s. Adding it to pending list.\n",subEP->topic);
+ celixThreadMutex_lock(&admin->noSerializerPendingsLock);
+ arrayList_add(admin->noSerializerSubscriptions,subEP);
+ celixThreadMutex_unlock(&admin->noSerializerPendingsLock);
+ }
+
+ if (status==CELIX_SUCCESS){
+
+ /* Try to connect internal publishers */
+ if(factory!=NULL){
+ topic_publication_pt topic_pubs = (topic_publication_pt)factory->handle;
+ array_list_pt topic_publishers = pubsub_topicPublicationGetPublisherList(topic_pubs);
+
+ if(topic_publishers!=NULL){
+ for(i=0;i<arrayList_size(topic_publishers);i++){
+ pubsub_endpoint_pt pubEP = (pubsub_endpoint_pt)arrayList_get(topic_publishers,i);
+ if(pubEP->endpoint !=NULL){
+ status += pubsub_topicSubscriptionConnectPublisher(subscription,pubEP->endpoint);
+ }
+ }
+ arrayList_destroy(topic_publishers);
+ }
+
+ }
+
+ /* Look also for external publishers */
+ if(ext_pub_list!=NULL){
+ for(i=0;i<arrayList_size(ext_pub_list);i++){
+ pubsub_endpoint_pt pubEP = (pubsub_endpoint_pt)arrayList_get(ext_pub_list,i);
+ if(pubEP->endpoint !=NULL){
+ status += pubsub_topicSubscriptionConnectPublisher(subscription,pubEP->endpoint);
+ }
+ }
+ }
+
+ pubsub_topicSubscriptionAddSubscriber(subscription,subEP);
+
+ status += pubsub_topicSubscriptionStart(subscription);
+
+ }
+
+ if(status==CELIX_SUCCESS){
+
+ hashMap_put(admin->subscriptions,strdup(scope_topic),subscription);
+
+ connectTopicPubSubToSerializer(admin, best_serializer, subscription, false);
+ }
+ }
+
+ if (status == CELIX_SUCCESS){
+ pubsub_topicIncreaseNrSubscribers(subscription);
+ }
+ }
+
+ free(scope_topic);
+ celixThreadMutex_unlock(&admin->externalPublicationsLock);
+ celixThreadMutex_unlock(&admin->localPublicationsLock);
+ celixThreadMutex_unlock(&admin->subscriptionsLock);
+ celixThreadMutex_unlock(&admin->pendingSubscriptionsLock);
+
+ return status;
+
+}
+
+celix_status_t pubsubAdmin_removeSubscription(pubsub_admin_pt admin,pubsub_endpoint_pt subEP){
+ celix_status_t status = CELIX_SUCCESS;
+
+ printf("PSA_UDP_MC: Removing subscription [FWUUID=%s bundleID=%ld scope=%s, topic=%s]\n",subEP->frameworkUUID,subEP->serviceID,subEP->scope, subEP->topic);
+
+ char* scope_topic = createScopeTopicKey(subEP->scope, subEP->topic);
+
+ celixThreadMutex_lock(&admin->subscriptionsLock);
+ topic_subscription_pt sub = (topic_subscription_pt)hashMap_get(admin->subscriptions,scope_topic);
+ if(sub!=NULL){
+ pubsub_topicDecreaseNrSubscribers(sub);
+ if(pubsub_topicGetNrSubscribers(sub) == 0) {
+ status = pubsub_topicSubscriptionRemoveSubscriber(sub,subEP);
+ }
+ }
+ celixThreadMutex_unlock(&admin->subscriptionsLock);
+
+ if(sub==NULL){
+ /* Maybe the endpoint was pending */
+ celixThreadMutex_lock(&admin->noSerializerPendingsLock);
+ if(!arrayList_removeElement(admin->noSerializerSubscriptions, subEP)){
+ status = CELIX_ILLEGAL_STATE;
+ }
+ celixThreadMutex_unlock(&admin->noSerializerPendingsLock);
+ }
+
+ free(scope_topic);
+
+
+
+ return status;
+
+}
+
+celix_status_t pubsubAdmin_addPublication(pubsub_admin_pt admin,pubsub_endpoint_pt pubEP){
+ celix_status_t status = CELIX_SUCCESS;
+
+ printf("PSA_UDP_MC: Received publication [FWUUID=%s bundleID=%ld scope=%s, topic=%s]\n",pubEP->frameworkUUID,pubEP->serviceID,pubEP->scope, pubEP->topic);
+
+ const char* fwUUID = NULL;
+
+ bundleContext_getProperty(admin->bundle_context,OSGI_FRAMEWORK_FRAMEWORK_UUID,&fwUUID);
+ if(fwUUID==NULL){
+ printf("PSA_UDP_MC: Cannot retrieve fwUUID.\n");
+ return CELIX_INVALID_BUNDLE_CONTEXT;
+ }
+ char* scope_topic = createScopeTopicKey(pubEP->scope, pubEP->topic);
+
+ if ((strcmp(pubEP->frameworkUUID, fwUUID) == 0) && (pubEP->endpoint == NULL)) {
+
+ celixThreadMutex_lock(&admin->localPublicationsLock);
+
+ service_factory_pt factory = (service_factory_pt) hashMap_get(admin->localPublications, scope_topic);
+
+ if (factory == NULL) {
+ topic_publication_pt pub = NULL;
+ pubsub_serializer_service_t *best_serializer = NULL;
+ if( (status=pubsubAdmin_getBestSerializer(admin, pubEP, &best_serializer)) == CELIX_SUCCESS){
+ status = pubsub_topicPublicationCreate(admin->sendSocket, pubEP, best_serializer, admin->mcIpAddress, &pub);
+ }
+ else{
+ printf("PSA_UDP_MC: Cannot find a serializer for publishing topic %s. Adding it to pending list.\n", pubEP->topic);
+ celixThreadMutex_lock(&admin->noSerializerPendingsLock);
+ arrayList_add(admin->noSerializerPublications,pubEP);
+ celixThreadMutex_unlock(&admin->noSerializerPendingsLock);
+ }
+
+ if (status == CELIX_SUCCESS) {
+ status = pubsub_topicPublicationStart(admin->bundle_context, pub, &factory);
+ if (status == CELIX_SUCCESS && factory != NULL) {
+ hashMap_put(admin->localPublications, strdup(scope_topic), factory);
+ connectTopicPubSubToSerializer(admin, best_serializer, pub, true);
+ }
+ } else {
+ printf("PSA_UDP_MC: Cannot create a topicPublication for scope=%s, topic=%s (bundle %ld).\n", pubEP->scope, pubEP->topic, pubEP->serviceID);
+ }
+ } else {
+ //just add the new EP to the list
+ topic_publication_pt pub = (topic_publication_pt) factory->handle;
+ pubsub_topicPublicationAddPublisherEP(pub, pubEP);
+ }
+
+ celixThreadMutex_unlock(&admin->localPublicationsLock);
+ }
+ else{
+
+ celixThreadMutex_lock(&admin->externalPublicationsLock);
+ array_list_pt ext_pub_list = (array_list_pt) hashMap_get(admin->externalPublications, scope_topic);
+ if (ext_pub_list == NULL) {
+ arrayList_create(&ext_pub_list);
+ hashMap_put(admin->externalPublications, strdup(scope_topic), ext_pub_list);
+ }
+
+ arrayList_add(ext_pub_list, pubEP);
+
+ celixThreadMutex_unlock(&admin->externalPublicationsLock);
+ }
+
+ /* Re-evaluate the pending subscriptions */
+ celixThreadMutex_lock(&admin->pendingSubscriptionsLock);
+
+ hash_map_entry_pt pendingSub = hashMap_getEntry(admin->pendingSubscriptions, scope_topic);
+ if (pendingSub != NULL) { //There were pending subscription for the just published topic. Let's connect them.
+ char* topic = (char*) hashMapEntry_getKey(pendingSub);
+ array_list_pt pendingSubList = (array_list_pt) hashMapEntry_getValue(pendingSub);
+ int i;
+ for (i = 0; i < arrayList_size(pendingSubList); i++) {
+ pubsub_endpoint_pt subEP = (pubsub_endpoint_pt) arrayList_get(pendingSubList, i);
+ pubsubAdmin_addSubscription(admin, subEP);
+ }
+ hashMap_remove(admin->pendingSubscriptions, scope_topic);
+ arrayList_clear(pendingSubList);
+ arrayList_destroy(pendingSubList);
+ free(topic);
+ }
+
+ celixThreadMutex_unlock(&admin->pendingSubscriptionsLock);
+
+ /* Connect the new publisher to the subscription for his topic, if there is any */
+ celixThreadMutex_lock(&admin->subscriptionsLock);
+
+ topic_subscription_pt sub = (topic_subscription_pt) hashMap_get(admin->subscriptions, scope_topic);
+ if (sub != NULL && pubEP->endpoint != NULL) {
+ pubsub_topicSubscriptionAddConnectPublisherToPendingList(sub, pubEP->endpoint);
+ }
+
+ /* And check also for ANY subscription */
+ topic_subscription_pt any_sub = (topic_subscription_pt) hashMap_get(admin->subscriptions, PUBSUB_ANY_SUB_TOPIC);
+ if (any_sub != NULL && pubEP->endpoint != NULL) {
+ pubsub_topicSubscriptionAddConnectPublisherToPendingList(any_sub, pubEP->endpoint);
+ }
+
+ free(scope_topic);
+
+ celixThreadMutex_unlock(&admin->subscriptionsLock);
+
+ return status;
+
+}
+
+celix_status_t pubsubAdmin_removePublication(pubsub_admin_pt admin,pubsub_endpoint_pt pubEP){
+ celix_status_t status = CELIX_SUCCESS;
+ int count = 0;
+
+ printf("PSA_UDP_MC: Removing publication [FWUUID=%s bundleID=%ld scope=%s, topic=%s]\n",pubEP->frameworkUUID,pubEP->serviceID,pubEP->scope, pubEP->topic);
+
+ const char* fwUUID = NULL;
+
+ bundleContext_getProperty(admin->bundle_context,OSGI_FRAMEWORK_FRAMEWORK_UUID,&fwUUID);
+ if(fwUUID==NULL){
+ printf("PSA_UDP_MC: Cannot retrieve fwUUID.\n");
+ return CELIX_INVALID_BUNDLE_CONTEXT;
+ }
+ char *scope_topic = createScopeTopicKey(pubEP->scope, pubEP->topic);
+
+ if(strcmp(pubEP->frameworkUUID,fwUUID)==0){
+
+ celixThreadMutex_lock(&admin->localPublicationsLock);
+ service_factory_pt factory = (service_factory_pt)hashMap_get(admin->localPublications,scope_topic);
+ if(factory!=NULL){
+ topic_publication_pt pub = (topic_publication_pt)factory->handle;
+ pubsub_topicPublicationRemovePublisherEP(pub,pubEP);
+ }
+ celixThreadMutex_unlock(&admin->localPublicationsLock);
+
+ if(factory==NULL){
+ /* Maybe the endpoint was pending */
+ celixThreadMutex_lock(&admin->noSerializerPendingsLock);
+ if(!arrayList_removeElement(admin->noSerializerPublications, pubEP)){
+ status = CELIX_ILLEGAL_STATE;
+ }
+ celixThreadMutex_unlock(&admin->noSerializerPendingsLock);
+ }
+
+ }
+ else{
+
+ celixThreadMutex_lock(&admin->externalPublicationsLock);
+ array_list_pt ext_pub_list = (array_list_pt)hashMap_get(admin->externalPublications,scope_topic);
+ if(ext_pub_list!=NULL){
+ int i;
+ bool found = false;
+ for(i=0;!found && i<arrayList_size(ext_pub_list);i++){
+ pubsub_endpoint_pt p = (pubsub_endpoint_pt)arrayList_get(ext_pub_list,i);
+ found = pubsubEndpoint_equals(pubEP,p);
+ if (found){
+ arrayList_remove(ext_pub_list,i);
+ }
+ }
+ // Check if there are more publishers on the same endpoint (happens when 1 celix-instance with multiple bundles publish in same topic)
+ for(i=0; i<arrayList_size(ext_pub_list);i++) {
+ pubsub_endpoint_pt p = (pubsub_endpoint_pt)arrayList_get(ext_pub_list,i);
+ if (strcmp(pubEP->endpoint,p->endpoint) == 0) {
+ count++;
+ }
+ }
+
+ if(arrayList_size(ext_pub_list)==0){
+ hash_map_entry_pt entry = hashMap_getEntry(admin->externalPublications,scope_topic);
+ char* topic = (char*)hashMapEntry_getKey(entry);
+ array_list_pt list = (array_list_pt)hashMapEntry_getValue(entry);
+ hashMap_remove(admin->externalPublications,topic);
+ arrayList_destroy(list);
+ free(topic);
+ }
+ }
+
+ celixThreadMutex_unlock(&admin->externalPublicationsLock);
+ }
+
+ /* Check if this publisher was connected to one of our subscribers*/
+ celixThreadMutex_lock(&admin->subscriptionsLock);
+
+ topic_subscription_pt sub = (topic_subscription_pt)hashMap_get(admin->subscriptions,scope_topic);
+ if(sub!=NULL && pubEP->endpoint!=NULL && count == 0){
+ pubsub_topicSubscriptionAddDisconnectPublisherToPendingList(sub,pubEP->endpoint);
+ }
+
+ /* And check also for ANY subscription */
+ topic_subscription_pt any_sub = (topic_subscription_pt)hashMap_get(admin->subscriptions,PUBSUB_ANY_SUB_TOPIC);
+ if(any_sub!=NULL && pubEP->endpoint!=NULL && count == 0){
+ pubsub_topicSubscriptionAddDisconnectPublisherToPendingList(any_sub,pubEP->endpoint);
+ }
+
+ free(scope_topic);
+ celixThreadMutex_unlock(&admin->subscriptionsLock);
+
+ return status;
+
+}
+
+celix_status_t pubsubAdmin_closeAllPublications(pubsub_admin_pt admin,char *scope, char* topic){
+ celix_status_t status = CELIX_SUCCESS;
+
+ printf("PSA_UDP_MC: Closing all publications for scope=%s,topic=%s\n", scope, topic);
+
+ celixThreadMutex_lock(&admin->localPublicationsLock);
+ char* scope_topic =createScopeTopicKey(scope, topic);
+ hash_map_entry_pt pubsvc_entry = (hash_map_entry_pt)hashMap_getEntry(admin->localPublications,scope_topic);
+ if(pubsvc_entry!=NULL){
+ char* key = (char*)hashMapEntry_getKey(pubsvc_entry);
+ service_factory_pt factory= (service_factory_pt)hashMapEntry_getValue(pubsvc_entry);
+ topic_publication_pt pub = (topic_publication_pt)factory->handle;
+ status += pubsub_topicPublicationStop(pub);
+ disconnectTopicPubSubFromSerializer(admin, pub, true);
+ status += pubsub_topicPublicationDestroy(pub);
+ hashMap_remove(admin->localPublications,scope_topic);
+ free(key);
+ free(factory);
+ }
+ free(scope_topic);
+ celixThreadMutex_unlock(&admin->localPublicationsLock);
+
+ return status;
+
+}
+
+celix_status_t pubsubAdmin_closeAllSubscriptions(pubsub_admin_pt admin,char *scope, char* topic){
+ celix_status_t status = CELIX_SUCCESS;
+
+ printf("PSA_UDP_MC: Closing all subscriptions\n");
+
+ celixThreadMutex_lock(&admin->subscriptionsLock);
+ char* scope_topic =createScopeTopicKey(scope, topic);
+ hash_map_entry_pt sub_entry = (hash_map_entry_pt)hashMap_getEntry(admin->subscriptions,scope_topic);
+ if(sub_entry!=NULL){
+ char* topic = (char*)hashMapEntry_getKey(sub_entry);
+
+ topic_subscription_pt ts = (topic_subscription_pt)hashMapEntry_getValue(sub_entry);
+ status += pubsub_topicSubscriptionStop(ts);
+ disconnectTopicPubSubFromSerializer(admin, ts, false);
+ status += pubsub_topicSubscriptionDestroy(ts);
+ hashMap_remove(admin->subscriptions,topic);
+ free(topic);
+
+ }
+ free(scope_topic);
+ celixThreadMutex_unlock(&admin->subscriptionsLock);
+
+ return status;
+
+}
+
+
+#ifndef ANDROID
+static celix_status_t pubsubAdmin_getIpAddress(const char* interface, char** ip) {
+ celix_status_t status = CELIX_BUNDLE_EXCEPTION;
+
+ struct ifaddrs *ifaddr, *ifa;
+ char host[NI_MAXHOST];
+
+ if (getifaddrs(&ifaddr) != -1)
+ {
+ for (ifa = ifaddr; ifa != NULL && status != CELIX_SUCCESS; ifa = ifa->ifa_next)
+ {
+ if (ifa->ifa_addr == NULL)
+ continue;
+
+ if ((getnameinfo(ifa->ifa_addr,sizeof(struct sockaddr_in), host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST) == 0) && (ifa->ifa_addr->sa_family == AF_INET)) {
+ if (interface == NULL) {
+ *ip = strdup(host);
+ status = CELIX_SUCCESS;
+ }
+ else if (strcmp(ifa->ifa_name, interface) == 0) {
+ *ip = strdup(host);
+ status = CELIX_SUCCESS;
+ }
+ }
+ }
+
+ freeifaddrs(ifaddr);
+ }
+
+ return status;
+}
+#endif
+
+static celix_status_t pubsubAdmin_addSubscriptionToPendingList(pubsub_admin_pt admin,pubsub_endpoint_pt subEP){
+ celix_status_t status = CELIX_SUCCESS;
+
+ char* scope_topic =createScopeTopicKey(subEP->scope, subEP->topic);
+ array_list_pt pendingListPerTopic = hashMap_get(admin->pendingSubscriptions,scope_topic);
+ if(pendingListPerTopic==NULL){
+ arrayList_create(&pendingListPerTopic);
+ hashMap_put(admin->pendingSubscriptions,strdup(scope_topic),pendingListPerTopic);
+ }
+ arrayList_add(pendingListPerTopic,subEP);
+ free(scope_topic);
+
+ return status;
+}
+
+
+celix_status_t pubsubAdmin_serializerAdded(void * handle, service_reference_pt reference, void * service){
+ /* Assumption: serializers are all available at startup.
+ * If a new (possibly better) serializer is installed and started, already created topic_publications/subscriptions will not be destroyed and recreated */
+
+ celix_status_t status = CELIX_SUCCESS;
+ int i=0;
+
+ const char *serType = NULL;
+ serviceReference_getProperty(reference, PUBSUB_SERIALIZER_TYPE_KEY,&serType);
+ if(serType == NULL){
+ printf("Serializer serviceReference %p has no pubsub_serializer.type property specified\n",reference);
+ return CELIX_SERVICE_EXCEPTION;
+ }
+
+ pubsub_admin_pt admin = (pubsub_admin_pt)handle;
+ celixThreadMutex_lock(&admin->serializerListLock);
+ arrayList_add(admin->serializerList, reference);
+ celixThreadMutex_unlock(&admin->serializerListLock);
+
+ /* Now let's re-evaluate the pending */
+ celixThreadMutex_lock(&admin->noSerializerPendingsLock);
+
+ for(i=0;i<arrayList_size(admin->noSerializerSubscriptions);i++){
+ pubsub_endpoint_pt ep = (pubsub_endpoint_pt)arrayList_get(admin->noSerializerSubscriptions,i);
+ pubsub_serializer_service_t *best_serializer = NULL;
+ pubsubAdmin_getBestSerializer(admin, ep, &best_serializer);
+ if(best_serializer != NULL){ /* Finally we have a valid serializer! */
+ pubsubAdmin_addSubscription(admin, ep);
+ }
+ }
+
+ for(i=0;i<arrayList_size(admin->noSerializerPublications);i++){
+ pubsub_endpoint_pt ep = (pubsub_endpoint_pt)arrayList_get(admin->noSerializerPublications,i);
+ pubsub_serializer_service_t *best_serializer = NULL;
+ pubsubAdmin_getBestSerializer(admin, ep, &best_serializer);
+ if(best_serializer != NULL){ /* Finally we have a valid serializer! */
+ pubsubAdmin_addPublication(admin, ep);
+ }
+ }
+
+ celixThreadMutex_unlock(&admin->noSerializerPendingsLock);
+
+ printf("PSA_UDP_MC: %s serializer added\n",serType);
+
+ return status;
+}
+
+celix_status_t pubsubAdmin_serializerRemoved(void * handle, service_reference_pt reference, void * service){
+
+ pubsub_admin_pt admin = (pubsub_admin_pt)handle;
+ int i=0, j=0;
+ const char *serType = NULL;
+
+ serviceReference_getProperty(reference, PUBSUB_SERIALIZER_TYPE_KEY,&serType);
+ if(serType == NULL){
+ printf("Serializer serviceReference %p has no pubsub_serializer.type property specified\n",reference);
+ return CELIX_SERVICE_EXCEPTION;
+ }
+
+ celixThreadMutex_lock(&admin->serializerListLock);
+ /* Remove the serializer from the list */
+ arrayList_removeElement(admin->serializerList, reference);
+ celixThreadMutex_unlock(&admin->serializerListLock);
+
+ celixThreadMutex_lock(&admin->usedSerializersLock);
+ array_list_pt topicPubList = (array_list_pt)hashMap_remove(admin->topicPublicationsPerSerializer, service);
+ array_list_pt topicSubList = (array_list_pt)hashMap_remove(admin->topicSubscriptionsPerSerializer, service);
+ celixThreadMutex_unlock(&admin->usedSerializersLock);
+
+ /* Now destroy the topicPublications, but first put back the pubsub_endpoints back to the noSerializer pending list */
+ if(topicPubList!=NULL){
+ for(i=0;i<arrayList_size(topicPubList);i++){
+ topic_publication_pt topicPub = (topic_publication_pt)arrayList_get(topicPubList,i);
+ /* Stop the topic publication */
+ pubsub_topicPublicationStop(topicPub);
+ /* Get the endpoints that are going to be orphan */
+ array_list_pt pubList = pubsub_topicPublicationGetPublisherList(topicPub);
+ for(j=0;j<arrayList_size(pubList);j++){
+ pubsub_endpoint_pt pubEP = (pubsub_endpoint_pt)arrayList_get(pubList,j);
+ /* Remove the publication */
+ pubsubAdmin_removePublication(admin, pubEP);
+ /* Reset the endpoint field, so that will be recreated from scratch when a new serializer will be found */
+ if(pubEP->endpoint!=NULL){
+ free(pubEP->endpoint);
+ pubEP->endpoint = NULL;
+ }
+ /* Add the orphan endpoint to the noSerializer pending list */
+ celixThreadMutex_lock(&admin->noSerializerPendingsLock);
+ arrayList_add(admin->noSerializerPublications,pubEP);
+ celixThreadMutex_unlock(&admin->noSerializerPendingsLock);
+ }
+ arrayList_destroy(pubList);
+
+ /* Cleanup also the localPublications hashmap*/
+ celixThreadMutex_lock(&admin->localPublicationsLock);
+ hash_map_iterator_pt iter = hashMapIterator_create(admin->localPublications);
+ char *key = NULL;
+ service_factory_pt factory = NULL;
+ while(hashMapIterator_hasNext(iter)){
+ hash_map_entry_pt entry = hashMapIterator_nextEntry(iter);
+ factory = (service_factory_pt)hashMapEntry_getValue(entry);
+ topic_publication_pt pub = (topic_publication_pt)factory->handle;
+ if(pub==topicPub){
+ key = (char*)hashMapEntry_getKey(entry);
+ break;
+ }
+ }
+ hashMapIterator_destroy(iter);
+ if(key!=NULL){
+ hashMap_remove(admin->localPublications, key);
+ free(factory);
+ free(key);
+ }
+ celixThreadMutex_unlock(&admin->localPublicationsLock);
+
+ /* Finally destroy the topicPublication */
+ pubsub_topicPublicationDestroy(topicPub);
+ }
+ arrayList_destroy(topicPubList);
+ }
+
+ /* Now destroy the topicSubscriptions, but first put back the pubsub_endpoints back to the noSerializer pending list */
+ if(topicSubList!=NULL){
+ for(i=0;i<arrayList_size(topicSubList);i++){
+ topic_subscription_pt topicSub = (topic_subscription_pt)arrayList_get(topicSubList,i);
+ /* Stop the topic subscription */
+ pubsub_topicSubscriptionStop(topicSub);
+ /* Get the endpoints that are going to be orphan */
+ array_list_pt subList = pubsub_topicSubscriptionGetSubscribersList(topicSub);
+ for(j=0;j<arrayList_size(subList);j++){
+ pubsub_endpoint_pt subEP = (pubsub_endpoint_pt)arrayList_get(subList,j);
+ /* Remove the subscription */
+ pubsubAdmin_removeSubscription(admin, subEP);
+ /* Reset the endpoint field, so that will be recreated from scratch when a new serializer will be found */
+ if(subEP->endpoint!=NULL){
+ free(subEP->endpoint);
+ subEP->endpoint = NULL;
+ }
+ /* Add the orphan endpoint to the noSerializer pending list */
+ celixThreadMutex_lock(&admin->noSerializerPendingsLock);
+ arrayList_add(admin->noSerializerSubscriptions,subEP);
+ celixThreadMutex_unlock(&admin->noSerializerPendingsLock);
+ }
+
+ /* Cleanup also the subscriptions hashmap*/
+ celixThreadMutex_lock(&admin->subscriptionsLock);
+ hash_map_iterator_pt iter = hashMapIterator_create(admin->subscriptions);
+ char *key = NULL;
+ while(hashMapIterator_hasNext(iter)){
+ hash_map_entry_pt entry = hashMapIterator_nextEntry(iter);
+ topic_subscription_pt sub = (topic_subscription_pt)hashMapEntry_getValue(entry);
+ if(sub==topicSub){
+ key = (char*)hashMapEntry_getKey(entry);
+ break;
+ }
+ }
+ hashMapIterator_destroy(iter);
+ if(key!=NULL){
+ hashMap_remove(admin->subscriptions, key);
+ free(key);
+ }
+ celixThreadMutex_unlock(&admin->subscriptionsLock);
+
+ /* Finally destroy the topicSubscription */
+ pubsub_topicSubscriptionDestroy(topicSub);
+ }
+ arrayList_destroy(topicSubList);
+ }
+
+ printf("PSA_UDP_MC: %s serializer removed\n",serType);
+
+
+ return CELIX_SUCCESS;
+}
+
+celix_status_t pubsubAdmin_matchEndpoint(pubsub_admin_pt admin, pubsub_endpoint_pt endpoint, double* score){
+ celix_status_t status = CELIX_SUCCESS;
+
+ celixThreadMutex_lock(&admin->serializerListLock);
+ status = pubsub_admin_match(endpoint->topic_props,PUBSUB_ADMIN_TYPE,admin->serializerList,score);
+ celixThreadMutex_unlock(&admin->serializerListLock);
+
+ return status;
+}
+
+/* This one recall the same logic as in the match function */
+static celix_status_t pubsubAdmin_getBestSerializer(pubsub_admin_pt admin,pubsub_endpoint_pt ep, pubsub_serializer_service_t **serSvc){
+
+ celix_status_t status = CELIX_SUCCESS;
+
+ celixThreadMutex_lock(&admin->serializerListLock);
+ status = pubsub_admin_get_best_serializer(ep->topic_props, admin->serializerList, serSvc);
+ celixThreadMutex_unlock(&admin->serializerListLock);
+
+ return status;
+
+}
+
+static void connectTopicPubSubToSerializer(pubsub_admin_pt admin,pubsub_serializer_service_t *serializer,void *topicPubSub,bool isPublication){
+
+ celixThreadMutex_lock(&admin->usedSerializersLock);
+
+ hash_map_pt map = isPublication?admin->topicPublicationsPerSerializer:admin->topicSubscriptionsPerSerializer;
+ array_list_pt list = (array_list_pt)hashMap_get(map,serializer);
+ if(list==NULL){
+ arrayList_create(&list);
+ hashMap_put(map,serializer,list);
+ }
+ arrayList_add(list,topicPubSub);
+
+ celixThreadMutex_unlock(&admin->usedSerializersLock);
+
+}
+
+static void disconnectTopicPubSubFromSerializer(pubsub_admin_pt admin,void *topicPubSub,bool isPublication){
+
+ celixThreadMutex_lock(&admin->usedSerializersLock);
+
+ hash_map_pt map = isPublication?admin->topicPublicationsPerSerializer:admin->topicSubscriptionsPerSerializer;
+ hash_map_iterator_pt iter = hashMapIterator_create(map);
+ while(hashMapIterator_hasNext(iter)){
+ array_list_pt list = (array_list_pt)hashMapIterator_nextValue(iter);
+ if(arrayList_removeElement(list, topicPubSub)){ //Found it!
+ break;
+ }
+ }
+ hashMapIterator_destroy(iter);
+
+ celixThreadMutex_unlock(&admin->usedSerializersLock);
+
+}
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/pubsub/pubsub_admin_udp_mc/src/pubsub_admin_impl.h
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_admin_udp_mc/src/pubsub_admin_impl.h b/pubsub/pubsub_admin_udp_mc/src/pubsub_admin_impl.h
new file mode 100644
index 0000000..de4b813
--- /dev/null
+++ b/pubsub/pubsub_admin_udp_mc/src/pubsub_admin_impl.h
@@ -0,0 +1,93 @@
+/**
+ *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.
+ */
+/*
+ * pubsub_admin_impl.h
+ *
+ * \date Dec 5, 2013
+ * \author <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ * \copyright Apache License, Version 2.0
+ */
+
+#ifndef PUBSUB_ADMIN_UDP_MC_IMPL_H_
+#define PUBSUB_ADMIN_UDP_MC_IMPL_H_
+
+#include "pubsub_admin.h"
+#include "log_helper.h"
+
+#define PUBSUB_ADMIN_TYPE "udp_mc"
+
+struct pubsub_admin {
+
+ bundle_context_pt bundle_context;
+ log_helper_pt loghelper;
+
+ /* List of the available serializers */
+ celix_thread_mutex_t serializerListLock; // List<serializers>
+ array_list_pt serializerList;
+
+ celix_thread_mutex_t localPublicationsLock;
+ hash_map_pt localPublications;//<topic(string),service_factory_pt>
+
+ celix_thread_mutex_t externalPublicationsLock;
+ hash_map_pt externalPublications;//<topic(string),List<pubsub_ep>>
+
+ celix_thread_mutex_t subscriptionsLock;
+ hash_map_pt subscriptions; //<topic(string),topic_subscription>
+
+ celix_thread_mutex_t pendingSubscriptionsLock;
+ celix_thread_mutexattr_t pendingSubscriptionsAttr;
+ hash_map_pt pendingSubscriptions; //<topic(string),List<pubsub_ep>>
+
+ /* Those are used to keep track of valid subscriptions/publications that still have no valid serializer */
+ celix_thread_mutex_t noSerializerPendingsLock;
+ celix_thread_mutexattr_t noSerializerPendingsAttr;
+ array_list_pt noSerializerSubscriptions; // List<pubsub_ep>
+ array_list_pt noSerializerPublications; // List<pubsub_ep>
+
+ celix_thread_mutex_t usedSerializersLock;
+ hash_map_pt topicSubscriptionsPerSerializer; // <serializer,List<topicSubscription>>
+ hash_map_pt topicPublicationsPerSerializer; // <serializer,List<topicPublications>>
+
+ char* ifIpAddress; // The local interface which is used for multicast communication
+ char* mcIpAddress; // The multicast IP address
+
+ int sendSocket;
+ void* zmq_context; // to be removed
+
+};
+
+celix_status_t pubsubAdmin_create(bundle_context_pt context, pubsub_admin_pt *admin);
+celix_status_t pubsubAdmin_destroy(pubsub_admin_pt admin);
+
+celix_status_t pubsubAdmin_addSubscription(pubsub_admin_pt admin,pubsub_endpoint_pt subEP);
+celix_status_t pubsubAdmin_removeSubscription(pubsub_admin_pt admin,pubsub_endpoint_pt subEP);
+
+celix_status_t pubsubAdmin_addPublication(pubsub_admin_pt admin,pubsub_endpoint_pt pubEP);
+celix_status_t pubsubAdmin_removePublication(pubsub_admin_pt admin,pubsub_endpoint_pt pubEP);
+
+celix_status_t pubsubAdmin_closeAllPublications(pubsub_admin_pt admin,char* scope, char* topic);
+celix_status_t pubsubAdmin_closeAllSubscriptions(pubsub_admin_pt admin,char* scope, char* topic);
+
+celix_status_t pubsubAdmin_serializerAdded(void * handle, service_reference_pt reference, void * service);
+celix_status_t pubsubAdmin_serializerRemoved(void * handle, service_reference_pt reference, void * service);
+
+celix_status_t pubsubAdmin_matchEndpoint(pubsub_admin_pt admin, pubsub_endpoint_pt endpoint, double* score);
+
+
+#endif /* PUBSUB_ADMIN_UDP_MC_IMPL_H_ */
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/pubsub/pubsub_admin_udp_mc/src/topic_publication.c
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_admin_udp_mc/src/topic_publication.c b/pubsub/pubsub_admin_udp_mc/src/topic_publication.c
new file mode 100644
index 0000000..e43ec29
--- /dev/null
+++ b/pubsub/pubsub_admin_udp_mc/src/topic_publication.c
@@ -0,0 +1,444 @@
+/**
+ *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
+ *
+ * htPSA_UDP_MC_TP://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.
+ */
+/*
+ * topic_publication.c
+ *
+ * \date Sep 24, 2015
+ * \author <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ * \copyright Apache License, Version 2.0
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#include "array_list.h"
+#include "celixbool.h"
+#include "service_registration.h"
+#include "utils.h"
+#include "service_factory.h"
+#include "version.h"
+
+#include "topic_publication.h"
+#include "pubsub_common.h"
+#include "publisher.h"
+#include "large_udp.h"
+
+#include "pubsub_serializer.h"
+
+#define EP_ADDRESS_LEN 32
+
+#define FIRST_SEND_DELAY 2
+
+struct topic_publication {
+ int sendSocket;
+ char* endpoint;
+ service_registration_pt svcFactoryReg;
+ array_list_pt pub_ep_list; //List<pubsub_endpoint>
+ hash_map_pt boundServices; //<bundle_pt,bound_service>
+ celix_thread_mutex_t tp_lock;
+ pubsub_serializer_service_t *serializer;
+ struct sockaddr_in destAddr;
+};
+
+typedef struct publish_bundle_bound_service {
+ topic_publication_pt parent;
+ pubsub_publisher_t service;
+ bundle_pt bundle;
+ char *scope;
+ char *topic;
+ hash_map_pt msgTypes;
+ unsigned short getCount;
+ celix_thread_mutex_t mp_lock;
+ largeUdp_pt largeUdpHandle;
+}* publish_bundle_bound_service_pt;
+
+
+typedef struct pubsub_msg{
+ pubsub_msg_header_pt header;
+ char* payload;
+ unsigned int payloadSize;
+} pubsub_msg_t;
+
+
+static unsigned int rand_range(unsigned int min, unsigned int max);
+
+static celix_status_t pubsub_topicPublicationGetService(void* handle, bundle_pt bundle, service_registration_pt registration, void **service);
+static celix_status_t pubsub_topicPublicationUngetService(void* handle, bundle_pt bundle, service_registration_pt registration, void **service);
+
+static publish_bundle_bound_service_pt pubsub_createPublishBundleBoundService(topic_publication_pt tp,bundle_pt bundle);
+static void pubsub_destroyPublishBundleBoundService(publish_bundle_bound_service_pt boundSvc);
+
+static int pubsub_topicPublicationSend(void* handle,unsigned int msgTypeId, const void *msg);
+
+static int pubsub_localMsgTypeIdForUUID(void* handle, const char* msgType, unsigned int* msgTypeId);
+
+
+static void delay_first_send_for_late_joiners(void);
+
+
+celix_status_t pubsub_topicPublicationCreate(int sendSocket, pubsub_endpoint_pt pubEP, pubsub_serializer_service_t *best_serializer, char* bindIP, topic_publication_pt *out){
+
+ char* ep = malloc(EP_ADDRESS_LEN);
+ memset(ep,0,EP_ADDRESS_LEN);
+ unsigned int port = pubEP->serviceID + rand_range(UDP_BASE_PORT+pubEP->serviceID+3, UDP_MAX_PORT);
+ snprintf(ep,EP_ADDRESS_LEN,"udp://%s:%u",bindIP,port);
+
+
+ topic_publication_pt pub = calloc(1,sizeof(*pub));
+
+ arrayList_create(&(pub->pub_ep_list));
+ pub->boundServices = hashMap_create(NULL,NULL,NULL,NULL);
+ celixThreadMutex_create(&(pub->tp_lock),NULL);
+
+ pub->endpoint = ep;
+ pub->sendSocket = sendSocket;
+ pub->destAddr.sin_family = AF_INET;
+ pub->destAddr.sin_addr.s_addr = inet_addr(bindIP);
+ pub->destAddr.sin_port = htons(port);
+
+ pub->serializer = best_serializer;
+
+ pubsub_topicPublicationAddPublisherEP(pub,pubEP);
+
+ *out = pub;
+
+ return CELIX_SUCCESS;
+}
+
+celix_status_t pubsub_topicPublicationDestroy(topic_publication_pt pub){
+ celix_status_t status = CELIX_SUCCESS;
+
+ celixThreadMutex_lock(&(pub->tp_lock));
+
+ free(pub->endpoint);
+ arrayList_destroy(pub->pub_ep_list);
+
+ hash_map_iterator_pt iter = hashMapIterator_create(pub->boundServices);
+ while(hashMapIterator_hasNext(iter)){
+ publish_bundle_bound_service_pt bound = hashMapIterator_nextValue(iter);
+ pubsub_destroyPublishBundleBoundService(bound);
+ }
+ hashMapIterator_destroy(iter);
+ hashMap_destroy(pub->boundServices,false,false);
+
+ pub->svcFactoryReg = NULL;
+ pub->serializer = NULL;
+
+ if(close(pub->sendSocket) != 0){
+ status = CELIX_FILE_IO_EXCEPTION;
+ }
+
+ celixThreadMutex_unlock(&(pub->tp_lock));
+
+ celixThreadMutex_destroy(&(pub->tp_lock));
+
+ free(pub);
+
+ return status;
+}
+
+celix_status_t pubsub_topicPublicationStart(bundle_context_pt bundle_context,topic_publication_pt pub,service_factory_pt* svcFactory){
+ celix_status_t status = CELIX_SUCCESS;
+
+ /* Let's register the new service */
+
+ pubsub_endpoint_pt pubEP = (pubsub_endpoint_pt)arrayList_get(pub->pub_ep_list,0);
+
+ if(pubEP!=NULL){
+ service_factory_pt factory = calloc(1, sizeof(*factory));
+ factory->handle = pub;
+ factory->getService = pubsub_topicPublicationGetService;
+ factory->ungetService = pubsub_topicPublicationUngetService;
+
+ properties_pt props = properties_create();
+ properties_set(props,PUBSUB_PUBLISHER_SCOPE,pubEP->scope);
+ properties_set(props,PUBSUB_PUBLISHER_TOPIC,pubEP->topic);
+
+ status = bundleContext_registerServiceFactory(bundle_context,PUBSUB_PUBLISHER_SERVICE_NAME,factory,props,&(pub->svcFactoryReg));
+
+ if(status != CELIX_SUCCESS){
+ properties_destroy(props);
+ printf("PSA_UDP_MC_PSA_UDP_MC_TP: Cannot register ServiceFactory for topic %s, topic %s (bundle %ld).\n",pubEP->scope, pubEP->topic,pubEP->serviceID);
+ }
+ else{
+ *svcFactory = factory;
+ }
+ }
+ else{
+ printf("PSA_UDP_MC_PSA_UDP_MC_TP: Cannot find pubsub_endpoint after adding it...Should never happen!\n");
+ status = CELIX_SERVICE_EXCEPTION;
+ }
+
+ return status;
+}
+
+celix_status_t pubsub_topicPublicationStop(topic_publication_pt pub){
+ return serviceRegistration_unregister(pub->svcFactoryReg);
+}
+
+celix_status_t pubsub_topicPublicationAddPublisherEP(topic_publication_pt pub,pubsub_endpoint_pt ep){
+
+ celixThreadMutex_lock(&(pub->tp_lock));
+ ep->endpoint = strdup(pub->endpoint);
+ arrayList_add(pub->pub_ep_list,ep);
+ celixThreadMutex_unlock(&(pub->tp_lock));
+
+ return CELIX_SUCCESS;
+}
+
+celix_status_t pubsub_topicPublicationRemovePublisherEP(topic_publication_pt pub,pubsub_endpoint_pt ep){
+
+ celixThreadMutex_lock(&(pub->tp_lock));
+ arrayList_removeElement(pub->pub_ep_list,ep);
+ celixThreadMutex_unlock(&(pub->tp_lock));
+
+ return CELIX_SUCCESS;
+}
+
+array_list_pt pubsub_topicPublicationGetPublisherList(topic_publication_pt pub){
+ array_list_pt list = NULL;
+ celixThreadMutex_lock(&(pub->tp_lock));
+ list = arrayList_clone(pub->pub_ep_list);
+ celixThreadMutex_unlock(&(pub->tp_lock));
+ return list;
+}
+
+
+static celix_status_t pubsub_topicPublicationGetService(void* handle, bundle_pt bundle, service_registration_pt registration, void **service) {
+ celix_status_t status = CELIX_SUCCESS;
+
+ topic_publication_pt publish = (topic_publication_pt)handle;
+
+ celixThreadMutex_lock(&(publish->tp_lock));
+
+ publish_bundle_bound_service_pt bound = (publish_bundle_bound_service_pt)hashMap_get(publish->boundServices,bundle);
+ if(bound==NULL){
+ bound = pubsub_createPublishBundleBoundService(publish,bundle);
+ if(bound!=NULL){
+ hashMap_put(publish->boundServices,bundle,bound);
+ }
+ }
+ else{
+ bound->getCount++;
+ }
+
+ if (bound != NULL) {
+ *service = &bound->service;
+ }
+
+ celixThreadMutex_unlock(&(publish->tp_lock));
+
+ return status;
+}
+
+static celix_status_t pubsub_topicPublicationUngetService(void* handle, bundle_pt bundle, service_registration_pt registration, void **service) {
+
+ topic_publication_pt publish = (topic_publication_pt)handle;
+
+ celixThreadMutex_lock(&(publish->tp_lock));
+
+ publish_bundle_bound_service_pt bound = (publish_bundle_bound_service_pt)hashMap_get(publish->boundServices,bundle);
+ if(bound!=NULL){
+
+ bound->getCount--;
+ if(bound->getCount==0){
+ pubsub_destroyPublishBundleBoundService(bound);
+ hashMap_remove(publish->boundServices,bundle);
+ }
+
+ }
+ else{
+ long bundleId = -1;
+ bundle_getBundleId(bundle,&bundleId);
+ printf("PSA_UDP_MC_TP: Unexpected ungetService call for bundle %ld.\n", bundleId);
+ }
+
+ /* service should be never used for unget, so let's set the pointer to NULL */
+ *service = NULL;
+
+ celixThreadMutex_unlock(&(publish->tp_lock));
+
+ return CELIX_SUCCESS;
+}
+
+static bool send_pubsub_msg(publish_bundle_bound_service_pt bound, pubsub_msg_t* msg, bool last, pubsub_release_callback_t *releaseCallback){
+ const int iovec_len = 3; // header + size + payload
+ bool ret = true;
+
+ struct iovec msg_iovec[iovec_len];
+ msg_iovec[0].iov_base = msg->header;
+ msg_iovec[0].iov_len = sizeof(*msg->header);
+ msg_iovec[1].iov_base = &msg->payloadSize;
+ msg_iovec[1].iov_len = sizeof(msg->payloadSize);
+ msg_iovec[2].iov_base = msg->payload;
+ msg_iovec[2].iov_len = msg->payloadSize;
+
+ delay_first_send_for_late_joiners();
+
+ if(largeUdp_sendmsg(bound->largeUdpHandle, bound->parent->sendSocket, msg_iovec, iovec_len, 0, &bound->parent->destAddr, sizeof(bound->parent->destAddr)) == -1) {
+ perror("send_pubsub_msg:sendSocket");
+ ret = false;
+ }
+
+ if(releaseCallback) {
+ releaseCallback->release(msg->payload, bound);
+ }
+ return ret;
+
+}
+
+
+static int pubsub_topicPublicationSend(void* handle, unsigned int msgTypeId, const void *inMsg) {
+ int status = 0;
+ publish_bundle_bound_service_pt bound = (publish_bundle_bound_service_pt) handle;
+
+ celixThreadMutex_lock(&(bound->parent->tp_lock));
+ celixThreadMutex_lock(&(bound->mp_lock));
+
+ pubsub_msg_serializer_t* msgSer = (pubsub_msg_serializer_t*)hashMap_get(bound->msgTypes, (void*)(uintptr_t)msgTypeId);
+
+ if (msgSer != NULL) {
+ int major=0, minor=0;
+
+ pubsub_msg_header_pt msg_hdr = calloc(1,sizeof(struct pubsub_msg_header));
+ strncpy(msg_hdr->topic,bound->topic,MAX_TOPIC_LEN-1);
+ msg_hdr->type = msgTypeId;
+
+
+ if (msgSer->msgVersion != NULL){
+ version_getMajor(msgSer->msgVersion, &major);
+ version_getMinor(msgSer->msgVersion, &minor);
+ msg_hdr->major = major;
+ msg_hdr->minor = minor;
+ }
+
+ void* serializedOutput = NULL;
+ size_t serializedOutputLen = 0;
+ msgSer->serialize(msgSer,inMsg,&serializedOutput, &serializedOutputLen);
+
+ pubsub_msg_t *msg = calloc(1,sizeof(pubsub_msg_t));
+ msg->header = msg_hdr;
+ msg->payload = (char*)serializedOutput;
+ msg->payloadSize = serializedOutputLen;
+
+
+ if(send_pubsub_msg(bound, msg,true, NULL) == false) {
+ status = -1;
+ }
+ free(msg_hdr);
+ free(msg);
+ free(serializedOutput);
+
+
+ } else {
+ printf("PSA_UDP_MC_TP: No msg serializer available for msg type id %d\n", msgTypeId);
+ status=-1;
+ }
+
+ celixThreadMutex_unlock(&(bound->mp_lock));
+ celixThreadMutex_unlock(&(bound->parent->tp_lock));
+
+ return status;
+}
+
+static int pubsub_localMsgTypeIdForUUID(void* handle, const char* msgType, unsigned int* msgTypeId){
+ *msgTypeId = utils_stringHash(msgType);
+ return 0;
+}
+
+
+static unsigned int rand_range(unsigned int min, unsigned int max){
+
+ double scaled = (double)(((double)random())/((double)RAND_MAX));
+ return (max-min+1)*scaled + min;
+
+}
+
+static publish_bundle_bound_service_pt pubsub_createPublishBundleBoundService(topic_publication_pt tp,bundle_pt bundle){
+
+ publish_bundle_bound_service_pt bound = calloc(1, sizeof(*bound));
+
+ if (bound != NULL) {
+
+ bound->parent = tp;
+ bound->bundle = bundle;
+ bound->getCount = 1;
+ celixThreadMutex_create(&bound->mp_lock,NULL);
+
+ if(tp->serializer != NULL){
+ tp->serializer->createSerializerMap(tp->serializer->handle,bundle,&bound->msgTypes);
+ }
+
+ pubsub_endpoint_pt pubEP = (pubsub_endpoint_pt)arrayList_get(bound->parent->pub_ep_list,0);
+ bound->scope=strdup(pubEP->scope);
+ bound->topic=strdup(pubEP->topic);
+ bound->largeUdpHandle = largeUdp_create(1);
+
+ bound->service.handle = bound;
+ bound->service.localMsgTypeIdForMsgType = pubsub_localMsgTypeIdForUUID;
+ bound->service.send = pubsub_topicPublicationSend;
+ bound->service.sendMultipart = NULL; //Multipart not supported for UDP
+
+ }
+
+ return bound;
+}
+
+static void pubsub_destroyPublishBundleBoundService(publish_bundle_bound_service_pt boundSvc){
+
+ celixThreadMutex_lock(&boundSvc->mp_lock);
+
+ if(boundSvc->parent->serializer != NULL && boundSvc->msgTypes != NULL){
+ boundSvc->parent->serializer->destroySerializerMap(boundSvc->parent->serializer->handle, boundSvc->msgTypes);
+ }
+
+ if(boundSvc->scope!=NULL){
+ free(boundSvc->scope);
+ }
+
+ if(boundSvc->topic!=NULL){
+ free(boundSvc->topic);
+ }
+
+ largeUdp_destroy(boundSvc->largeUdpHandle);
+
+ celixThreadMutex_unlock(&boundSvc->mp_lock);
+ celixThreadMutex_destroy(&boundSvc->mp_lock);
+
+ free(boundSvc);
+
+}
+
+static void delay_first_send_for_late_joiners(){
+
+ static bool firstSend = true;
+
+ if(firstSend){
+ printf("PSA_UDP_MC_TP: Delaying first send for late joiners...\n");
+ sleep(FIRST_SEND_DELAY);
+ firstSend = false;
+ }
+}
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/pubsub/pubsub_admin_udp_mc/src/topic_publication.h
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_admin_udp_mc/src/topic_publication.h b/pubsub/pubsub_admin_udp_mc/src/topic_publication.h
new file mode 100644
index 0000000..4363d71
--- /dev/null
+++ b/pubsub/pubsub_admin_udp_mc/src/topic_publication.h
@@ -0,0 +1,57 @@
+/**
+ *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.
+ */
+/*
+ * topic_publication.h
+ *
+ * \date Sep 24, 2015
+ * \author <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ * \copyright Apache License, Version 2.0
+ */
+
+#ifndef TOPIC_PUBLICATION_H_
+#define TOPIC_PUBLICATION_H_
+
+#include "publisher.h"
+#include "pubsub_endpoint.h"
+#include "pubsub_common.h"
+
+#include "pubsub_serializer.h"
+
+#define UDP_BASE_PORT 49152
+#define UDP_MAX_PORT 65000
+
+typedef struct pubsub_udp_msg {
+ struct pubsub_msg_header header;
+ unsigned int payloadSize;
+ char payload[];
+} pubsub_udp_msg_t;
+
+typedef struct topic_publication *topic_publication_pt;
+celix_status_t pubsub_topicPublicationCreate(int sendSocket, pubsub_endpoint_pt pubEP, pubsub_serializer_service_t *best_serializer, char* bindIP, topic_publication_pt *out);
+celix_status_t pubsub_topicPublicationDestroy(topic_publication_pt pub);
+
+celix_status_t pubsub_topicPublicationAddPublisherEP(topic_publication_pt pub,pubsub_endpoint_pt ep);
+celix_status_t pubsub_topicPublicationRemovePublisherEP(topic_publication_pt pub,pubsub_endpoint_pt ep);
+
+celix_status_t pubsub_topicPublicationStart(bundle_context_pt bundle_context,topic_publication_pt pub,service_factory_pt* svcFactory);
+celix_status_t pubsub_topicPublicationStop(topic_publication_pt pub);
+
+array_list_pt pubsub_topicPublicationGetPublisherList(topic_publication_pt pub);
+
+#endif /* TOPIC_PUBLICATION_H_ */
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/pubsub/pubsub_admin_udp_mc/src/topic_subscription.c
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_admin_udp_mc/src/topic_subscription.c b/pubsub/pubsub_admin_udp_mc/src/topic_subscription.c
new file mode 100644
index 0000000..d8e6f45
--- /dev/null
+++ b/pubsub/pubsub_admin_udp_mc/src/topic_subscription.c
@@ -0,0 +1,635 @@
+/**
+ *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.
+ */
+/*
+ * topic_subscription.c
+ *
+ * \date Oct 2, 2015
+ * \author <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ * \copyright Apache License, Version 2.0
+ */
+
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <signal.h>
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/epoll.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#include "utils.h"
+#include "celix_errno.h"
+#include "constants.h"
+#include "version.h"
+
+#include "topic_subscription.h"
+#include "topic_publication.h"
+#include "subscriber.h"
+#include "publisher.h"
+#include "large_udp.h"
+
+#include "pubsub_serializer.h"
+
+#define MAX_EPOLL_EVENTS 10
+#define RECV_THREAD_TIMEOUT 5
+#define UDP_BUFFER_SIZE 65535
+#define MAX_UDP_SESSIONS 16
+
+struct topic_subscription{
+ char* ifIpAddress;
+ service_tracker_pt tracker;
+ array_list_pt sub_ep_list;
+ celix_thread_t recv_thread;
+ bool running;
+ celix_thread_mutex_t ts_lock;
+ bundle_context_pt context;
+
+ pubsub_serializer_service_t *serializer;
+
+ int topicEpollFd; // EPOLL filedescriptor where the sockets are registered.
+ hash_map_pt servicesMap; // key = service, value = msg types map
+ hash_map_pt socketMap; // key = URL, value = listen-socket
+ celix_thread_mutex_t socketMap_lock;
+
+ celix_thread_mutex_t pendingConnections_lock;
+ array_list_pt pendingConnections;
+
+ array_list_pt pendingDisconnections;
+ celix_thread_mutex_t pendingDisconnections_lock;
+
+ //array_list_pt rawServices;
+ unsigned int nrSubscribers;
+ largeUdp_pt largeUdpHandle;
+};
+
+typedef struct msg_map_entry{
+ bool retain;
+ void* msgInst;
+}* msg_map_entry_pt;
+
+static celix_status_t topicsub_subscriberTracked(void * handle, service_reference_pt reference, void * service);
+static celix_status_t topicsub_subscriberUntracked(void * handle, service_reference_pt reference, void * service);
+static void* udp_recv_thread_func(void* arg);
+static bool checkVersion(version_pt msgVersion,pubsub_msg_header_pt hdr);
+static void sigusr1_sighandler(int signo);
+static int pubsub_localMsgTypeIdForMsgType(void* handle, const char* msgType, unsigned int* msgTypeId);
+static void connectPendingPublishers(topic_subscription_pt sub);
+static void disconnectPendingPublishers(topic_subscription_pt sub);
+
+
+celix_status_t pubsub_topicSubscriptionCreate(bundle_context_pt bundle_context, char* ifIp,char* scope, char* topic ,pubsub_serializer_service_t *best_serializer, topic_subscription_pt* out){
+ celix_status_t status = CELIX_SUCCESS;
+
+ topic_subscription_pt ts = (topic_subscription_pt) calloc(1,sizeof(*ts));
+ ts->context = bundle_context;
+ ts->ifIpAddress = strdup(ifIp);
+#if defined(__APPLE__) && defined(__MACH__)
+ //TODO: Use kqueue for OSX
+#else
+ ts->topicEpollFd = epoll_create1(0);
+#endif
+ if(ts->topicEpollFd == -1) {
+ status += CELIX_SERVICE_EXCEPTION;
+ }
+
+ ts->running = false;
+ ts->nrSubscribers = 0;
+ ts->serializer = best_serializer;
+
+ celixThreadMutex_create(&ts->ts_lock,NULL);
+ arrayList_create(&ts->sub_ep_list);
+ ts->servicesMap = hashMap_create(NULL, NULL, NULL, NULL);
+ ts->socketMap = hashMap_create(utils_stringHash, NULL, utils_stringEquals, NULL);
+
+ arrayList_create(&ts->pendingConnections);
+ arrayList_create(&ts->pendingDisconnections);
+ celixThreadMutex_create(&ts->pendingConnections_lock, NULL);
+ celixThreadMutex_create(&ts->pendingDisconnections_lock, NULL);
+ celixThreadMutex_create(&ts->socketMap_lock, NULL);
+
+ ts->largeUdpHandle = largeUdp_create(MAX_UDP_SESSIONS);
+
+ char filter[128];
+ memset(filter,0,128);
+ if(strncmp(PUBSUB_SUBSCRIBER_SCOPE_DEFAULT, scope, strlen(PUBSUB_SUBSCRIBER_SCOPE_DEFAULT)) == 0) {
+ // default scope, means that subscriber has not defined a scope property
+ snprintf(filter, 128, "(&(%s=%s)(%s=%s))",
+ (char*) OSGI_FRAMEWORK_OBJECTCLASS, PUBSUB_SUBSCRIBER_SERVICE_NAME,
+ PUBSUB_SUBSCRIBER_TOPIC,topic);
+
+ } else {
+ snprintf(filter, 128, "(&(%s=%s)(%s=%s)(%s=%s))",
+ (char*) OSGI_FRAMEWORK_OBJECTCLASS, PUBSUB_SUBSCRIBER_SERVICE_NAME,
+ PUBSUB_SUBSCRIBER_TOPIC,topic,
+ PUBSUB_SUBSCRIBER_SCOPE,scope);
+ }
+
+ service_tracker_customizer_pt customizer = NULL;
+ status += serviceTrackerCustomizer_create(ts,NULL,topicsub_subscriberTracked,NULL,topicsub_subscriberUntracked,&customizer);
+ status += serviceTracker_createWithFilter(bundle_context, filter, customizer, &ts->tracker);
+
+ struct sigaction actions;
+ memset(&actions, 0, sizeof(actions));
+ sigemptyset(&actions.sa_mask);
+ actions.sa_flags = 0;
+ actions.sa_handler = sigusr1_sighandler;
+
+ sigaction(SIGUSR1,&actions,NULL);
+
+ if (status == CELIX_SUCCESS) {
+ *out=ts;
+ }
+
+ return status;
+}
+
+celix_status_t pubsub_topicSubscriptionDestroy(topic_subscription_pt ts){
+ celix_status_t status = CELIX_SUCCESS;
+
+ celixThreadMutex_lock(&ts->ts_lock);
+ ts->running = false;
+ free(ts->ifIpAddress);
+ serviceTracker_destroy(ts->tracker);
+ arrayList_clear(ts->sub_ep_list);
+ arrayList_destroy(ts->sub_ep_list);
+ hashMap_destroy(ts->servicesMap,false,false);
+
+ celixThreadMutex_lock(&ts->socketMap_lock);
+ hashMap_destroy(ts->socketMap,true,true);
+ celixThreadMutex_unlock(&ts->socketMap_lock);
+ celixThreadMutex_destroy(&ts->socketMap_lock);
+
+ celixThreadMutex_lock(&ts->pendingConnections_lock);
+ arrayList_destroy(ts->pendingConnections);
+ celixThreadMutex_unlock(&ts->pendingConnections_lock);
+ celixThreadMutex_destroy(&ts->pendingConnections_lock);
+
+ celixThreadMutex_lock(&ts->pendingDisconnections_lock);
+ arrayList_destroy(ts->pendingDisconnections);
+ celixThreadMutex_unlock(&ts->pendingDisconnections_lock);
+ celixThreadMutex_destroy(&ts->pendingDisconnections_lock);
+
+ largeUdp_destroy(ts->largeUdpHandle);
+#if defined(__APPLE__) && defined(__MACH__)
+ //TODO: Use kqueue for OSX
+#else
+ close(ts->topicEpollFd);
+#endif
+
+ celixThreadMutex_unlock(&ts->ts_lock);
+
+ celixThreadMutex_destroy(&ts->ts_lock);
+
+ free(ts);
+
+ return status;
+}
+
+celix_status_t pubsub_topicSubscriptionStart(topic_subscription_pt ts){
+ celix_status_t status = CELIX_SUCCESS;
+
+ status = serviceTracker_open(ts->tracker);
+
+ ts->running = true;
+
+ if(status==CELIX_SUCCESS){
+ status=celixThread_create(&ts->recv_thread,NULL,udp_recv_thread_func,ts);
+ }
+
+ return status;
+}
+
+celix_status_t pubsub_topicSubscriptionStop(topic_subscription_pt ts){
+ celix_status_t status = CELIX_SUCCESS;
+ struct epoll_event ev;
+ memset(&ev, 0, sizeof(ev));
+
+ ts->running = false;
+
+ pthread_kill(ts->recv_thread.thread,SIGUSR1);
+
+ celixThread_join(ts->recv_thread,NULL);
+
+ status = serviceTracker_close(ts->tracker);
+
+ celixThreadMutex_lock(&ts->socketMap_lock);
+ hash_map_iterator_pt it = hashMapIterator_create(ts->socketMap);
+ while(hashMapIterator_hasNext(it)) {
+ hash_map_entry_pt entry = hashMapIterator_nextEntry(it);
+ char *url = hashMapEntry_getKey(entry);
+ int *s = hashMapEntry_getValue(entry);
+ memset(&ev, 0, sizeof(ev));
+ if(epoll_ctl(ts->topicEpollFd, EPOLL_CTL_DEL, *s, &ev) == -1) {
+ printf("in if error()\n");
+ perror("epoll_ctl() EPOLL_CTL_DEL");
+ status += CELIX_SERVICE_EXCEPTION;
+ }
+ free(s);
+ free(url);
+ //hashMapIterator_remove(it);
+ }
+ hashMapIterator_destroy(it);
+ hashMap_clear(ts->socketMap, false, false);
+ celixThreadMutex_unlock(&ts->socketMap_lock);
+
+
+ return status;
+}
+
+celix_status_t pubsub_topicSubscriptionConnectPublisher(topic_subscription_pt ts, char* pubURL) {
+
+ printf("pubsub_topicSubscriptionConnectPublisher : pubURL = %s\n", pubURL);
+
+ celix_status_t status = CELIX_SUCCESS;
+
+ celixThreadMutex_lock(&ts->socketMap_lock);
+
+ if(!hashMap_containsKey(ts->socketMap, pubURL)){
+
+ int *recvSocket = calloc(sizeof(int), 1);
+ *recvSocket = socket(AF_INET, SOCK_DGRAM, 0);
+ if (*recvSocket < 0) {
+ perror("pubsub_topicSubscriptionCreate:socket");
+ status = CELIX_SERVICE_EXCEPTION;
+ }
+
+ if (status == CELIX_SUCCESS){
+ int reuse = 1;
+ if (setsockopt(*recvSocket, SOL_SOCKET, SO_REUSEADDR, (char*) &reuse, sizeof(reuse)) != 0) {
+ perror("setsockopt() SO_REUSEADDR");
+ status = CELIX_SERVICE_EXCEPTION;
+ }
+ }
+
+ if(status == CELIX_SUCCESS){
+ // TODO Check if there is a better way to parse the URL to IP/Portnr
+ //replace ':' by spaces
+ char *url = strdup(pubURL);
+ char *pt = url;
+ while((pt=strchr(pt, ':')) != NULL) {
+ *pt = ' ';
+ }
+ char mcIp[100];
+ unsigned short mcPort;
+ sscanf(url, "udp //%s %hu", mcIp, &mcPort);
+ free(url);
+
+ printf("pubsub_topicSubscriptionConnectPublisher : IP = %s, Port = %hu\n", mcIp, mcPort);
+
+ struct ip_mreq mc_addr;
+ mc_addr.imr_multiaddr.s_addr = inet_addr(mcIp);
+ mc_addr.imr_interface.s_addr = inet_addr(ts->ifIpAddress);
+ printf("Adding MC %s at interface %s\n", mcIp, ts->ifIpAddress);
+ if (setsockopt(*recvSocket, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char*) &mc_addr, sizeof(mc_addr)) != 0) {
+ perror("setsockopt() IP_ADD_MEMBERSHIP");
+ status = CELIX_SERVICE_EXCEPTION;
+ }
+
+ if (status == CELIX_SUCCESS){
+ struct sockaddr_in mcListenAddr;
+ mcListenAddr.sin_family = AF_INET;
+ mcListenAddr.sin_addr.s_addr = INADDR_ANY;
+ mcListenAddr.sin_port = htons(mcPort);
+ if(bind(*recvSocket, (struct sockaddr*)&mcListenAddr, sizeof(mcListenAddr)) != 0) {
+ perror("bind()");
+ status = CELIX_SERVICE_EXCEPTION;
+ }
+ }
+
+ if (status == CELIX_SUCCESS){
+#if defined(__APPLE__) && defined(__MACH__)
+ //TODO: Use kqueue for OSX
+#else
+ struct epoll_event ev;
+ memset(&ev, 0, sizeof(ev));
+ ev.events = EPOLLIN;
+ ev.data.fd = *recvSocket;
+ if(epoll_ctl(ts->topicEpollFd, EPOLL_CTL_ADD, *recvSocket, &ev) == -1) {
+ perror("epoll_ctl() EPOLL_CTL_ADD");
+ status = CELIX_SERVICE_EXCEPTION;
+ }
+#endif
+ }
+
+ }
+
+ if (status == CELIX_SUCCESS){
+ hashMap_put(ts->socketMap, strdup(pubURL), (void*)recvSocket);
+ }
+ else{
+ free(recvSocket);
+ }
+ }
+
+ celixThreadMutex_unlock(&ts->socketMap_lock);
+
+ return status;
+}
+
+celix_status_t pubsub_topicSubscriptionAddConnectPublisherToPendingList(topic_subscription_pt ts, char* pubURL) {
+ celix_status_t status = CELIX_SUCCESS;
+ char *url = strdup(pubURL);
+ celixThreadMutex_lock(&ts->pendingConnections_lock);
+ arrayList_add(ts->pendingConnections, url);
+ celixThreadMutex_unlock(&ts->pendingConnections_lock);
+ return status;
+}
+
+celix_status_t pubsub_topicSubscriptionAddDisconnectPublisherToPendingList(topic_subscription_pt ts, char* pubURL) {
+ celix_status_t status = CELIX_SUCCESS;
+ char *url = strdup(pubURL);
+ celixThreadMutex_lock(&ts->pendingDisconnections_lock);
+ arrayList_add(ts->pendingDisconnections, url);
+ celixThreadMutex_unlock(&ts->pendingDisconnections_lock);
+ return status;
+}
+
+celix_status_t pubsub_topicSubscriptionDisconnectPublisher(topic_subscription_pt ts, char* pubURL){
+ printf("pubsub_topicSubscriptionDisconnectPublisher : pubURL = %s\n", pubURL);
+ celix_status_t status = CELIX_SUCCESS;
+ struct epoll_event ev;
+ memset(&ev, 0, sizeof(ev));
+
+ celixThreadMutex_lock(&ts->socketMap_lock);
+
+ if (hashMap_containsKey(ts->socketMap, pubURL)){
+
+#if defined(__APPLE__) && defined(__MACH__)
+ //TODO: Use kqueue for OSX
+#else
+ int *s = hashMap_remove(ts->socketMap, pubURL);
+ if(epoll_ctl(ts->topicEpollFd, EPOLL_CTL_DEL, *s, &ev) == -1) {
+ printf("in if error()\n");
+ perror("epoll_ctl() EPOLL_CTL_DEL");
+ status = CELIX_SERVICE_EXCEPTION;
+ }
+ free(s);
+#endif
+
+ }
+
+ celixThreadMutex_unlock(&ts->socketMap_lock);
+
+ return status;
+}
+
+celix_status_t pubsub_topicSubscriptionAddSubscriber(topic_subscription_pt ts, pubsub_endpoint_pt subEP){
+ celix_status_t status = CELIX_SUCCESS;
+
+ celixThreadMutex_lock(&ts->ts_lock);
+ arrayList_add(ts->sub_ep_list,subEP);
+ celixThreadMutex_unlock(&ts->ts_lock);
+
+ return status;
+
+}
+
+celix_status_t pubsub_topicIncreaseNrSubscribers(topic_subscription_pt ts) {
+ celix_status_t status = CELIX_SUCCESS;
+
+ celixThreadMutex_lock(&ts->ts_lock);
+ ts->nrSubscribers++;
+ celixThreadMutex_unlock(&ts->ts_lock);
+
+ return status;
+}
+
+celix_status_t pubsub_topicSubscriptionRemoveSubscriber(topic_subscription_pt ts, pubsub_endpoint_pt subEP){
+ celix_status_t status = CELIX_SUCCESS;
+
+ celixThreadMutex_lock(&ts->ts_lock);
+ arrayList_removeElement(ts->sub_ep_list,subEP);
+ celixThreadMutex_unlock(&ts->ts_lock);
+
+ return status;
+}
+
+celix_status_t pubsub_topicDecreaseNrSubscribers(topic_subscription_pt ts) {
+ celix_status_t status = CELIX_SUCCESS;
+
+ celixThreadMutex_lock(&ts->ts_lock);
+ ts->nrSubscribers--;
+ celixThreadMutex_unlock(&ts->ts_lock);
+
+ return status;
+}
+
+unsigned int pubsub_topicGetNrSubscribers(topic_subscription_pt ts) {
+ return ts->nrSubscribers;
+}
+
+array_list_pt pubsub_topicSubscriptionGetSubscribersList(topic_subscription_pt sub){
+ return sub->sub_ep_list;
+}
+
+
+static celix_status_t topicsub_subscriberTracked(void * handle, service_reference_pt reference, void * service){
+ celix_status_t status = CELIX_SUCCESS;
+ topic_subscription_pt ts = handle;
+
+ celixThreadMutex_lock(&ts->ts_lock);
+ if (!hashMap_containsKey(ts->servicesMap, service)) {
+ bundle_pt bundle = NULL;
+ hash_map_pt msgTypes = NULL;
+
+ serviceReference_getBundle(reference, &bundle);
+
+ if(ts->serializer != NULL && bundle!=NULL){
+ ts->serializer->createSerializerMap(ts->serializer->handle,bundle,&msgTypes);
+ if(msgTypes != NULL){
+ hashMap_put(ts->servicesMap, service, msgTypes);
+ printf("PSA_UDP_MC_TS: New subscriber registered.\n");
+ }
+ }
+ else{
+ printf("PSA_UDP_MC_TS: Cannot register new subscriber.\n");
+ status = CELIX_SERVICE_EXCEPTION;
+ }
+ }
+ celixThreadMutex_unlock(&ts->ts_lock);
+
+ return status;
+
+}
+
+static celix_status_t topicsub_subscriberUntracked(void * handle, service_reference_pt reference, void * service){
+ celix_status_t status = CELIX_SUCCESS;
+ topic_subscription_pt ts = handle;
+
+ celixThreadMutex_lock(&ts->ts_lock);
+ if (hashMap_containsKey(ts->servicesMap, service)) {
+ hash_map_pt msgTypes = hashMap_remove(ts->servicesMap, service);
+ if(msgTypes!=NULL && ts->serializer!=NULL){
+ ts->serializer->destroySerializerMap(ts->serializer->handle,msgTypes);
+ printf("PSA_ZMQ_TS: Subscriber unregistered.\n");
+ }
+ else{
+ printf("PSA_ZMQ_TS: Cannot unregister subscriber.\n");
+ status = CELIX_SERVICE_EXCEPTION;
+ }
+ }
+ celixThreadMutex_unlock(&ts->ts_lock);
+
+ printf("PSA_UDP_MC_TS: Subscriber unregistered.\n");
+ return status;
+}
+
+
+static void process_msg(topic_subscription_pt sub,pubsub_udp_msg_t *msg){
+
+ celixThreadMutex_lock(&sub->ts_lock);
+ hash_map_iterator_pt iter = hashMapIterator_create(sub->servicesMap);
+ while (hashMapIterator_hasNext(iter)) {
+ hash_map_entry_pt entry = hashMapIterator_nextEntry(iter);
+ pubsub_subscriber_pt subsvc = hashMapEntry_getKey(entry);
+ hash_map_pt msgTypes = hashMapEntry_getValue(entry);
+
+ pubsub_msg_serializer_t *msgSer = hashMap_get(msgTypes,(void*)(uintptr_t )msg->header.type);
+ if (msgSer == NULL) {
+ printf("PSA_UDP_MC_TS: Serializer not available for message %d.\n",msg->header.type);
+ }
+ else{
+ void *msgInst = NULL;
+ bool validVersion = checkVersion(msgSer->msgVersion,&msg->header);
+
+ if(validVersion){
+
+ celix_status_t status = msgSer->deserialize(msgSer, (const void *) msg->payload, 0, &msgInst);
+
+ if (status == CELIX_SUCCESS) {
+ bool release = true;
+ pubsub_multipart_callbacks_t mp_callbacks;
+ mp_callbacks.handle = sub;
+ mp_callbacks.localMsgTypeIdForMsgType = pubsub_localMsgTypeIdForMsgType;
+ mp_callbacks.getMultipart = NULL;
+
+ subsvc->receive(subsvc->handle, msgSer->msgName, msg->header.type, msgInst, &mp_callbacks, &release);
+
+ if(release){
+ msgSer->freeMsg(msgSer,msgInst);
+ }
+ }
+ else{
+ printf("PSA_UDP_MC_TS: Cannot deserialize msgType %s.\n",msgSer->msgName);
+ }
+
+ }
+ else{
+ int major=0,minor=0;
+ version_getMajor(msgSer->msgVersion,&major);
+ version_getMinor(msgSer->msgVersion,&minor);
+ printf("PSA_UDP_MC_TS: Version mismatch for primary message '%s' (have %d.%d, received %u.%u). NOT sending any part of the whole message.\n",
+ msgSer->msgName,major,minor,msg->header.major,msg->header.minor);
+ }
+
+ }
+ }
+ hashMapIterator_destroy(iter);
+ celixThreadMutex_unlock(&sub->ts_lock);
+}
+
+static void* udp_recv_thread_func(void * arg) {
+ topic_subscription_pt sub = (topic_subscription_pt) arg;
+
+#if defined(__APPLE__) && defined(__MACH__)
+ //TODO: use kqueue for OSX
+ //struct kevent events[MAX_EPOLL_EVENTS];
+ while (sub->running) {
+ int nfds = 0;
+ if(nfds > 0) {
+ pubsub_udp_msg_t* udpMsg = NULL;
+ process_msg(sub, udpMsg);
+ }
+ }
+#else
+ struct epoll_event events[MAX_EPOLL_EVENTS];
+
+ while (sub->running) {
+ int nfds = epoll_wait(sub->topicEpollFd, events, MAX_EPOLL_EVENTS, RECV_THREAD_TIMEOUT * 1000);
+ int i;
+ for(i = 0; i < nfds; i++ ) {
+ unsigned int index;
+ unsigned int size;
+ if(largeUdp_dataAvailable(sub->largeUdpHandle, events[i].data.fd, &index, &size) == true) {
+ // Handle data
+ pubsub_udp_msg_t *udpMsg = NULL;
+ if(largeUdp_read(sub->largeUdpHandle, index, (void**)&udpMsg, size) != 0) {
+ printf("PSA_UDP_MC_TS: ERROR largeUdp_read with index %d\n", index);
+ continue;
+ }
+
+ process_msg(sub, udpMsg);
+
+ free(udpMsg);
+ }
+ }
+ connectPendingPublishers(sub);
+ disconnectPendingPublishers(sub);
+ }
+#endif
+
+ return NULL;
+}
+
+static void connectPendingPublishers(topic_subscription_pt sub) {
+ celixThreadMutex_lock(&sub->pendingConnections_lock);
+ while(!arrayList_isEmpty(sub->pendingConnections)) {
+ char * pubEP = arrayList_remove(sub->pendingConnections, 0);
+ pubsub_topicSubscriptionConnectPublisher(sub, pubEP);
+ free(pubEP);
+ }
+ celixThreadMutex_unlock(&sub->pendingConnections_lock);
+}
+
+static void disconnectPendingPublishers(topic_subscription_pt sub) {
+ celixThreadMutex_lock(&sub->pendingDisconnections_lock);
+ while(!arrayList_isEmpty(sub->pendingDisconnections)) {
+ char * pubEP = arrayList_remove(sub->pendingDisconnections, 0);
+ pubsub_topicSubscriptionDisconnectPublisher(sub, pubEP);
+ free(pubEP);
+ }
+ celixThreadMutex_unlock(&sub->pendingDisconnections_lock);
+}
+
+static void sigusr1_sighandler(int signo){
+ printf("PSA_UDP_MC_TS: Topic subscription being shut down...\n");
+ return;
+}
+
+static bool checkVersion(version_pt msgVersion,pubsub_msg_header_pt hdr){
+ bool check=false;
+ int major=0,minor=0;
+
+ if(msgVersion!=NULL){
+ version_getMajor(msgVersion,&major);
+ version_getMinor(msgVersion,&minor);
+ if(hdr->major==((unsigned char)major)){ /* Different major means incompatible */
+ check = (hdr->minor>=((unsigned char)minor)); /* Compatible only if the provider has a minor equals or greater (means compatible update) */
+ }
+ }
+
+ return check;
+}
+
+static int pubsub_localMsgTypeIdForMsgType(void* handle, const char* msgType, unsigned int* msgTypeId){
+ *msgTypeId = utils_stringHash(msgType);
+ return 0;
+}
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/pubsub/pubsub_admin_udp_mc/src/topic_subscription.h
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_admin_udp_mc/src/topic_subscription.h b/pubsub/pubsub_admin_udp_mc/src/topic_subscription.h
new file mode 100644
index 0000000..475416a
--- /dev/null
+++ b/pubsub/pubsub_admin_udp_mc/src/topic_subscription.h
@@ -0,0 +1,60 @@
+/**
+ *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.
+ */
+/*
+ * topic_subscription.h
+ *
+ * \date Sep 22, 2015
+ * \author <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ * \copyright Apache License, Version 2.0
+ */
+
+#ifndef TOPIC_SUBSCRIPTION_H_
+#define TOPIC_SUBSCRIPTION_H_
+
+#include "celix_threads.h"
+#include "array_list.h"
+#include "celixbool.h"
+#include "service_tracker.h"
+
+#include "pubsub_endpoint.h"
+#include "pubsub_common.h"
+#include "pubsub_serializer.h"
+
+typedef struct topic_subscription* topic_subscription_pt;
+
+celix_status_t pubsub_topicSubscriptionCreate(bundle_context_pt bundle_context, char* ifIp,char* scope, char* topic ,pubsub_serializer_service_t *best_serializer, topic_subscription_pt* out);
+celix_status_t pubsub_topicSubscriptionDestroy(topic_subscription_pt ts);
+celix_status_t pubsub_topicSubscriptionStart(topic_subscription_pt ts);
+celix_status_t pubsub_topicSubscriptionStop(topic_subscription_pt ts);
+
+celix_status_t pubsub_topicSubscriptionAddConnectPublisherToPendingList(topic_subscription_pt ts, char* pubURL);
+celix_status_t pubsub_topicSubscriptionAddDisconnectPublisherToPendingList(topic_subscription_pt ts, char* pubURL);
+
+celix_status_t pubsub_topicSubscriptionConnectPublisher(topic_subscription_pt ts, char* pubURL);
+celix_status_t pubsub_topicSubscriptionDisconnectPublisher(topic_subscription_pt ts, char* pubURL);
+
+celix_status_t pubsub_topicSubscriptionAddSubscriber(topic_subscription_pt ts, pubsub_endpoint_pt subEP);
+celix_status_t pubsub_topicSubscriptionRemoveSubscriber(topic_subscription_pt ts, pubsub_endpoint_pt subEP);
+
+array_list_pt pubsub_topicSubscriptionGetSubscribersList(topic_subscription_pt sub);
+celix_status_t pubsub_topicIncreaseNrSubscribers(topic_subscription_pt subscription);
+celix_status_t pubsub_topicDecreaseNrSubscribers(topic_subscription_pt subscription);
+unsigned int pubsub_topicGetNrSubscribers(topic_subscription_pt subscription);
+
+#endif /*TOPIC_SUBSCRIPTION_H_ */
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/pubsub/pubsub_admin_zmq/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_admin_zmq/CMakeLists.txt b/pubsub/pubsub_admin_zmq/CMakeLists.txt
index ab250f9..d71aedb 100644
--- a/pubsub/pubsub_admin_zmq/CMakeLists.txt
+++ b/pubsub/pubsub_admin_zmq/CMakeLists.txt
@@ -50,14 +50,15 @@ if (BUILD_PUBSUB_PSA_ZMQ)
private/src/topic_subscription.c
private/src/topic_publication.c
${ZMQ_CRYPTO_C}
- ${PROJECT_SOURCE_DIR}/log_service/public/src/log_helper.c
${PROJECT_SOURCE_DIR}/pubsub/pubsub_common/public/src/pubsub_endpoint.c
${PROJECT_SOURCE_DIR}/pubsub/pubsub_common/public/src/pubsub_utils.c
${PROJECT_SOURCE_DIR}/pubsub/pubsub_common/public/src/pubsub_admin_match.c
)
set_target_properties(org.apache.celix.pubsub_admin.PubSubAdminZmq PROPERTIES INSTALL_RPATH "$ORIGIN")
- target_link_libraries(org.apache.celix.pubsub_admin.PubSubAdminZmq celix_framework celix_utils celix_dfi ${ZMQ_LIBRARIES} ${CZMQ_LIBRARIES} ${OPENSSL_CRYPTO_LIBRARY})
+ target_link_libraries(org.apache.celix.pubsub_admin.PubSubAdminZmq PRIVATE
+ Celix::framework Celix::dfi Celix::log_helper
+ ${ZMQ_LIBRARIES} ${CZMQ_LIBRARIES} ${OPENSSL_CRYPTO_LIBRARY})
install_bundle(org.apache.celix.pubsub_admin.PubSubAdminZmq)
endif()
[02/19] celix git commit: CELIX-417: Refactor for CMake usage in RSA,
PSA and Docker. mostly trying to identify the api and common libraries
Posted by pn...@apache.org.
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/utils/private/src/civetweb.c
----------------------------------------------------------------------
diff --git a/remote_services/utils/private/src/civetweb.c b/remote_services/utils/private/src/civetweb.c
deleted file mode 100644
index a6093b7..0000000
--- a/remote_services/utils/private/src/civetweb.c
+++ /dev/null
@@ -1,7907 +0,0 @@
- /* Copyright (c) 2013-2015 the Civetweb developers
- * Copyright (c) 2004-2013 Sergey Lyubka
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#if defined(_WIN32)
-#if !defined(_CRT_SECURE_NO_WARNINGS)
-#define _CRT_SECURE_NO_WARNINGS /* Disable deprecation warning in VS2005 */
-#endif
-#else
-#ifdef __linux__
-#define _XOPEN_SOURCE 600 /* For flockfile() on Linux */
-#endif
-#ifndef _LARGEFILE_SOURCE
-#define _LARGEFILE_SOURCE /* For fseeko(), ftello() */
-#endif
-#ifndef _FILE_OFFSET_BITS
-#define _FILE_OFFSET_BITS 64 /* Use 64-bit file offsets by default */
-#endif
-#ifndef __STDC_FORMAT_MACROS
-#define __STDC_FORMAT_MACROS /* <inttypes.h> wants this for C++ */
-#endif
-#ifndef __STDC_LIMIT_MACROS
-#define __STDC_LIMIT_MACROS /* C++ wants that for INT64_MAX */
-#endif
-#endif
-
-#if defined (_MSC_VER)
-/* 'type cast' : conversion from 'int' to 'HANDLE' of greater size */
-#pragma warning (disable : 4306 )
-/* conditional expression is constant: introduced by FD_SET(..) */
-#pragma warning (disable : 4127)
-/* non-constant aggregate initializer: issued due to missing C99 support */
-#pragma warning (disable : 4204)
-#endif
-
-/* Disable WIN32_LEAN_AND_MEAN.
- This makes windows.h always include winsock2.h */
-#if defined(WIN32_LEAN_AND_MEAN)
-#undef WIN32_LEAN_AND_MEAN
-#endif
-
-#if defined USE_IPV6 && defined(_WIN32)
-#include <ws2tcpip.h>
-#endif
-
-#if defined(__SYMBIAN32__)
-#define NO_SSL /* SSL is not supported */
-#define NO_CGI /* CGI is not supported */
-#define PATH_MAX FILENAME_MAX
-#endif /* __SYMBIAN32__ */
-
-#ifndef IGNORE_UNUSED_RESULT
-#define IGNORE_UNUSED_RESULT(a) (void)((a) && 1)
-#endif
-
-#ifndef _WIN32_WCE /* Some ANSI #includes are not available on Windows CE */
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <errno.h>
-#include <signal.h>
-#include <fcntl.h>
-#endif /* !_WIN32_WCE */
-
-#include <time.h>
-#include <stdlib.h>
-#include <stdarg.h>
-#include <assert.h>
-#include <string.h>
-#include <ctype.h>
-#include <limits.h>
-#include <stddef.h>
-#include <stdio.h>
-
-#ifndef MAX_WORKER_THREADS
-#define MAX_WORKER_THREADS (1024*64)
-#endif
-
-#if defined(_WIN32) && !defined(__SYMBIAN32__) /* Windows specific */
-#if defined(_MSC_VER) && _MSC_VER <= 1400
-#undef _WIN32_WINNT
-#define _WIN32_WINNT 0x0400 /* To make it link in VS2005 */
-#endif
-#include <windows.h>
-typedef const char * SOCK_OPT_TYPE;
-
-#ifndef PATH_MAX
-#define PATH_MAX MAX_PATH
-#endif
-
-#ifndef _IN_PORT_T
-#ifndef in_port_t
-#define in_port_t u_short
-#endif
-#endif
-
-#ifndef _WIN32_WCE
-#include <process.h>
-#include <direct.h>
-#include <io.h>
-#else /* _WIN32_WCE */
-#define NO_CGI /* WinCE has no pipes */
-
-typedef long off_t;
-
-#define errno GetLastError()
-#define strerror(x) _ultoa(x, (char *) _alloca(sizeof(x) *3 ), 10)
-#endif /* _WIN32_WCE */
-
-#define MAKEUQUAD(lo, hi) ((uint64_t)(((uint32_t)(lo)) | \
- ((uint64_t)((uint32_t)(hi))) << 32))
-#define RATE_DIFF 10000000 /* 100 nsecs */
-#define EPOCH_DIFF MAKEUQUAD(0xd53e8000, 0x019db1de)
-#define SYS2UNIX_TIME(lo, hi) \
- (time_t) ((MAKEUQUAD((lo), (hi)) - EPOCH_DIFF) / RATE_DIFF)
-
-/* Visual Studio 6 does not know __func__ or __FUNCTION__
- The rest of MS compilers use __FUNCTION__, not C99 __func__
- Also use _strtoui64 on modern M$ compilers */
-#if defined(_MSC_VER) && _MSC_VER < 1300
-#define STRX(x) #x
-#define STR(x) STRX(x)
-#define __func__ __FILE__ ":" STR(__LINE__)
-#define strtoull(x, y, z) (unsigned __int64) _atoi64(x)
-#define strtoll(x, y, z) _atoi64(x)
-#else
-#define __func__ __FUNCTION__
-#define strtoull(x, y, z) _strtoui64(x, y, z)
-#define strtoll(x, y, z) _strtoi64(x, y, z)
-#endif /* _MSC_VER */
-
-#define ERRNO GetLastError()
-#define NO_SOCKLEN_T
-#define SSL_LIB "ssleay32.dll"
-#define CRYPTO_LIB "libeay32.dll"
-#define O_NONBLOCK 0
-#define W_OK (2) /* http://msdn.microsoft.com/en-us/library/1w06ktdy.aspx */
-#if !defined(EWOULDBLOCK)
-#define EWOULDBLOCK WSAEWOULDBLOCK
-#endif /* !EWOULDBLOCK */
-#define _POSIX_
-#define INT64_FMT "I64d"
-
-#define WINCDECL __cdecl
-#define SHUT_WR 1
-#define snprintf _snprintf
-#define vsnprintf _vsnprintf
-#define access _access
-#define mg_sleep(x) Sleep(x)
-
-#define pipe(x) _pipe(x, MG_BUF_LEN, _O_BINARY)
-#ifndef popen
-#define popen(x, y) _popen(x, y)
-#endif
-#ifndef pclose
-#define pclose(x) _pclose(x)
-#endif
-#define close(x) _close(x)
-#define dlsym(x,y) GetProcAddress((HINSTANCE) (x), (y))
-#define RTLD_LAZY 0
-#define fseeko(x, y, z) _lseeki64(_fileno(x), (y), (z))
-#define fdopen(x, y) _fdopen((x), (y))
-#define write(x, y, z) _write((x), (y), (unsigned) z)
-#define read(x, y, z) _read((x), (y), (unsigned) z)
-#define flockfile(x) EnterCriticalSection(&global_log_file_lock)
-#define funlockfile(x) LeaveCriticalSection(&global_log_file_lock)
-#define sleep(x) Sleep((x) * 1000)
-#define rmdir(x) _rmdir(x)
-
-#if defined(USE_LUA) && defined(USE_WEBSOCKET)
-#define USE_TIMERS
-#endif
-
-#if !defined(va_copy)
-#define va_copy(x, y) x = y
-#endif /* !va_copy MINGW #defines va_copy */
-
-#if !defined(fileno)
-#define fileno(x) _fileno(x)
-#endif /* !fileno MINGW #defines fileno */
-
-typedef HANDLE pthread_mutex_t;
-typedef DWORD pthread_key_t;
-typedef HANDLE pthread_t;
-typedef struct {
- CRITICAL_SECTION threadIdSec;
- int waitingthreadcount; /* The number of threads queued. */
- pthread_t *waitingthreadhdls; /* The thread handles. */
-} pthread_cond_t;
-
-#ifndef __clockid_t_defined
-typedef DWORD clockid_t;
-#endif
-#ifndef CLOCK_MONOTONIC
-#define CLOCK_MONOTONIC (1)
-#endif
-#ifndef CLOCK_REALTIME
-#define CLOCK_REALTIME (2)
-#endif
-
-#ifndef _TIMESPEC_DEFINED
-struct timespec {
- time_t tv_sec; /* seconds */
- long tv_nsec; /* nanoseconds */
-};
-#endif
-
-#define pid_t HANDLE /* MINGW typedefs pid_t to int. Using #define here. */
-
-static int pthread_mutex_lock(pthread_mutex_t *);
-static int pthread_mutex_unlock(pthread_mutex_t *);
-static void to_unicode(const char *path, wchar_t *wbuf, size_t wbuf_len);
-struct file;
-static char *mg_fgets(char *buf, size_t size, struct file *filep, char **p);
-
-#if defined(HAVE_STDINT)
-#include <stdint.h>
-#else
-typedef unsigned int uint32_t;
-typedef unsigned short uint16_t;
-typedef unsigned __int64 uint64_t;
-typedef __int64 int64_t;
-#define INT64_MAX 9223372036854775807
-#endif /* HAVE_STDINT */
-
-/* POSIX dirent interface */
-struct dirent {
- char d_name[PATH_MAX];
-};
-
-typedef struct DIR {
- HANDLE handle;
- WIN32_FIND_DATAW info;
- struct dirent result;
-} DIR;
-
-#if !defined(USE_IPV6) && defined(_WIN32)
-#ifndef HAVE_POLL
-struct pollfd {
- SOCKET fd;
- short events;
- short revents;
-};
-#define POLLIN 1
-#endif
-#endif
-
-/* Mark required libraries */
-#ifdef _MSC_VER
-#pragma comment(lib, "Ws2_32.lib")
-#endif
-
-#else /* UNIX specific */
-#include <sys/wait.h>
-#include <sys/socket.h>
-#include <sys/poll.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <sys/time.h>
-#include <sys/utsname.h>
-#include <stdint.h>
-#include <inttypes.h>
-#include <netdb.h>
-typedef const void * SOCK_OPT_TYPE;
-
-//#if defined(ANDROID)
-typedef unsigned short int in_port_t;
-//#endif
-
-#include <pwd.h>
-#include <unistd.h>
-#include <dirent.h>
-#if !defined(NO_SSL_DL) && !defined(NO_SSL)
-#include <dlfcn.h>
-#endif
-#include <pthread.h>
-#if defined(__MACH__)
-#define SSL_LIB "libssl.dylib"
-#define CRYPTO_LIB "libcrypto.dylib"
-#else
-#if !defined(SSL_LIB)
-#define SSL_LIB "libssl.so"
-#endif
-#if !defined(CRYPTO_LIB)
-#define CRYPTO_LIB "libcrypto.so"
-#endif
-#endif
-#ifndef O_BINARY
-#define O_BINARY 0
-#endif /* O_BINARY */
-#define closesocket(a) close(a)
-#define mg_mkdir(x, y) mkdir(x, y)
-#define mg_remove(x) remove(x)
-#define mg_sleep(x) usleep((x) * 1000)
-#define ERRNO errno
-#define INVALID_SOCKET (-1)
-#define INT64_FMT PRId64
-typedef int SOCKET;
-#define WINCDECL
-
-#endif /* End of Windows and UNIX specific includes */
-
-#ifdef _WIN32
-static CRITICAL_SECTION global_log_file_lock;
-static DWORD pthread_self(void)
-{
- return GetCurrentThreadId();
-}
-
-int pthread_key_create(pthread_key_t *key, void (*_must_be_zero)(void*) /* destructor function not supported for windows */)
-{
- assert(_must_be_zero == NULL);
- if ((key!=0) && (_must_be_zero == NULL)) {
- *key = TlsAlloc();
- return (*key != TLS_OUT_OF_INDEXES) ? 0 : -1;
- }
- return -2;
-}
-
-int pthread_key_delete(pthread_key_t key)
-{
- return TlsFree(key) ? 0 : 1;
-}
-
-int pthread_setspecific(pthread_key_t key, void * value)
-{
- return TlsSetValue(key, value) ? 0 : 1;
-}
-
-void *pthread_getspecific(pthread_key_t key)
-{
- return TlsGetValue(key);
-}
-#endif /* _WIN32 */
-
-
-#include "civetweb.h"
-
-#define PASSWORDS_FILE_NAME ".htpasswd"
-#define CGI_ENVIRONMENT_SIZE 4096
-#define MAX_CGI_ENVIR_VARS 64
-#define MG_BUF_LEN 8192
-#ifndef MAX_REQUEST_SIZE
-#define MAX_REQUEST_SIZE 16384
-#endif
-#define ARRAY_SIZE(array) (sizeof(array) / sizeof(array[0]))
-
-#if !defined(DEBUG_TRACE)
-#if defined(CWDEBUG)
-
-static void DEBUG_TRACE_FUNC(const char *func, unsigned line, PRINTF_FORMAT_STRING(const char *fmt), ...) PRINTF_ARGS(3, 4);
-
-static void DEBUG_TRACE_FUNC(const char *func, unsigned line, const char *fmt, ...) {
-
- va_list args;
- flockfile(stdout);
- printf("*** %lu.%p.%s.%u: ",
- (unsigned long) time(NULL), (void *) pthread_self(),
- func, line);
- va_start(args, fmt);
- vprintf(fmt, args);
- va_end(args);
- putchar('\n');
- fflush(stdout);
- funlockfile(stdout);
-}
-
-#define DEBUG_TRACE(fmt, ...) DEBUG_TRACE_FUNC(__func__, __LINE__, fmt, __VA_ARGS__)
-
-#else
-#define DEBUG_TRACE(fmt, ...)
-#endif /* CWDEBUG */
-#endif /* DEBUG_TRACE */
-
-#if defined(MEMORY_DEBUGGING)
-static unsigned long blockCount = 0;
-static unsigned long totalMemUsed = 0;
-
-static void * mg_malloc_ex(size_t size, const char * file, unsigned line) {
-
- void * data = malloc(size + sizeof(size_t));
- void * memory = 0;
- char mallocStr[256];
-
- if (data) {
- *(size_t*)data = size;
- totalMemUsed += size;
- blockCount++;
- memory = (void *)(((char*)data)+sizeof(size_t));
- }
-
- sprintf(mallocStr, "MEM: %p %5lu alloc %7lu %4lu --- %s:%u\n", memory, (unsigned long)size, totalMemUsed, blockCount, file, line);
-#if defined(_WIN32)
- OutputDebugStringA(mallocStr);
-#else
- DEBUG_TRACE("%s", mallocStr);
-#endif
-
- return memory;
-}
-
-static void * mg_calloc_ex(size_t count, size_t size, const char * file, unsigned line) {
-
- void * data = mg_malloc_ex(size*count, file, line);
- if (data) memset(data, 0, size);
-
- return data;
-}
-
-static void mg_free_ex(void * memory, const char * file, unsigned line) {
-
- char mallocStr[256];
- void * data = (void *)(((char*)memory)-sizeof(size_t));
- size_t size;
-
- if (memory) {
- size = *(size_t*)data;
- totalMemUsed -= size;
- blockCount--;
- sprintf(mallocStr, "MEM: %p %5lu free %7lu %4lu --- %s:%u\n", memory, (unsigned long)size, totalMemUsed, blockCount, file, line);
-#if defined(_WIN32)
- OutputDebugStringA(mallocStr);
-#else
- DEBUG_TRACE("%s", mallocStr);
-#endif
-
- free(data);
- }
-}
-
-static void * mg_realloc_ex(void * memory, size_t newsize, const char * file, unsigned line) {
-
- char mallocStr[256];
- void * data;
- void * _realloc;
- size_t oldsize;
-
- if (newsize) {
- if (memory) {
- data = (void *)(((char*)memory)-sizeof(size_t));
- oldsize = *(size_t*)data;
- _realloc = realloc(data, newsize+sizeof(size_t));
- if (_realloc) {
- data = _realloc;
- totalMemUsed -= oldsize;
- sprintf(mallocStr, "MEM: %p %5lu r-free %7lu %4lu --- %s:%u\n", memory, (unsigned long)oldsize, totalMemUsed, blockCount, file, line);
-#if defined(_WIN32)
- OutputDebugStringA(mallocStr);
-#else
- DEBUG_TRACE("%s", mallocStr);
-#endif
- totalMemUsed += newsize;
- sprintf(mallocStr, "MEM: %p %5lu r-alloc %7lu %4lu --- %s:%u\n", memory, (unsigned long)newsize, totalMemUsed, blockCount, file, line);
-#if defined(_WIN32)
- OutputDebugStringA(mallocStr);
-#else
- DEBUG_TRACE("%s", mallocStr);
-#endif
- *(size_t*)data = newsize;
- data = (void *)(((char*)data)+sizeof(size_t));
- } else {
-#if defined(_WIN32)
- OutputDebugStringA("MEM: realloc failed\n");
-#else
- DEBUG_TRACE("%s", "MEM: realloc failed\n");
-#endif
- return _realloc;
- }
- } else {
- data = mg_malloc_ex(newsize, file, line);
- }
- } else {
- data = 0;
- mg_free_ex(memory, file, line);
- }
-
- return data;
-}
-
-#define mg_malloc(a) mg_malloc_ex(a, __FILE__, __LINE__)
-#define mg_calloc(a,b) mg_calloc_ex(a, b, __FILE__, __LINE__)
-#define mg_realloc(a, b) mg_realloc_ex(a, b, __FILE__, __LINE__)
-#define mg_free(a) mg_free_ex(a, __FILE__, __LINE__)
-
-#else
-static __inline void * mg_malloc(size_t a) {return malloc(a);}
-static __inline void * mg_calloc(size_t a, size_t b) {return calloc(a, b);}
-static __inline void * mg_realloc(void * a, size_t b) {return realloc(a, b);}
-static __inline void mg_free(void * a) {free(a);}
-#endif
-
-/* This following lines are just meant as a reminder to use the mg-functions for memory management */
-#ifdef malloc
- #undef malloc
-#endif
-#ifdef calloc
- #undef calloc
-#endif
-#ifdef realloc
- #undef realloc
-#endif
-#ifdef free
- #undef free
-#endif
-#define malloc DO_NOT_USE_THIS_FUNCTION__USE_mg_malloc
-#define calloc DO_NOT_USE_THIS_FUNCTION__USE_mg_calloc
-#define realloc DO_NOT_USE_THIS_FUNCTION__USE_mg_realloc
-#define free DO_NOT_USE_THIS_FUNCTION__USE_mg_free
-
-
-#define MD5_STATIC static
-#include "md5.inl"
-
-/* Darwin prior to 7.0 and Win32 do not have socklen_t */
-#ifdef NO_SOCKLEN_T
-typedef int socklen_t;
-#endif /* NO_SOCKLEN_T */
-#define _DARWIN_UNLIMITED_SELECT
-
-#define IP_ADDR_STR_LEN 50 /* IPv6 hex string is 46 chars */
-
-#if !defined(MSG_NOSIGNAL)
-#define MSG_NOSIGNAL 0
-#endif
-
-#if !defined(SOMAXCONN)
-#define SOMAXCONN 100
-#endif
-
-#if !defined(PATH_MAX)
-#define PATH_MAX 4096
-#endif
-
-/* Size of the accepted socket queue */
-#if !defined(MGSQLEN)
-#define MGSQLEN 20
-#endif
-
-#if defined(NO_SSL_DL)
-#include <openssl/ssl.h>
-#include <openssl/err.h>
-#else
-/* SSL loaded dynamically from DLL.
- I put the prototypes here to be independent from OpenSSL source
- installation. */
-
-typedef struct ssl_st SSL;
-typedef struct ssl_method_st SSL_METHOD;
-typedef struct ssl_ctx_st SSL_CTX;
-
-struct ssl_func {
- const char *name; /* SSL function name */
- void (*ptr)(void); /* Function pointer */
-};
-
-#define SSL_free (* (void (*)(SSL *)) ssl_sw[0].ptr)
-#define SSL_accept (* (int (*)(SSL *)) ssl_sw[1].ptr)
-#define SSL_connect (* (int (*)(SSL *)) ssl_sw[2].ptr)
-#define SSL_read (* (int (*)(SSL *, void *, int)) ssl_sw[3].ptr)
-#define SSL_write (* (int (*)(SSL *, const void *,int)) ssl_sw[4].ptr)
-#define SSL_get_error (* (int (*)(SSL *, int)) ssl_sw[5].ptr)
-#define SSL_set_fd (* (int (*)(SSL *, SOCKET)) ssl_sw[6].ptr)
-#define SSL_new (* (SSL * (*)(SSL_CTX *)) ssl_sw[7].ptr)
-#define SSL_CTX_new (* (SSL_CTX * (*)(SSL_METHOD *)) ssl_sw[8].ptr)
-#define SSLv23_server_method (* (SSL_METHOD * (*)(void)) ssl_sw[9].ptr)
-#define SSL_library_init (* (int (*)(void)) ssl_sw[10].ptr)
-#define SSL_CTX_use_PrivateKey_file (* (int (*)(SSL_CTX *, \
- const char *, int)) ssl_sw[11].ptr)
-#define SSL_CTX_use_certificate_file (* (int (*)(SSL_CTX *, \
- const char *, int)) ssl_sw[12].ptr)
-#define SSL_CTX_set_default_passwd_cb \
- (* (void (*)(SSL_CTX *, mg_callback_t)) ssl_sw[13].ptr)
-#define SSL_CTX_free (* (void (*)(SSL_CTX *)) ssl_sw[14].ptr)
-#define SSL_load_error_strings (* (void (*)(void)) ssl_sw[15].ptr)
-#define SSL_CTX_use_certificate_chain_file \
- (* (int (*)(SSL_CTX *, const char *)) ssl_sw[16].ptr)
-#define SSLv23_client_method (* (SSL_METHOD * (*)(void)) ssl_sw[17].ptr)
-#define SSL_pending (* (int (*)(SSL *)) ssl_sw[18].ptr)
-#define SSL_CTX_set_verify (* (void (*)(SSL_CTX *, int, int)) ssl_sw[19].ptr)
-#define SSL_shutdown (* (int (*)(SSL *)) ssl_sw[20].ptr)
-
-#define CRYPTO_num_locks (* (int (*)(void)) crypto_sw[0].ptr)
-#define CRYPTO_set_locking_callback \
- (* (void (*)(void (*)(int, int, const char *, int))) crypto_sw[1].ptr)
-#define CRYPTO_set_id_callback \
- (* (void (*)(unsigned long (*)(void))) crypto_sw[2].ptr)
-#define ERR_get_error (* (unsigned long (*)(void)) crypto_sw[3].ptr)
-#define ERR_error_string (* (char * (*)(unsigned long,char *)) crypto_sw[4].ptr)
-
-/* set_ssl_option() function updates this array.
- It loads SSL library dynamically and changes NULLs to the actual addresses
- of respective functions. The macros above (like SSL_connect()) are really
- just calling these functions indirectly via the pointer. */
-static struct ssl_func ssl_sw[] = {
- {"SSL_free", NULL},
- {"SSL_accept", NULL},
- {"SSL_connect", NULL},
- {"SSL_read", NULL},
- {"SSL_write", NULL},
- {"SSL_get_error", NULL},
- {"SSL_set_fd", NULL},
- {"SSL_new", NULL},
- {"SSL_CTX_new", NULL},
- {"SSLv23_server_method", NULL},
- {"SSL_library_init", NULL},
- {"SSL_CTX_use_PrivateKey_file", NULL},
- {"SSL_CTX_use_certificate_file",NULL},
- {"SSL_CTX_set_default_passwd_cb",NULL},
- {"SSL_CTX_free", NULL},
- {"SSL_load_error_strings", NULL},
- {"SSL_CTX_use_certificate_chain_file", NULL},
- {"SSLv23_client_method", NULL},
- {"SSL_pending", NULL},
- {"SSL_CTX_set_verify", NULL},
- {"SSL_shutdown", NULL},
- {NULL, NULL}
-};
-
-/* Similar array as ssl_sw. These functions could be located in different
- lib. */
-#if !defined(NO_SSL)
-static struct ssl_func crypto_sw[] = {
- {"CRYPTO_num_locks", NULL},
- {"CRYPTO_set_locking_callback", NULL},
- {"CRYPTO_set_id_callback", NULL},
- {"ERR_get_error", NULL},
- {"ERR_error_string", NULL},
- {NULL, NULL}
-};
-#endif /* NO_SSL */
-#endif /* NO_SSL_DL */
-
-static const char *month_names[] = {
- "Jan", "Feb", "Mar", "Apr", "May", "Jun",
- "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
-};
-
-/* Unified socket address. For IPv6 support, add IPv6 address structure
- in the union u. */
-union usa {
- struct sockaddr sa;
- struct sockaddr_in sin;
-#if defined(USE_IPV6)
- struct sockaddr_in6 sin6;
-#endif
-};
-
-/* Describes a string (chunk of memory). */
-struct vec {
- const char *ptr;
- size_t len;
-};
-
-struct file {
- int is_directory;
- time_t modification_time;
- int64_t size;
- FILE *fp;
- const char *membuf; /* Non-NULL if file data is in memory */
- /* set to 1 if the content is gzipped
- in which case we need a content-encoding: gzip header */
- int gzipped;
-};
-#define STRUCT_FILE_INITIALIZER {0, 0, 0, NULL, NULL, 0}
-
-/* Describes listening socket, or socket which was accept()-ed by the master
- thread and queued for future handling by the worker thread. */
-struct socket {
- SOCKET sock; /* Listening socket */
- union usa lsa; /* Local socket address */
- union usa rsa; /* Remote socket address */
- unsigned is_ssl:1; /* Is port SSL-ed */
- unsigned ssl_redir:1; /* Is port supposed to redirect everything to SSL
- port */
-};
-
-/* NOTE(lsm): this enum shoulds be in sync with the config_options below. */
-enum {
- CGI_EXTENSIONS, CGI_ENVIRONMENT, PUT_DELETE_PASSWORDS_FILE, CGI_INTERPRETER,
- PROTECT_URI, AUTHENTICATION_DOMAIN, SSI_EXTENSIONS, THROTTLE,
- ACCESS_LOG_FILE, ENABLE_DIRECTORY_LISTING, ERROR_LOG_FILE,
- GLOBAL_PASSWORDS_FILE, INDEX_FILES, ENABLE_KEEP_ALIVE, ACCESS_CONTROL_LIST,
- EXTRA_MIME_TYPES, LISTENING_PORTS, DOCUMENT_ROOT, SSL_CERTIFICATE,
- NUM_THREADS, RUN_AS_USER, REWRITE, HIDE_FILES, REQUEST_TIMEOUT,
- DECODE_URL,
-
-#if defined(USE_LUA)
- LUA_PRELOAD_FILE, LUA_SCRIPT_EXTENSIONS, LUA_SERVER_PAGE_EXTENSIONS,
-#endif
-#if defined(USE_WEBSOCKET)
- WEBSOCKET_ROOT,
-#endif
-#if defined(USE_LUA) && defined(USE_WEBSOCKET)
- LUA_WEBSOCKET_EXTENSIONS,
-#endif
- ACCESS_CONTROL_ALLOW_ORIGIN, ERROR_PAGES,
-
- NUM_OPTIONS
-};
-
-/* Config option name, config types, default value */
-static struct mg_option config_options[] = {
- {"cgi_pattern", CONFIG_TYPE_EXT_PATTERN, "**.cgi$|**.pl$|**.php$"},
- {"cgi_environment", CONFIG_TYPE_STRING, NULL},
- {"put_delete_auth_file", CONFIG_TYPE_FILE, NULL},
- {"cgi_interpreter", CONFIG_TYPE_FILE, NULL},
- {"protect_uri", CONFIG_TYPE_STRING, NULL},
- {"authentication_domain", CONFIG_TYPE_STRING, "mydomain.com"},
- {"ssi_pattern", CONFIG_TYPE_EXT_PATTERN, "**.shtml$|**.shtm$"},
- {"throttle", CONFIG_TYPE_STRING, NULL},
- {"access_log_file", CONFIG_TYPE_FILE, NULL},
- {"enable_directory_listing", CONFIG_TYPE_BOOLEAN, "yes"},
- {"error_log_file", CONFIG_TYPE_FILE, NULL},
- {"global_auth_file", CONFIG_TYPE_FILE, NULL},
- {"index_files", CONFIG_TYPE_STRING,
-#ifdef USE_LUA
- "index.xhtml,index.html,index.htm,index.lp,index.lsp,index.lua,index.cgi,index.shtml,index.php"},
-#else
- "index.xhtml,index.html,index.htm,index.cgi,index.shtml,index.php"},
-#endif
- {"enable_keep_alive", CONFIG_TYPE_BOOLEAN, "no"},
- {"access_control_list", CONFIG_TYPE_STRING, NULL},
- {"extra_mime_types", CONFIG_TYPE_STRING, NULL},
- {"listening_ports", CONFIG_TYPE_STRING, "8080"},
- {"document_root", CONFIG_TYPE_DIRECTORY, NULL},
- {"ssl_certificate", CONFIG_TYPE_FILE, NULL},
- {"num_threads", CONFIG_TYPE_NUMBER, "50"},
- {"run_as_user", CONFIG_TYPE_STRING, NULL},
- {"url_rewrite_patterns", CONFIG_TYPE_STRING, NULL},
- {"hide_files_patterns", CONFIG_TYPE_EXT_PATTERN, NULL},
- {"request_timeout_ms", CONFIG_TYPE_NUMBER, "30000"},
- {"decode_url", CONFIG_TYPE_BOOLEAN, "yes"},
-
-#if defined(USE_LUA)
- {"lua_preload_file", CONFIG_TYPE_FILE, NULL},
- {"lua_script_pattern", CONFIG_TYPE_EXT_PATTERN, "**.lua$"},
- {"lua_server_page_pattern", CONFIG_TYPE_EXT_PATTERN, "**.lp$|**.lsp$"},
-#endif
-#if defined(USE_WEBSOCKET)
- {"websocket_root", CONFIG_TYPE_DIRECTORY, NULL},
-#endif
-#if defined(USE_LUA) && defined(USE_WEBSOCKET)
- {"lua_websocket_pattern", CONFIG_TYPE_EXT_PATTERN, "**.lua$"},
-#endif
- {"access_control_allow_origin", CONFIG_TYPE_STRING, "*"},
- {"error_pages", CONFIG_TYPE_DIRECTORY, NULL},
-
- {NULL, CONFIG_TYPE_UNKNOWN, NULL}
-};
-
-struct mg_request_handler_info {
- char *uri;
- size_t uri_len;
- mg_request_handler handler;
-
- void *cbdata;
- struct mg_request_handler_info *next;
-};
-
-struct mg_context {
- volatile int stop_flag; /* Should we stop event loop */
- SSL_CTX *ssl_ctx; /* SSL context */
- char *config[NUM_OPTIONS]; /* Civetweb configuration parameters */
- struct mg_callbacks callbacks; /* User-defined callback function */
- void *user_data; /* User-defined data */
- int context_type; /* 1 = server context, 2 = client context */
-
- struct socket *listening_sockets;
- in_port_t *listening_ports;
- int num_listening_sockets;
-
- volatile int num_threads; /* Number of threads */
- pthread_mutex_t thread_mutex; /* Protects (max|num)_threads */
- pthread_cond_t thread_cond; /* Condvar for tracking workers terminations */
-
- struct socket queue[MGSQLEN]; /* Accepted sockets */
- volatile int sq_head; /* Head of the socket queue */
- volatile int sq_tail; /* Tail of the socket queue */
- pthread_cond_t sq_full; /* Signaled when socket is produced */
- pthread_cond_t sq_empty; /* Signaled when socket is consumed */
- pthread_t masterthreadid; /* The master thread ID */
- int workerthreadcount; /* The amount of worker threads. */
- pthread_t *workerthreadids; /* The worker thread IDs */
-
- unsigned long start_time; /* Server start time, used for authentication */
- pthread_mutex_t nonce_mutex; /* Protects nonce_count */
- unsigned long nonce_count; /* Used nonces, used for authentication */
-
- char *systemName; /* What operating system is running */
-
- /* linked list of uri handlers */
- struct mg_request_handler_info *request_handlers;
-
-#if defined(USE_LUA) && defined(USE_WEBSOCKET)
- /* linked list of shared lua websockets */
- struct mg_shared_lua_websocket_list *shared_lua_websockets;
-#endif
-
-#ifdef USE_TIMERS
- struct ttimers * timers;
-#endif
-};
-
-struct mg_connection {
- struct mg_request_info request_info;
- struct mg_context *ctx;
- SSL *ssl; /* SSL descriptor */
- SSL_CTX *client_ssl_ctx; /* SSL context for client connections */
- struct socket client; /* Connected client */
- time_t birth_time; /* Time when request was received */
- int64_t num_bytes_sent; /* Total bytes sent to client */
- int64_t content_len; /* Content-Length header value */
- int64_t consumed_content; /* How many bytes of content have been read */
- char *buf; /* Buffer for received data */
- char *path_info; /* PATH_INFO part of the URL */
- int must_close; /* 1 if connection must be closed */
- int in_error_handler; /* 1 if in handler for user defined error pages */
- int buf_size; /* Buffer size */
- int request_len; /* Size of the request + headers in a buffer */
- int data_len; /* Total size of data in a buffer */
- int status_code; /* HTTP reply status code, e.g. 200 */
- int throttle; /* Throttling, bytes/sec. <= 0 means no throttle */
- time_t last_throttle_time; /* Last time throttled data was sent */
- int64_t last_throttle_bytes; /* Bytes sent this second */
- pthread_mutex_t mutex; /* Used by mg_lock_connection/mg_unlock_connection to ensure atomic transmissions for websockets */
-#if defined(USE_LUA) && defined(USE_WEBSOCKET)
- void * lua_websocket_state; /* Lua_State for a websocket connection */
-#endif
-};
-
-static pthread_key_t sTlsKey; /* Thread local storage index */
-static int sTlsInit = 0;
-
-struct mg_workerTLS {
- int is_master;
-#if defined(_WIN32) && !defined(__SYMBIAN32__)
- HANDLE pthread_cond_helper_mutex;
-#endif
-};
-
-/* Directory entry */
-struct de {
- struct mg_connection *conn;
- char *file_name;
- struct file file;
-};
-
-#if defined(USE_WEBSOCKET)
-static int is_websocket_protocol(const struct mg_connection *conn);
-#else
-#define is_websocket_protocol(conn) (0)
-#endif
-
-int mg_atomic_inc(volatile int * addr)
-{
- int ret;
-#if defined(_WIN32) && !defined(__SYMBIAN32__)
- ret = InterlockedIncrement((volatile unsigned int *) addr);
-#elif defined(__GNUC__)
- ret = __sync_add_and_fetch(addr, 1);
-#else
- ret = (++(*addr));
-#endif
- return ret;
-}
-
-int mg_atomic_dec(volatile int * addr)
-{
- int ret;
-#if defined(_WIN32) && !defined(__SYMBIAN32__)
- ret = InterlockedDecrement((volatile unsigned int *) addr);
-#elif defined(__GNUC__)
- ret = __sync_sub_and_fetch(addr, 1);
-#else
- ret = (--(*addr));
-#endif
- return ret;
-}
-
-#if !defined(NO_THREAD_NAME)
-#if defined(_WIN32) && defined(_MSC_VER)
-/* Set the thread name for debugging purposes in Visual Studio
- http://msdn.microsoft.com/en-us/library/xcb2z8hs.aspx
-*/
-#pragma pack(push,8)
-typedef struct tagTHREADNAME_INFO
-{
- DWORD dwType; /* Must be 0x1000. */
- LPCSTR szName; /* Pointer to name (in user addr space). */
- DWORD dwThreadID; /* Thread ID (-1=caller thread). */
- DWORD dwFlags; /* Reserved for future use, must be zero. */
-} THREADNAME_INFO;
-#pragma pack(pop)
-#elif defined(__linux__)
-#include <sys/prctl.h>
-#endif
-
-void mg_set_thread_name(const char* name)
-{
- char threadName[16]; /* Max. thread length in Linux/OSX/.. */
-
- if (snprintf(threadName, sizeof(threadName), "civetweb-%s", name)<0) return;
- threadName[sizeof(threadName)-1] = 0;
-
-#if defined(_WIN32)
-#if defined(_MSC_VER)
- /* Windows and Visual Studio Compiler */
- __try
- {
- THREADNAME_INFO info;
- info.dwType = 0x1000;
- info.szName = threadName;
- info.dwThreadID = -1;
- info.dwFlags = 0;
-
- RaiseException(0x406D1388, 0, sizeof(info)/sizeof(ULONG_PTR), (ULONG_PTR*)&info);
- }
- __except(EXCEPTION_EXECUTE_HANDLER)
- {
- }
-#elif defined(__MINGW32__)
- /* No option known to set thread name for MinGW */
-#endif
-#elif defined(__linux__)
- /* Linux */
- (void)prctl(PR_SET_NAME,threadName,0,0,0);
-#elif defined(__APPLE__) || defined(__MACH__)
- /* OS X (TODO: test) */
- (void)pthread_setname_np(threadName);
-#elif defined(BSD) || defined(__FreeBSD__) || defined(__OpenBSD__)
- /* BSD (TODO: test) */
- pthread_set_name_np(pthread_self(), threadName);
-#else
- /* POSIX */
- (void)pthread_setname_np(pthread_self(), threadName);
-#endif
-}
-#else /* !defined(NO_THREAD_NAME) */
-void mg_set_thread_name(const char* threadName) {}
-#endif
-
-#if defined(MG_LEGACY_INTERFACE)
-const char **mg_get_valid_option_names(void)
-{
- static const char * data[2 * sizeof(config_options) / sizeof(config_options[0])] = {0};
- int i;
-
- for (i=0; config_options[i].name != NULL; i++) {
- data[i * 2] = config_options[i].name;
- data[i * 2 + 1] = config_options[i].default_value;
- }
-
- return data;
-}
-#endif
-
-const struct mg_option *mg_get_valid_options(void)
-{
- return config_options;
-}
-
-
-static int is_file_in_memory(struct mg_connection *conn, const char *path,
- struct file *filep)
-{
- size_t size = 0;
- if ((filep->membuf = conn->ctx->callbacks.open_file == NULL ? NULL :
- conn->ctx->callbacks.open_file(conn, path, &size)) != NULL) {
- /* NOTE: override filep->size only on success. Otherwise, it might
- break constructs like if (!mg_stat() || !mg_fopen()) ... */
- filep->size = size;
- }
- return filep->membuf != NULL;
-}
-
-static int is_file_opened(const struct file *filep)
-{
- return filep->membuf != NULL || filep->fp != NULL;
-}
-
-static int mg_fopen(struct mg_connection *conn, const char *path,
- const char *mode, struct file *filep)
-{
- if (!is_file_in_memory(conn, path, filep)) {
-#ifdef _WIN32
- wchar_t wbuf[PATH_MAX], wmode[20];
- to_unicode(path, wbuf, ARRAY_SIZE(wbuf));
- MultiByteToWideChar(CP_UTF8, 0, mode, -1, wmode, ARRAY_SIZE(wmode));
- filep->fp = _wfopen(wbuf, wmode);
-#else
- filep->fp = fopen(path, mode);
-#endif
- }
-
- return is_file_opened(filep);
-}
-
-static void mg_fclose(struct file *filep)
-{
- if (filep != NULL && filep->fp != NULL) {
- fclose(filep->fp);
- }
-}
-
-static void mg_strlcpy(register char *dst, register const char *src, size_t n)
-{
- for (; *src != '\0' && n > 1; n--) {
- *dst++ = *src++;
- }
- *dst = '\0';
-}
-
-static int lowercase(const char *s)
-{
- return tolower(* (const unsigned char *) s);
-}
-
-int mg_strncasecmp(const char *s1, const char *s2, size_t len)
-{
- int diff = 0;
-
- if (len > 0)
- do {
- diff = lowercase(s1++) - lowercase(s2++);
- } while (diff == 0 && s1[-1] != '\0' && --len > 0);
-
- return diff;
-}
-
-static int mg_strcasecmp(const char *s1, const char *s2)
-{
- int diff;
-
- do {
- diff = lowercase(s1++) - lowercase(s2++);
- } while (diff == 0 && s1[-1] != '\0');
-
- return diff;
-}
-
-static char * mg_strndup(const char *ptr, size_t len)
-{
- char *p;
-
- if ((p = (char *) mg_malloc(len + 1)) != NULL) {
- mg_strlcpy(p, ptr, len + 1);
- }
-
- return p;
-}
-
-static char * mg_strdup(const char *str)
-{
- return mg_strndup(str, strlen(str));
-}
-
-static const char *mg_strcasestr(const char *big_str, const char *small_str)
-{
- int i, big_len = (int)strlen(big_str), small_len = (int)strlen(small_str);
-
- for (i = 0; i <= big_len - small_len; i++) {
- if (mg_strncasecmp(big_str + i, small_str, small_len) == 0) {
- return big_str + i;
- }
- }
-
- return NULL;
-}
-
-/* Like snprintf(), but never returns negative value, or a value
- that is larger than a supplied buffer.
- Thanks to Adam Zeldis to pointing snprintf()-caused vulnerability
- in his audit report. */
-static int mg_vsnprintf(struct mg_connection *conn, char *buf, size_t buflen,
- const char *fmt, va_list ap)
-{
- int n;
-
- if (buflen == 0)
- return 0;
-
- n = vsnprintf(buf, buflen, fmt, ap);
-
- if (n < 0) {
- mg_cry(conn, "vsnprintf error");
- n = 0;
- } else if (n >= (int) buflen) {
- mg_cry(conn, "truncating vsnprintf buffer: [%.*s]",
- n > 200 ? 200 : n, buf);
- n = (int) buflen - 1;
- }
- buf[n] = '\0';
-
- return n;
-}
-
-static int mg_snprintf(struct mg_connection *conn, char *buf, size_t buflen,
- PRINTF_FORMAT_STRING(const char *fmt), ...)
-PRINTF_ARGS(4, 5);
-
-static int mg_snprintf(struct mg_connection *conn, char *buf, size_t buflen,
- const char *fmt, ...)
-{
- va_list ap;
- int n;
-
- va_start(ap, fmt);
- n = mg_vsnprintf(conn, buf, buflen, fmt, ap);
- va_end(ap);
-
- return n;
-}
-
-static int get_option_index(const char *name)
-{
- int i;
-
- for (i = 0; config_options[i].name != NULL; i++) {
- if (strcmp(config_options[i].name, name) == 0) {
- return i;
- }
- }
- return -1;
-}
-
-const char *mg_get_option(const struct mg_context *ctx, const char *name)
-{
- int i;
- if ((i = get_option_index(name)) == -1) {
- return NULL;
- } else if (ctx->config[i] == NULL) {
- return "";
- } else {
- return ctx->config[i];
- }
-}
-
-struct mg_context *mg_get_context(struct mg_connection * conn)
-{
- return (conn == NULL) ? (struct mg_context *)NULL : (conn->ctx);
-}
-
-void *mg_get_user_data(struct mg_context *ctx)
-{
- return (ctx == NULL) ? NULL : ctx->user_data;
-}
-
-size_t mg_get_ports(const struct mg_context *ctx, size_t size, int* ports, int* ssl)
-{
- size_t i;
- for (i = 0; i < size && i < (size_t)ctx->num_listening_sockets; i++)
- {
- ssl[i] = ctx->listening_sockets[i].is_ssl;
- ports[i] = ctx->listening_ports[i];
- }
- return i;
-}
-
-static void sockaddr_to_string(char *buf, size_t len,
- const union usa *usa)
-{
- buf[0] = '\0';
-#if defined(USE_IPV6)
- inet_ntop(usa->sa.sa_family, usa->sa.sa_family == AF_INET ?
- (void *) &usa->sin.sin_addr :
- (void *) &usa->sin6.sin6_addr, buf, len);
-#elif defined(_WIN32)
- /* Only Windows Vista (and newer) have inet_ntop() */
- mg_strlcpy(buf, inet_ntoa(usa->sin.sin_addr), len);
-#else
- inet_ntop(usa->sa.sa_family, (void *) &usa->sin.sin_addr, buf, len);
-#endif
-}
-
-/* Convert time_t to a string. According to RFC2616, Sec 14.18, this must be included in all responses other than 100, 101, 5xx. */
-static void gmt_time_string(char *buf, size_t buf_len, time_t *t)
-{
- struct tm *tm;
-
- tm = gmtime(t);
- if (tm != NULL) {
- strftime(buf, buf_len, "%a, %d %b %Y %H:%M:%S GMT", tm);
- } else {
- mg_strlcpy(buf, "Thu, 01 Jan 1970 00:00:00 GMT", buf_len);
- buf[buf_len - 1] = '\0';
- }
-}
-
-/* Print error message to the opened error log stream. */
-void mg_cry(struct mg_connection *conn, const char *fmt, ...)
-{
- char buf[MG_BUF_LEN], src_addr[IP_ADDR_STR_LEN];
- va_list ap;
- FILE *fp;
- time_t timestamp;
-
- va_start(ap, fmt);
- IGNORE_UNUSED_RESULT(vsnprintf(buf, sizeof(buf), fmt, ap));
- va_end(ap);
-
- /* Do not lock when getting the callback value, here and below.
- I suppose this is fine, since function cannot disappear in the
- same way string option can. */
- if (conn->ctx->callbacks.log_message == NULL ||
- conn->ctx->callbacks.log_message(conn, buf) == 0) {
- fp = conn->ctx->config[ERROR_LOG_FILE] == NULL ? NULL :
- fopen(conn->ctx->config[ERROR_LOG_FILE], "a+");
-
- if (fp != NULL) {
- flockfile(fp);
- timestamp = time(NULL);
-
- sockaddr_to_string(src_addr, sizeof(src_addr), &conn->client.rsa);
- fprintf(fp, "[%010lu] [error] [client %s] ", (unsigned long) timestamp,
- src_addr);
-
- if (conn->request_info.request_method != NULL) {
- fprintf(fp, "%s %s: ", conn->request_info.request_method,
- conn->request_info.uri);
- }
-
- fprintf(fp, "%s", buf);
- fputc('\n', fp);
- funlockfile(fp);
- fclose(fp);
- }
- }
-}
-
-/* Return fake connection structure. Used for logging, if connection
- is not applicable at the moment of logging. */
-static struct mg_connection *fc(struct mg_context *ctx)
-{
- static struct mg_connection fake_connection;
- fake_connection.ctx = ctx;
- return &fake_connection;
-}
-
-const char *mg_version(void)
-{
- return CIVETWEB_VERSION;
-}
-
-struct mg_request_info *mg_get_request_info(struct mg_connection *conn)
-{
- return &conn->request_info;
-}
-
-/* Skip the characters until one of the delimiters characters found.
- 0-terminate resulting word. Skip the delimiter and following whitespaces.
- Advance pointer to buffer to the next word. Return found 0-terminated word.
- Delimiters can be quoted with quotechar. */
-static char *skip_quoted(char **buf, const char *delimiters,
- const char *whitespace, char quotechar)
-{
- char *p, *begin_word, *end_word, *end_whitespace;
-
- begin_word = *buf;
- end_word = begin_word + strcspn(begin_word, delimiters);
-
- /* Check for quotechar */
- if (end_word > begin_word) {
- p = end_word - 1;
- while (*p == quotechar) {
- /* TODO (bel): it seems this code is never reached, so quotechar is actually
- not needed - check if this code may be droped */
-
- /* If there is anything beyond end_word, copy it */
- if (*end_word == '\0') {
- *p = '\0';
- break;
- } else {
- size_t end_off = strcspn(end_word + 1, delimiters);
- memmove (p, end_word, end_off + 1);
- p += end_off; /* p must correspond to end_word - 1 */
- end_word += end_off + 1;
- }
- }
- for (p++; p < end_word; p++) {
- *p = '\0';
- }
- }
-
- if (*end_word == '\0') {
- *buf = end_word;
- } else {
- end_whitespace = end_word + 1 + strspn(end_word + 1, whitespace);
-
- for (p = end_word; p < end_whitespace; p++) {
- *p = '\0';
- }
-
- *buf = end_whitespace;
- }
-
- return begin_word;
-}
-
-/* Simplified version of skip_quoted without quote char
- and whitespace == delimiters */
-static char *skip(char **buf, const char *delimiters)
-{
- return skip_quoted(buf, delimiters, delimiters, 0);
-}
-
-
-/* Return HTTP header value, or NULL if not found. */
-static const char *get_header(const struct mg_request_info *ri,
- const char *name)
-{
- int i;
-
- for (i = 0; i < ri->num_headers; i++)
- if (!mg_strcasecmp(name, ri->http_headers[i].name))
- return ri->http_headers[i].value;
-
- return NULL;
-}
-
-const char *mg_get_header(const struct mg_connection *conn, const char *name)
-{
- return get_header(&conn->request_info, name);
-}
-
-/* A helper function for traversing a comma separated list of values.
- It returns a list pointer shifted to the next value, or NULL if the end
- of the list found.
- Value is stored in val vector. If value has form "x=y", then eq_val
- vector is initialized to point to the "y" part, and val vector length
- is adjusted to point only to "x". */
-static const char *next_option(const char *list, struct vec *val,
- struct vec *eq_val)
-{
- if (list == NULL || *list == '\0') {
- /* End of the list */
- list = NULL;
- } else {
- val->ptr = list;
- if ((list = strchr(val->ptr, ',')) != NULL) {
- /* Comma found. Store length and shift the list ptr */
- val->len = list - val->ptr;
- list++;
- } else {
- /* This value is the last one */
- list = val->ptr + strlen(val->ptr);
- val->len = list - val->ptr;
- }
-
- if (eq_val != NULL) {
- /* Value has form "x=y", adjust pointers and lengths
- so that val points to "x", and eq_val points to "y". */
- eq_val->len = 0;
- eq_val->ptr = (const char *) memchr(val->ptr, '=', val->len);
- if (eq_val->ptr != NULL) {
- eq_val->ptr++; /* Skip over '=' character */
- eq_val->len = val->ptr + val->len - eq_val->ptr;
- val->len = (eq_val->ptr - val->ptr) - 1;
- }
- }
- }
-
- return list;
-}
-
-/* Perform case-insensitive match of string against pattern */
-static int match_prefix(const char *pattern, int pattern_len, const char *str)
-{
- const char *or_str;
- int i, j, len, res;
-
- if ((or_str = (const char *) memchr(pattern, '|', pattern_len)) != NULL) {
- res = match_prefix(pattern, (int)(or_str - pattern), str);
- return res > 0 ? res :
- match_prefix(or_str + 1, (int)((pattern + pattern_len) - (or_str + 1)), str);
- }
-
- i = j = 0;
- for (; i < pattern_len; i++, j++) {
- if (pattern[i] == '?' && str[j] != '\0') {
- continue;
- } else if (pattern[i] == '$') {
- return str[j] == '\0' ? j : -1;
- } else if (pattern[i] == '*') {
- i++;
- if (pattern[i] == '*') {
- i++;
- len = (int) strlen(str + j);
- } else {
- len = (int) strcspn(str + j, "/");
- }
- if (i == pattern_len) {
- return j + len;
- }
- do {
- res = match_prefix(pattern + i, pattern_len - i, str + j + len);
- } while (res == -1 && len-- > 0);
- return res == -1 ? -1 : j + res + len;
- } else if (lowercase(&pattern[i]) != lowercase(&str[j])) {
- return -1;
- }
- }
- return j;
-}
-
-/* HTTP 1.1 assumes keep alive if "Connection:" header is not set
- This function must tolerate situations when connection info is not
- set up, for example if request parsing failed. */
-static int should_keep_alive(const struct mg_connection *conn)
-{
- const char *http_version = conn->request_info.http_version;
- const char *header = mg_get_header(conn, "Connection");
- if (conn->must_close ||
- conn->status_code == 401 ||
- mg_strcasecmp(conn->ctx->config[ENABLE_KEEP_ALIVE], "yes") != 0 ||
- (header != NULL && mg_strcasecmp(header, "keep-alive") != 0) ||
- (header == NULL && http_version && 0!=strcmp(http_version, "1.1"))) {
- return 0;
- }
- return 1;
-}
-
-static int should_decode_url(const struct mg_connection *conn)
-{
- return (mg_strcasecmp(conn->ctx->config[DECODE_URL], "yes") == 0);
-}
-
-static const char *suggest_connection_header(const struct mg_connection *conn)
-{
- return should_keep_alive(conn) ? "keep-alive" : "close";
-}
-
-static void handle_file_based_request(struct mg_connection *conn, const char *path, struct file *filep);
-static int mg_stat(struct mg_connection *conn, const char *path, struct file *filep);
-
-static const char *mg_get_response_code_text(int response_code, struct mg_connection *conn)
-{
- switch (response_code)
- {
- /* RFC2616 Section 10.1 - Informational 1xx */
- case 100: return "Continue"; /* RFC2616 Section 10.1.1 */
- case 101: return "Switching Protocols"; /* RFC2616 Section 10.1.2 */
- case 102: return "Processing"; /* RFC2518 Section 10.1 */
-
- /* RFC2616 Section 10.2 - Successful 2xx */
- case 200: return "OK"; /* RFC2616 Section 10.2.1 */
- case 201: return "Created"; /* RFC2616 Section 10.2.2 */
- case 202: return "Accepted"; /* RFC2616 Section 10.2.3 */
- case 203: return "Non-Authoritative Information"; /* RFC2616 Section 10.2.4 */
- case 204: return "No Content"; /* RFC2616 Section 10.2.5 */
- case 205: return "Reset Content"; /* RFC2616 Section 10.2.6 */
- case 206: return "Partial Content"; /* RFC2616 Section 10.2.7 */
- case 207: return "Multi-Status"; /* RFC2518 Section 10.2, RFC4918 Section 11.1 */
-
- /* RFC2616 Section 10.3 - Redirection 3xx */
- case 300: return "Multiple Choices"; /* RFC2616 Section 10.3.1 */
- case 301: return "Moved Permanently"; /* RFC2616 Section 10.3.2 */
- case 302: return "Found"; /* RFC2616 Section 10.3.3 */
- case 303: return "See Other"; /* RFC2616 Section 10.3.4 */
- case 304: return "Not Modified"; /* RFC2616 Section 10.3.5 */
- case 305: return "Use Proxy"; /* RFC2616 Section 10.3.6 */
- case 307: return "Temporary Redirect"; /* RFC2616 Section 10.3.8 */
-
- /* RFC2616 Section 10.4 - Client Error 4xx */
- case 400: return "Bad Request"; /* RFC2616 Section 10.4.1 */
- case 401: return "Unauthorized"; /* RFC2616 Section 10.4.2 */
- case 402: return "Payment Required"; /* RFC2616 Section 10.4.3 */
- case 403: return "Forbidden"; /* RFC2616 Section 10.4.4 */
- case 404: return "Not Found"; /* RFC2616 Section 10.4.5 */
- case 405: return "Method Not Allowed"; /* RFC2616 Section 10.4.6 */
- case 406: return "Not Acceptable"; /* RFC2616 Section 10.4.7 */
- case 407: return "Proxy Authentication Required"; /* RFC2616 Section 10.4.8 */
- case 408: return "Request Time-out"; /* RFC2616 Section 10.4.9 */
- case 409: return "Conflict"; /* RFC2616 Section 10.4.10 */
- case 410: return "Gone"; /* RFC2616 Section 10.4.11 */
- case 411: return "Length Required"; /* RFC2616 Section 10.4.12 */
- case 412: return "Precondition Failed"; /* RFC2616 Section 10.4.13 */
- case 413: return "Request Entity Too Large"; /* RFC2616 Section 10.4.14 */
- case 414: return "Request-URI Too Large"; /* RFC2616 Section 10.4.15 */
- case 415: return "Unsupported Media Type"; /* RFC2616 Section 10.4.16 */
- case 416: return "Requested range not satisfiable"; /* RFC2616 Section 10.4.17 */
- case 417: return "Expectation Failed"; /* RFC2616 Section 10.4.18 */
- case 422: return "Unproccessable entity"; /* RFC2518 Section 10.3, RFC4918 Section 11.2 */
- case 423: return "Locked"; /* RFC2518 Section 10.4, RFC4918 Section 11.3 */
- case 424: return "Failed Dependency"; /* RFC2518 Section 10.5, RFC4918 Section 11.4 */
- case 428: return "Precondition Required"; /* RFC 6585, Section 3 */
- case 429: return "Too Many Requests"; /* RFC 6585, Section 4 */
- case 431: return "Request Header Fields Too Large"; /* RFC 6585, Section 5 */
-
- /* RFC2616 Section 10.5 - Server Error 5xx */
- case 500: return "Internal Server Error"; /* RFC2616 Section 10.5.1 */
- case 501: return "Not Implemented"; /* RFC2616 Section 10.5.2 */
- case 502: return "Bad Gateway"; /* RFC2616 Section 10.5.3 */
- case 503: return "Service Unavailable"; /* RFC2616 Section 10.5.4 */
- case 504: return "Gateway Time-out"; /* RFC2616 Section 10.5.5 */
- case 505: return "HTTP Version not supported"; /* RFC2616 Section 10.5.6 */
- case 507: return "Insufficient Storage"; /* RFC2518 Section 10.6, , RFC4918 Section 11.5 */
- case 511: return "Network Authentication Required"; /* RFC 6585, Section 6 */
-
- /* Other RFCs */
- case 426: return "Upgrade Required"; /* RFC 2817 */
-
- /* Return codes from non normative RFCs: */
- /* Informative and experimental RFCs, "de facto" standards due to common use, ... */
- case 208: return "Already Reported"; /* RFC5842 Section 7.1 */
- case 226: return "IM used"; /* RFC3229 Section 10.4.1 */
- case 308: return "Permanent Redirect"; /* RFC7238 Section 3 */
- case 418: return "I am a teapot"; /* RFC2324 Section 2.3.2 */
- case 419: return "Authentication Timeout"; /* common use */
- case 451: return "Unavailable For Legal Reasons"; /* draft-tbray-http-legally-restricted-status-05, Section 3 */
- case 506: return "Variant Also Negotiates"; /* RFC 2295, Section 8.1 */
- case 508: return "Loop Detected"; /* RFC5842 Section 7.1 */
- case 510: return "Not Extended"; /* RFC 2774, Section 7 */
-
- default:
- /* This error code is unknown. This should not happen. */
- if (conn) {
- mg_cry(conn, "Unknown HTTP response code: %u", response_code);
- }
-
- /* Return at least a category according to RFC 2616 Section 10. */
- if (response_code>=100 && response_code<200) {
- /* Unknown informational status code */
- return "Information";
- }
- if (response_code>=200 && response_code<300) {
- /* Unknown success code */
- return "Success";
- }
- if (response_code>=300 && response_code<400) {
- /* Unknown redirection code */
- return "Redirection";
- }
- if (response_code>=400 && response_code<500) {
- /* Unknown request error code */
- return "Client Error";
- }
- if (response_code>=500 && response_code<600) {
- /* Unknown server error code */
- return "Server Error";
- }
-
- /* Response code not even within reasonable range */
- return "";
- }
-}
-
-
-static void send_http_error(struct mg_connection *, int, const char *,
- PRINTF_FORMAT_STRING(const char *fmt), ...)
-PRINTF_ARGS(4, 5);
-
-
-static void send_http_error(struct mg_connection *conn, int status,
- const char *reason, const char *fmt, ...)
-{
- char buf[MG_BUF_LEN];
- va_list ap;
- int len = 0, i, page_handler_found, scope;
- char date[64];
- time_t curtime = time(NULL);
- const char *error_handler = NULL;
- struct file error_page_file = STRUCT_FILE_INITIALIZER;
- const char *error_page_file_ext, *tstr;
-
- if (!reason) {
- reason = mg_get_response_code_text(status, conn);
- }
-
- conn->status_code = status;
- if (conn->in_error_handler ||
- conn->ctx->callbacks.http_error == NULL ||
- conn->ctx->callbacks.http_error(conn, status)) {
-
- if (!conn->in_error_handler) {
- /* Send user defined error pages, if defined */
- error_handler = conn->ctx->config[ERROR_PAGES];
- error_page_file_ext = conn->ctx->config[INDEX_FILES];
- page_handler_found = 0;
- if (error_handler != NULL) {
- for (scope=1; (scope<=3) && !page_handler_found; scope++) {
- switch (scope) {
- case 1:
- len = mg_snprintf(conn, buf, sizeof(buf)-32, "%serror%03u.", error_handler, status);
- break;
- case 2:
- len = mg_snprintf(conn, buf, sizeof(buf)-32, "%serror%01uxx.", error_handler, status/100);
- break;
- default:
- len = mg_snprintf(conn, buf, sizeof(buf)-32, "%serror.", error_handler);
- break;
- }
- tstr = strchr(error_page_file_ext, '.');
- while (tstr) {
- for (i=1; i<32 && tstr[i]!=0 && tstr[i]!=','; i++) buf[len+i-1]=tstr[i];
- buf[len+i-1]=0;
- if (mg_stat(conn, buf, &error_page_file)) {
- page_handler_found = 1;
- break;
- }
- tstr = strchr(tstr+i, '.');
- }
- }
- }
-
- if (page_handler_found) {
- conn->in_error_handler = 1;
- handle_file_based_request(conn, buf, &error_page_file);
- conn->in_error_handler = 0;
- return;
- }
- }
-
- buf[0] = '\0';
- gmt_time_string(date, sizeof(date), &curtime);
-
- /* Errors 1xx, 204 and 304 MUST NOT send a body */
- if (status > 199 && status != 204 && status != 304) {
- len = mg_snprintf(conn, buf, sizeof(buf)-1, "Error %d: %s", status, reason);
- buf[len] = '\n';
- len++;
- buf[len] = 0;
-
- va_start(ap, fmt);
- len += mg_vsnprintf(conn, buf + len, sizeof(buf) - len, fmt, ap);
- va_end(ap);
- }
- DEBUG_TRACE("[%s]", buf);
-
- mg_printf(conn, "HTTP/1.1 %d %s\r\n"
- "Content-Length: %d\r\n"
- "Date: %s\r\n"
- "Connection: %s\r\n\r\n",
- status, reason, len, date,
- suggest_connection_header(conn));
- conn->num_bytes_sent += mg_printf(conn, "%s", buf);
- }
-}
-
-#if defined(_WIN32) && !defined(__SYMBIAN32__)
-static int pthread_mutex_init(pthread_mutex_t *mutex, void *unused)
-{
- (void) unused;
- *mutex = CreateMutex(NULL, FALSE, NULL);
- return *mutex == NULL ? -1 : 0;
-}
-
-static int pthread_mutex_destroy(pthread_mutex_t *mutex)
-{
- return CloseHandle(*mutex) == 0 ? -1 : 0;
-}
-
-static int pthread_mutex_lock(pthread_mutex_t *mutex)
-{
- return WaitForSingleObject(*mutex, INFINITE) == WAIT_OBJECT_0 ? 0 : -1;
-}
-
-static int pthread_mutex_trylock(pthread_mutex_t *mutex)
-{
- switch (WaitForSingleObject(*mutex, 0)) {
- case WAIT_OBJECT_0:
- return 0;
- case WAIT_TIMEOUT:
- return -2; /* EBUSY */
- }
- return -1;
-}
-
-static int pthread_mutex_unlock(pthread_mutex_t *mutex)
-{
- return ReleaseMutex(*mutex) == 0 ? -1 : 0;
-}
-
-#ifndef WIN_PTHREADS_TIME_H
-static int clock_gettime(clockid_t clk_id, struct timespec *tp)
-{
- FILETIME ft;
- ULARGE_INTEGER li;
- BOOL ok = FALSE;
- double d;
- static double perfcnt_per_sec = 0.0;
-
- if (tp) {
- if (clk_id == CLOCK_REALTIME) {
- GetSystemTimeAsFileTime(&ft);
- li.LowPart = ft.dwLowDateTime;
- li.HighPart = ft.dwHighDateTime;
- li.QuadPart -= 116444736000000000; /* 1.1.1970 in filedate */
- tp->tv_sec = (time_t)(li.QuadPart / 10000000);
- tp->tv_nsec = (long)(li.QuadPart % 10000000) * 100;
- ok = TRUE;
- } else if (clk_id == CLOCK_MONOTONIC) {
- if (perfcnt_per_sec == 0.0) {
- QueryPerformanceFrequency((LARGE_INTEGER *) &li);
- perfcnt_per_sec = 1.0 / li.QuadPart;
- }
- if (perfcnt_per_sec != 0.0) {
- QueryPerformanceCounter((LARGE_INTEGER *) &li);
- d = li.QuadPart * perfcnt_per_sec;
- tp->tv_sec = (time_t)d;
- d -= tp->tv_sec;
- tp->tv_nsec = (long)(d*1.0E9);
- ok = TRUE;
- }
- }
- }
-
- return ok ? 0 : -1;
-}
-#endif
-
-static int pthread_cond_init(pthread_cond_t *cv, const void *unused)
-{
- (void) unused;
- InitializeCriticalSection(&cv->threadIdSec);
- cv->waitingthreadcount = 0;
- cv->waitingthreadhdls = (pthread_t *) mg_calloc(MAX_WORKER_THREADS, sizeof(pthread_t));
- return (cv->waitingthreadhdls!=NULL) ? 0 : -1;
-}
-
-static int pthread_cond_timedwait(pthread_cond_t *cv, pthread_mutex_t *mutex, const struct timespec * abstime)
-{
- struct mg_workerTLS * tls = (struct mg_workerTLS *)TlsGetValue(sTlsKey);
- int ok;
- struct timespec tsnow;
- int64_t nsnow, nswaitabs, nswaitrel;
- DWORD mswaitrel;
-
- EnterCriticalSection(&cv->threadIdSec);
- assert(cv->waitingthreadcount < MAX_WORKER_THREADS);
- cv->waitingthreadhdls[cv->waitingthreadcount] = tls->pthread_cond_helper_mutex;
- cv->waitingthreadcount++;
- LeaveCriticalSection(&cv->threadIdSec);
-
- if (abstime) {
- clock_gettime(CLOCK_REALTIME, &tsnow);
- nsnow = (((uint64_t)tsnow.tv_sec)*1000000000) + tsnow.tv_nsec;
- nswaitabs = (((uint64_t)abstime->tv_sec)*1000000000) + abstime->tv_nsec;
- nswaitrel = nswaitabs - nsnow;
- if (nswaitrel<0) nswaitrel=0;
- mswaitrel = (DWORD)(nswaitrel / 1000000);
- } else {
- mswaitrel = INFINITE;
- }
-
- pthread_mutex_unlock(mutex);
- ok = (WAIT_OBJECT_0 == WaitForSingleObject(tls->pthread_cond_helper_mutex, mswaitrel));
- pthread_mutex_lock(mutex);
-
- return ok ? 0 : -1;
-}
-
-static int pthread_cond_wait(pthread_cond_t *cv, pthread_mutex_t *mutex)
-{
- return pthread_cond_timedwait(cv, mutex, NULL);
-}
-
-static int pthread_cond_signal(pthread_cond_t *cv)
-{
- int i;
- HANDLE wkup = NULL;
- BOOL ok = FALSE;
-
- EnterCriticalSection(&cv->threadIdSec);
- if (cv->waitingthreadcount) {
- wkup = cv->waitingthreadhdls[0];
- ok = SetEvent(wkup);
-
- for (i=1; i<cv->waitingthreadcount; i++) {
- cv->waitingthreadhdls[i-1] = cv->waitingthreadhdls[i];
- }
- cv->waitingthreadcount--;
-
- assert(ok);
- }
- LeaveCriticalSection(&cv->threadIdSec);
-
- return ok ? 0 : 1;
-}
-
-static int pthread_cond_broadcast(pthread_cond_t *cv)
-{
- EnterCriticalSection(&cv->threadIdSec);
- while (cv->waitingthreadcount) {
- pthread_cond_signal(cv);
- }
- LeaveCriticalSection(&cv->threadIdSec);
-
- return 0;
-}
-
-static int pthread_cond_destroy(pthread_cond_t *cv)
-{
- EnterCriticalSection(&cv->threadIdSec);
- assert(cv->waitingthreadcount==0);
- mg_free(cv->waitingthreadhdls);
- cv->waitingthreadhdls = 0;
- LeaveCriticalSection(&cv->threadIdSec);
- DeleteCriticalSection(&cv->threadIdSec);
-
- return 0;
-}
-
-/* For Windows, change all slashes to backslashes in path names. */
-static void change_slashes_to_backslashes(char *path)
-{
- int i;
-
- for (i = 0; path[i] != '\0'; i++) {
- if (path[i] == '/')
- path[i] = '\\';
- /* i > 0 check is to preserve UNC paths, like \\server\file.txt */
- if (path[i] == '\\' && i > 0)
- while (path[i + 1] == '\\' || path[i + 1] == '/')
- (void) memmove(path + i + 1,
- path + i + 2, strlen(path + i + 1));
- }
-}
-
-/* Encode 'path' which is assumed UTF-8 string, into UNICODE string.
- wbuf and wbuf_len is a target buffer and its length. */
-static void to_unicode(const char *path, wchar_t *wbuf, size_t wbuf_len)
-{
- char buf[PATH_MAX], buf2[PATH_MAX];
-
- mg_strlcpy(buf, path, sizeof(buf));
- change_slashes_to_backslashes(buf);
-
- /* Convert to Unicode and back. If doubly-converted string does not
- match the original, something is fishy, reject. */
- memset(wbuf, 0, wbuf_len * sizeof(wchar_t));
- MultiByteToWideChar(CP_UTF8, 0, buf, -1, wbuf, (int) wbuf_len);
- WideCharToMultiByte(CP_UTF8, 0, wbuf, (int) wbuf_len, buf2, sizeof(buf2),
- NULL, NULL);
- if (strcmp(buf, buf2) != 0) {
- wbuf[0] = L'\0';
- }
-}
-
-#if defined(_WIN32_WCE)
-static time_t time(time_t *ptime)
-{
- time_t t;
- SYSTEMTIME st;
- FILETIME ft;
-
- GetSystemTime(&st);
- SystemTimeToFileTime(&st, &ft);
- t = SYS2UNIX_TIME(ft.dwLowDateTime, ft.dwHighDateTime);
-
- if (ptime != NULL) {
- *ptime = t;
- }
-
- return t;
-}
-
-static struct tm *localtime(const time_t *ptime, struct tm *ptm)
-{
- int64_t t = ((int64_t) *ptime) * RATE_DIFF + EPOCH_DIFF;
- FILETIME ft, lft;
- SYSTEMTIME st;
- TIME_ZONE_INFORMATION tzinfo;
-
- if (ptm == NULL) {
- return NULL;
- }
-
- * (int64_t *) &ft = t;
- FileTimeToLocalFileTime(&ft, &lft);
- FileTimeToSystemTime(&lft, &st);
- ptm->tm_year = st.wYear - 1900;
- ptm->tm_mon = st.wMonth - 1;
- ptm->tm_wday = st.wDayOfWeek;
- ptm->tm_mday = st.wDay;
- ptm->tm_hour = st.wHour;
- ptm->tm_min = st.wMinute;
- ptm->tm_sec = st.wSecond;
- ptm->tm_yday = 0; /* hope nobody uses this */
- ptm->tm_isdst =
- GetTimeZoneInformation(&tzinfo) == TIME_ZONE_ID_DAYLIGHT ? 1 : 0;
-
- return ptm;
-}
-
-static struct tm *gmtime(const time_t *ptime, struct tm *ptm)
-{
- /* FIXME(lsm): fix this. */
- return localtime(ptime, ptm);
-}
-
-static size_t strftime(char *dst, size_t dst_size, const char *fmt,
- const struct tm *tm)
-{
- (void) snprintf(dst, dst_size, "implement strftime() for WinCE");
- return 0;
-}
-#endif
-
-/* Windows happily opens files with some garbage at the end of file name.
- For example, fopen("a.cgi ", "r") on Windows successfully opens
- "a.cgi", despite one would expect an error back.
- This function returns non-0 if path ends with some garbage. */
-static int path_cannot_disclose_cgi(const char *path)
-{
- static const char *allowed_last_characters = "_-";
- int last = path[strlen(path) - 1];
- return isalnum(last) || strchr(allowed_last_characters, last) != NULL;
-}
-
-static int mg_stat(struct mg_connection *conn, const char *path, struct file *filep)
-{
- wchar_t wbuf[PATH_MAX];
- WIN32_FILE_ATTRIBUTE_DATA info;
-
- if (!is_file_in_memory(conn, path, filep)) {
- to_unicode(path, wbuf, ARRAY_SIZE(wbuf));
- if (GetFileAttributesExW(wbuf, GetFileExInfoStandard, &info) != 0) {
- filep->size = MAKEUQUAD(info.nFileSizeLow, info.nFileSizeHigh);
- filep->modification_time = SYS2UNIX_TIME(
- info.ftLastWriteTime.dwLowDateTime,
- info.ftLastWriteTime.dwHighDateTime);
- filep->is_directory = info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
- /* If file name is fishy, reset the file structure and return
- error.
- Note it is important to reset, not just return the error, cause
- functions like is_file_opened() check the struct. */
- if (!filep->is_directory && !path_cannot_disclose_cgi(path)) {
- memset(filep, 0, sizeof(*filep));
- }
- }
- }
-
- return filep->membuf != NULL || filep->modification_time != 0;
-}
-
-static int mg_remove(const char *path)
-{
- wchar_t wbuf[PATH_MAX];
- to_unicode(path, wbuf, ARRAY_SIZE(wbuf));
- return DeleteFileW(wbuf) ? 0 : -1;
-}
-
-static int mg_mkdir(const char *path, int mode)
-{
- char buf[PATH_MAX];
- wchar_t wbuf[PATH_MAX];
-
- (void) mode;
- mg_strlcpy(buf, path, sizeof(buf));
- change_slashes_to_backslashes(buf);
-
- (void) MultiByteToWideChar(CP_UTF8, 0, buf, -1, wbuf, ARRAY_SIZE(wbuf));
-
- return CreateDirectoryW(wbuf, NULL) ? 0 : -1;
-}
-
-/* Implementation of POSIX opendir/closedir/readdir for Windows. */
-static DIR * opendir(const char *name)
-{
- DIR *dir = NULL;
- wchar_t wpath[PATH_MAX];
- DWORD attrs;
-
- if (name == NULL) {
- SetLastError(ERROR_BAD_ARGUMENTS);
- } else if ((dir = (DIR *) mg_malloc(sizeof(*dir))) == NULL) {
- SetLastError(ERROR_NOT_ENOUGH_MEMORY);
- } else {
- to_unicode(name, wpath, ARRAY_SIZE(wpath));
- attrs = GetFileAttributesW(wpath);
- if (attrs != 0xFFFFFFFF &&
- ((attrs & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY)) {
- (void) wcscat(wpath, L"\\*");
- dir->handle = FindFirstFileW(wpath, &dir->info);
- dir->result.d_name[0] = '\0';
- } else {
- mg_free(dir);
- dir = NULL;
- }
- }
-
- return dir;
-}
-
-static int closedir(DIR *dir)
-{
- int result = 0;
-
- if (dir != NULL) {
- if (dir->handle != INVALID_HANDLE_VALUE)
- result = FindClose(dir->handle) ? 0 : -1;
-
- mg_free(dir);
- } else {
- result = -1;
- SetLastError(ERROR_BAD_ARGUMENTS);
- }
-
- return result;
-}
-
-static struct dirent *readdir(DIR *dir)
-{
- struct dirent *result = 0;
-
- if (dir) {
- if (dir->handle != INVALID_HANDLE_VALUE) {
- result = &dir->result;
- (void) WideCharToMultiByte(CP_UTF8, 0,
- dir->info.cFileName, -1, result->d_name,
- sizeof(result->d_name), NULL, NULL);
-
- if (!FindNextFileW(dir->handle, &dir->info)) {
- (void) FindClose(dir->handle);
- dir->handle = INVALID_HANDLE_VALUE;
- }
-
- } else {
- SetLastError(ERROR_FILE_NOT_FOUND);
- }
- } else {
- SetLastError(ERROR_BAD_ARGUMENTS);
- }
-
- return result;
-}
-
-#ifndef HAVE_POLL
-static int poll(struct pollfd *pfd, int n, int milliseconds)
-{
- struct timeval tv;
- fd_set set;
- int i, result;
- SOCKET maxfd = 0;
-
- tv.tv_sec = milliseconds / 1000;
- tv.tv_usec = (milliseconds % 1000) * 1000;
- FD_ZERO(&set);
-
- for (i = 0; i < n; i++) {
- FD_SET((SOCKET) pfd[i].fd, &set);
- pfd[i].revents = 0;
-
- if (pfd[i].fd > maxfd) {
- maxfd = pfd[i].fd;
- }
- }
-
- if ((result = select((int)maxfd + 1, &set, NULL, NULL, &tv)) > 0) {
- for (i = 0; i < n; i++) {
- if (FD_ISSET(pfd[i].fd, &set)) {
- pfd[i].revents = POLLIN;
- }
- }
- }
-
- return result;
-}
-#endif /* HAVE_POLL */
-
-static void set_close_on_exec(SOCKET sock, struct mg_connection *conn /* may be null */)
-{
- (void) conn; /* Unused. */
- (void) SetHandleInformation((HANDLE) sock, HANDLE_FLAG_INHERIT, 0);
-}
-
-int mg_start_thread(mg_thread_func_t f, void *p)
-{
-#if defined(USE_STACK_SIZE) && (USE_STACK_SIZE > 1)
- /* Compile-time option to control stack size, e.g. -DUSE_STACK_SIZE=16384 */
- return ((_beginthread((void (__cdecl *)(void *)) f, USE_STACK_SIZE, p) == ((uintptr_t)(-1L))) ? -1 : 0);
-#else
- return ((_beginthread((void (__cdecl *)(void *)) f, 0, p) == ((uintptr_t)(-1L))) ? -1 : 0);
-#endif /* defined(USE_STACK_SIZE) && (USE_STACK_SIZE > 1) */
-}
-
-/* Start a thread storing the thread context. */
-
-static int mg_start_thread_with_id(unsigned (__stdcall *f)(void *), void *p,
- pthread_t *threadidptr)
-{
- uintptr_t uip;
- HANDLE threadhandle;
- int result = -1;
-
- uip = _beginthreadex(NULL, 0, (unsigned (__stdcall *)(void *)) f, p, 0,
- NULL);
- threadhandle = (HANDLE) uip;
- if ((uip != (uintptr_t)(-1L)) && (threadidptr != NULL)) {
- *threadidptr = threadhandle;
- result = 0;
- }
-
- return result;
-}
-
-/* Wait for a thread to finish. */
-
-static int mg_join_thread(pthread_t threadid)
-{
- int result;
- DWORD dwevent;
-
- result = -1;
- dwevent = WaitForSingleObject(threadid, INFINITE);
- if (dwevent == WAIT_FAILED) {
- int err;
-
- err = GetLastError();
- DEBUG_TRACE("WaitForSingleObject() failed, error %d", err);
- } else {
- if (dwevent == WAIT_OBJECT_0) {
- CloseHandle(threadid);
- result = 0;
- }
- }
-
- return result;
-}
-
-static HANDLE dlopen(const char *dll_name, int flags)
-{
- wchar_t wbuf[PATH_MAX];
- (void) flags;
- to_unicode(dll_name, wbuf, ARRAY_SIZE(wbuf));
- return LoadLibraryW(wbuf);
-}
-
-static int dlclose(void *handle)
-{
- int result;
-
- if (FreeLibrary((HMODULE) handle) != 0) {
- result = 0;
- } else {
- result = -1;
- }
-
- return result;
-}
-
-#if !defined(NO_CGI)
-#define SIGKILL 0
-static int kill(pid_t pid, int sig_num)
-{
- (void) TerminateProcess(pid, sig_num);
- (void) CloseHandle(pid);
- return 0;
-}
-
-static void trim_trailing_whitespaces(char *s)
-{
- char *e = s + strlen(s) - 1;
- while (e > s && isspace(* (unsigned char *) e)) {
- *e-- = '\0';
- }
-}
-
-static pid_t spawn_process(struct mg_connection *conn, const char *prog,
- char *envblk, char *envp[], int fdin,
- int fdout, const char *dir)
-{
- HANDLE me;
- char *p, *interp, full_interp[PATH_MAX], full_dir[PATH_MAX],
- cmdline[PATH_MAX], buf[PATH_MAX];
- struct file file = STRUCT_FILE_INITIALIZER;
- STARTUPINFOA si;
- PROCESS_INFORMATION pi = { 0 };
-
- (void) envp;
-
- memset(&si, 0, sizeof(si));
- si.cb = sizeof(si);
-
- /* TODO(lsm): redirect CGI errors to the error log file */
- si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
- si.wShowWindow = SW_HIDE;
-
- me = GetCurrentProcess();
- DuplicateHandle(me, (HANDLE) _get_osfhandle(fdin), me,
- &si.hStdInput, 0, TRUE, DUPLICATE_SAME_ACCESS);
- DuplicateHandle(me, (HANDLE) _get_osfhandle(fdout), me,
- &si.hStdOutput, 0, TRUE, DUPLICATE_SAME_ACCESS);
-
- /* If CGI file is a script, try to read the interpreter line */
- interp = conn->ctx->config[CGI_INTERPRETER];
- if (interp == NULL) {
- buf[0] = buf[1] = '\0';
-
- /* Read the first line of the script into the buffer */
- snprintf(cmdline, sizeof(cmdline), "%s%c%s", dir, '/', prog);
- if (mg_fopen(conn, cmdline, "r", &file)) {
- p = (char *) file.membuf;
- mg_fgets(buf, sizeof(buf), &file, &p);
- mg_fclose(&file);
- buf[sizeof(buf) - 1] = '\0';
- }
-
- if (buf[0] == '#' && buf[1] == '!') {
- trim_trailing_whitespaces(buf + 2);
- } else {
- buf[2] = '\0';
- }
- interp = buf + 2;
- }
-
- if (interp[0] != '\0') {
- GetFullPathNameA(interp, sizeof(full_interp), full_interp, NULL);
- interp = full_interp;
- }
- GetFullPathNameA(dir, sizeof(full_dir), full_dir, NULL);
-
- mg_snprintf(conn, cmdline, sizeof(cmdline), "%s%s\"%s\\%s\"",
- interp, interp[0] == '\0' ? "" : " ", full_dir, prog);
-
- DEBUG_TRACE("Running [%s]", cmdline);
- if (CreateProcessA(NULL, cmdline, NULL, NULL, TRUE,
- CREATE_NEW_PROCESS_GROUP, envblk, NULL, &si, &pi) == 0) {
- mg_cry(conn, "%s: CreateProcess(%s): %ld",
- __func__, cmdline, ERRNO);
- pi.hProcess = (pid_t) -1;
- }
-
- (void) CloseHandle(si.hStdOutput);
- (void) CloseHandle(si.hStdInput);
- if (pi.hThread != NULL)
- (void) CloseHandle(pi.hThread);
-
- return (pid_t) pi.hProcess;
-}
-#endif /* !NO_CGI */
-
-static int set_non_blocking_mode(SOCKET sock)
-{
- unsigned long on = 1;
- return ioctlsocket(sock, FIONBIO, &on);
-}
-
-#else
-static int mg_stat(struct mg_connection *conn, const char *path,
- struct file *filep)
-{
- struct stat st;
-
- if (!is_file_in_memory(conn, path, filep) && !stat(path, &st)) {
- filep->size = st.st_size;
- filep->modification_time = st.st_mtime;
- filep->is_directory = S_ISDIR(st.st_mode);
- } else {
- filep->modification_time = (time_t) 0;
- }
-
- return filep->membuf != NULL || filep->modification_time != (time_t) 0;
-}
-
-static void set_close_on_exec(int fd, struct mg_connection *conn /* may be null */)
-{
- if (fcntl(fd, F_SETFD, FD_CLOEXEC) != 0) {
- if (conn) {
- mg_cry(conn, "%s: fcntl(F_SETFD FD_CLOEXEC) failed: %s", __func__, strerror(ERRNO));
- }
- }
-}
-
-int mg_start_thread(mg_thread_func_t func, void *param)
-{
- pthread_t thread_id;
- pthread_attr_t attr;
- int result;
-
- (void) pthread_attr_init(&attr);
- (void) pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
-
-#if defined(USE_STACK_SIZE) && (USE_STACK_SIZE > 1)
- /* Compile-time option to control stack size,
- e.g. -DUSE_STACK_SIZE=16384 */
- (void) pthread_attr_setstacksize(&attr, USE_STACK_SIZE);
-#endif /* defined(USE_STACK_SIZE) && (USE_STACK_SIZE > 1) */
-
- result = pthread_create(&thread_id, &attr, func, param);
- pthread_attr_destroy(&attr);
-
- return result;
-}
-
-/* Start a thread storing the thread context. */
-
-static int mg_start_thread_with_id(mg_thread_func_t func, void *param, pthread_t *threadidptr)
-{
- pthread_t thread_id;
- pthread_attr_t attr;
- int result;
-
- (void) pthread_attr_init(&attr);
-
-#if defined(USE_STACK_SIZE) && (USE_STACK_SIZE > 1)
- /* Compile-time option to control stack size,
- e.g. -DUSE_STACK_SIZE=16384 */
- (void) pthread_attr_setstacksize(&attr, USE_STACK_SIZE);
-#endif /* defined(USE_STACK_SIZE) && USE_STACK_SIZE > 1 */
-
- result = pthread_create(&thread_id, &attr, func, param);
- pthread_attr_destroy(&attr);
- if ((result == 0) && (threadidptr != NULL)) {
- *threadidptr = thread_id;
- }
- return result;
-}
-
-/* Wait for a thread to finish. */
-
-static int mg_join_thread(pthread_t threadid)
-{
- int result;
-
- result = pthread_join(threadid, NULL);
- return result;
-}
-
-#ifndef NO_CGI
-static pid_t spawn_process(struct mg_connection *conn, const char *prog,
- char *envblk, char *envp[], int fdin,
- int fdout, const char *dir)
-{
- pid_t pid;
- const char *interp;
-
- (void) envblk;
-
- if ((pid = fork()) == -1) {
- /* Parent */
- send_http_error(conn, 500, NULL,
- "Error: Creating CGI process\nfork(): %s", strerror(ERRNO));
- } else if (pid == 0) {
- /* Child */
- if (chdir(dir) != 0) {
- mg_cry(conn, "%s: chdir(%s): %s", __func__, dir, strerror(ERRNO));
- } else if (dup2(fdin, 0) == -1) {
- mg_cry(conn, "%s: dup2(%d, 0): %s", __func__, fdin, strerror(ERRNO));
- } else if (dup2(fdout, 1) == -1) {
- mg_cry(conn, "%s: dup2(%d, 1): %s", __func__, fdout, strerror(ERRNO));
- } else {
- /* Not redirecting stderr to stdout, to avoid output being littered
- with the error messages. */
- (void) close(fdin);
- (void) close(fdout);
-
- /* After exec, all signal handlers are restored to their default
- values, with one exception of SIGCHLD. According to
- POSIX.1-2001 and Linux's implementation, SIGCHLD's handler will
- leave unchanged after exec if it was set to be ignored. Restore
- it to default action. */
- signal(SIGCHLD, SIG_DFL);
-
- interp = conn->ctx->config[CGI_INTERPRETER];
- if (interp == NULL) {
- (void) execle(prog, prog, NULL, envp);
- mg_cry(conn, "%s: execle(%s): %s", __func__, prog, strerror(ERRNO));
- } else {
- (void) execle(interp, interp, prog, NULL, envp);
- mg_cry(conn, "%s: execle(%s %s): %s", __func__, interp, prog,
- strerror(ERRNO));
- }
- }
- exit(EXIT_FAILURE);
- }
-
- return pid;
-}
-#endif /* !NO_CGI */
-
-static int set_non_blocking_mode(SOCKET sock)
-{
- int flags;
-
- flags = fcntl(sock, F_GETFL, 0);
- (void) fcntl(sock, F_SETFL, flags | O_NONBLOCK);
-
- return 0;
-}
-#endif /* _WIN32 */
-
-/* Write data to the IO channel - opened file descriptor, socket or SSL
- descriptor. Return number of bytes written. */
-static int64_t push(FILE *fp, SOCKET sock, SSL *ssl, const char *buf, int64_t len)
-{
- int64_t sent;
- int n, k;
-
- (void) ssl; /* Get rid of warning */
- sent = 0;
- while (sent < len) {
-
- /* How many bytes we send in this iteration */
- k = len - sent > INT_MAX ? INT_MAX : (int) (len - sent);
-
-#ifndef NO_SSL
- if (ssl != NULL) {
- n = SSL_write(ssl, buf + sent, k);
- } else
-#endif
- if (fp != NULL) {
- n = (int) fwrite(buf + sent, 1, (size_t) k, fp);
- if (ferror(fp))
- n = -1;
- } else {
- n = send(sock, buf + sent, (size_t) k, MSG_NOSIGNAL);
- }
-
- if (n <= 0)
- break;
-
- sent += n;
- }
-
- return sent;
-}
-
-/* Read from IO channel - opened file descriptor, socket, or SSL descriptor.
- Return negative value on error, or number of bytes read on success. */
-static int pull(FILE *fp, struct mg_connection *conn, char *buf, int len)
-{
- int nread;
-
- if (fp != NULL) {
- /* Use read() instead of fread(), because if we're reading from the
- CGI pipe, fread() may block until IO buffer is filled up. We cannot
- afford to block and must pass all read bytes immediately to the
- client. */
- nread = read(fileno(fp), buf, (size_t) len);
-#ifndef NO_SSL
- } else if (conn->ssl != NULL) {
- nread = SSL_read(conn->ssl, buf, len);
-#endif
- } else {
- nread = recv(conn->client.sock, buf, (size_t) len, 0);
- }
-
- return conn->ctx->stop_flag ? -1 : nread;
-}
-
-static int pull_all(FILE *fp, struct mg_connection *conn, char *buf, int len)
-{
- int n, nread = 0;
-
- while (len > 0 && conn->ctx->stop_flag == 0) {
- n = pull(fp, conn, buf + nread, len);
- if (n < 0) {
- nread = n; /* Propagate the error */
- break;
- } else if (n == 0) {
- break; /* No more data to read */
- } else {
- conn->consumed_content += n;
- nread += n;
- len -= n;
- }
- }
-
- return nread;
-}
-
-int mg_read(struct mg_connection *conn, void *buf, size_t len)
-{
- int64_t n, buffered_len, nread;
- int64_t len64 = (int64_t)(len > INT_MAX ? INT_MAX : len); /* since the return value is int, we may not read more bytes */
- const char *body;
-
- /* If Content-Length is not set for a PUT or POST request, read until socket is closed */
- if (conn->consumed_content == 0 && conn->content_len == -1) {
- conn->content_len = INT64_MAX;
- conn->must_close = 1;
- }
-
- nread = 0;
- if (conn->consumed_content < conn->content_len) {
- /* Adjust number of bytes to read. */
- int64_t left_to_read = conn->content_len - conn->consumed_content;
- if (left_to_read < len64) {
- /* Do not reade more than the total content length of the request. */
- len64 = left_to_read;
- }
-
- /* Return buffered data */
- buffered_len = (int64_t)(conn->data_len) - (int64_t)conn->request_len - conn->consumed_content;
- if (buffered_len > 0) {
- if (len64 < buffered_len) {
- buffered_len = len64;
- }
- body = conn->buf + conn->request_len + conn->consumed_content;
- memcpy(buf, body, (size_t) buffered_len);
- len64 -= buffered_len;
- conn->consumed_content += buffered_len;
- nread += buffered_len;
- buf = (char *) buf + buffered_len;
- }
-
- /* We have returned all buffered data. Read new data from the remote
- socket. */
- if ((n = pull_all(NULL, conn, (char *) buf, (int)len64)) >= 0) {
- nread += n;
- } else {
- nread = (nread > 0 ? nread : n);
- }
- }
- return (int)nread;
-}
-
-int mg_write(struct mg_connection *conn, const void *buf, size_t len)
-{
- time_t now;
- int64_t n, total, allowed;
-
- if (conn->throttle > 0) {
- if ((now = time(NULL)) != conn->last_throttle_time) {
- conn->last_throttle_time = now;
- conn->last_throttle_bytes = 0;
- }
- allowed = conn->throttle - conn->last_throttle_bytes;
- if (allowed > (int64_t) len) {
- allowed = len;
- }
- if ((total = push(NULL, conn->client.sock, conn->ssl, (const char *) buf,
- (int64_t) allowed)) == allowed) {
- buf = (char *) buf + total;
- conn->last_throttle_bytes += total;
- while (total < (int64_t) len && conn->ctx->stop_flag == 0) {
- allowed = conn->throttle > (int64_t) len - total ?
- (int64_t) len - total : conn->throttle;
- if ((n = push(NULL, conn->client.sock, conn->ssl, (const char *) buf,
- (int64_t) allowed)) != allowed) {
- break;
- }
- sleep(1);
- conn->last_throttle_bytes = allowed;
- conn->last_throttle_time = time(NULL);
- buf = (char *) buf + n;
- total += n;
- }
- }
- } else {
- total = push(NULL, conn->client.sock, conn->ssl, (const char *) buf,
- (int64_t) len);
- }
- return (int) total;
-}
-
-/* Alternative alloc_vprintf() for non-compliant C runtimes */
-static int alloc_vprintf2(char **buf, const char *fmt, va_list ap)
-{
- va_list ap_copy;
- int size = MG_BUF_LEN;
- int len = -1;
-
- *buf = NULL;
- while (len == -1) {
- if (*buf) mg_free(*buf);
- *buf = (char *)mg_malloc(size *= 4);
- if (!*buf) break;
- va_copy(ap_copy, ap);
- len = vsnprintf(*buf, size, fmt, ap_copy);
- va_end(ap_copy);
- }
-
- return len;
-}
-
-/* Print message to buffer. If buffer is large enough to hold the message,
- return buffer. If buffer is to small, allocate large enough buffer on heap,
- and return allocated buffer. */
-static int alloc_vprintf(char **buf, size_t size, const char *fmt, va_list ap)
-{
- va_list ap_copy;
- int len;
-
- /* Windows is not standard-compliant, and vsnprintf() returns -1 if
- buffer is too small. Also, older versions of msvcrt.dll do not have
- _vscprintf(). However, if size is 0, vsnprintf() behaves correctly.
- Therefore, we make two passes: on first pass, get required message
- length.
- On second pass, actually print the message. */
- va_copy(ap_copy, ap);
- len = vsnprintf(NULL, 0, fmt, ap_copy);
- va_end(ap_copy);
-
- if (len < 0) {
- /* C runtime is not standard compliant, vsnprintf() returned -1.
- Switch to alternative code path that uses incremental allocations.
- */
- va_copy(ap_copy, ap);
- len = alloc_vprintf2(buf, fmt, ap);
- va_end(ap_copy);
- } else if (len > (int) size &&
- (size = len + 1) > 0 &&
- (*buf = (char *) mg_malloc(size)) == NULL) {
- len = -1; /* Allocation failed, mark failure */
- } else {
- va_copy(ap_copy, ap);
- IGNORE_UNUSED_RESULT(vsnprintf(*buf, size, fmt, ap_copy));
- va_end(ap_copy);
- }
-
- return len;
-}
-
-int mg_vprintf(struct mg_connection *conn, const char *fmt, va_list ap)
-{
- char mem[MG_BUF_LEN], *buf = mem;
- int len;
-
- if ((len = alloc_vprintf(&buf, sizeof(mem), fmt, ap)) > 0) {
- len = mg_write(conn, buf, (size_t) len);
- }
- if (buf != mem && buf != NULL) {
- mg_free(buf);
- }
-
- return len;
-}
-
-int mg_printf(struct mg_connection *conn, const char *fmt, ...)
-{
- va_list ap;
- int result;
-
- va_start(ap, fmt);
- result = mg_vprintf(conn, fmt, ap);
- va_end(ap);
-
- return result;
-}
-
-int mg_url_decode(const char *src, int src_len, char *dst,
- int dst_len, int is_form_url_encoded)
-{
- int i, j, a, b;
-#define HEXTOI(x) (isdigit(x) ? x - '0' : x - 'W')
-
- for (i = j = 0; i < src_len && j < dst_len - 1; i++, j++) {
- if (i < src_len - 2 && src[i] == '%' &&
- isxdigit(* (const unsigned char *) (src + i + 1)) &&
- isxdigit(* (const unsigned char *) (src + i + 2))) {
- a = tolower(* (const unsigned char *) (src + i + 1));
- b = tolower(* (const unsigned char *) (src + i + 2));
- dst[j] = (char) ((HEXTOI(a) << 4) | HEXTOI(b));
- i += 2;
- } else if (is_form_url_encoded && src[i] == '+') {
- dst[j] = ' ';
- } else {
- dst[j] = src[i];
- }
- }
-
- dst[j] = '\0'; /* Null-terminate the destination */
-
- return i >= src_len ? j : -1;
-}
-
-int mg_get_var(const char *data, size_t data_len, const char *name,
- char *dst, size_t dst_len)
-{
- return mg_get_var2(data,data_len,name,dst,dst_len,0);
-}
-
-int mg_get_var2(const char *data, size_t data_len, const char *name,
- char *dst, size_t dst_len, size_t occurrence)
-{
- const char *p, *e, *s;
- size_t name_len;
- int len;
-
- if (dst == NULL || dst_len == 0) {
- len = -2;
- } else if (data == NULL || name == NULL || data_len == 0) {
- len = -1;
- dst[0] = '\0';
- } else {
- name_len = strlen(name);
- e = data + data_len;
- len = -1;
- dst[0] = '\0';
-
- /* data is "var1=val1&var2=val2...". Find variable first */
- for (p = data; p + name_len < e; p++) {
- if ((p == data || p[-1] == '&') && p[name_len] == '=' &&
- !mg_strncasecmp(name, p, name_len) && 0 == occurrence--) {
-
- /* Point p to variable value */
- p += name_len + 1;
-
- /* Point s to the end of the value */
- s = (const char *) memchr(p, '&', (size_t)(e - p));
- if (s == NULL) {
- s = e;
- }
- assert(s >= p);
-
- /* Decode variable into destination buffer */
- len = mg_url_decode(p, (int)(s - p), dst, (int)dst_len, 1);
-
- /* Redirect error code from -1 to -2 (destination buffer too
- small). */
- if (len == -1) {
- len = -2;
- }
- break;
- }
- }
- }
-
- return len;
-}
-
-int mg_get_cookie(const char *cookie_header, const char *var_name,
- char *dst, size_t dst_size)
-{
- const char *s, *p, *end;
- int name_len, len = -1;
-
- if (dst == NULL || dst_size == 0) {
- len = -2;
- } else if (var_name == NULL || (s = cookie_header) == NULL) {
- len = -1;
- dst[0] = '\0';
- } else {
- name_len = (int) strlen(var_name);
- end = s + strlen(s);
- dst[0] = '\0';
-
- for (; (s = mg_strcasestr(s, var_name)) != NULL; s += name_len) {
-
<TRUNCATED>
[11/19] celix git commit: CELIX-417: Refactor for CMake usage in RSA,
PSA and Docker. mostly trying to identify the api and common libraries
Posted by pn...@apache.org.
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/discovery_common/src/desc.xml
----------------------------------------------------------------------
diff --git a/remote_services/discovery_common/src/desc.xml b/remote_services/discovery_common/src/desc.xml
new file mode 100644
index 0000000..5998992
--- /dev/null
+++ b/remote_services/discovery_common/src/desc.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ *Licensed to the Apache Software Foundation (ASF) under one
+ *or more contributor license agreements. See the NOTICE file
+ *distributed with this work for additional information
+ *regarding copyright ownership. The ASF licenses this file
+ *to you under the Apache License, Version 2.0 (the
+ *"License"); you may not use this file except in compliance
+ *with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *Unless required by applicable law or agreed to in writing,
+ *software distributed under the License is distributed on an
+ *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *specific language governing permissions and limitations
+ *under the License.
+ -->
+<endpoint-descriptions xmlns="http://www.osgi.org/xmlns/rsa/v1.0.0">
+ <endpoint-description>
+ <property name="service.intents">
+ <list>
+ <value>SOAP</value>
+ <value>HTTP</value>
+ </list>
+ </property>
+ <property name="endpoint.id" value="http://ws.acme.com:9000/hello" />
+ <property name="objectClass" value="com.acme.Foo" />
+ <property name="endpoint.package.version.com.acme" value="4.2" />
+ <property name="service.imported.configs" value="com.acme" />
+ <property name="com.acme.ws.xml">
+ <xml>
+ <config xmlns="http://acme.com/defs">
+ <port>1029</port>
+ <host>www.acme.com</host>
+ </config>
+ </xml>
+ </property>
+ </endpoint-description>
+</endpoint-descriptions>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/discovery_common/src/discovery.c
----------------------------------------------------------------------
diff --git a/remote_services/discovery_common/src/discovery.c b/remote_services/discovery_common/src/discovery.c
new file mode 100644
index 0000000..d124c15
--- /dev/null
+++ b/remote_services/discovery_common/src/discovery.c
@@ -0,0 +1,234 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+/*
+ * discovery.c
+ *
+ * \date Aug 8, 2014
+ * \author <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ * \copyright Apache License, Version 2.0
+ */
+#include <stdio.h>
+#include <stdbool.h>
+#include <netdb.h>
+#include <string.h>
+
+#include "celix_threads.h"
+#include "bundle_context.h"
+#include "log_helper.h"
+#include "discovery.h"
+#include "endpoint_discovery_server.h"
+#include "discovery_impl.h" //TODO rename impl
+
+
+celix_status_t discovery_endpointAdded(void *handle, endpoint_description_pt endpoint, char *matchedFilter) {
+ celix_status_t status;
+ discovery_pt discovery = handle;
+
+ logHelper_log(discovery->loghelper, OSGI_LOGSERVICE_INFO, "Endpoint for %s, with filter \"%s\" added...", endpoint->service, matchedFilter);
+
+ status = endpointDiscoveryServer_addEndpoint(discovery->server, endpoint);
+
+ return status;
+}
+
+celix_status_t discovery_endpointRemoved(void *handle, endpoint_description_pt endpoint, char *matchedFilter) {
+ celix_status_t status;
+ discovery_pt discovery = handle;
+
+ logHelper_log(discovery->loghelper, OSGI_LOGSERVICE_INFO, "Endpoint for %s, with filter \"%s\" removed...", endpoint->service, matchedFilter);
+
+ status = endpointDiscoveryServer_removeEndpoint(discovery->server, endpoint);
+
+ return status;
+}
+
+celix_status_t discovery_endpointListenerAdding(void* handle, service_reference_pt reference, void** service) {
+ celix_status_t status = CELIX_SUCCESS;
+ discovery_pt discovery = handle;
+
+ bundleContext_getService(discovery->context, reference, service);
+
+ return status;
+}
+
+celix_status_t discovery_endpointListenerAdded(void* handle, service_reference_pt reference, void* service) {
+ celix_status_t status = CELIX_SUCCESS;
+ discovery_pt discovery = handle;
+
+ const char *discoveryListener = NULL;
+ serviceReference_getProperty(reference, "DISCOVERY", &discoveryListener);
+ const char *scope = NULL;
+ serviceReference_getProperty(reference, OSGI_ENDPOINT_LISTENER_SCOPE, &scope);
+
+ filter_pt filter = filter_create(scope);
+
+ if (discoveryListener != NULL && strcmp(discoveryListener, "true") == 0) {
+ logHelper_log(discovery->loghelper, OSGI_LOGSERVICE_INFO, "EndpointListener Ignored - Discovery listener");
+ } else {
+ celixThreadMutex_lock(&discovery->discoveredServicesMutex);
+
+ hash_map_iterator_pt iter = hashMapIterator_create(discovery->discoveredServices);
+ while (hashMapIterator_hasNext(iter)) {
+ endpoint_description_pt endpoint = hashMapIterator_nextValue(iter);
+
+ bool matchResult = false;
+ filter_match(filter, endpoint->properties, &matchResult);
+ if (matchResult) {
+ endpoint_listener_pt listener = service;
+
+ logHelper_log(discovery->loghelper, OSGI_LOGSERVICE_INFO, "EndpointListener Added - Add Scope");
+
+ listener->endpointAdded(listener->handle, endpoint, NULL);
+ }
+ }
+ hashMapIterator_destroy(iter);
+
+ celixThreadMutex_unlock(&discovery->discoveredServicesMutex);
+
+ celixThreadMutex_lock(&discovery->listenerReferencesMutex);
+
+ hashMap_put(discovery->listenerReferences, reference, NULL);
+
+ celixThreadMutex_unlock(&discovery->listenerReferencesMutex);
+ }
+
+ filter_destroy(filter);
+
+ return status;
+}
+
+celix_status_t discovery_endpointListenerModified(void * handle, service_reference_pt reference, void * service) {
+ celix_status_t status;
+
+ status = discovery_endpointListenerRemoved(handle, reference, service);
+ if (status == CELIX_SUCCESS) {
+ status = discovery_endpointListenerAdded(handle, reference, service);
+ }
+
+ return status;
+}
+
+celix_status_t discovery_endpointListenerRemoved(void * handle, service_reference_pt reference, void * service) {
+ celix_status_t status;
+ discovery_pt discovery = handle;
+
+ status = celixThreadMutex_lock(&discovery->listenerReferencesMutex);
+
+ if (status == CELIX_SUCCESS) {
+ if (discovery->listenerReferences != NULL) {
+ if (hashMap_remove(discovery->listenerReferences, reference)) {
+ logHelper_log(discovery->loghelper, OSGI_LOGSERVICE_INFO, "EndpointListener Removed");
+ }
+ }
+
+ status = celixThreadMutex_unlock(&discovery->listenerReferencesMutex);
+ }
+
+ return status;
+}
+
+celix_status_t discovery_informEndpointListeners(discovery_pt discovery, endpoint_description_pt endpoint, bool endpointAdded) {
+ celix_status_t status;
+
+ // Inform listeners of new endpoint
+ status = celixThreadMutex_lock(&discovery->listenerReferencesMutex);
+
+ if (status == CELIX_SUCCESS) {
+ if (discovery->listenerReferences != NULL) {
+ hash_map_iterator_pt iter = hashMapIterator_create(discovery->listenerReferences);
+ while (hashMapIterator_hasNext(iter)) {
+ hash_map_entry_pt entry = hashMapIterator_nextEntry(iter);
+
+ service_reference_pt reference = hashMapEntry_getKey(entry);
+ endpoint_listener_pt listener = NULL;
+
+ const char* scope = NULL;
+ serviceReference_getProperty(reference, OSGI_ENDPOINT_LISTENER_SCOPE, &scope);
+
+ filter_pt filter = filter_create(scope);
+ bool matchResult = false;
+
+ status = filter_match(filter, endpoint->properties, &matchResult);
+ if (status == CELIX_SUCCESS) {
+ if (matchResult) {
+ bundleContext_getService(discovery->context, reference, (void **) &listener);
+ if (endpointAdded) {
+ logHelper_log(discovery->loghelper, OSGI_LOGSERVICE_INFO, "Adding service (%s)", endpoint->service);
+
+ listener->endpointAdded(listener->handle, endpoint, (char*)scope);
+ } else {
+ logHelper_log(discovery->loghelper, OSGI_LOGSERVICE_INFO, "Removing service (%s)", endpoint->service);
+
+ listener->endpointRemoved(listener->handle, endpoint, (char*)scope);
+ }
+ }
+
+ filter_destroy(filter);
+ }
+ }
+ hashMapIterator_destroy(iter);
+ }
+
+ status = celixThreadMutex_unlock(&discovery->listenerReferencesMutex);
+ }
+
+ return status;
+}
+
+celix_status_t discovery_addDiscoveredEndpoint(discovery_pt discovery, endpoint_description_pt endpoint) {
+ celix_status_t status;
+
+ status = celixThreadMutex_lock(&discovery->discoveredServicesMutex);
+
+ if (status == CELIX_SUCCESS) {
+ char *endpointId = endpoint->id;
+ bool exists = hashMap_get(discovery->discoveredServices, endpointId) != NULL;
+ if (!exists) {
+ hashMap_put(discovery->discoveredServices, endpointId, endpoint);
+ }
+
+ status = celixThreadMutex_unlock(&discovery->discoveredServicesMutex);
+
+ if (!exists) {
+ // notify our listeners that a new endpoint is available...
+ discovery_informEndpointListeners(discovery, endpoint, true /* addingService */);
+ }
+ }
+
+ return status;
+}
+
+celix_status_t discovery_removeDiscoveredEndpoint(discovery_pt discovery, endpoint_description_pt endpoint) {
+ celix_status_t status;
+
+ status = celixThreadMutex_lock(&discovery->discoveredServicesMutex);
+
+ if (status == CELIX_SUCCESS) {
+ char *endpointId = endpoint->id;
+ void *oldValue = hashMap_remove(discovery->discoveredServices, endpointId);
+
+ status = celixThreadMutex_unlock(&discovery->discoveredServicesMutex);
+
+ if (oldValue) {
+ status = discovery_informEndpointListeners(discovery, endpoint, false /* removeService */);
+ }
+ }
+
+ return status;
+}
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/discovery_common/src/discovery_activator.c
----------------------------------------------------------------------
diff --git a/remote_services/discovery_common/src/discovery_activator.c b/remote_services/discovery_common/src/discovery_activator.c
new file mode 100644
index 0000000..3267d25
--- /dev/null
+++ b/remote_services/discovery_common/src/discovery_activator.c
@@ -0,0 +1,186 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+/*
+ * discovery_activator.c
+ *
+ * \date Aug 8, 2014
+ * \author <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ * \copyright Apache License, Version 2.0
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+
+#include "bundle_activator.h"
+#include "service_tracker.h"
+#include "constants.h"
+
+#include "log_helper.h"
+#include "discovery.h"
+#include "remote_constants.h"
+
+struct activator {
+ bundle_context_pt context;
+ discovery_pt discovery;
+ log_helper_pt loghelper;
+
+ service_tracker_pt endpointListenerTracker;
+ endpoint_listener_pt endpointListener;
+ service_registration_pt endpointListenerService;
+};
+
+celix_status_t bundleActivator_createEPLTracker(struct activator *activator, service_tracker_pt *tracker) {
+ celix_status_t status;
+
+ service_tracker_customizer_pt customizer = NULL;
+
+ status = serviceTrackerCustomizer_create(activator->discovery, discovery_endpointListenerAdding, discovery_endpointListenerAdded, discovery_endpointListenerModified,
+ discovery_endpointListenerRemoved, &customizer);
+
+ if (status == CELIX_SUCCESS) {
+ status = serviceTracker_create(activator->context, (char *) OSGI_ENDPOINT_LISTENER_SERVICE, customizer, tracker);
+ }
+
+ return status;
+}
+
+celix_status_t bundleActivator_create(bundle_context_pt context, void **userData) {
+ celix_status_t status;
+
+ struct activator* activator = calloc(1,sizeof(struct activator));
+ if (!activator) {
+ return CELIX_ENOMEM;
+ }
+
+ status = discovery_create(context, &activator->discovery);
+ if (status == CELIX_SUCCESS) {
+ activator->context = context;
+
+ logHelper_create(context, &activator->loghelper);
+
+ status = bundleActivator_createEPLTracker(activator, &activator->endpointListenerTracker);
+ if(status==CELIX_SUCCESS){
+ *userData = activator;
+ }
+ else{
+ bundleActivator_destroy(activator,context);
+ }
+ }
+ else{
+ free(activator);
+ }
+
+ return status;
+}
+
+celix_status_t bundleActivator_start(void * userData, bundle_context_pt context) {
+ celix_status_t status;
+ struct activator *activator = userData;
+ const char *uuid = NULL;
+
+ logHelper_start(activator->loghelper);
+
+ status = bundleContext_getProperty(context, OSGI_FRAMEWORK_FRAMEWORK_UUID, &uuid);
+ if (!uuid) {
+ logHelper_log(activator->loghelper, OSGI_LOGSERVICE_DEBUG, "no framework UUID defined?!");
+ return CELIX_ILLEGAL_STATE;
+ }
+
+ size_t len = 11 + strlen(OSGI_FRAMEWORK_OBJECTCLASS) + strlen(OSGI_RSA_ENDPOINT_FRAMEWORK_UUID) + strlen(uuid);
+ char *scope = malloc(len + 1);
+ if (!scope) {
+ return CELIX_ENOMEM;
+ }
+
+ sprintf(scope, "(&(%s=*)(%s=%s))", OSGI_FRAMEWORK_OBJECTCLASS, OSGI_RSA_ENDPOINT_FRAMEWORK_UUID, uuid);
+ scope[len] = 0;
+
+ logHelper_log(activator->loghelper, OSGI_LOGSERVICE_DEBUG, "using scope %s.", scope);
+
+ properties_pt props = properties_create();
+ properties_set(props, "DISCOVERY", "true");
+ properties_set(props, (char *) OSGI_ENDPOINT_LISTENER_SCOPE, scope);
+
+ if (status == CELIX_SUCCESS) {
+ status = serviceTracker_open(activator->endpointListenerTracker);
+ }
+
+ if (status == CELIX_SUCCESS) {
+ status = discovery_start(activator->discovery);
+ }
+
+ if (status == CELIX_SUCCESS) {
+ endpoint_listener_pt endpointListener = calloc(1, sizeof(struct endpoint_listener));
+
+ if (endpointListener) {
+ endpointListener->handle = activator->discovery;
+ endpointListener->endpointAdded = discovery_endpointAdded;
+ endpointListener->endpointRemoved = discovery_endpointRemoved;
+
+ status = bundleContext_registerService(context, (char *) OSGI_ENDPOINT_LISTENER_SERVICE, endpointListener, props, &activator->endpointListenerService);
+
+ if (status == CELIX_SUCCESS) {
+ activator->endpointListener = endpointListener;
+ }
+ }
+ }
+ // We can release the scope, as properties_set makes a copy of the key & value...
+ free(scope);
+
+ return status;
+}
+
+celix_status_t bundleActivator_stop(void * userData, bundle_context_pt context) {
+ celix_status_t status;
+ struct activator *activator = userData;
+
+ status = discovery_stop(activator->discovery);
+
+ status = serviceTracker_close(activator->endpointListenerTracker);
+
+ status = serviceRegistration_unregister(activator->endpointListenerService);
+ free(activator->endpointListener);
+
+ logHelper_stop(activator->loghelper);
+
+ return status;
+}
+
+celix_status_t bundleActivator_destroy(void * userData, bundle_context_pt context) {
+ celix_status_t status;
+ struct activator *activator = userData;
+
+ status = serviceTracker_destroy(activator->endpointListenerTracker);
+
+ status = discovery_destroy(activator->discovery);
+
+ logHelper_destroy(&activator->loghelper);
+
+ activator->loghelper = NULL;
+ activator->endpointListenerTracker = NULL;
+ activator->endpointListenerService = NULL;
+ activator->discovery = NULL;
+ activator->context = NULL;
+
+ free(activator);
+
+ return status;
+}
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/discovery_common/src/endpoint_descriptor_reader.c
----------------------------------------------------------------------
diff --git a/remote_services/discovery_common/src/endpoint_descriptor_reader.c b/remote_services/discovery_common/src/endpoint_descriptor_reader.c
new file mode 100644
index 0000000..ea176bf
--- /dev/null
+++ b/remote_services/discovery_common/src/endpoint_descriptor_reader.c
@@ -0,0 +1,387 @@
+/**
+ *Licensed to the Apache Software Foundation (ASF) under one
+ *or more contributor license agreements. See the NOTICE file
+ *distributed with this work for additional information
+ *regarding copyright ownership. The ASF licenses this file
+ *to you under the Apache License, Version 2.0 (the
+ *"License"); you may not use this file except in compliance
+ *with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *Unless required by applicable law or agreed to in writing,
+ *software distributed under the License is distributed on an
+ *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *specific language governing permissions and limitations
+ *under the License.
+ */
+/*
+ * endpoint_descriptor_reader.c
+ *
+ * \date 24 Jul 2014
+ * \author <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ * \copyright Apache License, Version 2.0
+ */
+
+#include <stdbool.h>
+#include <string.h>
+#include <libxml/xmlreader.h>
+
+#include "log_helper.h"
+#include "remote_constants.h"
+
+#include "endpoint_description.h"
+#include "endpoint_descriptor_common.h"
+#include "endpoint_descriptor_reader.h"
+
+struct endpoint_descriptor_reader {
+ xmlTextReaderPtr reader;
+ log_helper_pt* loghelper;
+};
+
+static valueType valueTypeFromString(char *name);
+
+celix_status_t endpointDescriptorReader_create(endpoint_discovery_poller_pt poller, endpoint_descriptor_reader_pt *reader) {
+ celix_status_t status = CELIX_SUCCESS;
+
+ *reader = malloc(sizeof(**reader));
+ if (!*reader) {
+ status = CELIX_ENOMEM;
+ } else {
+ (*reader)->reader = NULL;
+ (*reader)->loghelper = poller->loghelper;
+ }
+
+ return status;
+}
+
+celix_status_t endpointDescriptorReader_destroy(endpoint_descriptor_reader_pt reader) {
+ celix_status_t status = CELIX_SUCCESS;
+
+ reader->loghelper = NULL;
+
+ free(reader);
+
+ return status;
+}
+
+void endpointDescriptorReader_addSingleValuedProperty(properties_pt properties, const xmlChar* name, const xmlChar* value) {
+ properties_set(properties, (char *) name, (char*) value);
+}
+
+void endpointDescriptorReader_addMultiValuedProperty(properties_pt properties, const xmlChar* name, array_list_pt values) {
+ char *value = calloc(256, sizeof(*value));
+ if (value) {
+ unsigned int size = arrayList_size(values);
+ unsigned int i;
+ for (i = 0; i < size; i++) {
+ char* item = (char*) arrayList_get(values, i);
+ if (i > 0) {
+ value = strcat(value, ",");
+ }
+ value = strcat(value, item);
+ }
+
+ properties_set(properties, (char *) name, value);
+
+ free(value);
+ }
+}
+
+celix_status_t endpointDescriptorReader_parseDocument(endpoint_descriptor_reader_pt reader, char *document, array_list_pt *endpoints) {
+ celix_status_t status = CELIX_SUCCESS;
+
+ reader->reader = xmlReaderForMemory(document, (int) strlen(document), NULL, "UTF-8", 0);
+ if (reader->reader == NULL) {
+ status = CELIX_BUNDLE_EXCEPTION;
+ } else {
+ bool inProperty = false;
+ bool inXml = false;
+ bool inArray = false;
+ bool inList = false;
+ bool inSet = false;
+ bool inValue = false;
+
+ const xmlChar *propertyName = NULL;
+ const xmlChar *propertyValue = NULL;
+ valueType propertyType = VALUE_TYPE_STRING;
+ xmlChar *valueBuffer = xmlMalloc(256);
+ valueBuffer[0] = '\0';
+
+ array_list_pt propertyValues = NULL;
+ arrayList_create(&propertyValues);
+
+ array_list_pt endpointDescriptions = NULL;
+ if (*endpoints) {
+ // use the given arraylist...
+ endpointDescriptions = *endpoints;
+ } else {
+ arrayList_create(&endpointDescriptions);
+ // return the read endpoints...
+ *endpoints = endpointDescriptions;
+ }
+
+ properties_pt endpointProperties = NULL;
+
+ int read = xmlTextReaderRead(reader->reader);
+ while (read == XML_TEXTREADER_MODE_INTERACTIVE) {
+ int type = xmlTextReaderNodeType(reader->reader);
+
+ if (type == XML_READER_TYPE_ELEMENT) {
+ const xmlChar *localname = xmlTextReaderConstLocalName(reader->reader);
+
+ if (inXml) {
+ valueBuffer = xmlStrcat(valueBuffer, BAD_CAST "<");
+ valueBuffer = xmlStrcat(valueBuffer, localname);
+
+ int i = xmlTextReaderMoveToFirstAttribute(reader->reader);
+ while (i == 1) {
+ const xmlChar *name = xmlTextReaderConstName(reader->reader);
+ const xmlChar *value = xmlTextReaderConstValue(reader->reader);
+
+ valueBuffer = xmlStrcat(valueBuffer, BAD_CAST " ");
+ valueBuffer = xmlStrcat(valueBuffer, name);
+ valueBuffer = xmlStrcat(valueBuffer, BAD_CAST "=\"");
+ valueBuffer = xmlStrcat(valueBuffer, BAD_CAST value);
+ valueBuffer = xmlStrcat(valueBuffer, BAD_CAST "\"");
+
+ i = xmlTextReaderMoveToNextAttribute(reader->reader);
+ }
+
+ valueBuffer = xmlStrcat(valueBuffer, BAD_CAST ">");
+ } else if (xmlStrcmp(localname, ENDPOINT_DESCRIPTION) == 0) {
+
+ if (endpointProperties != NULL)
+ properties_destroy(endpointProperties);
+
+ endpointProperties = properties_create();
+ } else if (xmlStrcmp(localname, PROPERTY) == 0) {
+ inProperty = true;
+
+ propertyName = xmlTextReaderGetAttribute(reader->reader, NAME);
+ propertyValue = xmlTextReaderGetAttribute(reader->reader, VALUE);
+ xmlChar *vtype = xmlTextReaderGetAttribute(reader->reader, VALUE_TYPE);
+ propertyType = valueTypeFromString((char*) vtype);
+ arrayList_clear(propertyValues);
+
+ if (xmlTextReaderIsEmptyElement(reader->reader)) {
+ inProperty = false;
+
+ if (propertyValue != NULL) {
+ endpointDescriptorReader_addSingleValuedProperty(endpointProperties, propertyName, propertyValue);
+ }
+
+ xmlFree((void *) propertyName);
+ xmlFree((void *) propertyValue);
+ xmlFree((void *) vtype);
+ }
+ } else {
+ valueBuffer[0] = 0;
+ inArray |= inProperty && xmlStrcmp(localname, ARRAY) == 0;
+ inList |= inProperty && xmlStrcmp(localname, LIST) == 0;
+ inSet |= inProperty && xmlStrcmp(localname, SET) == 0;
+ inXml |= inProperty && xmlStrcmp(localname, XML) == 0;
+ inValue |= inProperty && xmlStrcmp(localname, VALUE) == 0;
+ }
+ } else if (type == XML_READER_TYPE_END_ELEMENT) {
+ const xmlChar *localname = xmlTextReaderConstLocalName(reader->reader);
+
+ if (inXml) {
+ if (xmlStrcmp(localname, XML) != 0) {
+ valueBuffer = xmlStrcat(valueBuffer, BAD_CAST "</");
+ valueBuffer = xmlStrcat(valueBuffer, localname);
+ valueBuffer = xmlStrcat(valueBuffer, BAD_CAST ">");
+ }
+ else {
+ inXml = false;
+ }
+ } else if (xmlStrcmp(localname, ENDPOINT_DESCRIPTION) == 0) {
+ endpoint_description_pt endpointDescription = NULL;
+ // Completely parsed endpoint description, add it to our list of results...
+ if(endpointDescription_create(endpointProperties, &endpointDescription) == CELIX_SUCCESS){
+ arrayList_add(endpointDescriptions, endpointDescription);
+ }
+
+ endpointProperties = properties_create();
+ } else if (xmlStrcmp(localname, PROPERTY) == 0) {
+ inProperty = false;
+
+ if (inArray || inList || inSet) {
+ endpointDescriptorReader_addMultiValuedProperty(endpointProperties, propertyName, propertyValues);
+ }
+ else if (propertyValue != NULL) {
+ if (propertyType != VALUE_TYPE_STRING) {
+ logHelper_log(*reader->loghelper, OSGI_LOGSERVICE_WARNING, "ENDPOINT_DESCRIPTOR_READER: Only string support for %s\n", propertyName);
+ }
+ endpointDescriptorReader_addSingleValuedProperty(endpointProperties, propertyName, propertyValue);
+
+ xmlFree((void *) propertyValue);
+ }
+ else {
+ endpointDescriptorReader_addSingleValuedProperty(endpointProperties, propertyName, valueBuffer);
+ }
+
+ xmlFree((void *) propertyName);
+ unsigned int k=0;
+ for(;k<arrayList_size(propertyValues);k++){
+ free(arrayList_get(propertyValues,k));
+ }
+ arrayList_clear(propertyValues);
+
+ propertyType = VALUE_TYPE_STRING;
+ inArray = false;
+ inList = false;
+ inSet = false;
+ inXml = false;
+ } else if (xmlStrcmp(localname, VALUE) == 0) {
+ arrayList_add(propertyValues, strdup((char*) valueBuffer));
+ valueBuffer[0] = 0;
+ inValue = false;
+ }
+ } else if (type == XML_READER_TYPE_TEXT) {
+ if (inValue || inXml) {
+ const xmlChar *value = xmlTextReaderValue(reader->reader);
+ valueBuffer = xmlStrcat(valueBuffer, value);
+ xmlFree((void *)value);
+ }
+ }
+
+ read = xmlTextReaderRead(reader->reader);
+ }
+
+ if(endpointProperties!=NULL){
+ properties_destroy(endpointProperties);
+ }
+
+ unsigned int k=0;
+ for(;k<arrayList_size(propertyValues);k++){
+ free(arrayList_get(propertyValues,k));
+ }
+ arrayList_destroy(propertyValues);
+ xmlFree(valueBuffer);
+
+ xmlFreeTextReader(reader->reader);
+ }
+
+ return status;
+}
+
+static valueType valueTypeFromString(char *name) {
+ if (name == NULL || strcmp(name, "") == 0 || strcmp(name, "String") == 0) {
+ return VALUE_TYPE_STRING;
+ } else if (strcmp(name, "long") == 0 || strcmp(name, "Long") == 0) {
+ return VALUE_TYPE_LONG;
+ } else if (strcmp(name, "double") == 0 || strcmp(name, "Double") == 0) {
+ return VALUE_TYPE_DOUBLE;
+ } else if (strcmp(name, "float") == 0 || strcmp(name, "Float") == 0) {
+ return VALUE_TYPE_FLOAT;
+ } else if (strcmp(name, "int") == 0 || strcmp(name, "integer") == 0 || strcmp(name, "Integer") == 0) {
+ return VALUE_TYPE_INTEGER;
+ } else if (strcmp(name, "short") == 0 || strcmp(name, "Short") == 0) {
+ return VALUE_TYPE_SHORT;
+ } else if (strcmp(name, "byte") == 0 || strcmp(name, "Byte") == 0) {
+ return VALUE_TYPE_BYTE;
+ } else if (strcmp(name, "char") == 0 || strcmp(name, "Character") == 0) {
+ return VALUE_TYPE_CHAR;
+ } else if (strcmp(name, "boolean") == 0 || strcmp(name, "Boolean") == 0) {
+ return VALUE_TYPE_BOOLEAN;
+ } else {
+ return VALUE_TYPE_STRING;
+ }
+}
+
+#ifdef RSA_ENDPOINT_TEST_READER
+int main() {
+ array_list_pt list = NULL;
+ endpoint_descriptor_reader_pt reader = NULL;
+
+ char *doc = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
+"<endpoint-descriptions xmlns=\"http://www.osgi.org/xmlns/rsa/v1.0.0\">"
+ "<endpoint-description>"
+ "<property name=\"endpoint.service.id\" value-type=\"long\" value=\"6\"/>"
+ "<property name=\"endpoint.framework.uuid\" value=\"2983D849-93B1-4C2C-AC6D-5BCDA93ACB96\"/>"
+ "<property name=\"service.intents\">"
+ "<list>"
+ "<value>SOAP</value>"
+ "<value>HTTP</value>"
+ "</list>"
+ "</property>"
+ "<property name=\"endpoint.id\" value=\"11111111-1111-1111-1111-111111111111\" />"
+ "<property name=\"objectClass\"><array><value>com.acme.Foo</value></array></property>"
+ "<property name=\"endpoint.package.version.com.acme\" value=\"4.2\" />"
+ "<property name=\"service.imported.configs\" value=\"com.acme\" />"
+ "<property name=\"service.imported\" value=\"true\"/>"
+ "<property name=\"com.acme.ws.xml\">"
+ "<xml>"
+ "<config xmlns=\"http://acme.com/defs\">"
+ "<port>1029</port>"
+ "<host>www.acme.com</host>"
+ "</config>"
+ "</xml>"
+ "</property>"
+ "</endpoint-description>"
+ "<endpoint-description>"
+ "<property name=\"endpoint.service.id\" value-type=\"long\" value=\"5\"/>"
+ "<property name=\"endpoint.framework.uuid\" value=\"2983D849-93B1-4C2C-AC6D-5BCDA93ACB96\"/>"
+ "<property name=\"service.intents\">"
+ "<list>"
+ "<value>SOAP</value>"
+ "<value>HTTP</value>"
+ "</list>"
+ "</property>"
+ "<property name=\"endpoint.id\" value=\"22222222-2222-2222-2222-222222222222\" />"
+ "<property name=\"objectClass\"><array><value>com.acme.Bar</value></array></property>"
+ "<property name=\"endpoint.package.version.com.acme\" value=\"4.2\" />"
+ "<property name=\"service.imported.configs\" value=\"com.acme\" />"
+ "<property name=\"com.acme.ws.xml\">"
+ "<xml>"
+ "<config xmlns=\"http://acme.com/defs\">"
+ "<port>1029</port>"
+ "<host>www.acme.com</host>"
+ "</config>"
+ "</xml>"
+ "</property>"
+ "</endpoint-description>"
+ "</endpoint-descriptions>";
+
+ endpointDescriptorReader_create(&reader);
+
+ endpointDescriptorReader_parseDocument(reader, doc, &list);
+
+ int i;
+ for (i = 0; i < arrayList_size(list); i++) {
+ printf("\nEndpoint description #%d:\n", (i+1));
+ endpoint_description_pt edp = arrayList_get(list, i);
+ printf("Id: %s\n", edp->id);
+ printf("Service Id: %lu\n", edp->serviceId);
+ printf("Framework UUID: %s\n", edp->frameworkUUID);
+ printf("Service: %s\n", edp->service);
+
+ properties_pt props = edp->properties;
+ if (props) {
+ printf("Service properties:\n");
+ hash_map_iterator_pt iter = hashMapIterator_create(props);
+ while (hashMapIterator_hasNext(iter)) {
+ hash_map_entry_pt entry = hashMapIterator_nextEntry(iter);
+
+ printf("- %s => '%s'\n", hashMapEntry_getKey(entry), hashMapEntry_getValue(entry));
+ }
+ hashMapIterator_destroy(iter);
+ } else {
+ printf("No service properties...\n");
+ }
+
+
+ endpointDescription_destroy(edp);
+ }
+
+ if (list != NULL) {
+ arrayList_destroy(list);
+ }
+
+ endpointDescriptorReader_destroy(reader);
+
+ return 0;
+}
+#endif
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/discovery_common/src/endpoint_descriptor_writer.c
----------------------------------------------------------------------
diff --git a/remote_services/discovery_common/src/endpoint_descriptor_writer.c b/remote_services/discovery_common/src/endpoint_descriptor_writer.c
new file mode 100644
index 0000000..71b07b4
--- /dev/null
+++ b/remote_services/discovery_common/src/endpoint_descriptor_writer.c
@@ -0,0 +1,233 @@
+/**
+ *Licensed to the Apache Software Foundation (ASF) under one
+ *or more contributor license agreements. See the NOTICE file
+ *distributed with this work for additional information
+ *regarding copyright ownership. The ASF licenses this file
+ *to you under the Apache License, Version 2.0 (the
+ *"License"); you may not use this file except in compliance
+ *with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *Unless required by applicable law or agreed to in writing,
+ *software distributed under the License is distributed on an
+ *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *specific language governing permissions and limitations
+ *under the License.
+ */
+/*
+ * endpoint_descriptor_writer.c
+ *
+ * \date 26 Jul 2014
+ * \author <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ * \copyright Apache License, Version 2.0
+ */
+#include <stdlib.h>
+#include <string.h>
+#include <libxml/xmlwriter.h>
+
+#include "constants.h"
+#include "remote_constants.h"
+
+#include "endpoint_description.h"
+#include "endpoint_descriptor_common.h"
+#include "endpoint_descriptor_writer.h"
+
+struct endpoint_descriptor_writer {
+ xmlBufferPtr buffer;
+ xmlTextWriterPtr writer;
+};
+
+static celix_status_t endpointDescriptorWriter_writeEndpoint(endpoint_descriptor_writer_pt writer, endpoint_description_pt endpoint);
+
+static char* valueTypeToString(valueType type);
+
+celix_status_t endpointDescriptorWriter_create(endpoint_descriptor_writer_pt *writer) {
+ celix_status_t status = CELIX_SUCCESS;
+
+ *writer = malloc(sizeof(**writer));
+ if (!*writer) {
+ status = CELIX_ENOMEM;
+ } else {
+ (*writer)->buffer = xmlBufferCreate();
+ if ((*writer)->buffer == NULL) {
+ status = CELIX_BUNDLE_EXCEPTION;
+ } else {
+ (*writer)->writer = xmlNewTextWriterMemory((*writer)->buffer, 0);
+ if ((*writer)->writer == NULL) {
+ status = CELIX_BUNDLE_EXCEPTION;
+ }
+ }
+ }
+
+ return status;
+}
+
+celix_status_t endpointDescriptorWriter_destroy(endpoint_descriptor_writer_pt writer) {
+ xmlFreeTextWriter(writer->writer);
+ xmlBufferFree(writer->buffer);
+ free(writer);
+ return CELIX_SUCCESS;
+}
+
+celix_status_t endpointDescriptorWriter_writeDocument(endpoint_descriptor_writer_pt writer, array_list_pt endpoints, char **document) {
+ celix_status_t status = CELIX_SUCCESS;
+ int rc;
+
+ rc = xmlTextWriterStartDocument(writer->writer, NULL, "UTF-8", NULL);
+ if (rc < 0) {
+ status = CELIX_BUNDLE_EXCEPTION;
+ } else {
+ rc = xmlTextWriterStartElementNS(writer->writer, NULL, ENDPOINT_DESCRIPTIONS, XMLNS);
+ if (rc < 0) {
+ status = CELIX_BUNDLE_EXCEPTION;
+ } else {
+ unsigned int i;
+ for (i = 0; i < arrayList_size(endpoints); i++) {
+ endpoint_description_pt endpoint = arrayList_get(endpoints, i);
+ status = endpointDescriptorWriter_writeEndpoint(writer, endpoint);
+ }
+ if (status == CELIX_SUCCESS) {
+ rc = xmlTextWriterEndElement(writer->writer);
+ if (rc < 0) {
+ status = CELIX_BUNDLE_EXCEPTION;
+ } else {
+ rc = xmlTextWriterEndDocument(writer->writer);
+ if (rc < 0) {
+ status = CELIX_BUNDLE_EXCEPTION;
+ } else {
+ *document = (char *) writer->buffer->content;
+ }
+ }
+ }
+ }
+ }
+
+ return status;
+}
+
+static celix_status_t endpointDescriptorWriter_writeArrayValue(xmlTextWriterPtr writer, const xmlChar* value) {
+ xmlTextWriterStartElement(writer, ARRAY);
+ xmlTextWriterStartElement(writer, VALUE);
+ xmlTextWriterWriteString(writer, value);
+ xmlTextWriterEndElement(writer); // value
+ xmlTextWriterEndElement(writer); // array
+
+ return CELIX_SUCCESS;
+}
+
+static celix_status_t endpointDescriptorWriter_writeTypedValue(xmlTextWriterPtr writer, valueType type, const xmlChar* value) {
+ xmlTextWriterWriteAttribute(writer, VALUE_TYPE, (const xmlChar*) valueTypeToString(type));
+ xmlTextWriterWriteAttribute(writer, VALUE, value);
+
+ return CELIX_SUCCESS;
+}
+
+static celix_status_t endpointDescriptorWriter_writeUntypedValue(xmlTextWriterPtr writer, const xmlChar* value) {
+ xmlTextWriterWriteAttribute(writer, VALUE, value);
+
+ return CELIX_SUCCESS;
+}
+
+static celix_status_t endpointDescriptorWriter_writeEndpoint(endpoint_descriptor_writer_pt writer, endpoint_description_pt endpoint) {
+ celix_status_t status = CELIX_SUCCESS;
+
+ if (endpoint == NULL || writer == NULL) {
+ status = CELIX_ILLEGAL_ARGUMENT;
+ } else {
+ xmlTextWriterStartElement(writer->writer, ENDPOINT_DESCRIPTION);
+
+ hash_map_iterator_pt iter = hashMapIterator_create(endpoint->properties);
+ while (hashMapIterator_hasNext(iter)) {
+ hash_map_entry_pt entry = hashMapIterator_nextEntry(iter);
+
+ void* propertyName = hashMapEntry_getKey(entry);
+ const xmlChar* propertyValue = (const xmlChar*) hashMapEntry_getValue(entry);
+
+ xmlTextWriterStartElement(writer->writer, PROPERTY);
+ xmlTextWriterWriteAttribute(writer->writer, NAME, propertyName);
+
+ if (strcmp(OSGI_FRAMEWORK_OBJECTCLASS, (char*) propertyName) == 0) {
+ // objectClass *must* be represented as array of string values...
+ endpointDescriptorWriter_writeArrayValue(writer->writer, propertyValue);
+ } else if (strcmp(OSGI_RSA_ENDPOINT_SERVICE_ID, (char*) propertyName) == 0) {
+ // endpoint.service.id *must* be represented as long value...
+ endpointDescriptorWriter_writeTypedValue(writer->writer, VALUE_TYPE_LONG, propertyValue);
+ } else {
+ // represent all other values as plain string values...
+ endpointDescriptorWriter_writeUntypedValue(writer->writer, propertyValue);
+ }
+
+ xmlTextWriterEndElement(writer->writer);
+ }
+ hashMapIterator_destroy(iter);
+
+ xmlTextWriterEndElement(writer->writer);
+ }
+
+ return status;
+}
+
+
+static char* valueTypeToString(valueType type) {
+ switch (type) {
+ case VALUE_TYPE_BOOLEAN:
+ return "boolean";
+ case VALUE_TYPE_BYTE:
+ return "byte";
+ case VALUE_TYPE_CHAR:
+ return "char";
+ case VALUE_TYPE_DOUBLE:
+ return "double";
+ case VALUE_TYPE_FLOAT:
+ return "float";
+ case VALUE_TYPE_INTEGER:
+ return "int";
+ case VALUE_TYPE_LONG:
+ return "long";
+ case VALUE_TYPE_SHORT:
+ return "short";
+ case VALUE_TYPE_STRING:
+ // FALL-THROUGH!
+ default:
+ return "string";
+ }
+}
+
+#ifdef RSA_ENDPOINT_TEST_WRITER
+int main() {
+ endpoint_descriptor_writer_pt writer = NULL;
+ endpointDescriptorWriter_create(&writer);
+ array_list_pt list = NULL;
+ arrayList_create(&list);
+
+ properties_pt props = properties_create();
+ properties_set(props, "objectClass", "com.acme.Foo");
+ properties_set(props, "endpoint.service.id", "3");
+ properties_set(props, "endpoint.id", "abcdefghijklmnopqrstuvwxyz");
+ properties_set(props, "endpoint.framework.uuid", "2983D849-93B1-4C2C-AC6D-5BCDA93ACB96");
+ endpoint_description_pt epd = NULL;
+ endpointDescription_create(props, &epd);
+ arrayList_add(list, epd);
+
+ properties_pt props2 = properties_create();
+ properties_set(props2, "objectClass", "com.acme.Bar");
+ properties_set(props, "endpoint.service.id", "4");
+ properties_set(props, "endpoint.id", "abcdefghijklmnopqrstuvwxyz");
+ properties_set(props, "endpoint.framework.uuid", "2983D849-93B1-4C2C-AC6D-5BCDA93ACB96");
+ endpoint_description_pt epd2 = NULL;
+ endpointDescription_create(props2, &epd2);
+ arrayList_add(list, epd2);
+
+ char *buffer = NULL;
+ endpointDescriptorWriter_writeDocument(writer, list, &buffer);
+
+ arrayList_destroy(list);
+ endpointDescription_destroy(epd);
+ endpointDescription_destroy(epd2);
+ endpointDescriptorWriter_destroy(writer);
+
+ printf("%s\n", buffer);
+}
+#endif
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/discovery_common/src/endpoint_discovery_poller.c
----------------------------------------------------------------------
diff --git a/remote_services/discovery_common/src/endpoint_discovery_poller.c b/remote_services/discovery_common/src/endpoint_discovery_poller.c
new file mode 100644
index 0000000..73fb7ba
--- /dev/null
+++ b/remote_services/discovery_common/src/endpoint_discovery_poller.c
@@ -0,0 +1,403 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+/*
+ * endpoint_discovery_poller.c
+ *
+ * \date 3 Jul 2014
+ * \author <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ * \copyright Apache License, Version 2.0
+ */
+#include <stdbool.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <curl/curl.h>
+
+#include "bundle_context.h"
+#include "log_helper.h"
+#include "utils.h"
+
+#include "discovery_impl.h"
+
+#include "endpoint_descriptor_reader.h"
+
+
+#define DISCOVERY_POLL_INTERVAL "DISCOVERY_CFG_POLL_INTERVAL"
+#define DEFAULT_POLL_INTERVAL "10"
+
+
+static void *endpointDiscoveryPoller_performPeriodicPoll(void *data);
+celix_status_t endpointDiscoveryPoller_poll(endpoint_discovery_poller_pt poller, char *url, array_list_pt currentEndpoints);
+static celix_status_t endpointDiscoveryPoller_getEndpoints(endpoint_discovery_poller_pt poller, char *url, array_list_pt *updatedEndpoints);
+static celix_status_t endpointDiscoveryPoller_endpointDescriptionEquals(const void *endpointPtr, const void *comparePtr, bool *equals);
+
+/**
+ * Allocates memory and initializes a new endpoint_discovery_poller instance.
+ */
+celix_status_t endpointDiscoveryPoller_create(discovery_pt discovery, bundle_context_pt context, endpoint_discovery_poller_pt *poller) {
+ celix_status_t status;
+
+ *poller = malloc(sizeof(struct endpoint_discovery_poller));
+ if (!*poller) {
+ return CELIX_ENOMEM;
+ }
+
+ (*poller)->loghelper = &discovery->loghelper;
+
+ status = celixThreadMutex_create(&(*poller)->pollerLock, NULL);
+ if (status != CELIX_SUCCESS) {
+ return status;
+ }
+
+ const char* interval = NULL;
+ status = bundleContext_getProperty(context, DISCOVERY_POLL_INTERVAL, &interval);
+ if (!interval) {
+ interval = DEFAULT_POLL_INTERVAL;
+ }
+
+ const char* endpointsProp = NULL;
+ status = bundleContext_getProperty(context, DISCOVERY_POLL_ENDPOINTS, &endpointsProp);
+ if (!endpointsProp) {
+ endpointsProp = DEFAULT_POLL_ENDPOINTS;
+ }
+ // we're going to mutate the string with strtok, so create a copy...
+ char* endpoints = strdup(endpointsProp);
+
+ (*poller)->poll_interval = atoi(interval);
+ (*poller)->discovery = discovery;
+ (*poller)->running = false;
+ (*poller)->entries = hashMap_create(utils_stringHash, NULL, utils_stringEquals, NULL);
+
+ const char* sep = ",";
+ char *save_ptr = NULL;
+ char* tok = strtok_r(endpoints, sep, &save_ptr);
+ while (tok) {
+ endpointDiscoveryPoller_addDiscoveryEndpoint(*poller, utils_stringTrim(tok));
+ tok = strtok_r(NULL, sep, &save_ptr);
+ }
+ // Clean up after ourselves...
+ free(endpoints);
+
+ status = celixThreadMutex_lock(&(*poller)->pollerLock);
+ if (status != CELIX_SUCCESS) {
+ return CELIX_BUNDLE_EXCEPTION;
+ }
+
+ (*poller)->running = true;
+
+ status += celixThread_create(&(*poller)->pollerThread, NULL, endpointDiscoveryPoller_performPeriodicPoll, *poller);
+ status += celixThreadMutex_unlock(&(*poller)->pollerLock);
+
+ if(status != CELIX_SUCCESS){
+ status = CELIX_BUNDLE_EXCEPTION;
+ }
+
+ return status;
+}
+
+/**
+ * Destroys and frees up memory for a given endpoint_discovery_poller struct.
+ */
+celix_status_t endpointDiscoveryPoller_destroy(endpoint_discovery_poller_pt poller) {
+ celix_status_t status;
+
+ poller->running = false;
+
+ celixThread_join(poller->pollerThread, NULL);
+
+ hash_map_iterator_pt iterator = hashMapIterator_create(poller->entries);
+ while (hashMapIterator_hasNext(iterator)) {
+ hash_map_entry_pt entry = hashMapIterator_nextEntry(iterator);
+
+ if ( endpointDiscoveryPoller_removeDiscoveryEndpoint(poller, (char*) hashMapEntry_getKey(entry)) == CELIX_SUCCESS) {
+ hashMapIterator_destroy(iterator);
+ iterator = hashMapIterator_create(poller->entries);
+ }
+ }
+ hashMapIterator_destroy(iterator);
+
+ status = celixThreadMutex_lock(&poller->pollerLock);
+
+ if (status != CELIX_SUCCESS) {
+ return CELIX_BUNDLE_EXCEPTION;
+ }
+
+ hashMap_destroy(poller->entries, true, false);
+
+ status = celixThreadMutex_unlock(&poller->pollerLock);
+
+ poller->loghelper = NULL;
+
+ free(poller);
+
+ return status;
+}
+
+
+celix_status_t endpointDiscoveryPoller_getDiscoveryEndpoints(endpoint_discovery_poller_pt poller, array_list_pt urls) {
+ celixThreadMutex_lock(&(poller)->pollerLock);
+
+ hash_map_iterator_pt iterator = hashMapIterator_create(poller->entries);
+
+ while(hashMapIterator_hasNext(iterator)) {
+ hash_map_entry_pt entry = hashMapIterator_nextEntry(iterator);
+ char* toAdd = strdup((char*) hashMapEntry_getKey(entry));
+ arrayList_add(urls, toAdd);
+ }
+
+ hashMapIterator_destroy(iterator);
+
+ celixThreadMutex_unlock(&(poller)->pollerLock);
+
+ return CELIX_SUCCESS;
+}
+
+/**
+ * Adds a new endpoint URL to the list of polled endpoints.
+ */
+celix_status_t endpointDiscoveryPoller_addDiscoveryEndpoint(endpoint_discovery_poller_pt poller, char *url) {
+ celix_status_t status;
+
+ status = celixThreadMutex_lock(&(poller)->pollerLock);
+ if (status != CELIX_SUCCESS) {
+ return CELIX_BUNDLE_EXCEPTION;
+ }
+
+ // Avoid memory leaks when adding an already existing URL...
+ array_list_pt endpoints = hashMap_get(poller->entries, url);
+ if (endpoints == NULL) {
+ status = arrayList_createWithEquals(endpointDiscoveryPoller_endpointDescriptionEquals, &endpoints);
+
+ if (status == CELIX_SUCCESS) {
+ logHelper_log(*poller->loghelper, OSGI_LOGSERVICE_DEBUG, "ENDPOINT_POLLER: add new discovery endpoint with url %s", url);
+ hashMap_put(poller->entries, strdup(url), endpoints);
+ endpointDiscoveryPoller_poll(poller, url, endpoints);
+ }
+ }
+
+ status = celixThreadMutex_unlock(&poller->pollerLock);
+
+ return status;
+}
+
+/**
+ * Removes an endpoint URL from the list of polled endpoints.
+ */
+celix_status_t endpointDiscoveryPoller_removeDiscoveryEndpoint(endpoint_discovery_poller_pt poller, char *url) {
+ celix_status_t status = CELIX_SUCCESS;
+
+ if (celixThreadMutex_lock(&poller->pollerLock) != CELIX_SUCCESS) {
+ status = CELIX_BUNDLE_EXCEPTION;
+ } else {
+ hash_map_entry_pt entry = hashMap_getEntry(poller->entries, url);
+
+ if (entry == NULL) {
+ logHelper_log(*poller->loghelper, OSGI_LOGSERVICE_DEBUG, "ENDPOINT_POLLER: There was no entry found belonging to url %s - maybe already removed?", url);
+ } else {
+ char* origKey = hashMapEntry_getKey(entry);
+
+ logHelper_log(*poller->loghelper, OSGI_LOGSERVICE_DEBUG, "ENDPOINT_POLLER: remove discovery endpoint with url %s", url);
+
+ array_list_pt entries = hashMap_remove(poller->entries, url);
+
+ if (entries != NULL) {
+ for (unsigned int i = arrayList_size(entries); i > 0; i--) {
+ endpoint_description_pt endpoint = arrayList_get(entries, i - 1);
+ discovery_removeDiscoveredEndpoint(poller->discovery, endpoint);
+ arrayList_remove(entries, i - 1);
+ endpointDescription_destroy(endpoint);
+ }
+ arrayList_destroy(entries);
+ }
+
+ free(origKey);
+ }
+ status = celixThreadMutex_unlock(&poller->pollerLock);
+ }
+
+ return status;
+}
+
+
+
+
+celix_status_t endpointDiscoveryPoller_poll(endpoint_discovery_poller_pt poller, char *url, array_list_pt currentEndpoints) {
+ celix_status_t status;
+ array_list_pt updatedEndpoints = NULL;
+
+ // create an arraylist with a custom equality test to ensure we can find endpoints properly...
+ arrayList_createWithEquals(endpointDiscoveryPoller_endpointDescriptionEquals, &updatedEndpoints);
+ status = endpointDiscoveryPoller_getEndpoints(poller, url, &updatedEndpoints);
+
+ if (status == CELIX_SUCCESS) {
+ if (updatedEndpoints!=NULL) {
+ for (unsigned int i = arrayList_size(currentEndpoints); i > 0; i--) {
+ endpoint_description_pt endpoint = arrayList_get(currentEndpoints, i - 1);
+
+ if (!arrayList_contains(updatedEndpoints, endpoint)) {
+ status = discovery_removeDiscoveredEndpoint(poller->discovery, endpoint);
+ arrayList_remove(currentEndpoints, i - 1);
+ endpointDescription_destroy(endpoint);
+ }
+ }
+
+ for (int i = arrayList_size(updatedEndpoints); i > 0; i--) {
+ endpoint_description_pt endpoint = arrayList_remove(updatedEndpoints, 0);
+
+ if (!arrayList_contains(currentEndpoints, endpoint)) {
+ arrayList_add(currentEndpoints, endpoint);
+ status = discovery_addDiscoveredEndpoint(poller->discovery, endpoint);
+ } else {
+ endpointDescription_destroy(endpoint);
+
+ }
+ }
+ }
+ }
+
+ if(updatedEndpoints!=NULL){
+ arrayList_destroy(updatedEndpoints);
+ }
+
+ return status;
+}
+
+static void *endpointDiscoveryPoller_performPeriodicPoll(void *data) {
+ endpoint_discovery_poller_pt poller = (endpoint_discovery_poller_pt) data;
+
+ useconds_t interval = (useconds_t) (poller->poll_interval * 1000000L);
+
+ while (poller->running) {
+ usleep(interval);
+ celix_status_t status = celixThreadMutex_lock(&poller->pollerLock);
+
+ if (status != CELIX_SUCCESS) {
+ logHelper_log(*poller->loghelper, OSGI_LOGSERVICE_WARNING, "ENDPOINT_POLLER: failed to obtain lock; retrying...");
+ } else {
+ hash_map_iterator_pt iterator = hashMapIterator_create(poller->entries);
+
+ while (hashMapIterator_hasNext(iterator)) {
+ hash_map_entry_pt entry = hashMapIterator_nextEntry(iterator);
+
+ char *url = hashMapEntry_getKey(entry);
+ array_list_pt currentEndpoints = hashMapEntry_getValue(entry);
+
+ endpointDiscoveryPoller_poll(poller, url, currentEndpoints);
+ }
+
+ hashMapIterator_destroy(iterator);
+ }
+
+ status = celixThreadMutex_unlock(&poller->pollerLock);
+ if (status != CELIX_SUCCESS) {
+ logHelper_log(*poller->loghelper, OSGI_LOGSERVICE_WARNING, "ENDPOINT_POLLER: failed to release lock; retrying...");
+ }
+ }
+
+ return NULL;
+}
+
+
+
+struct MemoryStruct {
+ char *memory;
+ size_t size;
+};
+
+static size_t endpointDiscoveryPoller_writeMemory(void *contents, size_t size, size_t nmemb, void *memoryPtr) {
+ size_t realsize = size * nmemb;
+ struct MemoryStruct *mem = (struct MemoryStruct *)memoryPtr;
+
+ mem->memory = realloc(mem->memory, mem->size + realsize + 1);
+ if(mem->memory == NULL) {
+ printf("ENDPOINT_POLLER: not enough memory (realloc returned NULL)!");
+ return 0;
+ }
+
+ memcpy(&(mem->memory[mem->size]), contents, realsize);
+ mem->size += realsize;
+ mem->memory[mem->size] = 0;
+
+ return realsize;
+}
+
+static celix_status_t endpointDiscoveryPoller_getEndpoints(endpoint_discovery_poller_pt poller, char *url, array_list_pt *updatedEndpoints) {
+ celix_status_t status = CELIX_SUCCESS;
+
+
+ CURL *curl = NULL;
+ CURLcode res = CURLE_OK;
+
+ struct MemoryStruct chunk;
+ chunk.memory = malloc(1);
+ chunk.size = 0;
+
+ curl = curl_easy_init();
+ if (!curl) {
+ status = CELIX_ILLEGAL_STATE;
+ } else {
+ curl_easy_setopt(curl, CURLOPT_URL, url);
+ curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1);
+ curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, endpointDiscoveryPoller_writeMemory);
+ curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&chunk);
+ curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 5L);
+ curl_easy_setopt(curl, CURLOPT_TIMEOUT, 10L);
+ res = curl_easy_perform(curl);
+
+ curl_easy_cleanup(curl);
+ }
+
+ // process endpoints file
+ if (res == CURLE_OK) {
+ endpoint_descriptor_reader_pt reader = NULL;
+
+ status = endpointDescriptorReader_create(poller, &reader);
+ if (status == CELIX_SUCCESS) {
+ status = endpointDescriptorReader_parseDocument(reader, chunk.memory, updatedEndpoints);
+ }
+
+ if (reader) {
+ endpointDescriptorReader_destroy(reader);
+ }
+ } else {
+ logHelper_log(*poller->loghelper, OSGI_LOGSERVICE_ERROR, "ENDPOINT_POLLER: unable to read endpoints from %s, reason: %s", url, curl_easy_strerror(res));
+ }
+
+ // clean up endpoints file
+ if (chunk.memory) {
+ free(chunk.memory);
+ }
+
+ return status;
+}
+
+static celix_status_t endpointDiscoveryPoller_endpointDescriptionEquals(const void *endpointPtr, const void *comparePtr, bool *equals) {
+ endpoint_description_pt endpoint = (endpoint_description_pt) endpointPtr;
+ endpoint_description_pt compare = (endpoint_description_pt) comparePtr;
+
+ if (strcmp(endpoint->id, compare->id) == 0) {
+ *equals = true;
+ } else {
+ *equals = false;
+ }
+
+ return CELIX_SUCCESS;
+}
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/discovery_common/src/endpoint_discovery_server.c
----------------------------------------------------------------------
diff --git a/remote_services/discovery_common/src/endpoint_discovery_server.c b/remote_services/discovery_common/src/endpoint_discovery_server.c
new file mode 100644
index 0000000..f5f82af
--- /dev/null
+++ b/remote_services/discovery_common/src/endpoint_discovery_server.c
@@ -0,0 +1,450 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+/*
+ * endpoint_discovery_server.c
+ *
+ * \date Aug 12, 2014
+ * \author <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ * \copyright Apache License, Version 2.0
+ */
+#include <stdlib.h>
+#include <string.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+#ifndef ANDROID
+#include <ifaddrs.h>
+#endif
+#include "civetweb.h"
+#include "celix_errno.h"
+#include "utils.h"
+#include "log_helper.h"
+#include "discovery.h"
+#include "discovery_impl.h"
+
+#include "endpoint_descriptor_writer.h"
+
+// defines how often the webserver is restarted (with an increased port number)
+#define MAX_NUMBER_OF_RESTARTS 15
+#define DEFAULT_SERVER_THREADS "1"
+
+#define CIVETWEB_REQUEST_NOT_HANDLED 0
+#define CIVETWEB_REQUEST_HANDLED 1
+
+static const char *response_headers =
+ "HTTP/1.1 200 OK\r\n"
+ "Cache: no-cache\r\n"
+ "Content-Type: application/xml;charset=utf-8\r\n"
+ "\r\n";
+
+struct endpoint_discovery_server {
+ log_helper_pt* loghelper;
+ hash_map_pt entries; // key = endpointId, value = endpoint_descriptor_pt
+
+ celix_thread_mutex_t serverLock;
+
+ const char* path;
+ const char *port;
+ const char* ip;
+ struct mg_context* ctx;
+};
+
+// Forward declarations...
+static int endpointDiscoveryServer_callback(struct mg_connection *conn);
+static char* format_path(const char* path);
+
+#ifndef ANDROID
+static celix_status_t endpointDiscoveryServer_getIpAdress(char* interface, char** ip);
+#endif
+
+celix_status_t endpointDiscoveryServer_create(discovery_pt discovery, bundle_context_pt context, endpoint_discovery_server_pt *server) {
+ celix_status_t status;
+
+ const char *port = NULL;
+ const char *ip = NULL;
+ char *detectedIp = NULL;
+ const char *path = NULL;
+ const char *retries = NULL;
+
+ int max_ep_num = MAX_NUMBER_OF_RESTARTS;
+
+ *server = malloc(sizeof(struct endpoint_discovery_server));
+ if (!*server) {
+ return CELIX_ENOMEM;
+ }
+
+ (*server)->loghelper = &discovery->loghelper;
+ (*server)->entries = hashMap_create(&utils_stringHash, NULL, &utils_stringEquals, NULL);
+ if (!(*server)->entries) {
+ return CELIX_ENOMEM;
+ }
+
+ status = celixThreadMutex_create(&(*server)->serverLock, NULL);
+ if (status != CELIX_SUCCESS) {
+ return CELIX_BUNDLE_EXCEPTION;
+ }
+
+ bundleContext_getProperty(context, DISCOVERY_SERVER_IP, &ip);
+#ifndef ANDROID
+ if (ip == NULL) {
+ const char *interface = NULL;
+
+ bundleContext_getProperty(context, DISCOVERY_SERVER_INTERFACE, &interface);
+ if ((interface != NULL) && (endpointDiscoveryServer_getIpAdress((char*)interface, &detectedIp) != CELIX_SUCCESS)) {
+ logHelper_log(*(*server)->loghelper, OSGI_LOGSERVICE_WARNING, "Could not retrieve IP adress for interface %s", interface);
+ }
+
+ if (detectedIp == NULL) {
+ endpointDiscoveryServer_getIpAdress(NULL, &detectedIp);
+ }
+
+ ip = detectedIp;
+ }
+#endif
+
+ if (ip != NULL) {
+ logHelper_log(*(*server)->loghelper, OSGI_LOGSERVICE_INFO, "Using %s for service annunciation", ip);
+ (*server)->ip = strdup(ip);
+ }
+ else {
+ logHelper_log(*(*server)->loghelper, OSGI_LOGSERVICE_WARNING, "No IP address for service annunciation set. Using %s", DEFAULT_SERVER_IP);
+ (*server)->ip = strdup((char*) DEFAULT_SERVER_IP);
+ }
+
+ if (detectedIp != NULL) {
+ free(detectedIp);
+ }
+
+ bundleContext_getProperty(context, DISCOVERY_SERVER_PORT, &port);
+ if (port == NULL) {
+ port = DEFAULT_SERVER_PORT;
+ }
+
+ bundleContext_getProperty(context, DISCOVERY_SERVER_PATH, &path);
+ if (path == NULL) {
+ path = DEFAULT_SERVER_PATH;
+ }
+
+ bundleContext_getProperty(context, DISCOVERY_SERVER_MAX_EP, &retries);
+ if (retries != NULL) {
+ errno=0;
+ max_ep_num = strtol(retries,NULL,10);
+ if(errno!=0 || max_ep_num<=0){
+ max_ep_num=MAX_NUMBER_OF_RESTARTS;
+ }
+ }
+
+ (*server)->path = format_path(path);
+
+ const struct mg_callbacks callbacks = {
+ .begin_request = endpointDiscoveryServer_callback,
+ };
+
+ unsigned int port_counter = 0;
+ char newPort[10];
+
+ do {
+ const char *options[] = {
+ "listening_ports", port,
+ "num_threads", DEFAULT_SERVER_THREADS,
+ NULL
+ };
+
+ (*server)->ctx = mg_start(&callbacks, (*server), options);
+
+ if ((*server)->ctx != NULL)
+ {
+ logHelper_log(discovery->loghelper, OSGI_LOGSERVICE_INFO, "Starting discovery server on port %s...", port);
+ }
+ else {
+ errno = 0;
+ char* endptr = (char*)port;
+ long currentPort = strtol(port, &endptr, 10);
+
+ if (*endptr || errno != 0) {
+ currentPort = strtol(DEFAULT_SERVER_PORT, NULL, 10);
+ }
+
+ port_counter++;
+ snprintf(&newPort[0], 10, "%ld", (currentPort+1));
+
+ logHelper_log(discovery->loghelper, OSGI_LOGSERVICE_ERROR, "Error while starting discovery server on port %s - retrying on port %s...", port, newPort);
+ port = newPort;
+
+ }
+
+ } while(((*server)->ctx == NULL) && (port_counter < max_ep_num));
+
+ (*server)->port = strdup(port);
+
+ return status;
+}
+
+celix_status_t endpointDiscoveryServer_getUrl(endpoint_discovery_server_pt server, char* url)
+{
+ celix_status_t status = CELIX_BUNDLE_EXCEPTION;
+
+ if (server->ip && server->port && server->path) {
+ sprintf(url, "http://%s:%s/%s", server->ip, server->port, server->path);
+ status = CELIX_SUCCESS;
+ }
+
+ return status;
+}
+
+celix_status_t endpointDiscoveryServer_destroy(endpoint_discovery_server_pt server) {
+ celix_status_t status;
+
+ // stop & block until the actual server is shut down...
+ if (server->ctx != NULL) {
+ mg_stop(server->ctx);
+ server->ctx = NULL;
+ }
+
+ status = celixThreadMutex_lock(&server->serverLock);
+
+ hashMap_destroy(server->entries, true /* freeKeys */, false /* freeValues */);
+
+ status = celixThreadMutex_unlock(&server->serverLock);
+ status = celixThreadMutex_destroy(&server->serverLock);
+
+ free((void*) server->path);
+ free((void*) server->port);
+ free((void*) server->ip);
+
+ free(server);
+
+ return status;
+}
+
+celix_status_t endpointDiscoveryServer_addEndpoint(endpoint_discovery_server_pt server, endpoint_description_pt endpoint) {
+ celix_status_t status;
+
+ status = celixThreadMutex_lock(&server->serverLock);
+ if (status != CELIX_SUCCESS) {
+ return CELIX_BUNDLE_EXCEPTION;
+ }
+
+ // create a local copy of the endpointId which we can control...
+ char* endpointId = strdup(endpoint->id);
+ endpoint_description_pt cur_value = hashMap_get(server->entries, endpointId);
+ if (!cur_value) {
+ logHelper_log(*server->loghelper, OSGI_LOGSERVICE_INFO, "exposing new endpoint \"%s\"...", endpointId);
+
+ hashMap_put(server->entries, endpointId, endpoint);
+ }
+
+ status = celixThreadMutex_unlock(&server->serverLock);
+ if (status != CELIX_SUCCESS) {
+ return CELIX_BUNDLE_EXCEPTION;
+ }
+
+ return status;
+}
+
+celix_status_t endpointDiscoveryServer_removeEndpoint(endpoint_discovery_server_pt server, endpoint_description_pt endpoint) {
+ celix_status_t status;
+
+ status = celixThreadMutex_lock(&server->serverLock);
+ if (status != CELIX_SUCCESS) {
+ return CELIX_BUNDLE_EXCEPTION;
+ }
+
+ hash_map_entry_pt entry = hashMap_getEntry(server->entries, endpoint->id);
+ if (entry) {
+ char* key = hashMapEntry_getKey(entry);
+
+ logHelper_log(*server->loghelper, OSGI_LOGSERVICE_INFO, "removing endpoint \"%s\"...\n", key);
+
+ hashMap_remove(server->entries, key);
+
+ // we've made this key, see _addEnpoint above...
+ free((void*) key);
+ }
+
+ status = celixThreadMutex_unlock(&server->serverLock);
+ if (status != CELIX_SUCCESS) {
+ return CELIX_BUNDLE_EXCEPTION;
+ }
+
+ return status;
+}
+
+static char* format_path(const char* path) {
+ char* result = strdup(path);
+ result = utils_stringTrim(result);
+ // check whether the path starts with a leading slash...
+ if (result[0] != '/') {
+ size_t len = strlen(result);
+ result = realloc(result, len + 2);
+ memmove(result + 1, result, len);
+ result[0] = '/';
+ result[len + 1] = 0;
+ }
+ return result;
+}
+
+static celix_status_t endpointDiscoveryServer_getEndpoints(endpoint_discovery_server_pt server, const char* the_endpoint_id, array_list_pt *endpoints) {
+ celix_status_t status;
+
+ status = arrayList_create(endpoints);
+ if (status != CELIX_SUCCESS) {
+ return CELIX_ENOMEM;
+ }
+
+
+ hash_map_iterator_pt iter = hashMapIterator_create(server->entries);
+ while (hashMapIterator_hasNext(iter)) {
+ hash_map_entry_pt entry = hashMapIterator_nextEntry(iter);
+
+ char* endpoint_id = hashMapEntry_getKey(entry);
+ if (the_endpoint_id == NULL || strcmp(the_endpoint_id, endpoint_id) == 0) {
+ endpoint_description_pt endpoint = hashMapEntry_getValue(entry);
+
+ arrayList_add(*endpoints, endpoint);
+ }
+ }
+ hashMapIterator_destroy(iter);
+
+ return status;
+}
+
+static int endpointDiscoveryServer_writeEndpoints(struct mg_connection* conn, array_list_pt endpoints) {
+ celix_status_t status;
+ int rv = CIVETWEB_REQUEST_NOT_HANDLED;
+
+ endpoint_descriptor_writer_pt writer = NULL;
+ status = endpointDescriptorWriter_create(&writer);
+ if (status == CELIX_SUCCESS) {
+
+ char *buffer = NULL;
+ status = endpointDescriptorWriter_writeDocument(writer, endpoints, &buffer);
+ if (buffer) {
+ mg_write(conn, response_headers, strlen(response_headers));
+ mg_write(conn, buffer, strlen(buffer));
+ }
+
+ rv = CIVETWEB_REQUEST_HANDLED;
+ }
+
+ if(writer!=NULL){
+ endpointDescriptorWriter_destroy(writer);
+ }
+
+ return rv;
+}
+
+// returns all endpoints as XML...
+static int endpointDiscoveryServer_returnAllEndpoints(endpoint_discovery_server_pt server, struct mg_connection* conn) {
+ int status = CIVETWEB_REQUEST_NOT_HANDLED;
+
+ array_list_pt endpoints = NULL;
+
+ if (celixThreadMutex_lock(&server->serverLock) == CELIX_SUCCESS) {
+ endpointDiscoveryServer_getEndpoints(server, NULL, &endpoints);
+ if (endpoints) {
+ status = endpointDiscoveryServer_writeEndpoints(conn, endpoints);
+
+ arrayList_destroy(endpoints);
+ }
+
+
+ celixThreadMutex_unlock(&server->serverLock);
+ }
+
+ return status;
+}
+
+// returns a single endpoint as XML...
+static int endpointDiscoveryServer_returnEndpoint(endpoint_discovery_server_pt server, struct mg_connection* conn, const char* endpoint_id) {
+ int status = CIVETWEB_REQUEST_NOT_HANDLED;
+
+ array_list_pt endpoints = NULL;
+
+ if (celixThreadMutex_lock(&server->serverLock) == CELIX_SUCCESS) {
+ endpointDiscoveryServer_getEndpoints(server, endpoint_id, &endpoints);
+ if (endpoints) {
+ status = endpointDiscoveryServer_writeEndpoints(conn, endpoints);
+
+ arrayList_destroy(endpoints);
+ }
+
+ celixThreadMutex_unlock(&server->serverLock);
+ }
+
+ return status;
+}
+
+static int endpointDiscoveryServer_callback(struct mg_connection* conn) {
+ int status = CIVETWEB_REQUEST_NOT_HANDLED;
+
+ const struct mg_request_info *request_info = mg_get_request_info(conn);
+ if (request_info->uri != NULL && strcmp("GET", request_info->request_method) == 0) {
+ endpoint_discovery_server_pt server = request_info->user_data;
+
+ const char *uri = request_info->uri;
+ const size_t path_len = strlen(server->path);
+ const size_t uri_len = strlen(uri);
+
+ if (strncmp(server->path, uri, strlen(server->path)) == 0) {
+ // Be lenient when it comes to the trailing slash...
+ if (path_len == uri_len || (uri_len == (path_len + 1) && uri[path_len] == '/')) {
+ status = endpointDiscoveryServer_returnAllEndpoints(server, conn);
+ } else {
+ const char* endpoint_id = uri + path_len + 1; // right after the slash...
+
+ status = endpointDiscoveryServer_returnEndpoint(server, conn, endpoint_id);
+ }
+ }
+ }
+
+ return status;
+}
+
+#ifndef ANDROID
+static celix_status_t endpointDiscoveryServer_getIpAdress(char* interface, char** ip) {
+ celix_status_t status = CELIX_BUNDLE_EXCEPTION;
+
+ struct ifaddrs *ifaddr, *ifa;
+ char host[NI_MAXHOST];
+
+ if (getifaddrs(&ifaddr) != -1)
+ {
+ for (ifa = ifaddr; ifa != NULL && status != CELIX_SUCCESS; ifa = ifa->ifa_next)
+ {
+ if (ifa->ifa_addr == NULL)
+ continue;
+
+ if ((getnameinfo(ifa->ifa_addr,sizeof(struct sockaddr_in), host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST) == 0) && (ifa->ifa_addr->sa_family == AF_INET)) {
+ if (interface == NULL) {
+ *ip = strdup(host);
+ status = CELIX_SUCCESS;
+ }
+ else if (strcmp(ifa->ifa_name, interface) == 0) {
+ *ip = strdup(host);
+ status = CELIX_SUCCESS;
+ }
+ }
+ }
+
+ freeifaddrs(ifaddr);
+ }
+
+ return status;
+}
+#endif
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/discovery_common/src/md5.inl
----------------------------------------------------------------------
diff --git a/remote_services/discovery_common/src/md5.inl b/remote_services/discovery_common/src/md5.inl
new file mode 100644
index 0000000..4da933d
--- /dev/null
+++ b/remote_services/discovery_common/src/md5.inl
@@ -0,0 +1,461 @@
+/*
+ * This an amalgamation of md5.c and md5.h into a single file
+ * with all static declaration to reduce linker conflicts
+ * in Civetweb.
+ *
+ * The MD5_STATIC declaration was added to facilitate static
+ * inclusion.
+ * No Face Press, LLC
+ */
+
+/* $Id: md5.h,v 1.4 2002/04/13 19:20:28 lpd Exp $ */
+/*
+ Independent implementation of MD5 (RFC 1321).
+
+ This code implements the MD5 Algorithm defined in RFC 1321, whose
+ text is available at
+ http://www.ietf.org/rfc/rfc1321.txt
+ The code is derived from the text of the RFC, including the test suite
+ (section A.5) but excluding the rest of Appendix A. It does not include
+ any code or documentation that is identified in the RFC as being
+ copyrighted.
+
+ The original and principal author of md5.h is L. Peter Deutsch
+ <gh...@aladdin.com>. Other authors are noted in the change history
+ that follows (in reverse chronological order):
+
+ 2002-04-13 lpd Removed support for non-ANSI compilers; removed
+ references to Ghostscript; clarified derivation from RFC 1321;
+ now handles byte order either statically or dynamically.
+ 1999-11-04 lpd Edited comments slightly for automatic TOC extraction.
+ 1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5);
+ added conditionalization for C++ compilation from Martin
+ Purschke <pu...@bnl.gov>.
+ 1999-05-03 lpd Original version.
+ */
+
+#ifndef md5_INCLUDED
+# define md5_INCLUDED
+
+/*
+ * This package supports both compile-time and run-time determination of CPU
+ * byte order. If ARCH_IS_BIG_ENDIAN is defined as 0, the code will be
+ * compiled to run only on little-endian CPUs; if ARCH_IS_BIG_ENDIAN is
+ * defined as non-zero, the code will be compiled to run only on big-endian
+ * CPUs; if ARCH_IS_BIG_ENDIAN is not defined, the code will be compiled to
+ * run on either big- or little-endian CPUs, but will run slightly less
+ * efficiently on either one than if ARCH_IS_BIG_ENDIAN is defined.
+ */
+
+typedef unsigned char md5_byte_t; /* 8-bit byte */
+typedef unsigned int md5_word_t; /* 32-bit word */
+
+/* Define the state of the MD5 Algorithm. */
+typedef struct md5_state_s {
+ md5_word_t count[2]; /* message length in bits, lsw first */
+ md5_word_t abcd[4]; /* digest buffer */
+ md5_byte_t buf[64]; /* accumulate block */
+} md5_state_t;
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/* Initialize the algorithm. */
+MD5_STATIC void md5_init(md5_state_t *pms);
+
+/* Append a string to the message. */
+MD5_STATIC void md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes);
+
+/* Finish the message and return the digest. */
+MD5_STATIC void md5_finish(md5_state_t *pms, md5_byte_t digest[16]);
+
+#ifdef __cplusplus
+} /* end extern "C" */
+#endif
+
+#endif /* md5_INCLUDED */
+
+/*
+ Copyright (C) 1999, 2000, 2002 Aladdin Enterprises. All rights reserved.
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+
+ L. Peter Deutsch
+ ghost@aladdin.com
+
+ */
+/* $Id: md5.c,v 1.6 2002/04/13 19:20:28 lpd Exp $ */
+/*
+ Independent implementation of MD5 (RFC 1321).
+
+ This code implements the MD5 Algorithm defined in RFC 1321, whose
+ text is available at
+ http://www.ietf.org/rfc/rfc1321.txt
+ The code is derived from the text of the RFC, including the test suite
+ (section A.5) but excluding the rest of Appendix A. It does not include
+ any code or documentation that is identified in the RFC as being
+ copyrighted.
+
+ The original and principal author of md5.c is L. Peter Deutsch
+ <gh...@aladdin.com>. Other authors are noted in the change history
+ that follows (in reverse chronological order):
+
+ 2002-04-13 lpd Clarified derivation from RFC 1321; now handles byte order
+ either statically or dynamically; added missing #include <string.h>
+ in library.
+ 2002-03-11 lpd Corrected argument list for main(), and added int return
+ type, in test program and T value program.
+ 2002-02-21 lpd Added missing #include <stdio.h> in test program.
+ 2000-07-03 lpd Patched to eliminate warnings about "constant is
+ unsigned in ANSI C, signed in traditional"; made test program
+ self-checking.
+ 1999-11-04 lpd Edited comments slightly for automatic TOC extraction.
+ 1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5).
+ 1999-05-03 lpd Original version.
+ */
+
+#ifndef MD5_STATIC
+#include <string.h>
+#endif
+
+#undef BYTE_ORDER /* 1 = big-endian, -1 = little-endian, 0 = unknown */
+#ifdef ARCH_IS_BIG_ENDIAN
+# define BYTE_ORDER (ARCH_IS_BIG_ENDIAN ? 1 : -1)
+#else
+# define BYTE_ORDER 0
+#endif
+
+#define T_MASK ((md5_word_t)~0)
+#define T1 /* 0xd76aa478 */ (T_MASK ^ 0x28955b87)
+#define T2 /* 0xe8c7b756 */ (T_MASK ^ 0x173848a9)
+#define T3 0x242070db
+#define T4 /* 0xc1bdceee */ (T_MASK ^ 0x3e423111)
+#define T5 /* 0xf57c0faf */ (T_MASK ^ 0x0a83f050)
+#define T6 0x4787c62a
+#define T7 /* 0xa8304613 */ (T_MASK ^ 0x57cfb9ec)
+#define T8 /* 0xfd469501 */ (T_MASK ^ 0x02b96afe)
+#define T9 0x698098d8
+#define T10 /* 0x8b44f7af */ (T_MASK ^ 0x74bb0850)
+#define T11 /* 0xffff5bb1 */ (T_MASK ^ 0x0000a44e)
+#define T12 /* 0x895cd7be */ (T_MASK ^ 0x76a32841)
+#define T13 0x6b901122
+#define T14 /* 0xfd987193 */ (T_MASK ^ 0x02678e6c)
+#define T15 /* 0xa679438e */ (T_MASK ^ 0x5986bc71)
+#define T16 0x49b40821
+#define T17 /* 0xf61e2562 */ (T_MASK ^ 0x09e1da9d)
+#define T18 /* 0xc040b340 */ (T_MASK ^ 0x3fbf4cbf)
+#define T19 0x265e5a51
+#define T20 /* 0xe9b6c7aa */ (T_MASK ^ 0x16493855)
+#define T21 /* 0xd62f105d */ (T_MASK ^ 0x29d0efa2)
+#define T22 0x02441453
+#define T23 /* 0xd8a1e681 */ (T_MASK ^ 0x275e197e)
+#define T24 /* 0xe7d3fbc8 */ (T_MASK ^ 0x182c0437)
+#define T25 0x21e1cde6
+#define T26 /* 0xc33707d6 */ (T_MASK ^ 0x3cc8f829)
+#define T27 /* 0xf4d50d87 */ (T_MASK ^ 0x0b2af278)
+#define T28 0x455a14ed
+#define T29 /* 0xa9e3e905 */ (T_MASK ^ 0x561c16fa)
+#define T30 /* 0xfcefa3f8 */ (T_MASK ^ 0x03105c07)
+#define T31 0x676f02d9
+#define T32 /* 0x8d2a4c8a */ (T_MASK ^ 0x72d5b375)
+#define T33 /* 0xfffa3942 */ (T_MASK ^ 0x0005c6bd)
+#define T34 /* 0x8771f681 */ (T_MASK ^ 0x788e097e)
+#define T35 0x6d9d6122
+#define T36 /* 0xfde5380c */ (T_MASK ^ 0x021ac7f3)
+#define T37 /* 0xa4beea44 */ (T_MASK ^ 0x5b4115bb)
+#define T38 0x4bdecfa9
+#define T39 /* 0xf6bb4b60 */ (T_MASK ^ 0x0944b49f)
+#define T40 /* 0xbebfbc70 */ (T_MASK ^ 0x4140438f)
+#define T41 0x289b7ec6
+#define T42 /* 0xeaa127fa */ (T_MASK ^ 0x155ed805)
+#define T43 /* 0xd4ef3085 */ (T_MASK ^ 0x2b10cf7a)
+#define T44 0x04881d05
+#define T45 /* 0xd9d4d039 */ (T_MASK ^ 0x262b2fc6)
+#define T46 /* 0xe6db99e5 */ (T_MASK ^ 0x1924661a)
+#define T47 0x1fa27cf8
+#define T48 /* 0xc4ac5665 */ (T_MASK ^ 0x3b53a99a)
+#define T49 /* 0xf4292244 */ (T_MASK ^ 0x0bd6ddbb)
+#define T50 0x432aff97
+#define T51 /* 0xab9423a7 */ (T_MASK ^ 0x546bdc58)
+#define T52 /* 0xfc93a039 */ (T_MASK ^ 0x036c5fc6)
+#define T53 0x655b59c3
+#define T54 /* 0x8f0ccc92 */ (T_MASK ^ 0x70f3336d)
+#define T55 /* 0xffeff47d */ (T_MASK ^ 0x00100b82)
+#define T56 /* 0x85845dd1 */ (T_MASK ^ 0x7a7ba22e)
+#define T57 0x6fa87e4f
+#define T58 /* 0xfe2ce6e0 */ (T_MASK ^ 0x01d3191f)
+#define T59 /* 0xa3014314 */ (T_MASK ^ 0x5cfebceb)
+#define T60 0x4e0811a1
+#define T61 /* 0xf7537e82 */ (T_MASK ^ 0x08ac817d)
+#define T62 /* 0xbd3af235 */ (T_MASK ^ 0x42c50dca)
+#define T63 0x2ad7d2bb
+#define T64 /* 0xeb86d391 */ (T_MASK ^ 0x14792c6e)
+
+
+static void
+md5_process(md5_state_t *pms, const md5_byte_t *data /*[64]*/)
+{
+ md5_word_t
+ a = pms->abcd[0], b = pms->abcd[1],
+ c = pms->abcd[2], d = pms->abcd[3];
+ md5_word_t t;
+#if BYTE_ORDER > 0
+ /* Define storage only for big-endian CPUs. */
+ md5_word_t X[16];
+#else
+ /* Define storage for little-endian or both types of CPUs. */
+ md5_word_t xbuf[16];
+ const md5_word_t *X;
+#endif
+
+ {
+#if BYTE_ORDER == 0
+ /*
+ * Determine dynamically whether this is a big-endian or
+ * little-endian machine, since we can use a more efficient
+ * algorithm on the latter.
+ */
+ static const int w = 1;
+
+ if (*((const md5_byte_t *)&w)) /* dynamic little-endian */
+#endif
+#if BYTE_ORDER <= 0 /* little-endian */
+ {
+ /*
+ * On little-endian machines, we can process properly aligned
+ * data without copying it.
+ */
+ if (!((data - (const md5_byte_t *)0) & 3)) {
+ /* data are properly aligned */
+ X = (const md5_word_t *)data;
+ } else {
+ /* not aligned */
+ memcpy(xbuf, data, 64);
+ X = xbuf;
+ }
+ }
+#endif
+#if BYTE_ORDER == 0
+ else /* dynamic big-endian */
+#endif
+#if BYTE_ORDER >= 0 /* big-endian */
+ {
+ /*
+ * On big-endian machines, we must arrange the bytes in the
+ * right order.
+ */
+ const md5_byte_t *xp = data;
+ int i;
+
+# if BYTE_ORDER == 0
+ X = xbuf; /* (dynamic only) */
+# else
+# define xbuf X /* (static only) */
+# endif
+ for (i = 0; i < 16; ++i, xp += 4)
+ xbuf[i] = xp[0] + (xp[1] << 8) + (xp[2] << 16) + (xp[3] << 24);
+ }
+#endif
+ }
+
+#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
+
+ /* Round 1. */
+ /* Let [abcd k s i] denote the operation
+ a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */
+#define F(x, y, z) (((x) & (y)) | (~(x) & (z)))
+#define SET(a, b, c, d, k, s, Ti)\
+ t = a + F(b,c,d) + X[k] + Ti;\
+ a = ROTATE_LEFT(t, s) + b
+ /* Do the following 16 operations. */
+ SET(a, b, c, d, 0, 7, T1);
+ SET(d, a, b, c, 1, 12, T2);
+ SET(c, d, a, b, 2, 17, T3);
+ SET(b, c, d, a, 3, 22, T4);
+ SET(a, b, c, d, 4, 7, T5);
+ SET(d, a, b, c, 5, 12, T6);
+ SET(c, d, a, b, 6, 17, T7);
+ SET(b, c, d, a, 7, 22, T8);
+ SET(a, b, c, d, 8, 7, T9);
+ SET(d, a, b, c, 9, 12, T10);
+ SET(c, d, a, b, 10, 17, T11);
+ SET(b, c, d, a, 11, 22, T12);
+ SET(a, b, c, d, 12, 7, T13);
+ SET(d, a, b, c, 13, 12, T14);
+ SET(c, d, a, b, 14, 17, T15);
+ SET(b, c, d, a, 15, 22, T16);
+#undef SET
+
+ /* Round 2. */
+ /* Let [abcd k s i] denote the operation
+ a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */
+#define G(x, y, z) (((x) & (z)) | ((y) & ~(z)))
+#define SET(a, b, c, d, k, s, Ti)\
+ t = a + G(b,c,d) + X[k] + Ti;\
+ a = ROTATE_LEFT(t, s) + b
+ /* Do the following 16 operations. */
+ SET(a, b, c, d, 1, 5, T17);
+ SET(d, a, b, c, 6, 9, T18);
+ SET(c, d, a, b, 11, 14, T19);
+ SET(b, c, d, a, 0, 20, T20);
+ SET(a, b, c, d, 5, 5, T21);
+ SET(d, a, b, c, 10, 9, T22);
+ SET(c, d, a, b, 15, 14, T23);
+ SET(b, c, d, a, 4, 20, T24);
+ SET(a, b, c, d, 9, 5, T25);
+ SET(d, a, b, c, 14, 9, T26);
+ SET(c, d, a, b, 3, 14, T27);
+ SET(b, c, d, a, 8, 20, T28);
+ SET(a, b, c, d, 13, 5, T29);
+ SET(d, a, b, c, 2, 9, T30);
+ SET(c, d, a, b, 7, 14, T31);
+ SET(b, c, d, a, 12, 20, T32);
+#undef SET
+
+ /* Round 3. */
+ /* Let [abcd k s t] denote the operation
+ a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). */
+#define H(x, y, z) ((x) ^ (y) ^ (z))
+#define SET(a, b, c, d, k, s, Ti)\
+ t = a + H(b,c,d) + X[k] + Ti;\
+ a = ROTATE_LEFT(t, s) + b
+ /* Do the following 16 operations. */
+ SET(a, b, c, d, 5, 4, T33);
+ SET(d, a, b, c, 8, 11, T34);
+ SET(c, d, a, b, 11, 16, T35);
+ SET(b, c, d, a, 14, 23, T36);
+ SET(a, b, c, d, 1, 4, T37);
+ SET(d, a, b, c, 4, 11, T38);
+ SET(c, d, a, b, 7, 16, T39);
+ SET(b, c, d, a, 10, 23, T40);
+ SET(a, b, c, d, 13, 4, T41);
+ SET(d, a, b, c, 0, 11, T42);
+ SET(c, d, a, b, 3, 16, T43);
+ SET(b, c, d, a, 6, 23, T44);
+ SET(a, b, c, d, 9, 4, T45);
+ SET(d, a, b, c, 12, 11, T46);
+ SET(c, d, a, b, 15, 16, T47);
+ SET(b, c, d, a, 2, 23, T48);
+#undef SET
+
+ /* Round 4. */
+ /* Let [abcd k s t] denote the operation
+ a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s). */
+#define I(x, y, z) ((y) ^ ((x) | ~(z)))
+#define SET(a, b, c, d, k, s, Ti)\
+ t = a + I(b,c,d) + X[k] + Ti;\
+ a = ROTATE_LEFT(t, s) + b
+ /* Do the following 16 operations. */
+ SET(a, b, c, d, 0, 6, T49);
+ SET(d, a, b, c, 7, 10, T50);
+ SET(c, d, a, b, 14, 15, T51);
+ SET(b, c, d, a, 5, 21, T52);
+ SET(a, b, c, d, 12, 6, T53);
+ SET(d, a, b, c, 3, 10, T54);
+ SET(c, d, a, b, 10, 15, T55);
+ SET(b, c, d, a, 1, 21, T56);
+ SET(a, b, c, d, 8, 6, T57);
+ SET(d, a, b, c, 15, 10, T58);
+ SET(c, d, a, b, 6, 15, T59);
+ SET(b, c, d, a, 13, 21, T60);
+ SET(a, b, c, d, 4, 6, T61);
+ SET(d, a, b, c, 11, 10, T62);
+ SET(c, d, a, b, 2, 15, T63);
+ SET(b, c, d, a, 9, 21, T64);
+#undef SET
+
+ /* Then perform the following additions. (That is increment each
+ of the four registers by the value it had before this block
+ was started.) */
+ pms->abcd[0] += a;
+ pms->abcd[1] += b;
+ pms->abcd[2] += c;
+ pms->abcd[3] += d;
+}
+
+MD5_STATIC void
+md5_init(md5_state_t *pms)
+{
+ pms->count[0] = pms->count[1] = 0;
+ pms->abcd[0] = 0x67452301;
+ pms->abcd[1] = /*0xefcdab89*/ T_MASK ^ 0x10325476;
+ pms->abcd[2] = /*0x98badcfe*/ T_MASK ^ 0x67452301;
+ pms->abcd[3] = 0x10325476;
+}
+
+MD5_STATIC void
+md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes)
+{
+ const md5_byte_t *p = data;
+ int left = nbytes;
+ int offset = (pms->count[0] >> 3) & 63;
+ md5_word_t nbits = (md5_word_t)(nbytes << 3);
+
+ if (nbytes <= 0)
+ return;
+
+ /* Update the message length. */
+ pms->count[1] += nbytes >> 29;
+ pms->count[0] += nbits;
+ if (pms->count[0] < nbits)
+ pms->count[1]++;
+
+ /* Process an initial partial block. */
+ if (offset) {
+ int copy = (offset + nbytes > 64 ? 64 - offset : nbytes);
+
+ memcpy(pms->buf + offset, p, copy);
+ if (offset + copy < 64)
+ return;
+ p += copy;
+ left -= copy;
+ md5_process(pms, pms->buf);
+ }
+
+ /* Process full blocks. */
+ for (; left >= 64; p += 64, left -= 64)
+ md5_process(pms, p);
+
+ /* Process a final partial block. */
+ if (left)
+ memcpy(pms->buf, p, left);
+}
+
+MD5_STATIC void
+md5_finish(md5_state_t *pms, md5_byte_t digest[16])
+{
+ static const md5_byte_t pad[64] = {
+ 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ };
+ md5_byte_t data[8];
+ int i;
+
+ /* Save the length before padding. */
+ for (i = 0; i < 8; ++i)
+ data[i] = (md5_byte_t)(pms->count[i >> 2] >> ((i & 3) << 3));
+ /* Pad to 56 bytes mod 64. */
+ md5_append(pms, pad, ((55 - (pms->count[0] >> 3)) & 63) + 1);
+ /* Append the length. */
+ md5_append(pms, data, 8);
+ for (i = 0; i < 16; ++i)
+ digest[i] = (md5_byte_t)(pms->abcd[i >> 2] >> ((i & 3) << 3));
+}
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/discovery_configured/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/remote_services/discovery_configured/CMakeLists.txt b/remote_services/discovery_configured/CMakeLists.txt
index b9f849d..e0f3e9b 100644
--- a/remote_services/discovery_configured/CMakeLists.txt
+++ b/remote_services/discovery_configured/CMakeLists.txt
@@ -19,39 +19,19 @@ if (RSA_DISCOVERY_CONFIGURED)
find_package(CURL REQUIRED)
find_package(LibXml2 REQUIRED)
- include_directories("${CURL_INCLUDE_DIR}")
- include_directories("${LIBXML2_INCLUDE_DIR}")
- include_directories("${PROJECT_SOURCE_DIR}/utils/public/include")
- include_directories("${PROJECT_SOURCE_DIR}/remote_services/utils/private/include")
- include_directories("${PROJECT_SOURCE_DIR}/remote_services/utils/public/include")
- include_directories("${PROJECT_SOURCE_DIR}/remote_services/discovery/private/include")
- include_directories("${PROJECT_SOURCE_DIR}/remote_services/discovery_configured/private/include")
- include_directories("${PROJECT_SOURCE_DIR}/remote_services/endpoint_listener/public/include")
- include_directories("${PROJECT_SOURCE_DIR}/remote_services/remote_service_admin/public/include")
- include_directories("${PROJECT_SOURCE_DIR}/log_service/public/include")
- include_directories(private/include)
-
add_bundle(discovery_configured
- VERSION 0.9.0
- SYMBOLIC_NAME "apache_celix_rsa_discovery_configured"
- NAME "Apache Celix RSA Configured Discovery"
- SOURCES
-
- private/src/discovery_impl.c
- ${PROJECT_SOURCE_DIR}/remote_services/discovery/private/src/discovery_activator.c
- ${PROJECT_SOURCE_DIR}/remote_services/discovery/private/src/discovery.c
- ${PROJECT_SOURCE_DIR}/remote_services/discovery/private/src/endpoint_descriptor_reader.c
- ${PROJECT_SOURCE_DIR}/remote_services/discovery/private/src/endpoint_descriptor_writer.c
- ${PROJECT_SOURCE_DIR}/remote_services/discovery/private/src/endpoint_discovery_poller.c
- ${PROJECT_SOURCE_DIR}/remote_services/discovery/private/src/endpoint_discovery_server.c
- ${PROJECT_SOURCE_DIR}/remote_services/remote_service_admin/private/src/endpoint_description.c
- ${PROJECT_SOURCE_DIR}/remote_services/utils/private/src/civetweb.c
+ VERSION 0.9.0
+ SYMBOLIC_NAME "apache_celix_rsa_discovery_configured"
+ NAME "Apache Celix RSA Configured Discovery"
+ SOURCES
+ src/discovery_impl.c
)
- target_link_libraries(discovery_configured PRIVATE Celix::log_helper)
+ target_include_directories(discovery_configured PRIVATE src)
+ target_link_libraries(discovery_configured PRIVATE ${CURL_LIBRARIES} ${LIBXML2_LIBRARIES} Celix::log_helper discovery_common)
install_bundle(discovery_configured)
- target_link_libraries(discovery_configured PRIVATE ${CURL_LIBRARIES} ${LIBXML2_LIBRARIES})
+
if (RSA_ENDPOINT_TEST_READER)
add_executable(descparser
[12/19] celix git commit: CELIX-417: Refactor for CMake usage in RSA,
PSA and Docker. mostly trying to identify the api and common libraries
Posted by pn...@apache.org.
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/remote_services/discovery_common/src/civetweb.c
----------------------------------------------------------------------
diff --git a/remote_services/discovery_common/src/civetweb.c b/remote_services/discovery_common/src/civetweb.c
new file mode 100644
index 0000000..a6093b7
--- /dev/null
+++ b/remote_services/discovery_common/src/civetweb.c
@@ -0,0 +1,7907 @@
+ /* Copyright (c) 2013-2015 the Civetweb developers
+ * Copyright (c) 2004-2013 Sergey Lyubka
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#if defined(_WIN32)
+#if !defined(_CRT_SECURE_NO_WARNINGS)
+#define _CRT_SECURE_NO_WARNINGS /* Disable deprecation warning in VS2005 */
+#endif
+#else
+#ifdef __linux__
+#define _XOPEN_SOURCE 600 /* For flockfile() on Linux */
+#endif
+#ifndef _LARGEFILE_SOURCE
+#define _LARGEFILE_SOURCE /* For fseeko(), ftello() */
+#endif
+#ifndef _FILE_OFFSET_BITS
+#define _FILE_OFFSET_BITS 64 /* Use 64-bit file offsets by default */
+#endif
+#ifndef __STDC_FORMAT_MACROS
+#define __STDC_FORMAT_MACROS /* <inttypes.h> wants this for C++ */
+#endif
+#ifndef __STDC_LIMIT_MACROS
+#define __STDC_LIMIT_MACROS /* C++ wants that for INT64_MAX */
+#endif
+#endif
+
+#if defined (_MSC_VER)
+/* 'type cast' : conversion from 'int' to 'HANDLE' of greater size */
+#pragma warning (disable : 4306 )
+/* conditional expression is constant: introduced by FD_SET(..) */
+#pragma warning (disable : 4127)
+/* non-constant aggregate initializer: issued due to missing C99 support */
+#pragma warning (disable : 4204)
+#endif
+
+/* Disable WIN32_LEAN_AND_MEAN.
+ This makes windows.h always include winsock2.h */
+#if defined(WIN32_LEAN_AND_MEAN)
+#undef WIN32_LEAN_AND_MEAN
+#endif
+
+#if defined USE_IPV6 && defined(_WIN32)
+#include <ws2tcpip.h>
+#endif
+
+#if defined(__SYMBIAN32__)
+#define NO_SSL /* SSL is not supported */
+#define NO_CGI /* CGI is not supported */
+#define PATH_MAX FILENAME_MAX
+#endif /* __SYMBIAN32__ */
+
+#ifndef IGNORE_UNUSED_RESULT
+#define IGNORE_UNUSED_RESULT(a) (void)((a) && 1)
+#endif
+
+#ifndef _WIN32_WCE /* Some ANSI #includes are not available on Windows CE */
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <signal.h>
+#include <fcntl.h>
+#endif /* !_WIN32_WCE */
+
+#include <time.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <assert.h>
+#include <string.h>
+#include <ctype.h>
+#include <limits.h>
+#include <stddef.h>
+#include <stdio.h>
+
+#ifndef MAX_WORKER_THREADS
+#define MAX_WORKER_THREADS (1024*64)
+#endif
+
+#if defined(_WIN32) && !defined(__SYMBIAN32__) /* Windows specific */
+#if defined(_MSC_VER) && _MSC_VER <= 1400
+#undef _WIN32_WINNT
+#define _WIN32_WINNT 0x0400 /* To make it link in VS2005 */
+#endif
+#include <windows.h>
+typedef const char * SOCK_OPT_TYPE;
+
+#ifndef PATH_MAX
+#define PATH_MAX MAX_PATH
+#endif
+
+#ifndef _IN_PORT_T
+#ifndef in_port_t
+#define in_port_t u_short
+#endif
+#endif
+
+#ifndef _WIN32_WCE
+#include <process.h>
+#include <direct.h>
+#include <io.h>
+#else /* _WIN32_WCE */
+#define NO_CGI /* WinCE has no pipes */
+
+typedef long off_t;
+
+#define errno GetLastError()
+#define strerror(x) _ultoa(x, (char *) _alloca(sizeof(x) *3 ), 10)
+#endif /* _WIN32_WCE */
+
+#define MAKEUQUAD(lo, hi) ((uint64_t)(((uint32_t)(lo)) | \
+ ((uint64_t)((uint32_t)(hi))) << 32))
+#define RATE_DIFF 10000000 /* 100 nsecs */
+#define EPOCH_DIFF MAKEUQUAD(0xd53e8000, 0x019db1de)
+#define SYS2UNIX_TIME(lo, hi) \
+ (time_t) ((MAKEUQUAD((lo), (hi)) - EPOCH_DIFF) / RATE_DIFF)
+
+/* Visual Studio 6 does not know __func__ or __FUNCTION__
+ The rest of MS compilers use __FUNCTION__, not C99 __func__
+ Also use _strtoui64 on modern M$ compilers */
+#if defined(_MSC_VER) && _MSC_VER < 1300
+#define STRX(x) #x
+#define STR(x) STRX(x)
+#define __func__ __FILE__ ":" STR(__LINE__)
+#define strtoull(x, y, z) (unsigned __int64) _atoi64(x)
+#define strtoll(x, y, z) _atoi64(x)
+#else
+#define __func__ __FUNCTION__
+#define strtoull(x, y, z) _strtoui64(x, y, z)
+#define strtoll(x, y, z) _strtoi64(x, y, z)
+#endif /* _MSC_VER */
+
+#define ERRNO GetLastError()
+#define NO_SOCKLEN_T
+#define SSL_LIB "ssleay32.dll"
+#define CRYPTO_LIB "libeay32.dll"
+#define O_NONBLOCK 0
+#define W_OK (2) /* http://msdn.microsoft.com/en-us/library/1w06ktdy.aspx */
+#if !defined(EWOULDBLOCK)
+#define EWOULDBLOCK WSAEWOULDBLOCK
+#endif /* !EWOULDBLOCK */
+#define _POSIX_
+#define INT64_FMT "I64d"
+
+#define WINCDECL __cdecl
+#define SHUT_WR 1
+#define snprintf _snprintf
+#define vsnprintf _vsnprintf
+#define access _access
+#define mg_sleep(x) Sleep(x)
+
+#define pipe(x) _pipe(x, MG_BUF_LEN, _O_BINARY)
+#ifndef popen
+#define popen(x, y) _popen(x, y)
+#endif
+#ifndef pclose
+#define pclose(x) _pclose(x)
+#endif
+#define close(x) _close(x)
+#define dlsym(x,y) GetProcAddress((HINSTANCE) (x), (y))
+#define RTLD_LAZY 0
+#define fseeko(x, y, z) _lseeki64(_fileno(x), (y), (z))
+#define fdopen(x, y) _fdopen((x), (y))
+#define write(x, y, z) _write((x), (y), (unsigned) z)
+#define read(x, y, z) _read((x), (y), (unsigned) z)
+#define flockfile(x) EnterCriticalSection(&global_log_file_lock)
+#define funlockfile(x) LeaveCriticalSection(&global_log_file_lock)
+#define sleep(x) Sleep((x) * 1000)
+#define rmdir(x) _rmdir(x)
+
+#if defined(USE_LUA) && defined(USE_WEBSOCKET)
+#define USE_TIMERS
+#endif
+
+#if !defined(va_copy)
+#define va_copy(x, y) x = y
+#endif /* !va_copy MINGW #defines va_copy */
+
+#if !defined(fileno)
+#define fileno(x) _fileno(x)
+#endif /* !fileno MINGW #defines fileno */
+
+typedef HANDLE pthread_mutex_t;
+typedef DWORD pthread_key_t;
+typedef HANDLE pthread_t;
+typedef struct {
+ CRITICAL_SECTION threadIdSec;
+ int waitingthreadcount; /* The number of threads queued. */
+ pthread_t *waitingthreadhdls; /* The thread handles. */
+} pthread_cond_t;
+
+#ifndef __clockid_t_defined
+typedef DWORD clockid_t;
+#endif
+#ifndef CLOCK_MONOTONIC
+#define CLOCK_MONOTONIC (1)
+#endif
+#ifndef CLOCK_REALTIME
+#define CLOCK_REALTIME (2)
+#endif
+
+#ifndef _TIMESPEC_DEFINED
+struct timespec {
+ time_t tv_sec; /* seconds */
+ long tv_nsec; /* nanoseconds */
+};
+#endif
+
+#define pid_t HANDLE /* MINGW typedefs pid_t to int. Using #define here. */
+
+static int pthread_mutex_lock(pthread_mutex_t *);
+static int pthread_mutex_unlock(pthread_mutex_t *);
+static void to_unicode(const char *path, wchar_t *wbuf, size_t wbuf_len);
+struct file;
+static char *mg_fgets(char *buf, size_t size, struct file *filep, char **p);
+
+#if defined(HAVE_STDINT)
+#include <stdint.h>
+#else
+typedef unsigned int uint32_t;
+typedef unsigned short uint16_t;
+typedef unsigned __int64 uint64_t;
+typedef __int64 int64_t;
+#define INT64_MAX 9223372036854775807
+#endif /* HAVE_STDINT */
+
+/* POSIX dirent interface */
+struct dirent {
+ char d_name[PATH_MAX];
+};
+
+typedef struct DIR {
+ HANDLE handle;
+ WIN32_FIND_DATAW info;
+ struct dirent result;
+} DIR;
+
+#if !defined(USE_IPV6) && defined(_WIN32)
+#ifndef HAVE_POLL
+struct pollfd {
+ SOCKET fd;
+ short events;
+ short revents;
+};
+#define POLLIN 1
+#endif
+#endif
+
+/* Mark required libraries */
+#ifdef _MSC_VER
+#pragma comment(lib, "Ws2_32.lib")
+#endif
+
+#else /* UNIX specific */
+#include <sys/wait.h>
+#include <sys/socket.h>
+#include <sys/poll.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <sys/time.h>
+#include <sys/utsname.h>
+#include <stdint.h>
+#include <inttypes.h>
+#include <netdb.h>
+typedef const void * SOCK_OPT_TYPE;
+
+//#if defined(ANDROID)
+typedef unsigned short int in_port_t;
+//#endif
+
+#include <pwd.h>
+#include <unistd.h>
+#include <dirent.h>
+#if !defined(NO_SSL_DL) && !defined(NO_SSL)
+#include <dlfcn.h>
+#endif
+#include <pthread.h>
+#if defined(__MACH__)
+#define SSL_LIB "libssl.dylib"
+#define CRYPTO_LIB "libcrypto.dylib"
+#else
+#if !defined(SSL_LIB)
+#define SSL_LIB "libssl.so"
+#endif
+#if !defined(CRYPTO_LIB)
+#define CRYPTO_LIB "libcrypto.so"
+#endif
+#endif
+#ifndef O_BINARY
+#define O_BINARY 0
+#endif /* O_BINARY */
+#define closesocket(a) close(a)
+#define mg_mkdir(x, y) mkdir(x, y)
+#define mg_remove(x) remove(x)
+#define mg_sleep(x) usleep((x) * 1000)
+#define ERRNO errno
+#define INVALID_SOCKET (-1)
+#define INT64_FMT PRId64
+typedef int SOCKET;
+#define WINCDECL
+
+#endif /* End of Windows and UNIX specific includes */
+
+#ifdef _WIN32
+static CRITICAL_SECTION global_log_file_lock;
+static DWORD pthread_self(void)
+{
+ return GetCurrentThreadId();
+}
+
+int pthread_key_create(pthread_key_t *key, void (*_must_be_zero)(void*) /* destructor function not supported for windows */)
+{
+ assert(_must_be_zero == NULL);
+ if ((key!=0) && (_must_be_zero == NULL)) {
+ *key = TlsAlloc();
+ return (*key != TLS_OUT_OF_INDEXES) ? 0 : -1;
+ }
+ return -2;
+}
+
+int pthread_key_delete(pthread_key_t key)
+{
+ return TlsFree(key) ? 0 : 1;
+}
+
+int pthread_setspecific(pthread_key_t key, void * value)
+{
+ return TlsSetValue(key, value) ? 0 : 1;
+}
+
+void *pthread_getspecific(pthread_key_t key)
+{
+ return TlsGetValue(key);
+}
+#endif /* _WIN32 */
+
+
+#include "civetweb.h"
+
+#define PASSWORDS_FILE_NAME ".htpasswd"
+#define CGI_ENVIRONMENT_SIZE 4096
+#define MAX_CGI_ENVIR_VARS 64
+#define MG_BUF_LEN 8192
+#ifndef MAX_REQUEST_SIZE
+#define MAX_REQUEST_SIZE 16384
+#endif
+#define ARRAY_SIZE(array) (sizeof(array) / sizeof(array[0]))
+
+#if !defined(DEBUG_TRACE)
+#if defined(CWDEBUG)
+
+static void DEBUG_TRACE_FUNC(const char *func, unsigned line, PRINTF_FORMAT_STRING(const char *fmt), ...) PRINTF_ARGS(3, 4);
+
+static void DEBUG_TRACE_FUNC(const char *func, unsigned line, const char *fmt, ...) {
+
+ va_list args;
+ flockfile(stdout);
+ printf("*** %lu.%p.%s.%u: ",
+ (unsigned long) time(NULL), (void *) pthread_self(),
+ func, line);
+ va_start(args, fmt);
+ vprintf(fmt, args);
+ va_end(args);
+ putchar('\n');
+ fflush(stdout);
+ funlockfile(stdout);
+}
+
+#define DEBUG_TRACE(fmt, ...) DEBUG_TRACE_FUNC(__func__, __LINE__, fmt, __VA_ARGS__)
+
+#else
+#define DEBUG_TRACE(fmt, ...)
+#endif /* CWDEBUG */
+#endif /* DEBUG_TRACE */
+
+#if defined(MEMORY_DEBUGGING)
+static unsigned long blockCount = 0;
+static unsigned long totalMemUsed = 0;
+
+static void * mg_malloc_ex(size_t size, const char * file, unsigned line) {
+
+ void * data = malloc(size + sizeof(size_t));
+ void * memory = 0;
+ char mallocStr[256];
+
+ if (data) {
+ *(size_t*)data = size;
+ totalMemUsed += size;
+ blockCount++;
+ memory = (void *)(((char*)data)+sizeof(size_t));
+ }
+
+ sprintf(mallocStr, "MEM: %p %5lu alloc %7lu %4lu --- %s:%u\n", memory, (unsigned long)size, totalMemUsed, blockCount, file, line);
+#if defined(_WIN32)
+ OutputDebugStringA(mallocStr);
+#else
+ DEBUG_TRACE("%s", mallocStr);
+#endif
+
+ return memory;
+}
+
+static void * mg_calloc_ex(size_t count, size_t size, const char * file, unsigned line) {
+
+ void * data = mg_malloc_ex(size*count, file, line);
+ if (data) memset(data, 0, size);
+
+ return data;
+}
+
+static void mg_free_ex(void * memory, const char * file, unsigned line) {
+
+ char mallocStr[256];
+ void * data = (void *)(((char*)memory)-sizeof(size_t));
+ size_t size;
+
+ if (memory) {
+ size = *(size_t*)data;
+ totalMemUsed -= size;
+ blockCount--;
+ sprintf(mallocStr, "MEM: %p %5lu free %7lu %4lu --- %s:%u\n", memory, (unsigned long)size, totalMemUsed, blockCount, file, line);
+#if defined(_WIN32)
+ OutputDebugStringA(mallocStr);
+#else
+ DEBUG_TRACE("%s", mallocStr);
+#endif
+
+ free(data);
+ }
+}
+
+static void * mg_realloc_ex(void * memory, size_t newsize, const char * file, unsigned line) {
+
+ char mallocStr[256];
+ void * data;
+ void * _realloc;
+ size_t oldsize;
+
+ if (newsize) {
+ if (memory) {
+ data = (void *)(((char*)memory)-sizeof(size_t));
+ oldsize = *(size_t*)data;
+ _realloc = realloc(data, newsize+sizeof(size_t));
+ if (_realloc) {
+ data = _realloc;
+ totalMemUsed -= oldsize;
+ sprintf(mallocStr, "MEM: %p %5lu r-free %7lu %4lu --- %s:%u\n", memory, (unsigned long)oldsize, totalMemUsed, blockCount, file, line);
+#if defined(_WIN32)
+ OutputDebugStringA(mallocStr);
+#else
+ DEBUG_TRACE("%s", mallocStr);
+#endif
+ totalMemUsed += newsize;
+ sprintf(mallocStr, "MEM: %p %5lu r-alloc %7lu %4lu --- %s:%u\n", memory, (unsigned long)newsize, totalMemUsed, blockCount, file, line);
+#if defined(_WIN32)
+ OutputDebugStringA(mallocStr);
+#else
+ DEBUG_TRACE("%s", mallocStr);
+#endif
+ *(size_t*)data = newsize;
+ data = (void *)(((char*)data)+sizeof(size_t));
+ } else {
+#if defined(_WIN32)
+ OutputDebugStringA("MEM: realloc failed\n");
+#else
+ DEBUG_TRACE("%s", "MEM: realloc failed\n");
+#endif
+ return _realloc;
+ }
+ } else {
+ data = mg_malloc_ex(newsize, file, line);
+ }
+ } else {
+ data = 0;
+ mg_free_ex(memory, file, line);
+ }
+
+ return data;
+}
+
+#define mg_malloc(a) mg_malloc_ex(a, __FILE__, __LINE__)
+#define mg_calloc(a,b) mg_calloc_ex(a, b, __FILE__, __LINE__)
+#define mg_realloc(a, b) mg_realloc_ex(a, b, __FILE__, __LINE__)
+#define mg_free(a) mg_free_ex(a, __FILE__, __LINE__)
+
+#else
+static __inline void * mg_malloc(size_t a) {return malloc(a);}
+static __inline void * mg_calloc(size_t a, size_t b) {return calloc(a, b);}
+static __inline void * mg_realloc(void * a, size_t b) {return realloc(a, b);}
+static __inline void mg_free(void * a) {free(a);}
+#endif
+
+/* This following lines are just meant as a reminder to use the mg-functions for memory management */
+#ifdef malloc
+ #undef malloc
+#endif
+#ifdef calloc
+ #undef calloc
+#endif
+#ifdef realloc
+ #undef realloc
+#endif
+#ifdef free
+ #undef free
+#endif
+#define malloc DO_NOT_USE_THIS_FUNCTION__USE_mg_malloc
+#define calloc DO_NOT_USE_THIS_FUNCTION__USE_mg_calloc
+#define realloc DO_NOT_USE_THIS_FUNCTION__USE_mg_realloc
+#define free DO_NOT_USE_THIS_FUNCTION__USE_mg_free
+
+
+#define MD5_STATIC static
+#include "md5.inl"
+
+/* Darwin prior to 7.0 and Win32 do not have socklen_t */
+#ifdef NO_SOCKLEN_T
+typedef int socklen_t;
+#endif /* NO_SOCKLEN_T */
+#define _DARWIN_UNLIMITED_SELECT
+
+#define IP_ADDR_STR_LEN 50 /* IPv6 hex string is 46 chars */
+
+#if !defined(MSG_NOSIGNAL)
+#define MSG_NOSIGNAL 0
+#endif
+
+#if !defined(SOMAXCONN)
+#define SOMAXCONN 100
+#endif
+
+#if !defined(PATH_MAX)
+#define PATH_MAX 4096
+#endif
+
+/* Size of the accepted socket queue */
+#if !defined(MGSQLEN)
+#define MGSQLEN 20
+#endif
+
+#if defined(NO_SSL_DL)
+#include <openssl/ssl.h>
+#include <openssl/err.h>
+#else
+/* SSL loaded dynamically from DLL.
+ I put the prototypes here to be independent from OpenSSL source
+ installation. */
+
+typedef struct ssl_st SSL;
+typedef struct ssl_method_st SSL_METHOD;
+typedef struct ssl_ctx_st SSL_CTX;
+
+struct ssl_func {
+ const char *name; /* SSL function name */
+ void (*ptr)(void); /* Function pointer */
+};
+
+#define SSL_free (* (void (*)(SSL *)) ssl_sw[0].ptr)
+#define SSL_accept (* (int (*)(SSL *)) ssl_sw[1].ptr)
+#define SSL_connect (* (int (*)(SSL *)) ssl_sw[2].ptr)
+#define SSL_read (* (int (*)(SSL *, void *, int)) ssl_sw[3].ptr)
+#define SSL_write (* (int (*)(SSL *, const void *,int)) ssl_sw[4].ptr)
+#define SSL_get_error (* (int (*)(SSL *, int)) ssl_sw[5].ptr)
+#define SSL_set_fd (* (int (*)(SSL *, SOCKET)) ssl_sw[6].ptr)
+#define SSL_new (* (SSL * (*)(SSL_CTX *)) ssl_sw[7].ptr)
+#define SSL_CTX_new (* (SSL_CTX * (*)(SSL_METHOD *)) ssl_sw[8].ptr)
+#define SSLv23_server_method (* (SSL_METHOD * (*)(void)) ssl_sw[9].ptr)
+#define SSL_library_init (* (int (*)(void)) ssl_sw[10].ptr)
+#define SSL_CTX_use_PrivateKey_file (* (int (*)(SSL_CTX *, \
+ const char *, int)) ssl_sw[11].ptr)
+#define SSL_CTX_use_certificate_file (* (int (*)(SSL_CTX *, \
+ const char *, int)) ssl_sw[12].ptr)
+#define SSL_CTX_set_default_passwd_cb \
+ (* (void (*)(SSL_CTX *, mg_callback_t)) ssl_sw[13].ptr)
+#define SSL_CTX_free (* (void (*)(SSL_CTX *)) ssl_sw[14].ptr)
+#define SSL_load_error_strings (* (void (*)(void)) ssl_sw[15].ptr)
+#define SSL_CTX_use_certificate_chain_file \
+ (* (int (*)(SSL_CTX *, const char *)) ssl_sw[16].ptr)
+#define SSLv23_client_method (* (SSL_METHOD * (*)(void)) ssl_sw[17].ptr)
+#define SSL_pending (* (int (*)(SSL *)) ssl_sw[18].ptr)
+#define SSL_CTX_set_verify (* (void (*)(SSL_CTX *, int, int)) ssl_sw[19].ptr)
+#define SSL_shutdown (* (int (*)(SSL *)) ssl_sw[20].ptr)
+
+#define CRYPTO_num_locks (* (int (*)(void)) crypto_sw[0].ptr)
+#define CRYPTO_set_locking_callback \
+ (* (void (*)(void (*)(int, int, const char *, int))) crypto_sw[1].ptr)
+#define CRYPTO_set_id_callback \
+ (* (void (*)(unsigned long (*)(void))) crypto_sw[2].ptr)
+#define ERR_get_error (* (unsigned long (*)(void)) crypto_sw[3].ptr)
+#define ERR_error_string (* (char * (*)(unsigned long,char *)) crypto_sw[4].ptr)
+
+/* set_ssl_option() function updates this array.
+ It loads SSL library dynamically and changes NULLs to the actual addresses
+ of respective functions. The macros above (like SSL_connect()) are really
+ just calling these functions indirectly via the pointer. */
+static struct ssl_func ssl_sw[] = {
+ {"SSL_free", NULL},
+ {"SSL_accept", NULL},
+ {"SSL_connect", NULL},
+ {"SSL_read", NULL},
+ {"SSL_write", NULL},
+ {"SSL_get_error", NULL},
+ {"SSL_set_fd", NULL},
+ {"SSL_new", NULL},
+ {"SSL_CTX_new", NULL},
+ {"SSLv23_server_method", NULL},
+ {"SSL_library_init", NULL},
+ {"SSL_CTX_use_PrivateKey_file", NULL},
+ {"SSL_CTX_use_certificate_file",NULL},
+ {"SSL_CTX_set_default_passwd_cb",NULL},
+ {"SSL_CTX_free", NULL},
+ {"SSL_load_error_strings", NULL},
+ {"SSL_CTX_use_certificate_chain_file", NULL},
+ {"SSLv23_client_method", NULL},
+ {"SSL_pending", NULL},
+ {"SSL_CTX_set_verify", NULL},
+ {"SSL_shutdown", NULL},
+ {NULL, NULL}
+};
+
+/* Similar array as ssl_sw. These functions could be located in different
+ lib. */
+#if !defined(NO_SSL)
+static struct ssl_func crypto_sw[] = {
+ {"CRYPTO_num_locks", NULL},
+ {"CRYPTO_set_locking_callback", NULL},
+ {"CRYPTO_set_id_callback", NULL},
+ {"ERR_get_error", NULL},
+ {"ERR_error_string", NULL},
+ {NULL, NULL}
+};
+#endif /* NO_SSL */
+#endif /* NO_SSL_DL */
+
+static const char *month_names[] = {
+ "Jan", "Feb", "Mar", "Apr", "May", "Jun",
+ "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
+};
+
+/* Unified socket address. For IPv6 support, add IPv6 address structure
+ in the union u. */
+union usa {
+ struct sockaddr sa;
+ struct sockaddr_in sin;
+#if defined(USE_IPV6)
+ struct sockaddr_in6 sin6;
+#endif
+};
+
+/* Describes a string (chunk of memory). */
+struct vec {
+ const char *ptr;
+ size_t len;
+};
+
+struct file {
+ int is_directory;
+ time_t modification_time;
+ int64_t size;
+ FILE *fp;
+ const char *membuf; /* Non-NULL if file data is in memory */
+ /* set to 1 if the content is gzipped
+ in which case we need a content-encoding: gzip header */
+ int gzipped;
+};
+#define STRUCT_FILE_INITIALIZER {0, 0, 0, NULL, NULL, 0}
+
+/* Describes listening socket, or socket which was accept()-ed by the master
+ thread and queued for future handling by the worker thread. */
+struct socket {
+ SOCKET sock; /* Listening socket */
+ union usa lsa; /* Local socket address */
+ union usa rsa; /* Remote socket address */
+ unsigned is_ssl:1; /* Is port SSL-ed */
+ unsigned ssl_redir:1; /* Is port supposed to redirect everything to SSL
+ port */
+};
+
+/* NOTE(lsm): this enum shoulds be in sync with the config_options below. */
+enum {
+ CGI_EXTENSIONS, CGI_ENVIRONMENT, PUT_DELETE_PASSWORDS_FILE, CGI_INTERPRETER,
+ PROTECT_URI, AUTHENTICATION_DOMAIN, SSI_EXTENSIONS, THROTTLE,
+ ACCESS_LOG_FILE, ENABLE_DIRECTORY_LISTING, ERROR_LOG_FILE,
+ GLOBAL_PASSWORDS_FILE, INDEX_FILES, ENABLE_KEEP_ALIVE, ACCESS_CONTROL_LIST,
+ EXTRA_MIME_TYPES, LISTENING_PORTS, DOCUMENT_ROOT, SSL_CERTIFICATE,
+ NUM_THREADS, RUN_AS_USER, REWRITE, HIDE_FILES, REQUEST_TIMEOUT,
+ DECODE_URL,
+
+#if defined(USE_LUA)
+ LUA_PRELOAD_FILE, LUA_SCRIPT_EXTENSIONS, LUA_SERVER_PAGE_EXTENSIONS,
+#endif
+#if defined(USE_WEBSOCKET)
+ WEBSOCKET_ROOT,
+#endif
+#if defined(USE_LUA) && defined(USE_WEBSOCKET)
+ LUA_WEBSOCKET_EXTENSIONS,
+#endif
+ ACCESS_CONTROL_ALLOW_ORIGIN, ERROR_PAGES,
+
+ NUM_OPTIONS
+};
+
+/* Config option name, config types, default value */
+static struct mg_option config_options[] = {
+ {"cgi_pattern", CONFIG_TYPE_EXT_PATTERN, "**.cgi$|**.pl$|**.php$"},
+ {"cgi_environment", CONFIG_TYPE_STRING, NULL},
+ {"put_delete_auth_file", CONFIG_TYPE_FILE, NULL},
+ {"cgi_interpreter", CONFIG_TYPE_FILE, NULL},
+ {"protect_uri", CONFIG_TYPE_STRING, NULL},
+ {"authentication_domain", CONFIG_TYPE_STRING, "mydomain.com"},
+ {"ssi_pattern", CONFIG_TYPE_EXT_PATTERN, "**.shtml$|**.shtm$"},
+ {"throttle", CONFIG_TYPE_STRING, NULL},
+ {"access_log_file", CONFIG_TYPE_FILE, NULL},
+ {"enable_directory_listing", CONFIG_TYPE_BOOLEAN, "yes"},
+ {"error_log_file", CONFIG_TYPE_FILE, NULL},
+ {"global_auth_file", CONFIG_TYPE_FILE, NULL},
+ {"index_files", CONFIG_TYPE_STRING,
+#ifdef USE_LUA
+ "index.xhtml,index.html,index.htm,index.lp,index.lsp,index.lua,index.cgi,index.shtml,index.php"},
+#else
+ "index.xhtml,index.html,index.htm,index.cgi,index.shtml,index.php"},
+#endif
+ {"enable_keep_alive", CONFIG_TYPE_BOOLEAN, "no"},
+ {"access_control_list", CONFIG_TYPE_STRING, NULL},
+ {"extra_mime_types", CONFIG_TYPE_STRING, NULL},
+ {"listening_ports", CONFIG_TYPE_STRING, "8080"},
+ {"document_root", CONFIG_TYPE_DIRECTORY, NULL},
+ {"ssl_certificate", CONFIG_TYPE_FILE, NULL},
+ {"num_threads", CONFIG_TYPE_NUMBER, "50"},
+ {"run_as_user", CONFIG_TYPE_STRING, NULL},
+ {"url_rewrite_patterns", CONFIG_TYPE_STRING, NULL},
+ {"hide_files_patterns", CONFIG_TYPE_EXT_PATTERN, NULL},
+ {"request_timeout_ms", CONFIG_TYPE_NUMBER, "30000"},
+ {"decode_url", CONFIG_TYPE_BOOLEAN, "yes"},
+
+#if defined(USE_LUA)
+ {"lua_preload_file", CONFIG_TYPE_FILE, NULL},
+ {"lua_script_pattern", CONFIG_TYPE_EXT_PATTERN, "**.lua$"},
+ {"lua_server_page_pattern", CONFIG_TYPE_EXT_PATTERN, "**.lp$|**.lsp$"},
+#endif
+#if defined(USE_WEBSOCKET)
+ {"websocket_root", CONFIG_TYPE_DIRECTORY, NULL},
+#endif
+#if defined(USE_LUA) && defined(USE_WEBSOCKET)
+ {"lua_websocket_pattern", CONFIG_TYPE_EXT_PATTERN, "**.lua$"},
+#endif
+ {"access_control_allow_origin", CONFIG_TYPE_STRING, "*"},
+ {"error_pages", CONFIG_TYPE_DIRECTORY, NULL},
+
+ {NULL, CONFIG_TYPE_UNKNOWN, NULL}
+};
+
+struct mg_request_handler_info {
+ char *uri;
+ size_t uri_len;
+ mg_request_handler handler;
+
+ void *cbdata;
+ struct mg_request_handler_info *next;
+};
+
+struct mg_context {
+ volatile int stop_flag; /* Should we stop event loop */
+ SSL_CTX *ssl_ctx; /* SSL context */
+ char *config[NUM_OPTIONS]; /* Civetweb configuration parameters */
+ struct mg_callbacks callbacks; /* User-defined callback function */
+ void *user_data; /* User-defined data */
+ int context_type; /* 1 = server context, 2 = client context */
+
+ struct socket *listening_sockets;
+ in_port_t *listening_ports;
+ int num_listening_sockets;
+
+ volatile int num_threads; /* Number of threads */
+ pthread_mutex_t thread_mutex; /* Protects (max|num)_threads */
+ pthread_cond_t thread_cond; /* Condvar for tracking workers terminations */
+
+ struct socket queue[MGSQLEN]; /* Accepted sockets */
+ volatile int sq_head; /* Head of the socket queue */
+ volatile int sq_tail; /* Tail of the socket queue */
+ pthread_cond_t sq_full; /* Signaled when socket is produced */
+ pthread_cond_t sq_empty; /* Signaled when socket is consumed */
+ pthread_t masterthreadid; /* The master thread ID */
+ int workerthreadcount; /* The amount of worker threads. */
+ pthread_t *workerthreadids; /* The worker thread IDs */
+
+ unsigned long start_time; /* Server start time, used for authentication */
+ pthread_mutex_t nonce_mutex; /* Protects nonce_count */
+ unsigned long nonce_count; /* Used nonces, used for authentication */
+
+ char *systemName; /* What operating system is running */
+
+ /* linked list of uri handlers */
+ struct mg_request_handler_info *request_handlers;
+
+#if defined(USE_LUA) && defined(USE_WEBSOCKET)
+ /* linked list of shared lua websockets */
+ struct mg_shared_lua_websocket_list *shared_lua_websockets;
+#endif
+
+#ifdef USE_TIMERS
+ struct ttimers * timers;
+#endif
+};
+
+struct mg_connection {
+ struct mg_request_info request_info;
+ struct mg_context *ctx;
+ SSL *ssl; /* SSL descriptor */
+ SSL_CTX *client_ssl_ctx; /* SSL context for client connections */
+ struct socket client; /* Connected client */
+ time_t birth_time; /* Time when request was received */
+ int64_t num_bytes_sent; /* Total bytes sent to client */
+ int64_t content_len; /* Content-Length header value */
+ int64_t consumed_content; /* How many bytes of content have been read */
+ char *buf; /* Buffer for received data */
+ char *path_info; /* PATH_INFO part of the URL */
+ int must_close; /* 1 if connection must be closed */
+ int in_error_handler; /* 1 if in handler for user defined error pages */
+ int buf_size; /* Buffer size */
+ int request_len; /* Size of the request + headers in a buffer */
+ int data_len; /* Total size of data in a buffer */
+ int status_code; /* HTTP reply status code, e.g. 200 */
+ int throttle; /* Throttling, bytes/sec. <= 0 means no throttle */
+ time_t last_throttle_time; /* Last time throttled data was sent */
+ int64_t last_throttle_bytes; /* Bytes sent this second */
+ pthread_mutex_t mutex; /* Used by mg_lock_connection/mg_unlock_connection to ensure atomic transmissions for websockets */
+#if defined(USE_LUA) && defined(USE_WEBSOCKET)
+ void * lua_websocket_state; /* Lua_State for a websocket connection */
+#endif
+};
+
+static pthread_key_t sTlsKey; /* Thread local storage index */
+static int sTlsInit = 0;
+
+struct mg_workerTLS {
+ int is_master;
+#if defined(_WIN32) && !defined(__SYMBIAN32__)
+ HANDLE pthread_cond_helper_mutex;
+#endif
+};
+
+/* Directory entry */
+struct de {
+ struct mg_connection *conn;
+ char *file_name;
+ struct file file;
+};
+
+#if defined(USE_WEBSOCKET)
+static int is_websocket_protocol(const struct mg_connection *conn);
+#else
+#define is_websocket_protocol(conn) (0)
+#endif
+
+int mg_atomic_inc(volatile int * addr)
+{
+ int ret;
+#if defined(_WIN32) && !defined(__SYMBIAN32__)
+ ret = InterlockedIncrement((volatile unsigned int *) addr);
+#elif defined(__GNUC__)
+ ret = __sync_add_and_fetch(addr, 1);
+#else
+ ret = (++(*addr));
+#endif
+ return ret;
+}
+
+int mg_atomic_dec(volatile int * addr)
+{
+ int ret;
+#if defined(_WIN32) && !defined(__SYMBIAN32__)
+ ret = InterlockedDecrement((volatile unsigned int *) addr);
+#elif defined(__GNUC__)
+ ret = __sync_sub_and_fetch(addr, 1);
+#else
+ ret = (--(*addr));
+#endif
+ return ret;
+}
+
+#if !defined(NO_THREAD_NAME)
+#if defined(_WIN32) && defined(_MSC_VER)
+/* Set the thread name for debugging purposes in Visual Studio
+ http://msdn.microsoft.com/en-us/library/xcb2z8hs.aspx
+*/
+#pragma pack(push,8)
+typedef struct tagTHREADNAME_INFO
+{
+ DWORD dwType; /* Must be 0x1000. */
+ LPCSTR szName; /* Pointer to name (in user addr space). */
+ DWORD dwThreadID; /* Thread ID (-1=caller thread). */
+ DWORD dwFlags; /* Reserved for future use, must be zero. */
+} THREADNAME_INFO;
+#pragma pack(pop)
+#elif defined(__linux__)
+#include <sys/prctl.h>
+#endif
+
+void mg_set_thread_name(const char* name)
+{
+ char threadName[16]; /* Max. thread length in Linux/OSX/.. */
+
+ if (snprintf(threadName, sizeof(threadName), "civetweb-%s", name)<0) return;
+ threadName[sizeof(threadName)-1] = 0;
+
+#if defined(_WIN32)
+#if defined(_MSC_VER)
+ /* Windows and Visual Studio Compiler */
+ __try
+ {
+ THREADNAME_INFO info;
+ info.dwType = 0x1000;
+ info.szName = threadName;
+ info.dwThreadID = -1;
+ info.dwFlags = 0;
+
+ RaiseException(0x406D1388, 0, sizeof(info)/sizeof(ULONG_PTR), (ULONG_PTR*)&info);
+ }
+ __except(EXCEPTION_EXECUTE_HANDLER)
+ {
+ }
+#elif defined(__MINGW32__)
+ /* No option known to set thread name for MinGW */
+#endif
+#elif defined(__linux__)
+ /* Linux */
+ (void)prctl(PR_SET_NAME,threadName,0,0,0);
+#elif defined(__APPLE__) || defined(__MACH__)
+ /* OS X (TODO: test) */
+ (void)pthread_setname_np(threadName);
+#elif defined(BSD) || defined(__FreeBSD__) || defined(__OpenBSD__)
+ /* BSD (TODO: test) */
+ pthread_set_name_np(pthread_self(), threadName);
+#else
+ /* POSIX */
+ (void)pthread_setname_np(pthread_self(), threadName);
+#endif
+}
+#else /* !defined(NO_THREAD_NAME) */
+void mg_set_thread_name(const char* threadName) {}
+#endif
+
+#if defined(MG_LEGACY_INTERFACE)
+const char **mg_get_valid_option_names(void)
+{
+ static const char * data[2 * sizeof(config_options) / sizeof(config_options[0])] = {0};
+ int i;
+
+ for (i=0; config_options[i].name != NULL; i++) {
+ data[i * 2] = config_options[i].name;
+ data[i * 2 + 1] = config_options[i].default_value;
+ }
+
+ return data;
+}
+#endif
+
+const struct mg_option *mg_get_valid_options(void)
+{
+ return config_options;
+}
+
+
+static int is_file_in_memory(struct mg_connection *conn, const char *path,
+ struct file *filep)
+{
+ size_t size = 0;
+ if ((filep->membuf = conn->ctx->callbacks.open_file == NULL ? NULL :
+ conn->ctx->callbacks.open_file(conn, path, &size)) != NULL) {
+ /* NOTE: override filep->size only on success. Otherwise, it might
+ break constructs like if (!mg_stat() || !mg_fopen()) ... */
+ filep->size = size;
+ }
+ return filep->membuf != NULL;
+}
+
+static int is_file_opened(const struct file *filep)
+{
+ return filep->membuf != NULL || filep->fp != NULL;
+}
+
+static int mg_fopen(struct mg_connection *conn, const char *path,
+ const char *mode, struct file *filep)
+{
+ if (!is_file_in_memory(conn, path, filep)) {
+#ifdef _WIN32
+ wchar_t wbuf[PATH_MAX], wmode[20];
+ to_unicode(path, wbuf, ARRAY_SIZE(wbuf));
+ MultiByteToWideChar(CP_UTF8, 0, mode, -1, wmode, ARRAY_SIZE(wmode));
+ filep->fp = _wfopen(wbuf, wmode);
+#else
+ filep->fp = fopen(path, mode);
+#endif
+ }
+
+ return is_file_opened(filep);
+}
+
+static void mg_fclose(struct file *filep)
+{
+ if (filep != NULL && filep->fp != NULL) {
+ fclose(filep->fp);
+ }
+}
+
+static void mg_strlcpy(register char *dst, register const char *src, size_t n)
+{
+ for (; *src != '\0' && n > 1; n--) {
+ *dst++ = *src++;
+ }
+ *dst = '\0';
+}
+
+static int lowercase(const char *s)
+{
+ return tolower(* (const unsigned char *) s);
+}
+
+int mg_strncasecmp(const char *s1, const char *s2, size_t len)
+{
+ int diff = 0;
+
+ if (len > 0)
+ do {
+ diff = lowercase(s1++) - lowercase(s2++);
+ } while (diff == 0 && s1[-1] != '\0' && --len > 0);
+
+ return diff;
+}
+
+static int mg_strcasecmp(const char *s1, const char *s2)
+{
+ int diff;
+
+ do {
+ diff = lowercase(s1++) - lowercase(s2++);
+ } while (diff == 0 && s1[-1] != '\0');
+
+ return diff;
+}
+
+static char * mg_strndup(const char *ptr, size_t len)
+{
+ char *p;
+
+ if ((p = (char *) mg_malloc(len + 1)) != NULL) {
+ mg_strlcpy(p, ptr, len + 1);
+ }
+
+ return p;
+}
+
+static char * mg_strdup(const char *str)
+{
+ return mg_strndup(str, strlen(str));
+}
+
+static const char *mg_strcasestr(const char *big_str, const char *small_str)
+{
+ int i, big_len = (int)strlen(big_str), small_len = (int)strlen(small_str);
+
+ for (i = 0; i <= big_len - small_len; i++) {
+ if (mg_strncasecmp(big_str + i, small_str, small_len) == 0) {
+ return big_str + i;
+ }
+ }
+
+ return NULL;
+}
+
+/* Like snprintf(), but never returns negative value, or a value
+ that is larger than a supplied buffer.
+ Thanks to Adam Zeldis to pointing snprintf()-caused vulnerability
+ in his audit report. */
+static int mg_vsnprintf(struct mg_connection *conn, char *buf, size_t buflen,
+ const char *fmt, va_list ap)
+{
+ int n;
+
+ if (buflen == 0)
+ return 0;
+
+ n = vsnprintf(buf, buflen, fmt, ap);
+
+ if (n < 0) {
+ mg_cry(conn, "vsnprintf error");
+ n = 0;
+ } else if (n >= (int) buflen) {
+ mg_cry(conn, "truncating vsnprintf buffer: [%.*s]",
+ n > 200 ? 200 : n, buf);
+ n = (int) buflen - 1;
+ }
+ buf[n] = '\0';
+
+ return n;
+}
+
+static int mg_snprintf(struct mg_connection *conn, char *buf, size_t buflen,
+ PRINTF_FORMAT_STRING(const char *fmt), ...)
+PRINTF_ARGS(4, 5);
+
+static int mg_snprintf(struct mg_connection *conn, char *buf, size_t buflen,
+ const char *fmt, ...)
+{
+ va_list ap;
+ int n;
+
+ va_start(ap, fmt);
+ n = mg_vsnprintf(conn, buf, buflen, fmt, ap);
+ va_end(ap);
+
+ return n;
+}
+
+static int get_option_index(const char *name)
+{
+ int i;
+
+ for (i = 0; config_options[i].name != NULL; i++) {
+ if (strcmp(config_options[i].name, name) == 0) {
+ return i;
+ }
+ }
+ return -1;
+}
+
+const char *mg_get_option(const struct mg_context *ctx, const char *name)
+{
+ int i;
+ if ((i = get_option_index(name)) == -1) {
+ return NULL;
+ } else if (ctx->config[i] == NULL) {
+ return "";
+ } else {
+ return ctx->config[i];
+ }
+}
+
+struct mg_context *mg_get_context(struct mg_connection * conn)
+{
+ return (conn == NULL) ? (struct mg_context *)NULL : (conn->ctx);
+}
+
+void *mg_get_user_data(struct mg_context *ctx)
+{
+ return (ctx == NULL) ? NULL : ctx->user_data;
+}
+
+size_t mg_get_ports(const struct mg_context *ctx, size_t size, int* ports, int* ssl)
+{
+ size_t i;
+ for (i = 0; i < size && i < (size_t)ctx->num_listening_sockets; i++)
+ {
+ ssl[i] = ctx->listening_sockets[i].is_ssl;
+ ports[i] = ctx->listening_ports[i];
+ }
+ return i;
+}
+
+static void sockaddr_to_string(char *buf, size_t len,
+ const union usa *usa)
+{
+ buf[0] = '\0';
+#if defined(USE_IPV6)
+ inet_ntop(usa->sa.sa_family, usa->sa.sa_family == AF_INET ?
+ (void *) &usa->sin.sin_addr :
+ (void *) &usa->sin6.sin6_addr, buf, len);
+#elif defined(_WIN32)
+ /* Only Windows Vista (and newer) have inet_ntop() */
+ mg_strlcpy(buf, inet_ntoa(usa->sin.sin_addr), len);
+#else
+ inet_ntop(usa->sa.sa_family, (void *) &usa->sin.sin_addr, buf, len);
+#endif
+}
+
+/* Convert time_t to a string. According to RFC2616, Sec 14.18, this must be included in all responses other than 100, 101, 5xx. */
+static void gmt_time_string(char *buf, size_t buf_len, time_t *t)
+{
+ struct tm *tm;
+
+ tm = gmtime(t);
+ if (tm != NULL) {
+ strftime(buf, buf_len, "%a, %d %b %Y %H:%M:%S GMT", tm);
+ } else {
+ mg_strlcpy(buf, "Thu, 01 Jan 1970 00:00:00 GMT", buf_len);
+ buf[buf_len - 1] = '\0';
+ }
+}
+
+/* Print error message to the opened error log stream. */
+void mg_cry(struct mg_connection *conn, const char *fmt, ...)
+{
+ char buf[MG_BUF_LEN], src_addr[IP_ADDR_STR_LEN];
+ va_list ap;
+ FILE *fp;
+ time_t timestamp;
+
+ va_start(ap, fmt);
+ IGNORE_UNUSED_RESULT(vsnprintf(buf, sizeof(buf), fmt, ap));
+ va_end(ap);
+
+ /* Do not lock when getting the callback value, here and below.
+ I suppose this is fine, since function cannot disappear in the
+ same way string option can. */
+ if (conn->ctx->callbacks.log_message == NULL ||
+ conn->ctx->callbacks.log_message(conn, buf) == 0) {
+ fp = conn->ctx->config[ERROR_LOG_FILE] == NULL ? NULL :
+ fopen(conn->ctx->config[ERROR_LOG_FILE], "a+");
+
+ if (fp != NULL) {
+ flockfile(fp);
+ timestamp = time(NULL);
+
+ sockaddr_to_string(src_addr, sizeof(src_addr), &conn->client.rsa);
+ fprintf(fp, "[%010lu] [error] [client %s] ", (unsigned long) timestamp,
+ src_addr);
+
+ if (conn->request_info.request_method != NULL) {
+ fprintf(fp, "%s %s: ", conn->request_info.request_method,
+ conn->request_info.uri);
+ }
+
+ fprintf(fp, "%s", buf);
+ fputc('\n', fp);
+ funlockfile(fp);
+ fclose(fp);
+ }
+ }
+}
+
+/* Return fake connection structure. Used for logging, if connection
+ is not applicable at the moment of logging. */
+static struct mg_connection *fc(struct mg_context *ctx)
+{
+ static struct mg_connection fake_connection;
+ fake_connection.ctx = ctx;
+ return &fake_connection;
+}
+
+const char *mg_version(void)
+{
+ return CIVETWEB_VERSION;
+}
+
+struct mg_request_info *mg_get_request_info(struct mg_connection *conn)
+{
+ return &conn->request_info;
+}
+
+/* Skip the characters until one of the delimiters characters found.
+ 0-terminate resulting word. Skip the delimiter and following whitespaces.
+ Advance pointer to buffer to the next word. Return found 0-terminated word.
+ Delimiters can be quoted with quotechar. */
+static char *skip_quoted(char **buf, const char *delimiters,
+ const char *whitespace, char quotechar)
+{
+ char *p, *begin_word, *end_word, *end_whitespace;
+
+ begin_word = *buf;
+ end_word = begin_word + strcspn(begin_word, delimiters);
+
+ /* Check for quotechar */
+ if (end_word > begin_word) {
+ p = end_word - 1;
+ while (*p == quotechar) {
+ /* TODO (bel): it seems this code is never reached, so quotechar is actually
+ not needed - check if this code may be droped */
+
+ /* If there is anything beyond end_word, copy it */
+ if (*end_word == '\0') {
+ *p = '\0';
+ break;
+ } else {
+ size_t end_off = strcspn(end_word + 1, delimiters);
+ memmove (p, end_word, end_off + 1);
+ p += end_off; /* p must correspond to end_word - 1 */
+ end_word += end_off + 1;
+ }
+ }
+ for (p++; p < end_word; p++) {
+ *p = '\0';
+ }
+ }
+
+ if (*end_word == '\0') {
+ *buf = end_word;
+ } else {
+ end_whitespace = end_word + 1 + strspn(end_word + 1, whitespace);
+
+ for (p = end_word; p < end_whitespace; p++) {
+ *p = '\0';
+ }
+
+ *buf = end_whitespace;
+ }
+
+ return begin_word;
+}
+
+/* Simplified version of skip_quoted without quote char
+ and whitespace == delimiters */
+static char *skip(char **buf, const char *delimiters)
+{
+ return skip_quoted(buf, delimiters, delimiters, 0);
+}
+
+
+/* Return HTTP header value, or NULL if not found. */
+static const char *get_header(const struct mg_request_info *ri,
+ const char *name)
+{
+ int i;
+
+ for (i = 0; i < ri->num_headers; i++)
+ if (!mg_strcasecmp(name, ri->http_headers[i].name))
+ return ri->http_headers[i].value;
+
+ return NULL;
+}
+
+const char *mg_get_header(const struct mg_connection *conn, const char *name)
+{
+ return get_header(&conn->request_info, name);
+}
+
+/* A helper function for traversing a comma separated list of values.
+ It returns a list pointer shifted to the next value, or NULL if the end
+ of the list found.
+ Value is stored in val vector. If value has form "x=y", then eq_val
+ vector is initialized to point to the "y" part, and val vector length
+ is adjusted to point only to "x". */
+static const char *next_option(const char *list, struct vec *val,
+ struct vec *eq_val)
+{
+ if (list == NULL || *list == '\0') {
+ /* End of the list */
+ list = NULL;
+ } else {
+ val->ptr = list;
+ if ((list = strchr(val->ptr, ',')) != NULL) {
+ /* Comma found. Store length and shift the list ptr */
+ val->len = list - val->ptr;
+ list++;
+ } else {
+ /* This value is the last one */
+ list = val->ptr + strlen(val->ptr);
+ val->len = list - val->ptr;
+ }
+
+ if (eq_val != NULL) {
+ /* Value has form "x=y", adjust pointers and lengths
+ so that val points to "x", and eq_val points to "y". */
+ eq_val->len = 0;
+ eq_val->ptr = (const char *) memchr(val->ptr, '=', val->len);
+ if (eq_val->ptr != NULL) {
+ eq_val->ptr++; /* Skip over '=' character */
+ eq_val->len = val->ptr + val->len - eq_val->ptr;
+ val->len = (eq_val->ptr - val->ptr) - 1;
+ }
+ }
+ }
+
+ return list;
+}
+
+/* Perform case-insensitive match of string against pattern */
+static int match_prefix(const char *pattern, int pattern_len, const char *str)
+{
+ const char *or_str;
+ int i, j, len, res;
+
+ if ((or_str = (const char *) memchr(pattern, '|', pattern_len)) != NULL) {
+ res = match_prefix(pattern, (int)(or_str - pattern), str);
+ return res > 0 ? res :
+ match_prefix(or_str + 1, (int)((pattern + pattern_len) - (or_str + 1)), str);
+ }
+
+ i = j = 0;
+ for (; i < pattern_len; i++, j++) {
+ if (pattern[i] == '?' && str[j] != '\0') {
+ continue;
+ } else if (pattern[i] == '$') {
+ return str[j] == '\0' ? j : -1;
+ } else if (pattern[i] == '*') {
+ i++;
+ if (pattern[i] == '*') {
+ i++;
+ len = (int) strlen(str + j);
+ } else {
+ len = (int) strcspn(str + j, "/");
+ }
+ if (i == pattern_len) {
+ return j + len;
+ }
+ do {
+ res = match_prefix(pattern + i, pattern_len - i, str + j + len);
+ } while (res == -1 && len-- > 0);
+ return res == -1 ? -1 : j + res + len;
+ } else if (lowercase(&pattern[i]) != lowercase(&str[j])) {
+ return -1;
+ }
+ }
+ return j;
+}
+
+/* HTTP 1.1 assumes keep alive if "Connection:" header is not set
+ This function must tolerate situations when connection info is not
+ set up, for example if request parsing failed. */
+static int should_keep_alive(const struct mg_connection *conn)
+{
+ const char *http_version = conn->request_info.http_version;
+ const char *header = mg_get_header(conn, "Connection");
+ if (conn->must_close ||
+ conn->status_code == 401 ||
+ mg_strcasecmp(conn->ctx->config[ENABLE_KEEP_ALIVE], "yes") != 0 ||
+ (header != NULL && mg_strcasecmp(header, "keep-alive") != 0) ||
+ (header == NULL && http_version && 0!=strcmp(http_version, "1.1"))) {
+ return 0;
+ }
+ return 1;
+}
+
+static int should_decode_url(const struct mg_connection *conn)
+{
+ return (mg_strcasecmp(conn->ctx->config[DECODE_URL], "yes") == 0);
+}
+
+static const char *suggest_connection_header(const struct mg_connection *conn)
+{
+ return should_keep_alive(conn) ? "keep-alive" : "close";
+}
+
+static void handle_file_based_request(struct mg_connection *conn, const char *path, struct file *filep);
+static int mg_stat(struct mg_connection *conn, const char *path, struct file *filep);
+
+static const char *mg_get_response_code_text(int response_code, struct mg_connection *conn)
+{
+ switch (response_code)
+ {
+ /* RFC2616 Section 10.1 - Informational 1xx */
+ case 100: return "Continue"; /* RFC2616 Section 10.1.1 */
+ case 101: return "Switching Protocols"; /* RFC2616 Section 10.1.2 */
+ case 102: return "Processing"; /* RFC2518 Section 10.1 */
+
+ /* RFC2616 Section 10.2 - Successful 2xx */
+ case 200: return "OK"; /* RFC2616 Section 10.2.1 */
+ case 201: return "Created"; /* RFC2616 Section 10.2.2 */
+ case 202: return "Accepted"; /* RFC2616 Section 10.2.3 */
+ case 203: return "Non-Authoritative Information"; /* RFC2616 Section 10.2.4 */
+ case 204: return "No Content"; /* RFC2616 Section 10.2.5 */
+ case 205: return "Reset Content"; /* RFC2616 Section 10.2.6 */
+ case 206: return "Partial Content"; /* RFC2616 Section 10.2.7 */
+ case 207: return "Multi-Status"; /* RFC2518 Section 10.2, RFC4918 Section 11.1 */
+
+ /* RFC2616 Section 10.3 - Redirection 3xx */
+ case 300: return "Multiple Choices"; /* RFC2616 Section 10.3.1 */
+ case 301: return "Moved Permanently"; /* RFC2616 Section 10.3.2 */
+ case 302: return "Found"; /* RFC2616 Section 10.3.3 */
+ case 303: return "See Other"; /* RFC2616 Section 10.3.4 */
+ case 304: return "Not Modified"; /* RFC2616 Section 10.3.5 */
+ case 305: return "Use Proxy"; /* RFC2616 Section 10.3.6 */
+ case 307: return "Temporary Redirect"; /* RFC2616 Section 10.3.8 */
+
+ /* RFC2616 Section 10.4 - Client Error 4xx */
+ case 400: return "Bad Request"; /* RFC2616 Section 10.4.1 */
+ case 401: return "Unauthorized"; /* RFC2616 Section 10.4.2 */
+ case 402: return "Payment Required"; /* RFC2616 Section 10.4.3 */
+ case 403: return "Forbidden"; /* RFC2616 Section 10.4.4 */
+ case 404: return "Not Found"; /* RFC2616 Section 10.4.5 */
+ case 405: return "Method Not Allowed"; /* RFC2616 Section 10.4.6 */
+ case 406: return "Not Acceptable"; /* RFC2616 Section 10.4.7 */
+ case 407: return "Proxy Authentication Required"; /* RFC2616 Section 10.4.8 */
+ case 408: return "Request Time-out"; /* RFC2616 Section 10.4.9 */
+ case 409: return "Conflict"; /* RFC2616 Section 10.4.10 */
+ case 410: return "Gone"; /* RFC2616 Section 10.4.11 */
+ case 411: return "Length Required"; /* RFC2616 Section 10.4.12 */
+ case 412: return "Precondition Failed"; /* RFC2616 Section 10.4.13 */
+ case 413: return "Request Entity Too Large"; /* RFC2616 Section 10.4.14 */
+ case 414: return "Request-URI Too Large"; /* RFC2616 Section 10.4.15 */
+ case 415: return "Unsupported Media Type"; /* RFC2616 Section 10.4.16 */
+ case 416: return "Requested range not satisfiable"; /* RFC2616 Section 10.4.17 */
+ case 417: return "Expectation Failed"; /* RFC2616 Section 10.4.18 */
+ case 422: return "Unproccessable entity"; /* RFC2518 Section 10.3, RFC4918 Section 11.2 */
+ case 423: return "Locked"; /* RFC2518 Section 10.4, RFC4918 Section 11.3 */
+ case 424: return "Failed Dependency"; /* RFC2518 Section 10.5, RFC4918 Section 11.4 */
+ case 428: return "Precondition Required"; /* RFC 6585, Section 3 */
+ case 429: return "Too Many Requests"; /* RFC 6585, Section 4 */
+ case 431: return "Request Header Fields Too Large"; /* RFC 6585, Section 5 */
+
+ /* RFC2616 Section 10.5 - Server Error 5xx */
+ case 500: return "Internal Server Error"; /* RFC2616 Section 10.5.1 */
+ case 501: return "Not Implemented"; /* RFC2616 Section 10.5.2 */
+ case 502: return "Bad Gateway"; /* RFC2616 Section 10.5.3 */
+ case 503: return "Service Unavailable"; /* RFC2616 Section 10.5.4 */
+ case 504: return "Gateway Time-out"; /* RFC2616 Section 10.5.5 */
+ case 505: return "HTTP Version not supported"; /* RFC2616 Section 10.5.6 */
+ case 507: return "Insufficient Storage"; /* RFC2518 Section 10.6, , RFC4918 Section 11.5 */
+ case 511: return "Network Authentication Required"; /* RFC 6585, Section 6 */
+
+ /* Other RFCs */
+ case 426: return "Upgrade Required"; /* RFC 2817 */
+
+ /* Return codes from non normative RFCs: */
+ /* Informative and experimental RFCs, "de facto" standards due to common use, ... */
+ case 208: return "Already Reported"; /* RFC5842 Section 7.1 */
+ case 226: return "IM used"; /* RFC3229 Section 10.4.1 */
+ case 308: return "Permanent Redirect"; /* RFC7238 Section 3 */
+ case 418: return "I am a teapot"; /* RFC2324 Section 2.3.2 */
+ case 419: return "Authentication Timeout"; /* common use */
+ case 451: return "Unavailable For Legal Reasons"; /* draft-tbray-http-legally-restricted-status-05, Section 3 */
+ case 506: return "Variant Also Negotiates"; /* RFC 2295, Section 8.1 */
+ case 508: return "Loop Detected"; /* RFC5842 Section 7.1 */
+ case 510: return "Not Extended"; /* RFC 2774, Section 7 */
+
+ default:
+ /* This error code is unknown. This should not happen. */
+ if (conn) {
+ mg_cry(conn, "Unknown HTTP response code: %u", response_code);
+ }
+
+ /* Return at least a category according to RFC 2616 Section 10. */
+ if (response_code>=100 && response_code<200) {
+ /* Unknown informational status code */
+ return "Information";
+ }
+ if (response_code>=200 && response_code<300) {
+ /* Unknown success code */
+ return "Success";
+ }
+ if (response_code>=300 && response_code<400) {
+ /* Unknown redirection code */
+ return "Redirection";
+ }
+ if (response_code>=400 && response_code<500) {
+ /* Unknown request error code */
+ return "Client Error";
+ }
+ if (response_code>=500 && response_code<600) {
+ /* Unknown server error code */
+ return "Server Error";
+ }
+
+ /* Response code not even within reasonable range */
+ return "";
+ }
+}
+
+
+static void send_http_error(struct mg_connection *, int, const char *,
+ PRINTF_FORMAT_STRING(const char *fmt), ...)
+PRINTF_ARGS(4, 5);
+
+
+static void send_http_error(struct mg_connection *conn, int status,
+ const char *reason, const char *fmt, ...)
+{
+ char buf[MG_BUF_LEN];
+ va_list ap;
+ int len = 0, i, page_handler_found, scope;
+ char date[64];
+ time_t curtime = time(NULL);
+ const char *error_handler = NULL;
+ struct file error_page_file = STRUCT_FILE_INITIALIZER;
+ const char *error_page_file_ext, *tstr;
+
+ if (!reason) {
+ reason = mg_get_response_code_text(status, conn);
+ }
+
+ conn->status_code = status;
+ if (conn->in_error_handler ||
+ conn->ctx->callbacks.http_error == NULL ||
+ conn->ctx->callbacks.http_error(conn, status)) {
+
+ if (!conn->in_error_handler) {
+ /* Send user defined error pages, if defined */
+ error_handler = conn->ctx->config[ERROR_PAGES];
+ error_page_file_ext = conn->ctx->config[INDEX_FILES];
+ page_handler_found = 0;
+ if (error_handler != NULL) {
+ for (scope=1; (scope<=3) && !page_handler_found; scope++) {
+ switch (scope) {
+ case 1:
+ len = mg_snprintf(conn, buf, sizeof(buf)-32, "%serror%03u.", error_handler, status);
+ break;
+ case 2:
+ len = mg_snprintf(conn, buf, sizeof(buf)-32, "%serror%01uxx.", error_handler, status/100);
+ break;
+ default:
+ len = mg_snprintf(conn, buf, sizeof(buf)-32, "%serror.", error_handler);
+ break;
+ }
+ tstr = strchr(error_page_file_ext, '.');
+ while (tstr) {
+ for (i=1; i<32 && tstr[i]!=0 && tstr[i]!=','; i++) buf[len+i-1]=tstr[i];
+ buf[len+i-1]=0;
+ if (mg_stat(conn, buf, &error_page_file)) {
+ page_handler_found = 1;
+ break;
+ }
+ tstr = strchr(tstr+i, '.');
+ }
+ }
+ }
+
+ if (page_handler_found) {
+ conn->in_error_handler = 1;
+ handle_file_based_request(conn, buf, &error_page_file);
+ conn->in_error_handler = 0;
+ return;
+ }
+ }
+
+ buf[0] = '\0';
+ gmt_time_string(date, sizeof(date), &curtime);
+
+ /* Errors 1xx, 204 and 304 MUST NOT send a body */
+ if (status > 199 && status != 204 && status != 304) {
+ len = mg_snprintf(conn, buf, sizeof(buf)-1, "Error %d: %s", status, reason);
+ buf[len] = '\n';
+ len++;
+ buf[len] = 0;
+
+ va_start(ap, fmt);
+ len += mg_vsnprintf(conn, buf + len, sizeof(buf) - len, fmt, ap);
+ va_end(ap);
+ }
+ DEBUG_TRACE("[%s]", buf);
+
+ mg_printf(conn, "HTTP/1.1 %d %s\r\n"
+ "Content-Length: %d\r\n"
+ "Date: %s\r\n"
+ "Connection: %s\r\n\r\n",
+ status, reason, len, date,
+ suggest_connection_header(conn));
+ conn->num_bytes_sent += mg_printf(conn, "%s", buf);
+ }
+}
+
+#if defined(_WIN32) && !defined(__SYMBIAN32__)
+static int pthread_mutex_init(pthread_mutex_t *mutex, void *unused)
+{
+ (void) unused;
+ *mutex = CreateMutex(NULL, FALSE, NULL);
+ return *mutex == NULL ? -1 : 0;
+}
+
+static int pthread_mutex_destroy(pthread_mutex_t *mutex)
+{
+ return CloseHandle(*mutex) == 0 ? -1 : 0;
+}
+
+static int pthread_mutex_lock(pthread_mutex_t *mutex)
+{
+ return WaitForSingleObject(*mutex, INFINITE) == WAIT_OBJECT_0 ? 0 : -1;
+}
+
+static int pthread_mutex_trylock(pthread_mutex_t *mutex)
+{
+ switch (WaitForSingleObject(*mutex, 0)) {
+ case WAIT_OBJECT_0:
+ return 0;
+ case WAIT_TIMEOUT:
+ return -2; /* EBUSY */
+ }
+ return -1;
+}
+
+static int pthread_mutex_unlock(pthread_mutex_t *mutex)
+{
+ return ReleaseMutex(*mutex) == 0 ? -1 : 0;
+}
+
+#ifndef WIN_PTHREADS_TIME_H
+static int clock_gettime(clockid_t clk_id, struct timespec *tp)
+{
+ FILETIME ft;
+ ULARGE_INTEGER li;
+ BOOL ok = FALSE;
+ double d;
+ static double perfcnt_per_sec = 0.0;
+
+ if (tp) {
+ if (clk_id == CLOCK_REALTIME) {
+ GetSystemTimeAsFileTime(&ft);
+ li.LowPart = ft.dwLowDateTime;
+ li.HighPart = ft.dwHighDateTime;
+ li.QuadPart -= 116444736000000000; /* 1.1.1970 in filedate */
+ tp->tv_sec = (time_t)(li.QuadPart / 10000000);
+ tp->tv_nsec = (long)(li.QuadPart % 10000000) * 100;
+ ok = TRUE;
+ } else if (clk_id == CLOCK_MONOTONIC) {
+ if (perfcnt_per_sec == 0.0) {
+ QueryPerformanceFrequency((LARGE_INTEGER *) &li);
+ perfcnt_per_sec = 1.0 / li.QuadPart;
+ }
+ if (perfcnt_per_sec != 0.0) {
+ QueryPerformanceCounter((LARGE_INTEGER *) &li);
+ d = li.QuadPart * perfcnt_per_sec;
+ tp->tv_sec = (time_t)d;
+ d -= tp->tv_sec;
+ tp->tv_nsec = (long)(d*1.0E9);
+ ok = TRUE;
+ }
+ }
+ }
+
+ return ok ? 0 : -1;
+}
+#endif
+
+static int pthread_cond_init(pthread_cond_t *cv, const void *unused)
+{
+ (void) unused;
+ InitializeCriticalSection(&cv->threadIdSec);
+ cv->waitingthreadcount = 0;
+ cv->waitingthreadhdls = (pthread_t *) mg_calloc(MAX_WORKER_THREADS, sizeof(pthread_t));
+ return (cv->waitingthreadhdls!=NULL) ? 0 : -1;
+}
+
+static int pthread_cond_timedwait(pthread_cond_t *cv, pthread_mutex_t *mutex, const struct timespec * abstime)
+{
+ struct mg_workerTLS * tls = (struct mg_workerTLS *)TlsGetValue(sTlsKey);
+ int ok;
+ struct timespec tsnow;
+ int64_t nsnow, nswaitabs, nswaitrel;
+ DWORD mswaitrel;
+
+ EnterCriticalSection(&cv->threadIdSec);
+ assert(cv->waitingthreadcount < MAX_WORKER_THREADS);
+ cv->waitingthreadhdls[cv->waitingthreadcount] = tls->pthread_cond_helper_mutex;
+ cv->waitingthreadcount++;
+ LeaveCriticalSection(&cv->threadIdSec);
+
+ if (abstime) {
+ clock_gettime(CLOCK_REALTIME, &tsnow);
+ nsnow = (((uint64_t)tsnow.tv_sec)*1000000000) + tsnow.tv_nsec;
+ nswaitabs = (((uint64_t)abstime->tv_sec)*1000000000) + abstime->tv_nsec;
+ nswaitrel = nswaitabs - nsnow;
+ if (nswaitrel<0) nswaitrel=0;
+ mswaitrel = (DWORD)(nswaitrel / 1000000);
+ } else {
+ mswaitrel = INFINITE;
+ }
+
+ pthread_mutex_unlock(mutex);
+ ok = (WAIT_OBJECT_0 == WaitForSingleObject(tls->pthread_cond_helper_mutex, mswaitrel));
+ pthread_mutex_lock(mutex);
+
+ return ok ? 0 : -1;
+}
+
+static int pthread_cond_wait(pthread_cond_t *cv, pthread_mutex_t *mutex)
+{
+ return pthread_cond_timedwait(cv, mutex, NULL);
+}
+
+static int pthread_cond_signal(pthread_cond_t *cv)
+{
+ int i;
+ HANDLE wkup = NULL;
+ BOOL ok = FALSE;
+
+ EnterCriticalSection(&cv->threadIdSec);
+ if (cv->waitingthreadcount) {
+ wkup = cv->waitingthreadhdls[0];
+ ok = SetEvent(wkup);
+
+ for (i=1; i<cv->waitingthreadcount; i++) {
+ cv->waitingthreadhdls[i-1] = cv->waitingthreadhdls[i];
+ }
+ cv->waitingthreadcount--;
+
+ assert(ok);
+ }
+ LeaveCriticalSection(&cv->threadIdSec);
+
+ return ok ? 0 : 1;
+}
+
+static int pthread_cond_broadcast(pthread_cond_t *cv)
+{
+ EnterCriticalSection(&cv->threadIdSec);
+ while (cv->waitingthreadcount) {
+ pthread_cond_signal(cv);
+ }
+ LeaveCriticalSection(&cv->threadIdSec);
+
+ return 0;
+}
+
+static int pthread_cond_destroy(pthread_cond_t *cv)
+{
+ EnterCriticalSection(&cv->threadIdSec);
+ assert(cv->waitingthreadcount==0);
+ mg_free(cv->waitingthreadhdls);
+ cv->waitingthreadhdls = 0;
+ LeaveCriticalSection(&cv->threadIdSec);
+ DeleteCriticalSection(&cv->threadIdSec);
+
+ return 0;
+}
+
+/* For Windows, change all slashes to backslashes in path names. */
+static void change_slashes_to_backslashes(char *path)
+{
+ int i;
+
+ for (i = 0; path[i] != '\0'; i++) {
+ if (path[i] == '/')
+ path[i] = '\\';
+ /* i > 0 check is to preserve UNC paths, like \\server\file.txt */
+ if (path[i] == '\\' && i > 0)
+ while (path[i + 1] == '\\' || path[i + 1] == '/')
+ (void) memmove(path + i + 1,
+ path + i + 2, strlen(path + i + 1));
+ }
+}
+
+/* Encode 'path' which is assumed UTF-8 string, into UNICODE string.
+ wbuf and wbuf_len is a target buffer and its length. */
+static void to_unicode(const char *path, wchar_t *wbuf, size_t wbuf_len)
+{
+ char buf[PATH_MAX], buf2[PATH_MAX];
+
+ mg_strlcpy(buf, path, sizeof(buf));
+ change_slashes_to_backslashes(buf);
+
+ /* Convert to Unicode and back. If doubly-converted string does not
+ match the original, something is fishy, reject. */
+ memset(wbuf, 0, wbuf_len * sizeof(wchar_t));
+ MultiByteToWideChar(CP_UTF8, 0, buf, -1, wbuf, (int) wbuf_len);
+ WideCharToMultiByte(CP_UTF8, 0, wbuf, (int) wbuf_len, buf2, sizeof(buf2),
+ NULL, NULL);
+ if (strcmp(buf, buf2) != 0) {
+ wbuf[0] = L'\0';
+ }
+}
+
+#if defined(_WIN32_WCE)
+static time_t time(time_t *ptime)
+{
+ time_t t;
+ SYSTEMTIME st;
+ FILETIME ft;
+
+ GetSystemTime(&st);
+ SystemTimeToFileTime(&st, &ft);
+ t = SYS2UNIX_TIME(ft.dwLowDateTime, ft.dwHighDateTime);
+
+ if (ptime != NULL) {
+ *ptime = t;
+ }
+
+ return t;
+}
+
+static struct tm *localtime(const time_t *ptime, struct tm *ptm)
+{
+ int64_t t = ((int64_t) *ptime) * RATE_DIFF + EPOCH_DIFF;
+ FILETIME ft, lft;
+ SYSTEMTIME st;
+ TIME_ZONE_INFORMATION tzinfo;
+
+ if (ptm == NULL) {
+ return NULL;
+ }
+
+ * (int64_t *) &ft = t;
+ FileTimeToLocalFileTime(&ft, &lft);
+ FileTimeToSystemTime(&lft, &st);
+ ptm->tm_year = st.wYear - 1900;
+ ptm->tm_mon = st.wMonth - 1;
+ ptm->tm_wday = st.wDayOfWeek;
+ ptm->tm_mday = st.wDay;
+ ptm->tm_hour = st.wHour;
+ ptm->tm_min = st.wMinute;
+ ptm->tm_sec = st.wSecond;
+ ptm->tm_yday = 0; /* hope nobody uses this */
+ ptm->tm_isdst =
+ GetTimeZoneInformation(&tzinfo) == TIME_ZONE_ID_DAYLIGHT ? 1 : 0;
+
+ return ptm;
+}
+
+static struct tm *gmtime(const time_t *ptime, struct tm *ptm)
+{
+ /* FIXME(lsm): fix this. */
+ return localtime(ptime, ptm);
+}
+
+static size_t strftime(char *dst, size_t dst_size, const char *fmt,
+ const struct tm *tm)
+{
+ (void) snprintf(dst, dst_size, "implement strftime() for WinCE");
+ return 0;
+}
+#endif
+
+/* Windows happily opens files with some garbage at the end of file name.
+ For example, fopen("a.cgi ", "r") on Windows successfully opens
+ "a.cgi", despite one would expect an error back.
+ This function returns non-0 if path ends with some garbage. */
+static int path_cannot_disclose_cgi(const char *path)
+{
+ static const char *allowed_last_characters = "_-";
+ int last = path[strlen(path) - 1];
+ return isalnum(last) || strchr(allowed_last_characters, last) != NULL;
+}
+
+static int mg_stat(struct mg_connection *conn, const char *path, struct file *filep)
+{
+ wchar_t wbuf[PATH_MAX];
+ WIN32_FILE_ATTRIBUTE_DATA info;
+
+ if (!is_file_in_memory(conn, path, filep)) {
+ to_unicode(path, wbuf, ARRAY_SIZE(wbuf));
+ if (GetFileAttributesExW(wbuf, GetFileExInfoStandard, &info) != 0) {
+ filep->size = MAKEUQUAD(info.nFileSizeLow, info.nFileSizeHigh);
+ filep->modification_time = SYS2UNIX_TIME(
+ info.ftLastWriteTime.dwLowDateTime,
+ info.ftLastWriteTime.dwHighDateTime);
+ filep->is_directory = info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
+ /* If file name is fishy, reset the file structure and return
+ error.
+ Note it is important to reset, not just return the error, cause
+ functions like is_file_opened() check the struct. */
+ if (!filep->is_directory && !path_cannot_disclose_cgi(path)) {
+ memset(filep, 0, sizeof(*filep));
+ }
+ }
+ }
+
+ return filep->membuf != NULL || filep->modification_time != 0;
+}
+
+static int mg_remove(const char *path)
+{
+ wchar_t wbuf[PATH_MAX];
+ to_unicode(path, wbuf, ARRAY_SIZE(wbuf));
+ return DeleteFileW(wbuf) ? 0 : -1;
+}
+
+static int mg_mkdir(const char *path, int mode)
+{
+ char buf[PATH_MAX];
+ wchar_t wbuf[PATH_MAX];
+
+ (void) mode;
+ mg_strlcpy(buf, path, sizeof(buf));
+ change_slashes_to_backslashes(buf);
+
+ (void) MultiByteToWideChar(CP_UTF8, 0, buf, -1, wbuf, ARRAY_SIZE(wbuf));
+
+ return CreateDirectoryW(wbuf, NULL) ? 0 : -1;
+}
+
+/* Implementation of POSIX opendir/closedir/readdir for Windows. */
+static DIR * opendir(const char *name)
+{
+ DIR *dir = NULL;
+ wchar_t wpath[PATH_MAX];
+ DWORD attrs;
+
+ if (name == NULL) {
+ SetLastError(ERROR_BAD_ARGUMENTS);
+ } else if ((dir = (DIR *) mg_malloc(sizeof(*dir))) == NULL) {
+ SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+ } else {
+ to_unicode(name, wpath, ARRAY_SIZE(wpath));
+ attrs = GetFileAttributesW(wpath);
+ if (attrs != 0xFFFFFFFF &&
+ ((attrs & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY)) {
+ (void) wcscat(wpath, L"\\*");
+ dir->handle = FindFirstFileW(wpath, &dir->info);
+ dir->result.d_name[0] = '\0';
+ } else {
+ mg_free(dir);
+ dir = NULL;
+ }
+ }
+
+ return dir;
+}
+
+static int closedir(DIR *dir)
+{
+ int result = 0;
+
+ if (dir != NULL) {
+ if (dir->handle != INVALID_HANDLE_VALUE)
+ result = FindClose(dir->handle) ? 0 : -1;
+
+ mg_free(dir);
+ } else {
+ result = -1;
+ SetLastError(ERROR_BAD_ARGUMENTS);
+ }
+
+ return result;
+}
+
+static struct dirent *readdir(DIR *dir)
+{
+ struct dirent *result = 0;
+
+ if (dir) {
+ if (dir->handle != INVALID_HANDLE_VALUE) {
+ result = &dir->result;
+ (void) WideCharToMultiByte(CP_UTF8, 0,
+ dir->info.cFileName, -1, result->d_name,
+ sizeof(result->d_name), NULL, NULL);
+
+ if (!FindNextFileW(dir->handle, &dir->info)) {
+ (void) FindClose(dir->handle);
+ dir->handle = INVALID_HANDLE_VALUE;
+ }
+
+ } else {
+ SetLastError(ERROR_FILE_NOT_FOUND);
+ }
+ } else {
+ SetLastError(ERROR_BAD_ARGUMENTS);
+ }
+
+ return result;
+}
+
+#ifndef HAVE_POLL
+static int poll(struct pollfd *pfd, int n, int milliseconds)
+{
+ struct timeval tv;
+ fd_set set;
+ int i, result;
+ SOCKET maxfd = 0;
+
+ tv.tv_sec = milliseconds / 1000;
+ tv.tv_usec = (milliseconds % 1000) * 1000;
+ FD_ZERO(&set);
+
+ for (i = 0; i < n; i++) {
+ FD_SET((SOCKET) pfd[i].fd, &set);
+ pfd[i].revents = 0;
+
+ if (pfd[i].fd > maxfd) {
+ maxfd = pfd[i].fd;
+ }
+ }
+
+ if ((result = select((int)maxfd + 1, &set, NULL, NULL, &tv)) > 0) {
+ for (i = 0; i < n; i++) {
+ if (FD_ISSET(pfd[i].fd, &set)) {
+ pfd[i].revents = POLLIN;
+ }
+ }
+ }
+
+ return result;
+}
+#endif /* HAVE_POLL */
+
+static void set_close_on_exec(SOCKET sock, struct mg_connection *conn /* may be null */)
+{
+ (void) conn; /* Unused. */
+ (void) SetHandleInformation((HANDLE) sock, HANDLE_FLAG_INHERIT, 0);
+}
+
+int mg_start_thread(mg_thread_func_t f, void *p)
+{
+#if defined(USE_STACK_SIZE) && (USE_STACK_SIZE > 1)
+ /* Compile-time option to control stack size, e.g. -DUSE_STACK_SIZE=16384 */
+ return ((_beginthread((void (__cdecl *)(void *)) f, USE_STACK_SIZE, p) == ((uintptr_t)(-1L))) ? -1 : 0);
+#else
+ return ((_beginthread((void (__cdecl *)(void *)) f, 0, p) == ((uintptr_t)(-1L))) ? -1 : 0);
+#endif /* defined(USE_STACK_SIZE) && (USE_STACK_SIZE > 1) */
+}
+
+/* Start a thread storing the thread context. */
+
+static int mg_start_thread_with_id(unsigned (__stdcall *f)(void *), void *p,
+ pthread_t *threadidptr)
+{
+ uintptr_t uip;
+ HANDLE threadhandle;
+ int result = -1;
+
+ uip = _beginthreadex(NULL, 0, (unsigned (__stdcall *)(void *)) f, p, 0,
+ NULL);
+ threadhandle = (HANDLE) uip;
+ if ((uip != (uintptr_t)(-1L)) && (threadidptr != NULL)) {
+ *threadidptr = threadhandle;
+ result = 0;
+ }
+
+ return result;
+}
+
+/* Wait for a thread to finish. */
+
+static int mg_join_thread(pthread_t threadid)
+{
+ int result;
+ DWORD dwevent;
+
+ result = -1;
+ dwevent = WaitForSingleObject(threadid, INFINITE);
+ if (dwevent == WAIT_FAILED) {
+ int err;
+
+ err = GetLastError();
+ DEBUG_TRACE("WaitForSingleObject() failed, error %d", err);
+ } else {
+ if (dwevent == WAIT_OBJECT_0) {
+ CloseHandle(threadid);
+ result = 0;
+ }
+ }
+
+ return result;
+}
+
+static HANDLE dlopen(const char *dll_name, int flags)
+{
+ wchar_t wbuf[PATH_MAX];
+ (void) flags;
+ to_unicode(dll_name, wbuf, ARRAY_SIZE(wbuf));
+ return LoadLibraryW(wbuf);
+}
+
+static int dlclose(void *handle)
+{
+ int result;
+
+ if (FreeLibrary((HMODULE) handle) != 0) {
+ result = 0;
+ } else {
+ result = -1;
+ }
+
+ return result;
+}
+
+#if !defined(NO_CGI)
+#define SIGKILL 0
+static int kill(pid_t pid, int sig_num)
+{
+ (void) TerminateProcess(pid, sig_num);
+ (void) CloseHandle(pid);
+ return 0;
+}
+
+static void trim_trailing_whitespaces(char *s)
+{
+ char *e = s + strlen(s) - 1;
+ while (e > s && isspace(* (unsigned char *) e)) {
+ *e-- = '\0';
+ }
+}
+
+static pid_t spawn_process(struct mg_connection *conn, const char *prog,
+ char *envblk, char *envp[], int fdin,
+ int fdout, const char *dir)
+{
+ HANDLE me;
+ char *p, *interp, full_interp[PATH_MAX], full_dir[PATH_MAX],
+ cmdline[PATH_MAX], buf[PATH_MAX];
+ struct file file = STRUCT_FILE_INITIALIZER;
+ STARTUPINFOA si;
+ PROCESS_INFORMATION pi = { 0 };
+
+ (void) envp;
+
+ memset(&si, 0, sizeof(si));
+ si.cb = sizeof(si);
+
+ /* TODO(lsm): redirect CGI errors to the error log file */
+ si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
+ si.wShowWindow = SW_HIDE;
+
+ me = GetCurrentProcess();
+ DuplicateHandle(me, (HANDLE) _get_osfhandle(fdin), me,
+ &si.hStdInput, 0, TRUE, DUPLICATE_SAME_ACCESS);
+ DuplicateHandle(me, (HANDLE) _get_osfhandle(fdout), me,
+ &si.hStdOutput, 0, TRUE, DUPLICATE_SAME_ACCESS);
+
+ /* If CGI file is a script, try to read the interpreter line */
+ interp = conn->ctx->config[CGI_INTERPRETER];
+ if (interp == NULL) {
+ buf[0] = buf[1] = '\0';
+
+ /* Read the first line of the script into the buffer */
+ snprintf(cmdline, sizeof(cmdline), "%s%c%s", dir, '/', prog);
+ if (mg_fopen(conn, cmdline, "r", &file)) {
+ p = (char *) file.membuf;
+ mg_fgets(buf, sizeof(buf), &file, &p);
+ mg_fclose(&file);
+ buf[sizeof(buf) - 1] = '\0';
+ }
+
+ if (buf[0] == '#' && buf[1] == '!') {
+ trim_trailing_whitespaces(buf + 2);
+ } else {
+ buf[2] = '\0';
+ }
+ interp = buf + 2;
+ }
+
+ if (interp[0] != '\0') {
+ GetFullPathNameA(interp, sizeof(full_interp), full_interp, NULL);
+ interp = full_interp;
+ }
+ GetFullPathNameA(dir, sizeof(full_dir), full_dir, NULL);
+
+ mg_snprintf(conn, cmdline, sizeof(cmdline), "%s%s\"%s\\%s\"",
+ interp, interp[0] == '\0' ? "" : " ", full_dir, prog);
+
+ DEBUG_TRACE("Running [%s]", cmdline);
+ if (CreateProcessA(NULL, cmdline, NULL, NULL, TRUE,
+ CREATE_NEW_PROCESS_GROUP, envblk, NULL, &si, &pi) == 0) {
+ mg_cry(conn, "%s: CreateProcess(%s): %ld",
+ __func__, cmdline, ERRNO);
+ pi.hProcess = (pid_t) -1;
+ }
+
+ (void) CloseHandle(si.hStdOutput);
+ (void) CloseHandle(si.hStdInput);
+ if (pi.hThread != NULL)
+ (void) CloseHandle(pi.hThread);
+
+ return (pid_t) pi.hProcess;
+}
+#endif /* !NO_CGI */
+
+static int set_non_blocking_mode(SOCKET sock)
+{
+ unsigned long on = 1;
+ return ioctlsocket(sock, FIONBIO, &on);
+}
+
+#else
+static int mg_stat(struct mg_connection *conn, const char *path,
+ struct file *filep)
+{
+ struct stat st;
+
+ if (!is_file_in_memory(conn, path, filep) && !stat(path, &st)) {
+ filep->size = st.st_size;
+ filep->modification_time = st.st_mtime;
+ filep->is_directory = S_ISDIR(st.st_mode);
+ } else {
+ filep->modification_time = (time_t) 0;
+ }
+
+ return filep->membuf != NULL || filep->modification_time != (time_t) 0;
+}
+
+static void set_close_on_exec(int fd, struct mg_connection *conn /* may be null */)
+{
+ if (fcntl(fd, F_SETFD, FD_CLOEXEC) != 0) {
+ if (conn) {
+ mg_cry(conn, "%s: fcntl(F_SETFD FD_CLOEXEC) failed: %s", __func__, strerror(ERRNO));
+ }
+ }
+}
+
+int mg_start_thread(mg_thread_func_t func, void *param)
+{
+ pthread_t thread_id;
+ pthread_attr_t attr;
+ int result;
+
+ (void) pthread_attr_init(&attr);
+ (void) pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
+
+#if defined(USE_STACK_SIZE) && (USE_STACK_SIZE > 1)
+ /* Compile-time option to control stack size,
+ e.g. -DUSE_STACK_SIZE=16384 */
+ (void) pthread_attr_setstacksize(&attr, USE_STACK_SIZE);
+#endif /* defined(USE_STACK_SIZE) && (USE_STACK_SIZE > 1) */
+
+ result = pthread_create(&thread_id, &attr, func, param);
+ pthread_attr_destroy(&attr);
+
+ return result;
+}
+
+/* Start a thread storing the thread context. */
+
+static int mg_start_thread_with_id(mg_thread_func_t func, void *param, pthread_t *threadidptr)
+{
+ pthread_t thread_id;
+ pthread_attr_t attr;
+ int result;
+
+ (void) pthread_attr_init(&attr);
+
+#if defined(USE_STACK_SIZE) && (USE_STACK_SIZE > 1)
+ /* Compile-time option to control stack size,
+ e.g. -DUSE_STACK_SIZE=16384 */
+ (void) pthread_attr_setstacksize(&attr, USE_STACK_SIZE);
+#endif /* defined(USE_STACK_SIZE) && USE_STACK_SIZE > 1 */
+
+ result = pthread_create(&thread_id, &attr, func, param);
+ pthread_attr_destroy(&attr);
+ if ((result == 0) && (threadidptr != NULL)) {
+ *threadidptr = thread_id;
+ }
+ return result;
+}
+
+/* Wait for a thread to finish. */
+
+static int mg_join_thread(pthread_t threadid)
+{
+ int result;
+
+ result = pthread_join(threadid, NULL);
+ return result;
+}
+
+#ifndef NO_CGI
+static pid_t spawn_process(struct mg_connection *conn, const char *prog,
+ char *envblk, char *envp[], int fdin,
+ int fdout, const char *dir)
+{
+ pid_t pid;
+ const char *interp;
+
+ (void) envblk;
+
+ if ((pid = fork()) == -1) {
+ /* Parent */
+ send_http_error(conn, 500, NULL,
+ "Error: Creating CGI process\nfork(): %s", strerror(ERRNO));
+ } else if (pid == 0) {
+ /* Child */
+ if (chdir(dir) != 0) {
+ mg_cry(conn, "%s: chdir(%s): %s", __func__, dir, strerror(ERRNO));
+ } else if (dup2(fdin, 0) == -1) {
+ mg_cry(conn, "%s: dup2(%d, 0): %s", __func__, fdin, strerror(ERRNO));
+ } else if (dup2(fdout, 1) == -1) {
+ mg_cry(conn, "%s: dup2(%d, 1): %s", __func__, fdout, strerror(ERRNO));
+ } else {
+ /* Not redirecting stderr to stdout, to avoid output being littered
+ with the error messages. */
+ (void) close(fdin);
+ (void) close(fdout);
+
+ /* After exec, all signal handlers are restored to their default
+ values, with one exception of SIGCHLD. According to
+ POSIX.1-2001 and Linux's implementation, SIGCHLD's handler will
+ leave unchanged after exec if it was set to be ignored. Restore
+ it to default action. */
+ signal(SIGCHLD, SIG_DFL);
+
+ interp = conn->ctx->config[CGI_INTERPRETER];
+ if (interp == NULL) {
+ (void) execle(prog, prog, NULL, envp);
+ mg_cry(conn, "%s: execle(%s): %s", __func__, prog, strerror(ERRNO));
+ } else {
+ (void) execle(interp, interp, prog, NULL, envp);
+ mg_cry(conn, "%s: execle(%s %s): %s", __func__, interp, prog,
+ strerror(ERRNO));
+ }
+ }
+ exit(EXIT_FAILURE);
+ }
+
+ return pid;
+}
+#endif /* !NO_CGI */
+
+static int set_non_blocking_mode(SOCKET sock)
+{
+ int flags;
+
+ flags = fcntl(sock, F_GETFL, 0);
+ (void) fcntl(sock, F_SETFL, flags | O_NONBLOCK);
+
+ return 0;
+}
+#endif /* _WIN32 */
+
+/* Write data to the IO channel - opened file descriptor, socket or SSL
+ descriptor. Return number of bytes written. */
+static int64_t push(FILE *fp, SOCKET sock, SSL *ssl, const char *buf, int64_t len)
+{
+ int64_t sent;
+ int n, k;
+
+ (void) ssl; /* Get rid of warning */
+ sent = 0;
+ while (sent < len) {
+
+ /* How many bytes we send in this iteration */
+ k = len - sent > INT_MAX ? INT_MAX : (int) (len - sent);
+
+#ifndef NO_SSL
+ if (ssl != NULL) {
+ n = SSL_write(ssl, buf + sent, k);
+ } else
+#endif
+ if (fp != NULL) {
+ n = (int) fwrite(buf + sent, 1, (size_t) k, fp);
+ if (ferror(fp))
+ n = -1;
+ } else {
+ n = send(sock, buf + sent, (size_t) k, MSG_NOSIGNAL);
+ }
+
+ if (n <= 0)
+ break;
+
+ sent += n;
+ }
+
+ return sent;
+}
+
+/* Read from IO channel - opened file descriptor, socket, or SSL descriptor.
+ Return negative value on error, or number of bytes read on success. */
+static int pull(FILE *fp, struct mg_connection *conn, char *buf, int len)
+{
+ int nread;
+
+ if (fp != NULL) {
+ /* Use read() instead of fread(), because if we're reading from the
+ CGI pipe, fread() may block until IO buffer is filled up. We cannot
+ afford to block and must pass all read bytes immediately to the
+ client. */
+ nread = read(fileno(fp), buf, (size_t) len);
+#ifndef NO_SSL
+ } else if (conn->ssl != NULL) {
+ nread = SSL_read(conn->ssl, buf, len);
+#endif
+ } else {
+ nread = recv(conn->client.sock, buf, (size_t) len, 0);
+ }
+
+ return conn->ctx->stop_flag ? -1 : nread;
+}
+
+static int pull_all(FILE *fp, struct mg_connection *conn, char *buf, int len)
+{
+ int n, nread = 0;
+
+ while (len > 0 && conn->ctx->stop_flag == 0) {
+ n = pull(fp, conn, buf + nread, len);
+ if (n < 0) {
+ nread = n; /* Propagate the error */
+ break;
+ } else if (n == 0) {
+ break; /* No more data to read */
+ } else {
+ conn->consumed_content += n;
+ nread += n;
+ len -= n;
+ }
+ }
+
+ return nread;
+}
+
+int mg_read(struct mg_connection *conn, void *buf, size_t len)
+{
+ int64_t n, buffered_len, nread;
+ int64_t len64 = (int64_t)(len > INT_MAX ? INT_MAX : len); /* since the return value is int, we may not read more bytes */
+ const char *body;
+
+ /* If Content-Length is not set for a PUT or POST request, read until socket is closed */
+ if (conn->consumed_content == 0 && conn->content_len == -1) {
+ conn->content_len = INT64_MAX;
+ conn->must_close = 1;
+ }
+
+ nread = 0;
+ if (conn->consumed_content < conn->content_len) {
+ /* Adjust number of bytes to read. */
+ int64_t left_to_read = conn->content_len - conn->consumed_content;
+ if (left_to_read < len64) {
+ /* Do not reade more than the total content length of the request. */
+ len64 = left_to_read;
+ }
+
+ /* Return buffered data */
+ buffered_len = (int64_t)(conn->data_len) - (int64_t)conn->request_len - conn->consumed_content;
+ if (buffered_len > 0) {
+ if (len64 < buffered_len) {
+ buffered_len = len64;
+ }
+ body = conn->buf + conn->request_len + conn->consumed_content;
+ memcpy(buf, body, (size_t) buffered_len);
+ len64 -= buffered_len;
+ conn->consumed_content += buffered_len;
+ nread += buffered_len;
+ buf = (char *) buf + buffered_len;
+ }
+
+ /* We have returned all buffered data. Read new data from the remote
+ socket. */
+ if ((n = pull_all(NULL, conn, (char *) buf, (int)len64)) >= 0) {
+ nread += n;
+ } else {
+ nread = (nread > 0 ? nread : n);
+ }
+ }
+ return (int)nread;
+}
+
+int mg_write(struct mg_connection *conn, const void *buf, size_t len)
+{
+ time_t now;
+ int64_t n, total, allowed;
+
+ if (conn->throttle > 0) {
+ if ((now = time(NULL)) != conn->last_throttle_time) {
+ conn->last_throttle_time = now;
+ conn->last_throttle_bytes = 0;
+ }
+ allowed = conn->throttle - conn->last_throttle_bytes;
+ if (allowed > (int64_t) len) {
+ allowed = len;
+ }
+ if ((total = push(NULL, conn->client.sock, conn->ssl, (const char *) buf,
+ (int64_t) allowed)) == allowed) {
+ buf = (char *) buf + total;
+ conn->last_throttle_bytes += total;
+ while (total < (int64_t) len && conn->ctx->stop_flag == 0) {
+ allowed = conn->throttle > (int64_t) len - total ?
+ (int64_t) len - total : conn->throttle;
+ if ((n = push(NULL, conn->client.sock, conn->ssl, (const char *) buf,
+ (int64_t) allowed)) != allowed) {
+ break;
+ }
+ sleep(1);
+ conn->last_throttle_bytes = allowed;
+ conn->last_throttle_time = time(NULL);
+ buf = (char *) buf + n;
+ total += n;
+ }
+ }
+ } else {
+ total = push(NULL, conn->client.sock, conn->ssl, (const char *) buf,
+ (int64_t) len);
+ }
+ return (int) total;
+}
+
+/* Alternative alloc_vprintf() for non-compliant C runtimes */
+static int alloc_vprintf2(char **buf, const char *fmt, va_list ap)
+{
+ va_list ap_copy;
+ int size = MG_BUF_LEN;
+ int len = -1;
+
+ *buf = NULL;
+ while (len == -1) {
+ if (*buf) mg_free(*buf);
+ *buf = (char *)mg_malloc(size *= 4);
+ if (!*buf) break;
+ va_copy(ap_copy, ap);
+ len = vsnprintf(*buf, size, fmt, ap_copy);
+ va_end(ap_copy);
+ }
+
+ return len;
+}
+
+/* Print message to buffer. If buffer is large enough to hold the message,
+ return buffer. If buffer is to small, allocate large enough buffer on heap,
+ and return allocated buffer. */
+static int alloc_vprintf(char **buf, size_t size, const char *fmt, va_list ap)
+{
+ va_list ap_copy;
+ int len;
+
+ /* Windows is not standard-compliant, and vsnprintf() returns -1 if
+ buffer is too small. Also, older versions of msvcrt.dll do not have
+ _vscprintf(). However, if size is 0, vsnprintf() behaves correctly.
+ Therefore, we make two passes: on first pass, get required message
+ length.
+ On second pass, actually print the message. */
+ va_copy(ap_copy, ap);
+ len = vsnprintf(NULL, 0, fmt, ap_copy);
+ va_end(ap_copy);
+
+ if (len < 0) {
+ /* C runtime is not standard compliant, vsnprintf() returned -1.
+ Switch to alternative code path that uses incremental allocations.
+ */
+ va_copy(ap_copy, ap);
+ len = alloc_vprintf2(buf, fmt, ap);
+ va_end(ap_copy);
+ } else if (len > (int) size &&
+ (size = len + 1) > 0 &&
+ (*buf = (char *) mg_malloc(size)) == NULL) {
+ len = -1; /* Allocation failed, mark failure */
+ } else {
+ va_copy(ap_copy, ap);
+ IGNORE_UNUSED_RESULT(vsnprintf(*buf, size, fmt, ap_copy));
+ va_end(ap_copy);
+ }
+
+ return len;
+}
+
+int mg_vprintf(struct mg_connection *conn, const char *fmt, va_list ap)
+{
+ char mem[MG_BUF_LEN], *buf = mem;
+ int len;
+
+ if ((len = alloc_vprintf(&buf, sizeof(mem), fmt, ap)) > 0) {
+ len = mg_write(conn, buf, (size_t) len);
+ }
+ if (buf != mem && buf != NULL) {
+ mg_free(buf);
+ }
+
+ return len;
+}
+
+int mg_printf(struct mg_connection *conn, const char *fmt, ...)
+{
+ va_list ap;
+ int result;
+
+ va_start(ap, fmt);
+ result = mg_vprintf(conn, fmt, ap);
+ va_end(ap);
+
+ return result;
+}
+
+int mg_url_decode(const char *src, int src_len, char *dst,
+ int dst_len, int is_form_url_encoded)
+{
+ int i, j, a, b;
+#define HEXTOI(x) (isdigit(x) ? x - '0' : x - 'W')
+
+ for (i = j = 0; i < src_len && j < dst_len - 1; i++, j++) {
+ if (i < src_len - 2 && src[i] == '%' &&
+ isxdigit(* (const unsigned char *) (src + i + 1)) &&
+ isxdigit(* (const unsigned char *) (src + i + 2))) {
+ a = tolower(* (const unsigned char *) (src + i + 1));
+ b = tolower(* (const unsigned char *) (src + i + 2));
+ dst[j] = (char) ((HEXTOI(a) << 4) | HEXTOI(b));
+ i += 2;
+ } else if (is_form_url_encoded && src[i] == '+') {
+ dst[j] = ' ';
+ } else {
+ dst[j] = src[i];
+ }
+ }
+
+ dst[j] = '\0'; /* Null-terminate the destination */
+
+ return i >= src_len ? j : -1;
+}
+
+int mg_get_var(const char *data, size_t data_len, const char *name,
+ char *dst, size_t dst_len)
+{
+ return mg_get_var2(data,data_len,name,dst,dst_len,0);
+}
+
+int mg_get_var2(const char *data, size_t data_len, const char *name,
+ char *dst, size_t dst_len, size_t occurrence)
+{
+ const char *p, *e, *s;
+ size_t name_len;
+ int len;
+
+ if (dst == NULL || dst_len == 0) {
+ len = -2;
+ } else if (data == NULL || name == NULL || data_len == 0) {
+ len = -1;
+ dst[0] = '\0';
+ } else {
+ name_len = strlen(name);
+ e = data + data_len;
+ len = -1;
+ dst[0] = '\0';
+
+ /* data is "var1=val1&var2=val2...". Find variable first */
+ for (p = data; p + name_len < e; p++) {
+ if ((p == data || p[-1] == '&') && p[name_len] == '=' &&
+ !mg_strncasecmp(name, p, name_len) && 0 == occurrence--) {
+
+ /* Point p to variable value */
+ p += name_len + 1;
+
+ /* Point s to the end of the value */
+ s = (const char *) memchr(p, '&', (size_t)(e - p));
+ if (s == NULL) {
+ s = e;
+ }
+ assert(s >= p);
+
+ /* Decode variable into destination buffer */
+ len = mg_url_decode(p, (int)(s - p), dst, (int)dst_len, 1);
+
+ /* Redirect error code from -1 to -2 (destination buffer too
+ small). */
+ if (len == -1) {
+ len = -2;
+ }
+ break;
+ }
+ }
+ }
+
+ return len;
+}
+
+int mg_get_cookie(const char *cookie_header, const char *var_name,
+ char *dst, size_t dst_size)
+{
+ const char *s, *p, *end;
+ int name_len, len = -1;
+
+ if (dst == NULL || dst_size == 0) {
+ len = -2;
+ } else if (var_name == NULL || (s = cookie_header) == NULL) {
+ len = -1;
+ dst[0] = '\0';
+ } else {
+ name_len = (int) strlen(var_name);
+ end = s + strlen(s);
+ dst[0] = '\0';
+
+ for (; (s = mg_strcasestr(s, var_name)) != NULL; s += name_len) {
+
<TRUNCATED>
[18/19] celix git commit: CELIX-417: Refactor for CMake usage in RSA,
PSA and Docker. mostly trying to identify the api and common libraries
Posted by pn...@apache.org.
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/pubsub/pubsub_admin_udp_mc/private/src/pubsub_admin_impl.c
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_admin_udp_mc/private/src/pubsub_admin_impl.c b/pubsub/pubsub_admin_udp_mc/private/src/pubsub_admin_impl.c
deleted file mode 100644
index 1fbdb08..0000000
--- a/pubsub/pubsub_admin_udp_mc/private/src/pubsub_admin_impl.c
+++ /dev/null
@@ -1,1039 +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.
- */
-/*
- * pubsub_admin_impl.c
- *
- * \date Sep 30, 2011
- * \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>
-
-#ifndef ANDROID
-#include <ifaddrs.h>
-#endif
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <netdb.h>
-
-#include "constants.h"
-#include "utils.h"
-#include "hash_map.h"
-#include "array_list.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 "service_factory.h"
-
-#include "pubsub_admin_impl.h"
-#include "topic_subscription.h"
-#include "topic_publication.h"
-#include "pubsub_endpoint.h"
-#include "subscriber.h"
-#include "pubsub_admin_match.h"
-
-static const char *DEFAULT_MC_IP = "224.100.1.1";
-static char *DEFAULT_MC_PREFIX = "224.100";
-
-static celix_status_t pubsubAdmin_getIpAddress(const char* interface, char** ip);
-static celix_status_t pubsubAdmin_addSubscriptionToPendingList(pubsub_admin_pt admin,pubsub_endpoint_pt subEP);
-static celix_status_t pubsubAdmin_addAnySubscription(pubsub_admin_pt admin,pubsub_endpoint_pt subEP);
-
-static celix_status_t pubsubAdmin_getBestSerializer(pubsub_admin_pt admin,pubsub_endpoint_pt ep, pubsub_serializer_service_t **serSvc);
-static void connectTopicPubSubToSerializer(pubsub_admin_pt admin,pubsub_serializer_service_t *serializer,void *topicPubSub,bool isPublication);
-static void disconnectTopicPubSubFromSerializer(pubsub_admin_pt admin,void *topicPubSub,bool isPublication);
-
-celix_status_t pubsubAdmin_create(bundle_context_pt context, pubsub_admin_pt *admin) {
- celix_status_t status = CELIX_SUCCESS;
-
- *admin = calloc(1, sizeof(**admin));
-
- if (!*admin) {
- return CELIX_ENOMEM;
- }
-
- char *mc_ip = NULL;
- char *if_ip = NULL;
- int sendSocket = -1;
-
- if (logHelper_create(context, &(*admin)->loghelper) == CELIX_SUCCESS) {
- logHelper_start((*admin)->loghelper);
- }
- const char *mc_ip_prop = NULL;
- bundleContext_getProperty(context,PSA_IP , &mc_ip_prop);
- if(mc_ip_prop) {
- mc_ip = strdup(mc_ip_prop);
- }
-
-#ifndef ANDROID
- if (mc_ip == NULL) {
- const char *mc_prefix = NULL;
- const char *interface = NULL;
- int b0 = 0, b1 = 0, b2 = 0, b3 = 0;
- bundleContext_getProperty(context,PSA_MULTICAST_IP_PREFIX , &mc_prefix);
- if(mc_prefix == NULL) {
- mc_prefix = DEFAULT_MC_PREFIX;
- }
-
- bundleContext_getProperty(context, PSA_ITF, &interface);
- if (pubsubAdmin_getIpAddress(interface, &if_ip) != CELIX_SUCCESS) {
- logHelper_log((*admin)->loghelper, OSGI_LOGSERVICE_WARNING, "PSA_UDP_MC: Could not retrieve IP address for interface %s", interface);
- }
-
- printf("IP Detected : %s\n", if_ip);
- if(if_ip && sscanf(if_ip, "%i.%i.%i.%i", &b0, &b1, &b2, &b3) != 4) {
- logHelper_log((*admin)->loghelper, OSGI_LOGSERVICE_WARNING, "PSA_UDP_MC: Could not parse IP address %s", if_ip);
- b2 = 1;
- b3 = 1;
- }
-
- asprintf(&mc_ip, "%s.%d.%d",mc_prefix, b2, b3);
-
- sendSocket = socket(AF_INET, SOCK_DGRAM, 0);
- if(sendSocket == -1) {
- perror("pubsubAdmin_create:socket");
- status = CELIX_SERVICE_EXCEPTION;
- }
-
- if(status == CELIX_SUCCESS){
- char loop = 1;
- if(setsockopt(sendSocket, IPPROTO_IP, IP_MULTICAST_LOOP, &loop, sizeof(loop)) != 0) {
- perror("pubsubAdmin_create:setsockopt(IP_MULTICAST_LOOP)");
- status = CELIX_SERVICE_EXCEPTION;
- }
- }
-
- if(status == CELIX_SUCCESS){
- struct in_addr multicast_interface;
- inet_aton(if_ip, &multicast_interface);
- if(setsockopt(sendSocket, IPPROTO_IP, IP_MULTICAST_IF, &multicast_interface, sizeof(multicast_interface)) != 0) {
- perror("pubsubAdmin_create:setsockopt(IP_MULTICAST_IF)");
- status = CELIX_SERVICE_EXCEPTION;
- }
- }
-
- }
-
-
- if(status != CELIX_SUCCESS){
- logHelper_stop((*admin)->loghelper);
- logHelper_destroy(&((*admin)->loghelper));
- if(sendSocket >=0){
- close(sendSocket);
- }
- if(if_ip != NULL){
- free(if_ip);
- }
- if(mc_ip != NULL){
- free(mc_ip);
- }
- return status;
- }
- else{
- (*admin)->sendSocket = sendSocket;
- }
-
-#endif
-
- (*admin)->bundle_context= context;
- (*admin)->localPublications = hashMap_create(utils_stringHash, NULL, utils_stringEquals, NULL);
- (*admin)->subscriptions = hashMap_create(utils_stringHash, NULL, utils_stringEquals, NULL);
- (*admin)->pendingSubscriptions = hashMap_create(utils_stringHash, NULL, utils_stringEquals, NULL);
- (*admin)->externalPublications = hashMap_create(utils_stringHash, NULL, utils_stringEquals, NULL);
- (*admin)->topicSubscriptionsPerSerializer = hashMap_create(NULL, NULL, NULL, NULL);
- (*admin)->topicPublicationsPerSerializer = hashMap_create(NULL, NULL, NULL, NULL);
- arrayList_create(&((*admin)->noSerializerSubscriptions));
- arrayList_create(&((*admin)->noSerializerPublications));
- arrayList_create(&((*admin)->serializerList));
-
- celixThreadMutex_create(&(*admin)->localPublicationsLock, NULL);
- celixThreadMutex_create(&(*admin)->subscriptionsLock, NULL);
- celixThreadMutex_create(&(*admin)->externalPublicationsLock, NULL);
- celixThreadMutex_create(&(*admin)->serializerListLock, NULL);
- celixThreadMutex_create(&(*admin)->usedSerializersLock, NULL);
-
- celixThreadMutexAttr_create(&(*admin)->noSerializerPendingsAttr);
- celixThreadMutexAttr_settype(&(*admin)->noSerializerPendingsAttr, CELIX_THREAD_MUTEX_RECURSIVE);
- celixThreadMutex_create(&(*admin)->noSerializerPendingsLock, &(*admin)->noSerializerPendingsAttr);
-
- celixThreadMutexAttr_create(&(*admin)->pendingSubscriptionsAttr);
- celixThreadMutexAttr_settype(&(*admin)->pendingSubscriptionsAttr, CELIX_THREAD_MUTEX_RECURSIVE);
- celixThreadMutex_create(&(*admin)->pendingSubscriptionsLock, &(*admin)->pendingSubscriptionsAttr);
-
- if (if_ip != NULL) {
- logHelper_log((*admin)->loghelper, OSGI_LOGSERVICE_INFO, "PSA_UDP_MC: Using %s as interface for multicast communication", if_ip);
- (*admin)->ifIpAddress = if_ip;
- } else {
- (*admin)->ifIpAddress = strdup("127.0.0.1");
- }
-
- if (mc_ip != NULL) {
- logHelper_log((*admin)->loghelper, OSGI_LOGSERVICE_INFO, "PSA_UDP_MC: Using %s for service annunciation", mc_ip);
- (*admin)->mcIpAddress = mc_ip;
- }
- else {
- logHelper_log((*admin)->loghelper, OSGI_LOGSERVICE_WARNING, "PSA_UDP_MC: No IP address for service annunciation set. Using %s", DEFAULT_MC_IP);
- (*admin)->mcIpAddress = strdup(DEFAULT_MC_IP);
- }
-
- return status;
-}
-
-
-celix_status_t pubsubAdmin_destroy(pubsub_admin_pt admin)
-{
- celix_status_t status = CELIX_SUCCESS;
-
- free(admin->mcIpAddress);
- free(admin->ifIpAddress);
-
- celixThreadMutex_lock(&admin->pendingSubscriptionsLock);
- hash_map_iterator_pt iter = hashMapIterator_create(admin->pendingSubscriptions);
- while(hashMapIterator_hasNext(iter)){
- hash_map_entry_pt entry = hashMapIterator_nextEntry(iter);
- free((char*)hashMapEntry_getKey(entry));
- arrayList_destroy((array_list_pt)hashMapEntry_getValue(entry));
- }
- hashMapIterator_destroy(iter);
- hashMap_destroy(admin->pendingSubscriptions,false,false);
- celixThreadMutex_unlock(&admin->pendingSubscriptionsLock);
-
- celixThreadMutex_lock(&admin->subscriptionsLock);
- hashMap_destroy(admin->subscriptions,false,false);
- celixThreadMutex_unlock(&admin->subscriptionsLock);
-
- celixThreadMutex_lock(&admin->localPublicationsLock);
- hashMap_destroy(admin->localPublications,true,false);
- celixThreadMutex_unlock(&admin->localPublicationsLock);
-
- celixThreadMutex_lock(&admin->externalPublicationsLock);
- iter = hashMapIterator_create(admin->externalPublications);
- while(hashMapIterator_hasNext(iter)){
- hash_map_entry_pt entry = hashMapIterator_nextEntry(iter);
- free((char*)hashMapEntry_getKey(entry));
- arrayList_destroy((array_list_pt)hashMapEntry_getValue(entry));
- }
- hashMapIterator_destroy(iter);
- hashMap_destroy(admin->externalPublications,false,false);
- celixThreadMutex_unlock(&admin->externalPublicationsLock);
-
- celixThreadMutex_lock(&admin->serializerListLock);
- arrayList_destroy(admin->serializerList);
- celixThreadMutex_unlock(&admin->serializerListLock);
-
- celixThreadMutex_lock(&admin->noSerializerPendingsLock);
- arrayList_destroy(admin->noSerializerSubscriptions);
- arrayList_destroy(admin->noSerializerPublications);
- celixThreadMutex_unlock(&admin->noSerializerPendingsLock);
-
- celixThreadMutex_lock(&admin->usedSerializersLock);
-
- iter = hashMapIterator_create(admin->topicSubscriptionsPerSerializer);
- while(hashMapIterator_hasNext(iter)){
- arrayList_destroy((array_list_pt)hashMapIterator_nextValue(iter));
- }
- hashMapIterator_destroy(iter);
- hashMap_destroy(admin->topicSubscriptionsPerSerializer,false,false);
-
- iter = hashMapIterator_create(admin->topicPublicationsPerSerializer);
- while(hashMapIterator_hasNext(iter)){
- arrayList_destroy((array_list_pt)hashMapIterator_nextValue(iter));
- }
- hashMapIterator_destroy(iter);
- hashMap_destroy(admin->topicPublicationsPerSerializer,false,false);
-
- celixThreadMutex_unlock(&admin->usedSerializersLock);
-
- celixThreadMutex_destroy(&admin->usedSerializersLock);
- celixThreadMutex_destroy(&admin->serializerListLock);
-
- celixThreadMutexAttr_destroy(&admin->noSerializerPendingsAttr);
- celixThreadMutex_destroy(&admin->noSerializerPendingsLock);
-
- celixThreadMutex_destroy(&admin->pendingSubscriptionsLock);
- celixThreadMutexAttr_destroy(&admin->pendingSubscriptionsAttr);
-
- celixThreadMutex_destroy(&admin->subscriptionsLock);
- celixThreadMutex_destroy(&admin->localPublicationsLock);
- celixThreadMutex_destroy(&admin->externalPublicationsLock);
-
- logHelper_stop(admin->loghelper);
-
- logHelper_destroy(&admin->loghelper);
-
- free(admin);
-
- return status;
-}
-
-static celix_status_t pubsubAdmin_addAnySubscription(pubsub_admin_pt admin,pubsub_endpoint_pt subEP){
- celix_status_t status = CELIX_SUCCESS;
-
- celixThreadMutex_lock(&admin->subscriptionsLock);
-
- topic_subscription_pt any_sub = hashMap_get(admin->subscriptions,PUBSUB_ANY_SUB_TOPIC);
-
- if(any_sub==NULL){
-
- int i;
- pubsub_serializer_service_t *best_serializer = NULL;
- if( (status=pubsubAdmin_getBestSerializer(admin, subEP, &best_serializer)) == CELIX_SUCCESS){
- status = pubsub_topicSubscriptionCreate(admin->bundle_context, admin->ifIpAddress, PUBSUB_SUBSCRIBER_SCOPE_DEFAULT, PUBSUB_ANY_SUB_TOPIC, best_serializer, &any_sub);
- }
- else{
- printf("PSA_UDP_MC: Cannot find a serializer for subscribing topic %s. Adding it to pending list.\n",subEP->topic);
- celixThreadMutex_lock(&admin->noSerializerPendingsLock);
- arrayList_add(admin->noSerializerSubscriptions,subEP);
- celixThreadMutex_unlock(&admin->noSerializerPendingsLock);
- }
-
- if (status == CELIX_SUCCESS){
-
- /* Connect all internal publishers */
- celixThreadMutex_lock(&admin->localPublicationsLock);
- hash_map_iterator_pt lp_iter =hashMapIterator_create(admin->localPublications);
- while(hashMapIterator_hasNext(lp_iter)){
- service_factory_pt factory = (service_factory_pt)hashMapIterator_nextValue(lp_iter);
- topic_publication_pt topic_pubs = (topic_publication_pt)factory->handle;
- array_list_pt topic_publishers = pubsub_topicPublicationGetPublisherList(topic_pubs);
-
- if(topic_publishers!=NULL){
- for(i=0;i<arrayList_size(topic_publishers);i++){
- pubsub_endpoint_pt pubEP = (pubsub_endpoint_pt)arrayList_get(topic_publishers,i);
- if(pubEP->endpoint !=NULL){
- status += pubsub_topicSubscriptionConnectPublisher(any_sub,pubEP->endpoint);
- }
- }
- arrayList_destroy(topic_publishers);
- }
- }
- hashMapIterator_destroy(lp_iter);
- celixThreadMutex_unlock(&admin->localPublicationsLock);
-
- /* Connect also all external publishers */
- celixThreadMutex_lock(&admin->externalPublicationsLock);
- hash_map_iterator_pt extp_iter =hashMapIterator_create(admin->externalPublications);
- while(hashMapIterator_hasNext(extp_iter)){
- array_list_pt ext_pub_list = (array_list_pt)hashMapIterator_nextValue(extp_iter);
- if(ext_pub_list!=NULL){
- for(i=0;i<arrayList_size(ext_pub_list);i++){
- pubsub_endpoint_pt pubEP = (pubsub_endpoint_pt)arrayList_get(ext_pub_list,i);
- if(pubEP->endpoint !=NULL){
- status += pubsub_topicSubscriptionConnectPublisher(any_sub,pubEP->endpoint);
- }
- }
- }
- }
- hashMapIterator_destroy(extp_iter);
- celixThreadMutex_unlock(&admin->externalPublicationsLock);
-
-
- pubsub_topicSubscriptionAddSubscriber(any_sub,subEP);
-
- status += pubsub_topicSubscriptionStart(any_sub);
-
- }
-
- if (status == CELIX_SUCCESS){
- hashMap_put(admin->subscriptions,strdup(PUBSUB_ANY_SUB_TOPIC),any_sub);
- connectTopicPubSubToSerializer(admin, best_serializer, any_sub, false);
- }
-
- }
-
- celixThreadMutex_unlock(&admin->subscriptionsLock);
-
- return status;
-}
-
-celix_status_t pubsubAdmin_addSubscription(pubsub_admin_pt admin,pubsub_endpoint_pt subEP){
- celix_status_t status = CELIX_SUCCESS;
-
- printf("PSA_UDP_MC: Received subscription [FWUUID=%s bundleID=%ld scope=%s, topic=%s]\n",subEP->frameworkUUID,subEP->serviceID,subEP->scope,subEP->topic);
-
- if(strcmp(subEP->topic,PUBSUB_ANY_SUB_TOPIC)==0){
- return pubsubAdmin_addAnySubscription(admin,subEP);
- }
-
- /* Check if we already know some publisher about this topic, otherwise let's put the subscription in the pending hashmap */
- celixThreadMutex_lock(&admin->pendingSubscriptionsLock);
- celixThreadMutex_lock(&admin->subscriptionsLock);
- celixThreadMutex_lock(&admin->localPublicationsLock);
- celixThreadMutex_lock(&admin->externalPublicationsLock);
-
- char* scope_topic = createScopeTopicKey(subEP->scope,subEP->topic);
-
- service_factory_pt factory = (service_factory_pt)hashMap_get(admin->localPublications,scope_topic);
- array_list_pt ext_pub_list = (array_list_pt)hashMap_get(admin->externalPublications,scope_topic);
-
- if(factory==NULL && ext_pub_list==NULL){ //No (local or external) publishers yet for this topic
- pubsubAdmin_addSubscriptionToPendingList(admin,subEP);
- }
- else{
- int i;
- topic_subscription_pt subscription = hashMap_get(admin->subscriptions, scope_topic);
-
- if(subscription == NULL) {
- pubsub_serializer_service_t *best_serializer = NULL;
- if( (status=pubsubAdmin_getBestSerializer(admin, subEP, &best_serializer)) == CELIX_SUCCESS){
- status += pubsub_topicSubscriptionCreate(admin->bundle_context,admin->ifIpAddress, subEP->scope, subEP->topic, best_serializer, &subscription);
- }
- else{
- printf("PSA_UDP_MC: Cannot find a serializer for subscribing topic %s. Adding it to pending list.\n",subEP->topic);
- celixThreadMutex_lock(&admin->noSerializerPendingsLock);
- arrayList_add(admin->noSerializerSubscriptions,subEP);
- celixThreadMutex_unlock(&admin->noSerializerPendingsLock);
- }
-
- if (status==CELIX_SUCCESS){
-
- /* Try to connect internal publishers */
- if(factory!=NULL){
- topic_publication_pt topic_pubs = (topic_publication_pt)factory->handle;
- array_list_pt topic_publishers = pubsub_topicPublicationGetPublisherList(topic_pubs);
-
- if(topic_publishers!=NULL){
- for(i=0;i<arrayList_size(topic_publishers);i++){
- pubsub_endpoint_pt pubEP = (pubsub_endpoint_pt)arrayList_get(topic_publishers,i);
- if(pubEP->endpoint !=NULL){
- status += pubsub_topicSubscriptionConnectPublisher(subscription,pubEP->endpoint);
- }
- }
- arrayList_destroy(topic_publishers);
- }
-
- }
-
- /* Look also for external publishers */
- if(ext_pub_list!=NULL){
- for(i=0;i<arrayList_size(ext_pub_list);i++){
- pubsub_endpoint_pt pubEP = (pubsub_endpoint_pt)arrayList_get(ext_pub_list,i);
- if(pubEP->endpoint !=NULL){
- status += pubsub_topicSubscriptionConnectPublisher(subscription,pubEP->endpoint);
- }
- }
- }
-
- pubsub_topicSubscriptionAddSubscriber(subscription,subEP);
-
- status += pubsub_topicSubscriptionStart(subscription);
-
- }
-
- if(status==CELIX_SUCCESS){
-
- hashMap_put(admin->subscriptions,strdup(scope_topic),subscription);
-
- connectTopicPubSubToSerializer(admin, best_serializer, subscription, false);
- }
- }
-
- if (status == CELIX_SUCCESS){
- pubsub_topicIncreaseNrSubscribers(subscription);
- }
- }
-
- free(scope_topic);
- celixThreadMutex_unlock(&admin->externalPublicationsLock);
- celixThreadMutex_unlock(&admin->localPublicationsLock);
- celixThreadMutex_unlock(&admin->subscriptionsLock);
- celixThreadMutex_unlock(&admin->pendingSubscriptionsLock);
-
- return status;
-
-}
-
-celix_status_t pubsubAdmin_removeSubscription(pubsub_admin_pt admin,pubsub_endpoint_pt subEP){
- celix_status_t status = CELIX_SUCCESS;
-
- printf("PSA_UDP_MC: Removing subscription [FWUUID=%s bundleID=%ld scope=%s, topic=%s]\n",subEP->frameworkUUID,subEP->serviceID,subEP->scope, subEP->topic);
-
- char* scope_topic = createScopeTopicKey(subEP->scope, subEP->topic);
-
- celixThreadMutex_lock(&admin->subscriptionsLock);
- topic_subscription_pt sub = (topic_subscription_pt)hashMap_get(admin->subscriptions,scope_topic);
- if(sub!=NULL){
- pubsub_topicDecreaseNrSubscribers(sub);
- if(pubsub_topicGetNrSubscribers(sub) == 0) {
- status = pubsub_topicSubscriptionRemoveSubscriber(sub,subEP);
- }
- }
- celixThreadMutex_unlock(&admin->subscriptionsLock);
-
- if(sub==NULL){
- /* Maybe the endpoint was pending */
- celixThreadMutex_lock(&admin->noSerializerPendingsLock);
- if(!arrayList_removeElement(admin->noSerializerSubscriptions, subEP)){
- status = CELIX_ILLEGAL_STATE;
- }
- celixThreadMutex_unlock(&admin->noSerializerPendingsLock);
- }
-
- free(scope_topic);
-
-
-
- return status;
-
-}
-
-celix_status_t pubsubAdmin_addPublication(pubsub_admin_pt admin,pubsub_endpoint_pt pubEP){
- celix_status_t status = CELIX_SUCCESS;
-
- printf("PSA_UDP_MC: Received publication [FWUUID=%s bundleID=%ld scope=%s, topic=%s]\n",pubEP->frameworkUUID,pubEP->serviceID,pubEP->scope, pubEP->topic);
-
- const char* fwUUID = NULL;
-
- bundleContext_getProperty(admin->bundle_context,OSGI_FRAMEWORK_FRAMEWORK_UUID,&fwUUID);
- if(fwUUID==NULL){
- printf("PSA_UDP_MC: Cannot retrieve fwUUID.\n");
- return CELIX_INVALID_BUNDLE_CONTEXT;
- }
- char* scope_topic = createScopeTopicKey(pubEP->scope, pubEP->topic);
-
- if ((strcmp(pubEP->frameworkUUID, fwUUID) == 0) && (pubEP->endpoint == NULL)) {
-
- celixThreadMutex_lock(&admin->localPublicationsLock);
-
- service_factory_pt factory = (service_factory_pt) hashMap_get(admin->localPublications, scope_topic);
-
- if (factory == NULL) {
- topic_publication_pt pub = NULL;
- pubsub_serializer_service_t *best_serializer = NULL;
- if( (status=pubsubAdmin_getBestSerializer(admin, pubEP, &best_serializer)) == CELIX_SUCCESS){
- status = pubsub_topicPublicationCreate(admin->sendSocket, pubEP, best_serializer, admin->mcIpAddress, &pub);
- }
- else{
- printf("PSA_UDP_MC: Cannot find a serializer for publishing topic %s. Adding it to pending list.\n", pubEP->topic);
- celixThreadMutex_lock(&admin->noSerializerPendingsLock);
- arrayList_add(admin->noSerializerPublications,pubEP);
- celixThreadMutex_unlock(&admin->noSerializerPendingsLock);
- }
-
- if (status == CELIX_SUCCESS) {
- status = pubsub_topicPublicationStart(admin->bundle_context, pub, &factory);
- if (status == CELIX_SUCCESS && factory != NULL) {
- hashMap_put(admin->localPublications, strdup(scope_topic), factory);
- connectTopicPubSubToSerializer(admin, best_serializer, pub, true);
- }
- } else {
- printf("PSA_UDP_MC: Cannot create a topicPublication for scope=%s, topic=%s (bundle %ld).\n", pubEP->scope, pubEP->topic, pubEP->serviceID);
- }
- } else {
- //just add the new EP to the list
- topic_publication_pt pub = (topic_publication_pt) factory->handle;
- pubsub_topicPublicationAddPublisherEP(pub, pubEP);
- }
-
- celixThreadMutex_unlock(&admin->localPublicationsLock);
- }
- else{
-
- celixThreadMutex_lock(&admin->externalPublicationsLock);
- array_list_pt ext_pub_list = (array_list_pt) hashMap_get(admin->externalPublications, scope_topic);
- if (ext_pub_list == NULL) {
- arrayList_create(&ext_pub_list);
- hashMap_put(admin->externalPublications, strdup(scope_topic), ext_pub_list);
- }
-
- arrayList_add(ext_pub_list, pubEP);
-
- celixThreadMutex_unlock(&admin->externalPublicationsLock);
- }
-
- /* Re-evaluate the pending subscriptions */
- celixThreadMutex_lock(&admin->pendingSubscriptionsLock);
-
- hash_map_entry_pt pendingSub = hashMap_getEntry(admin->pendingSubscriptions, scope_topic);
- if (pendingSub != NULL) { //There were pending subscription for the just published topic. Let's connect them.
- char* topic = (char*) hashMapEntry_getKey(pendingSub);
- array_list_pt pendingSubList = (array_list_pt) hashMapEntry_getValue(pendingSub);
- int i;
- for (i = 0; i < arrayList_size(pendingSubList); i++) {
- pubsub_endpoint_pt subEP = (pubsub_endpoint_pt) arrayList_get(pendingSubList, i);
- pubsubAdmin_addSubscription(admin, subEP);
- }
- hashMap_remove(admin->pendingSubscriptions, scope_topic);
- arrayList_clear(pendingSubList);
- arrayList_destroy(pendingSubList);
- free(topic);
- }
-
- celixThreadMutex_unlock(&admin->pendingSubscriptionsLock);
-
- /* Connect the new publisher to the subscription for his topic, if there is any */
- celixThreadMutex_lock(&admin->subscriptionsLock);
-
- topic_subscription_pt sub = (topic_subscription_pt) hashMap_get(admin->subscriptions, scope_topic);
- if (sub != NULL && pubEP->endpoint != NULL) {
- pubsub_topicSubscriptionAddConnectPublisherToPendingList(sub, pubEP->endpoint);
- }
-
- /* And check also for ANY subscription */
- topic_subscription_pt any_sub = (topic_subscription_pt) hashMap_get(admin->subscriptions, PUBSUB_ANY_SUB_TOPIC);
- if (any_sub != NULL && pubEP->endpoint != NULL) {
- pubsub_topicSubscriptionAddConnectPublisherToPendingList(any_sub, pubEP->endpoint);
- }
-
- free(scope_topic);
-
- celixThreadMutex_unlock(&admin->subscriptionsLock);
-
- return status;
-
-}
-
-celix_status_t pubsubAdmin_removePublication(pubsub_admin_pt admin,pubsub_endpoint_pt pubEP){
- celix_status_t status = CELIX_SUCCESS;
- int count = 0;
-
- printf("PSA_UDP_MC: Removing publication [FWUUID=%s bundleID=%ld scope=%s, topic=%s]\n",pubEP->frameworkUUID,pubEP->serviceID,pubEP->scope, pubEP->topic);
-
- const char* fwUUID = NULL;
-
- bundleContext_getProperty(admin->bundle_context,OSGI_FRAMEWORK_FRAMEWORK_UUID,&fwUUID);
- if(fwUUID==NULL){
- printf("PSA_UDP_MC: Cannot retrieve fwUUID.\n");
- return CELIX_INVALID_BUNDLE_CONTEXT;
- }
- char *scope_topic = createScopeTopicKey(pubEP->scope, pubEP->topic);
-
- if(strcmp(pubEP->frameworkUUID,fwUUID)==0){
-
- celixThreadMutex_lock(&admin->localPublicationsLock);
- service_factory_pt factory = (service_factory_pt)hashMap_get(admin->localPublications,scope_topic);
- if(factory!=NULL){
- topic_publication_pt pub = (topic_publication_pt)factory->handle;
- pubsub_topicPublicationRemovePublisherEP(pub,pubEP);
- }
- celixThreadMutex_unlock(&admin->localPublicationsLock);
-
- if(factory==NULL){
- /* Maybe the endpoint was pending */
- celixThreadMutex_lock(&admin->noSerializerPendingsLock);
- if(!arrayList_removeElement(admin->noSerializerPublications, pubEP)){
- status = CELIX_ILLEGAL_STATE;
- }
- celixThreadMutex_unlock(&admin->noSerializerPendingsLock);
- }
-
- }
- else{
-
- celixThreadMutex_lock(&admin->externalPublicationsLock);
- array_list_pt ext_pub_list = (array_list_pt)hashMap_get(admin->externalPublications,scope_topic);
- if(ext_pub_list!=NULL){
- int i;
- bool found = false;
- for(i=0;!found && i<arrayList_size(ext_pub_list);i++){
- pubsub_endpoint_pt p = (pubsub_endpoint_pt)arrayList_get(ext_pub_list,i);
- found = pubsubEndpoint_equals(pubEP,p);
- if (found){
- arrayList_remove(ext_pub_list,i);
- }
- }
- // Check if there are more publishers on the same endpoint (happens when 1 celix-instance with multiple bundles publish in same topic)
- for(i=0; i<arrayList_size(ext_pub_list);i++) {
- pubsub_endpoint_pt p = (pubsub_endpoint_pt)arrayList_get(ext_pub_list,i);
- if (strcmp(pubEP->endpoint,p->endpoint) == 0) {
- count++;
- }
- }
-
- if(arrayList_size(ext_pub_list)==0){
- hash_map_entry_pt entry = hashMap_getEntry(admin->externalPublications,scope_topic);
- char* topic = (char*)hashMapEntry_getKey(entry);
- array_list_pt list = (array_list_pt)hashMapEntry_getValue(entry);
- hashMap_remove(admin->externalPublications,topic);
- arrayList_destroy(list);
- free(topic);
- }
- }
-
- celixThreadMutex_unlock(&admin->externalPublicationsLock);
- }
-
- /* Check if this publisher was connected to one of our subscribers*/
- celixThreadMutex_lock(&admin->subscriptionsLock);
-
- topic_subscription_pt sub = (topic_subscription_pt)hashMap_get(admin->subscriptions,scope_topic);
- if(sub!=NULL && pubEP->endpoint!=NULL && count == 0){
- pubsub_topicSubscriptionAddDisconnectPublisherToPendingList(sub,pubEP->endpoint);
- }
-
- /* And check also for ANY subscription */
- topic_subscription_pt any_sub = (topic_subscription_pt)hashMap_get(admin->subscriptions,PUBSUB_ANY_SUB_TOPIC);
- if(any_sub!=NULL && pubEP->endpoint!=NULL && count == 0){
- pubsub_topicSubscriptionAddDisconnectPublisherToPendingList(any_sub,pubEP->endpoint);
- }
-
- free(scope_topic);
- celixThreadMutex_unlock(&admin->subscriptionsLock);
-
- return status;
-
-}
-
-celix_status_t pubsubAdmin_closeAllPublications(pubsub_admin_pt admin,char *scope, char* topic){
- celix_status_t status = CELIX_SUCCESS;
-
- printf("PSA_UDP_MC: Closing all publications for scope=%s,topic=%s\n", scope, topic);
-
- celixThreadMutex_lock(&admin->localPublicationsLock);
- char* scope_topic =createScopeTopicKey(scope, topic);
- hash_map_entry_pt pubsvc_entry = (hash_map_entry_pt)hashMap_getEntry(admin->localPublications,scope_topic);
- if(pubsvc_entry!=NULL){
- char* key = (char*)hashMapEntry_getKey(pubsvc_entry);
- service_factory_pt factory= (service_factory_pt)hashMapEntry_getValue(pubsvc_entry);
- topic_publication_pt pub = (topic_publication_pt)factory->handle;
- status += pubsub_topicPublicationStop(pub);
- disconnectTopicPubSubFromSerializer(admin, pub, true);
- status += pubsub_topicPublicationDestroy(pub);
- hashMap_remove(admin->localPublications,scope_topic);
- free(key);
- free(factory);
- }
- free(scope_topic);
- celixThreadMutex_unlock(&admin->localPublicationsLock);
-
- return status;
-
-}
-
-celix_status_t pubsubAdmin_closeAllSubscriptions(pubsub_admin_pt admin,char *scope, char* topic){
- celix_status_t status = CELIX_SUCCESS;
-
- printf("PSA_UDP_MC: Closing all subscriptions\n");
-
- celixThreadMutex_lock(&admin->subscriptionsLock);
- char* scope_topic =createScopeTopicKey(scope, topic);
- hash_map_entry_pt sub_entry = (hash_map_entry_pt)hashMap_getEntry(admin->subscriptions,scope_topic);
- if(sub_entry!=NULL){
- char* topic = (char*)hashMapEntry_getKey(sub_entry);
-
- topic_subscription_pt ts = (topic_subscription_pt)hashMapEntry_getValue(sub_entry);
- status += pubsub_topicSubscriptionStop(ts);
- disconnectTopicPubSubFromSerializer(admin, ts, false);
- status += pubsub_topicSubscriptionDestroy(ts);
- hashMap_remove(admin->subscriptions,topic);
- free(topic);
-
- }
- free(scope_topic);
- celixThreadMutex_unlock(&admin->subscriptionsLock);
-
- return status;
-
-}
-
-
-#ifndef ANDROID
-static celix_status_t pubsubAdmin_getIpAddress(const char* interface, char** ip) {
- celix_status_t status = CELIX_BUNDLE_EXCEPTION;
-
- struct ifaddrs *ifaddr, *ifa;
- char host[NI_MAXHOST];
-
- if (getifaddrs(&ifaddr) != -1)
- {
- for (ifa = ifaddr; ifa != NULL && status != CELIX_SUCCESS; ifa = ifa->ifa_next)
- {
- if (ifa->ifa_addr == NULL)
- continue;
-
- if ((getnameinfo(ifa->ifa_addr,sizeof(struct sockaddr_in), host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST) == 0) && (ifa->ifa_addr->sa_family == AF_INET)) {
- if (interface == NULL) {
- *ip = strdup(host);
- status = CELIX_SUCCESS;
- }
- else if (strcmp(ifa->ifa_name, interface) == 0) {
- *ip = strdup(host);
- status = CELIX_SUCCESS;
- }
- }
- }
-
- freeifaddrs(ifaddr);
- }
-
- return status;
-}
-#endif
-
-static celix_status_t pubsubAdmin_addSubscriptionToPendingList(pubsub_admin_pt admin,pubsub_endpoint_pt subEP){
- celix_status_t status = CELIX_SUCCESS;
-
- char* scope_topic =createScopeTopicKey(subEP->scope, subEP->topic);
- array_list_pt pendingListPerTopic = hashMap_get(admin->pendingSubscriptions,scope_topic);
- if(pendingListPerTopic==NULL){
- arrayList_create(&pendingListPerTopic);
- hashMap_put(admin->pendingSubscriptions,strdup(scope_topic),pendingListPerTopic);
- }
- arrayList_add(pendingListPerTopic,subEP);
- free(scope_topic);
-
- return status;
-}
-
-
-celix_status_t pubsubAdmin_serializerAdded(void * handle, service_reference_pt reference, void * service){
- /* Assumption: serializers are all available at startup.
- * If a new (possibly better) serializer is installed and started, already created topic_publications/subscriptions will not be destroyed and recreated */
-
- celix_status_t status = CELIX_SUCCESS;
- int i=0;
-
- const char *serType = NULL;
- serviceReference_getProperty(reference, PUBSUB_SERIALIZER_TYPE_KEY,&serType);
- if(serType == NULL){
- printf("Serializer serviceReference %p has no pubsub_serializer.type property specified\n",reference);
- return CELIX_SERVICE_EXCEPTION;
- }
-
- pubsub_admin_pt admin = (pubsub_admin_pt)handle;
- celixThreadMutex_lock(&admin->serializerListLock);
- arrayList_add(admin->serializerList, reference);
- celixThreadMutex_unlock(&admin->serializerListLock);
-
- /* Now let's re-evaluate the pending */
- celixThreadMutex_lock(&admin->noSerializerPendingsLock);
-
- for(i=0;i<arrayList_size(admin->noSerializerSubscriptions);i++){
- pubsub_endpoint_pt ep = (pubsub_endpoint_pt)arrayList_get(admin->noSerializerSubscriptions,i);
- pubsub_serializer_service_t *best_serializer = NULL;
- pubsubAdmin_getBestSerializer(admin, ep, &best_serializer);
- if(best_serializer != NULL){ /* Finally we have a valid serializer! */
- pubsubAdmin_addSubscription(admin, ep);
- }
- }
-
- for(i=0;i<arrayList_size(admin->noSerializerPublications);i++){
- pubsub_endpoint_pt ep = (pubsub_endpoint_pt)arrayList_get(admin->noSerializerPublications,i);
- pubsub_serializer_service_t *best_serializer = NULL;
- pubsubAdmin_getBestSerializer(admin, ep, &best_serializer);
- if(best_serializer != NULL){ /* Finally we have a valid serializer! */
- pubsubAdmin_addPublication(admin, ep);
- }
- }
-
- celixThreadMutex_unlock(&admin->noSerializerPendingsLock);
-
- printf("PSA_UDP_MC: %s serializer added\n",serType);
-
- return status;
-}
-
-celix_status_t pubsubAdmin_serializerRemoved(void * handle, service_reference_pt reference, void * service){
-
- pubsub_admin_pt admin = (pubsub_admin_pt)handle;
- int i=0, j=0;
- const char *serType = NULL;
-
- serviceReference_getProperty(reference, PUBSUB_SERIALIZER_TYPE_KEY,&serType);
- if(serType == NULL){
- printf("Serializer serviceReference %p has no pubsub_serializer.type property specified\n",reference);
- return CELIX_SERVICE_EXCEPTION;
- }
-
- celixThreadMutex_lock(&admin->serializerListLock);
- /* Remove the serializer from the list */
- arrayList_removeElement(admin->serializerList, reference);
- celixThreadMutex_unlock(&admin->serializerListLock);
-
- celixThreadMutex_lock(&admin->usedSerializersLock);
- array_list_pt topicPubList = (array_list_pt)hashMap_remove(admin->topicPublicationsPerSerializer, service);
- array_list_pt topicSubList = (array_list_pt)hashMap_remove(admin->topicSubscriptionsPerSerializer, service);
- celixThreadMutex_unlock(&admin->usedSerializersLock);
-
- /* Now destroy the topicPublications, but first put back the pubsub_endpoints back to the noSerializer pending list */
- if(topicPubList!=NULL){
- for(i=0;i<arrayList_size(topicPubList);i++){
- topic_publication_pt topicPub = (topic_publication_pt)arrayList_get(topicPubList,i);
- /* Stop the topic publication */
- pubsub_topicPublicationStop(topicPub);
- /* Get the endpoints that are going to be orphan */
- array_list_pt pubList = pubsub_topicPublicationGetPublisherList(topicPub);
- for(j=0;j<arrayList_size(pubList);j++){
- pubsub_endpoint_pt pubEP = (pubsub_endpoint_pt)arrayList_get(pubList,j);
- /* Remove the publication */
- pubsubAdmin_removePublication(admin, pubEP);
- /* Reset the endpoint field, so that will be recreated from scratch when a new serializer will be found */
- if(pubEP->endpoint!=NULL){
- free(pubEP->endpoint);
- pubEP->endpoint = NULL;
- }
- /* Add the orphan endpoint to the noSerializer pending list */
- celixThreadMutex_lock(&admin->noSerializerPendingsLock);
- arrayList_add(admin->noSerializerPublications,pubEP);
- celixThreadMutex_unlock(&admin->noSerializerPendingsLock);
- }
- arrayList_destroy(pubList);
-
- /* Cleanup also the localPublications hashmap*/
- celixThreadMutex_lock(&admin->localPublicationsLock);
- hash_map_iterator_pt iter = hashMapIterator_create(admin->localPublications);
- char *key = NULL;
- service_factory_pt factory = NULL;
- while(hashMapIterator_hasNext(iter)){
- hash_map_entry_pt entry = hashMapIterator_nextEntry(iter);
- factory = (service_factory_pt)hashMapEntry_getValue(entry);
- topic_publication_pt pub = (topic_publication_pt)factory->handle;
- if(pub==topicPub){
- key = (char*)hashMapEntry_getKey(entry);
- break;
- }
- }
- hashMapIterator_destroy(iter);
- if(key!=NULL){
- hashMap_remove(admin->localPublications, key);
- free(factory);
- free(key);
- }
- celixThreadMutex_unlock(&admin->localPublicationsLock);
-
- /* Finally destroy the topicPublication */
- pubsub_topicPublicationDestroy(topicPub);
- }
- arrayList_destroy(topicPubList);
- }
-
- /* Now destroy the topicSubscriptions, but first put back the pubsub_endpoints back to the noSerializer pending list */
- if(topicSubList!=NULL){
- for(i=0;i<arrayList_size(topicSubList);i++){
- topic_subscription_pt topicSub = (topic_subscription_pt)arrayList_get(topicSubList,i);
- /* Stop the topic subscription */
- pubsub_topicSubscriptionStop(topicSub);
- /* Get the endpoints that are going to be orphan */
- array_list_pt subList = pubsub_topicSubscriptionGetSubscribersList(topicSub);
- for(j=0;j<arrayList_size(subList);j++){
- pubsub_endpoint_pt subEP = (pubsub_endpoint_pt)arrayList_get(subList,j);
- /* Remove the subscription */
- pubsubAdmin_removeSubscription(admin, subEP);
- /* Reset the endpoint field, so that will be recreated from scratch when a new serializer will be found */
- if(subEP->endpoint!=NULL){
- free(subEP->endpoint);
- subEP->endpoint = NULL;
- }
- /* Add the orphan endpoint to the noSerializer pending list */
- celixThreadMutex_lock(&admin->noSerializerPendingsLock);
- arrayList_add(admin->noSerializerSubscriptions,subEP);
- celixThreadMutex_unlock(&admin->noSerializerPendingsLock);
- }
-
- /* Cleanup also the subscriptions hashmap*/
- celixThreadMutex_lock(&admin->subscriptionsLock);
- hash_map_iterator_pt iter = hashMapIterator_create(admin->subscriptions);
- char *key = NULL;
- while(hashMapIterator_hasNext(iter)){
- hash_map_entry_pt entry = hashMapIterator_nextEntry(iter);
- topic_subscription_pt sub = (topic_subscription_pt)hashMapEntry_getValue(entry);
- if(sub==topicSub){
- key = (char*)hashMapEntry_getKey(entry);
- break;
- }
- }
- hashMapIterator_destroy(iter);
- if(key!=NULL){
- hashMap_remove(admin->subscriptions, key);
- free(key);
- }
- celixThreadMutex_unlock(&admin->subscriptionsLock);
-
- /* Finally destroy the topicSubscription */
- pubsub_topicSubscriptionDestroy(topicSub);
- }
- arrayList_destroy(topicSubList);
- }
-
- printf("PSA_UDP_MC: %s serializer removed\n",serType);
-
-
- return CELIX_SUCCESS;
-}
-
-celix_status_t pubsubAdmin_matchEndpoint(pubsub_admin_pt admin, pubsub_endpoint_pt endpoint, double* score){
- celix_status_t status = CELIX_SUCCESS;
-
- celixThreadMutex_lock(&admin->serializerListLock);
- status = pubsub_admin_match(endpoint->topic_props,PUBSUB_ADMIN_TYPE,admin->serializerList,score);
- celixThreadMutex_unlock(&admin->serializerListLock);
-
- return status;
-}
-
-/* This one recall the same logic as in the match function */
-static celix_status_t pubsubAdmin_getBestSerializer(pubsub_admin_pt admin,pubsub_endpoint_pt ep, pubsub_serializer_service_t **serSvc){
-
- celix_status_t status = CELIX_SUCCESS;
-
- celixThreadMutex_lock(&admin->serializerListLock);
- status = pubsub_admin_get_best_serializer(ep->topic_props, admin->serializerList, serSvc);
- celixThreadMutex_unlock(&admin->serializerListLock);
-
- return status;
-
-}
-
-static void connectTopicPubSubToSerializer(pubsub_admin_pt admin,pubsub_serializer_service_t *serializer,void *topicPubSub,bool isPublication){
-
- celixThreadMutex_lock(&admin->usedSerializersLock);
-
- hash_map_pt map = isPublication?admin->topicPublicationsPerSerializer:admin->topicSubscriptionsPerSerializer;
- array_list_pt list = (array_list_pt)hashMap_get(map,serializer);
- if(list==NULL){
- arrayList_create(&list);
- hashMap_put(map,serializer,list);
- }
- arrayList_add(list,topicPubSub);
-
- celixThreadMutex_unlock(&admin->usedSerializersLock);
-
-}
-
-static void disconnectTopicPubSubFromSerializer(pubsub_admin_pt admin,void *topicPubSub,bool isPublication){
-
- celixThreadMutex_lock(&admin->usedSerializersLock);
-
- hash_map_pt map = isPublication?admin->topicPublicationsPerSerializer:admin->topicSubscriptionsPerSerializer;
- hash_map_iterator_pt iter = hashMapIterator_create(map);
- while(hashMapIterator_hasNext(iter)){
- array_list_pt list = (array_list_pt)hashMapIterator_nextValue(iter);
- if(arrayList_removeElement(list, topicPubSub)){ //Found it!
- break;
- }
- }
- hashMapIterator_destroy(iter);
-
- celixThreadMutex_unlock(&admin->usedSerializersLock);
-
-}
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/pubsub/pubsub_admin_udp_mc/private/src/topic_publication.c
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_admin_udp_mc/private/src/topic_publication.c b/pubsub/pubsub_admin_udp_mc/private/src/topic_publication.c
deleted file mode 100644
index e43ec29..0000000
--- a/pubsub/pubsub_admin_udp_mc/private/src/topic_publication.c
+++ /dev/null
@@ -1,444 +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
- *
- * htPSA_UDP_MC_TP://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.
- */
-/*
- * topic_publication.c
- *
- * \date Sep 24, 2015
- * \author <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- * \copyright Apache License, Version 2.0
- */
-
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <errno.h>
-
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-
-#include "array_list.h"
-#include "celixbool.h"
-#include "service_registration.h"
-#include "utils.h"
-#include "service_factory.h"
-#include "version.h"
-
-#include "topic_publication.h"
-#include "pubsub_common.h"
-#include "publisher.h"
-#include "large_udp.h"
-
-#include "pubsub_serializer.h"
-
-#define EP_ADDRESS_LEN 32
-
-#define FIRST_SEND_DELAY 2
-
-struct topic_publication {
- int sendSocket;
- char* endpoint;
- service_registration_pt svcFactoryReg;
- array_list_pt pub_ep_list; //List<pubsub_endpoint>
- hash_map_pt boundServices; //<bundle_pt,bound_service>
- celix_thread_mutex_t tp_lock;
- pubsub_serializer_service_t *serializer;
- struct sockaddr_in destAddr;
-};
-
-typedef struct publish_bundle_bound_service {
- topic_publication_pt parent;
- pubsub_publisher_t service;
- bundle_pt bundle;
- char *scope;
- char *topic;
- hash_map_pt msgTypes;
- unsigned short getCount;
- celix_thread_mutex_t mp_lock;
- largeUdp_pt largeUdpHandle;
-}* publish_bundle_bound_service_pt;
-
-
-typedef struct pubsub_msg{
- pubsub_msg_header_pt header;
- char* payload;
- unsigned int payloadSize;
-} pubsub_msg_t;
-
-
-static unsigned int rand_range(unsigned int min, unsigned int max);
-
-static celix_status_t pubsub_topicPublicationGetService(void* handle, bundle_pt bundle, service_registration_pt registration, void **service);
-static celix_status_t pubsub_topicPublicationUngetService(void* handle, bundle_pt bundle, service_registration_pt registration, void **service);
-
-static publish_bundle_bound_service_pt pubsub_createPublishBundleBoundService(topic_publication_pt tp,bundle_pt bundle);
-static void pubsub_destroyPublishBundleBoundService(publish_bundle_bound_service_pt boundSvc);
-
-static int pubsub_topicPublicationSend(void* handle,unsigned int msgTypeId, const void *msg);
-
-static int pubsub_localMsgTypeIdForUUID(void* handle, const char* msgType, unsigned int* msgTypeId);
-
-
-static void delay_first_send_for_late_joiners(void);
-
-
-celix_status_t pubsub_topicPublicationCreate(int sendSocket, pubsub_endpoint_pt pubEP, pubsub_serializer_service_t *best_serializer, char* bindIP, topic_publication_pt *out){
-
- char* ep = malloc(EP_ADDRESS_LEN);
- memset(ep,0,EP_ADDRESS_LEN);
- unsigned int port = pubEP->serviceID + rand_range(UDP_BASE_PORT+pubEP->serviceID+3, UDP_MAX_PORT);
- snprintf(ep,EP_ADDRESS_LEN,"udp://%s:%u",bindIP,port);
-
-
- topic_publication_pt pub = calloc(1,sizeof(*pub));
-
- arrayList_create(&(pub->pub_ep_list));
- pub->boundServices = hashMap_create(NULL,NULL,NULL,NULL);
- celixThreadMutex_create(&(pub->tp_lock),NULL);
-
- pub->endpoint = ep;
- pub->sendSocket = sendSocket;
- pub->destAddr.sin_family = AF_INET;
- pub->destAddr.sin_addr.s_addr = inet_addr(bindIP);
- pub->destAddr.sin_port = htons(port);
-
- pub->serializer = best_serializer;
-
- pubsub_topicPublicationAddPublisherEP(pub,pubEP);
-
- *out = pub;
-
- return CELIX_SUCCESS;
-}
-
-celix_status_t pubsub_topicPublicationDestroy(topic_publication_pt pub){
- celix_status_t status = CELIX_SUCCESS;
-
- celixThreadMutex_lock(&(pub->tp_lock));
-
- free(pub->endpoint);
- arrayList_destroy(pub->pub_ep_list);
-
- hash_map_iterator_pt iter = hashMapIterator_create(pub->boundServices);
- while(hashMapIterator_hasNext(iter)){
- publish_bundle_bound_service_pt bound = hashMapIterator_nextValue(iter);
- pubsub_destroyPublishBundleBoundService(bound);
- }
- hashMapIterator_destroy(iter);
- hashMap_destroy(pub->boundServices,false,false);
-
- pub->svcFactoryReg = NULL;
- pub->serializer = NULL;
-
- if(close(pub->sendSocket) != 0){
- status = CELIX_FILE_IO_EXCEPTION;
- }
-
- celixThreadMutex_unlock(&(pub->tp_lock));
-
- celixThreadMutex_destroy(&(pub->tp_lock));
-
- free(pub);
-
- return status;
-}
-
-celix_status_t pubsub_topicPublicationStart(bundle_context_pt bundle_context,topic_publication_pt pub,service_factory_pt* svcFactory){
- celix_status_t status = CELIX_SUCCESS;
-
- /* Let's register the new service */
-
- pubsub_endpoint_pt pubEP = (pubsub_endpoint_pt)arrayList_get(pub->pub_ep_list,0);
-
- if(pubEP!=NULL){
- service_factory_pt factory = calloc(1, sizeof(*factory));
- factory->handle = pub;
- factory->getService = pubsub_topicPublicationGetService;
- factory->ungetService = pubsub_topicPublicationUngetService;
-
- properties_pt props = properties_create();
- properties_set(props,PUBSUB_PUBLISHER_SCOPE,pubEP->scope);
- properties_set(props,PUBSUB_PUBLISHER_TOPIC,pubEP->topic);
-
- status = bundleContext_registerServiceFactory(bundle_context,PUBSUB_PUBLISHER_SERVICE_NAME,factory,props,&(pub->svcFactoryReg));
-
- if(status != CELIX_SUCCESS){
- properties_destroy(props);
- printf("PSA_UDP_MC_PSA_UDP_MC_TP: Cannot register ServiceFactory for topic %s, topic %s (bundle %ld).\n",pubEP->scope, pubEP->topic,pubEP->serviceID);
- }
- else{
- *svcFactory = factory;
- }
- }
- else{
- printf("PSA_UDP_MC_PSA_UDP_MC_TP: Cannot find pubsub_endpoint after adding it...Should never happen!\n");
- status = CELIX_SERVICE_EXCEPTION;
- }
-
- return status;
-}
-
-celix_status_t pubsub_topicPublicationStop(topic_publication_pt pub){
- return serviceRegistration_unregister(pub->svcFactoryReg);
-}
-
-celix_status_t pubsub_topicPublicationAddPublisherEP(topic_publication_pt pub,pubsub_endpoint_pt ep){
-
- celixThreadMutex_lock(&(pub->tp_lock));
- ep->endpoint = strdup(pub->endpoint);
- arrayList_add(pub->pub_ep_list,ep);
- celixThreadMutex_unlock(&(pub->tp_lock));
-
- return CELIX_SUCCESS;
-}
-
-celix_status_t pubsub_topicPublicationRemovePublisherEP(topic_publication_pt pub,pubsub_endpoint_pt ep){
-
- celixThreadMutex_lock(&(pub->tp_lock));
- arrayList_removeElement(pub->pub_ep_list,ep);
- celixThreadMutex_unlock(&(pub->tp_lock));
-
- return CELIX_SUCCESS;
-}
-
-array_list_pt pubsub_topicPublicationGetPublisherList(topic_publication_pt pub){
- array_list_pt list = NULL;
- celixThreadMutex_lock(&(pub->tp_lock));
- list = arrayList_clone(pub->pub_ep_list);
- celixThreadMutex_unlock(&(pub->tp_lock));
- return list;
-}
-
-
-static celix_status_t pubsub_topicPublicationGetService(void* handle, bundle_pt bundle, service_registration_pt registration, void **service) {
- celix_status_t status = CELIX_SUCCESS;
-
- topic_publication_pt publish = (topic_publication_pt)handle;
-
- celixThreadMutex_lock(&(publish->tp_lock));
-
- publish_bundle_bound_service_pt bound = (publish_bundle_bound_service_pt)hashMap_get(publish->boundServices,bundle);
- if(bound==NULL){
- bound = pubsub_createPublishBundleBoundService(publish,bundle);
- if(bound!=NULL){
- hashMap_put(publish->boundServices,bundle,bound);
- }
- }
- else{
- bound->getCount++;
- }
-
- if (bound != NULL) {
- *service = &bound->service;
- }
-
- celixThreadMutex_unlock(&(publish->tp_lock));
-
- return status;
-}
-
-static celix_status_t pubsub_topicPublicationUngetService(void* handle, bundle_pt bundle, service_registration_pt registration, void **service) {
-
- topic_publication_pt publish = (topic_publication_pt)handle;
-
- celixThreadMutex_lock(&(publish->tp_lock));
-
- publish_bundle_bound_service_pt bound = (publish_bundle_bound_service_pt)hashMap_get(publish->boundServices,bundle);
- if(bound!=NULL){
-
- bound->getCount--;
- if(bound->getCount==0){
- pubsub_destroyPublishBundleBoundService(bound);
- hashMap_remove(publish->boundServices,bundle);
- }
-
- }
- else{
- long bundleId = -1;
- bundle_getBundleId(bundle,&bundleId);
- printf("PSA_UDP_MC_TP: Unexpected ungetService call for bundle %ld.\n", bundleId);
- }
-
- /* service should be never used for unget, so let's set the pointer to NULL */
- *service = NULL;
-
- celixThreadMutex_unlock(&(publish->tp_lock));
-
- return CELIX_SUCCESS;
-}
-
-static bool send_pubsub_msg(publish_bundle_bound_service_pt bound, pubsub_msg_t* msg, bool last, pubsub_release_callback_t *releaseCallback){
- const int iovec_len = 3; // header + size + payload
- bool ret = true;
-
- struct iovec msg_iovec[iovec_len];
- msg_iovec[0].iov_base = msg->header;
- msg_iovec[0].iov_len = sizeof(*msg->header);
- msg_iovec[1].iov_base = &msg->payloadSize;
- msg_iovec[1].iov_len = sizeof(msg->payloadSize);
- msg_iovec[2].iov_base = msg->payload;
- msg_iovec[2].iov_len = msg->payloadSize;
-
- delay_first_send_for_late_joiners();
-
- if(largeUdp_sendmsg(bound->largeUdpHandle, bound->parent->sendSocket, msg_iovec, iovec_len, 0, &bound->parent->destAddr, sizeof(bound->parent->destAddr)) == -1) {
- perror("send_pubsub_msg:sendSocket");
- ret = false;
- }
-
- if(releaseCallback) {
- releaseCallback->release(msg->payload, bound);
- }
- return ret;
-
-}
-
-
-static int pubsub_topicPublicationSend(void* handle, unsigned int msgTypeId, const void *inMsg) {
- int status = 0;
- publish_bundle_bound_service_pt bound = (publish_bundle_bound_service_pt) handle;
-
- celixThreadMutex_lock(&(bound->parent->tp_lock));
- celixThreadMutex_lock(&(bound->mp_lock));
-
- pubsub_msg_serializer_t* msgSer = (pubsub_msg_serializer_t*)hashMap_get(bound->msgTypes, (void*)(uintptr_t)msgTypeId);
-
- if (msgSer != NULL) {
- int major=0, minor=0;
-
- pubsub_msg_header_pt msg_hdr = calloc(1,sizeof(struct pubsub_msg_header));
- strncpy(msg_hdr->topic,bound->topic,MAX_TOPIC_LEN-1);
- msg_hdr->type = msgTypeId;
-
-
- if (msgSer->msgVersion != NULL){
- version_getMajor(msgSer->msgVersion, &major);
- version_getMinor(msgSer->msgVersion, &minor);
- msg_hdr->major = major;
- msg_hdr->minor = minor;
- }
-
- void* serializedOutput = NULL;
- size_t serializedOutputLen = 0;
- msgSer->serialize(msgSer,inMsg,&serializedOutput, &serializedOutputLen);
-
- pubsub_msg_t *msg = calloc(1,sizeof(pubsub_msg_t));
- msg->header = msg_hdr;
- msg->payload = (char*)serializedOutput;
- msg->payloadSize = serializedOutputLen;
-
-
- if(send_pubsub_msg(bound, msg,true, NULL) == false) {
- status = -1;
- }
- free(msg_hdr);
- free(msg);
- free(serializedOutput);
-
-
- } else {
- printf("PSA_UDP_MC_TP: No msg serializer available for msg type id %d\n", msgTypeId);
- status=-1;
- }
-
- celixThreadMutex_unlock(&(bound->mp_lock));
- celixThreadMutex_unlock(&(bound->parent->tp_lock));
-
- return status;
-}
-
-static int pubsub_localMsgTypeIdForUUID(void* handle, const char* msgType, unsigned int* msgTypeId){
- *msgTypeId = utils_stringHash(msgType);
- return 0;
-}
-
-
-static unsigned int rand_range(unsigned int min, unsigned int max){
-
- double scaled = (double)(((double)random())/((double)RAND_MAX));
- return (max-min+1)*scaled + min;
-
-}
-
-static publish_bundle_bound_service_pt pubsub_createPublishBundleBoundService(topic_publication_pt tp,bundle_pt bundle){
-
- publish_bundle_bound_service_pt bound = calloc(1, sizeof(*bound));
-
- if (bound != NULL) {
-
- bound->parent = tp;
- bound->bundle = bundle;
- bound->getCount = 1;
- celixThreadMutex_create(&bound->mp_lock,NULL);
-
- if(tp->serializer != NULL){
- tp->serializer->createSerializerMap(tp->serializer->handle,bundle,&bound->msgTypes);
- }
-
- pubsub_endpoint_pt pubEP = (pubsub_endpoint_pt)arrayList_get(bound->parent->pub_ep_list,0);
- bound->scope=strdup(pubEP->scope);
- bound->topic=strdup(pubEP->topic);
- bound->largeUdpHandle = largeUdp_create(1);
-
- bound->service.handle = bound;
- bound->service.localMsgTypeIdForMsgType = pubsub_localMsgTypeIdForUUID;
- bound->service.send = pubsub_topicPublicationSend;
- bound->service.sendMultipart = NULL; //Multipart not supported for UDP
-
- }
-
- return bound;
-}
-
-static void pubsub_destroyPublishBundleBoundService(publish_bundle_bound_service_pt boundSvc){
-
- celixThreadMutex_lock(&boundSvc->mp_lock);
-
- if(boundSvc->parent->serializer != NULL && boundSvc->msgTypes != NULL){
- boundSvc->parent->serializer->destroySerializerMap(boundSvc->parent->serializer->handle, boundSvc->msgTypes);
- }
-
- if(boundSvc->scope!=NULL){
- free(boundSvc->scope);
- }
-
- if(boundSvc->topic!=NULL){
- free(boundSvc->topic);
- }
-
- largeUdp_destroy(boundSvc->largeUdpHandle);
-
- celixThreadMutex_unlock(&boundSvc->mp_lock);
- celixThreadMutex_destroy(&boundSvc->mp_lock);
-
- free(boundSvc);
-
-}
-
-static void delay_first_send_for_late_joiners(){
-
- static bool firstSend = true;
-
- if(firstSend){
- printf("PSA_UDP_MC_TP: Delaying first send for late joiners...\n");
- sleep(FIRST_SEND_DELAY);
- firstSend = false;
- }
-}
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/pubsub/pubsub_admin_udp_mc/private/src/topic_subscription.c
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_admin_udp_mc/private/src/topic_subscription.c b/pubsub/pubsub_admin_udp_mc/private/src/topic_subscription.c
deleted file mode 100644
index d8e6f45..0000000
--- a/pubsub/pubsub_admin_udp_mc/private/src/topic_subscription.c
+++ /dev/null
@@ -1,635 +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.
- */
-/*
- * topic_subscription.c
- *
- * \date Oct 2, 2015
- * \author <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- * \copyright Apache License, Version 2.0
- */
-
-#include <string.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <signal.h>
-
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/epoll.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-
-#include "utils.h"
-#include "celix_errno.h"
-#include "constants.h"
-#include "version.h"
-
-#include "topic_subscription.h"
-#include "topic_publication.h"
-#include "subscriber.h"
-#include "publisher.h"
-#include "large_udp.h"
-
-#include "pubsub_serializer.h"
-
-#define MAX_EPOLL_EVENTS 10
-#define RECV_THREAD_TIMEOUT 5
-#define UDP_BUFFER_SIZE 65535
-#define MAX_UDP_SESSIONS 16
-
-struct topic_subscription{
- char* ifIpAddress;
- service_tracker_pt tracker;
- array_list_pt sub_ep_list;
- celix_thread_t recv_thread;
- bool running;
- celix_thread_mutex_t ts_lock;
- bundle_context_pt context;
-
- pubsub_serializer_service_t *serializer;
-
- int topicEpollFd; // EPOLL filedescriptor where the sockets are registered.
- hash_map_pt servicesMap; // key = service, value = msg types map
- hash_map_pt socketMap; // key = URL, value = listen-socket
- celix_thread_mutex_t socketMap_lock;
-
- celix_thread_mutex_t pendingConnections_lock;
- array_list_pt pendingConnections;
-
- array_list_pt pendingDisconnections;
- celix_thread_mutex_t pendingDisconnections_lock;
-
- //array_list_pt rawServices;
- unsigned int nrSubscribers;
- largeUdp_pt largeUdpHandle;
-};
-
-typedef struct msg_map_entry{
- bool retain;
- void* msgInst;
-}* msg_map_entry_pt;
-
-static celix_status_t topicsub_subscriberTracked(void * handle, service_reference_pt reference, void * service);
-static celix_status_t topicsub_subscriberUntracked(void * handle, service_reference_pt reference, void * service);
-static void* udp_recv_thread_func(void* arg);
-static bool checkVersion(version_pt msgVersion,pubsub_msg_header_pt hdr);
-static void sigusr1_sighandler(int signo);
-static int pubsub_localMsgTypeIdForMsgType(void* handle, const char* msgType, unsigned int* msgTypeId);
-static void connectPendingPublishers(topic_subscription_pt sub);
-static void disconnectPendingPublishers(topic_subscription_pt sub);
-
-
-celix_status_t pubsub_topicSubscriptionCreate(bundle_context_pt bundle_context, char* ifIp,char* scope, char* topic ,pubsub_serializer_service_t *best_serializer, topic_subscription_pt* out){
- celix_status_t status = CELIX_SUCCESS;
-
- topic_subscription_pt ts = (topic_subscription_pt) calloc(1,sizeof(*ts));
- ts->context = bundle_context;
- ts->ifIpAddress = strdup(ifIp);
-#if defined(__APPLE__) && defined(__MACH__)
- //TODO: Use kqueue for OSX
-#else
- ts->topicEpollFd = epoll_create1(0);
-#endif
- if(ts->topicEpollFd == -1) {
- status += CELIX_SERVICE_EXCEPTION;
- }
-
- ts->running = false;
- ts->nrSubscribers = 0;
- ts->serializer = best_serializer;
-
- celixThreadMutex_create(&ts->ts_lock,NULL);
- arrayList_create(&ts->sub_ep_list);
- ts->servicesMap = hashMap_create(NULL, NULL, NULL, NULL);
- ts->socketMap = hashMap_create(utils_stringHash, NULL, utils_stringEquals, NULL);
-
- arrayList_create(&ts->pendingConnections);
- arrayList_create(&ts->pendingDisconnections);
- celixThreadMutex_create(&ts->pendingConnections_lock, NULL);
- celixThreadMutex_create(&ts->pendingDisconnections_lock, NULL);
- celixThreadMutex_create(&ts->socketMap_lock, NULL);
-
- ts->largeUdpHandle = largeUdp_create(MAX_UDP_SESSIONS);
-
- char filter[128];
- memset(filter,0,128);
- if(strncmp(PUBSUB_SUBSCRIBER_SCOPE_DEFAULT, scope, strlen(PUBSUB_SUBSCRIBER_SCOPE_DEFAULT)) == 0) {
- // default scope, means that subscriber has not defined a scope property
- snprintf(filter, 128, "(&(%s=%s)(%s=%s))",
- (char*) OSGI_FRAMEWORK_OBJECTCLASS, PUBSUB_SUBSCRIBER_SERVICE_NAME,
- PUBSUB_SUBSCRIBER_TOPIC,topic);
-
- } else {
- snprintf(filter, 128, "(&(%s=%s)(%s=%s)(%s=%s))",
- (char*) OSGI_FRAMEWORK_OBJECTCLASS, PUBSUB_SUBSCRIBER_SERVICE_NAME,
- PUBSUB_SUBSCRIBER_TOPIC,topic,
- PUBSUB_SUBSCRIBER_SCOPE,scope);
- }
-
- service_tracker_customizer_pt customizer = NULL;
- status += serviceTrackerCustomizer_create(ts,NULL,topicsub_subscriberTracked,NULL,topicsub_subscriberUntracked,&customizer);
- status += serviceTracker_createWithFilter(bundle_context, filter, customizer, &ts->tracker);
-
- struct sigaction actions;
- memset(&actions, 0, sizeof(actions));
- sigemptyset(&actions.sa_mask);
- actions.sa_flags = 0;
- actions.sa_handler = sigusr1_sighandler;
-
- sigaction(SIGUSR1,&actions,NULL);
-
- if (status == CELIX_SUCCESS) {
- *out=ts;
- }
-
- return status;
-}
-
-celix_status_t pubsub_topicSubscriptionDestroy(topic_subscription_pt ts){
- celix_status_t status = CELIX_SUCCESS;
-
- celixThreadMutex_lock(&ts->ts_lock);
- ts->running = false;
- free(ts->ifIpAddress);
- serviceTracker_destroy(ts->tracker);
- arrayList_clear(ts->sub_ep_list);
- arrayList_destroy(ts->sub_ep_list);
- hashMap_destroy(ts->servicesMap,false,false);
-
- celixThreadMutex_lock(&ts->socketMap_lock);
- hashMap_destroy(ts->socketMap,true,true);
- celixThreadMutex_unlock(&ts->socketMap_lock);
- celixThreadMutex_destroy(&ts->socketMap_lock);
-
- celixThreadMutex_lock(&ts->pendingConnections_lock);
- arrayList_destroy(ts->pendingConnections);
- celixThreadMutex_unlock(&ts->pendingConnections_lock);
- celixThreadMutex_destroy(&ts->pendingConnections_lock);
-
- celixThreadMutex_lock(&ts->pendingDisconnections_lock);
- arrayList_destroy(ts->pendingDisconnections);
- celixThreadMutex_unlock(&ts->pendingDisconnections_lock);
- celixThreadMutex_destroy(&ts->pendingDisconnections_lock);
-
- largeUdp_destroy(ts->largeUdpHandle);
-#if defined(__APPLE__) && defined(__MACH__)
- //TODO: Use kqueue for OSX
-#else
- close(ts->topicEpollFd);
-#endif
-
- celixThreadMutex_unlock(&ts->ts_lock);
-
- celixThreadMutex_destroy(&ts->ts_lock);
-
- free(ts);
-
- return status;
-}
-
-celix_status_t pubsub_topicSubscriptionStart(topic_subscription_pt ts){
- celix_status_t status = CELIX_SUCCESS;
-
- status = serviceTracker_open(ts->tracker);
-
- ts->running = true;
-
- if(status==CELIX_SUCCESS){
- status=celixThread_create(&ts->recv_thread,NULL,udp_recv_thread_func,ts);
- }
-
- return status;
-}
-
-celix_status_t pubsub_topicSubscriptionStop(topic_subscription_pt ts){
- celix_status_t status = CELIX_SUCCESS;
- struct epoll_event ev;
- memset(&ev, 0, sizeof(ev));
-
- ts->running = false;
-
- pthread_kill(ts->recv_thread.thread,SIGUSR1);
-
- celixThread_join(ts->recv_thread,NULL);
-
- status = serviceTracker_close(ts->tracker);
-
- celixThreadMutex_lock(&ts->socketMap_lock);
- hash_map_iterator_pt it = hashMapIterator_create(ts->socketMap);
- while(hashMapIterator_hasNext(it)) {
- hash_map_entry_pt entry = hashMapIterator_nextEntry(it);
- char *url = hashMapEntry_getKey(entry);
- int *s = hashMapEntry_getValue(entry);
- memset(&ev, 0, sizeof(ev));
- if(epoll_ctl(ts->topicEpollFd, EPOLL_CTL_DEL, *s, &ev) == -1) {
- printf("in if error()\n");
- perror("epoll_ctl() EPOLL_CTL_DEL");
- status += CELIX_SERVICE_EXCEPTION;
- }
- free(s);
- free(url);
- //hashMapIterator_remove(it);
- }
- hashMapIterator_destroy(it);
- hashMap_clear(ts->socketMap, false, false);
- celixThreadMutex_unlock(&ts->socketMap_lock);
-
-
- return status;
-}
-
-celix_status_t pubsub_topicSubscriptionConnectPublisher(topic_subscription_pt ts, char* pubURL) {
-
- printf("pubsub_topicSubscriptionConnectPublisher : pubURL = %s\n", pubURL);
-
- celix_status_t status = CELIX_SUCCESS;
-
- celixThreadMutex_lock(&ts->socketMap_lock);
-
- if(!hashMap_containsKey(ts->socketMap, pubURL)){
-
- int *recvSocket = calloc(sizeof(int), 1);
- *recvSocket = socket(AF_INET, SOCK_DGRAM, 0);
- if (*recvSocket < 0) {
- perror("pubsub_topicSubscriptionCreate:socket");
- status = CELIX_SERVICE_EXCEPTION;
- }
-
- if (status == CELIX_SUCCESS){
- int reuse = 1;
- if (setsockopt(*recvSocket, SOL_SOCKET, SO_REUSEADDR, (char*) &reuse, sizeof(reuse)) != 0) {
- perror("setsockopt() SO_REUSEADDR");
- status = CELIX_SERVICE_EXCEPTION;
- }
- }
-
- if(status == CELIX_SUCCESS){
- // TODO Check if there is a better way to parse the URL to IP/Portnr
- //replace ':' by spaces
- char *url = strdup(pubURL);
- char *pt = url;
- while((pt=strchr(pt, ':')) != NULL) {
- *pt = ' ';
- }
- char mcIp[100];
- unsigned short mcPort;
- sscanf(url, "udp //%s %hu", mcIp, &mcPort);
- free(url);
-
- printf("pubsub_topicSubscriptionConnectPublisher : IP = %s, Port = %hu\n", mcIp, mcPort);
-
- struct ip_mreq mc_addr;
- mc_addr.imr_multiaddr.s_addr = inet_addr(mcIp);
- mc_addr.imr_interface.s_addr = inet_addr(ts->ifIpAddress);
- printf("Adding MC %s at interface %s\n", mcIp, ts->ifIpAddress);
- if (setsockopt(*recvSocket, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char*) &mc_addr, sizeof(mc_addr)) != 0) {
- perror("setsockopt() IP_ADD_MEMBERSHIP");
- status = CELIX_SERVICE_EXCEPTION;
- }
-
- if (status == CELIX_SUCCESS){
- struct sockaddr_in mcListenAddr;
- mcListenAddr.sin_family = AF_INET;
- mcListenAddr.sin_addr.s_addr = INADDR_ANY;
- mcListenAddr.sin_port = htons(mcPort);
- if(bind(*recvSocket, (struct sockaddr*)&mcListenAddr, sizeof(mcListenAddr)) != 0) {
- perror("bind()");
- status = CELIX_SERVICE_EXCEPTION;
- }
- }
-
- if (status == CELIX_SUCCESS){
-#if defined(__APPLE__) && defined(__MACH__)
- //TODO: Use kqueue for OSX
-#else
- struct epoll_event ev;
- memset(&ev, 0, sizeof(ev));
- ev.events = EPOLLIN;
- ev.data.fd = *recvSocket;
- if(epoll_ctl(ts->topicEpollFd, EPOLL_CTL_ADD, *recvSocket, &ev) == -1) {
- perror("epoll_ctl() EPOLL_CTL_ADD");
- status = CELIX_SERVICE_EXCEPTION;
- }
-#endif
- }
-
- }
-
- if (status == CELIX_SUCCESS){
- hashMap_put(ts->socketMap, strdup(pubURL), (void*)recvSocket);
- }
- else{
- free(recvSocket);
- }
- }
-
- celixThreadMutex_unlock(&ts->socketMap_lock);
-
- return status;
-}
-
-celix_status_t pubsub_topicSubscriptionAddConnectPublisherToPendingList(topic_subscription_pt ts, char* pubURL) {
- celix_status_t status = CELIX_SUCCESS;
- char *url = strdup(pubURL);
- celixThreadMutex_lock(&ts->pendingConnections_lock);
- arrayList_add(ts->pendingConnections, url);
- celixThreadMutex_unlock(&ts->pendingConnections_lock);
- return status;
-}
-
-celix_status_t pubsub_topicSubscriptionAddDisconnectPublisherToPendingList(topic_subscription_pt ts, char* pubURL) {
- celix_status_t status = CELIX_SUCCESS;
- char *url = strdup(pubURL);
- celixThreadMutex_lock(&ts->pendingDisconnections_lock);
- arrayList_add(ts->pendingDisconnections, url);
- celixThreadMutex_unlock(&ts->pendingDisconnections_lock);
- return status;
-}
-
-celix_status_t pubsub_topicSubscriptionDisconnectPublisher(topic_subscription_pt ts, char* pubURL){
- printf("pubsub_topicSubscriptionDisconnectPublisher : pubURL = %s\n", pubURL);
- celix_status_t status = CELIX_SUCCESS;
- struct epoll_event ev;
- memset(&ev, 0, sizeof(ev));
-
- celixThreadMutex_lock(&ts->socketMap_lock);
-
- if (hashMap_containsKey(ts->socketMap, pubURL)){
-
-#if defined(__APPLE__) && defined(__MACH__)
- //TODO: Use kqueue for OSX
-#else
- int *s = hashMap_remove(ts->socketMap, pubURL);
- if(epoll_ctl(ts->topicEpollFd, EPOLL_CTL_DEL, *s, &ev) == -1) {
- printf("in if error()\n");
- perror("epoll_ctl() EPOLL_CTL_DEL");
- status = CELIX_SERVICE_EXCEPTION;
- }
- free(s);
-#endif
-
- }
-
- celixThreadMutex_unlock(&ts->socketMap_lock);
-
- return status;
-}
-
-celix_status_t pubsub_topicSubscriptionAddSubscriber(topic_subscription_pt ts, pubsub_endpoint_pt subEP){
- celix_status_t status = CELIX_SUCCESS;
-
- celixThreadMutex_lock(&ts->ts_lock);
- arrayList_add(ts->sub_ep_list,subEP);
- celixThreadMutex_unlock(&ts->ts_lock);
-
- return status;
-
-}
-
-celix_status_t pubsub_topicIncreaseNrSubscribers(topic_subscription_pt ts) {
- celix_status_t status = CELIX_SUCCESS;
-
- celixThreadMutex_lock(&ts->ts_lock);
- ts->nrSubscribers++;
- celixThreadMutex_unlock(&ts->ts_lock);
-
- return status;
-}
-
-celix_status_t pubsub_topicSubscriptionRemoveSubscriber(topic_subscription_pt ts, pubsub_endpoint_pt subEP){
- celix_status_t status = CELIX_SUCCESS;
-
- celixThreadMutex_lock(&ts->ts_lock);
- arrayList_removeElement(ts->sub_ep_list,subEP);
- celixThreadMutex_unlock(&ts->ts_lock);
-
- return status;
-}
-
-celix_status_t pubsub_topicDecreaseNrSubscribers(topic_subscription_pt ts) {
- celix_status_t status = CELIX_SUCCESS;
-
- celixThreadMutex_lock(&ts->ts_lock);
- ts->nrSubscribers--;
- celixThreadMutex_unlock(&ts->ts_lock);
-
- return status;
-}
-
-unsigned int pubsub_topicGetNrSubscribers(topic_subscription_pt ts) {
- return ts->nrSubscribers;
-}
-
-array_list_pt pubsub_topicSubscriptionGetSubscribersList(topic_subscription_pt sub){
- return sub->sub_ep_list;
-}
-
-
-static celix_status_t topicsub_subscriberTracked(void * handle, service_reference_pt reference, void * service){
- celix_status_t status = CELIX_SUCCESS;
- topic_subscription_pt ts = handle;
-
- celixThreadMutex_lock(&ts->ts_lock);
- if (!hashMap_containsKey(ts->servicesMap, service)) {
- bundle_pt bundle = NULL;
- hash_map_pt msgTypes = NULL;
-
- serviceReference_getBundle(reference, &bundle);
-
- if(ts->serializer != NULL && bundle!=NULL){
- ts->serializer->createSerializerMap(ts->serializer->handle,bundle,&msgTypes);
- if(msgTypes != NULL){
- hashMap_put(ts->servicesMap, service, msgTypes);
- printf("PSA_UDP_MC_TS: New subscriber registered.\n");
- }
- }
- else{
- printf("PSA_UDP_MC_TS: Cannot register new subscriber.\n");
- status = CELIX_SERVICE_EXCEPTION;
- }
- }
- celixThreadMutex_unlock(&ts->ts_lock);
-
- return status;
-
-}
-
-static celix_status_t topicsub_subscriberUntracked(void * handle, service_reference_pt reference, void * service){
- celix_status_t status = CELIX_SUCCESS;
- topic_subscription_pt ts = handle;
-
- celixThreadMutex_lock(&ts->ts_lock);
- if (hashMap_containsKey(ts->servicesMap, service)) {
- hash_map_pt msgTypes = hashMap_remove(ts->servicesMap, service);
- if(msgTypes!=NULL && ts->serializer!=NULL){
- ts->serializer->destroySerializerMap(ts->serializer->handle,msgTypes);
- printf("PSA_ZMQ_TS: Subscriber unregistered.\n");
- }
- else{
- printf("PSA_ZMQ_TS: Cannot unregister subscriber.\n");
- status = CELIX_SERVICE_EXCEPTION;
- }
- }
- celixThreadMutex_unlock(&ts->ts_lock);
-
- printf("PSA_UDP_MC_TS: Subscriber unregistered.\n");
- return status;
-}
-
-
-static void process_msg(topic_subscription_pt sub,pubsub_udp_msg_t *msg){
-
- celixThreadMutex_lock(&sub->ts_lock);
- hash_map_iterator_pt iter = hashMapIterator_create(sub->servicesMap);
- while (hashMapIterator_hasNext(iter)) {
- hash_map_entry_pt entry = hashMapIterator_nextEntry(iter);
- pubsub_subscriber_pt subsvc = hashMapEntry_getKey(entry);
- hash_map_pt msgTypes = hashMapEntry_getValue(entry);
-
- pubsub_msg_serializer_t *msgSer = hashMap_get(msgTypes,(void*)(uintptr_t )msg->header.type);
- if (msgSer == NULL) {
- printf("PSA_UDP_MC_TS: Serializer not available for message %d.\n",msg->header.type);
- }
- else{
- void *msgInst = NULL;
- bool validVersion = checkVersion(msgSer->msgVersion,&msg->header);
-
- if(validVersion){
-
- celix_status_t status = msgSer->deserialize(msgSer, (const void *) msg->payload, 0, &msgInst);
-
- if (status == CELIX_SUCCESS) {
- bool release = true;
- pubsub_multipart_callbacks_t mp_callbacks;
- mp_callbacks.handle = sub;
- mp_callbacks.localMsgTypeIdForMsgType = pubsub_localMsgTypeIdForMsgType;
- mp_callbacks.getMultipart = NULL;
-
- subsvc->receive(subsvc->handle, msgSer->msgName, msg->header.type, msgInst, &mp_callbacks, &release);
-
- if(release){
- msgSer->freeMsg(msgSer,msgInst);
- }
- }
- else{
- printf("PSA_UDP_MC_TS: Cannot deserialize msgType %s.\n",msgSer->msgName);
- }
-
- }
- else{
- int major=0,minor=0;
- version_getMajor(msgSer->msgVersion,&major);
- version_getMinor(msgSer->msgVersion,&minor);
- printf("PSA_UDP_MC_TS: Version mismatch for primary message '%s' (have %d.%d, received %u.%u). NOT sending any part of the whole message.\n",
- msgSer->msgName,major,minor,msg->header.major,msg->header.minor);
- }
-
- }
- }
- hashMapIterator_destroy(iter);
- celixThreadMutex_unlock(&sub->ts_lock);
-}
-
-static void* udp_recv_thread_func(void * arg) {
- topic_subscription_pt sub = (topic_subscription_pt) arg;
-
-#if defined(__APPLE__) && defined(__MACH__)
- //TODO: use kqueue for OSX
- //struct kevent events[MAX_EPOLL_EVENTS];
- while (sub->running) {
- int nfds = 0;
- if(nfds > 0) {
- pubsub_udp_msg_t* udpMsg = NULL;
- process_msg(sub, udpMsg);
- }
- }
-#else
- struct epoll_event events[MAX_EPOLL_EVENTS];
-
- while (sub->running) {
- int nfds = epoll_wait(sub->topicEpollFd, events, MAX_EPOLL_EVENTS, RECV_THREAD_TIMEOUT * 1000);
- int i;
- for(i = 0; i < nfds; i++ ) {
- unsigned int index;
- unsigned int size;
- if(largeUdp_dataAvailable(sub->largeUdpHandle, events[i].data.fd, &index, &size) == true) {
- // Handle data
- pubsub_udp_msg_t *udpMsg = NULL;
- if(largeUdp_read(sub->largeUdpHandle, index, (void**)&udpMsg, size) != 0) {
- printf("PSA_UDP_MC_TS: ERROR largeUdp_read with index %d\n", index);
- continue;
- }
-
- process_msg(sub, udpMsg);
-
- free(udpMsg);
- }
- }
- connectPendingPublishers(sub);
- disconnectPendingPublishers(sub);
- }
-#endif
-
- return NULL;
-}
-
-static void connectPendingPublishers(topic_subscription_pt sub) {
- celixThreadMutex_lock(&sub->pendingConnections_lock);
- while(!arrayList_isEmpty(sub->pendingConnections)) {
- char * pubEP = arrayList_remove(sub->pendingConnections, 0);
- pubsub_topicSubscriptionConnectPublisher(sub, pubEP);
- free(pubEP);
- }
- celixThreadMutex_unlock(&sub->pendingConnections_lock);
-}
-
-static void disconnectPendingPublishers(topic_subscription_pt sub) {
- celixThreadMutex_lock(&sub->pendingDisconnections_lock);
- while(!arrayList_isEmpty(sub->pendingDisconnections)) {
- char * pubEP = arrayList_remove(sub->pendingDisconnections, 0);
- pubsub_topicSubscriptionDisconnectPublisher(sub, pubEP);
- free(pubEP);
- }
- celixThreadMutex_unlock(&sub->pendingDisconnections_lock);
-}
-
-static void sigusr1_sighandler(int signo){
- printf("PSA_UDP_MC_TS: Topic subscription being shut down...\n");
- return;
-}
-
-static bool checkVersion(version_pt msgVersion,pubsub_msg_header_pt hdr){
- bool check=false;
- int major=0,minor=0;
-
- if(msgVersion!=NULL){
- version_getMajor(msgVersion,&major);
- version_getMinor(msgVersion,&minor);
- if(hdr->major==((unsigned char)major)){ /* Different major means incompatible */
- check = (hdr->minor>=((unsigned char)minor)); /* Compatible only if the provider has a minor equals or greater (means compatible update) */
- }
- }
-
- return check;
-}
-
-static int pubsub_localMsgTypeIdForMsgType(void* handle, const char* msgType, unsigned int* msgTypeId){
- *msgTypeId = utils_stringHash(msgType);
- return 0;
-}
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/pubsub/pubsub_admin_udp_mc/src/large_udp.c
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_admin_udp_mc/src/large_udp.c b/pubsub/pubsub_admin_udp_mc/src/large_udp.c
new file mode 100644
index 0000000..7455925
--- /dev/null
+++ b/pubsub/pubsub_admin_udp_mc/src/large_udp.c
@@ -0,0 +1,372 @@
+/**
+ *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.
+ */
+/*
+ * large_udp.c
+ *
+ * \date Mar 1, 2016
+ * \author <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ * \copyright Apache License, Version 2.0
+ */
+
+#include "large_udp.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <array_list.h>
+#include <pthread.h>
+
+#define MAX_UDP_MSG_SIZE 65535 /* 2^16 -1 */
+#define IP_HEADER_SIZE 20
+#define UDP_HEADER_SIZE 8
+//#define MTU_SIZE 1500
+#define MTU_SIZE 8000
+#define MAX_MSG_VECTOR_LEN 64
+
+//#define NO_IP_FRAGMENTATION
+
+struct largeUdp {
+ unsigned int maxNrLists;
+ array_list_pt udpPartLists;
+ pthread_mutex_t dbLock;
+};
+
+typedef struct udpPartList {
+ unsigned int msg_ident;
+ unsigned int msg_size;
+ unsigned int nrPartsRemaining;
+ char *data;
+} *udpPartList_pt;
+
+
+typedef struct msg_part_header {
+ unsigned int msg_ident;
+ unsigned int total_msg_size;
+ unsigned int part_msg_size;
+ unsigned int offset;
+} msg_part_header_t;
+
+#ifdef NO_IP_FRAGMENTATION
+#define MAX_PART_SIZE (MTU_SIZE - (IP_HEADER_SIZE + UDP_HEADER_SIZE + sizeof(struct msg_part_header) ))
+#else
+#define MAX_PART_SIZE (MAX_UDP_MSG_SIZE - (IP_HEADER_SIZE + UDP_HEADER_SIZE + sizeof(struct msg_part_header) ))
+#endif
+
+typedef struct msg_part {
+ msg_part_header_t header;
+ char data[MAX_PART_SIZE];
+} msg_part_t;
+
+//
+// Create a handle
+//
+largeUdp_pt largeUdp_create(unsigned int maxNrUdpReceptions)
+{
+ printf("## Creating large UDP\n");
+ largeUdp_pt handle = calloc(sizeof(*handle), 1);
+ if(handle != NULL) {
+ handle->maxNrLists = maxNrUdpReceptions;
+ if(arrayList_create(&handle->udpPartLists) != CELIX_SUCCESS) {
+ free(handle);
+ handle = NULL;
+ }
+ pthread_mutex_init(&handle->dbLock, 0);
+ }
+
+ return handle;
+}
+
+//
+// Destroys the handle
+//
+void largeUdp_destroy(largeUdp_pt handle)
+{
+ printf("### Destroying large UDP\n");
+ if(handle != NULL) {
+ pthread_mutex_lock(&handle->dbLock);
+ int nrUdpLists = arrayList_size(handle->udpPartLists);
+ int i;
+ for(i=0; i < nrUdpLists; i++) {
+ udpPartList_pt udpPartList = arrayList_remove(handle->udpPartLists, i);
+ if(udpPartList) {
+ if(udpPartList->data) {
+ free(udpPartList->data);
+ udpPartList->data = NULL;
+ }
+ free(udpPartList);
+ }
+ }
+ arrayList_destroy(handle->udpPartLists);
+ handle->udpPartLists = NULL;
+ pthread_mutex_unlock(&handle->dbLock);
+ pthread_mutex_destroy(&handle->dbLock);
+ free(handle);
+ }
+}
+
+//
+// Write large data to UDP. This function splits the data in chunks and sends these chunks with a header over UDP.
+//
+int largeUdp_sendmsg(largeUdp_pt handle, int fd, struct iovec *largeMsg_iovec, int len, int flags, struct sockaddr_in *dest_addr, size_t addrlen)
+{
+ int n;
+ int result = 0;
+ msg_part_header_t header;
+
+ int written = 0;
+ header.msg_ident = (unsigned int)random();
+ header.total_msg_size = 0;
+ for(n = 0; n < len ;n++) {
+ header.total_msg_size += largeMsg_iovec[n].iov_len;
+ }
+ int nr_buffers = (header.total_msg_size / MAX_PART_SIZE) + 1;
+
+ struct iovec msg_iovec[MAX_MSG_VECTOR_LEN];
+ struct msghdr msg;
+ msg.msg_name = dest_addr;
+ msg.msg_namelen = addrlen;
+ msg.msg_flags = 0;
+ msg.msg_iov = msg_iovec;
+ msg.msg_iovlen = 2; // header and payload;
+ msg.msg_control = NULL;
+ msg.msg_controllen = 0;
+
+ msg.msg_iov[0].iov_base = &header;
+ msg.msg_iov[0].iov_len = sizeof(header);
+
+ for(n = 0; n < nr_buffers; n++) {
+
+ header.part_msg_size = (((header.total_msg_size - n * MAX_PART_SIZE) > MAX_PART_SIZE) ? MAX_PART_SIZE : (header.total_msg_size - n * MAX_PART_SIZE));
+ header.offset = n * MAX_PART_SIZE;
+ int remainingOffset = header.offset;
+ int recvPart = 0;
+ // find the start of the part
+ while(remainingOffset > largeMsg_iovec[recvPart].iov_len) {
+ remainingOffset -= largeMsg_iovec[recvPart].iov_len;
+ recvPart++;
+ }
+ int remainingData = header.part_msg_size;
+ int sendPart = 1;
+ msg.msg_iovlen = 1;
+
+ // fill in the output iovec from the input iovec in such a way that all UDP frames are filled maximal.
+ while(remainingData > 0) {
+ int partLen = ( (largeMsg_iovec[recvPart].iov_len - remainingOffset) <= remainingData ? (largeMsg_iovec[recvPart].iov_len -remainingOffset) : remainingData);
+ msg.msg_iov[sendPart].iov_base = largeMsg_iovec[recvPart].iov_base + remainingOffset;
+ msg.msg_iov[sendPart].iov_len = partLen;
+ remainingData -= partLen;
+ remainingOffset = 0;
+ sendPart++;
+ recvPart++;
+ msg.msg_iovlen++;
+ }
+ int tmp, tmptot;
+ for(tmp = 0, tmptot=0; tmp < msg.msg_iovlen; tmp++) {
+ tmptot += msg.msg_iov[tmp].iov_len;
+ }
+
+ int w = sendmsg(fd, &msg, 0);
+ if(w == -1) {
+ perror("send()");
+ result = -1;
+ break;
+ }
+ written += w;
+ }
+
+ return (result == 0 ? written : result);
+}
+
+//
+// Write large data to UDP. This function splits the data in chunks and sends these chunks with a header over UDP.
+//
+int largeUdp_sendto(largeUdp_pt handle, int fd, void *buf, size_t count, int flags, struct sockaddr_in *dest_addr, size_t addrlen)
+{
+ int n;
+ int nr_buffers = (count / MAX_PART_SIZE) + 1;
+ int result = 0;
+ msg_part_header_t header;
+
+ int written = 0;
+ header.msg_ident = (unsigned int)random();
+ header.total_msg_size = count;
+ char *databuf = buf;
+
+ struct iovec msg_iovec[2];
+ struct msghdr msg;
+ msg.msg_name = dest_addr;
+ msg.msg_namelen = addrlen;
+ msg.msg_flags = 0;
+ msg.msg_iov = msg_iovec;
+ msg.msg_iovlen = 2; // header and payload;
+ msg.msg_control = NULL;
+ msg.msg_controllen = 0;
+
+ msg.msg_iov[0].iov_base = &header;
+ msg.msg_iov[0].iov_len = sizeof(header);
+
+ for(n = 0; n < nr_buffers; n++) {
+
+ header.part_msg_size = (((header.total_msg_size - n * MAX_PART_SIZE) > MAX_PART_SIZE) ? MAX_PART_SIZE : (header.total_msg_size - n * MAX_PART_SIZE));
+ header.offset = n * MAX_PART_SIZE;
+ msg.msg_iov[1].iov_base = &databuf[header.offset];
+ msg.msg_iov[1].iov_len = header.part_msg_size;
+ int w = sendmsg(fd, &msg, 0);
+ if(w == -1) {
+ perror("send()");
+ result = -1;
+ break;
+ }
+ written += w;
+ //usleep(1000); // TODO: If not slept a UDP buffer overflow occurs and parts are missing at the reception side (at least via localhost)
+ }
+
+ return (result == 0 ? written : result);
+}
+
+//
+// Reads data from the filedescriptor which has date (determined by epoll()) and stores it in the internal structure
+// If the message is completely reassembled true is returned and the index and size have valid values
+//
+bool largeUdp_dataAvailable(largeUdp_pt handle, int fd, unsigned int *index, unsigned int *size) {
+ msg_part_header_t header;
+ int result = false;
+ // Only read the header, we don't know yet where to store the payload
+ if(recv(fd, &header, sizeof(header), MSG_PEEK) < 0) {
+ perror("read()");
+ return false;
+ }
+
+ struct iovec msg_vec[2];
+ struct msghdr msg;
+ msg.msg_name = NULL;
+ msg.msg_namelen = 0;
+ msg.msg_flags = 0;
+ msg.msg_iov = msg_vec;
+ msg.msg_iovlen = 2; // header and payload;
+ msg.msg_control = NULL;
+ msg.msg_controllen = 0;
+
+ msg.msg_iov[0].iov_base = &header;
+ msg.msg_iov[0].iov_len = sizeof(header);
+
+ pthread_mutex_lock(&handle->dbLock);
+
+ int nrUdpLists = arrayList_size(handle->udpPartLists);
+ int i;
+ bool found = false;
+ for(i = 0; i < nrUdpLists; i++) {
+ udpPartList_pt udpPartList = arrayList_get(handle->udpPartLists, i);
+ if(udpPartList->msg_ident == header.msg_ident) {
+ found = true;
+
+ //sanity check
+ if(udpPartList->msg_size != header.total_msg_size) {
+ // Corruption occurred. Remove the existing administration and build up a new one.
+ arrayList_remove(handle->udpPartLists, i);
+ free(udpPartList->data);
+ free(udpPartList);
+ found = false;
+ break;
+ }
+
+ msg.msg_iov[1].iov_base = &udpPartList->data[header.offset];
+ msg.msg_iov[1].iov_len = header.part_msg_size;
+ if(recvmsg(fd, &msg, 0)<0){
+ found=true;
+ result=false;
+ break;
+ }
+
+ udpPartList->nrPartsRemaining--;
+ if(udpPartList->nrPartsRemaining == 0) {
+ *index = i;
+ *size = udpPartList->msg_size;
+ result = true;
+ break;
+ } else {
+ result = false; // not complete
+ break;
+ }
+ }
+ }
+
+ if(found == false) {
+ udpPartList_pt udpPartList = NULL;
+ if(nrUdpLists == handle->maxNrLists) {
+ // remove list at index 0
+ udpPartList = arrayList_remove(handle->udpPartLists, 0);
+ fprintf(stderr, "ERROR: Removing entry for id %d: %d parts not received\n",udpPartList->msg_ident, udpPartList->nrPartsRemaining );
+ free(udpPartList->data);
+ free(udpPartList);
+ nrUdpLists--;
+ }
+ udpPartList = calloc(sizeof(*udpPartList), 1);
+ udpPartList->msg_ident = header.msg_ident;
+ udpPartList->msg_size = header.total_msg_size;
+ udpPartList->nrPartsRemaining = header.total_msg_size / MAX_PART_SIZE;
+ udpPartList->data = calloc(sizeof(char), header.total_msg_size);
+
+ msg.msg_iov[1].iov_base = &udpPartList->data[header.offset];
+ msg.msg_iov[1].iov_len = header.part_msg_size;
+ if(recvmsg(fd, &msg, 0)<0){
+ free(udpPartList->data);
+ free(udpPartList);
+ result=false;
+ }
+ else{
+ arrayList_add(handle->udpPartLists, udpPartList);
+
+ if(udpPartList->nrPartsRemaining == 0) {
+ *index = nrUdpLists;
+ *size = udpPartList->msg_size;
+ result = true;
+ } else {
+ result = false;
+ }
+ }
+
+ }
+
+ pthread_mutex_unlock(&handle->dbLock);
+
+ return result;
+}
+
+//
+// Read out the message which is indicated available by the largeUdp_dataAvailable function
+//
+int largeUdp_read(largeUdp_pt handle, unsigned int index, void ** buffer, unsigned int size)
+{
+ int result = 0;
+ pthread_mutex_lock(&handle->dbLock);
+
+ udpPartList_pt udpPartList = arrayList_remove(handle->udpPartLists, index);
+ if(udpPartList) {
+ *buffer = udpPartList->data;
+ free(udpPartList);
+ } else {
+ result = -1;
+ }
+ pthread_mutex_unlock(&handle->dbLock);
+
+ return result;
+}
http://git-wip-us.apache.org/repos/asf/celix/blob/2a670f26/pubsub/pubsub_admin_udp_mc/src/large_udp.h
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_admin_udp_mc/src/large_udp.h b/pubsub/pubsub_admin_udp_mc/src/large_udp.h
new file mode 100644
index 0000000..a21e654
--- /dev/null
+++ b/pubsub/pubsub_admin_udp_mc/src/large_udp.h
@@ -0,0 +1,45 @@
+/**
+ *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.
+ */
+/*
+ * large_udp.h
+ *
+ * \date Mar 1, 2016
+ * \author <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ * \copyright Apache License, Version 2.0
+ */
+
+#ifndef _LARGE_UDP_H_
+#define _LARGE_UDP_H_
+#include <stdbool.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+
+typedef struct largeUdp *largeUdp_pt;
+
+largeUdp_pt largeUdp_create(unsigned int maxNrUdpReceptions);
+void largeUdp_destroy(largeUdp_pt handle);
+
+int largeUdp_sendto(largeUdp_pt handle, int fd, void *buf, size_t count, int flags, struct sockaddr_in *dest_addr, size_t addrlen);
+int largeUdp_sendmsg(largeUdp_pt handle, int fd, struct iovec *largeMsg_iovec, int len, int flags, struct sockaddr_in *dest_addr, size_t addrlen);
+bool largeUdp_dataAvailable(largeUdp_pt handle, int fd, unsigned int *index, unsigned int *size);
+int largeUdp_read(largeUdp_pt handle, unsigned int index, void ** buffer, unsigned int size);
+
+#endif /* _LARGE_UDP_H_ */