Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Tip

Look at How to start new project? for starting new project ...

Look at Development tips and Best practicesBest practices and Reference implementation.

Adhere to conventions how to write the code.

...

Tip

You can use RouteBeanNameGenerator for automatic bean names generation.

Unit tests

Each route implementation must have corresponding unit tests, at least one successful scenario.

  • create unit test that extends AbstractTest or AbstractDbTest if database support is needed (both classes are from test module)
  • you can use Spring test profiles - see org.openhubframework.openhub.modules.TestProfiles
  • use @ActiveRoutes annotation that defines which routes will be activated for specific unit test
Tip

See How to write unit test? for more details about writing unit tests.

New synchronous route implementation

Synchronous route is route where source system waits for response. This type of requests are not stored in OpenHub evidence, there are mentions in log files only. Possible error is immediately propagated to source system.

Steps for implementation are identical to those mentioned in previous chapter.

New asynchronous route implementation

How to implement asynchronous routes is described in another page.

Route implementation tips

Checklist of features which can be used during route implementation:

...

New synchronous route implementation

Synchronous route is route where source system waits for response. This type of requests are not stored in OpenHub evidence, there are mentions in log files only. Possible error is immediately propagated to source system.

Steps for implementation are identical to those mentioned in previous chapter.

New asynchronous route implementation

How to implement asynchronous routes is described in another page.

Route implementation tips

Checklist of features which can be used during route implementation:

  • throttling - route for processing asynchronnous input requests contains throttling by default. You should add it to all synchronnous routes
  • external call - each call to external system should go through "external call" funcionality
  • route authorization is made by Camel policy, see Camel Security
  • guaranteed message processing order
  • checking of obsolete messages via object ID
  • look at components for use - msg-funnelasynch-child, ...
  • define senders CloseableHttpComponentsMessageSender for calling external system via Spring Web Service (SOAP messages). Add configuration into /META-INF/sp_ws_wsdl.xml

...

WSDL is available on /ws/hello.wsdl and endpoint on the URL /ws/hello/v1


Tip

See How to define implement web service APIservices? for more details about implementing web services.

Synchronous Hello service

Synchronous implementation is in class org.openhubframework.openhub.modules.in.hello.SyncHelloRoute

...

Code Block
@CamelConfiguration(value = AsyncHelloRoute.ROUTE_BEAN)
@Profile(ExampleProperties.EXAMPLE_PROFILE)
public class AsyncHelloRoute extends AbstractBasicRoute {

    private static final Logger LOG = LoggerFactory.getLogger(AsyncHelloRoute.class);

    static final String ROUTE_BEAN = "asyncHelloRouteBean";

    private static final String OPERATION_NAME = "asyncHello";

    static final String ROUTE_ID_ASYNC_IN = getInRouteId(ServiceEnum.HELLO, OPERATION_NAME);

    static final String ROUTE_ID_ASYNC_OUT = getOutRouteId(ServiceEnum.HELLO, OPERATION_NAME);

    static final String URI_ASYNC_HELLO_OUT = "direct:" + ROUTE_ID_ASYNC_OUT;

    private static final String URI_PRINT_GREETING = "direct:printGreeting";

    @Override
    protected void doConfigure() throws Exception {
        // asyncHello - input asynch message
        createRouteForAsyncHelloRouteIn();

        // asyncHello - process delivery to external systems
        createRouteForAsyncHelloRouteOut();
    }

    /**
     * Route for asynchronous <strong>asyncHello</strong> input operation.
     * <p/>
     * Prerequisite: none
     * <p/>
     * Output: {@link AsyncHelloResponse}
     */
    private void createRouteForAsyncHelloRouteIn() {
        Namespaces ns = new Namespaces("h", SyncHelloRoute.HELLO_SERVICE_NS);

        // note: mandatory parameters are set already in XSD, this validation is extra
        XPathValidator validator = new XPathValidator("/h:asyncHelloRequest", ns, "h:name");

        // note: only shows using but without any influence in this case
        Expression nameExpr = xpath("/h:asyncHelloRequest/h:name").namespaces(ns).stringResult();

        AsynchRouteBuilder.newInstance(ServiceEnum.HELLO, OPERATION_NAME,
                getInWsUri(new QName(SyncHelloRoute.HELLO_SERVICE_NS, "asyncHelloRequest")),
                new AsynchResponseProcessor() {
                    @Override
                    protected Object setCallbackResponse(CallbackResponse callbackResponse) {
                        AsyncHelloResponse res = new AsyncHelloResponse();
                        res.setConfirmAsyncHello(callbackResponse);
                        return res;
                    }
                }, jaxb(AsyncHelloResponse.class))

                .withValidator(validator)
                .withObjectIdExpr(nameExpr)
                .build(this);
    }

    /**
     * Route for <strong>asyncHello</strong> operation - process delivery to external systems.
     * <p/>
     * Prerequisite: none
     */
    private void createRouteForAsyncHelloRouteOut() {
        from(URI_ASYNC_HELLO_OUT)
                .routeId(ROUTE_ID_ASYNC_OUT)

                // xml -> AsyncHelloRequest
                .unmarshal(jaxb(AsyncHelloRequest.class))

                .to("extcall:message:" + URI_PRINT_GREETING);


        from(URI_PRINT_GREETING)
                .bean(this, "printGreeting");
    }

    @Handler
    public void printGreeting(@Body AsyncHelloRequest req) {
        Assert.notNull(req, "req must not be null");

        String greeting = "Hello " + req.getName();

        LOG.debug("Greeting: " + greeting);
    }
}

Unit tests

Each route implementation must have corresponding unit tests, at least one successful scenario.

  • create unit test that extends AbstractTest or AbstractDbTest if database support is needed (both classes are from test module)
  • you can use Spring test profiles - see org.openhubframework.openhub.modules.TestProfiles
  • use @ActiveRoutes annotation that defines which routes will be activated for specific unit test
Tip

See How to write unit test? for more details about writing unit tests.


There are corresponding unit tests to each route - SyncHelloRouteTest resp. AsyncHelloRouteTest.

...