In the light of the recent case of introducing malicious code through a popular JavaScript module on npm, I like to mention snyk.io .

In a simple, free of charge scenario, snyk.io scans build or dependencies files on your github or gitlab projects and periodically reports vulnerabilities. Snyk supports Node, Ruby, Java, Scala and Python projects.

If you pay for snyk.io, you get a lot more integrations, CLI and API access etc.

In my own trial I found that even for fairly recent spring boot and apache camel dependency tree there a dozen of high-rated vulnerabilities! (Many of them by using “com.fasterxml.jackson.core:jackson-databind@2.9.1”). So the next question is if it’s advisable to upgrade to a secure patch of – say – jackson-databind although I use it only indirectly – in other words: will the depended framework still work with the secure patch version?

An open-source alternative is OWASP-Dependency-Check. It scans Java and .Net dependencies, has experimental support for Python, Ruby, PHP (composer), and Node.js applications. The tool seems to be JVM-based. There is a SonarQube-plugin. I have not tried it myself.

For almost 10 years I have been working with email (SMTP) as
integration technology. It is often used between different
organizations. Using email as integration technology may seem
outdated but it is not.

mail-button

Here is a list of advantages:

  • Infrastructure (Mail servers etc.) is often already there. no need to install new software
  • Knowledge of SMTP is often available because someone has to operate the mail service within the organization anyway
  • Chances are high there are email libraries for your development  plattform given how widespread the use case of sending and receiving mails is.
  • No need for a point-to-point connection between two IT-systems because email uses several “hops” to get delivered. No need for new firewall rules, application level gateways etc.
  • Email is asynchronous. Unless you need an instant answer, using async services is a good thing. Asynchronous messaging is promoted in the context of microservices.
  • For manual testing you can send mails from your email client to
    the system
  • For manual testing or monitoring, you can easily configure another mailbox that receives mails beside the actual mailbox (just add an additional address in “To” field or add a “Cc” field)
  • Although email is one-way communication in one case we have implemented acknowledge mails with timeout rules and a retry mechanism
  • emails can be automatically acknowledged (called “delivery status notification”) but this is often configured for non-delivery only
  • there are standards for “doing things”, like encryption

Of course there are some disadvantages:

  • less control: you may depend on that “mail guy” for configuring stuff and looking after log files. this might not be a problem unless you are practicing DevOps because that “mail guy” is part of the operations team anyway
  • less control: there might be a mail server between source and destiny that does something like adding a PGP signature or rewriting a header that changes the message
  • you may have to deal with additional mails like non-delivery-mails. These mails inform you that your original mail could not be delivered
  • there are size limitations, email is not suitable for sending large filesSo from my point of you there are a number of advantage of using email
    as integration technology when exchanging messages between two or
    more different organizations.

Zachary Flower points out the importance of proper documention in his article “API Design: A Documentation-first Approach ” and even encourages a “documentation-first approach”.

He also cautions us against a “build-first” approach, utilizing existing architecture:

When designing an API, it is often desireable to take a “build first” approach, especially when utilizing the architecture of a pre-existing product. Unfortunately, this mindset doesn’t follow the standard usability practices that we follow when building apps with graphic interfaces. It is extremely important that we take a user-centric approach to API design, because we are developing a product to be consumed by other developers. If we can’t empathise with their needs and frustrations, then who can we empathise with? This user-centric focus is an important reason to start by writing your API documentation, rather than just designing it. When you create good documentation, good design follows, but the reverse isn’t necessarily true.

If you want to stop the route you are currently using, you can’t do it using

context.stopRoute()

because it will wait for the current “inflight” message to be processed until “the end”.

So you need to do this async:

// ....
  private void shutdownRoute() {
    ShutdownRoute shutdownRoute = new ShutdownRoute(camelContext);
    new Thread(shutdownRoute).start();
    try {
      Thread.sleep(1000); // makes sure route is stop before this message finished 
    } catch (InterruptedException e) {
      // whatever
    }
  }
// ...

class ShutdownRoute implements Runnable {
  /** log instance */
  private Logger log = LoggerFactory.getLogger(ShutdownRoute.class.getName());
  
  private final CamelContext context;
  
  ShutdownRoute(final CamelContext cContext) {
    context = cContext;
    
  }
  
  @Override
  public void run() {
    try {      
      context.stopRoute(YOUR_ROUTE_ID);
    } catch (Exception e) {
      log.error("Failed to stop route",e);
    }
  }
}

We do this when using the circuit breaker pattern. In the error handling processor we check if the circuit breaker goes to the OPEN state. If so, the route stops itself. Via another route we check periodically if the circuit breaker is in the HALF-OPEN state and start the route again.

At one point in our latest project using Apache Camel, I wanted to stop a message from being further processed depending on a condition. This is quite easy to do with the route builder, for example:

from("direct:example")
  .choice()
    .when(header("someheader").isEqualTo("bla"))
      .stop()
  .end()

If you already know that a message needs to be stopped right away in a Processor or a AggregationStrategy, there is an easy way to signal this without a seperate “stop-branch” in the route. You simply set the header ROUTE_STOP to TRUE like this:

if  (....) { // stop here 
      original.setProperty(Exchange.ROUTE_STOP, Boolean.TRUE);
      return original;
}

And the message will not be further processed.