Stan's Corner

 View Only

Use Apache Camel K to Create Microservice Apps with Instana

By RUI LIU posted Mon August 16, 2021 10:36 AM

  
Instana is the fully-automated Application Performance Management (APM) solution designed specifically for the challenges of managing microservices and cloud-native applications.  Its extensive support of middlewares, services, products and environments ensures that Instana provides the market-leading solution in APM systems.


Apache Camel K is the popular open-source, lightweight integration framework built from Apache Camel that runs natively on Kubernetes and is specifically designed for serverless and microservice architectures. Users of Camel K can instantly run integration code written in Camel DSL on their preferred cloud (Kubernetes or OpenShift).


Instana and Apache Camel K are focused on and they are best partnered working in microservice and cloud-native environments.  With Apache Camel K, you can quickly create your code to read Instana for metrics, events, and topology data, working as a web hook to receive events, and even configure and change the Instana server system, without having to create Docker images and find image repositories.
Now let's set up Apache Camel K to work with Instana.

Set up credentials

You probably need to get credentials to access Instana unless you only want to create a Web hook to receive Instana events. Click the Settings icon, choose Team Settings > API Tokens, and then click the Add API Token link to create a new API Token.

5a097d61-9715-4fc1-80b2-8e75d975b096
Set appropriate permissions for the API Token in accordance with your requirements to use Instana Backend API.

2ffe6817-e830-4e8e-af8e-fb1950f74025
To set access information (endpoint and API token) of Instana to Camel K integrations, a typical way is to use Config Map to set Camel K system properties.
For example:

apiVersion: v1
kind: ConfigMap
metadata:
  name: instana-config
data:
  application.properties: |
    instana.token=skDXGZsrQpq8sBI2_G9rpA
    instana.endpoint=instanaa1-xxx.com
...

You can use the following method to add Instana endpoint and API token into the Camel K integration code as system properties:

@PropertyInject("instana.token")
private String iToken;


@PropertyInject(value="instana.endpoint")
private String iEndpoint;

Use Instana backend REST API

Instana has a rich set of APIs to access data and configure changes. For more details, see the official online document at https://instana.github.io/openapi/.
The Instana backend REST API includes the following contents:
  • API for infrastructure monitoring 
  • API for website monitoring
  • API for application monitoring
  • APIs for events
  • API for settings
Here is a curl command to call a simple Instana back-end service of listing all supported plugins of infrastructure monitoring:

curl -ik -H "Authorization: apiToken $TOKEN" "https://$ENDPOINT/api/infrastructure-monitoring/catalog/plugins?pretty"


Typical settings for TOKEN and ENDPOINT environment variables for a public Instana Server:
ENDPOINT=xxxx.instana.io
TOKEN=xxxxxxxx
Typical settings for TOKEN and ENDPOINT environment variables for a self-hosting Instana Server:

ENDPOINT=xxxx.yyyy.com
TOKEN=xxxxxxxx

Sample code of Camel K to call Instana REST API to get settings of Instana Application Perspectives (Note: we are using Java DSL):

from("direct:start").streamCaching()
  .removeHeaders("CamelHttp*")
  .setHeader("Authorization", constant("apiToken " + iToken))
  .setHeader("app-id", constant(appId))
  .setProperty("instana_endpoint", constant(iEndpoint))
  .setBody().constant(null)
  .toD("https://${exchangeProperty[instana_endpoint]}/api/application-monitoring/settings/application/" 
    + "${header.app-id}")
  .log("get-app-settings in: ${body}");​

Note: According to https://instana.github.io/openapi/#section/Backend-REST-API, a rate limit is applied to Instana REST API usage, and a maximum of 5,000 calls per hour can be made. This restriction is for each Instana API token.

More considerations of the Camel K code 


For self-hosting Instana, usually we do not need to verify the certificate and key file returned by the HTTPS request to the Instana server. We just use API tokens. Here is the code:

public static void configureHttpClient(CamelContext context) {
  HttpComponent httpComponent = context.getComponent("https", HttpComponent.class);
  httpComponent.setHttpClientConfigurer(new HttpClientConfigurer() {


  @Override
  public void configureHttpClient(HttpClientBuilder clientBuilder) {
    SSLContext sslContext = null;
    try {
      sslContext = new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() {
      public boolean isTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
        return true;
      }
      }).build();
    } catch (KeyManagementException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    } catch (NoSuchAlgorithmException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    } catch (KeyStoreException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
    clientBuilder.setSSLContext(sslContext);
    final HostnameVerifier hostnameVerifier = getHostnameVerifier();
    SSLConnectionSocketFactory sslSocketFactory = new SSLConnectionSocketFactory(sslContext, hostnameVerifier);
    Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create()
      .register("http", PlainConnectionSocketFactory.getSocketFactory()).register("https", sslSocketFactory).build();
    PoolingHttpClientConnectionManager connMgr = new PoolingHttpClientConnectionManager(socketFactoryRegistry);
    clientBuilder.setConnectionManager(connMgr);
  }
  });
}


public void configure() {
  configureHttpClient(getContext());
  ...
}

In Camel Integration, it is common to retry when there are exceptions which might be caused by temporary network or database failures.  This mechanism is called Redelivery. Following is typical code to set the Redelivery policy to access Instana.

public static void handleErrorAndException(RouteBuilder route, Logger log) {
  route.errorHandler(
    getDefaultErrorHandler(route).useExponentialBackOff().useCollisionAvoidance().onRedelivery(exchange -> log
      .warn("{} - retrying", exchange.getProperty(Exchange.EXCEPTION_CAUGHT, Exception.class).getMessage())));


  route.onException(IOException.class).maximumRedeliveries(10);
}​


With the code, we enable Camel Integration to retry 10 times at maximum when there is IOExeption.
Collision avoidance is enabled to add some randomness to the timings. The exponential backoff is used (i.e. the time between retries increases using a backoff multiplier).
And finally, following is a sample command line to run Camel K Integration with Instana: (Note: we use Camel K version 3.2)

kamel run --name instana-controller \
    --property xxx1=yyy1 \
    --property xxx2=yyy2 \
    --trait knative-service.enabled=false \
    --trait knative-service.min-scale=1 \
    --trait knative.sink-binding=false \
    --configmap instana-config \
    -d camel-quarkus-http \
    -d camel-quarkus-kafka \
    -d camel-quarkus-avro \
    -d mvn:org.apache.camel.k:camel-knative-api:1.4.1 \
    -d mvn:io.apicurio:apicurio-registry-rest-client:1.3.2.Final \
    xxxx1.java \
    xxxx2.java​

Now it is time for you to create your own first Camel K integration to access Instana. Enjoy it!

#CamelK
#Instana
#Microservices
#APM
#Apache
#Integration
#MicroservicesMonitoring
#Camel
#HowTo

Permalink