Skip to content

Commit

Permalink
Merge pull request #30 from ga4gh/feature/issue-28-dockerize
Browse files Browse the repository at this point in the history
dockerize app and test dockerized service
  • Loading branch information
Jeremy Adams authored Mar 25, 2022
2 parents 2a9a221 + 7c7ffb6 commit 7d5d347
Show file tree
Hide file tree
Showing 25 changed files with 741 additions and 29 deletions.
58 changes: 58 additions & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,61 @@ jobs:
run: | #jacocoTestReport is for testing code coverage, submits the last report to the link
./gradlew jacocoTestReport
bash <(curl -s https://codecov.io/bash)
Docker-Test:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2

- name: Setup Gradle
uses: gradle/gradle-build-action@v2

- name: Setup Docker Buildx
id: buildx
uses: docker/setup-buildx-action@v1

- name: Docker Hub Login
uses: docker/login-action@v1
with:
username: ${{ secrets.DOCKER_HUB_USERNAME }}
password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }}

- name: Set Docker Image Version
run: |
source ci/set-docker-image-version.sh
echo "version=${DOCKER_IMG_VER}" >> $GITHUB_ENV
- name: Build Docker Image
uses: docker/build-push-action@v2
with:
context: .
builder: ${{ steps.buildx.outputs.name }}
push: true
tags: ga4gh/ga4gh-testbed-api:test
build-args: VERSION=${{ env.version }}
cache-from: type=gha #GitHub Actions Cache Exporter
cache-to: type=gha,mode=max

- name: Start Services
run: docker-compose up -d

- name: Service Health Check
uses: jtalk/url-health-check-action@v2
with:
url: http://localhost:4500/reports
follow-redirect: false
max-attempts: 6
retry-delay: 10s
retry-all: true

# - name: Setup upterm session # Using Github - SSH for debugging
# uses: lhotari/action-upterm@v1
# with:
# ## limits ssh access and adds the ssh public key for the user which triggered the workflow
# limit-access-to-actor: true
# ## limits ssh access and adds the ssh public keys of the listed GitHub users
# limit-access-to-users: jb-adams

- name: Docker Test
run: ./gradlew test --tests=docker.*
64 changes: 64 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
##################################################
# BUILDER CONTAINER
##################################################

FROM openjdk:11.0.12 as builder

USER root

WORKDIR /usr/src/dependencies

# INSTALL MAKE
RUN apt update \
&& apt install build-essential -y

# INSTALL SQLITE3
RUN wget https://www.sqlite.org/2021/sqlite-autoconf-3340100.tar.gz \
&& tar -zxf sqlite-autoconf-3340100.tar.gz \
&& cd sqlite-autoconf-3340100 \
&& ./configure \
&& make \
&& make install

# USER 'make' and 'sqlite3' to create the dev database
COPY Makefile Makefile
COPY database/sqlite database/sqlite
RUN make sqlite-db-refresh

##################################################
# GRADLE CONTAINER
##################################################

FROM gradle:7.3.3-jdk11 as gradleimage

WORKDIR /home/gradle/source

COPY build.gradle build.gradle
COPY gradlew gradlew
COPY settings.gradle settings.gradle
COPY src src

RUN gradle wrapper

RUN ./gradlew bootJar

##################################################
# FINAL CONTAINER
##################################################

FROM adoptopenjdk/openjdk12:jre-12.0.2_10-alpine

USER root

ARG VERSION

WORKDIR /usr/src/app

# copy jar, dev db, and dev resource files
COPY --from=gradleimage /home/gradle/source/build/libs/ga4gh-testbed-api-${VERSION}.jar ga4gh-testbed-api.jar
COPY --from=builder /usr/src/dependencies/ga4gh-testbed-api.dev.db ga4gh-testbed-api.dev.db
COPY src/test/resources/ src/test/resources/

RUN chmod 666 ga4gh-testbed-api.dev.db

ENTRYPOINT ["java", "-jar", "ga4gh-testbed-api.jar"]
8 changes: 7 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
DOCKER_ORG := ga4gh
DOCKER_REPO := ga4gh-testbed-api
DOCKER_TAG := 0.1.0
DOCKER_TAG := $(shell cat build.gradle | grep "^version" | cut -f 2 -d ' ' | sed "s/'//g")
DOCKER_IMG := ${DOCKER_ORG}/${DOCKER_REPO}:${DOCKER_TAG}
DEVDB := ga4gh-testbed-api.dev.db

Expand Down Expand Up @@ -47,4 +47,10 @@ sqlite-db-populate-dev-dataset:
.PHONY: sqlite-db-refresh
sqlite-db-refresh: clean-sqlite sqlite-db-build sqlite-db-populate-dev-dataset

.PHONY: docker-build
docker-build:
docker build -t ${DOCKER_IMG} --build-arg VERSION=${DOCKER_TAG} .

.PHONY: docker-build-test
docker-build-test:
docker build -t ga4gh/ga4gh-testbed-api:test --build-arg VERSION=${DOCKER_TAG} .
4 changes: 2 additions & 2 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ plugins {
}

archivesBaseName = 'ga4gh-testbed-api'
group = 'org.ga4gh'
version = '0.1.0'
group 'org.ga4gh'
version '0.1.0'

repositories {
// Use jcenter for resolving dependencies.
Expand Down
1 change: 1 addition & 0 deletions ci/set-docker-image-version.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export DOCKER_IMG_VER=`cat build.gradle | grep "^version" | cut -f 2 -d ' ' | sed "s/'//g"`
4 changes: 4 additions & 0 deletions database/postgresql/add-dev-dataset.sql
Original file line number Diff line number Diff line change
Expand Up @@ -76,10 +76,14 @@ insert into specification_platform values

insert into report_series values (
'1edb5213-52a2-434f-a7b8-b101fea8fb30',
'k4A2I1FUJrbpN70v4FXrrAqwvcamnZyB',
'dcaa1ff102a989efeaebef66e950216d86160303689120e9e76d88d4a70bd003', /* plaintext token is K5pLbwScVu8rEoLLj8pRy5Wv7EXTVahn */
'refget-compliance',
'org.ga4gh.refget.starterkit'
),(
'483382e9-f92b-466d-9427-154d56a75fcf',
'JQhtM8FvjgaQaNbxTFbawJTWFjbdiiSL',
'463bdadca28c206693339fcc5465c9885395a7e03deff93ce1e851c5561bae36', /* plaintext token is l0HiRbbpjVDKc6k3tQ2skzROB1oAP2IV */
'rnaget-compliance',
'org.ga4gh.rnaget.starterkit'
);
Expand Down
2 changes: 2 additions & 0 deletions database/postgresql/create-tables.sql
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,8 @@ CREATE TABLE IF NOT EXISTS summary
CREATE TABLE IF NOT EXISTS report_series
(
id text PRIMARY KEY,
token_salt text NOT NULL,
token_hash text NOT NULL,
fk_testbed_id text NOT NULL,
fk_platform_id text NOT NULL,
foreign key (fk_testbed_id) references testbed(id),
Expand Down
4 changes: 4 additions & 0 deletions database/sqlite/add-dev-dataset.sql
Original file line number Diff line number Diff line change
Expand Up @@ -76,10 +76,14 @@ insert into specification_platform values

insert into report_series values (
"1edb5213-52a2-434f-a7b8-b101fea8fb30",
'k4A2I1FUJrbpN70v4FXrrAqwvcamnZyB',
'dcaa1ff102a989efeaebef66e950216d86160303689120e9e76d88d4a70bd003', /* plaintext token is K5pLbwScVu8rEoLLj8pRy5Wv7EXTVahn */
'refget-compliance',
'org.ga4gh.refget.starterkit'
),(
"483382e9-f92b-466d-9427-154d56a75fcf",
'JQhtM8FvjgaQaNbxTFbawJTWFjbdiiSL',
'463bdadca28c206693339fcc5465c9885395a7e03deff93ce1e851c5561bae36', /* plaintext token is l0HiRbbpjVDKc6k3tQ2skzROB1oAP2IV */
'rnaget-compliance',
'org.ga4gh.rnaget.starterkit'
);
Expand Down
2 changes: 2 additions & 0 deletions database/sqlite/create-tables.sql
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,8 @@ CREATE TABLE IF NOT EXISTS summary
CREATE TABLE IF NOT EXISTS report_series
(
id text PRIMARY KEY,
token_salt text NOT NULL,
token_hash text NOT NULL,
fk_testbed_id text NOT NULL,
fk_platform_id text NOT NULL,
foreign key (fk_testbed_id) references testbed(id),
Expand Down
7 changes: 7 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
version: "3.9"
services:
testbed-api:
image: ga4gh/ga4gh-testbed-api:test
hostname: testbed.ga4gh.org
ports:
- "4500:4500"
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
import org.ga4gh.testbed.api.utils.hibernate.TestbedApiHibernateUtil;
import org.ga4gh.testbed.api.utils.logging.TestbedLoggingUtil;
import org.ga4gh.testbed.api.utils.requesthandler.report.CreateReportHandler;
import org.ga4gh.testbed.api.utils.requesthandler.report.DeleteReportHandler;
import org.ga4gh.testbed.api.utils.requesthandler.report.ShowReportHandler;
import org.ga4gh.testbed.api.utils.secretmanager.AwsSecretManagerUtil;
import org.springframework.beans.factory.annotation.Autowired;
Expand Down Expand Up @@ -230,6 +231,12 @@ public CreateReportHandler createReportHandler() {
return new CreateReportHandler();
}

@Bean
@RequestScope
public DeleteReportHandler deleteReportHandler() {
return new DeleteReportHandler();
}

@Bean
@RequestScope
public BasicShowRequestHandler<String, ReportSeries> showReportSeriesHandler(
Expand Down
15 changes: 15 additions & 0 deletions src/main/java/org/ga4gh/testbed/api/controller/Reports.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@
import org.ga4gh.testbed.api.utils.SerializeView;
import org.ga4gh.testbed.api.utils.hibernate.TestbedApiHibernateUtil;
import org.ga4gh.testbed.api.utils.requesthandler.report.CreateReportHandler;
import org.ga4gh.testbed.api.utils.requesthandler.report.DeleteReportHandler;
import org.ga4gh.testbed.api.utils.requesthandler.report.ShowReportHandler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
Expand All @@ -29,6 +31,9 @@ public class Reports {
@Autowired
private CreateReportHandler createReport;

@Autowired
private DeleteReportHandler deleteReport;

@GetMapping
@JsonView(SerializeView.ReportSimple.class)
public List<Report> getReports() {
Expand All @@ -52,4 +57,14 @@ public Report postReport(
) throws Exception {
return createReport.prepare(reportSeriesId, reportSeriesToken, report).handleRequest();
}

@DeleteMapping("/{reportId:.+}")
@JsonView(SerializeView.ReportFull.class)
public Report deleteReport(
@PathVariable String reportId,
@RequestHeader("GA4GH-TestbedReportSeriesId") String reportSeriesId,
@RequestHeader("GA4GH-TestbedReportSeriesToken") String reportSeriesToken
) throws Exception {
return deleteReport.prepare(reportId, reportSeriesId, reportSeriesToken).handleRequest();
}
}
8 changes: 8 additions & 0 deletions src/main/java/org/ga4gh/testbed/api/model/ReportSeries.java
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,14 @@ public class ReportSeries implements HibernateEntity<String> {
@JsonView(SerializeView.Always.class)
private String id;

@Column(name = "token_salt", nullable = false)
@JsonView(SerializeView.Never.class)
private String tokenSalt;

@Column(name = "token_hash", nullable = false)
@JsonView(SerializeView.Never.class)
private String tokenHash;

@ManyToOne(fetch = FetchType.EAGER,
cascade = {CascadeType.PERSIST, CascadeType.MERGE,
CascadeType.DETACH, CascadeType.REFRESH})
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
package org.ga4gh.testbed.api.utils.requesthandler.report;

import java.util.HashMap;
import java.util.UUID;

import org.apache.commons.codec.digest.DigestUtils;
import org.ga4gh.starterkit.common.exception.ConflictException;
import org.ga4gh.starterkit.common.exception.ResourceNotFoundException;
Expand All @@ -25,7 +23,7 @@ public class CreateReportHandler extends BasicCreateRequestHandler<String, Repor
private String reportSeriesId;
private String reportSeriesToken;
private Report report;
private static final String TESTBED_TOKENS_SECRET_NAME = "ga4gh-testbed-reportseries-tokens";
// private static final String TESTBED_TOKENS_SECRET_NAME = "ga4gh-testbed-reportseries-tokens";

@Autowired
TestbedApiHibernateUtil hibernateUtil;
Expand Down Expand Up @@ -53,20 +51,29 @@ public Report handleRequest() {
}
report.setReportSeries(reportSeries);

// get the token salt and token hash from AWS SM
HashMap<String, String> tokenMap;
try {
tokenMap = awsSecretManagerUtil.retrieveSecret(TESTBED_TOKENS_SECRET_NAME);
} catch(Exception ex){
// TODO: log the original exception message
throw new ResourceNotFoundException(String.format("Retrieval of token salt and hash failed for report series id: %s",reportSeriesId));
}
String tokenSalt = tokenMap.get("token-salt-"+reportSeriesId);
String tokenHash = tokenMap.get("token-hash-"+reportSeriesId);
if (tokenSalt == null || tokenHash == null){
// TODO: log this
System.err.println(String.format("token salt or token hash is not available in the secret manager for report series id: %s",reportSeriesId) );
// first, look up the db for token salt and hash
String tokenSalt = reportSeries.getTokenSalt();
String tokenHash = reportSeries.getTokenHash();

/*
if (tokenSalt == null || tokenHash == null) {
// AWS SECRET MANAGER
// get the token salt and token hash from AWS SM
HashMap<String, String> tokenMap;
try {
tokenMap = awsSecretManagerUtil.retrieveSecret(TESTBED_TOKENS_SECRET_NAME);
} catch(Exception ex){
// TODO: log the original exception message
throw new ResourceNotFoundException(String.format("Retrieval of token salt and hash failed for report series id: %s",reportSeriesId));
}
tokenSalt = tokenMap.get("token-salt-"+reportSeriesId);
tokenHash = tokenMap.get("token-hash-"+reportSeriesId);
if (tokenSalt == null || tokenHash == null){
// TODO: log this
System.err.println(String.format("token salt or token hash is not available in the secret manager for report series id: %s",reportSeriesId) );
}
}
*/

// calculate the input token hash based on input token and salt
// compare the input token hash to the report series's token hash in the AWS SM
Expand Down
Loading

0 comments on commit 7d5d347

Please sign in to comment.