Develop a new Application Service
Using Application Service Template
To help users build a custom Application Service, IOTech provides a template in the proprietary Application Service SDK, which is based on the EdgeX community's app-service-template.
If you are new to Application Functions SDK, it is recommended to read this article Application Functions SDK - EdgeX Foundry Documentation first.
This template contains a buildable/runnable sample for a new custom application service based on the 2.3.x release of the Edge Xpert Application Functions SDK.
Note
To create your own Application Services using Edge Xpert Application Service SDK, you will need a certain level of knowledge on writing Go programs. If built-in pipeline functions can satisfy your requirement, it is advisable that you use Edge Xpert Application Service Configurable rather than creating a new custom application service.
Follow the instructions below to create your new custom application service:
-
Create a new folder on your local file system and use it as the working directory for the following steps.
-
Copy all contents of edgexpert-app-service-template except configurable to the working directory.
-
Create a folder named app-functions-sdk-go-private in the working directory, and copy all the SDK contents except edgexpert-app-service-template into it.
-
Update the go.mod file in the working directory. (Go modules is a dependency management tool of Go.)
- Change the Go Module name new-app-service in go.mod to an appropriate name for your service.
- Typically this is the URL to the repository for your service. For example, if you create a repository named MyAppService on GitHub for your application, then you can use github.com/MyOrganization/MyAppService as the module name.
Note
The go-mod-bootstrap, go-mod-configuration, and go-mod-registry go modules need to be replaced with IOTech's proprietary modules for core-keeper since Edge Xpert v2.3.0:
replace github.com/edgexfoundry/go-mod-bootstrap/v2 => github.com/IOTechSystems/go-mod-bootstrap/v2 v2.3-branch replace github.com/edgexfoundry/go-mod-configuration/v2 => github.com/IOTechSystems/go-mod-configuration/v2 v2.3-branch replace github.com/edgexfoundry/go-mod-registry/v2 => github.com/IOTechSystems/go-mod-registry/v2 v2.3-branch
-
Do a global search for new-app-service in the following files to replace it with the name of your service.
- makefile
- Dockerfile
- main.go
Note
The name will be used as the service key for the Configuration and Registry Service (i.e. Consul), and you should avoid using any special characters for its value.
Note
If you change the Go Module name to a URL in step 4, you should also update the import statement inside main.go to match the name you provided in the go.mod file. For example, if the Go Module name is changed from new-app-service to github.com/MyOrganization/MyAppService, the local import statement should be updated accordingly, as shown in the following extract:
import ( "fmt" "os" "github.com/edgexfoundry/app-functions-sdk-go/appcontext" "github.com/edgexfoundry/app-functions-sdk-go/appsdk" "github.com/edgexfoundry/app-functions-sdk-go/pkg/transforms" "github.com/MyOrgnization/MyAppServiceName/functions" // Note this line )
-
Run unit tests to verify changes didn't break the code.
- Open a terminal.
- Enter the following command:
cd /path/to/workDir # See step 1 make test
-
Verify you are able to build the Go source code to an executable binary. In the terminal opened in step 6, enter the following command:
make build
-
Verify you are able to build the docker image. In the terminal opened in step 6, enter the following command:
make docker
-
Resolve all TODOs as listed in following files for your custom code:
-
makefile - defines set of tasks to be executed, such as running unit tests, building executable binary and docker image.
-
Dockerfile - defines all instructions to assemble a docker image. For more details about Dockerfile, please refer to Dockerfile reference.
-
main.go - defines the main package with a func
main()
for building an executable. The main.go will initialize an SDK instance and set up the functions pipeline. -
functions/sample.go - provides a sample implementation for following custom pipeline functions:
- LogEventDetails - prints out the incoming EdgeX Event and then pass the Event to next pipeline function.
- ConvertEventToXML - transforms incoming EdgeX Event to XMl format and then pass the transformed data to next pipeline function.
- OutputXML - sets the response data that will be returned to the trigger when pipeline execution is complete. The response data will be in XML format.
-
functions/sample_test.go - contains unit tests for the above pipeline functions.
-
res/configuration.toml - defines the default configuration for Application Service.
-
-
Repeat steps 6, 7, and 8 to verify and build your custom application service.
-
To use your custom application service in Edge Xpert, copy the following docker-compose files to your working directory.
- /etc/edgexpert/app-service.yml
- /etc/edgexpert/app-service-security.yml
cp /etc/edgexpert/app-service.yml /path/to/workDir/. cp /etc/edgexpert/app-service-security.yml /path/to/workDir/.
Update docker-compose files with your app service docker image name and tag:
app-service: image: name:tag
Note
The name and tag should match the values you specified for the -t option of the docker build command inside the makefile. You can also use command below to find the name and tag of your app service docker image:
The app service image as built in step 10 should be listed at the top of the image list:docker images
In this case, the image name is example/my-app-service and tag is dev.REPOSITORY TAG IMAGE ID CREATED SIZE example/my-app-service dev b209a554e44f 1 hours ago 33MB
-
Launch your custom application service with Edge Xpert. Open a terminal and enter command below:
cd /path/to/workDir edgexpert up app-service -p <path to the configuration toml file>
Note
edgexpert
CLI will look for docker-compose files residing in the current folder first. For further information on edgexpert CLI, refer to Edge Xpert CLI Tool.
Create new configurable pipeline functions
To create new configurable pipeline functions, you will need to do the following: - Add the pipeline function implementation to the package pkg/transforms of the SDK. - Add the configurable function implementation to the package appsdk of the SDK.
The configurable function is a helper function invoked by the LoadConfigurablePipeline
function of
the SDK to parse the [Writable.Pipeline.Functions.{FunctionName}.Parameters] configuration into the actual parameters required by the pipeline function.
Note
The Parameters
section for each function is defined in key/value pairs. You will need to convert each pair of key/value to corresponding value types as need by the configuration function.
The configurable function should have the following function signature if your configurable function requires parameters:
func (dynamic AppFunctionsSDKConfigurable) YourFunctionName(parameters map[string]string) appcontext.AppFunction
func (dynamic AppFunctionsSDKConfigurable) YourFunctionName() appcontext.AppFunction
The configurable/sample_configurable.go provides a sample implementation that shows how to make configurable functions for the sample functions. Follow instructions below to add the sample files into SDK to build a custom configurable application service:
-
Complete all steps as listed in the previous section.
-
Copy functions/sample.go and functions/sample_test.go to app-functions-sdk-go-private/pkg/transforms
-
Rename the package name inside the sample.go and sample_test.go from functions to transforms.
-
Copy configurable/sample_configurable.go to app-functions-sdk-go-private/internal/app/sample_configurable.go.
-
Modify main.go to use the
LoadConfigurablePipeline
method of SDK to read Pipeline function settings from configuration.toml:appFunctions, err := edgexSdk.LoadConfigurablePipeline() if err != nil { edgexSdk.LoggingClient.Error("failed to create function pipeline from configuration: " + err.Error()) os.Exit(-1) }
-
Follow step 6, 7, and 8 as described in the previous section to run test and build image.
-
To use these new configurable pipeline functions (LogEventDetails, ConvertEventToXML, and OutputXML), add following configuration into the [Writable] section of your service configuration toml file to define the pipeline:
[Writable.Pipeline] UseTargetTypeOfByteArray = false ExecutionOrder = "LogEventDetails, ConvertEventToXML, OutputXML" [Writable.Pipeline.Functions.LogEventDetails] [Writable.Pipeline.Functions.LogEventDetails.Parameters] LogBinaryValue = "false" [Writable.Pipeline.Functions.ConvertEventToXML] [Writable.Pipeline.Functions.OutputXML]