PengZheng commented on code in PR #690: URL: https://github.com/apache/celix/pull/690#discussion_r1403975941
########## bundles/remote_services/rsa_rpc_json/README.md: ########## @@ -0,0 +1,68 @@ +--- +title: Remote Service Admin RPC Using JSON +--- + +<!-- +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 RPC Using JSON + +Remote service admin RPC does not appear in the OSGI standard document. It is an extraction of the serialization/deserialization functionality from remote service admin. It is part of the remote service admin feature. + +`rsa_json_rpc` is a serialization implementation based on [JSON representation](https://amdatu.atlassian.net/wiki/spaces/AMDATUDEV/pages/21954571/Amdatu+Remote#AmdatuRemote-AdminHTTP%2FJson). It uses `libdfi` to convert function invocation information into JSON messages. The interface description is configured through the description file in the interface consumer/provider. See the [libdfi documentation](../../../libs/dfi/README.md) for the interface description file. + +### Supported Platform +- Linux + +### Properties/Configuration + +| **Properties** | **Type** | **Description**| +|----------------|----------|----------------| +| **RSA_JSON_RPC_LOG_CALLS**| bool | If set to true, the RSA will Log calls info to the file in RSA_JSON_RPC_LOG_CALLS_FILE. Default is false. | +| **RSA_JSON_RPC_LOG_CALLS_FILE**| string | Log file. If RSA_JSON_RPC_LOG_CALLS is enabled, the service calls info will be writen to the file(If restart this bundle, it will truncate file). Default is stdout. | + +### Conan Option + build_rsa_json_rpc=True Default is False + +### CMake Option + RSA_JSON_RPC=ON Default is OFF + +### Software Design + +The implementation of `rsa_json_rpc` includes two parts: 1. Creation of remote service endpoints; 2. Creation of remote service proxies + +- Remote service endpoint: It receives remote JSON_RPC requests and calls the corresponding service instances. +- Remote service proxy: It provides proxy services and serializes service call information (method name, arguments,...) into JSON_RPC requests. + +#### The Process Of Creating And Using A Remote Endpoint + +When a service is exported, RSA can use rsa_json_rpc to create a service endpoint. When a service is called, the service endpoint calls the corresponding service instance after the RPC request is deserialized. The detailed process is as follows diagram: + + + + +#### The Process Of Creating And Using A Remote Proxy + +When a service is imported, RSA can use rsa_json_rpc to create a proxy service factory. When a service is called, the proxy service factory creates the proxy service and gives it to the service caller. Then the service proxy serializes the service call information into an RPC request. And the RPC request will be sent to remote endpoint by RSA. The detailed process is as follows diagram: + + + +In the above process, each consumer of the remote service will have a different service proxy, because the service proxy needs to use the interface description file in the consumer (which may be a bundle) to serialize the service call information. Review Comment: This does not feel right. Currently, service descriptor is bundled by its various consumers. THis is far less than ideal. We'd better let service discovery and RSA fetch service descriptors from service providers at runtime. Alternatively, we can generate the descriptor from the service header, i.e. solve #590. In the same process, there should be one unique copy of service descriptor for each remote service instance. ########## bundles/remote_services/discovery_zeroconf/README.md: ########## @@ -0,0 +1,73 @@ +--- +title: Discovery Zeroconf +--- + +<!-- +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 Zeroconf + +The `Discovery_zeroconf` is implemented based on [Bonjour](https://github.com/apple-oss-distributions/mDNSResponder), and its operation depends on the mDNS daemon. + +The mapping between celix and mdns services is as follows: + +| **mDNS service** | **celix service** | +|------------------|-------------------------------------------| +| instance name | service name+hash(endpoint uuid) | +| service type | "_celix-rpc._udp"+${custom subtype} | +| domain name | "local" | +| txt record | service properties | +| host | "celix_rpc_dumb_host.local."(It is dummy) | +| port | 50009(It is dummy) | + + +Because We will perform the mDNS query only using link-local multicast, so we set domain name default value "local". + +To reduce the operation of conversion between host name and address info. we set the address info to txt record, and set the host name and port to a dummy value("celix_rpc_dumb_host.local." and "50009"). Review Comment: The content of TXT is set by the service provider. This design will force them to watch for address change, which violates the rationale of zeroconf and suggests a severe design flaw. I'll have a good read of RFC 6762 and 6763 this weekend before making further comments on this. ########## libs/dfi/README.md: ########## @@ -19,4 +19,243 @@ See the License for the specific language governing permissions and limitations under the License. --> -# Apache Celix Dynamic Function Interface +## Apache Celix Dynamic Function Interface + +Dynamic Function Interface (DFI) is a dynamic interface type implementation based on [libffi](https://en.wikipedia.org/wiki/Libffi). +It can generate dynamic interface types according to the interface description file, and can convert the corresponding +dynamic interface call into a [JSON representation](https://amdatu.atlassian.net/wiki/spaces/AMDATUDEV/pages/21954571/Amdatu+Remote#AmdatuRemote-AdminHTTP%2FJson). It can also convert the JSON representation into a dynamic interface call. + +### Conan Option + build_celix_dfi=True Default is False + +### CMake Option + CELIX_DFI=ON Default is ON + +### Interface Descriptor + +In `libdfi`, we have defined a set of simple interface description languages. Users can use this language to describe interface types, and at runtime, libdfi converts the interface description into a dynamic interface. + +Before introducing the interface description language, let's look at an example of interface description. + +~~~ +:header +type=interface +name=calculator +version=1.0.0 +:annotations +classname=org.example.Calculator +:types +StatsResult={DDD[D average min max input} +:methods +add(DD)D=add(#am=handle;PDD#am=pre;*D)N +~~~ + +As above, the interface description has four sections: the header section, annotations section, types section, and methods section. The format of each section is as follows: + +~~~ + ':header\n' 'Name=Value\n'... + ':annotations\n' 'Name=Value\n'... + ':types\n' 'TypeId=Value\n'... + ':methods\n' 'MethodId=Value\n'... +~~~ + +Among them, the legal characters that can be used in the “name” and “TypeId” include [a-zA-Z0-9_], the legal characters in “MethodId” include [a-zA-Z0-9_] and ".();[{}/". Besides [a-zA-Z0-9], the legal characters in “value” also include ".<>{}[]?;:~!@#$%^&*()_+-=,./'". It's worth noting that there should not be spaces on either side of '=', and each statement must end with a newline(‘\n’). + +For the interface description, its header section must include three elements: type, name, version. The value of "type" should be "interface", "name" is the interface name (service name), the value of "version" should coincide with the version number in the actually used interface header file, and it should conform to [semantic versioning requirements](https://semver.org/). + +#### The Data Types In The Interface Descriptor + +The data types supported by the interface description include: + +- **Simple Types** + + *Type schema*: + + |**Identifier**|B |D |F |I |J |S |V |Z |b | i | j | s |P |t |N | + |---------|---|------|-----|-------|-------|-------|----|--------------|-----|--------|--------|--------|------|------|---| + |**Types**|char|double|float|int32_t|int64_t|int16_t|void|boolean(uint8)|uchar|uint32_t|uint64_t|uint16_t|void *|char *|int| Review Comment: Now that we have `*`, why we need `t` for `char *`? ########## libs/dfi/README.md: ########## @@ -19,4 +19,243 @@ See the License for the specific language governing permissions and limitations under the License. --> -# Apache Celix Dynamic Function Interface +## Apache Celix Dynamic Function Interface + +Dynamic Function Interface (DFI) is a dynamic interface type implementation based on [libffi](https://en.wikipedia.org/wiki/Libffi). +It can generate dynamic interface types according to the interface description file, and can convert the corresponding +dynamic interface call into a [JSON representation](https://amdatu.atlassian.net/wiki/spaces/AMDATUDEV/pages/21954571/Amdatu+Remote#AmdatuRemote-AdminHTTP%2FJson). It can also convert the JSON representation into a dynamic interface call. + +### Conan Option + build_celix_dfi=True Default is False + +### CMake Option + CELIX_DFI=ON Default is ON + +### Interface Descriptor + +In `libdfi`, we have defined a set of simple interface description languages. Users can use this language to describe interface types, and at runtime, libdfi converts the interface description into a dynamic interface. + +Before introducing the interface description language, let's look at an example of interface description. + +~~~ +:header +type=interface +name=calculator +version=1.0.0 +:annotations +classname=org.example.Calculator +:types +StatsResult={DDD[D average min max input} +:methods +add(DD)D=add(#am=handle;PDD#am=pre;*D)N +~~~ + +As above, the interface description has four sections: the header section, annotations section, types section, and methods section. The format of each section is as follows: + +~~~ + ':header\n' 'Name=Value\n'... + ':annotations\n' 'Name=Value\n'... + ':types\n' 'TypeId=Value\n'... + ':methods\n' 'MethodId=Value\n'... +~~~ + +Among them, the legal characters that can be used in the “name” and “TypeId” include [a-zA-Z0-9_], the legal characters in “MethodId” include [a-zA-Z0-9_] and ".();[{}/". Besides [a-zA-Z0-9], the legal characters in “value” also include ".<>{}[]?;:~!@#$%^&*()_+-=,./'". It's worth noting that there should not be spaces on either side of '=', and each statement must end with a newline(‘\n’). + +For the interface description, its header section must include three elements: type, name, version. The value of "type" should be "interface", "name" is the interface name (service name), the value of "version" should coincide with the version number in the actually used interface header file, and it should conform to [semantic versioning requirements](https://semver.org/). + +#### The Data Types In The Interface Descriptor + +The data types supported by the interface description include: + +- **Simple Types** + + *Type schema*: + + |**Identifier**|B |D |F |I |J |S |V |Z |b | i | j | s |P |t |N | + |---------|---|------|-----|-------|-------|-------|----|--------------|-----|--------|--------|--------|------|------|---| + |**Types**|char|double|float|int32_t|int64_t|int16_t|void|boolean(uint8)|uchar|uint32_t|uint64_t|uint16_t|void *|char *|int| + + +- **Complex Types(Struct)** + + *Type schema*: + ~~~ + {[Type]+ [(Name)(SPACE)]+} + ~~~ + *Example*: + ~~~ + {DDII a b c d} + ~~~ + *To C language*: + ~~~ + struct { double a; double b; int c; int d; }; + ~~~ + +- **Sequence Type** + + *Type schema*: + ~~~ + [(type) + ~~~ + *Example*: + ~~~ + [D + ~~~ + *To C language*: + ~~~ + struct { + uint32_t cap; + uint32_t len; + duoble *buf; + }; + ~~~ + +- **Typed Pointer** + + *Type schema*: + ~~~ + *(Type) + ~~~ + *Example*: + ~~~ + *D + ~~~ + *To C language*: + ~~~ + duoble *d; + ~~~ + +- **Reference By Value** + + *Type schema*: + ~~~ + l(name); + ~~~ + *Example*: + ~~~ + MySubType={jDD time d1 d2} + MyType={DDlMySubType; d11 d12 subTypeVal} + ~~~ + *To C language*: + ~~~ + struct MySubType{ + uint64_t time; + double d1; + double d2; + }; + struct MyType { + double d11; + double d12; + struct MySubType subTypeVal; + }; + ~~~ + +- **Pointer Reference** + + *Type schema*: + ~~~ + L(name);//shortcut for *l(name); Review Comment: Now that we have `*`, why we need `*l`? -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: dev-unsubscr...@celix.apache.org For queries about this service, please contact Infrastructure at: us...@infra.apache.org