Skip to content

dhis2/camel-dhis2

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

DHIS2

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>

URI Format

dhis2://operation/method[?options]

Configuring Options

Camel components are configured on two separate levels:

  • component level

  • endpoint level

Configuring Component Options

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.

Configuring Endpoint Options

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.

Component Options

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

Endpoint Options

The DHIS2 endpoint is configured using URI syntax:

dhis2:apiName/methodName

with the following path and query parameters:

Path 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

Query Parameters

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

API Parameters

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.

API: get

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

METHOD resource

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.

METHOD collection

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.

API: post

Both producer and consumer are supported

The post API is defined in the syntax as follows:

dhis2:post/methodName?[parameters]

METHOD resource

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.

API: put

Both producer and consumer are supported

The post API is defined in the syntax as follows:

dhis2:put/methodName?[parameters]

METHOD resource

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.

API: delete

Both producer and consumer are supported

The delete API is defined in the syntax as follows:

dhis2:delete/methodName?[parameters]

METHOD resource

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.

API: resourceTables

Both producer and consumer are supported

The resourceTables API is defined in the syntax as follows:

dhis2:resourceTables/methodName?[parameters]

METHOD analytics

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 30000.

Integer

async

Whether to block until analytics is complete. Default is false.

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.

Examples

  • 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");
        }
    }