Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding IBMMQ Discovery Agent #148

Open
wants to merge 15 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -548,6 +548,7 @@ The Event Management Agent comes with the following event or message broker plug
* Solace PubSub+
* Confluent Schema Registry
* MSK
* IBM MQ

The default application.yml provides various plugin examples. For Kafka, the properties section under credentials is passthrough. For example a property in ConsumerConfig or SSLConfigs classes.

Expand Down
5 changes: 5 additions & 0 deletions service/application/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,11 @@
<artifactId>terraform-plugin</artifactId>
<version>1.6.6-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.solace.maas.plugin.ibmmq</groupId>
<artifactId>ibmmq-plugin</artifactId>
<version>1.6.6-SNAPSHOT</version>
</dependency>

<dependency>
<groupId>io.micrometer</groupId>
Expand Down
19 changes: 19 additions & 0 deletions service/application/src/main/resources/application.yml
Original file line number Diff line number Diff line change
Expand Up @@ -355,3 +355,22 @@ eventPortal:
# value: software.amazon.msk.auth.iam.IAMLoginModule required;
# - name: sasl.client.callback.handler.class
# value: software.amazon.msk.auth.iam.IAMClientCallbackHandler
# # IBM MQ Example
# - id: ibmmqDefaultService
# type: IBMMQ
# name: IBM MQ Test Service
# connections:
# - name: IBMMQBroker
## Example: https://[domain:[port]]/ibmmq/rest/v1/admin/qmgr/{qmgrName}
# url: ${IBM_MQ_REST_API_URL}
# authentication:
# - protocol: BASIC
# credentials:
# - source: ENVIRONMENT_VARIABLE
# operations:
# - name: IBMMQ_ALL
# properties:
# - name: username
# value: ${IBMMQ_ADMINISTRATOR_USERNAME}
# - name: password
# value: ${IBMMQ_ADMINISTRATOR_PASSWORD}
94 changes: 94 additions & 0 deletions service/ibmmq-plugin/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
<?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>
<groupId>com.solace.maas.plugin.ibmmq</groupId>
<artifactId>ibmmq-plugin</artifactId>
<version>1.6.6-SNAPSHOT</version>
<name>Solace Event Management Agent - IBM MQ Plugin</name>
<description>Solace Event Management Agent - IBM MQ Plugin</description>

<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<solace.maas.ema.version>1.6.6-SNAPSHOT</solace.maas.ema.version>
<spring.boot.version>3.1.11</spring.boot.version>
<!--
<spring.cloud.openfeign.version>4.0.6</spring.cloud.openfeign.version>
<openfeign.jackson.version>13.0</openfeign.jackson.version>
-->
Copy link
Collaborator

Choose a reason for hiding this comment

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

If the commented out code is deadcode, please remove them.

<okhttp.version>4.0.1</okhttp.version>
<camel.version>4.2.0</camel.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>

<dependencies>
<!-- <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<version>${spring.boot.version}</version>
</dependency>-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
<version>${spring.boot.version}</version>
<exclusions>
<exclusion>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- <dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
<version>${spring.cloud.openfeign.version}</version>
</dependency>
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-jackson</artifactId>
<version>${openfeign.jackson.version}</version>
</dependency>-->
<dependency>
<groupId>com.solace.maas</groupId>
<artifactId>plugin</artifactId>
<version>${solace.maas.ema.version}</version>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-jackson</artifactId>
<version>${camel.version}</version>
</dependency>

<!-- TESTING -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<version>${spring.boot.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>${okhttp.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>mockwebserver</artifactId>
<version>${okhttp.version}</version>
<scope>test</scope>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${spring.boot.version}</version>
</plugin>
</plugins>
</build>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.solace.maas.ep.event.management.agent.plugin.ibmmq;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class IbmMqApplication {

public static void main(String[] args) {
SpringApplication.run(IbmMqApplication.class, args);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.solace.maas.ep.event.management.agent.plugin.ibmmq.client.http;

import org.springframework.web.service.annotation.GetExchange;
import org.springframework.web.service.annotation.HttpExchange;

/**
* Interface for Spring HTTPInterface to create the IBM MQ Admin Client.
*/
@HttpExchange
public interface IbmMqHttpClient {

/*Gets all queues on a given queue manager*/
@GetExchange("/queue")
IbmMqQueueResponse getQueues();

/*Gets all subscriptions (topics) on a given queue manager*/
@GetExchange("/subscription")
IbmMqSubscriptionResponse getSubscriptions();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.solace.maas.ep.event.management.agent.plugin.ibmmq.client.http;

import com.solace.maas.ep.event.management.agent.plugin.ibmmq.processor.event.IbmMqQueueEvent;
import lombok.Getter;

import java.util.List;

/**
* Represents the response JSON from the IBM MQ Admin client
* when querying for Queue information.
*/
@Getter
public class IbmMqQueueResponse {

private List<IbmMqQueueEvent> queue;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.solace.maas.ep.event.management.agent.plugin.ibmmq.client.http;

import com.solace.maas.ep.event.management.agent.plugin.ibmmq.processor.event.IbmMqSubscriptionEvent;
import lombok.Data;

import java.util.List;

/**
* Represents the response JSON from the IBM MQ Admin client
* when querying for Subscription (topic) information.
*/
@Data
public class IbmMqSubscriptionResponse {

List<IbmMqSubscriptionEvent> subscription;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.solace.maas.ep.event.management.agent.plugin.ibmmq.manager.client;

import com.solace.maas.ep.event.management.agent.plugin.manager.client.MessagingServiceClientConfig;
import org.springframework.context.annotation.Configuration;

@Configuration
public class IbmMqClientConfigImpl extends MessagingServiceClientConfig {

protected IbmMqClientConfigImpl() {
super("IBMMQ", new IbmMqClientManagerImpl());
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package com.solace.maas.ep.event.management.agent.plugin.ibmmq.manager.client;

import com.solace.maas.ep.event.management.agent.plugin.ibmmq.client.http.IbmMqHttpClient;
import com.solace.maas.ep.event.management.agent.plugin.manager.client.MessagingServiceClientManager;
import com.solace.maas.ep.event.management.agent.plugin.messagingService.event.AuthenticationDetailsEvent;
import com.solace.maas.ep.event.management.agent.plugin.messagingService.event.ConnectionDetailsEvent;
import com.solace.maas.ep.event.management.agent.plugin.util.MessagingServiceConfigurationUtil;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.reactive.function.client.ExchangeFilterFunctions;
import org.springframework.web.reactive.function.client.WebClient;
import org.springframework.web.reactive.function.client.support.WebClientAdapter;
import org.springframework.web.service.invoker.HttpServiceProxyFactory;

import java.util.NoSuchElementException;

/**
* Implementation of the IBM MQ Administration client.
* <p>
* This client provides access to the various administrative endpoints exposed by IBM MQ.
*/
@Slf4j
@Data
@Component
public class IbmMqClientManagerImpl implements MessagingServiceClientManager<IbmMqHttpClient> {

public IbmMqClientManagerImpl() {
}

@Override
public IbmMqHttpClient getClient(ConnectionDetailsEvent connectionDetailsEvent) {

log.trace("Creating IBM MQ RESTful client for event broker [{}].",
connectionDetailsEvent.getMessagingServiceId());

//get authentication details from config file
AuthenticationDetailsEvent authenticationDetailsEvent = connectionDetailsEvent.getAuthenticationDetails()
.stream()
.findFirst().orElseThrow(() -> {
String message = String.format("Could not find authentication details for service with id [%s].",
connectionDetailsEvent.getMessagingServiceId());
log.error(message);
return new NoSuchElementException(message);
});

//grab authentication details
String username = MessagingServiceConfigurationUtil.getUsername(authenticationDetailsEvent);
String password = MessagingServiceConfigurationUtil.getPassword(authenticationDetailsEvent);
String url = connectionDetailsEvent.getUrl();

//setup a basic webclient that will be used in generating
//the actual IBM HTTP Client
WebClient client = WebClient.builder()
.filter(ExchangeFilterFunctions.basicAuthentication(username, password))
.baseUrl(url)
.build();

HttpServiceProxyFactory proxyFactory = HttpServiceProxyFactory
.builder(WebClientAdapter.forClient(client)).build();

return proxyFactory.createClient(IbmMqHttpClient.class);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package com.solace.maas.ep.event.management.agent.plugin.ibmmq.processor;

import com.solace.maas.ep.event.management.agent.plugin.constants.RouteConstants;
import com.solace.maas.ep.event.management.agent.plugin.ibmmq.client.http.IbmMqHttpClient;
import com.solace.maas.ep.event.management.agent.plugin.ibmmq.client.http.IbmMqQueueResponse;
import com.solace.maas.ep.event.management.agent.plugin.ibmmq.processor.event.IbmMqQueueEvent;
import com.solace.maas.ep.event.management.agent.plugin.processor.base.ResultProcessorImpl;
import com.solace.maas.ep.event.management.agent.plugin.service.MessagingServiceDelegateService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Map;

@Slf4j
@Component
public class IbmMqQueueProcessor extends ResultProcessorImpl<List<IbmMqQueueEvent>, Void> {
private final MessagingServiceDelegateService messagingServiceDelegateService;

@Autowired
public IbmMqQueueProcessor(MessagingServiceDelegateService messagingServiceDelegateService) {
super();
this.messagingServiceDelegateService = messagingServiceDelegateService;
}

@Override
public List<IbmMqQueueEvent> handleEvent(Map<String, Object> properties, Void body) throws Exception {
String messagingServiceId = (String) properties.get(RouteConstants.MESSAGING_SERVICE_ID);

IbmMqHttpClient client = messagingServiceDelegateService.getMessagingServiceClient(messagingServiceId);

log.info("### Invoking Queue endpoint for broker with ID {}", messagingServiceId);
IbmMqQueueResponse queueList = client.getQueues();

return queueList.getQueue();
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package com.solace.maas.ep.event.management.agent.plugin.ibmmq.processor;

import com.solace.maas.ep.event.management.agent.plugin.constants.RouteConstants;
import com.solace.maas.ep.event.management.agent.plugin.ibmmq.client.http.IbmMqHttpClient;
import com.solace.maas.ep.event.management.agent.plugin.ibmmq.client.http.IbmMqSubscriptionResponse;
import com.solace.maas.ep.event.management.agent.plugin.ibmmq.processor.event.IbmMqSubscriptionEvent;
import com.solace.maas.ep.event.management.agent.plugin.processor.base.ResultProcessorImpl;
import com.solace.maas.ep.event.management.agent.plugin.service.MessagingServiceDelegateService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Map;

@Slf4j
@Component
public class IbmMqSubscriptionProcessor extends ResultProcessorImpl<List<IbmMqSubscriptionEvent>, Void> {
private final MessagingServiceDelegateService messagingServiceDelegateService;

@Autowired
public IbmMqSubscriptionProcessor(MessagingServiceDelegateService messagingServiceDelegateService) {
super();
this.messagingServiceDelegateService = messagingServiceDelegateService;
}

@Override
public List<IbmMqSubscriptionEvent> handleEvent(Map<String, Object> properties, Void body) throws Exception {
String messagingServiceId = (String) properties.get(RouteConstants.MESSAGING_SERVICE_ID);

IbmMqHttpClient client = messagingServiceDelegateService.getMessagingServiceClient(messagingServiceId);

log.info("### Invoking Queue endpoint for broker with ID {}", messagingServiceId);
IbmMqSubscriptionResponse subscriptionList = client.getSubscriptions();

return subscriptionList.getSubscription();
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package com.solace.maas.ep.event.management.agent.plugin.ibmmq.processor.event;

import lombok.Getter;

import java.io.Serializable;

/**
* Attributes parsed from the response JSON.
* Note: Other attributes may be returned in the raw JSON.
*/
@Getter
public class IbmMqQueueEvent implements Serializable {

private static final long serialVersionUID = 7693606299215131178L;

private String name;
private String type;
}
Loading