Skip to content
101 changes: 41 additions & 60 deletions apps/generator/docs/generator-template-java.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,8 @@ Add the following code snippet to your package.json file:
"version": "0.0.1",
"description": "A template that generates a Java MQTT client using MQTT.",
"generator": {
"apiVersion": "v1",
"generator": ">=1.10.0 <2.0.0",
"apiVersion": "v2",
"generator": ">=2.0.0 <3.0.0",
"supportedProtocols": ["mqtt"]
},
"dependencies": {
Expand Down Expand Up @@ -204,7 +204,7 @@ public class TestClient {
int idLength = 8;
int minValue = (int) Math.pow(10, idLength - 1); // Minimum 8-digit number (e.g., 10000000)
int maxValue = (int) Math.pow(10, idLength) - 1; // Maximum 8-digit number (e.g., 99999999)
System.out.println("Validating generated generated Client.java");
System.out.println("Validating generated Client.java");
System.out.println("Running tests in TestClient.java");
System.out.println("Sending temperature changes to the broker...");
System.err.println("\n");
Expand Down Expand Up @@ -286,8 +286,8 @@ In **package.json** define a script property that you invoke by calling `npm run
"version": "0.0.1",
"description": "A template that generates a Java MQTT client using MQTT.",
"generator": {
"apiVersion": "v1",
"generator": ">=1.10.0 <2.0.0",
"apiVersion": "v2",
"generator": ">=2.0.0 <3.0.0",
"supportedProtocols": ["mqtt"],
"parameters": {
"server": {
Expand Down Expand Up @@ -315,17 +315,17 @@ Run `npm test` to see if everything is working.

#### 5a. Creating more reusable components

Similar to the previous `TopicFunction` function we will create a function to make reusable components regardless of the number of channels in the asyncAPI document.
Similar to the previous `TopicFunction` function we will create a function to make reusable components regardless of the number of channels in the asyncAPI v3 document.

Create a **components** directory at the root of your project and create a file named `TopicFunction.js` and add the code snippet below:

```js
/*
* This component returns a block of functions that users can use to send messages to specific topics.
* As input it requires a list of Channel models from the parsed AsyncAPI document.
* As input it requires operations from the parsed AsyncAPI v3 document.
*/
export function TopicFunction({ channels }) {
const topicsDetails = getTopics(channels);
export function TopicFunction({ operations }) {
const topicsDetails = getTopicsFromOperations(operations);
let functions = '';

topicsDetails.forEach((t) => {
Expand All @@ -346,21 +346,21 @@ export function TopicFunction({ channels }) {
}

/*
* This function returns a list of objects, one for each channel, each containing two properties: `name` and `topic`.
* name - holds information about the `operationId` definedin the AsyncAPI document
* This function returns a list of objects, one for each receive operation.
* name - holds information about the `operationId` defined in the AsyncAPI document
* topic - holds information about the topic's address.
*
* It requires as input, a list of Channel models from the parsed AsyncAPI document.
* It requires operations from the parsed AsyncAPI v3 document.
*/
function getTopics(channels) {
const channelsCanSendTo = channels
function getTopicsFromOperations(operations) {
const receiveOperations = operations.filterBySend();
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

operations if you look into line 381 are already filtered correct by receive, so not filter by send again makes no sense, will always be empty, no?

let topicsDetails = []
Comment thread
coderabbitai[bot] marked this conversation as resolved.

channelsCanSendTo.forEach((ch) => {
receiveOperations.forEach((op) => {
const topic = {}
const operationId = ch.operations().filterByReceive()[0].id()
const operationId = op.id()
topic.name = operationId.charAt(0).toUpperCase() + operationId.slice(1)
topic.topic = ch.address()
topic.topic = op.channel().address()

topicsDetails.push(topic)
})
Expand All @@ -373,14 +373,15 @@ export function TopicFunction({ channels }) {
Import the `TopicFunction` component in your template code in **index.js** and add the template code to generate the functions for the topics which the `Temperature Service` application is subscribed to. In your case, the final version of your template code should look like this:

```js
import { File, Text } from '@asyncapi/generator-react-sdk';
import { File } from '@asyncapi/generator-react-sdk';
import { TopicFunction } from '../components/TopicFunction'

export default function ({ asyncapi, params }) {
let channels = asyncapi.channels().filterByReceive(); // Get all the channels that receive messages

// v3: Get receive operations instead of channels
const operations = asyncapi.operations();
const server = asyncapi.server(params.server);
// Generate Java code for each topic dynamically using TopicFunction
const topicMethods = TopicFunction({ channels }); // This will return Java methods as text
const topicMethods = TopicFunction({ operations }); // This will return Java methods as text

return (
<File name="Client.java">
Expand All @@ -389,7 +390,7 @@ export default function ({ asyncapi, params }) {
`import org.eclipse.paho.client.mqttv3.*;

public class Client {
private static final String BROKER_URL = "${asyncapi.servers().get(params.server).url()}";
private static final String BROKER_URL = "tcp://${server.host()}";
private static final String TOPIC = "temperature/changed";

private MqttClient client;
Expand Down Expand Up @@ -449,7 +450,7 @@ java-mqtt-client-template
Add the following AsyncAPI document to have more channels:

```yaml
asyncapi: 2.6.0
asyncapi: 3.0.0

info:
title: Temperature Service
Expand All @@ -458,44 +459,24 @@ info:

servers:
dev:
url: tcp://test.mosquitto.org:1883
host: test.mosquitto.org:1883
protocol: mqtt

channels:
temperature/dropped:
description: Notifies the user when the temperature drops past a certain point.
publish:
operationId: temperatureDrop
message:
description: Message that is being sent when the temperature drops past a certain point.
payload:
type: object
additionalProperties: false
properties:
temperatureId:
type: string

temperature/dropped:
address: temperature/dropped
temperature/risen:
description: Notifies the user when the temperature rises past a certain point.
publish:
operationId: temperatureRise
message:
description: Message that is being sent when the temperature rises past a certain point.
payload:
type: object
additionalProperties: false
properties:
temperatureId:
type: string

components:
schemas:
temperatureId:
type: object
additionalProperties: false
properties:
temperatureId:
type: string
address: temperature/risen

operations:
temperatureDrop:
action: receive
channel:
$ref: '#/channels/temperature~1dropped'
temperatureRise:
action: receive
channel:
$ref: '#/channels/temperature~1risen'

```
#### 5c. Update TestClient.java
Expand All @@ -513,7 +494,7 @@ public class TestClient {
int idLength = 8;
int minValue = (int) Math.pow(10, idLength - 1); // Minimum 8-digit number (e.g., 10000000)
int maxValue = (int) Math.pow(10, idLength) - 1; // Maximum 8-digit number (e.g., 99999999)
System.out.println("Validating generated generated Client.java");
System.out.println("Validating generated Client.java");
System.out.println("Running tests in TestClient.java");
System.out.println("Sending temperature changes to the broker...");
System.err.println("\n");
Expand All @@ -540,7 +521,7 @@ Run `npm test` to validate that everything works as expected. You should see log
```cmd
Connected to MQTT broker: tcp://test.mosquitto.org:1883

Validating generated generated Client.java
Validating generated Client.java
Running tests in TestClient.java
Sending temperature changes to the broker...
TemperatureDrop change sent: 43289900
Expand All @@ -555,4 +536,4 @@ Great job completing this tutorial! You have learnt how to use an AsyncAPI file

If you want to tinker with a completed template and see what it would look like in production, check out the [Java-MQTT-client-template](https://github.com/ssala034/Java-MQTT-client-template). You can also check out the accompanying [article about creating MQTT client code](https://www.brainfart.dev/blog/asyncapi-codegen-python).

You can also check out the [MQTT beginners guide](https://medium.com/python-point/mqtt-basics-with-python-examples-7c758e605d4) tutorial to learn more about asynchronous messaging using MQTT.
You can also check out the [MQTT beginners guide](https://medium.com/python-point/mqtt-basics-with-python-examples-7c758e605d4) tutorial to learn more about asynchronous messaging using MQTT.
Loading