diff --git a/src/java/rabbitmq-poc/.gitignore b/src/java/rabbitmq-poc/.gitignore new file mode 100644 index 0000000..fc3f89c --- /dev/null +++ b/src/java/rabbitmq-poc/.gitignore @@ -0,0 +1,39 @@ +target/ +!.mvn/wrapper/maven-wrapper.jar +!**/src/main/**/target/ +!**/src/test/**/target/ + +### IntelliJ IDEA ### +.idea +.idea/modules.xml +.idea/jarRepositories.xml +.idea/compiler.xml +.idea/libraries/ +*.iws +*.iml +*.ipr + +### Eclipse ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ +!**/src/main/**/build/ +!**/src/test/**/build/ + +### VS Code ### +.vscode/ + +### Mac OS ### +.DS_Store \ No newline at end of file diff --git a/src/java/rabbitmq-poc/pom.xml b/src/java/rabbitmq-poc/pom.xml new file mode 100644 index 0000000..ef24740 --- /dev/null +++ b/src/java/rabbitmq-poc/pom.xml @@ -0,0 +1,49 @@ + + 4.0.0 + nl.ovpay + rabbitmq + 1.0-SNAPSHOT + OVpay - RabbitMQ POC + + + com.rabbitmq + amqp-client + 5.23.0 + + + + + org.apache.logging.log4j + log4j-api + 2.23.1 + + + org.apache.logging.log4j + log4j-core + 2.23.1 + + + org.apache.logging.log4j + log4j-slf4j-impl + 2.23.1 + + + org.json + json + 20240303 + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + 11 + 11 + + + + + diff --git a/src/java/rabbitmq-poc/src/main/java/nl/ovpay/queue/DummyX509TrustManager.java b/src/java/rabbitmq-poc/src/main/java/nl/ovpay/queue/DummyX509TrustManager.java new file mode 100644 index 0000000..aa92afc --- /dev/null +++ b/src/java/rabbitmq-poc/src/main/java/nl/ovpay/queue/DummyX509TrustManager.java @@ -0,0 +1,40 @@ +package nl.ovpay.queue; + +import java.security.cert.X509Certificate; +import javax.net.ssl.TrustManager; +import javax.net.ssl.X509TrustManager; + +public final class DummyX509TrustManager implements X509TrustManager { + + private static DummyX509TrustManager INSTANCE; + + private DummyX509TrustManager() { + // prevent instantiation + } + + public static DummyX509TrustManager getInstance() { + if (INSTANCE == null) { + INSTANCE = new DummyX509TrustManager(); + } + return INSTANCE; + } + + public static TrustManager[] getDummyArray() { + if (INSTANCE == null) { + INSTANCE = new DummyX509TrustManager(); + } + return new TrustManager[] { INSTANCE }; + } + + public X509Certificate[] getAcceptedIssuers() { + return null; + } + + public void checkClientTrusted(X509Certificate[] certs, String authType) { + } + + public void checkServerTrusted(X509Certificate[] certs, String authType) { + } +} + + diff --git a/src/java/rabbitmq-poc/src/main/java/nl/ovpay/queue/Helpers.java b/src/java/rabbitmq-poc/src/main/java/nl/ovpay/queue/Helpers.java new file mode 100644 index 0000000..fce38e7 --- /dev/null +++ b/src/java/rabbitmq-poc/src/main/java/nl/ovpay/queue/Helpers.java @@ -0,0 +1,90 @@ +package nl.ovpay.queue; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.HttpURLConnection; +import java.net.URL; +import java.net.URLConnection; +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.security.KeyManagementException; +import java.security.NoSuchAlgorithmException; +import java.util.HashMap; +import java.util.Map; +import java.util.StringJoiner; +import javax.net.ssl.HttpsURLConnection; +import javax.net.ssl.SSLContext; + +import org.json.JSONObject; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public final class Helpers { + + private static Logger LOGGER = LoggerFactory.getLogger(Helpers.class); + + public static String getAlertId(String string) throws IOException { + return new JSONObject(string).get("alertId").toString(); + } + + public static String getXbot(String string) throws IOException { + return new JSONObject(string).get("xbot").toString(); + } + + public static void getAlertDetails(String alertId, String xBot, String gboBearerToken) throws Exception { + SSLContext sc = SSLContext.getInstance("SSL"); + sc.init(null, DummyX509TrustManager.getDummyArray(), new java.security.SecureRandom()); + HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory()); + + + URL url = new URL("https://api.sbx.idbt.translink.nl/api/v3/id-media/tokens/xbot/" + xBot + "/alerts/" + alertId + "/details"); + URLConnection con = url.openConnection(); + HttpURLConnection http = (HttpURLConnection)con; + http.setRequestMethod("GET"); + http.setDoOutput(true); + http.setRequestProperty("Authorization", "Bearer " + gboBearerToken); + http.connect(); + + try(InputStream is = http.getInputStream()) { + String response = new String(is.readAllBytes(), StandardCharsets.UTF_8); + LOGGER.info("GBO API 8851 alert details response for xBOT " + xBot + ": \n" + new JSONObject(response).toString(2)); + } + } + + public static String getGboBearerToken() throws IOException, NoSuchAlgorithmException, KeyManagementException { + SSLContext sc = SSLContext.getInstance("SSL"); + sc.init(null, DummyX509TrustManager.getDummyArray(), new java.security.SecureRandom()); + HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory()); + + URL url = new URL("https://api.sbx.idbt.translink.nl/api/v3/auth/oauth2/token"); + URLConnection con = url.openConnection(); + HttpURLConnection http = (HttpURLConnection)con; + http.setRequestMethod("POST"); + http.setDoOutput(true); + + Map arguments = new HashMap<>(); + arguments.put("client_id", "HTM-auth-client"); + arguments.put("client_secret", "HTM-auth-827kJJ"); + arguments.put("grant_type", "client_credentials"); + StringJoiner sj = new StringJoiner("&"); + for(Map.Entry entry : arguments.entrySet()) + sj.add(URLEncoder.encode(entry.getKey(), "UTF-8") + "=" + + URLEncoder.encode(entry.getValue(), "UTF-8")); + byte[] out = sj.toString().getBytes(StandardCharsets.UTF_8); + int length = out.length; + + http.setFixedLengthStreamingMode(length); + http.setRequestProperty("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8"); + http.connect(); + try(OutputStream os = http.getOutputStream()) { + os.write(out); + } + try(InputStream is = http.getInputStream()) { + String response = new String(is.readAllBytes(), StandardCharsets.UTF_8); + JSONObject json = new JSONObject(response); + LOGGER.info("Got GBO bearer token: " + json.get("access_token")); + return json.get("access_token").toString(); + } + } +} diff --git a/src/java/rabbitmq-poc/src/main/java/nl/ovpay/queue/RabbitConnector.java b/src/java/rabbitmq-poc/src/main/java/nl/ovpay/queue/RabbitConnector.java new file mode 100644 index 0000000..a408dc0 --- /dev/null +++ b/src/java/rabbitmq-poc/src/main/java/nl/ovpay/queue/RabbitConnector.java @@ -0,0 +1,68 @@ +package nl.ovpay.queue; + +import java.util.Map; + +import com.rabbitmq.client.AMQP; +import com.rabbitmq.client.Channel; +import com.rabbitmq.client.Connection; +import com.rabbitmq.client.ConnectionFactory; +import com.rabbitmq.client.DeliverCallback; +import com.rabbitmq.client.impl.ForgivingExceptionHandler; +import org.json.JSONObject; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class RabbitConnector { + + private static final Logger LOGGER = LoggerFactory.getLogger(RabbitConnector.class); + + public static void main(String[] args) throws Exception { + ConnectionFactory factory = new ConnectionFactory(); + factory.setVirtualHost("/"); + factory.setAutomaticRecoveryEnabled(true); + factory.setPort(443); + factory.setHost("not.sbx.idbt.translink.nl"); + factory.setUsername("BEID_3_ALERTS_nZs3"); + factory.setPassword("VyubhPnczKgTB2zJ"); + factory.useSslProtocol("TLSv1.2"); + factory.setExceptionHandler(new ForgivingExceptionHandler()); + Map configs = factory.getClientProperties(); + LOGGER.info("Client properties: \n" + new JSONObject(configs).toString(2)); + + Connection connection = factory.newConnection(); + Channel channel = connection.createChannel(); + DeliverCallback deliverCallback = initDeliverCallback(channel); + + AMQP.Queue.DeclareOk queue = channel.queueDeclarePassive("BEID_3.ALERTS"); + LOGGER.info( + "Declared queue: " + queue.getQueue() + ", consumer count: " + queue.getConsumerCount() + ", message count: " + + queue.getMessageCount()); + + // Second parameter controls autoAck - false = no autoAck = messages are only deleted from queue after consumer acknowledges them + channel.basicConsume(queue.getQueue(), false, deliverCallback, consumerTag -> {}); + LOGGER.info("Waiting for messages from the queue. To exit press CTRL+C"); + } + + private static DeliverCallback initDeliverCallback(Channel channel) { + return (consumerTag, delivery) -> { + final String message = new String(delivery.getBody(), "UTF-8"); + LOGGER.info("Received from message from the queue: \n " + new JSONObject(message).toString(2)); + + LOGGER.info("Acknowledging message with delivery tag: " + delivery.getEnvelope().getDeliveryTag()); + channel.basicAck(delivery.getEnvelope().getDeliveryTag(), false); + LOGGER.info("Successfully acknowledged message with delivery tag: " + delivery.getEnvelope().getDeliveryTag()); + + LOGGER.info("Getting alert details via GBO API 8851..."); + try { + String alertId = Helpers.getAlertId(message); + String xBot = Helpers.getXbot(message); + String gboBearerToken = Helpers.getGboBearerToken(); + + Helpers.getAlertDetails(alertId, xBot, gboBearerToken); + + } catch (Exception e) { + throw new RuntimeException(e); + } + }; + } +} diff --git a/src/java/rabbitmq-poc/src/main/resources/log4j2.xml b/src/java/rabbitmq-poc/src/main/resources/log4j2.xml new file mode 100644 index 0000000..47eb2d8 --- /dev/null +++ b/src/java/rabbitmq-poc/src/main/resources/log4j2.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + +