Skip to content

Commit

Permalink
Azure Event Hub example-Signed-off-by: Kai Zimmermann <kai.zimmermann…
Browse files Browse the repository at this point in the history
…@microsoft.com>
  • Loading branch information
kaizimmerm committed Mar 25, 2019
1 parent 287dcc2 commit 551dde1
Show file tree
Hide file tree
Showing 6 changed files with 227 additions and 0 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,4 @@ target/
yarn.lock
.env
wifi.ini
.DS_Store
5 changes: 5 additions & 0 deletions azure/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Samples for Microsoft Azure users

Samples to leverage an Eclipse Ditto compatible service with Microsoft Azure services.

- Eclipse Ditto event and message consumption with Azure Event Hubs: [azure-eventhub-consumer](azure-eventhub-consumer/).
93 changes: 93 additions & 0 deletions azure/azure-eventhub-consumer/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
# Sample: Eclipse Ditto event and message consumption with Azure Event Hubs

This sample demonstrates consuming Eclipse Ditto events and messages with a Spring Boot app and Spring Cloud Stream Kafka integration.

## Prerequisites

- Running Ditto instance (e.g. locally or on an Azure Kubernetes Service (AKS))
- Azure subscription.
- [Azure CLI](https://docs.microsoft.com/en-us/cli/azure/install-azure-cli) to setup Azure Event Hubs.
- OpenJDK 11 and Maven 3 to build and run the sample.

## Howto run the sample

### SetUp Azure Events Hubs

First create a Azure resource group if you have not done so yet.

```bash
export resourceGroupName=myresourcegroup
az group create --name $resourceGroupName --location westeurope
```

Now create your [Azure Event Hub's](https://docs.microsoft.com/en-us/azure/event-hubs/event-hubs-about) namespace and Hub.

Note: this sample leverages Azure Event Hub's Kafka support as an option for consuming Ditto thing updates.

```bash
export namespace=mydittonamespace
export eventHubName=ditto
export consumerGroup=dittocg

az eventhubs namespace create --name $namespace --resource-group $resourceGroupName --enable-kafka

az eventhubs eventhub create --name $eventHubName --resource-group $resourceGroupName --namespace-name $namespace --message-retention 1 --partition-count 2

az eventhubs eventhub consumer-group create --eventhub-name $eventHubName --resource-group $resourceGroupName --namespace-name $namespace --name $consumerGroup
```

Now we can create users for Ditto with `Send` permission and for the sample app to `Listen`.

```bash
export ditto_user_sas_key_name=dittouser
export sample_app_user_sas_key_name=samplereader

az eventhubs eventhub authorization-rule create --resource-group $resourceGroupName --namespace-name $namespace --eventhub-name $eventHubName --name $ditto_user_sas_key_name --rights Send
az eventhubs eventhub authorization-rule create --resource-group $resourceGroupName --namespace-name $namespace --eventhub-name $eventHubName --name $sample_app_user_sas_key_name --rights Listen
```

Now the CLI again to retrieve the key necessary in the REST call to Ditto below:

```bash
az eventhubs eventhub authorization-rule keys list --resource-group $resourceGroupName --namespace-name $namespace --eventhub-name $eventHubName --name $ditto_user_sas_key_name --query primaryKey
```

No register the connection to the Event Hub in your Ditto instance. Follow Ditto's [Manage Connection documentation](https://www.eclipse.org/ditto/connectivity-manage-connections.html).

A payload could look like this:

```json
{
"targetActorSelection": "/system/sharding/connection",
"headers": {},
"piggybackCommand": {
"type": "connectivity.commands:createConnection",
"connection": {
"id": "azure-example-connection",
"connectionType": "amqp-10",
"connectionStatus": "open",
"failoverEnabled": false,
"uri": "amqps://YOUR_SAS_KEY_NAME:YOUR_SAS_KEY@YOUR_NAMESPACE_NAME.servicebus.windows.net:5671",
"targets": [
{
"address": "YOUR_HUB_NAME",
"topics": ["_/_/things/twin/events", "_/_/things/live/messages"],
"authorizationContext": ["ditto"]
}
]
}
}
}
```

Now it is time to compile and run our sample:

```bash
mvn clean install

export sample_app_user_sas_key=`az eventhubs eventhub authorization-rule keys list --resource-group $resourceGroupName --namespace-name $namespace --eventhub-name $eventHubName --name $sample_app_user_sas_key_name --query primaryConnectionString --output tsv`

java -jar target/azure-eventhub-consumer-0.0.1-SNAPSHOT.jar --azure.event-hubs.namespace=$namespace --azure.event-hubs.connection-string=$sample_app_user_sas_key --azure.event-hubs.hubname=$eventHubName --azure.event-hubs.consumer-group=$consumerGroup
```

Now you should see on the console events comming in as you change data in Ditto, e.g. as described in the [Ditto hello world](https://www.eclipse.org/ditto/intro-hello-world.html).
67 changes: 67 additions & 0 deletions azure/azure-eventhub-consumer/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.3.RELEASE</version>
</parent>
<groupId>org.eclipse.ditto.examples.azure</groupId>
<artifactId>azure-eventhub-consumer</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>azure-eventhub-consumer</name>
<description>Example application that consumes Events from Eclipse Ditto by Azure Event Hub.</description>

<properties>
<java.version>11</java.version>
<spring-cloud.version>Greenwich.RELEASE</spring-cloud.version>
<ditto.version>0.8.0</ditto.version>
</properties>

<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-stream</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-stream-kafka</artifactId>
</dependency>

<dependency>
<groupId>org.eclipse.ditto</groupId>
<artifactId>ditto-protocol-adapter</artifactId>
</dependency>
</dependencies>

<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.eclipse.ditto</groupId>
<artifactId>ditto-bom</artifactId>
<version>${ditto.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>

<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>

</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/*
* Copyright (c) 2019 Microsoft
*
* All rights reserved. This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v2.0 which accompanies this distribution, and is available at
* https://www.eclipse.org/org/documents/epl-2.0/index.php
*
* SPDX-License-Identifier: EPL-2.0
*/
package org.eclipse.ditto.examples.azure;

import org.eclipse.ditto.json.JsonFactory;
import org.eclipse.ditto.json.JsonValue;
import org.eclipse.ditto.protocoladapter.Adaptable;
import org.eclipse.ditto.protocoladapter.DittoProtocolAdapter;
import org.eclipse.ditto.protocoladapter.ProtocolFactory;
import org.eclipse.ditto.signals.base.Signal;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.stream.annotation.EnableBinding;
import org.springframework.cloud.stream.annotation.StreamListener;
import org.springframework.cloud.stream.messaging.Sink;

@SpringBootApplication
@EnableBinding(Sink.class)
public class DittoAzureEventHubExampleApplication {

private static final DittoProtocolAdapter DITTO_PROTOCOL_ADAPTER =
DittoProtocolAdapter.newInstance();

public static void main(final String[] args) {
SpringApplication.run(DittoAzureEventHubExampleApplication.class, args);
}

@StreamListener(Sink.INPUT)
void getEvent(final String event) {

final JsonValue jsonValue = JsonFactory.readFrom(event.substring(8));
final Adaptable adaptable = ProtocolFactory.jsonifiableAdaptableFromJson(jsonValue.asObject());

final Signal<?> actual = DITTO_PROTOCOL_ADAPTER.fromAdaptable(adaptable);

System.out.println("Got signal from Ditto: " + actual);

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# To be provided by user.
azure.event-hubs.connection-string=
azure.event-hubs.namespace=
azure.event-hubs.hubname=
azure.event-hubs.consumer-group=

# Mapping to Spring Cloud Stream properties
azure.event-hubs.service-host=${azure.event-hubs.namespace}.servicebus.windows.net
azure.event-hubs.service-port=9093
spring.cloud.stream.kafka.binder.brokers=${azure.event-hubs.service-host}:${azure.event-hubs.service-port}
spring.cloud.stream.kafka.binder.configuration.sasl.jaas.config=org.apache.kafka.common.security.plain.PlainLoginModule required username="$ConnectionString" password="${azure.event-hubs.connection-string}";
spring.cloud.stream.kafka.binder.configuration.sasl.mechanism=PLAIN
spring.cloud.stream.kafka.binder.configuration.security.protocol=SASL_SSL
spring.cloud.stream.bindings.input.destination=${azure.event-hubs.hubname}
spring.cloud.stream.bindings.input.group=${azure.event-hubs.consumer-group}

0 comments on commit 551dde1

Please sign in to comment.