External functions map existing services to Kuiper SQL functions through configuration. When running the rules that use external functions, Kuiper will convert data input and output according to the configuration, and call the corresponding service.
The configuration file of the external function is in json format, which usually consists of two parts:
The json configuration file includes the following two parts:
{"name":"helloFromMsgpack","serviceName":"SayHello"}
can map the SayHello service in the service definition to the SQL function helloFromMsgpack. For unmapped functions, the defined service uses the original name as the SQL function name.Assuming we have a service named 'sample', we can define a service definition file named sample.json as follows:
{
"about": {
"author": {
"name": "EMQ",
"email": "contact@emqx.io",
"company": "EMQ Technologies Co., Ltd",
"website": "https://www.emqx.io"
},
"helpUrl": {
"en_US": "https://github.com/emqx/kuiper/blob/master/docs/en_US/plugins/functions/functions.md",
"zh_CN": "https://github.com/emqx/kuiper/blob/master/docs/zh_CN/plugins/functions/functions.md"
},
"description": {
"en_US": "Sample external services for test only",
"zh_CN": "示例外部函数配置,仅供测试"
}
},
"interfaces": {
"trueno": {
"address": "tcp://localhost:50051",
"protocol": "grpc",
"schemaType": "protobuf",
"schemaFile": "trueno.proto"
},
"tsrest": {
"address": "http://localhost:8090",
"protocol": "rest",
"options": {
"insecureSkipVerify": true,
"headers": {
"Accept-Charset": "utf-8"
}
},
"schemaType": "protobuf",
"schemaFile": "tsrest.proto",
"functions": [
{
"name": "objectDetect",
"serviceName": "object_detection"
}
]
},
"tsrpc": {
"address": "tcp://localhost:9000",
"protocol": "msgpack-rpc",
"schemaType": "protobuf",
"schemaFile": "tsrpc.proto",
"functions": [
{
"name": "getFeature",
"serviceName": "get_feature"
},
{
"name": "getSimilarity",
"serviceName": "get_similarity"
}
]
}
}
}
This file defines the sample service, which contains the call information of 3 service interfaces:
The service provided by each service interface is defined by its corresponding schema file. Taking tsrest as an example, its schema file is tsrest.proto, which is defined as follows:
syntax = "proto3";
package ts;
service TSRest {
rpc object_detection(ObjectDetectionRequest) returns(ObjectDetectionResponse) {}
}
message ObjectDetectionRequest {
string cmd = 1;
string base64_img = 2;
}
message ObjectDetectionResponse {
string info = 1;
int32 code = 2;
string image = 3;
string result = 4;
string type = 5;
}
This file defines the tsrest service interface to provide a service object_detection, and its input and output formats are also defined by the protobuf format.
Protobuf uses proto3 format. Please refer to proto3-spec for detailed format.
Since REST and msgpack-rpc are not natively defined by protobuf, there are some limitations when using them.
The REST service is POST by default currently, and the transmission format is json. In the defined protobuf:
The msgpack-rpc service has the following limitation:
External functions need to be registered before being used. There are two ways to register:
When Kuiper is started, it will read and register the external service configuration file in the configuration folder etc/services. Before starting, users can put the configuration file into the configuration folder according to the following rules:
The file name must be $service name$.json. For example, sample.json will be registered as a sample service.
The Schema file used must be placed in the schema folder. The directory structure is similar to:
etc
services
schema
sample.proto
random.proto
...
sample.json
other.json
...
Note: After Kuiper is started, it cannot automatically load the system by modifying the configuration file. If you need to update dynamically, please use the REST service.
For dynamic registration and management of services, please refer to External Service Management API.
After the service is registered, all functions defined in it can be used in rules. Taking the rest service function object_detection defined in sample.json above as an example, it is mapped to the objectDetection function in functions. Therefore, the SQL to call this function is:
SELECT objectDetection(cmd, img) from comandStream
Before calling the function, you need to make sure that the REST service is running on http://localhost:8090 and there is an API http://localhost:8090/object_detection in it.
In the ptoto file, the general parameters are in message type. When being mapped to Kuiper, its parameters can be received in two situations:
In the above example, objectDetection receives a message parameter.
message ObjectDetectionRequest {
string cmd = 1;
string base64_img = 2;
}
In Kuiper, users can pass in the entire struct as a parameter, or pass in two string parameters as cmd and base64_img respectively.