Since Camel 4.0.0
Both producer and consumer are supported
The Camel DHIS2 component leverages the DHIS2 Java SDK to integrate Apache Camel with DHIS2. DHIS2 is a free, open-source, fully customizable platform for collecting, analyzing, visualizing, and sharing aggregate and individual-data for district-level, national, regional, and international system and program management in health, education, and other domains.
Maven users will need to add the following dependency to their pom.xml
.
<dependency>
<groupId>org.hisp.dhis.integration.camel</groupId>
<artifactId>camel-dhis2</artifactId>
<version>x.x.x</version>
</dependency>
Camel components are configured on two separate levels:
-
component level
-
endpoint level
The component level is the highest level which holds general and common configurations that are inherited by the endpoints. For example a component may have security settings, credentials for authentication, urls for network connection and so forth.
Some components only have a few options, and others may have many. Because components typically have pre-configured defaults that are commonly used, then you may often only need to configure a few options on a component; or none at all.
Configuring components can be done with the Component DSL, in a configuration file (application.properties|yaml), or directly with Java code.
Where you find yourself configuring the most is on endpoints, as endpoints often have many options, which allows you to configure what you need the endpoint to do. The options are also categorized into whether the endpoint is used as consumer (from) or as a producer (to), or used for both.
Configuring endpoints is most often done directly in the endpoint URI as path and query parameters. You can also use the Endpoint DSL as a type safe way of configuring endpoints.
A good practice when configuring options is to use Property Placeholders, which allows to not hardcode urls, port numbers, sensitive information, and other settings. In other words placeholders allows to externalize the configuration from your code, and gives more flexibility and reuse.
The following two sections lists all the options, firstly for the component followed by the endpoint.
The DHIS2 component supports the options listed below.
Naming | Description | Default | Type |
---|---|---|---|
baseApiUrl (common) |
DHIS2 server base API URL |
String |
|
username (common) |
Username of the DHIS2 user to operate as |
String |
|
password (common) |
Password of the DHIS2 username |
String |
|
personalAccessToken (common) |
Personal access token to authenticate with DHIS2. This option is mutually exclusive to username and password |
String |
|
client (advanced) |
Dhis2Client is an expensive object to create. To avoid creating multiple instances, it can be set directly. |
org.hisp.dhis.integration.sdk.api.Dhis2Client |
The DHIS2 endpoint is configured using URI syntax:
dhis2:apiName/methodName
with the following path and query parameters:
Naming | Description | Default | Type |
---|---|---|---|
apiName (common) |
Required What kind of operation to perform. Enum values: |
Dhis2ApiName |
|
methodName (common) |
Required What sub operation to use for the selected operation |
String |
Naming | Description | Default | Type |
---|---|---|---|
baseApiUrl (common) |
DHIS2 server base API URL |
String |
|
inBody (common) |
Sets the name of a parameter to be passed in the exchange In Body |
resource |
String |
client (advanced) |
To use the custom client |
org.hisp.dhis.integration.sdk.api.Dhis2Client |
|
password (security) |
Password to use for basic authentication |
String |
|
username (security) |
Username to use for basic authentication |
String |
The DHIS2 endpoint is an API-based component and has additional parameters based on which API name and API method is used. The API name and API method is located in the endpoint URI as the apiName/methodName path parameters:
dhis2:apiName/methodName
The API names as listed in the table below:
API Name | Type | Description |
---|---|---|
get |
Both |
API for the get operation, which fetches a resource or a list resources from the server |
post |
Both |
API for the create operation, which creates a new resource on the server |
resourceTables |
Both |
API for resource and analytic operations |
Each API is documented in the following sections to come.
Both producer and consumer are supported
The get API is defined in the syntax as follows:
dhis2:get/methodName?[parameters]
The method(s) is listed in the table below, followed by detailed syntax for each method. (API methods can have a shorthand alias name which can be used in the syntax instead of the name)
Method | Alias | Description |
---|---|---|
resource |
Retrieve a resource |
|
collection |
Retrieve a list of resources |
Signatures:
-
java.io.InputStream resource(java.lang.String path, java.lang.String fields, java.lang.String filter, org.apache.camel.component.dhis2.api.RootJunctionEnum rootJunction, java.util.Map<String, Object> queryParams)
The get/resource API method has the parameters listed in the table below:
Parameter | Description | Type |
---|---|---|
path |
Resource URL path |
String |
fields |
Comma-delimited list of fields to fetch |
String |
filter |
Search criteria |
String |
rootJunction |
Logic junction used between filters |
RootJunctionEnum |
queryParams |
Custom query parameters |
Map |
In addition to the parameters above, the get/resource API can also use any of the Query Parameters.
Any of the parameters can be provided in either the endpoint URI, or dynamically in a message header. The message header name must be of the format CamelDhis2.parameter. The inBody parameter overrides message header, i.e. the endpoint parameter inBody=myParameterNameHere would override a CamelDhis2.myParameterNameHere header.
Signatures:
-
java.util.Iterator collection(java.lang.String path, java.lang.Boolean paging, java.lang.String fields, java.lang.String filter, java.util.Map<String, Object> queryParams)
The get/collection API method has the parameters listed in the table below:
Parameter | Description | Type |
---|---|---|
path |
Resource URL path |
String |
arrayName |
JSON property name holding the array to read |
String |
paging |
Turn paging on/off |
Boolean |
fields |
Comma-delimited list of fields to fetch |
String |
filter |
Search criteria |
String |
rootJunction |
Logic junction used between filters |
RootJunctionEnum |
queryParams |
Custom query parameters |
Map |
In addition to the parameters above, the get/collection API can also use any of the Query Parameters.
Any of the parameters can be provided in either the endpoint URI, or dynamically in a message header. The message header name must be of the format CamelDhis2.parameter. The inBody parameter overrides message header, i.e. the endpoint parameter inBody=myParameterNameHere would override a CamelDhis2.myParameterNameHere header.
Both producer and consumer are supported
The post API is defined in the syntax as follows:
dhis2:post/methodName?[parameters]
Signatures:
-
java.io.InputStream resource(java.lang.String path, java.lang.Object resource, java.util.Map<String, Object queryParams)
The post/resource API method has the parameters listed in the table below:
Parameter | Description | Type |
---|---|---|
path |
Resource URL path |
String |
resource |
New resource |
Object |
queryParams |
Custom query parameters |
Map |
In addition to the parameters above, the post/resource API can also use any of the Query Parameters.
Any of the parameters can be provided in either the endpoint URI, or dynamically in a message header. The message header name must be of the format CamelDhis2.parameter. The inBody parameter overrides message header, i.e. the endpoint parameter inBody=myParameterNameHere would override a CamelDhis2.myParameterNameHere header.
Both producer and consumer are supported
The post API is defined in the syntax as follows:
dhis2:put/methodName?[parameters]
Signatures:
-
java.io.InputStream resource(java.lang.String path, java.lang.Object resource, java.util.Map<String, Object queryParams)
The put/resource API method has the parameters listed in the table below:
Parameter | Description | Type |
---|---|---|
path |
Resource URL path |
String |
resource |
Updated resource |
Object |
queryParams |
Custom query parameters |
Map |
In addition to the parameters above, the put/resource API can also use any of the Query Parameters.
Any of the parameters can be provided in either the endpoint URI, or dynamically in a message header. The message header name must be of the format CamelDhis2.parameter. The inBody parameter overrides message header, i.e. the endpoint parameter inBody=myParameterNameHere would override a CamelDhis2.myParameterNameHere header.
Both producer and consumer are supported
The delete API is defined in the syntax as follows:
dhis2:delete/methodName?[parameters]
Signatures:
-
java.io.InputStream resource(java.lang.String path, java.lang.Object resource, java.util.Map<String, Object queryParams)
The delete/resource API method has the parameters listed in the table below:
Parameter | Description | Type |
---|---|---|
path |
Resource URL path |
String |
resource |
Deleted resource |
Object |
queryParams |
Custom query parameters |
Map |
In addition to the parameters above, the delete/resource API can also use any of the Query Parameters.
Any of the parameters can be provided in either the endpoint URI, or dynamically in a message header. The message header name must be of the format CamelDhis2.parameter. The inBody parameter overrides message header, i.e. the endpoint parameter inBody=myParameterNameHere would override a CamelDhis2.myParameterNameHere header.
Both producer and consumer are supported
The resourceTables API is defined in the syntax as follows:
dhis2:resourceTables/methodName?[parameters]
Signatures:
-
void analytics(java.lang.Boolean skipAggregate, java.lang.Boolean skipEvents, java.lang.Integer lastYears, java.lang.Integer, interval)
The post/resource API method has the parameters listed in the table below:
The resourceTables/analytics API method has the parameters listed in the table below:
Parameter | Description | Type |
---|---|---|
skipAggregate |
Skip generation of aggregate data and completeness data |
Boolean |
skipEvents |
Skip generation of event data |
Boolean |
lastYears |
Number of last years of data to include |
Integer |
interval |
Duration in milliseconds between completeness checks. Default is |
Integer |
async |
Whether to block until analytics is complete. Default is |
Integer |
In addition to the parameters above, the resourceTables/analytics API can also use any of the Query Parameters.
Any of the parameters can be provided in either the endpoint URI, or dynamically in a message header. The message header name must be of the format CamelDhis2.parameter. The inBody parameter overrides message header, i.e. the endpoint parameter inBody=myParameterNameHere would override a CamelDhis2.myParameterNameHere header.
-
Fetch an organisation unit by ID:
package org.camel.dhis2.example; import org.apache.camel.builder.RouteBuilder; public class MyRouteBuilder extends RouteBuilder { public void configure() { from("direct:getResource") .to("dhis2://get/resource?path=organisationUnits/O6uvpzGd5pu&username=admin&password=district&baseApiUrl=https://play.dhis2.org/40.2.2/api") .unmarshal() .json(org.hisp.dhis.api.model.v40_2_2.OrganisationUnit.class); } }
-
Fetch an organisation unit code by ID:
package org.camel.dhis2.example; import org.apache.camel.builder.RouteBuilder; public class MyRouteBuilder extends RouteBuilder { public void configure() { from("direct:getResource") .to("dhis2://get/resource?path=organisationUnits/O6uvpzGd5pu&fields=code&username=admin&password=district&baseApiUrl=https://play.dhis2.org/40.2.2/api") .unmarshal() .json(org.hisp.dhis.api.model.v40_2_2.OrganisationUnit.class); } }
-
Fetch all organisation units:
package org.camel.dhis2.example; import org.apache.camel.builder.RouteBuilder; public class MyRouteBuilder extends RouteBuilder { public void configure() { from("direct:getCollection") .to("dhis2://get/collection?path=organisationUnits&arrayName=organisationUnits&username=admin&password=district&baseApiUrl=https://play.dhis2.org/40.2.2/api") .split().body() .convertBodyTo(org.hisp.dhis.api.model.v40_2_2.OrganisationUnit.class).log("${body}"); } }
-
Fetch all organisation unit codes:
package org.camel.dhis2.example; import org.apache.camel.builder.RouteBuilder; public class MyRouteBuilder extends RouteBuilder { public void configure() { from("direct:getCollection") .to("dhis2://get/collection?path=organisationUnits&fields=code&arrayName=organisationUnits&username=admin&password=district&baseApiUrl=https://play.dhis2.org/40.2.2/api") .split().body() .convertBodyTo(org.hisp.dhis.api.model.v40_2_2.OrganisationUnit.class) .log("${body}"); } }
-
Fetch users with a phone number:
package org.camel.dhis2.example; import org.apache.camel.builder.RouteBuilder; public class MyRouteBuilder extends RouteBuilder { public void configure() { from("direct:getCollection") .to("dhis2://get/collection?path=users&filter=phoneNumber:!null:&arrayName=users&username=admin&password=district&baseApiUrl=https://play.dhis2.org/40.2.2/api") .split().body() .convertBodyTo(org.hisp.dhis.api.model.v40_2_2.User.class) .log("${body}"); } }
-
Save a data value set
package org.camel.dhis2.example; import org.apache.camel.LoggingLevel; import org.apache.camel.builder.RouteBuilder; import org.hisp.dhis.api.model.v40_2_2.DataValueSet; import org.hisp.dhis.api.model.v40_2_2.DataValue; import org.hisp.dhis.api.model.v40_2_2.WebMessage; import org.hisp.dhis.integration.sdk.support.period.PeriodBuilder; import java.time.ZoneOffset; import java.time.ZonedDateTime; import java.time.format.DateTimeFormatter; import java.util.Date; import java.util.List; public class MyRouteBuilder extends RouteBuilder { public void configure() { from("direct:postResource") .setBody(exchange -> new DataValueSet().withCompleteDate( ZonedDateTime.now(ZoneOffset.UTC).format(DateTimeFormatter.ISO_INSTANT)) .withOrgUnit("O6uvpzGd5pu") .withDataSet("lyLU2wR22tC").withPeriod(PeriodBuilder.monthOf(new Date(), -1)) .withDataValues( List.of(new DataValue().withDataElement("aIJZ2d2QgVV").withValue("20")))) .to("dhis2://post/resource?path=dataValueSets&username=admin&password=district&baseApiUrl=https://play.dhis2.org/40.2.2/api") .unmarshal().json(WebMessage.class) .choice() .when(exchange -> !exchange.getMessage().getBody(WebMessage.class).getStatus().equals(WebMessage.StatusRef.OK)) .log(LoggingLevel.ERROR, "Import error from DHIS2 while saving data value set => ${body}") .end(); } }
-
Update an organisation unit
package org.camel.dhis2.example; import org.apache.camel.LoggingLevel; import org.apache.camel.builder.RouteBuilder; import org.hisp.dhis.api.model.v40_2_2.OrganisationUnit; import org.hisp.dhis.api.model.v40_2_2.WebMessage; import org.hisp.dhis.integration.sdk.support.period.PeriodBuilder; import java.time.ZoneOffset; import java.time.ZonedDateTime; import java.time.format.DateTimeFormatter; import java.util.Date; import java.util.List; public class MyRouteBuilder extends RouteBuilder { public void configure() { from("direct:putResource") .setBody(exchange -> new OrganisationUnit().withName("Acme").withShortName("Acme").withOpeningDate(new Date())) .to("dhis2://put/resource?path=organisationUnits/jUb8gELQApl&username=admin&password=district&baseApiUrl=https://play.dhis2.org/40.2.2/api") .unmarshal().json(WebMessage.class) .choice() .when(exchange -> !exchange.getMessage().getBody(WebMessage.class).getStatus().equals(WebMessage.StatusRef.OK)) .log(LoggingLevel.ERROR, "Import error from DHIS2 while updating org unit => ${body}") .end(); } }
-
Delete an organisation unit
package org.camel.dhis2.example; import org.apache.camel.LoggingLevel; import org.apache.camel.builder.RouteBuilder; import org.hisp.dhis.api.model.v40_2_2.WebMessage; import org.hisp.dhis.integration.sdk.support.period.PeriodBuilder; import java.time.ZoneOffset; import java.time.ZonedDateTime; import java.time.format.DateTimeFormatter; import java.util.Date; import java.util.List; public class MyRouteBuilder extends RouteBuilder { public void configure() { from("direct:deleteResource") .to("dhis2://delete/resource?path=organisationUnits/jUb8gELQApl&username=admin&password=district&baseApiUrl=https://play.dhis2.org/40.2.2/api") .unmarshal().json(WebMessage.class) .choice() .when(exchange -> !exchange.getMessage().getBody(WebMessage.class).getStatus().equals(WebMessage.StatusRef.OK)) .log(LoggingLevel.ERROR, "Import error from DHIS2 while deleting org unit => ${body}") .end(); } }
-
Run analytics
package org.camel.dhis2.example; import org.apache.camel.builder.RouteBuilder; public class MyRouteBuilder extends RouteBuilder { public void configure() { from("direct:resourceTablesAnalytics") .to("dhis2://resourceTables/analytics?skipAggregate=false&skipEvents=true&lastYears=1&username=admin&password=district&baseApiUrl=https://play.dhis2.org/40.2.2/api"); } }
-
Reference DHIS2 client
package org.camel.dhis2.example; import org.apache.camel.builder.RouteBuilder; import org.hisp.dhis.integration.sdk.Dhis2ClientBuilder; import org.hisp.dhis.integration.sdk.api.Dhis2Client; public class MyRouteBuilder extends RouteBuilder { public void configure() { Dhis2Client dhis2Client = Dhis2ClientBuilder.newClient("https://play.dhis2.org/40.2.2/api", "admin", "district").build(); getCamelContext().getRegistry().bind("dhis2Client", dhis2Client); from("direct:resourceTablesAnalytics") .to("dhis2://resourceTables/analytics?skipAggregate=true&skipEvents=true&lastYears=1&client=#dhis2Client"); } }
-
Set custom query parameters
package org.camel.dhis2.example; import org.apache.camel.builder.RouteBuilder; import java.util.List; import java.util.Map; public class MyRouteBuilder extends RouteBuilder { public void configure() { from("direct:postResource") .setHeader("CamelDhis2.queryParams", constant(Map.of("cacheClear", List.of("true")))) .to("dhis2://post/resource?path=maintenance&client=#dhis2Client"); } }