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

Update to handle TLS channels #20

Open
wants to merge 1 commit into
base: master
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
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -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
qm-config/cookiejar.txt
*.kdb
*.sth
*.pem
168 changes: 130 additions & 38 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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

Expand Down Expand Up @@ -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.

___
Expand All @@ -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.

___

Expand All @@ -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 `<your password>` 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 <your password> -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
Expand All @@ -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 | <Your_Application_APIKey>
| APP_USER | <Your_Application_MQUsername>
| QMGR_HOST | <The_Hostname_Of_Your_Queue_Manager>
| QMGR_PORT | <Your_QM_Port>
| QMGR_NAME | <Your_QMGR_NAME>
| APP_PASSWORD | *Your aws application api key* <app-aws.json>
| APP_USER | *Your aws application user name* <app-aws.json>
| QMGR_HOST | *The hostname for your queue manager* <info-aws.json>
| QMGR_PORT | *The listener port number for your queue manager* <info-aws.json>
| 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)

Expand All @@ -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

Expand All @@ -199,27 +251,65 @@ 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.
___

#### 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 `<your password>` 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 <your password> -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`

Expand All @@ -231,6 +321,8 @@ export QMGR_HOST=<Your-IBM-cloud-queue-managers-hostname>
export QMGR_PORT=<Your-IBM-cloud-queue-managers-listener-port>
export APP_USER=<Your-app-username>
export APP_PASSWORD=<Your-app-password>
export SSL_KEYSTORE=<Your-keystore-filepath>
export SSL_KEYSTORE_PASSWORD=<Your-keystore-password>
```

Now source the `.env` file by running the following command:
Expand All @@ -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.

Expand All @@ -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.
Expand Down Expand Up @@ -305,4 +397,4 @@ must include a statement stating you accept the terms in the CLA.

## Copyright

© Copyright IBM Corporation 2018
© Copyright IBM Corporation 2018, 2021
Binary file modified assets/aws_running.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified assets/ibm_running.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified assets/lamdba_function.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified assets/scenario_image.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
9 changes: 6 additions & 3 deletions aws-backend-request/JMSLambdaFunction/build.gradle
Original file line number Diff line number Diff line change
@@ -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.
Expand All @@ -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')
Expand All @@ -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
}
Expand Down
Loading