diff --git a/.gitignore b/.gitignore index 34183b6..f1a6bf1 100644 --- a/.gitignore +++ b/.gitignore @@ -7,4 +7,7 @@ ibm-backend-response/jmsapp/com/ibm/mq/samples/jms/JmsPutGet.class ibm-backend-response/jmsapp/jars/*.* aws-backend-request/JMSLambdaFunction/jars/*.* qm-config/*.json -qm-config/cookiejar.txt \ No newline at end of file +qm-config/cookiejar.txt +*.kdb +*.sth +*.pem diff --git a/README.md b/README.md index 10531c6..e7a6806 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,7 @@ An end to end scenario to demonstrate secure, reliable transmissions of data across multiple regions and cloud providers - for example IBM MQ on IBM Cloud in the UK and IBM MQ on AWS in the US ![Image of demo scenario](./assets/scenario_image.png) + ___ ## Contents @@ -32,12 +33,12 @@ This guide will cover the following; Before you start, you will need the following: -- IBM Cloud Account -- AWS account +- IBM Cloud Account - [Register here](https://cloud.ibm.com) +- AWS account - [Register here](https://aws.amazon.com/) Please note the instructions in this guide are purely suggestions of how and where to deploy each component. -For example, you could also deploy the two IBM MQ queue managers to IBM Cloud only if you wished. +For example, you could also deploy the two IBM MQ queue managers to IBM Cloud only if you wished, this is a demonstration of cross-cloud connectivty enhanced with IBM MQ. ## Getting started @@ -67,14 +68,16 @@ Check that the following files exist along with various other dependencies in th ```sh --- -ibm-backend-response/jmsapp/jars/com.ibm.mq.allclient-9.0.4.0.jar +ibm-backend-response/jmsapp/jars/com.ibm.mq.allclient-9.2.0.1.jar ibm-backend-response/jmsapp/jars/javax.jms-api-2.0.1.jar --- +aws-backend-request/JMSLambdaFunction/jars/com.ibm.mq.allclient-9.2.0.1.jar aws-backend-request/JMSLambdaFunction/jars/javax.jms-api-2.0.1.jar -aws-backend-request/JMSLambdaFunction/jars/com.ibm.mq.allclient-9.0.4.0.jar --- ``` +Now you must install the client libraries for IBM MQ. To download the Mac OS MQ Toolkit follow the instructions [here](https://developer.ibm.com/components/ibm-mq/tutorials/mq-macos-dev), for all other operating systems, follow instructions [here](https://developer.ibm.com/components/ibm-mq/articles/mq-downloads/). + Once confirmed you can now continue on with the next step of this guide. ___ @@ -88,9 +91,11 @@ The first part of this guide will cover the following: - Creating application user permissions for connecting apps to both queue managers. - Creating admin user permissions for managing both queue managers. -Follow these [instructions](./qm-config/README.md#configuring-two-ibm-mq-on-cloud-queue-managers) to setup two MQ on Cloud queue managers. +**Follow these [instructions](./qm-config/README.md#configuring-two-ibm-mq-on-cloud-queue-managers) to setup two MQ on Cloud queue managers.** -Once complete, return to this page to continue with the rest of the setup. +**Once complete, return to this page to continue with the rest of the setup.** + +Ok now that the queue managers are configured and connected we can progress on with the setup of the applications. ___ @@ -102,6 +107,44 @@ The first of the two applications will be triggered by a REST api, simulating a ### 2.1 Build Steps +### 2.1.1 Creating the keystore + +1. The queue managers are configured to use TLS to secure the connection between client applications and the channel used for a connection. + +2. Navigate to the following directory; + + ``` + cd mq-cloud-demo/aws-backend-request/JMSLambdaFunction/ + ``` + +3. You should have the `qmgrcert.pem` file in this directory for the AWS queue manager in the queue manager configuration and setup section of this guide. + +4. Run the following command to create a keystore in this directory, this will be used as the keystore for the JMS application running on AWS Lambda. + + *Note: replace the `` text for a suitable password, and make note of this as it is needed for the application setup in AWS later* + + ``` + runmqakm -keydb -create -db key.kdb -pw -type pkcs12 -expire 0 -stash + + # In some operating systems you may have to update the file permissions to make the keystore readable + chmod +rw key.* + + ``` + +5. Now add the queue manager certificate to the keystore. + + ``` + runmqakm -cert -add -db key.kdb -file qmgrcert.pem -label qmgrcert -stashed -type pkcs12 -format ascii + ``` + +6. You can then list the certificates in the keystore to verify it has worked. + + ``` + runmqakm -cert -list -db key.kdb + ``` + +### 2.1.2 Building the application bundle + 1. Build the deployment zip: ```bash @@ -123,49 +166,54 @@ The first of the two applications will be triggered by a REST api, simulating a 4. Name the function JMSLambdaFunction -5. Select `Java 8` from the Runtime dropdown. - -6. Under role, select `Create a custom role`, you will be taken to a new page, leave the values as default and click `Allow`. +5. Depending on which version used to compile choose either `Java 8` or `Java 11` from the Runtime dropdown. -7. Now click `Create function` and wait for the process to complete, you will be redirected to the Lambda Function configuration page. +6. Now click `Create function` and wait for the process to complete, you will be redirected to the Lambda Function configuration page. ### 2.3 Deploy Function code -1. In the `Configuration` tab, select the function `JMSLambdaFunction` from the designer. Scroll down the page to the `Function code` sub-section. +1. In the `Code` tab, select the function `JMSLambdaFunction` from the designer. Scroll down the page to the `Runtime settings` sub-section and click edit. -2. In this section, paste the following into the `Handler` field. +2. In this page, paste the following into the `Handler` field and click save. ```bash com.example.lambda.ibmmq.JMSLambda::handleRequest ``` -3. Click upload, navigate to `mq-cloud-demo/aws-backend-request/JMSLambdaFunction/build/distributions` and select `JMSLambdaFunction.zip`. +3. Now click 'Upload from' and choose 'from .zip or .jar file' and click 'upload'. In the file browser navigate to `mq-cloud-demo/aws-backend-request/JMSLambdaFunction/build/distributions` and select `JMSLambdaFunction.zip`. + +4. Go to the 'Configuration' tab, and click 'General configuration' in the left-hand navigation menu. -4. Now click `Save` at the top right of the page. +5. Click 'Edit' and set the timeout to 1 minute 0 seconds. +6. Click 'Save' ### 2.4 Set Environment variables -For this step, you will require the connection information for the AWS queue manager that you would have downloaded earlier from section 1 of this guide (hint: look for aws.json). +For this step, you will require the connection information for the AWS queue manager that you would have downloaded earlier from section 1 of this guide (hint: look for info-aws.json). -You will also require the application details and api key, which was downloaded in section 1 (hint: look for app.json). +You will also require the application details and api key, which was downloaded in section 1 (hint: look for app-aws.json). -With your function still selected, below the "Function code" section, there is another box entitled "Environment variables". +Navigate to the 'Configuration' section, and then click 'Environment Variables' in the left-hand navigation menu. + +Click 'Edit'. To add a new environment variable click the 'Add environment variable' button, and repeat this for every key value pair shown in the list below. Add the following key / value pairs as environment variables. | Variable Name | Value | | ------------- | ------ | -| APP_PASSWORD | -| APP_USER | -| QMGR_HOST | -| QMGR_PORT | -| QMGR_NAME | +| APP_PASSWORD | *Your aws application api key* +| APP_USER | *Your aws application user name* +| QMGR_HOST | *The hostname for your queue manager* +| QMGR_PORT | *The listener port number for your queue manager* +| QMGR_NAME | QM.AWS +| SSL_KEYSTORE| com/example/lambda/ibmmq/key.kdb +| SSL_KEYSTORE_PASSWORD | *The password set previously for your keystore* | RESPONSE_QUEUE_NAME | STOCK.REPLY | TARGET_QUEUE_NAME | STOCK ___ -#### Screenshot of configured Lambda Function +#### **Example Screenshot of Fully Configured Lambda Function** ![Configured Lambda Function](./assets/lamdba_function.png) @@ -175,19 +223,23 @@ ___ Now we will add an API Gateway which will allow us to invoke the function using a simple HTTP REST call. -1. In the `Configuration` tab, within the `Designer` sub-section, click `API Gateway` from the left hand column. +1. In the `Configuration` tab, within the `Function-overview` sub-section, click `Add trigger`. + +2. On the Add trigger page, select the 'Api Gateway' trigger from the dropdown. -2. Once added, under `Configure triggers`, from the API dropdown select `Create a new API`. +3. In the next dropdown, select 'Create an API'. -3. Under `Security` choose Open. +4. Select 'REST API' -4. Click `Add`, and then click `Save` in the top right hand corner of the page. +5. Under Security selct 'Open' in the dropdown. -5. This will create a new API Gateway named `JMSLambdaFunction-API` +6. Click `Add`. + +7. This will create a new API Gateway named `JMSLambdaFunction-API` - You will now see an API endpoint has been generated, take note of this as we will need it later. -6. Click the name for the API Gateway to access its dashboard to configure it. +8. Click the link for the API Gateway to access its dashboard to configure it. ### 2.6 Configure API Gateway @@ -199,13 +251,13 @@ Now we must configure and deploy the API we have just created. 3. In the dropdown presented on screen, select `POST` and click the checkmark button. -4. In the setup view, choose your function from the Lambda Function field, leave everything else as default, and click 'Save'. +4. In the setup view, start to type 'JMS' in Lambda Function field, you should see the 'JMSLambdaFunction' appear, select that and leave everything else on this page as default, and click 'Save'. 5. Click 'Actions' and select 'Enable CORS'. This is nescessary to allow testing from locally hosted applications for example. 6. In the 'Enable CORS' page, leave defaults and click `Enable CORS and replace existing CORS headers`, when prompted click `Yes, replace existing values`. -7. Click 'Actions' and select 'Deploy API'. Select `default` for 'Deployment stage', add an option description and click `Deploy`. +7. Click 'Actions' and select 'Deploy API'. Select `default` for 'Deployment stage', optionally add a description and click `Deploy`. The Lambda function is now ready to be invoked over REST, now let's configure the backend responder that will return the stock count. ___ @@ -213,13 +265,51 @@ ___ #### Screenshot of fully configured API Gateway ![Configured API Gateway](./assets/api-gateway.png) + ___ ## Setting up the stock check backend JMS application This next section will cover setting up a local JMS application which will act as the backend service (see diagram at top of page) that will return the stock count for a particular product. -### 3.1 Set the environment variables +### 3.1 Setup keystore for local JMS application + +1. Our queue managers are configured to use TLS to secure the connection between client applications and the channel used for a connection. + +2. Navigate to the following directory; + + ``` + cd ibm-backend-response/jmsapp + ``` + +3. You should have the `qmgrcert.pem` file in this directory for the AWS queue manager in the queue manager configuration and setup section of this guide. + +4. Run the following command to create a keystore in this directory, this will be used as the keystore for the JMS application running on AWS Lambda. + + *Note: replace the `` text for a suitable password, and make note of this as it is needed for the application setup in AWS later* + + ``` + runmqakm -keydb -create -db key.kdb -pw -type pkcs12 -expire 0 -stash + + # In some operating systems you may have to update the file permissions to make the keystore readable + chmod +rw key.* + + ``` + +5. Now add the queue manager certificate to the keystore. + + ``` + runmqakm -cert -add -db key.kdb -file qmgrcert.pem -label qmgrcert -stashed -type pkcs12 -format ascii + ``` + +6. You can then list the certificates in the keystore to verify it has worked. + + ``` + runmqakm -cert -list -db key.kdb + ``` + + +### 3.2 Set the environment variables First, change the values in the `.env` file found in the following directory - `mq-cloud-demo/ibm-backend-request/jmsapp` @@ -231,6 +321,8 @@ export QMGR_HOST= export QMGR_PORT= export APP_USER= export APP_PASSWORD= +export SSL_KEYSTORE= +export SSL_KEYSTORE_PASSWORD= ``` Now source the `.env` file by running the following command: @@ -240,7 +332,7 @@ cd mq-cloud-demo/ibm-backend-response/jmsapp source .env ``` -### 3.2 Compile the JMS application +### 3.3 Compile the JMS application Open your terminal / command prompt, and navigate to the JMS application directory. @@ -251,17 +343,17 @@ cd mq-cloud-demo/ibm-backend-request/jmsapp Compile the JMS application with the following command: ``` bash -javac -cp ./jars/com.ibm.mq.allclient-9.0.4.0.jar:./jars/javax.jms-api-2.0.1.jar:. com/ibm/mq/samples/jms/JmsPutGet.java +javac -cp ./jars/com.ibm.mq.allclient-9.2.0.1.jar:./jars/javax.jms-api-2.0.1.jar:. com/ibm/mq/samples/jms/JmsPutGet.java ``` This will compile the java application and point it at your queue manager -### 3.3 Run the JMS application +### 3.4 Run the JMS application Insert the connection information for your IBM Cloud queue manager in the spaces shown below and execute the following command to run the newly compiled JMS application: ``` bash -java -cp ./jars/com.ibm.mq.allclient-9.0.4.0.jar:./jars/javax.jms-api-2.0.1.jar:. com.ibm.mq.samples.jms.JmsPutGet +java -cp ./jars/com.ibm.mq.allclient-9.2.0.1.jar:./jars/javax.jms-api-2.0.1.jar:. com.ibm.mq.samples.jms.JmsPutGet ``` The JMS application is now listening for connections on the STOCK message queue. @@ -305,4 +397,4 @@ must include a statement stating you accept the terms in the CLA. ## Copyright -© Copyright IBM Corporation 2018 \ No newline at end of file +© Copyright IBM Corporation 2018, 2021 \ No newline at end of file diff --git a/assets/aws_running.png b/assets/aws_running.png index f7b2203..ec86f4b 100644 Binary files a/assets/aws_running.png and b/assets/aws_running.png differ diff --git a/assets/ibm_running.png b/assets/ibm_running.png index 71c3681..5c61bfa 100644 Binary files a/assets/ibm_running.png and b/assets/ibm_running.png differ diff --git a/assets/lamdba_function.png b/assets/lamdba_function.png index f1ea891..bdb5701 100644 Binary files a/assets/lamdba_function.png and b/assets/lamdba_function.png differ diff --git a/assets/scenario_image.png b/assets/scenario_image.png index 1c04e4f..8c42209 100644 Binary files a/assets/scenario_image.png and b/assets/scenario_image.png differ diff --git a/aws-backend-request/JMSLambdaFunction/build.gradle b/aws-backend-request/JMSLambdaFunction/build.gradle index 2012d32..982b156 100644 --- a/aws-backend-request/JMSLambdaFunction/build.gradle +++ b/aws-backend-request/JMSLambdaFunction/build.gradle @@ -1,5 +1,5 @@ /** -* © Copyright IBM Corporation 2018 +* © Copyright IBM Corporation 2018, 2021 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,7 +23,7 @@ repositories { dependencies { compile group: 'com.amazonaws', name: 'aws-lambda-java-core', version: '1.1.0' compile group: 'com.amazonaws', name: 'aws-lambda-java-events', version: '1.1.0' - compile group: 'com.ibm.mq', name: 'com.ibm.mq.allclient', version: '9.0.4.0' + compile group: 'com.ibm.mq', name: 'com.ibm.mq.allclient', version: '9.2.0.1' compile group: 'javax.jms', name: 'javax.jms-api', version: '2.0.1' compile fileTree(dir: 'jars', include: '*.jar') @@ -36,7 +36,10 @@ task getDeps(type: Copy) { task buildZip(type: Zip) { from compileJava - from processResources + from processResources + into('com/example/lambda/ibmmq'){ + from file("./key.kdb") + } into('lib') { from configurations.compileClasspath } diff --git a/aws-backend-request/JMSLambdaFunction/src/main/java/com/example/lambda/ibmmq/JMSLambda.java b/aws-backend-request/JMSLambdaFunction/src/main/java/com/example/lambda/ibmmq/JMSLambda.java index 226197b..f923042 100644 --- a/aws-backend-request/JMSLambdaFunction/src/main/java/com/example/lambda/ibmmq/JMSLambda.java +++ b/aws-backend-request/JMSLambdaFunction/src/main/java/com/example/lambda/ibmmq/JMSLambda.java @@ -1,5 +1,5 @@ /** -* © Copyright IBM Corporation 2018 +* © Copyright IBM Corporation 2018, 2021 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -43,33 +43,41 @@ public class JMSLambda implements RequestHandler,String> { private static final String APP_PASSWORD = System.getenv("APP_PASSWORD"); //Password that the application uses to connect to MQ private static final String TARGET_QUEUE_NAME = System.getenv("TARGET_QUEUE_NAME"); // Queue that the application uses to put and get messages to and from private static final String RESPONSE_QUEUE_NAME = System.getenv("RESPONSE_QUEUE_NAME"); // Queue that the application uses to put and get messages to and from - - @Override - public String handleRequest(Map input, Context context) { - //context.getLogger().log("Input: " + input); - - JMSContext jmscontext = null; - Destination destination = null; - Destination source = null; - JMSProducer producer = null; - JMSConsumer consumer = null; - - try { + private static final String SSL_KEYSTORE = System.getenv("SSL_KEYSTORE"); // Keystore which holds the public certificate of the queue manager + private static final String SSL_KEYSTORE_PASSWORD = System.getenv("SSL_KEYSTORE_PASSWORD") ; // Password for the SSL Keystore + private static final String CIPHER_SPEC = "ANY_TLS12_OR_HIGHER"; // Cipher specification + + @Override + public String handleRequest(Map input, Context context) { + //context.getLogger().log("Input: " + input) + + JMSContext jmscontext = null; + Destination destination = null; + Destination source = null; + JMSProducer producer = null; + JMSConsumer consumer = null; + + try { // Create a connection factory JmsFactoryFactory ff = JmsFactoryFactory.getInstance(WMQConstants.WMQ_PROVIDER); JmsConnectionFactory cf = ff.createConnectionFactory(); + System.setProperty("javax.net.ssl.keyStore", SSL_KEYSTORE); + System.setProperty("javax.net.ssl.keyStorePassword", SSL_KEYSTORE_PASSWORD); + // Set the properties cf.setStringProperty(WMQConstants.WMQ_HOST_NAME, HOST); cf.setIntProperty(WMQConstants.WMQ_PORT, PORT); cf.setStringProperty(WMQConstants.WMQ_CHANNEL, CHANNEL); cf.setIntProperty(WMQConstants.WMQ_CONNECTION_MODE, WMQConstants.WMQ_CM_CLIENT); cf.setStringProperty(WMQConstants.WMQ_QUEUE_MANAGER, QMGR); - cf.setStringProperty(WMQConstants.WMQ_APPLICATIONNAME, "JmsPutGet (JMS)"); + cf.setStringProperty(WMQConstants.WMQ_APPLICATIONNAME, "AWS Stock Finder (JMS)"); cf.setBooleanProperty(WMQConstants.USER_AUTHENTICATION_MQCSP, true); cf.setStringProperty(WMQConstants.USERID, APP_USER); cf.setStringProperty(WMQConstants.PASSWORD, APP_PASSWORD); - + cf.setStringProperty(WMQConstants.WMQ_SSL_CIPHER_SPEC, CIPHER_SPEC); + cf.setIntProperty(WMQConstants.WMQ_CONNECTION_MODE, WMQConstants.WMQ_CM_CLIENT); + // Create JMS objects jmscontext = cf.createContext(); destination = jmscontext.createQueue("queue:///" + TARGET_QUEUE_NAME); @@ -98,7 +106,7 @@ public String handleRequest(Map input, Context context) { source = jmscontext.createQueue("queue:///" + RESPONSE_QUEUE_NAME); consumer = jmscontext.createConsumer(source, "JMSCorrelationID='"+corrid+"'"); // autoclosable - String receivedMessage = consumer.receiveBody(String.class, 15000); // in ms or 15 seconds + String receivedMessage = consumer.receiveBody(String.class, 60000); // in ms or 60 seconds System.out.println("\nGot reply message from STOCK.REPLY queue: " + receivedMessage); diff --git a/ibm-backend-response/jmsapp/.env b/ibm-backend-response/jmsapp/.env index 7e303f5..e87a061 100644 --- a/ibm-backend-response/jmsapp/.env +++ b/ibm-backend-response/jmsapp/.env @@ -16,3 +16,5 @@ export QMGR_HOST= export QMGR_PORT= export APP_USER= export APP_PASSWORD= +export SSL_KEYSTORE= +export SSL_KEYSTORE_PASSWORD= diff --git a/ibm-backend-response/jmsapp/build.gradle b/ibm-backend-response/jmsapp/build.gradle index 44fcade..0726be1 100644 --- a/ibm-backend-response/jmsapp/build.gradle +++ b/ibm-backend-response/jmsapp/build.gradle @@ -1,5 +1,5 @@ /** -* © Copyright IBM Corporation 2018 +* © Copyright IBM Corporation 2018, 2021 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,7 +20,7 @@ repositories { } dependencies { - compile group: 'com.ibm.mq', name: 'com.ibm.mq.allclient', version: '9.0.4.0' + compile group: 'com.ibm.mq', name: 'com.ibm.mq.allclient', version: '9.2.0.1' compile group: 'javax.jms', name: 'javax.jms-api', version: '2.0.1' } diff --git a/ibm-backend-response/jmsapp/com/ibm/mq/samples/jms/JmsPutGet.java b/ibm-backend-response/jmsapp/com/ibm/mq/samples/jms/JmsPutGet.java index 5d779b4..fb56bdb 100644 --- a/ibm-backend-response/jmsapp/com/ibm/mq/samples/jms/JmsPutGet.java +++ b/ibm-backend-response/jmsapp/com/ibm/mq/samples/jms/JmsPutGet.java @@ -1,5 +1,5 @@ /** -* © Copyright IBM Corporation 2018 +* © Copyright IBM Corporation 2018,2021 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -63,7 +63,10 @@ public class JmsPutGet { private static final String APP_USER = System.getenv("APP_USER"); // User name that application uses to connect to MQ private static final String APP_PASSWORD = System.getenv("APP_PASSWORD"); // Password that the application uses to connect to MQ private static final String TARGET_QUEUE_NAME = "STOCK.REPLY"; // Queue that the application uses to put and get messages to and from - private static final String SOURCE_QUEUE_NAME = "STOCK"; // Queue that the application uses to put and get messages to and from + private static final String SOURCE_QUEUE_NAME = "STOCK"; // Queue that the application uses to put and get messages to and from + private static final String SSL_KEYSTORE = System.getenv("SSL_KEYSTORE"); // Keystore which holds the public certificate of the queue manager + private static final String SSL_KEYSTORE_PASSWORD = System.getenv("SSL_KEYSTORE_PASSWORD") ; // Password for the SSL Keystore + private static final String CIPHER_SPEC = "ANY_TLS12_OR_HIGHER"; // Cipher specification /** * Main method @@ -75,11 +78,13 @@ public static void main(String[] args) { System.out.println("port is: " + PORT); System.out.println("qmgr name " + QMGR); System.out.println("App_user is: " + APP_USER); - System.out.println("app api key is: " + APP_PASSWORD); + System.out.println("App api key is: " + APP_PASSWORD.substring(0, 6) + "..."); + System.out.println("Cipher Spec is: " + CIPHER_SPEC); + // Variables JMSContext context = null; Destination destination = null; - Destination source = null; + Destination source = null; JMSProducer producer = null; JMSConsumer consumer = null; @@ -90,16 +95,21 @@ public static void main(String[] args) { JmsFactoryFactory ff = JmsFactoryFactory.getInstance(WMQConstants.WMQ_PROVIDER); JmsConnectionFactory cf = ff.createConnectionFactory(); + System.setProperty("javax.net.ssl.keyStore", SSL_KEYSTORE); + System.setProperty("javax.net.ssl.keyStorePassword", SSL_KEYSTORE_PASSWORD); + // Set the properties cf.setStringProperty(WMQConstants.WMQ_HOST_NAME, HOST); cf.setIntProperty(WMQConstants.WMQ_PORT, PORT); cf.setStringProperty(WMQConstants.WMQ_CHANNEL, CHANNEL); cf.setIntProperty(WMQConstants.WMQ_CONNECTION_MODE, WMQConstants.WMQ_CM_CLIENT); cf.setStringProperty(WMQConstants.WMQ_QUEUE_MANAGER, QMGR); - cf.setStringProperty(WMQConstants.WMQ_APPLICATIONNAME, "JmsPutGet (JMS)"); + cf.setStringProperty(WMQConstants.WMQ_APPLICATIONNAME, "IBM Cloud Stock App (JMS)"); cf.setBooleanProperty(WMQConstants.USER_AUTHENTICATION_MQCSP, true); cf.setStringProperty(WMQConstants.USERID, APP_USER); cf.setStringProperty(WMQConstants.PASSWORD, APP_PASSWORD); + cf.setStringProperty(WMQConstants.WMQ_SSL_CIPHER_SPEC, CIPHER_SPEC); + cf.setIntProperty(WMQConstants.WMQ_CONNECTION_MODE, WMQConstants.WMQ_CM_CLIENT); // Create JMS objects context = cf.createContext(); @@ -120,14 +130,12 @@ public static void main(String[] args) { corrid = "blank"; } -// String receivedMessage = TMreceivedMessage.toString(); String receivedMessage = TMreceivedMessage.getBody(String.class); if ( receivedMessage != null ) { System.out.println("\n\n}============================{\n"); - //receivedMessage = "{ \"product\": \"iphone8\" }"; //TMP System.out.println("\nGot message from STOCK queue:\n " + receivedMessage); System.out.println("\n\nRetrieving stock level ...\n"); diff --git a/qm-config/README.md b/qm-config/README.md index 6840909..0e2cc11 100644 --- a/qm-config/README.md +++ b/qm-config/README.md @@ -4,29 +4,34 @@ In this part of the guide we will deploy IBM MQ to two regions; IBM Cloud US Sou ## 1. Create two IBM MQ service instance -Go to the [IBM MQ on Cloud catalog page](https://console.bluemix.net/catalog/services/mq). +Go to the [IBM MQ on Cloud catalog page](https://cloud.ibm.com/catalog/services/mq). -Give the service the name 'MQ-cloud-demo-ibm'. -Choose 'London' from the 'Choose a region/location to deploy in:' dropdown to deploy in. +Choose 'London (eu-gb)' from the 'Select a location' dropdown. -This will allow us to deploy a queue manager in 'IBM Cloud United Kingdom'. +Choose the Lite plan for this region. + +Name the service 'MQ-cloud-demo-ibm-eu-gb'. + +This will allow us to deploy a queue manager in MQ on Cloud deployment region named 'IBM Cloud United Kingdom'. Click 'Create'. -Once complete, go back to the [IBM MQ on Cloud catalog page](https://console.bluemix.net/catalog/services/mq). +Once complete, go back to the [IBM MQ on Cloud catalog page](https://cloud.ibm.com/catalog/services/mq). + +Choose 'Dallas (us-south)' from the 'Select a location' dropdown. -Give the service the name 'MQ-cloud-demo-aws'. +Choose the Default plan for this region. AWS deployments are not supported in lite plan. -Choose 'Dallas' from the 'Choose a region/location to deploy in:' dropdown to deploy in. +Give the service the name 'MQ-cloud-demo-aws-us-east'. -This will allow us to deploy a queue manager in 'AWS US East 1'. +This will allow us to deploy a queue manager in the MQ on Cloud deployment region named 'AWS US East 1'. Click 'Create'. -Go to the [dashboard](https://console.bluemix.net/dashboard/apps?search=mq-cloud-demo). +Go to the [resource list](https://cloud.ibm.com/resources?search=mq-cloud-demo). -You should see two instances of IBM MQ running on IBM Cloud, in Dallas and London. +Under the services section in the resource list you should see two instances of IBM MQ running on IBM Cloud, in Dallas and London. ___ @@ -34,23 +39,23 @@ ___ ### 2.1 Deploy IBM Cloud queue manager -First, let's deploy a queue manager, to the 'MQ-cloud-demo-ibm' instance. +First, let's deploy a queue manager, to the 'MQ-cloud-demo-ibm-eu-gb' instance. -Go to the [dashboard](https://console.bluemix.net/dashboard/apps?search=mq-cloud-demo), and click 'MQ-cloud-demo-ibm' in the list view. +Go to the [resource list](https://cloud.ibm.com/resources?search=mq-cloud-demo), and click 'MQ-cloud-demo-ibm-eu-gb' in the list view. In the service instance, whilst on the 'Queue managers' tab click 'Create'. Give this queue manager the name 'QM.IBM', and the display name 'IBM Cloud Stock Check queue manager' -Select 'IBM Cloud United Kingdom ' from the location dropdown. +Select 'IBM Cloud United Kingdom' from the location dropdown. -Select 'Trial' as the queue manager size. This will be free to use for 30 days. +The 'Lite' queue manager size should already be selected. Now click 'Create'. You should now see the queue manager listed in the 'Queue managers' tab. ### 2.2 Deploy AWS queue manager -Whilst this is deploying, in a new tab Go back to the [dashboard](https://console.bluemix.net/dashboard/apps?search=mq-cloud-demo), and click 'MQ-cloud-demo-aws' in the list view. +Whilst this is deploying, in a new tab Go back to the [resource list](https://cloud.ibm.com/resources?search=mq-cloud-demo), and click 'MQ-cloud-demo-aws-us-east' in the list view. In the service instance, from the the 'Queue managers' tab click 'Create'. @@ -58,14 +63,13 @@ Give this queue manager the name 'QM.AWS', and the display name 'AWS Stock Check Select 'AWS US East 1' from the location dropdown. -You can only select from Small, Medium, or Large queue managers sizes for AWS deployments. -For this demo, choose 'Small'. +For this demo set the queue manager size to 'Extra Small'. -Click 'Create'. Now back in the queue manager list you should see 'QM.AWS' is deploying,and in your other tab, in the 'MQ-cloud-demo-ibm' you should see 'QM.IBM' is deploying also. +Click 'Create'. Now back in the queue manager list you should see 'QM.AWS' is deploying,and in your other tab, in the 'MQ-cloud-demo-ibm-eu-gb' service instance you should see 'QM.IBM' is deploying also. Wait a few minutes for both queue managers to finish deploying, once complete move onto creating application permissions. -![Image of deployed qm ibm](../assets/ibm_running.png) +![Image of deployed qm ibm](../assets/ibm_running.png) ![Image of deployed qm aws](../assets/aws_running.png) ___ @@ -76,55 +80,60 @@ In order for an MQ application to connect to an instance of IBM MQ on Cloud, we ## 3.1 Create application permissions for IBM Cloud queue manager -Go to the [dashboard](https://console.bluemix.net/dashboard/apps?search=mq-cloud-demo), and click 'MQ-cloud-demo-ibm' in the list view. +Go to the [resource list](https://cloud.ibm.com/resources?search=mq-cloud-demo), and click 'MQ-cloud-demo-ibm-eu-gb' in the list view. -Navigate to the 'Application Permissions' tab, and click 'Create'. +Navigate to the 'Application credentials' tab, and click 'Create'. -Give the application the name 'stockcheck-ibm', and the description 'IBM stock check application'. +Give the application the name 'ibm-stock, and the description 'IBM stock check application'. -Click 'Generate MQ username', this will be used in conjunction with an API Key to authenticate the applications with our queue managers. +The application username will be automatically generated from the application credential name as 'ibmstock' Click 'Add and generate API key' to continue. Wait a few moments whilst this action is performed. -In the subsequent dialog, click 'Download', this will save a copy of the API key to your computer in a `.json` file. Move this file `mq-cloud-demo/qm-config` and rename it `app-ibm.json`. +In the subsequent dialog, click 'Download', this will save a copy of the API key to your computer in a `.json` file. Move this file to the project directory and into `mq-cloud-demo/qm-config`, then rename it `app-ibm.json`. ## 3.2 Create application permissions for AWS queue manager -Go to the [dashboard](https://console.bluemix.net/dashboard/apps?search=mq-cloud-demo), and click 'MQ-cloud-demo-aws' in the list view. +Go to the [resource list](https://cloud.ibm.com/resources?search=mq-cloud-demo), and click 'MQ-cloud-demo-aws-us-east' in the list view. -Navigate to the 'Application Permissions' tab, and click 'Create'. +Navigate to the 'Application credentials' tab, and click 'Create'. -Give the application the name 'stockcheck-aws', and the description 'AWS stock check application'. +Give the application the name 'aws-stock, and the description 'AWS stock check application'. -Click 'Generate MQ username', this will be used in conjunction with an API Key to authenticate the applications with our queue managers. +The application username will be automatically generated from the application credential name as 'awsstock' Click 'Add and generate API key' to continue. Wait a few moments whilst this action is performed. -In the subsequent dialog, click 'Download', this will save a copy of the API key to your computer in a `.json` file. Move this file `mq-cloud-demo/qm-config` and rename it `app-aws.json`. +In the subsequent dialog, click 'Download', this will save a copy of the API key to your computer in a `.json` file. Move this file to the project directory and into `mq-cloud-demo/qm-config`, then rename it `app-aws.json`. +Now you should have two application credentials json files in the mq-cloud-demo directory + +```bash +mq-cloud-demo +| +|- /qm-config + |- app-aws.json // QM.AWS connection info + |- app-ibm.json // QM.IBM connection info +``` ___ ## 4. Download Connection Info for both queue managers -Go to the [dashboard](https://console.bluemix.net/dashboard/apps?search=mq-cloud-demo), and click 'MQ-cloud-demo-aws' in the list view. +In the 'MQ-cloud-demo-aws-us-east' service instance, go to the 'Queue managers' tab. -Go to the 'Queue managers' tab. - -Click on actions menu for 'QM.AWS' and click 'Download connection info (JSON)'. +Hover on the table row for 'QM.AWS' and click the three dot menu icon, and then click 'Download connection info (JSON)'. This will download the connection info in json format for this queue manager, including hostname, port number, queue manager name. This information will be used to configure the two JMS applications later. Do the same for your IBM Cloud queue manager 'QM.IBM'. -Go to the [dashboard](https://console.bluemix.net/dashboard/apps?search=mq-cloud-demo), and click 'MQ-cloud-demo-ibm' in the list view. - -Go to the 'Queue managers' tab. +In the 'MQ-cloud-demo-ibm-eu-gb' service instance, go to the 'Queue managers' tab. -Click on actions menu for 'QM.IBM' and click 'Download connection info (JSON)'. +Hover on the table row for 'QM.IBM' and click the three dot menu icon, and then click 'Download connection info (JSON)'. Move both of these files to `mq-cloud-demo/qm-config` and rename them `info-aws.json` and `info-ibm.json` accordingly. @@ -132,63 +141,63 @@ Move both of these files to `mq-cloud-demo/qm-config` and rename them `info-aws. mq-cloud-demo | |- /qm-config + ... |- info-aws.json // QM.AWS connection info |- info-ibm.json // QM.IBM connection info ``` ___ -## 5. Create admin user permissions - -### 5.1 Add user permissions to IBM Cloud queue manager +## 5. Get admin user credentials -Go to the [dashboard](https://console.bluemix.net/dashboard/apps?search=mq-cloud-demo), and click 'MQ-cloud-demo-ibm' in the list view. +Admin user permissions are automatically added to your queue manager when you first created it. To retrieve the api key and details for the admin user for your queue managers, follow these instructions. This api key is tied to the IBM Cloud platform, so we can download it once an reuse for both queue managers. -Navigate to the 'User permissions' tab. +Go to the [resource list](https://cloud.ibm.com/resources?search=mq-cloud-demo), and click 'MQ-cloud-demo-ibm-eu-gb' in the list view. +Click on 'QM.IBM' in the 'Queue managers' tab. This will take you to the details view for this queue manager. -Click `Add permissions`. +From here, click on the 'Administration' tab. You will now see three buttons which will switch between three views; MQ Console, MQ Explorer, and runmqsc. For now select runmqsc, and then click the 'Create/Reset IBM Cloud API Key button' (text will differ depending on whether you have previously created an API key using this service). -Enter the email address for your IBM Cloud account. +Download the api key file from the subsequent dialog, and move this file to `mq-cloud-demo/qm-config` and rename it to `admin-user.json`. -Click `Generate MQ username`. - -This will generate your unique MQ username, do not edit this. - -Click `Add permissions` to continue, once complete you will be navigated back to the 'User permissions' view. - -### 5.2 Add user permissions to IBM Cloud queue manager +___ -Go to the [dashboard](https://console.bluemix.net/dashboard/apps?search=mq-cloud-demo), and click 'MQ-cloud-demo-aws' in the list view. +## 6. Downloading public certificates for queue managers -Navigate to the 'User permissions' tab. +As of the release for version 9.2.2 revision 1 of the MQ on Cloud queue manager, TLS has been enabled by default to ensure a higher standard of security for all users. This means that an additional step of configuring the client applications to use a keystore with trusted public certificates from the queue manager is required. -Click `Add permissions`. +## 6.1 Obtaining the public certificate for the IBM queue manager -Enter the email address for your IBM Cloud account. +Firstly we will download the public certificate for the IBM queue manager 'QM.IBM'. -Click `Generate MQ username`. +Go to the [resource list](https://cloud.ibm.com/resources?search=mq-cloud-demo), and click 'MQ-cloud-demo-ibm-eu-gb' in the list view. +Click on 'QM.IBM' in the 'Queue managers' tab. This will take you to the details view for this queue manager. -This will generate your unique MQ username, do not edit this. +Next, click on the 'Key store' tab and then click the three dot menu on the certificate labeled 'Default: qmgrcert'. -Click `Add permissions` to continue, once complete you will be navigated back to the 'User permissions' view. +In this menu, click the 'Download public certificate' button. This will download a file names `qmgrcert.pem`. Move this to your project directory and into the `ibm-backend-response` internal directory, and place it in the java project filepath. -### 5.3 Download api key +``` +mq-cloud-demo/ibm-backend-response/jmsapp/qmgrcert.pem +``` -Next, we must generate an MQ username and API key which will allow you to use the MQ Console and administer the queue manager using the administrative REST api or other methods (e.g. MQ Explorer, runmqsc). +## 6.2 Obtaining the public certificate for the AWS queue manager -Go to the [dashboard](https://console.bluemix.net/dashboard/apps?search=mq-cloud-demo), and click 'MQ-cloud-demo-aws' in the list view. This api key is tied to the IBM Cloud platform, so we can download it once an reuse for both queue managers. +Firstly we will download the public certificate for the IBM queue manager 'QM.IBM'. +Go to the [resource list](https://cloud.ibm.com/resources?search=mq-cloud-demo), and click 'MQ-cloud-demo-aws-us-east' in the list view. Click on 'QM.AWS' in the 'Queue managers' tab. This will take you to the details view for this queue manager. -From here, click on the 'Administration' tab. We will now generate you an MQ username, and check whether you have an existing MQ on Cloud api key, or an existing IBM Cloud platform API key. +Next, click on the 'Key store' tab and then click the three dot menu on the certificate labeled 'Default: qmgrcert'. -If you do not already have an existing API key for IBM Cloud, click the 'Create/Reset IBM Cloud API Key' button. +In this menu, click the 'Download public certificate' button. This will download a file names `qmgrcert.pem`. Move this to your project directory and into the `aws-backend-request` internal directory, and place it in the java project filepath. -Download the api key file from the subsequent dialog, and move this file to `mq-cloud-demo/qm-config` and rename it to `user.json`. +``` +mq-cloud-demo/aws-backend-request/JMSLambdaFunction/qmgrcert.pem +``` -___ +We will configure keystores in each individual applications setup instructions which will follow later in this guide. -## 6. Configuring the queue managers +## 7. Configuring the queue managers We have included a handy script that will configure both queue managers using the supplied connection info files, application details and admin user details. @@ -202,15 +211,21 @@ mq-cloud-demo |- info-ibm.json |- app-ibm.json |- app-aws.json - |- user.json + |- admin-user.json |- configure_qmgr.sh ``` +As the script expects files to be named in a specifc way please ensure this is correct before continuing. + Run the following script passing in the following parameters. ```bash cd mq-cloud-demo/qm-config -./configure_qmgr.sh info-ibm.json app-ibm.json info-aws.json app-aws.json user.json +./configure_qmgr.sh info-ibm.json app-ibm.json info-aws.json app-aws.json admin-user.json ``` -Greate, you have enabled messaging between two IBM MQ on Cloud queue managers. Return to the main README page to continue the guide -> [Go Back](../README.md#setting-up-the-aws-lambda-function) \ No newline at end of file +Greate, you have enabled messaging between two IBM MQ on Cloud queue managers. Return to the main README page to continue the guide -> [Go Back](../README.md#setting-up-the-aws-lambda-function) + +## Copyright + +© Copyright IBM Corporation 2018, 2021 diff --git a/qm-config/configure_qmgr.sh b/qm-config/configure_qmgr.sh index 08da923..b66ed5a 100755 --- a/qm-config/configure_qmgr.sh +++ b/qm-config/configure_qmgr.sh @@ -1,5 +1,5 @@ #!/bin/bash -# © Copyright IBM Corporation 2018 +# © Copyright IBM Corporation 2018, 2021 # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at @@ -63,7 +63,7 @@ then QMGR_1_HOST=`jq '.hostname' ${QM_FILE_1} -r` QMGR_1_PORT=`jq '.listenerPort' ${QM_FILE_1} -r` QMGR_1_NAME=`jq '.queueManagerName' ${QM_FILE_1} -r` - QMGR_1_ENV=`jq '.deploymentLocation' ${QM_FILE_1} -r | awk -F"-" '{ print $1}' | tr '[:lower:]' '[:upper:]'` + QMGR_1_ENV=`jq '.hostname' ${QM_FILE_1} -r | awk -F"-" '{ print $2}' | tr '[:lower:]' '[:upper:]'` if [ ${QMGR_1_ENV} == ${BMX} ]; then QMGR_1_ENV=${IBM} @@ -126,11 +126,11 @@ then QMGR_2_HOST=`jq '.hostname' ${QM_FILE_2} -r` QMGR_2_PORT=`jq '.listenerPort' ${QM_FILE_2} -r` QMGR_2_NAME=`jq '.queueManagerName' ${QM_FILE_2} -r` - QMGR_2_ENV=`jq '.deploymentLocation' ${QM_FILE_2} -r | awk -F"-" '{ print $1}' | tr '[:lower:]' '[:upper:]'` + QMGR_2_ENV=`jq '.hostname' ${QM_FILE_2} -r | awk -F"-" '{ print $2}' | tr '[:lower:]' '[:upper:]'` if [ ${QMGR_2_ENV} == ${BMX} ]; then QMGR_2_ENV=${IBM} - echo ${QMGR_1_ENV} + echo ${QMGR_2_ENV} fi else printf "\nHostname of second queue manager: e.g. qm2.other.domain.com\n"