Return-Path: X-Original-To: apmail-celix-commits-archive@www.apache.org Delivered-To: apmail-celix-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 5A03B1830B for ; Sun, 31 May 2015 18:34:25 +0000 (UTC) Received: (qmail 84235 invoked by uid 500); 31 May 2015 18:34:25 -0000 Delivered-To: apmail-celix-commits-archive@celix.apache.org Received: (qmail 84175 invoked by uid 500); 31 May 2015 18:34:25 -0000 Mailing-List: contact commits-help@celix.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@celix.apache.org Delivered-To: mailing list commits@celix.apache.org Received: (qmail 84158 invoked by uid 99); 31 May 2015 18:34:25 -0000 Received: from git1-us-west.apache.org (HELO git1-us-west.apache.org) (140.211.11.23) by apache.org (qpsmtpd/0.29) with ESMTP; Sun, 31 May 2015 18:34:25 +0000 Received: by git1-us-west.apache.org (ASF Mail Server at git1-us-west.apache.org, from userid 33) id 003AEDFDAE; Sun, 31 May 2015 18:34:24 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: pnoltes@apache.org To: commits@celix.apache.org Date: Sun, 31 May 2015 18:34:25 -0000 Message-Id: <1dc475a31ca84828bc1c27391c065ee2@git.apache.org> In-Reply-To: <64d6ee9664414c078a235b5752215b03@git.apache.org> References: <64d6ee9664414c078a235b5752215b03@git.apache.org> X-Mailer: ASF-Git Admin Mailer Subject: [2/2] celix git commit: CELIX-237: initial drop. Contains a ffi based rsa. CELIX-237: initial drop. Contains a ffi based rsa. The rsa is still incomplete and buggy, but has a working a client server examples with proxy/endpoint. The rsa tree also contains a dyn_type and json_serialize code which together with a provided schema can be used for dynamic type serialization. Project: http://git-wip-us.apache.org/repos/asf/celix/repo Commit: http://git-wip-us.apache.org/repos/asf/celix/commit/387f7792 Tree: http://git-wip-us.apache.org/repos/asf/celix/tree/387f7792 Diff: http://git-wip-us.apache.org/repos/asf/celix/diff/387f7792 Branch: refs/heads/feature/CELIX-237_rsa-ffi Commit: 387f7792d88cc6eab1202a3e9cd48167af44058a Parents: 3acf970 Author: Pepijn Noltes Authored: Sun May 31 20:26:19 2015 +0200 Committer: Pepijn Noltes Committed: Sun May 31 20:26:19 2015 +0200 ---------------------------------------------------------------------- .gitignore | 2 + remote_services/CMakeLists.txt | 13 +- remote_services/dyn_type/CMakeLists.txt | 9 + remote_services/dyn_type/dyn_type.c | 551 +++++++++ remote_services/dyn_type/dyn_type.h | 78 ++ remote_services/dyn_type/json_serializer.c | 123 ++ remote_services/dyn_type/json_serializer.h | 9 + remote_services/dyn_type/struct_tests.c | 159 +++ .../private/src/calculator_proxy_impl.c | 2 +- .../private/src/calculator_activator.c | 1 + .../public/include/calculator_service.h | 31 +- .../calculator_shell/private/src/add_command.c | 3 +- .../calculator_shell/private/src/sqrt_command.c | 2 +- .../calculator_shell/private/src/sub_command.c | 2 +- remote_services/examples/deploy.cmake | 38 +- .../private/src/export_registration_impl.c | 4 +- .../CMakeLists.txt | 49 + .../include/remote_service_admin_http_impl.h | 52 + .../src/remote_service_admin_activator.c | 122 ++ .../private/src/remote_service_admin_impl.c | 1085 ++++++++++++++++++ .../private/src/topology_manager.c | 7 +- 21 files changed, 2291 insertions(+), 51 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/celix/blob/387f7792/.gitignore ---------------------------------------------------------------------- diff --git a/.gitignore b/.gitignore index eb89068..f77383b 100644 --- a/.gitignore +++ b/.gitignore @@ -18,3 +18,5 @@ /.project .DS_Store build +*~ +*.swp http://git-wip-us.apache.org/repos/asf/celix/blob/387f7792/remote_services/CMakeLists.txt ---------------------------------------------------------------------- diff --git a/remote_services/CMakeLists.txt b/remote_services/CMakeLists.txt index abb6024..9f56b58 100644 --- a/remote_services/CMakeLists.txt +++ b/remote_services/CMakeLists.txt @@ -33,13 +33,16 @@ if (REMOTE_SERVICE_ADMIN) add_subdirectory(topology_manager) - add_subdirectory(remote_service_admin) - add_subdirectory(remote_service_admin_http) - add_subdirectory(remote_service_admin_shm) + #add_subdirectory(remote_service_admin) + #add_subdirectory(remote_service_admin_http) + add_subdirectory(remote_service_admin_http_ffi) + #add_subdirectory(remote_service_admin_shm) - add_subdirectory(discovery_configured) + #add_subdirectory(discovery_configured) add_subdirectory(discovery_etcd) - add_subdirectory(discovery_shm) + #add_subdirectory(discovery_shm) + + add_subdirectory(dyn_type) endif (REMOTE_SERVICE_ADMIN) http://git-wip-us.apache.org/repos/asf/celix/blob/387f7792/remote_services/dyn_type/CMakeLists.txt ---------------------------------------------------------------------- diff --git a/remote_services/dyn_type/CMakeLists.txt b/remote_services/dyn_type/CMakeLists.txt new file mode 100644 index 0000000..8b5b78f --- /dev/null +++ b/remote_services/dyn_type/CMakeLists.txt @@ -0,0 +1,9 @@ +find_package(Jansson REQUIRED) + +add_executable(struct_tests + struct_tests.c + dyn_type.c + json_serializer.c +) + +target_link_libraries(struct_tests ${JANSSON_LIBRARIES} /lib64/libffi.so ) http://git-wip-us.apache.org/repos/asf/celix/blob/387f7792/remote_services/dyn_type/dyn_type.c ---------------------------------------------------------------------- diff --git a/remote_services/dyn_type/dyn_type.c b/remote_services/dyn_type/dyn_type.c new file mode 100644 index 0000000..fe4c9bc --- /dev/null +++ b/remote_services/dyn_type/dyn_type.c @@ -0,0 +1,551 @@ +#include "dyn_type.h" + +#include +#include +#include +#include +#include +#include +#include + + +//place in dyn_type.h? +struct generic_sequence { + uint32_t _cap; + uint32_t _len; + void *buf; +}; + +struct _dyn_type { + int type; + union { + struct { + ffi_type *ffiType; + } simple; + + struct { + ffi_type ffiType; + char **names; + dyn_type **nested_types; + } complex; + + struct { + ffi_type seqStruct; + dyn_type *dynType; //set if sequence is of a complex type + ffi_type *simpleType; //set if sequence is of a simple type + } sequence; + }; +}; + +static char dynType_schemaType(dyn_type *dynType, ffi_type *ffiType); + +static void dynType_print_sequence(dyn_type *type, int depth); +static void dynType_print_complex(dyn_type *type, int depth); +static void dynType_print_any(dyn_type *type, int depth); + +static unsigned short get_offset_at(ffi_type *type, int index); +static void dynType_trim(const char *str, size_t len, int *start, int *end); + +static int dynType_complex_create(char *schema, dyn_type **result); +static int dynType_sequence_create(char *schema, dyn_type **result); +static int dynType_simple_create(char t, dyn_type **result); + +static ffi_type* dynType_ffiType_for(char c); + +int dynType_create(const char *schema, dyn_type **result) { + //trim white space + int status = 0; + int offset, len; + dynType_trim(schema, strlen(schema), &offset, &len); + + /* + char test[len+1]; + memcpy(test, schema + offset, len); + test[len] = '\0'; + printf("trimmed schema is %s\n", test); + */ + + if (schema[offset] == '{' && schema[offset + len -1] == '}') { + //complex + + //removing prefix { and postfix } + offset += 1; + len -= 2; + + int offsetType; + int lenType; + //trim again + dynType_trim(schema + offset, len , &offsetType, &lenType); + + char type[lenType + 1]; + memcpy(type, schema + offset + offsetType, lenType); + type[lenType] = '\0'; + status = dynType_complex_create(type, result); + } else if (schema[offset] == '[') { + //sequence + //fixme assuming simple type + offset += 1; //remove [ + len -= 1; + char type[len + 1]; + memcpy(type, schema + offset, len); + type[len] = '\0'; + status = dynType_sequence_create(type, result); + } else if (len == 1){ + //simple + status = dynType_simple_create(schema[offset], result); + } else { + printf("invalid schema '%s'\n", schema); + } + + return status; +} + +static int dynType_simple_create(char t, dyn_type **result) { + int status = 0; + ffi_type *ffiType = dynType_ffiType_for(t); + dyn_type *simple = NULL; + if (ffiType != NULL) { + dyn_type *simple = calloc(1,sizeof(*simple)); + simple->type = DYN_TYPE_SIMPLE; + simple->simple.ffiType = ffiType; + } + if (ffiType != NULL && simple != NULL) { + *result = simple; + } + return status; +} + +static int dynType_sequence_create(char *schema, dyn_type **result) { + int status = 0; + dyn_type *type = calloc(1, sizeof(*type)); + + type->type = DYN_TYPE_SEQUENCE; + type->sequence.seqStruct.elements = calloc(4, sizeof(ffi_type)); + type->sequence.seqStruct.elements[0] = &ffi_type_uint32; //_cap + type->sequence.seqStruct.elements[1] = &ffi_type_uint32; //_len + type->sequence.seqStruct.elements[2] = &ffi_type_pointer; + type->sequence.seqStruct.elements[3] = NULL; + + if (schema[0] == '{') { //complex type + int len = strlen(schema) -2; + char complexSchema[len + 1]; + memcpy(complexSchema, schema + 1, len); + complexSchema[len] = '\0'; + status = dynType_complex_create(complexSchema, &type->sequence.dynType); + } else { //simple type + type->sequence.simpleType = dynType_ffiType_for(schema[0]); + } + //TODO sequence of sequence + + if (status == 0) { + //dummy cif prep to ensure size for struct ffi_type is set + ffi_cif cif; + ffi_type *args[1]; + args[0] = &type->sequence.seqStruct; + ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, &ffi_type_uint, args); + + *result = type; + return 0; + } else { + printf("DYN_TYPE: invalid type schema\n"); + return 1; + } + + return status; +} + +static int dynType_complex_create(char *schema, dyn_type **result) { + bool valid = true; + size_t len = strlen(schema); + int i = 0; + + dyn_type *type = calloc(1, sizeof(*type)); + type->type = DYN_TYPE_COMPLEX; + if (type == NULL) { + return -1; + } + + //count elements + int k; + size_t count = 0; + for (k=i; k < len && !isspace(schema[k]); k += 1) { + if (schema[k] == '[') { + k += 1; + } else if (schema[k] == '{') { + for (; schema[k] != '}'; k += 1) ; + } + count += 1; + } + + type->complex.ffiType.elements = calloc(count + 1, sizeof(ffi_type)); + type->complex.nested_types = calloc(count + 1, sizeof(dyn_type *)); + int index = 0; + for (k=0; k+i < len && !isspace(schema[k+i]); k += 1, index += 1) { + if (schema[k+i] == '[') { //sequence + //FIXME assume simple type + dyn_type *seqType; + char seq[2]; + seq[0] = schema[k+i+1]; + seq[1] = '\0'; + dynType_sequence_create(seq, &seqType); + + type->complex.nested_types[index] = seqType; + type->complex.ffiType.elements[index] = &seqType->sequence.seqStruct; + k += 1; + } else if (schema[k+i] == '{') { //nested complex + int start = k+i; + int end; + for (; schema[k+i] != '}' && k+i < len; k +=1) ; + if (schema[k+i] == '}') { + end = k+i; + size_t len = end-start + 1 -2; //without {} + char nested[len+1]; + memcpy(nested, schema + start + 1, len); + nested[len] = '\0'; + dyn_type *nestedType = NULL; + dynType_complex_create(nested, &nestedType); //TODO use status result + type->complex.nested_types[index] = nestedType; + type->complex.ffiType.elements[index] = &ffi_type_pointer; + } else { + printf("invalid schema. object not closed '%s'\n", schema); + } + } else { + ffi_type *elType = NULL; + elType = dynType_ffiType_for(schema[k+i]); + if (elType != NULL) { + type->complex.ffiType.elements[index] = elType; + } else { + valid=false; + } + } + } + + + //eat { and } + int j; + int nrOfBraces = 0; + for (j = 0; j < len; j += 1) { //TODO make safer + if (isspace(schema[j]) && nrOfBraces == 0) { + break; + } + if (schema[j] == '{') { + nrOfBraces += 1; + } else if (schema[j] == '}') { + nrOfBraces -=1 ; + } + } + + char *names = schema + j +1; + + type->complex.names = calloc(count, sizeof(char *)); + k = 0; + char *savePtr; + char *token = NULL; + token = strtok_r(names, " ", &savePtr); + while (token != NULL && k < count) { + type->complex.names[k] = strdup(token); + k += 1; + token = strtok_r(NULL, " ", &savePtr); + } + if ( k != count || token != NULL) { + valid =false; + } + + if (valid) { + //dummy cif prep to ensure size for struct ffi_type is set + ffi_cif cif; + ffi_type *args[1]; + args[0] = &type->complex.ffiType; + ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, &ffi_type_uint, args); + + *result = type; + return 0; + } else { + printf("DYN_TYPE: invalid type schema '%s'\n", schema); + return 1; + } +} + +int dynType_destroy(dyn_type *type) { + //TODO + return 0; +} + +void * dynType_alloc(dyn_type *type) { + assert(type != NULL); + void *result = NULL; + switch(type->type) { + case DYN_TYPE_COMPLEX : + result = calloc(1, type->complex.ffiType.size); + break; + case DYN_TYPE_SEQUENCE : + result = calloc(1, type->sequence.seqStruct.size); + break; + case DYN_TYPE_SIMPLE : + result = calloc(1, type->simple.ffiType->size); + break; + default : + printf("DYN_TYPE: unsupported type %i\n", type->type); + break; + } + return result; +} + +static ffi_type* dynType_ffiType_for(char c) { + ffi_type *type = NULL; + switch (c) { + case 'F' : + type = &ffi_type_float; + break; + case 'D' : + type = &ffi_type_double; + break; + case 'B' : + type = &ffi_type_sint8; + break; + case 'S' : + type = &ffi_type_sint16; + break; + case 'I' : + type = &ffi_type_sint32; + break; + case 'J' : + type = &ffi_type_sint64; + break; + default: + printf("unsupported type %c\n", c); + } + return type; +} + +static unsigned short get_offset_at(ffi_type *type, int index) { + unsigned short offset = 0; + + int i; + for (i = 0; i <= index && type->elements[i] != NULL; i += 1) { + size_t size = type->elements[i]->size; + unsigned short alignment = type->elements[i]->alignment; + int alignment_diff = offset % alignment; + if (alignment_diff > 0) { + offset += (alignment - alignment_diff); + } + if (i < index) { + offset += size; + } + } + + //TODO check if last element is not reached + + return offset; +} + +int dynType_complex_set_value_at(dyn_type *type, int index, void *start, void *in) { + assert(type->type == DYN_TYPE_COMPLEX); + char *loc = ((char *)start) + get_offset_at(&type->complex.ffiType, index); + size_t size = type->complex.ffiType.elements[index]->size; + memcpy(loc, in, size); + return 0; +} + +int dynType_complex_index_for_name(dyn_type *type, const char *name) { + assert(type->type == DYN_TYPE_COMPLEX); + int i; + int index = -1; + for (i = 0; type->complex.ffiType.elements[i] != NULL; i += 1) { + if (strcmp(type->complex.names[i], name) == 0) { + index = i; + break; + } + } + return index; +} + +char dynType_complex_schemaType_at(dyn_type *complexType, int index) { + assert(complexType->type == DYN_TYPE_COMPLEX); + + ffi_type *type = complexType->complex.ffiType.elements[index]; + dyn_type *nestedType = complexType->complex.nested_types[index]; + + return dynType_schemaType(nestedType, type); +} + +static char dynType_schemaType(dyn_type *dynType, ffi_type *ffiType) { + char result = '\0'; + if (dynType != NULL) { + switch(dynType->type) { + case DYN_TYPE_SIMPLE : + result = dynType_schemaType(NULL, dynType->simple.ffiType); + break; + case DYN_TYPE_COMPLEX : + result = '{'; + break; + case DYN_TYPE_SEQUENCE : + result = '['; + break; + } + } else if (ffiType != NULL) { + switch(ffiType->type) { + case FFI_TYPE_FLOAT : + result = 'F'; + break; + case FFI_TYPE_DOUBLE : + result = 'D'; + break; + case FFI_TYPE_SINT8 : + result = 'B'; + break; + case FFI_TYPE_SINT16 : + result = 'S'; + break; + case FFI_TYPE_SINT32 : + result = 'I'; + break; + case FFI_TYPE_SINT64 : + result = 'J'; + break; + default : + printf("Unsurported ffi type encounted. ffi type is %u\n", ffiType->type); + } + } + return result; +} + +dyn_type * dynType_complex_dynType_at(dyn_type *type, int index) { + assert(type->type == DYN_TYPE_COMPLEX); + return type->complex.nested_types[index]; +} + +void * dynType_complex_val_loc_at(dyn_type *type, void *inst_loc, int index) { + assert(type->type == DYN_TYPE_COMPLEX); + char *l = inst_loc; + return (void *)(l + get_offset_at(&type->complex.ffiType, index)); +} + +int dynType_simple_set_value(dyn_type *type, void *typeLoc, void *in) { + //TODO + return 0; +} + +static void dynType_print_sequence(dyn_type *type, int depth) { + assert(type->type == DYN_TYPE_SEQUENCE); + static const char const *SEQ_NAMES[] = {"_cap", "_len", "buf"}; + + int i; + for (i = 0; i < 3 ; i += 1) { + int k; + for (k = 0; k < depth; k += 1) { + printf("\t"); + } + printf("element %i with name '%s': size is %zu, allignment is %i and offset is %i\n", i, + SEQ_NAMES[i], type->sequence.seqStruct.elements[i]->size, type->sequence.seqStruct.elements[i]->alignment, get_offset_at(&type->sequence.seqStruct, i)); + } +} + +static void dynType_print_complex(dyn_type *type, int depth) { + assert(type->type == DYN_TYPE_COMPLEX); + int i, k; + for (k = 0; k < depth; k += 1) { + printf("\t"); + } + printf("printing ffi type. size is %zu, allignment is %i :\n", type->complex.ffiType.size, type->complex.ffiType.alignment); + for (i = 0; type->complex.ffiType.elements[i] != NULL; i += 1) { + for (k = 0; k < depth; k += 1) { + printf("\t"); + } + printf(" element %i with name '%s': size is %zu, allignment is %i and offset is %i\n", i, + type->complex.names[i], type->complex.ffiType.elements[i]->size, type->complex.ffiType.elements[i]->alignment, get_offset_at(&type->complex.ffiType, i)); + if (type->complex.nested_types[i] != NULL) { + dynType_print_any(type->complex.nested_types[i], depth + 1); + } + } +} + +static void dynType_print_any(dyn_type *type, int depth) { + switch (type->type) { + case DYN_TYPE_COMPLEX : + dynType_print_complex(type, depth); + break; + case DYN_TYPE_SEQUENCE : + dynType_print_sequence(type, depth); + break; + default : + printf("Unsurported dyn type %i\n", type->type); + } +} + +void dynType_print(dyn_type *type) { + dynType_print_any(type, 0); +} + +size_t dynType_size(dyn_type *type) { + assert(type != NULL); + size_t size = 0; + switch (type->type) { + case DYN_TYPE_COMPLEX : + size = type->complex.ffiType.size; + break; + case DYN_TYPE_SEQUENCE : + size = type->sequence.seqStruct.size; + break; + case DYN_TYPE_SIMPLE : + size = type->simple.ffiType->size; + break; + default : + printf("Error unsupported type %i\n", type->type); + break; + } + return size; +} + +int dynType_type(dyn_type *type) { + return type->type; +} + +static void dynType_trim(const char *str, size_t strLen, int *offset, int *len) { + int i; + for (i = 0; i < strLen && isspace(str[i]); i += 1) { + ; + } + *offset = i; + + for (i = strLen-1; i >= 0 && isspace(str[i]); i -= 1) { + ; + } + *len = i - (*offset) + 1; +} + + +void* dynType_sequence_init(dyn_type *type, void *inst, size_t cap) { + assert(type->type == DYN_TYPE_SEQUENCE); + char *result; + struct generic_sequence *seq = inst; + if (seq != NULL) { + size_t size = type->sequence.simpleType != NULL ? type->sequence.simpleType->size : dynType_size(type->sequence.dynType); + seq->buf = calloc(cap, size); + seq->_cap = cap; + result = seq->buf; + } + return result; +} + +char dynType_sequence_elementSchemaType(dyn_type *type) { + assert(type->type == DYN_TYPE_SEQUENCE); + return dynType_schemaType(type->sequence.dynType, type->sequence.simpleType); +} + +int dynType_sequence_append(dyn_type *type, void *inst, void *in) { + int index = -1; + struct generic_sequence *seq = inst; + if (seq->_len + 1 <= seq->_cap) { + index = seq->_len; + seq->_len += 1; + char *buf = seq->buf; + size_t elSize = type->sequence.dynType != NULL ? dynType_size(type->sequence.dynType) : type->sequence.simpleType->size; + size_t offset = (elSize * index); + memcpy(buf + offset, in, elSize); + } else { + printf("DYN_TYPE: sequence out of capacity\n"); + //todo resize ? + } + return index; +} http://git-wip-us.apache.org/repos/asf/celix/blob/387f7792/remote_services/dyn_type/dyn_type.h ---------------------------------------------------------------------- diff --git a/remote_services/dyn_type/dyn_type.h b/remote_services/dyn_type/dyn_type.h new file mode 100644 index 0000000..5877fdf --- /dev/null +++ b/remote_services/dyn_type/dyn_type.h @@ -0,0 +1,78 @@ +#ifndef __DYN_TYPE_H_ +#define __DYN_TYPE_H_ + +#include + + +/*Schema description + * + * Type = SimpleType | ComplexType | ArrayType + * Name = alpha[(alpha|numeric)*] + * SPACE = ' ' + * + * SimplesTypes (based on java bytecode method signatures) + * //Java based: + * B char + * C (not supported) + * D double + * F float + * I int //TODO use int32_t instead? + * J long //TODO use int64_t intead? + * S short //TODO use int16_t instead? + * V void + * Z boolean + * //Extended + * b unsigned char + * i unsigned int (see I) + * j unsigned long (see J) + * s unsigned short (see S) + * P pointer + * T char* string + * + * + * ComplexTypes + * {[Type]+} [(Name)(SPACE)]+ + * + * SequenceType + * [(Type) + * + * examples + * "{DDII a b c d}" -> struct { double a; double b; int c; int d; }; + * "{DD{FF c1 c2} a b c" -> struct { double a; double b; struct c { float c1; float c2; }; }; + * + * + */ + +#define DYN_TYPE_SIMPLE 1 +#define DYN_TYPE_COMPLEX 2 +#define DYN_TYPE_SEQUENCE 3 + +typedef struct _dyn_type dyn_type; + +int dynType_create(const char *schema, dyn_type **type); +int dynType_destroy(dyn_type *type); + +//generic +void dynType_print(dyn_type *type); +size_t dynType_size(dyn_type *type); +int dynType_type(dyn_type *type); +void * dynType_alloc(dyn_type *type); +//TODO void dynType_free(dyn_type *type, void *inst); + +//complex +int dynType_complex_index_for_name(dyn_type *type, const char *name); +char dynType_complex_schemaType_at(dyn_type *type, int index); +dyn_type * dynType_complex_dynType_at(dyn_type *type, int index); +void * dynType_complex_val_loc_at(dyn_type *type, void *inst_loc, int index); +int dynType_complex_set_value_at(dyn_type *type, int index, void *start_loc_type, void *in); + +//sequence +void * dynType_sequence_init(dyn_type *type, void *seqInst, size_t cap); //note assume seq struct at seqLoc. only allocates buf +char dynType_sequence_elementSchemaType(dyn_type *type); +int dynType_sequence_append(dyn_type *type, void *inst, void *in); + +//simple +int dynType_simple_set_value(dyn_type *type, void *typeLoc, void *in); + + +#endif http://git-wip-us.apache.org/repos/asf/celix/blob/387f7792/remote_services/dyn_type/json_serializer.c ---------------------------------------------------------------------- diff --git a/remote_services/dyn_type/json_serializer.c b/remote_services/dyn_type/json_serializer.c new file mode 100644 index 0000000..e198445 --- /dev/null +++ b/remote_services/dyn_type/json_serializer.c @@ -0,0 +1,123 @@ +#include "json_serializer.h" + +#include +#include + +static int json_serializer_writeObject(dyn_type *type, json_t *object, void **result); +static void json_serializer_writeObjectMember(dyn_type *type, const char *name, json_t *val, void *inst); +static void json_serializer_writeSequence(json_t *array, dyn_type *seq, void *seqLoc); + +int json_deserialize(dyn_type *type, const char *input, void **result) { + //FIXME function is assuming complex type + int status = 0; + + + json_error_t error; + json_t *root = json_loads(input, JSON_DECODE_ANY, &error); + + if (root != NULL) { + status = json_serializer_writeObject(type, root, result); + json_decref(root); + } else { + status = 1; + printf("JSON_SERIALIZER: error parsing json input '%s'. Error is %s\n", input, error.text); + } + + return status; +} + +static int json_serializer_writeObject(dyn_type *type, json_t *object, void **result) { + assert(object != NULL); + int status = 0; + + void *inst = dynType_alloc(type); + json_t *value; + const char *key; + + if (inst != NULL) { + json_object_foreach(object, key, value) { + json_serializer_writeObjectMember(type, key, value, inst); + } + *result = inst; + } else { + status = 1; + printf("JSON_SERIALIZER: Error allocating memory\n"); + } + + return status; +} + +static void json_serializer_writeObjectMember(dyn_type *type, const char *name, json_t *val, void *inst) { + //TODO rename to complex. write generic write + int index = dynType_complex_index_for_name(type, name); + char charType = dynType_complex_schemaType_at(type, index); + void *valp = dynType_complex_val_loc_at(type, inst, index); + + + float *f; + double *d; + char *c; + short *s; + int *i; + long *l; + dyn_type *nested; + + switch (charType) { + case 'F' : + f = valp; + *f = json_real_value(val); + break; + case 'D' : + d = valp; + *d = json_real_value(val); + break; + case 'B' : + c = valp; + *c = json_integer_value(val); + break; + case 'S' : + s = valp; + *s = json_integer_value(val); + break; + case 'I' : + i = valp; + *i = json_integer_value(val); + break; + case 'J' : + l = valp; + *l = json_integer_value(val); + break; + case '[' : + nested = dynType_complex_dynType_at(type, index); + json_serializer_writeSequence(val, nested, valp); + break; + case '{' : + nested = dynType_complex_dynType_at(type, index); + json_serializer_writeObject(nested, val, (void **)valp); + break; + default : + printf("JSON_SERIALIZER: error provided type '%c' not supported\n", charType); + printf("Skipping\n"); + } +} + +static void json_serializer_writeSequence(json_t *array, dyn_type *seq, void *seqLoc) { + assert(dynType_type(seq) == DYN_TYPE_SEQUENCE); + size_t size = json_array_size(array); + //char seqType = dynType_sequence_elementSchemaType(seq); + + dynType_sequence_init(seq, seqLoc, size); //seq is already allocated. only need to allocate the buf + + //assuming int + int32_t i; + int index; + json_t *val; + json_array_foreach(array, index, val) { + i = json_number_value(val); + dynType_sequence_append(seq, seqLoc, &i); + } +} + +int json_serialize(dyn_type *type, void *input, char **output, size_t *size) { + return 0; +} http://git-wip-us.apache.org/repos/asf/celix/blob/387f7792/remote_services/dyn_type/json_serializer.h ---------------------------------------------------------------------- diff --git a/remote_services/dyn_type/json_serializer.h b/remote_services/dyn_type/json_serializer.h new file mode 100644 index 0000000..edc87af --- /dev/null +++ b/remote_services/dyn_type/json_serializer.h @@ -0,0 +1,9 @@ +#ifndef __JSON_SERIALIZER_H_ +#define __JSON_SERIALIZER_H_ + +#include "dyn_type.h" + +int json_deserialize(dyn_type *type, const char *input, void **result); +int json_serialize(dyn_type *type, void *input, char **output, size_t *size); + +#endif http://git-wip-us.apache.org/repos/asf/celix/blob/387f7792/remote_services/dyn_type/struct_tests.c ---------------------------------------------------------------------- diff --git a/remote_services/dyn_type/struct_tests.c b/remote_services/dyn_type/struct_tests.c new file mode 100644 index 0000000..ecf1fd4 --- /dev/null +++ b/remote_services/dyn_type/struct_tests.c @@ -0,0 +1,159 @@ +#include +#include +#include +#include +#include + +#include + +#include "dyn_type.h" +#include "json_serializer.h" + +/*********** example 1 ************************/ +/** struct type ******************************/ +const char *example1_schema = "{DJISF a b c d e}"; + +const char *example1_input = "{ \ + \"a\" : 1.0, \ + \"b\" : 22, \ + \"c\" : 32, \ + \"d\" : 42, \ + \"e\" : 4.4 \ +}"; + +struct example1 { + double a; //0 + int64_t b; //1 + int32_t c; //2 + int16_t d; //3 + float e; //4 +}; + +void print_example1(void *data) { + struct example1 *ex = data; + printf("example1: a:%f, b:%li, c:%i, d:%i, e:%f\n", ex->a, ex->b, ex->c, ex->d, ex->e); +} + +/*********** example 2 ************************/ +/** struct type with some extra whitespace*/ +const char *example2_schema = " { BJJDFD byte long1 long2 double1 float1 double2 } "; + +const char *example2_input = "{ \ + \"byte\" : 42, \ + \"long1\" : 232, \ + \"long2\" : 242, \ + \"double1\" : 4.2, \ + \"float1\" : 3.2, \ + \"double2\" : 4.4 \ +}"; + +struct example2 { + char byte; //0 + int64_t long1; //1 + int64_t long2; //2 + double double1; //3 + float float1; //4 + double double2; //5 +}; + +void print_example2(void *data) { + struct example2 *ex = data; + printf("example2: byte:%i, long1:%li, long2:%li, double1:%f, float1:%f, double2:%f\n", ex->byte, ex->long1, ex->long2, ex->double1, ex->float1, ex->double2); +} + + +/*********** example 3 ************************/ +/** sequence with a simple type **************/ +const char *example3_schema = "{[I numbers}"; + +const char *example3_input = "{ \ + \"numbers\" : [22,32,42] \ +}"; + +struct example3 { + struct { + uint32_t _cap; + uint32_t _len; + int32_t *buf; + } numbers; +}; + +void print_example3(void *data) { + struct example3 *ex = data; + printf("example3: numbers length is %u and cap is %u and pointer buf is %p\n", ex->numbers._len, ex->numbers._cap, ex->numbers.buf); + int i; + for (i = 0; i < ex->numbers._len; i += 1) { + printf("\telement %i : %i\n", i, ex->numbers.buf[i]); + } +} + +/*********** example 4 ************************/ +/** structs within a struct (by reference)*******/ +//TODO think about references in schema e.g "{Lleaf;Lleaf; left right}\nleaf{IDD index val1 val2}" +const char *example4_schema = "{{IDD index val1 val2}{IDD index val1 val2} left right}"; + +const char *example4_input = "{ \ + \"left\" : {\"index\":1, \"val1\":1.0, \"val2\":2.0 }, \ + \"right\" : {\"index\":2, \"val1\":5.0, \"val2\":4.0 } \ +}"; + +struct leaf { + int32_t index; + double val1; + double val2; +}; + +struct example4 { + struct leaf *left; + struct leaf *right; +}; + +void print_example4(void *data) { + struct example4 *ex = data; + printf("example4: left { index:%i, val1:%f, val2:%f }, right { index;%i, val1:%f, val2:%f }\n", ex->left->index, ex->left->val1, ex->left->val2, ex->right->index, ex->right->val1, ex->right->val2); +} + +int main() { + printf("Starting ffi struct test\n"); + dyn_type *type; + void *inst; + + type = NULL; + inst = NULL; + dynType_create(example1_schema, &type); + printf("-- example 1\n"); + dynType_print(type); + json_deserialize(type, example1_input, &inst); + print_example1(inst); + printf("--\n\n"); + + + type = NULL; + inst = NULL; + dynType_create(example2_schema, &type); + printf("-- example 2\n"); + dynType_print(type); + json_deserialize(type, example2_input, &inst); + print_example2(inst); + printf("--\n\n"); + + type = NULL; + inst = NULL; + dynType_create(example3_schema, &type); + printf("-- example 3\n"); + dynType_print(type); + json_deserialize(type, example3_input, &inst); + print_example3(inst); + printf("--\n\n"); + + type = NULL; + inst = NULL; + dynType_create(example4_schema, &type); + printf("-- example 4\n"); + dynType_print(type); + json_deserialize(type, example4_input, &inst); + print_example4(inst); + printf("--\n\n"); + + return 0; +} http://git-wip-us.apache.org/repos/asf/celix/blob/387f7792/remote_services/examples/calculator_proxy/private/src/calculator_proxy_impl.c ---------------------------------------------------------------------- diff --git a/remote_services/examples/calculator_proxy/private/src/calculator_proxy_impl.c b/remote_services/examples/calculator_proxy/private/src/calculator_proxy_impl.c index fc21412..af2cfc3 100644 --- a/remote_services/examples/calculator_proxy/private/src/calculator_proxy_impl.c +++ b/remote_services/examples/calculator_proxy/private/src/calculator_proxy_impl.c @@ -68,7 +68,7 @@ celix_status_t calculatorProxy_add(calculator_pt calculator, double a, double b, if (calculator->endpoint != NULL) { json_t *root; - root = json_pack("{s:s, s:[ff]}", "m", "add(DD)D", "a", a, b); + root = json_pack("{s:s, s:[fmt]}", "m", "add(DD)D", "a", a, b); char *data = json_dumps(root, 0); char *reply = NULL; http://git-wip-us.apache.org/repos/asf/celix/blob/387f7792/remote_services/examples/calculator_service/private/src/calculator_activator.c ---------------------------------------------------------------------- diff --git a/remote_services/examples/calculator_service/private/src/calculator_activator.c b/remote_services/examples/calculator_service/private/src/calculator_activator.c index 22f72b5..d280eaa 100644 --- a/remote_services/examples/calculator_service/private/src/calculator_activator.c +++ b/remote_services/examples/calculator_service/private/src/calculator_activator.c @@ -75,6 +75,7 @@ celix_status_t bundleActivator_start(void * userData, bundle_context_pt context) properties = properties_create(); properties_set(properties, (char *) OSGI_RSA_SERVICE_EXPORTED_INTERFACES, (char *) CALCULATOR_SERVICE); + properties_set(properties, (char *) "protocol.schema", (char *)CALC_SCHEMA); bundleContext_registerService(context, (char *) CALCULATOR_SERVICE, activator->service, properties, &activator->calculatorReg); http://git-wip-us.apache.org/repos/asf/celix/blob/387f7792/remote_services/examples/calculator_service/public/include/calculator_service.h ---------------------------------------------------------------------- diff --git a/remote_services/examples/calculator_service/public/include/calculator_service.h b/remote_services/examples/calculator_service/public/include/calculator_service.h index 0a802d2..3219c64 100644 --- a/remote_services/examples/calculator_service/public/include/calculator_service.h +++ b/remote_services/examples/calculator_service/public/include/calculator_service.h @@ -33,6 +33,31 @@ typedef struct calculator *calculator_pt; typedef struct calculator_service *calculator_service_pt; +#define CALC_SCHEMA "[\"add(DD)D\",\"sub(DD)D\",\"sqrt(D)D\"]" + +/* +purpose different schema setup +{ + "methods" : [ "add(DD)D", "sub(DD)D", "sqrt(D)D", abc(Labc_input;)D", sum([D)D" ], + "types" : { + "abc_input" : "DDD a b c" + } +} + +struct abc_input { + double a; + double b; + double c; +} + +//for [D the following struct layout will be assumed +struct double_sequence { + size_t _max; + size_t _length; + double *buffer; +}; +*/ + /* * The calculator service definition corresponds to the following Java interface: * @@ -44,9 +69,9 @@ typedef struct calculator_service *calculator_service_pt; */ struct calculator_service { calculator_pt calculator; - celix_status_t (*add)(calculator_pt calculator, double a, double b, double *result); - celix_status_t (*sub)(calculator_pt calculator, double a, double b, double *result); - celix_status_t (*sqrt)(calculator_pt calculator, double a, double *result); + 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); }; http://git-wip-us.apache.org/repos/asf/celix/blob/387f7792/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 index 13071cf..260add3 100644 --- a/remote_services/examples/calculator_shell/private/src/add_command.c +++ b/remote_services/examples/calculator_shell/private/src/add_command.c @@ -26,6 +26,7 @@ #include #include +#include #include "array_list.h" #include "bundle_context.h" @@ -58,7 +59,7 @@ void addCommand_execute(command_pt command, char *line, void (*out)(char *), voi status = bundleContext_getServiceReference(command->bundleContext, (char *) CALCULATOR_SERVICE, &calculatorService); if (status == CELIX_SUCCESS) { - char *token; + char *token = line; strtok_r(line, " ", &token); char *aStr = strtok_r(NULL, " ", &token); bool numeric; http://git-wip-us.apache.org/repos/asf/celix/blob/387f7792/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 index bdb809a..af770d1 100644 --- a/remote_services/examples/calculator_shell/private/src/sqrt_command.c +++ b/remote_services/examples/calculator_shell/private/src/sqrt_command.c @@ -58,7 +58,7 @@ void sqrtCommand_execute(command_pt command, char *line, void (*out)(char *), vo status = bundleContext_getServiceReference(command->bundleContext, (char *) CALCULATOR_SERVICE, &calculatorService); if (status == CELIX_SUCCESS) { - char *token; + char *token = line; strtok_r(line, " ", &token); char *aStr = strtok_r(NULL, " ", &token); bool numeric; http://git-wip-us.apache.org/repos/asf/celix/blob/387f7792/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 index 8ba8a9e..b4dc95a 100644 --- a/remote_services/examples/calculator_shell/private/src/sub_command.c +++ b/remote_services/examples/calculator_shell/private/src/sub_command.c @@ -58,7 +58,7 @@ void subCommand_execute(command_pt command, char *line, void (*out)(char *), voi status = bundleContext_getServiceReference(command->bundleContext, (char *) CALCULATOR_SERVICE, &calculatorService); if (status == CELIX_SUCCESS) { - char *token; + char *token = line; strtok_r(line, " ", &token); char *aStr = strtok_r(NULL, " ", &token); bool numeric; http://git-wip-us.apache.org/repos/asf/celix/blob/387f7792/remote_services/examples/deploy.cmake ---------------------------------------------------------------------- diff --git a/remote_services/examples/deploy.cmake b/remote_services/examples/deploy.cmake index 9f254d7..0b17811 100644 --- a/remote_services/examples/deploy.cmake +++ b/remote_services/examples/deploy.cmake @@ -16,44 +16,10 @@ # under the License. is_enabled(RSA_EXAMPLES) if (RSA_EXAMPLES) - is_enabled(RSA_REMOTE_SERVICE_ADMIN_HTTP) - if (RSA_REMOTE_SERVICE_ADMIN_HTTP) - is_enabled(RSA_DISCOVERY_CONFIGURED) - if (RSA_DISCOVERY_CONFIGURED) - deploy("remote-services-cfg" BUNDLES discovery_configured topology_manager remote_service_admin_http calculator shell shell_tui log_service log_writer - ENDPOINTS - org.apache.celix.calc.api.Calculator_endpoint - org.apache.celix.calc.api.Calculator2_endpoint - PROPERTIES - RSA_PORT=8001 - DISCOVERY_CFG_POLL_ENDPOINTS=http://localhost:8082/org.apache.celix.discovery.configured - DISCOVERY_CFG_SERVER_PORT=8081) - deploy("remote-services-cfg-client" BUNDLES topology_manager remote_service_admin_http shell shell_tui log_service log_writer calculator_shell discovery_configured - ENDPOINTS org.apache.celix.calc.api.Calculator_proxy org.apache.celix.calc.api.Calculator2_proxy - PROPERTIES - RSA_PORT=8002 - DISCOVERY_CFG_POLL_ENDPOINTS=http://localhost:8081/org.apache.celix.discovery.configured - DISCOVERY_CFG_SERVER_PORT=8082) - endif () - endif () - - is_enabled(RSA_REMOTE_SERVICE_ADMIN_SHM) - if (RSA_REMOTE_SERVICE_ADMIN_SHM) - is_enabled(RSA_DISCOVERY_SHM) - if (RSA_DISCOVERY_SHM) - deploy("remote-services-shm" BUNDLES discovery_shm topology_manager remote_service_admin_shm calculator shell shell_tui log_service log_writer - ENDPOINTS org.apache.celix.calc.api.Calculator_endpoint) - deploy("remote-services-shm-client" BUNDLES topology_manager remote_service_admin_shm shell shell_tui log_service log_writer calculator_shell discovery_shm - ENDPOINTS org.apache.celix.calc.api.Calculator_proxy) - endif () - endif () - is_enabled(RSA_DISCOVERY_ETCD) if (RSA_DISCOVERY_ETCD) - deploy("remote-services-etcd" BUNDLES discovery_etcd topology_manager remote_service_admin_http calculator shell shell_tui log_service log_writer - ENDPOINTS org.apache.celix.calc.api.Calculator_endpoint) - deploy("remote-services-etcd-client" BUNDLES topology_manager remote_service_admin_http shell shell_tui log_service log_writer calculator_shell discovery_etcd - ENDPOINTS org.apache.celix.calc.api.Calculator_proxy) + deploy("remote-services-etcd" BUNDLES discovery_etcd topology_manager remote_service_admin_http calculator shell shell_tui log_service log_writer) + deploy("remote-services-etcd-client" BUNDLES topology_manager remote_service_admin_http shell shell_tui log_service log_writer calculator_shell discovery_etcd) endif () endif (RSA_EXAMPLES) http://git-wip-us.apache.org/repos/asf/celix/blob/387f7792/remote_services/remote_service_admin/private/src/export_registration_impl.c ---------------------------------------------------------------------- diff --git a/remote_services/remote_service_admin/private/src/export_registration_impl.c b/remote_services/remote_service_admin/private/src/export_registration_impl.c index 7011104..d6ce934 100644 --- a/remote_services/remote_service_admin/private/src/export_registration_impl.c +++ b/remote_services/remote_service_admin/private/src/export_registration_impl.c @@ -174,7 +174,8 @@ celix_status_t exportRegistration_endpointRemoved(void * handle, service_referen } celix_status_t exportRegistration_open(export_registration_pt registration) { - celix_status_t status; + celix_status_t status = CELIX_SUCCESS; + /* char *bundleStore = NULL; bundleContext_getProperty(registration->context, BUNDLE_STORE_PROPERTY_NAME, &bundleStore); @@ -192,6 +193,7 @@ celix_status_t exportRegistration_open(export_registration_pt registration) { if (status == CELIX_SUCCESS) { } } + */ return status; } http://git-wip-us.apache.org/repos/asf/celix/blob/387f7792/remote_services/remote_service_admin_http_ffi/CMakeLists.txt ---------------------------------------------------------------------- diff --git a/remote_services/remote_service_admin_http_ffi/CMakeLists.txt b/remote_services/remote_service_admin_http_ffi/CMakeLists.txt new file mode 100644 index 0000000..ea94b16 --- /dev/null +++ b/remote_services/remote_service_admin_http_ffi/CMakeLists.txt @@ -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. +celix_subproject(RSA_REMOTE_SERVICE_ADMIN_HTTP "Option to enable building the Remote Service Admin Service HTTP ffi" OFF) +if (RSA_REMOTE_SERVICE_ADMIN_HTTP) + find_package(CURL REQUIRED) + find_package(Jansson REQUIRED) + + include_directories(${CURL_INCLUDE_DIRS}) + include_directories(${Jansson}) + include_directories("${PROJECT_SOURCE_DIR}/utils/public/include") + include_directories("${PROJECT_SOURCE_DIR}/log_service/public/include") + include_directories("${PROJECT_SOURCE_DIR}/remote_services/utils/private/include") + include_directories("${PROJECT_SOURCE_DIR}/remote_services/utils/public/include") + include_directories("${PROJECT_SOURCE_DIR}/remote_services/remote_service_admin/public/include") + include_directories("${PROJECT_SOURCE_DIR}/remote_services/remote_service_admin/private/include") + include_directories("${PROJECT_SOURCE_DIR}/remote_services/remote_service_admin_http/private/include") + include_directories("${PROJECT_SOURCE_DIR}/remote_services/endpoint_listener/public/include") + + SET_HEADER(BUNDLE_SYMBOLICNAME "apache_celix_remote_service_admin_http_ffi") + SET(BUNDLE_VERSION "0.0.1") + SET_HEADERS("Bundle-Name: Apache Celix Remote Service Admin HTTP for ffi") + + bundle(remote_service_admin_http SOURCES + private/src/remote_service_admin_impl + private/src/remote_service_admin_activator + ${PROJECT_SOURCE_DIR}/remote_services/remote_service_admin/private/src/export_registration_impl + ${PROJECT_SOURCE_DIR}/remote_services/remote_service_admin/private/src/import_registration_impl + ${PROJECT_SOURCE_DIR}/remote_services/utils/private/src/civetweb.c + ${PROJECT_SOURCE_DIR}/log_service/public/src/log_helper.c + ) + + install_bundle(remote_service_admin_http) + + target_link_libraries(remote_service_admin_http celix_framework ${CURL_LIBRARIES} ${JANSSON_LIBRARIES} /lib64/libffi.so ) +endif (RSA_REMOTE_SERVICE_ADMIN_HTTP) http://git-wip-us.apache.org/repos/asf/celix/blob/387f7792/remote_services/remote_service_admin_http_ffi/private/include/remote_service_admin_http_impl.h ---------------------------------------------------------------------- diff --git a/remote_services/remote_service_admin_http_ffi/private/include/remote_service_admin_http_impl.h b/remote_services/remote_service_admin_http_ffi/private/include/remote_service_admin_http_impl.h new file mode 100644 index 0000000..dbf71c9 --- /dev/null +++ b/remote_services/remote_service_admin_http_ffi/private/include/remote_service_admin_http_impl.h @@ -0,0 +1,52 @@ +/** + *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 Apache Celix Project Team + * \copyright Apache License, Version 2.0 + */ + +#ifndef REMOTE_SERVICE_ADMIN_HTTP_IMPL_H_ +#define REMOTE_SERVICE_ADMIN_HTTP_IMPL_H_ + +#include "remote_service_admin_impl.h" +#include "log_helper.h" +#include "civetweb.h" + +struct remote_service_admin { + bundle_context_pt context; + log_helper_pt loghelper; + + celix_thread_mutex_t exportedServicesLock; + hash_map_pt exportedServices; + + celix_thread_mutex_t importedServicesLock; + hash_map_pt importedServices; + + char *port; + char *ip; + + struct mg_context *ctx; +}; + +celix_status_t remoteServiceAdmin_stop(remote_service_admin_pt admin); + +#endif /* REMOTE_SERVICE_ADMIN_HTTP_IMPL_H_ */ http://git-wip-us.apache.org/repos/asf/celix/blob/387f7792/remote_services/remote_service_admin_http_ffi/private/src/remote_service_admin_activator.c ---------------------------------------------------------------------- diff --git a/remote_services/remote_service_admin_http_ffi/private/src/remote_service_admin_activator.c b/remote_services/remote_service_admin_http_ffi/private/src/remote_service_admin_activator.c new file mode 100644 index 0000000..e4125fc --- /dev/null +++ b/remote_services/remote_service_admin_http_ffi/private/src/remote_service_admin_activator.c @@ -0,0 +1,122 @@ +/** + *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 Apache Celix Project Team + * \copyright Apache License, Version 2.0 + */ +#include + +#include "bundle_activator.h" +#include "service_registration.h" + +#include "remote_service_admin_http_impl.h" +#include "export_registration_impl.h" +#include "import_registration_impl.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 = exportRegistration_close; + 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; + + remoteServiceAdmin_stop(activator->admin); + serviceRegistration_unregister(activator->registration); + activator->registration = NULL; + + 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; +} + +