Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
…nto fix/transient-task
  • Loading branch information
mpgxvii committed Apr 16, 2024
2 parents 9f673c4 + caa129b commit f45fc5c
Show file tree
Hide file tree
Showing 29 changed files with 527 additions and 168 deletions.
49 changes: 47 additions & 2 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
# Continuous integration, including test and integration test
name: CI

# Run in master and dev branches and in all pull requests to those branches
# Run in master and dev branches and in all pull requests to those branches, as well as on workflow dispatch for downstream testing
on:
workflow_dispatch:
push:
branches: [ master, dev ]
pull_request:
Expand Down Expand Up @@ -33,13 +34,15 @@ jobs:
- name: Compile code
run: ./gradlew assemble

# Use 'docker compose' instead of 'docker-compose' to use v2
- name: Setup docker services
run: |
sudo mkdir -p /usr/local/var/lib/radar/appserver/logs/
sudo chown -R $(whoami) /usr/local/var/lib/radar/appserver/logs
docker-compose -f src/integrationTest/resources/docker/docker-compose.yml up -d postgres managementportal
docker compose -f src/integrationTest/resources/docker/non_appserver/docker-compose.yml up -d
# Wait for services to start up.
sleep 50
- name: Install gpg secret key
run: |
cat <(echo -e "${{ secrets.GPG_SECRET_KEY }}") | gpg --batch --import
Expand All @@ -60,10 +63,52 @@ jobs:
if-no-files-found: ignore
retention-days: 5

# Build and test the code against the :dev docker image of parent repositories
test-downstream:
# The type of runner that the job will run on
runs-on: ubuntu-latest
# only run this on 'ready for review' PRs or when triggered by an upstream job
if: github.event.pull_request.draft == false || github.event_name == 'workflow_dispatch'

# Steps represent a sequence of tasks that will be executed as part of the job
steps:
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
- uses: actions/checkout@v3

- uses: actions/setup-java@v3
with:
java-version: 17
distribution: temurin

# Use 'docker compose' instead of 'docker-compose' to use v2
- name: Setup docker services (:dev)
run: |
sudo mkdir -p /usr/local/var/lib/radar/appserver/logs/
sudo chown -R $(whoami) /usr/local/var/lib/radar/appserver/logs
# call docker compose without args to include the override file
cd src/integrationTest/resources/docker/appserver_downstream
docker compose up -d
# Wait for services to start up.
sleep 50
- name: Install gpg secret key
run: |
cat <(echo -e "${{ secrets.GPG_SECRET_KEY }}") | gpg --batch --import
gpg --list-secret-keys --keyid-format LONG
- name: Decrypt google application credentials
run: |
gpg --pinentry-mode loopback --local-user "Yatharth Ranjan" --batch --yes --passphrase "${{ secrets.GPG_SECRET_KEY_PASSPHRASE }}" --output src/integrationTest/resources/google-credentials.json --decrypt src/integrationTest/resources/google-credentials.enc.gpg
# Gradle check
- name: Check
run: GOOGLE_APPLICATION_CREDENTIALS=$(pwd)/src/integrationTest/resources/google-credentials.json ./gradlew check

# Check that the docker image builds correctly
docker:
# The type of runner that the job will run on
runs-on: ubuntu-latest
if: github.event_name != 'workflow_dispatch'

# Steps represent a sequence of tasks that will be executed as part of the job
steps:
Expand Down
12 changes: 6 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,10 @@ The app server provides REST endpoints to interact with the entities and data. F
3.1. To use the standalone instance, run the database a docker service by

```bash
docker-compose -f src/integrationTest/resources/docker/docker-compose.yml up -d hsqldb
docker-compose -f src/integrationTest/resources/docker/non_appserver/docker-compose.yml up -d postgres
```

This will start the database at `localhost:9001`
This will start the database at `localhost:5432`

3.2. To use as an embedded in-memory database instance (Not recommended for production deployments), set the `spring.datasource.url=jdbc:hsqldb:mem:/appserver` in `application-<profile>.properties`. Also, change the properties in `src/main/resources/application.properties` to dev or prod according to your requirements.

Expand Down Expand Up @@ -152,7 +152,7 @@ The AppServer is also available as a docker container. Its [Dockerfile](/Dockerf
docker run -v /logs/:/var/log/radar/appserver/ \
-v etc/google-credentials.json:/etc/google-credentials.json \
-e "GOOGLE_APPLICATION_CREDENTIALS=/etc/google-credentials.json" \
radarbase/radar-appserver:0.0.1
radarbase/radar-appserver:1.1.0
```
Make sure to have the correct path to the google-credentials.json file.

Expand All @@ -179,7 +179,7 @@ The same can be achieved by running as a docker-compose service. Just specify th
SPRING_BOOT_ADMIN_CLIENT_INSTANCE_NAME: radar-appserver
```

An example `docker-compose` file with all the other components is provided in [integrationTest resources](/src/integrationTest/resources/docker/docker-compose.yml).
An example `docker-compose` file with all the other components is provided in [integrationTest resources](/src/integrationTest/resources/docker/appserver_dockerhub/docker-compose.yml).

## Architecture
Here is a high level architecture and data flow diagram for the AppServer and its example interaction with a Cordova application (hybrid) like the [RADAR-Questionnaire](https://github.com/RADAR-base/RADAR-Questionnaire).
Expand Down Expand Up @@ -407,13 +407,13 @@ To make this work,
spring.boot.admin.client".password = admin-server-password
```
The same can be achieved when deployed with the components as microservices in docker containers using docker-compose. The file [docker-compose.yml](/src/integrationTest/resources/docker/docker-compose.yml) in this project shows an example of how this is achieved.
The same can be achieved when deployed with the components as microservices in docker containers using docker-compose. The file [docker-compose.yml](/src/integrationTest/resources/docker/appserver_dockerhub/docker-compose.yml) in this project shows an example of how this is achieved.
Please note how the App server is configured in the container compared to the method of adding properties in `application.properties` file shown above.
Just run -
```bash
cd src/integrationTest/resources/docker/
cd src/integrationTest/resources/docker/appserver_dockerhub/
sudo docker-compose up -d
```
Expand Down
3 changes: 1 addition & 2 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ java {

repositories {
mavenCentral()
mavenLocal()
maven { url = "https://oss.sonatype.org/content/repositories/snapshots" }
}

Expand All @@ -39,7 +38,7 @@ ext {
springDocVersion = '2.2.0'
lombokVersion = '1.18.26'
junit5Version = '5.9.2'
radarSpringAuthVersion = '1.2.0'
radarSpringAuthVersion = '1.2.1'
springSecurityVersion = '6.0.2'
hibernateValidatorVersion = '8.0.0.Final'
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.springframework.web.client.ResourceAccessException;

@ExtendWith(SpringExtension.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
Expand Down Expand Up @@ -158,20 +159,23 @@ public void unauthorisedCreateNotificationsForUser() {
HttpEntity<FcmNotificationDto> notificationDtoHttpEntity =
new HttpEntity<>(fcmNotificationDto, HEADERS);

ResponseEntity<FcmNotificationDto> notificationDtoResponseEntity =
restTemplate.exchange(
createURLWithPort(
port,
ProjectEndpointAuthTest.PROJECT_PATH
+ UserEndpointAuthTest.DEFAULT_PROJECT
+ UserEndpointAuthTest.USER_PATH
+ DEFAULT_USER
+ NOTIFICATION_PATH),
HttpMethod.POST,
notificationDtoHttpEntity,
FcmNotificationDto.class);

assertEquals(HttpStatus.UNAUTHORIZED, notificationDtoResponseEntity.getStatusCode());
ResponseEntity<FcmNotificationDto> notificationDtoResponseEntity = null;
try {
notificationDtoResponseEntity =
restTemplate.exchange(
createURLWithPort(
port,
ProjectEndpointAuthTest.PROJECT_PATH
+ UserEndpointAuthTest.DEFAULT_PROJECT
+ UserEndpointAuthTest.USER_PATH
+ DEFAULT_USER
+ NOTIFICATION_PATH),
HttpMethod.POST,
notificationDtoHttpEntity,
FcmNotificationDto.class);
} catch (ResourceAccessException e) {
assertEquals(notificationDtoResponseEntity, null);
}
}

@Test
Expand Down Expand Up @@ -295,4 +299,4 @@ public void forbiddenViewNotificationsForOtherProject() {

assertEquals(HttpStatus.UNAUTHORIZED, notificationDtoResponseEntity.getStatusCode());
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,12 @@
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.springframework.web.client.ResourceAccessException;

@ExtendWith(SpringExtension.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@TestMethodOrder(OrderAnnotation.class)
@SuppressWarnings("PMD.DataflowAnomalyAnalysis")
public class ProjectEndpointAuthTest {

public static final String PROJECT_PATH = "/projects";
Expand All @@ -70,13 +72,17 @@ public void unauthorisedCreateProject() {
ProjectDto projectDto = new ProjectDto().setProjectId("radar");
HttpEntity<ProjectDto> projectEntity = new HttpEntity<>(projectDto, HEADERS);

ResponseEntity<ProjectDto> responseEntity =
restTemplate.exchange(
createURLWithPort(port, PROJECT_PATH),
HttpMethod.POST,
projectEntity,
ProjectDto.class);
assertEquals(HttpStatus.UNAUTHORIZED, responseEntity.getStatusCode());
ResponseEntity<ProjectDto> responseEntity = null;
try {
responseEntity =
restTemplate.exchange(
createURLWithPort(port, PROJECT_PATH),
HttpMethod.POST,
projectEntity,
ProjectDto.class);
} catch (ResourceAccessException e) {
assertEquals(responseEntity, null);
}
}

@Test
Expand Down Expand Up @@ -167,4 +173,4 @@ public void getForbiddenProjectWithAuth() {
// Access denied as the user has only access to the project that it is part of.
assertEquals(HttpStatus.FORBIDDEN, responseEntity.getStatusCode());
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.springframework.web.client.ResourceAccessException;

@ExtendWith(SpringExtension.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
Expand Down Expand Up @@ -109,15 +110,18 @@ public void unauthorisedViewSingleUser() {
public void unauthorisedCreateUser() {
HttpEntity<FcmUserDto> userDtoHttpEntity = new HttpEntity<>(userDto, HEADERS);

ResponseEntity<FcmUserDto> responseEntity =
restTemplate.exchange(
createURLWithPort(
port, ProjectEndpointAuthTest.PROJECT_PATH + DEFAULT_PROJECT + USER_PATH),
HttpMethod.POST,
userDtoHttpEntity,
FcmUserDto.class);

assertEquals(HttpStatus.UNAUTHORIZED, responseEntity.getStatusCode());
ResponseEntity<FcmUserDto> responseEntity = null;
try {
responseEntity =
restTemplate.exchange(
createURLWithPort(
port, ProjectEndpointAuthTest.PROJECT_PATH + DEFAULT_PROJECT + USER_PATH),
HttpMethod.POST,
userDtoHttpEntity,
FcmUserDto.class);
} catch (ResourceAccessException e) {
assertEquals(responseEntity, null);
}
}

@Test
Expand Down Expand Up @@ -202,4 +206,4 @@ public void viewAllUsers() {
// This should return a filtered list of users for which the token has access.
assertEquals(HttpStatus.OK, responseEntity.getStatusCode());
}
}
}
4 changes: 2 additions & 2 deletions src/integrationTest/resources/application.properties
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ spring.jpa.hibernate.ddl-auto=none
spring.datasource.username=postgres
spring.datasource.password=radar
spring.datasource.url=jdbc:postgresql://localhost:5432/radar
#jdbc:hsqldb:hsql://localhost:9001/appserver for running hsql separately in dev or testing
# jdbc:hsqldb:hsql://localhost:9001/appserver for running hsql separately in dev or testing
spring.jpa.properties.hibernate.jdbc.time_zone=UTC
spring.jpa.properties.hibernate.generate_statistics=false
spring.jpa.properties.hibernate.jdbc.batch_size=20
Expand Down Expand Up @@ -87,7 +87,7 @@ spring.datasource.hikari.leakDetectionThreshold=120000
# OAuth2 Resource Server Security
security.oauth2.resource.id=res_AppServer
security.radar.managementportal.enabled=true
security.radar.managementportal.url=http://localhost:8081
security.radar.managementportal.url=http://localhost:8081/managementportal
# OAuth2 Client Security
#security.oauth2.client.clientId=
#security.oauth2.client.clientSecret=
Expand Down
22 changes: 22 additions & 0 deletions src/integrationTest/resources/docker/appserver.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
version: "3.8"

services:
appserver:
image: radarbase/radar-appserver
build: ../../../..
restart: always
ports:
- "8080:8080"
volumes:
- ../radar-is.yml:/resources/radar-is.yml
- ../../../../logs/:/var/log/radar/appserver/
environment:
JDK_JAVA_OPTIONS: -Xmx4G -Djava.security.egd=file:/dev/./urandom
FCMSERVER_SENDERID: "1043784930865"
FCMSERVER_SERVERKEY: "AAAA8wZuFjE:APA91bGpJQ3Sft0mZAaVMjDJGNLjFsdDLTo-37ZN69r4lKlHiRN78t4bCfkNKcXG5c9cJg-eGtWB7FqceQUDVtf7B1Zvw_2ycynqwKe2YqXFeyaq83Gf0R3AS1EKSWFS60GCr8eUEliz"
RADAR_ADMIN_USER: "radar"
RADAR_ADMIN_PASSWORD: "radar"
SPRING_APPLICATION_JSON: '{"spring":{"boot":{"admin":{"client":{"url":"http://spring-boot-admin:1111","username":"radar","password":"appserver"}}}}}'
RADAR_IS_CONFIG_LOCATION: "/resources/radar-is.yml"
SPRING_BOOT_ADMIN_CLIENT_INSTANCE_NAME: radar-appserver
SPRING_DATASOURCE_URL: jdbc:postgresql://postgres:5432/radar
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# start the dockerstack using a prebuilt image pulled from dockerhub. This stack does not work without adding GOOGLE_APPLICATION_CREDENTIALS
version: "3.8"

include:
- "../non_appserver/docker-compose.yml"

services:
appserver:
extends:
file: ../appserver.yml
service: appserver
networks:
- db
- default
- admin
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
version: "3.8"

services:
managementportal:
extends:
file: ../managementportal.yml
service: managementportal
image: radarbase/management-portal:dev
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# start the supporting dockerstack using the :dev image of the managementportal dependency.
version: "3.8"

include:
- "../non_appserver/docker-compose.yml"

# This file should be called in conjunction with the accompanying docker-compose.override.yml file
# This can be done by navigating to the directory with both files and calling 'docker compose up -d'
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# start the dockerstack using a locally built docker image of the appserver. This stack does not work without adding GOOGLE_APPLICATION_CREDENTIALS
version: "3.8"

include:
- "../non_appserver/docker-compose.yml"

services:
appserver:
extends:
file: ../appserver.yml
service: appserver
image: appserver
networks:
- db
- default
- admin
Loading

0 comments on commit f45fc5c

Please sign in to comment.