Skip to content

Commit c57dd42

Browse files
Merge branch 'main' into NIAD-3393
2 parents 71364c3 + 7208505 commit c57dd42

File tree

7 files changed

+222
-59
lines changed

7 files changed

+222
-59
lines changed

.github/workflows/release.yml

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,18 @@
11
on:
2-
push:
3-
tags: "*"
2+
release:
3+
types: [published]
44

55
jobs:
66
push_to_dockerhub:
77
strategy:
88
matrix:
9-
image:
10-
- {folder: service, dockerhub_name: nia-gp2gp-adaptor}
9+
config:
10+
- folder: service
11+
dockerhub_name: nia-gp2gp-adaptor
12+
upload_url: ${{ github.event.release.upload_url }}
1113
uses: NHSDigital/integration-adaptor-actions/.github/workflows/release-adaptor-container-image.yml@main
1214
with:
13-
dockerhub_name: ${{matrix.image.dockerhub_name}}
14-
folder: ${{matrix.image.folder}}
15-
15+
folder: ${{ matrix.config.folder }}
16+
dockerhub_name: ${{ matrix.config.dockerhub_name }}
17+
upload_url: ${{ matrix.config.upload_url }}
1618
secrets: inherit

e2e-tests/build.gradle

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,17 +16,18 @@ dependencies {
1616
implementation 'org.apache.qpid:qpid-jms-client:2.7.0'
1717
implementation "org.apache.geronimo.specs:geronimo-jms_1.1_spec:1.1.1"
1818
implementation 'org.mongodb:mongo-java-driver:3.12.14'
19+
testImplementation(platform('org.junit:junit-bom:5.13.4'))
20+
testImplementation 'org.junit.jupiter:junit-jupiter'
1921
testImplementation 'com.fasterxml.jackson.core:jackson-databind:2.19.2'
2022
testImplementation 'com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.19.2'
2123
testImplementation 'commons-io:commons-io:2.20.0'
2224
testImplementation 'org.awaitility:awaitility:4.3.0'
23-
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.11.4'
2425
testImplementation "org.assertj:assertj-core:3.27.4"
2526
testImplementation 'ch.qos.logback:logback-classic:1.5.18'
2627
testImplementation 'org.xmlunit:xmlunit-assertj3:2.10.3'
2728
testImplementation 'org.apache.httpcomponents.client5:httpclient5:5.5'
2829

29-
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.11.4'
30+
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
3031
}
3132

3233
tasks.withType(Test) {

scripts/config/.syft.yaml

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
# a list of globs to exclude from scanning. same as --exclude ; for example:
2+
# exclude:
3+
# - "/etc/**"
4+
# - "./out/**/*.json"
5+
exclude:
6+
- ./.git/**
7+
8+
# maximum number of workers used to process the list of package catalogers in parallel
9+
parallelism: 3
10+
11+
# cataloging packages is exposed through the packages and power-user subcommands
12+
package:
13+
# search within archives that do contain a file index to search against (zip)
14+
# note: for now this only applies to the java package cataloger
15+
# SYFT_PACKAGE_SEARCH_INDEXED_ARCHIVES env var
16+
search-indexed-archives: true
17+
# search within archives that do not contain a file index to search against (tar, tar.gz, tar.bz2, etc)
18+
# note: enabling this may result in a performance impact since all discovered compressed tars will be decompressed
19+
# note: for now this only applies to the java package cataloger
20+
# SYFT_PACKAGE_SEARCH_UNINDEXED_ARCHIVES env var
21+
search-unindexed-archives: true
22+
cataloger:
23+
# enable/disable cataloging of packages
24+
# SYFT_PACKAGE_CATALOGER_ENABLED env var
25+
enabled: true
26+
# the search space to look for packages (options: all-layers, squashed)
27+
# same as -s ; SYFT_PACKAGE_CATALOGER_SCOPE env var
28+
scope: "squashed"
29+
30+
# cataloging file contents is exposed through the power-user subcommand
31+
file-contents:
32+
cataloger:
33+
# enable/disable cataloging of secrets
34+
# SYFT_FILE_CONTENTS_CATALOGER_ENABLED env var
35+
enabled: true
36+
# the search space to look for secrets (options: all-layers, squashed)
37+
# SYFT_FILE_CONTENTS_CATALOGER_SCOPE env var
38+
scope: "squashed"
39+
# skip searching a file entirely if it is above the given size (default = 1MB; unit = bytes)
40+
# SYFT_FILE_CONTENTS_SKIP_FILES_ABOVE_SIZE env var
41+
skip-files-above-size: 1048576
42+
# file globs for the cataloger to match on
43+
# SYFT_FILE_CONTENTS_GLOBS env var
44+
globs: []
45+
46+
# cataloging file metadata is exposed through the power-user subcommand
47+
file-metadata:
48+
cataloger:
49+
# enable/disable cataloging of file metadata
50+
# SYFT_FILE_METADATA_CATALOGER_ENABLED env var
51+
enabled: true
52+
# the search space to look for file metadata (options: all-layers, squashed)
53+
# SYFT_FILE_METADATA_CATALOGER_SCOPE env var
54+
scope: "squashed"
55+
# the file digest algorithms to use when cataloging files (options: "sha256", "md5", "sha1")
56+
# SYFT_FILE_METADATA_DIGESTS env var
57+
digests: ["sha256"]
58+
59+
# cataloging secrets is exposed through the power-user subcommand
60+
secrets:
61+
cataloger:
62+
# enable/disable cataloging of secrets
63+
# SYFT_SECRETS_CATALOGER_ENABLED env var
64+
enabled: true
65+
# the search space to look for secrets (options: all-layers, squashed)
66+
# SYFT_SECRETS_CATALOGER_SCOPE env var
67+
scope: "all-layers"
68+
# show extracted secret values in the final JSON report
69+
# SYFT_SECRETS_REVEAL_VALUES env var
70+
reveal-values: false
71+
# skip searching a file entirely if it is above the given size (default = 1MB; unit = bytes)
72+
# SYFT_SECRETS_SKIP_FILES_ABOVE_SIZE env var
73+
skip-files-above-size: 1048576
74+
# name-regex pairs to consider when searching files for secrets. Note: the regex must match single line patterns
75+
# but may also have OPTIONAL multiline capture groups. Regexes with a named capture group of "value" will
76+
# use the entire regex to match, but the secret value will be assumed to be entirely contained within the
77+
# "value" named capture group.
78+
additional-patterns: {}
79+
# names to exclude from the secrets search, valid values are: "aws-access-key", "aws-secret-key", "pem-private-key",
80+
# "docker-config-auth", and "generic-api-key". Note: this does not consider any names introduced in the
81+
# "secrets.additional-patterns" config option.
82+
# SYFT_SECRETS_EXCLUDE_PATTERN_NAMES env var
83+
exclude-pattern-names: []

scripts/sbom-generator.sh

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
#!/bin/bash
2+
3+
set -e
4+
5+
# Script to generate SBOM (Software Bill of Materials) for the repository
6+
# content and any artefact created by the CI/CD pipeline.
7+
#
8+
# Usage:
9+
# $ ./generate-sbom.sh
10+
#
11+
# Options:
12+
# VERBOSE=true # Show all the executed commands, default is `false`
13+
14+
# ==============================================================================
15+
16+
# SEE: https://github.com/anchore/syft/pkgs/container/syft, use the `linux/amd64` os/arch
17+
image_version=v0.84.1@sha256:9a8f80eee3984d4a3f9a86e4d66e739e30dfc34564d76d3574f98798db5d5b35
18+
19+
# ==============================================================================
20+
21+
function main() {
22+
echo $BUILD_SOURCESIRECTORY
23+
create-sbom
24+
enrich-sbom
25+
}
26+
27+
function create-sbom() {
28+
29+
docker run --rm --platform linux/amd64 \
30+
--volume $PWD:/scan \
31+
--workdir /scan \
32+
ghcr.io/anchore/syft:$image_version \
33+
packages dir:/scan \
34+
--config /scan/scripts/config/.syft.yaml \
35+
--output spdx-json=/scan/sbom-spdx.tmp.json
36+
}
37+
38+
function enrich-sbom() {
39+
40+
git_url=$(git config --get remote.origin.url)
41+
git_branch=$(git rev-parse --abbrev-ref HEAD)
42+
git_commit_hash=$(git rev-parse HEAD)
43+
git_tags=$(echo \"$(git tag | tr '\n' ',' | sed 's/,$//' | sed 's/,/","/g')\" | sed 's/""//g')
44+
pipeline_run_id=${BUILD_BUILDID:-0}
45+
pipeline_run_number=${BUILD_BUILDNUMBER:-0}
46+
pipeline_run_attempt=${GITHUB_RUN_ATTEMPT:-0}
47+
echo "pipeline_run_attempt: ${pipeline_run_id}"
48+
docker run --rm --platform linux/amd64 \
49+
--volume $PWD:/repo \
50+
--workdir /repo \
51+
ghcr.io/make-ops-tools/jq:latest \
52+
'.creationInfo |= . + {"repository":{"url":"'${git_url}'","branch":"'${git_branch}'","tags":['${git_tags}'],"commitHash":"'${git_commit_hash}'"},"pipeline":{"id":'${pipeline_run_id}',"number":'${pipeline_run_number}',"attempt":'${pipeline_run_attempt}'}}' \
53+
sbom-spdx.tmp.json \
54+
> sbom-spdx.json
55+
rm -f sbom-spdx.tmp.json
56+
}
57+
58+
function is_arg_true() {
59+
60+
if [[ "$1" =~ ^(true|yes|y|on|1|TRUE|YES|Y|ON)$ ]]; then
61+
return 0
62+
else
63+
return 1
64+
fi
65+
}
66+
67+
# ==============================================================================
68+
69+
is_arg_true "$VERBOSE" && set -x
70+
71+
main $*
72+
73+
exit 0

service/build.gradle

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,8 @@ dependencies {
7171
testImplementation 'org.testcontainers:junit-jupiter:1.21.3'
7272
testImplementation 'org.awaitility:awaitility:4.3.0'
7373
testImplementation 'org.wiremock:wiremock-standalone:3.13.1'
74-
testImplementation 'com.squareup.okhttp3:okhttp:4.12.0'
75-
testImplementation 'com.squareup.okhttp3:mockwebserver:4.12.0'
74+
testImplementation 'com.squareup.okhttp3:okhttp:5.1.0'
75+
testImplementation 'com.squareup.okhttp3:mockwebserver3:5.1.0'
7676
testImplementation 'com.adobe.testing:s3mock-testcontainers:4.7.0'
7777

7878
pitest 'com.arcmutate:base:1.3.2'

service/src/intTest/java/uk/nhs/adaptors/gp2gp/gpc/GpcWebClientTest.java

Lines changed: 22 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,12 @@
1313
import java.util.ArrayList;
1414
import java.util.Collection;
1515
import java.util.Objects;
16+
import java.util.concurrent.TimeUnit;
1617
import java.util.concurrent.TimeoutException;
1718

19+
import mockwebserver3.MockResponse;
20+
import mockwebserver3.MockWebServer;
21+
1822
import org.junit.jupiter.api.AfterEach;
1923
import org.junit.jupiter.api.BeforeEach;
2024
import org.junit.jupiter.api.Test;
@@ -27,9 +31,6 @@
2731
import org.springframework.test.context.bean.override.mockito.MockitoSpyBean;
2832
import org.springframework.test.context.junit.jupiter.SpringExtension;
2933

30-
import okhttp3.mockwebserver.MockResponse;
31-
import okhttp3.mockwebserver.MockWebServer;
32-
import okhttp3.mockwebserver.SocketPolicy;
3334
import uk.nhs.adaptors.gp2gp.common.exception.RetryLimitReachedException;
3435
import uk.nhs.adaptors.gp2gp.gpc.builder.GpcTokenBuilder;
3536
import uk.nhs.adaptors.gp2gp.gpc.configuration.GpcConfiguration;
@@ -69,33 +70,30 @@ public class GpcWebClientTest {
6970
private GpcClient gpcWebClient;
7071

7172
private static MockResponse initialiseOKResponse() {
72-
MockResponse response = new MockResponse();
73-
response.setResponseCode(OK.value())
74-
.setBody(TEST_BODY);
75-
76-
return response;
73+
return new MockResponse.Builder()
74+
.code(OK.value())
75+
.body(TEST_BODY)
76+
.build();
7777
}
7878

7979
private static MockResponse initialise500Response() {
80-
MockResponse response = new MockResponse();
81-
response.setResponseCode(INTERNAL_SERVER_ERROR.value());
82-
response.setBody(TEST_BODY);
83-
84-
return response;
80+
return new MockResponse.Builder()
81+
.code(INTERNAL_SERVER_ERROR.value())
82+
.body(TEST_BODY)
83+
.build();
8584
}
8685

8786
private static MockResponse initialise500ResponseNoBody() {
88-
MockResponse response = new MockResponse();
89-
response.setResponseCode(INTERNAL_SERVER_ERROR.value());
90-
91-
return response;
87+
return new MockResponse.Builder()
88+
.code(INTERNAL_SERVER_ERROR.value())
89+
.build();
9290
}
9391

9492
private static MockResponse initialiseNoResponse() {
95-
MockResponse response = new MockResponse();
96-
response.setSocketPolicy(SocketPolicy.NO_RESPONSE);
97-
98-
return response;
93+
return new MockResponse.Builder()
94+
.bodyDelay(1, TimeUnit.HOURS)
95+
.headersDelay(1, TimeUnit.HOURS)
96+
.build();
9997
}
10098

10199
@BeforeEach
@@ -107,8 +105,8 @@ public void initialise() throws IOException {
107105
}
108106

109107
@AfterEach
110-
public void tearDown() throws IOException {
111-
mockWebServer.shutdown();
108+
public void tearDown() {
109+
mockWebServer.close();
112110
}
113111

114112
@Test
@@ -254,7 +252,7 @@ void When_GetStructuredRecord_With_HttpStatus200_Expect_AuthorizationHeaderToBeP
254252
gpcWebClient.getStructuredRecord(taskDefinition);
255253
tokens.add(Objects.requireNonNull(mockWebServer
256254
.takeRequest()
257-
.getHeader(HttpHeaders.AUTHORIZATION))); // Add token from Authorisation header (WebClient call).
255+
.getHeaders().get(HttpHeaders.AUTHORIZATION))); // Add token from Authorisation header (WebClient call).
258256

259257
// then
260258
final long distinctTokens = tokens.stream().distinct().count();

0 commit comments

Comments
 (0)