# Deploy avail-api-app service
[bamboo@localhost solar-travel-availability]$ gradle :avail-api:deployContainer -PimageVersion=0.0.1-DEMO -PocProjectName=fet-nfv-poc
~~~
> Configure project :avail-api
Working directory: /home/bamboo/projects/solar-travel-availability
> Task :avail-api:createNewProject
Executing command: oc new-project fet-nfv-poc
Executing command: oc project fet-nfv-poc
Already on project "fet-nfv-poc" on server "https://c100-e.eu-de.containers.cloud.ibm.com:32553".
> Task :avail-api:createImageSecret
Skip creating Image Secret. Repository is public on quay.io, private is not free.
> Task :avail-api:deleteApp
Executing command: oc delete all -l app=avail-api-app
No resources found
> Task :avail-api:installRedisDatabase
Executing command: oc new-app --docker-image redis --name redis-solar-travel-availability
Executing command: oc new-app --docker-image redis --name redis-solar-travel-pubsub
> Task :avail-api:createNewApp
Executing command: oc project fet-nfv-poc
Already on project "fet-nfv-poc" on server "https://c100-e.eu-de.containers.cloud.ibm.com:32553".
Executing command: oc new-app --docker-image quay.io/solar-travel/avail-api-app:0.0.1-DEMO -e DEVELOPMENT_ENV=true -e REDIS_HOST=redis-solar-travel-availability -e IBM_S3_LOCATION=null -e IBM_S3_API_KEY=null -e IBM_S3_IAM_SERVICE_ID=null -e IBM_S3_PUBLIC_ENDPOINT=null -e RES_DATA_BUCKET_NAME=null -e RES_DATA_OBJECT_KEY=null -e REDIS_CONNECTION_STRING=redis://redis-solar-travel-availability -e REDIS_PUBSUB_CONNECTION_STRING=redis://redis-solar-travel-pubsub -e REDIS_API_KEY=null -e REDIS_PASSWORD='' -e REDIS_DEPLOYMENT_ID=''
--> Found Docker image e426479 (9 days old) from quay.io for "quay.io/solar-travel/avail-api-app:0.0.1-DEMO"
* An image stream tag will be created as "avail-api-app:0.0.1-DEMO" that will track this image
* This image will be deployed in deployment config "avail-api-app"
* Ports 9080/tcp, 9443/tcp will be load balanced by service "avail-api-app"
* Other containers can access this service through the hostname "avail-api-app"
--> Creating resources ...
imagestream.image.openshift.io "avail-api-app" created
deploymentconfig.apps.openshift.io "avail-api-app" created
service "avail-api-app" created
--> Success
Application is not exposed. You can expose services to the outside world by executing one or more of the commands below:
'oc expose svc/avail-api-app'
Run 'oc status' to view your app.
> Task :avail-api:checkPodStatus
Executing command: oc get dc avail-api-app | grep avail-api-app | cut -d' ' -f1,4,14,23
avail-api-app 1 1 0
Retry pods status checking: 0
Executing command: oc get dc avail-api-app | grep avail-api-app | cut -d' ' -f1,4,14,23
avail-api-app 1 1 1
Executing command: oc get dc avail-api-app | grep avail-api-app | cut -d' ' -f1,4,14,23
avail-api-app 1 1 1
> Task :avail-api:exposeService
Executing command: oc expose service avail-api-app
route.route.openshift.io/avail-api-app exposed
Executing command: oc patch route/avail-api-app --patch '{"spec":{"tls":{"termination":"edge"}}}'
route.route.openshift.io/avail-api-app patched
> Task :avail-api:testDeployedService
Executing command: oc get route | grep avail-api-app | grep -P 'avail-api-app-fet-nfv-poc.*\.(com|cloud)' -o
avail-api-app-fet-nfv-poc.fetnet-1579251008816-f72ef11f3ab089a8c677044eb28292cd-0001.eu-de.containers.appdomain.cloud
Executing command: curl -sX GET https://avail-api-app-fet-nfv-poc.fetnet-1579251008816-f72ef11f3ab089a8c677044eb28292cd-0001.eu-de.containers.appdomain.cloud/hello
Executing command: curl -sX GET https://avail-api-app-fet-nfv-poc.fetnet-1579251008816-f72ef11f3ab089a8c677044eb28292cd-0001.eu-de.containers.appdomain.cloud/hello
Hello, world
Test success
----------------------------------------------------------------------------------------
> Task :avail-api:deployContainer
The container has been successfully deployed.
~~~
# Deploy avail-mgnt-app service
[bamboo@localhost solar-travel-availability]$ gradle :avail-mgnt:deployContainer -PimageVersion=0.0.1-DEMO -PocProjectName=fet-nfv-poc
~~~
> Configure project :avail-api
Working directory: /home/bamboo/projects/solar-travel-availability
> Task :avail-mgnt:createNewProject
Executing command: oc new-project fet-nfv-poc
> Task :avail-mgnt:createImageSecret
Skip creating Image Secret. Repository is public on quay.io, private is not free.
> Task :avail-mgnt:deleteApp
Executing command: oc delete all -l app=avail-mgnt-app
No resources found
> Task :avail-mgnt:installRedisDatabase
Executing command: oc new-app --docker-image redis --name redis-solar-travel-availability
Executing command: oc new-app --docker-image redis --name redis-solar-travel-pubsub
> Task :avail-mgnt:createNewApp
Executing command: oc project fet-nfv-poc
Already on project "fet-nfv-poc" on server "https://c100-e.eu-de.containers.cloud.ibm.com:32553".
Executing command: oc new-app --docker-image quay.io/solar-travel/avail-mgnt-app:0.0.1-DEMO -e DEVELOPMENT_ENV=true -e REDIS_HOST=redis-solar-travel-availability -e IBM_S3_LOCATION=null -e IBM_S3_API_KEY=null -e IBM_S3_IAM_SERVICE_ID=null -e IBM_S3_PUBLIC_ENDPOINT=null -e RES_DATA_BUCKET_NAME=null -e RES_DATA_OBJECT_KEY=null -e REDIS_CONNECTION_STRING=redis://redis-solar-travel-availability -e REDIS_PUBSUB_CONNECTION_STRING=redis://redis-solar-travel-pubsub -e REDIS_API_KEY=null -e REDIS_PASSWORD='' -e REDIS_DEPLOYMENT_ID=''
--> Found Docker image fde1105 (8 days old) from quay.io for "quay.io/solar-travel/avail-mgnt-app:0.0.1-DEMO"
* An image stream tag will be created as "avail-mgnt-app:0.0.1-DEMO" that will track this image
* This image will be deployed in deployment config "avail-mgnt-app"
* Ports 9080/tcp, 9443/tcp will be load balanced by service "avail-mgnt-app"
* Other containers can access this service through the hostname "avail-mgnt-app"
--> Creating resources ...
imagestream.image.openshift.io "avail-mgnt-app" created
deploymentconfig.apps.openshift.io "avail-mgnt-app" created
service "avail-mgnt-app" created
--> Success
Application is not exposed. You can expose services to the outside world by executing one or more of the commands below:
'oc expose svc/avail-mgnt-app'
Run 'oc status' to view your app.
> Task :avail-mgnt:checkPodStatus
Executing command: oc get dc avail-mgnt-app | grep avail-mgnt-app | cut -d' ' -f1,4,14,23
avail-mgnt-app 1 1 0
Retry pods status checking: 0
Executing command: oc get dc avail-mgnt-app | grep avail-mgnt-app | cut -d' ' -f1,4,14,23
avail-mgnt-app 1 1 1
Executing command: oc get dc avail-mgnt-app | grep avail-mgnt-app | cut -d' ' -f1,4,14,23
avail-mgnt-app 1 1 1
> Task :avail-mgnt:exposeService
Executing command: oc expose service avail-mgnt-app
route.route.openshift.io/avail-mgnt-app exposed
Executing command: oc patch route/avail-mgnt-app --patch '{"spec":{"tls":{"termination":"edge"}}}'
route.route.openshift.io/avail-mgnt-app patched
> Task :avail-mgnt:testDeployedService
Executing command: oc get route | grep avail-mgnt-app | grep -P 'avail-mgnt-app-fet-nfv-poc.*\.(com|cloud)' -o
avail-mgnt-app-fet-nfv-poc.fetnet-1579251008816-f72ef11f3ab089a8c677044eb28292cd-0001.eu-de.containers.appdomain.cloud
Executing command: curl -sX GET https://avail-mgnt-app-fet-nfv-poc.fetnet-1579251008816-f72ef11f3ab089a8c677044eb28292cd-0001.eu-de.containers.appdomain.cloud/hello
Hello, world
Test success
----------------------------------------------------------------------------------------
> Task :avail-mgnt:deployContainer
The container has been successfully deployed.
BUILD SUCCESSFUL in 1m 1s
9 actionable tasks: 9 executed
~~~
# Running CLI command to reload data into in-memory database
[bamboo@localhost demo-scripts]$ ./reload.sh
~~~
1d5ac0d8-0cbc-4c06-bca0-c498348d497e
~~~
[bamboo@localhost demo-scripts]$ ./wait.sh 1d5ac0d8-0cbc-4c06-bca0-c498348d497e
~~~
wait response:
id=1d5ac0d8-0cbc-4c06-bca0-c498348d497e
receivedTime=2020-02-17T04:19:42.597+0000
status=COMPLETE
~~~
# Calling api /trains/{trainDate}/{trainTime}/{origin}/{dest}/ai
[bamboo@localhost demo-scripts]$ curl -sX GET 'https://avail-api-app-fet-nfv-poc.fetnet-1579251008816-f72ef11f3ab089a8c677044eb28292cd-0001.eu-de.containers.appdomain.cloud/trains/20190131/2200/SUN/EAR/ai'
~~~
[{
"destinationStation": {
"locationCode": "EAR"
},
"originStation": {
"locationCode": "SUN"
},
"trainDate": "20190131",
"trainTime": "2205",
"train": {
"trainNumber": "0295"
},
"classCodes": [{
"code": "Y",
"quantity": 0
}, {
"code": "YF",
"quantity": 0
}, {
"code": "YV",
"quantity": 0
}, {
"code": "YW;",
"quantity": 0
}]
}, {
"destinationStation": {
"locationCode": "EAR"
},
"originStation": {
"locationCode": "SUN"
},
"trainDate": "20190131",
"trainTime": "2215",
"train": {
"trainNumber": "0565"
},
"classCodes": [{
"code": "Y",
"quantity": 0
}, {
"code": "YF",
"quantity": 0
}, {
"code": "YV",
"quantity": 0
}, {
"code": "YW;",
"quantity": 0
}]
}, {
"destinationStation": {
"locationCode": "EAR"
},
"originStation": {
"locationCode": "SUN"
},
"trainDate": "20190131",
"trainTime": "2250",
"train": {
"trainNumber": "0567"
},
"classCodes": [{
"code": "Y",
"quantity": 0
}, {
"code": "YF",
"quantity": 0
}, {
"code": "YV",
"quantity": 0
}, {
"code": "YW;",
"quantity": 0
}]
}]
~~~
# Deploy api-gateway-app
[bamboo@localhost solar-travel-integration]$ gradle :api-gateway:deployContainer -PimageVersion=0.0.4-DEMO -PocProjectName=fet-nfv-poc
~~~
> Task :api-gateway:createNewProject
Executing command: oc new-project fet-nfv-poc
> Task :api-gateway:createImageSecret
Skip creating Image Secret. Repository is public on quay.io, private is not free.
> Task :api-gateway:deleteApp
Executing command: oc delete all -l app=api-gateway-app
pod "api-gateway-app-67bf5787f-kjh9z" deleted
service "api-gateway-app" deleted
replicaset.apps "api-gateway-app-67bf5787f" deleted
route.route.openshift.io "api-gateway-app" deleted
Executing command: oc delete serviceaccounts api-gateway-app
serviceaccount "api-gateway-app" deleted
Executing command: oc delete deployment api-gateway-app
deployment.extensions "api-gateway-app" deleted
Executing command: oc delete clusterrolebindings api-gateway-cluster-reader
clusterrolebinding.authorization.openshift.io "api-gateway-cluster-reader" deleted
> Task :api-gateway:createNewApp
Executing command: cat api-gateway/create-api-gateway-template.yaml|sed "s/{{ ocProjectName }}/fet-nfv-poc/g;s/{{ imageVersion }}/0.0.4-DEMO/g" > api-gateway/create-api-gateway.yaml
Executing command: oc create -f api-gateway/create-api-gateway.yaml
serviceaccount/api-gateway-app created
clusterrolebinding.authorization.openshift.io/api-gateway-cluster-reader created
route.route.openshift.io/api-gateway-app created
service/api-gateway-app created
deployment.apps/api-gateway-app created
> Task :api-gateway:checkPodStatus
Executing command: oc get deployment api-gateway-app | grep api-gateway-app | cut -d' ' -f1,4,14,23
api-gateway-app 1
> Task :api-gateway:exposeService
Skip exposing service, already did in the deployment yaml file
> Task :api-gateway:testDeployedService
Executing command: oc get route | grep api-gateway-app | grep -P 'api-gateway-app-fet-nfv-poc.*\.(com|cloud)' -o
api-gateway-app-fet-nfv-poc.fetnet-1579251008816-f72ef11f3ab089a8c677044eb28292cd-0001.eu-de.containers.appdomain.cloud
Executing command: (masked): oc serviceaccounts get-token api-gateway-app
******
Executing command: (masked): curl -H "Authorization: bearer <token>" -sX Get https://api-gateway-app-fet-nfv-poc.fetnet-1579251008816-f72ef11f3ab089a8c677044eb28292cd-0001.eu-de.containers.appdomain.cloud/hello
******
Executing command: (masked): curl -H "Authorization: bearer <token>" -sX Get https://api-gateway-app-fet-nfv-poc.fetnet-1579251008816-f72ef11f3ab089a8c677044eb28292cd-0001.eu-de.containers.appdomain.cloud/hello
******
Test success
----------------------------------------------------------------------------------------
> Task :api-gateway:deployContainer
The container has been successfully deployed.
BUILD SUCCESSFUL in 55s
8 actionable tasks: 8 executed
~~~
# Access API gateway url /hello via a web browser
https://api-gateway-app-fet-nfv-poc.fetnet-1579251008816-f72ef11f3ab089a8c677044eb28292cd-0001.eu-de.containers.appdomain.cloud/hello
# Access API gateway url /management/trains/reload using Authorization Header
## Getting the token
[bamboo@localhost solar-travel-integration]$ TOKEN=$(oc serviceaccounts get-token api-gateway-app)
## Use the token
[bamboo@localhost solar-travel-integration]$ curl -H "Authorization: bearer $TOKEN" -sX Get https://api-gateway-app-fet-nfv-poc.fetnet-1579251008816-f72ef11f3ab089a8c677044eb28292cd-0001.eu-de.containers.appdomain.cloud/management/trains/reload
~~~
{"id":"76afc0bf-1308-41af-9489-39b12cd3a1fe","receivedTime":"2020-02-17T04:42:41.049+0000","status":"ACCEPTED"}
~~~
# Lookup Train schedule via API gateway
[bamboo@localhost solar-travel-integration]$ curl -H "Authorization: bearer $TOKEN" -sX Get 'https://api-gateway-app-fet-nfv-poc.fetnet-1579251008816-f72ef11f3ab089a8c677044eb28292cd-0001.eu-de.containers.appdomain.cloud/customers/trains?trainDate=20190131&trainTime=2200&origin=EAR&dest=SUN'
~~~
[{"destinationStation":{"locationCode":"SUN"},"originStation":{"locationCode":"EAR"},"trainDate":"20190131","trainTime":"2202","train":{"trainNumber":"0684"},"classCodes":[{"code":"Y","quantity":0},{"code":"YF","quantity":0},{"code":"YV","quantity":0},{"code":"YW;","quantity":0}]},{"destinationStation":{"locationCode":"SUN"},"originStation":{"locationCode":"EAR"},"trainDate":"20190131","trainTime":"2232","train":{"trainNumber":"0160"},"classCodes":[{"code":"Y","quantity":0},{"code":"YF","quantity":0},{"code":"YV","quantity":0},{"code":"YW;","quantity":0}]},{"destinationStation":{"locationCode":"SUN"},"originStation":{"locationCode":"EAR"},"trainDate":"20190131","trainTime":"2242","train":{"trainNumber":"0858"},"classCodes":[{"code":"YA","quantity":0},{"code":"Y","quantity":0},{"code":"YB","quantity":0},{"code":"YF","quantity":0},{"code":"YV","quantity":0},{"code":"YW;","quantity":0}]},{"destinationStation":{"locationCode":"SUN"},"originStation":{"locationCode":"EAR"},"trainDate":"20190131","trainTime":"2307","train":{"trainNumber":"0690"},"classCodes":[{"code":"Y","quantity":0},{"code":"YF","quantity":0},{"code":"YV","quantity":0},{"code":"YW;","quantity":0}]},{"destinationStation":{"locationCode":"SUN"},"originStation":{"locationCode":"EAR"},"trainDate":"20190131","trainTime":"2347","train":{"trainNumber":"0862"},"classCodes":[{"code":"YA","quantity":0},{"code":"Y","quantity":0},{"code":"YB","quantity":0},{"code":"YF","quantity":0},{"code":"YV","quantity":0},{"code":"YW;","quantity":0}]},{"destinationStation":{"locationCode":"SUN"},"originStation":{"locationCode":"EAR"},"trainDate":"20190131","trainTime":"2352","train":{"trainNumber":"0294"},"classCodes":[{"code":"YA","quantity":0},{"code":"Y","quantity":0},{"code":"YB","quantity":0},{"code":"YF","quantity":0},{"code":"YV","quantity":0},{"code":"YW;","quantity":0}]}]
~~~
# oauth-proxy sidecar deployment
[bamboo@localhost solar-travel-integration]$ oc get deployments api-gateway-app -o yaml
~~~
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
annotations:
deployment.kubernetes.io/revision: "1"
creationTimestamp: 2020-02-17T04:32:41Z
generation: 1
name: api-gateway-app
namespace: fet-nfv-poc
resourceVersion: "10787232"
selfLink: /apis/extensions/v1beta1/namespaces/fet-nfv-poc/deployments/api-gateway-app
uid: 890ea3a3-513e-11ea-8fd4-8a83bb8e45db
spec:
progressDeadlineSeconds: 600
replicas: 1
revisionHistoryLimit: 10
selector:
matchLabels:
app: api-gateway-app
strategy:
rollingUpdate:
maxSurge: 25%
maxUnavailable: 25%
type: RollingUpdate
template:
metadata:
creationTimestamp: null
labels:
app: api-gateway-app
spec:
containers:
- args:
- --https-address=:8443
- --provider=openshift
- --openshift-service-account=api-gateway-app
- --upstream=http://localhost:9080
- --tls-cert=/etc/tls/private/tls.crt
- --tls-key=/etc/tls/private/tls.key
- --cookie-secret=SECRET
- --openshift-delegate-urls={"/":{"resource":"services","verb":"get","project":"fet-nfv-poc","name":"api-gateway-app"}}
image: openshift/oauth-proxy:latest
imagePullPolicy: IfNotPresent
name: oauth-proxy
ports:
- containerPort: 8443
name: public
protocol: TCP
resources: {}
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
volumeMounts:
- mountPath: /etc/tls/private
name: api-gateway-proxy-tls
- env:
- name: AVAILABILITY_SERVICE_NAME
value: avail-api-app:9080
- name: AVAILABILITY_MGNT_SERVICE_NAME
value: avail-mgnt-app:9080
- name: DEVELOPMENT_ENV
value: "true"
- name: IBM_S3_API_KEY
value: "null"
- name: IBM_S3_IAM_SERVICE_ID
value: "null"
- name: IBM_S3_LOCATION
value: "null"
- name: IBM_S3_PUBLIC_ENDPOINT
value: "null"
- name: RES_DATA_BUCKET_NAME
value: "null"
- name: RES_DATA_OBJECT_KEY
value: "null"
image: quay.io/solar-travel/api-gateway-app:0.0.4-DEMO
imagePullPolicy: Always
name: api-gateway-app-upstream
resources: {}
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
dnsPolicy: ClusterFirst
restartPolicy: Always
schedulerName: default-scheduler
securityContext: {}
serviceAccount: api-gateway-app
serviceAccountName: api-gateway-app
terminationGracePeriodSeconds: 30
volumes:
- name: api-gateway-proxy-tls
secret:
defaultMode: 420
secretName: api-gateway-proxy-tls
status:
availableReplicas: 1
conditions:
- lastTransitionTime: 2020-02-17T04:32:46Z
lastUpdateTime: 2020-02-17T04:32:46Z
message: Deployment has minimum availability.
reason: MinimumReplicasAvailable
status: "True"
type: Available
- lastTransitionTime: 2020-02-17T04:32:41Z
lastUpdateTime: 2020-02-17T04:32:46Z
message: ReplicaSet "api-gateway-app-69fdbcf798" has successfully progressed.
reason: NewReplicaSetAvailable
status: "True"
type: Progressing
observedGeneration: 1
readyReplicas: 1
replicas: 1
updatedReplicas: 1
~~~
# Integration Testing with Gradle docker-compose-plugin
[bamboo@localhost solar-travel-integration]$ gradle api-gateway:tasks --all
~~~
> Task :api-gateway:tasks
------------------------------------------------------------
Tasks runnable from project :api-gateway
------------------------------------------------------------
Application tasks
-----------------
bootRun - Runs this project as a Spring Boot application.
Build tasks
-----------
assemble - Assembles the outputs of this project.
bootJar - Assembles an executable jar archive containing the main classes and their dependencies.
build - Assembles and tests this project.
buildDependents - Assembles and tests this project and all projects that depend on it.
buildNeeded - Assembles and tests this project and all projects it depends on.
classes - Assembles main classes.
clean - Deletes the build directory.
jar - Assembles a jar archive containing the main classes.
testClasses - Assembles test classes.
Docker tasks
------------
composeBuild - Builds images for services of docker-compose project
composeDown - Stops and removes containers of docker-compose project (only if stopContainers is set to true)
composeDownForced - Stops and removes containers of docker-compose project
composeLogs - Stores log output from services in containers of docker-compose project
composePull - Builds and pulls images of docker-compose project
composePush - Pushes images for services of docker-compose project
composeUp - Builds and starts containers of docker-compose project
Documentation tasks
-------------------
javadoc - Generates Javadoc API documentation for the main source code.
Help tasks
----------
buildEnvironment - Displays all buildscript dependencies declared in project ':api-gateway'.
components - Displays the components produced by project ':api-gateway'. [incubating]
dependencies - Displays all dependencies declared in project ':api-gateway'.
dependencyInsight - Displays the insight into a specific dependency in project ':api-gateway'.
dependencyManagement - Displays the dependency management declared in project ':api-gateway'.
dependentComponents - Displays the dependent components of components in project ':api-gateway'. [incubating]
help - Displays a help message.
model - Displays the configuration model of project ':api-gateway'. [incubating]
projects - Displays the sub-projects of project ':api-gateway'.
properties - Displays the properties of project ':api-gateway'.
tasks - Displays the tasks runnable from project ':api-gateway'.
Verification tasks
------------------
check - Runs all checks.
test - Runs the unit tests.
Other tasks
-----------
buildDockerImage - Build the docker image of Websphere Liberty Developer version that run the springboot app.
checkPodStatus - Check the deployed pods status.
compileJava - Compiles main Java source.
compileTestJava - Compiles test Java source.
createImageSecret - Create a secret for pulling image from the image registry.
createNewApp
createNewProject - Create a new Openshift project using the optional value of -PocProjectName if provided, otherwise, it is default to the parent project name.
deleteApp - Delete the openshift application.
deployContainer
enableSpringApp - Let Liberty recognizes the Springboot app.
exposeService - Make the app accessible outside the cluster by creating a service route.
initConfigParameters
installIBMCloudPlugin - Install IBM Cloud cr and cs plugins.
integrationTest - Perform integration test with other containers.
loginCloud - Login to IBM Cloud.
loginOpenshift - Loging to openshift with parameter <openshiftUrl>.
processResources - Processes main resources.
processTestResources - Processes test resources.
pushDockerImage - Push the spring boot application docker image to a Container Registry.
removeDockerContainer - Remove any running api-gateway container.
removeDockerImage - Remove any api-gateway-app image.
testDeployedService - Test the deployed service.
testDockerImage - Test the docker image created by the buildDockerImage task.
validateContainer
Rules
-----
Pattern: clean<TaskName>: Cleans the output files of a task.
Pattern: build<ConfigurationName>: Assembles the artifacts of a configuration.
Pattern: upload<ConfigurationName>: Assembles and uploads the artifacts belonging to a configuration.
BUILD SUCCESSFUL in 1s
1 actionable task: 1 executed
<-------------> 0% WAITING
> IDLE
~~~
## docker-compose-plugins settings
~~~
dockerCompose {
useComposeFiles = ['api-gateway-integration.yaml']
removeImages = "Local"
environment.put 'AVAIL_API_VERSION', '0.0.1-SNAPSHOT'
environment.put 'AVAIL_MGNT_VERSION', '0.0.1-SNAPSHOT'
}
dockerCompose.isRequiredBy(integrationTest)
~~~
[bamboo@localhost solar-travel-integration]$ ls api-gateway/api-gateway-integration.yaml -ls
~~~
4 -rw-rw-r--. 1 bamboo bamboo 1384 Feb 7 12:20 api-gateway/api-gateway-integration.yaml
~~~
[bamboo@localhost solar-travel-integration]$ vi api-gateway/api-gateway-integration.yaml -R
~~~
1 version: "3.3"
2
3 services:
4 api-gateway:
5 build: .
6 links:
7 - avail-api-app
8 - avail-mgnt-app
9 ports:
10 - "39083:9080"
11 environment:
12 - AVAILABILITY_SERVICE_NAME=avail-api-app:9080
13 - AVAILABILITY_MGNT_SERVICE_NAME=avail-mgnt-app:9080
14
15 avail-api-app:
16 image: "quay.io/solar-travel/avail-api-app:${AVAIL_API_VERSION}"
17 links:
18 - redis-solar-travel-availability
19 ports:
20 - "39081:9080"
21 environment:
22 - REDIS_CONNECTION_STRING=redis://redis-solar-travel-availability
23 - IBM_S3_LOCATION=""
24 - IBM_S3_API_KEY=""
25 - IBM_S3_IAM_SERVICE_ID=""
26 - IBM_S3_PUBLIC_ENDPOINT=""
27 - RES_DATA_BUCKET_NAME=""
28 - RES_DATA_OBJECT_KEY=""
29
30 avail-mgnt-app:
31 image: "quay.io/solar-travel/avail-mgnt-app:${AVAIL_MGNT_VERSION}"
32 links:
33 - redis-solar-travel-availability
34 - redis-solar-travel-pubsub
35 ports:
36 - "39082:9080"
37 environment:
38 - REDIS_CONNECTION_STRING=redis://redis-solar-travel-availability
39 - REDIS_PUBSUB_CONNECTION_STRING=redis://redis-solar-travel-pubsub
40 - IBM_S3_LOCATION=""
41 - IBM_S3_API_KEY=""
42 - IBM_S3_IAM_SERVICE_ID=""
43 - IBM_S3_PUBLIC_ENDPOINT=""
44 - RES_DATA_BUCKET_NAME=""
45 - RES_DATA_OBJECT_KEY=""
46
47 redis-solar-travel-availability:
48 image: redis
49
50 redis-solar-travel-pubsub:
51 image: redis
~~~
## Grdle integrationTest task implementation
~~~
669 task integrationTest(dependsOn: build) {
670 description = "Perform integration test with other containers."
671
672 doLast {
673 String[] ports = ["39081", "39082", "39083"]
674 for (String port : ports) {
675 sendRetry("http://localhost:$port/hello")
676 println "Connected to endpoint http://localhost:$port/hello"
677 println "----------------------------------------------------------------------------------------"
678 }
679 String result = executeCmd("curl -sX GET 'http://localhost:39083/management/trains/reload'")
680 def jsonSlurper = new groovy.json.JsonSlurper()
681 def reloadResult = jsonSlurper.parseText(result)
682
683 executeCmd("curl -sX GET 'http://localhost:39083/management/trains/waitfor/${reloadResult.id}'")
684 result = executeCmd("curl -sX GET 'http://localhost:39083/customers/trains?trainDate=20190131&trainTime=2200&origin=EAR&dest=SUN'")
685 def trains = jsonSlurper.parseText(result)
686 assert 6 == trains.size()
687 println "Total number of trains return: ${trains.size()}"
688 }
689 }
~~~
## Running the integration Test
[bamboo@rhel-7-server solar-travel-integration]$ gradle :api-gateway:integrationTest
~~~
Starting a Gradle Daemon (subsequent builds will be faster)
> Task :api-gateway:composeUp
redis-solar-travel-availability uses an image, skipping
avail-api-app uses an image, skipping
redis-solar-travel-pubsub uses an image, skipping
avail-mgnt-app uses an image, skipping
Building api-gateway
aa06e167b60ece271c3dc97464aed27fapigateway_redis-solar-travel-availability_1 is up-to-date
aa06e167b60ece271c3dc97464aed27fapigateway_redis-solar-travel-pubsub_1 is up-to-date
aa06e167b60ece271c3dc97464aed27fapigateway_avail-api-app_1 is up-to-date
aa06e167b60ece271c3dc97464aed27fapigateway_avail-mgnt-app_1 is up-to-date
aa06e167b60ece271c3dc97464aed27fapigateway_api-gateway_1 is up-to-date
Will use 172.20.0.1 (network aa06e167b60ece271c3dc97464aed27fapigateway_default) as host of redis-solar-travel-availability
Will use 172.20.0.1 (network aa06e167b60ece271c3dc97464aed27fapigateway_default) as host of avail-api-app
Will use 172.20.0.1 (network aa06e167b60ece271c3dc97464aed27fapigateway_default) as host of redis-solar-travel-pubsub
Will use 172.20.0.1 (network aa06e167b60ece271c3dc97464aed27fapigateway_default) as host of avail-mgnt-app
Will use 172.20.0.1 (network aa06e167b60ece271c3dc97464aed27fapigateway_default) as host of api-gateway
Probing TCP socket on 172.20.0.1:39081 of service 'avail-api-app_1'
TCP socket on 172.20.0.1:39081 of service 'avail-api-app_1' is ready
Probing TCP socket on 172.20.0.1:39082 of service 'avail-mgnt-app_1'
TCP socket on 172.20.0.1:39082 of service 'avail-mgnt-app_1' is ready
Probing TCP socket on 172.20.0.1:39083 of service 'api-gateway_1'
TCP socket on 172.20.0.1:39083 of service 'api-gateway_1' is ready
> Task :api-gateway:integrationTest
Executing command: curl -sX GET http://localhost:39081/hello
Hello, world
Connected to endpoint http://localhost:39081/hello
----------------------------------------------------------------------------------------
Executing command: curl -sX GET http://localhost:39082/hello
Hello, world
Connected to endpoint http://localhost:39082/hello
----------------------------------------------------------------------------------------
Executing command: curl -sX GET http://localhost:39083/hello
Hello, world
Connected to endpoint http://localhost:39083/hello
----------------------------------------------------------------------------------------
Executing command: curl -sX GET 'http://localhost:39083/management/trains/reload'
{"id":"9f8b3775-1db9-4b05-9f89-7903d85f853b","receivedTime":"2020-02-17T08:18:12.400+0000","status":"ACCEPTED"}
Executing command: curl -sX GET 'http://localhost:39083/management/trains/waitfor/9f8b3775-1db9-4b05-9f89-7903d85f853b'
{"id":"9f8b3775-1db9-4b05-9f89-7903d85f853b","receivedTime":"2020-02-17T08:18:42.660+0000","status":"COMPLETE"}
Executing command: curl -sX GET 'http://localhost:39083/customers/trains?trainDate=20190131&trainTime=2200&origin=EAR&dest=SUN'
[{"destinationStation":{"locationCode":"SUN"},"originStation":{"locationCode":"EAR"},"trainDate":"20190131","trainTime":"2202","train":{"trainNumber":"0684"},"classCodes":[{"code":"Y","quantity":0},{"code":"YF","quantity":0},{"code":"YV","quantity":0},{"code":"YW;","quantity":0}]},{"destinationStation":{"locationCode":"SUN"},"originStation":{"locationCode":"EAR"},"trainDate":"20190131","trainTime":"2232","train":{"trainNumber":"0160"},"classCodes":[{"code":"Y","quantity":0},{"code":"YF","quantity":0},{"code":"YV","quantity":0},{"code":"YW;","quantity":0}]},{"destinationStation":{"locationCode":"SUN"},"originStation":{"locationCode":"EAR"},"trainDate":"20190131","trainTime":"2242","train":{"trainNumber":"0858"},"classCodes":[{"code":"YA","quantity":0},{"code":"Y","quantity":0},{"code":"YB","quantity":0},{"code":"YF","quantity":0},{"code":"YV","quantity":0},{"code":"YW;","quantity":0}]},{"destinationStation":{"locationCode":"SUN"},"originStation":{"locationCode":"EAR"},"trainDate":"20190131","trainTime":"2307","train":{"trainNumber":"0690"},"classCodes":[{"code":"Y","quantity":0},{"code":"YF","quantity":0},{"code":"YV","quantity":0},{"code":"YW;","quantity":0}]},{"destinationStation":{"locationCode":"SUN"},"originStation":{"locationCode":"EAR"},"trainDate":"20190131","trainTime":"2347","train":{"trainNumber":"0862"},"classCodes":[{"code":"YA","quantity":0},{"code":"Y","quantity":0},{"code":"YB","quantity":0},{"code":"YF","quantity":0},{"code":"YV","quantity":0},{"code":"YW;","quantity":0}]},{"destinationStation":{"locationCode":"SUN"},"originStation":{"locationCode":"EAR"},"trainDate":"20190131","trainTime":"2352","train":{"trainNumber":"0294"},"classCodes":[{"code":"YA","quantity":0},{"code":"Y","quantity":0},{"code":"YB","quantity":0},{"code":"YF","quantity":0},{"code":"YV","quantity":0},{"code":"YW;","quantity":0}]}]
Total number of trains return: 6
> Task :api-gateway:composeDown
Stopping aa06e167b60ece271c3dc97464aed27fapigateway_api-gateway_1 ...
Stopping aa06e167b60ece271c3dc97464aed27fapigateway_avail-mgnt-app_1 ...
Stopping aa06e167b60ece271c3dc97464aed27fapigateway_avail-api-app_1 ...
Stopping aa06e167b60ece271c3dc97464aed27fapigateway_redis-solar-travel-pubsub_1 ...
Stopping aa06e167b60ece271c3dc97464aed27fapigateway_redis-solar-travel-availability_1 ...
Stopping aa06e167b60ece271c3dc97464aed27fapigateway_api-gateway_1 ... done
Stopping aa06e167b60ece271c3dc97464aed27fapigateway_avail-api-app_1 ... done
Stopping aa06e167b60ece271c3dc97464aed27fapigateway_avail-mgnt-app_1 ... done
Stopping aa06e167b60ece271c3dc97464aed27fapigateway_redis-solar-travel-pubsub_1 ... done
Stopping aa06e167b60ece271c3dc97464aed27fapigateway_redis-solar-travel-availability_1 ... done
Removing aa06e167b60ece271c3dc97464aed27fapigateway_api-gateway_1 ...
Removing aa06e167b60ece271c3dc97464aed27fapigateway_avail-mgnt-app_1 ...
Removing aa06e167b60ece271c3dc97464aed27fapigateway_avail-api-app_1 ...
Removing aa06e167b60ece271c3dc97464aed27fapigateway_redis-solar-travel-pubsub_1 ...
Removing aa06e167b60ece271c3dc97464aed27fapigateway_redis-solar-travel-availability_1 ...
Removing aa06e167b60ece271c3dc97464aed27fapigateway_redis-solar-travel-availability_1 ... done
Removing aa06e167b60ece271c3dc97464aed27fapigateway_avail-api-app_1 ... done
Removing aa06e167b60ece271c3dc97464aed27fapigateway_api-gateway_1 ... done
Removing aa06e167b60ece271c3dc97464aed27fapigateway_redis-solar-travel-pubsub_1 ... done
Removing aa06e167b60ece271c3dc97464aed27fapigateway_avail-mgnt-app_1 ... done
Removing network aa06e167b60ece271c3dc97464aed27fapigateway_default
Removing image aa06e167b60ece271c3dc97464aed27fapigateway_api-gateway
BUILD SUCCESSFUL in 1m 20s
6 actionable tasks: 3 executed, 3 up-to-date
~~~
# Jenkins Pipeline
~~~
def executeCmd(def cmd) {
def output = new StringBuffer();
println "Executing command: " + cmd
def process = ['bash', '-c', cmd].execute()
process.waitForProcessOutput(output, output)
if (process.exitValue() != 0) throw new Exception(output.toString())
println output.toString()
return output.toString()
}
"${BUILD_NUMBER}"
node {
stage('Clone sources') {
executeCmd "rm -r -f ${workspace}/${serviceName}"
executeCmd "git config --global user.name 'George Tsang'"
executeCmd "git config --global user.emai 'tsangcc@tw.ibm.com'"
withCredentials([string(credentialsId: 'jenkins-ibm-git-repo-key', variable: 'IBM_GIT_REPO_KEY')]) {
executeCmd "git clone --single-branch --branch $branch https://${IBM_GIT_REPO_KEY}@github.ibm.com/tsangcc/solar-travel-integration.git ${workspace}/${serviceName}"
}
//executeCmd "sudo chown -R jenkins:jenkins ${workspace}/avail-api-app"
}
stage('Compile and Test service application') {
dir("${WORKSPACE}/${serviceName}") {
def statusCode = sh label: '', returnStatus: true, script: './gradlew clean && ./gradlew ${serviceName}:build'
if (statusCode != 0) throw new Exception("Failed to build container image.")
}
}
stage('Build Container Image') {
dir("${WORKSPACE}/${serviceName}") {
def statusCode = sh label: '', returnStatus: true, script: './gradlew -PimageVersion=${imageVersion}.${BUILD_NUMBER}-${imageTagName} :${serviceName}:buildDockerImage'
if (statusCode != 0) throw new Exception("Failed to build container image.")
}
}
stage('Test Container Image') {
dir("${WORKSPACE}/${serviceName}") {
def statusCode = sh label: '', returnStatus: true, script: './gradlew -PimageVersion=${imageVersion}.${BUILD_NUMBER}-${imageTagName} :${serviceName}:testDockerImage'
if (statusCode != 0) throw new Exception("Failed to test container image.")
}
}
stage('Validate and Push Container Image') {
dir("${WORKSPACE}/${serviceName}") {
withCredentials([string(credentialsId: 'jenkins-docker-password', variable: 'dockerPassword')]) {
def statusCode = sh label: '', returnStatus: true, script: './gradlew -PimageVersion=${imageVersion}.${BUILD_NUMBER}-${imageTagName} -PdockerUser=gtsang -PdockerPassword=$dockerPassword -PdockerImageRegistryUrl=$DOCKER_IMAGE_REGISTRY_URL -PdockerImageNamespace=$DOCKER_IMAGE_NAMESPACE :${serviceName}:validateContainer'
if (statusCode != 0) throw new Exception("Failed to validate container image.")
}
}
}
stage('Deploy Container to OpenShift') {
dir("${WORKSPACE}/${serviceName}") {
withCredentials([string(credentialsId: 'jenkins-openshift-login-token', variable: 'token')]) {
executeCmd "oc login $ocHost --token=$token --insecure-skip-tls-verify"
}
def statusCode = sh label: '', returnStatus: true, script: './gradlew -PimageVersion=${imageVersion}.${BUILD_NUMBER}-${imageTagName} -Ptls-termination=edge -PocProjectName=$ocProjectName -PdockerImageRegistryUrl=$DOCKER_IMAGE_REGISTRY_URL -PdockerImageNamespace=$DOCKER_IMAGE_NAMESPACE :${serviceName}:deployContainer'
executeCmd "oc logout"
if (statusCode != 0) throw new Exception("Failed to deploy container")
}
}
}
~~~
## Jenkins Build with Parameters setting example

## Jenkins Build result
