Skip to content

Commit 2f2ec66

Browse files
Release 0.2.1
1 parent b9ce3c3 commit 2f2ec66

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+2671
-141
lines changed

.gitlab-ci.yml

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,15 @@ default:
1010
key: "$CI_PROJECT_PATH-slug"
1111
paths:
1212
- .gradle/
13-
- ~/.gradle/caches/
14-
- ~/.gradle/wrapper/
13+
# Keep the Gradle wrapper and caches inside the project directory for reuse across jobs.
14+
before_script:
15+
- export GRADLE_USER_HOME="$CI_PROJECT_DIR/.gradle"
16+
# The Docker image ships without execute permissions on scripts; fix this before running the wrapper.
17+
- chmod +x gradlew
1518

1619
variables:
1720
GRADLE_OPTS: "-Dorg.gradle.daemon=false"
21+
GRADLE_USER_HOME: "$CI_PROJECT_DIR/.gradle"
1822
PACKAGE_NAME: "fat-jar"
1923
## settings for harbor container registry
2024
CONTAINER_REGISTRY_SERVER: $CI_REGISTRY
@@ -26,17 +30,21 @@ variables:
2630

2731
lint:
2832
stage: lint
33+
dependencies: []
2934
script:
30-
- gradle --no-daemon --scan --stacktrace checkstyleMain checkstyleTest
35+
# Gradle Checkstyle tasks fail the job when violations exist (see build.gradle.kts Checkstyle setup).
36+
- ./gradlew --no-daemon --stacktrace checkstyleMain checkstyleTest
3137
artifacts:
3238
paths:
3339
- build/reports/checkstyle/
3440
expire_in: 1 week
3541

3642
test:
3743
stage: test
44+
needs: [ "lint" ]
45+
dependencies: []
3846
script:
39-
- gradle --no-daemon -scan --stacktrace test
47+
- ./gradlew --no-daemon --stacktrace test
4048
artifacts:
4149
when: always
4250
reports:
@@ -48,21 +56,31 @@ test:
4856
build-jar:
4957
stage: build
5058
needs: [ "test" ]
59+
dependencies: []
5160
script:
52-
- gradle --no-daemon clean bootJar
61+
- ./gradlew --no-daemon clean bootJar
5362
artifacts:
5463
paths:
5564
- build/libs/*.jar
5665
expire_in: 1 week
66+
rules:
67+
- if: '$CI_COMMIT_TAG'
68+
when: on_success
69+
- if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH'
70+
when: on_success
71+
- when: never
5772

5873
publish-jar:
5974
stage: publish
6075
image: curlimages/curl:latest
76+
needs: [ "build-jar" ]
6177
dependencies:
6278
- build-jar
6379
script:
80+
- TAG="${CI_COMMIT_TAG:-${CI_COMMIT_SHORT_SHA:-${CI_COMMIT_REF_SLUG}}}"
6481
- JAR_FILE=$(ls build/libs/*.jar | head -n1)
65-
82+
- JAR_NAME=$(basename "${JAR_FILE}")
83+
- VERSION="${TAG}"
6684
- sha256sum "$JAR_FILE" | awk '{print $1}' > "${JAR_FILE}.sha256"
6785
- SHA256="$(cat "${JAR_FILE}.sha256")"
6886

@@ -88,8 +106,10 @@ publish-jar:
88106
publish-image:
89107
stage: publish
90108
needs: [ "build-jar" ]
109+
dependencies: []
91110
script:
92-
- gradle --no-configuration-cache jib
111+
- TAG="${CI_COMMIT_TAG:-${CI_COMMIT_SHORT_SHA:-${CI_COMMIT_REF_SLUG}}}"
112+
- ./gradlew --no-configuration-cache jib
93113
-Djib.to.image="${CI_REGISTRY_IMAGE}:${TAG}"
94114
-Djib.to.auth.username="${CI_REGISTRY_USER}"
95115
-Djib.to.auth.password="${CI_REGISTRY_PASSWORD}"

README.md

Lines changed: 36 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -195,17 +195,20 @@ viewable in a small bundled UI.
195195
- ``wss://<host>:<port>/achelos_testfachdienst/ws`` (HTTPS mode)
196196
- ``ws://<host>:<port>/achelos_testfachdienst/ws`` (HTTP mode)
197197

198-
- Application prefix (SEND here): ``/app``
198+
- Application prefix (SEND here): ``/<context-path>/app`` (default context path:
199+
``/achelos_testfachdienst``). If no servlet context path is configured, use ``/app``.
199200
- Example client destinations:
200-
- ``/app/erezept.create`` - create and broadcast
201-
- ``/app/erezept.read.{id}`` - fetch one and reply to caller
202-
- ``/app/erezept.update.{id}`` - update and broadcast
203-
- ``/app/erezept.delete.{id}`` - delete and ack to caller
204-
- ``/app/erezept.list`` - list and reply to caller
201+
- ``/achelos_testfachdienst/app/erezept.create`` - create and broadcast
202+
- ``/achelos_testfachdienst/app/erezept.read.{id}`` - fetch one and reply to caller
203+
- ``/achelos_testfachdienst/app/erezept.update.{id}`` - update and broadcast
204+
- ``/achelos_testfachdienst/app/erezept.delete.{id}`` - delete and ack to caller
205+
- ``/achelos_testfachdienst/app/erezept.list`` - list and reply to caller
205206

206207
- Broker prefixes (SUBSCRIBE here):
207-
- Broadcasts: ``/topic/erezept``
208-
- Per-user replies: ``/user/queue/erezept``
208+
- Broadcasts: ``/achelos_testfachdienst/topic/erezept`` (or ``/topic/erezept`` when no context path
209+
is set)
210+
- Per-user replies: ``/achelos_testfachdienst/user/queue/erezept`` (or ``/user/queue/erezept`` without
211+
a context path)
209212

210213
### AsyncAPI (code-first) docs
211214

@@ -219,40 +222,6 @@ For unambiguous schemas,
219222
we pin payload types with ``@AsyncMessage(payload = ERezept.class)`` or ``ERezept[].class`` for list
220223
responses.
221224

222-
### Minimal client (JS) example
223-
224-
```html
225-
226-
<script src="https://cdn.jsdelivr.net/npm/sockjs-client/dist/sockjs.min.js"></script>
227-
<script src="https://cdn.jsdelivr.net/npm/stompjs/lib/stomp.min.js"></script>
228-
<script>
229-
const sock = new SockJS('/achelos_testfachdienst/ws');
230-
const stomp = Stomp.over(sock);
231-
232-
stomp.connect({}, () => {
233-
// Subscribe to broadcasts
234-
stomp.subscribe('/topic/erezept', msg => {
235-
console.log('Broadcast:', JSON.parse(msg.body));
236-
});
237-
238-
// Subscribe to per-user replies
239-
stomp.subscribe('/user/queue/erezept', msg => {
240-
console.log('Direct reply:', JSON.parse(msg.body));
241-
});
242-
243-
// Create a new ERezept (adjust fields to your model)
244-
stomp.send('/app/erezept.create', {}, JSON.stringify({
245-
id: null,
246-
prescriptionId: 'RX-12345',
247-
status: 'CREATED'
248-
}));
249-
250-
// Fetch a single ERezept
251-
stomp.send('/app/erezept.read.1', {}, {});
252-
}, (err) => console.error('STOMP error', err));
253-
</script>
254-
```
255-
256225
### cURL quick checks (spec & UI)
257226

258227
```bash
@@ -266,6 +235,28 @@ curl -k https://localhost:8080/achelos_testfachdienst/springwolf/asyncapi-ui.htm
266235
> When running via ``./gradlew bootRun``, HTTPS is enabled by default in this project;
267236
> use ``-k/--insecure`` for local self-signed certs.
268237
238+
## Exemplary self disclosure export
239+
This service allows to configure an OTLP based export of a self disclosure log record (see A_27494-01, gemSpec_ZETA)
240+
using the official [OpenTelemetry SDK](https://opentelemetry.io/docs/languages/java/intro/) to generate and export
241+
OTLP and gemSpec_ZETA conformant log records and [Jobrunr](https://www.jobrunr.io/) to manage the recurring background
242+
task.
243+
244+
The configuration parameters for the OTLP exporter are located at the `otlp` key in the
245+
[application.yaml](./src/main/resources/application.yml).
246+
For convenience all of those options can also be configured through their respective environment variables, please
247+
consult the [application.yaml](./src/main/resources/application.yml) for details.
248+
249+
250+
The configuration parameters for the - more or less - static values of the self disclosure are located at the
251+
`selfdisclosure` key in the [application.yaml](./src/main/resources/application.yml).
252+
253+
The configuration parameters for the `jobrunr` values are located at the `jobrunr` key in the
254+
[application.yaml](./src/main/resources/application.yml).
255+
Please consult the [Jobruner documentation](https://www.jobrunr.io/en/documentation/configuration/spring/) for details
256+
on how to configure `jobrunr`.
257+
258+
259+
269260
## Quality Tooling
270261

271262
- Tests use JUnit 5, AssertJ, Mockito, and Spring Boot test slices (DataJpaTest).
@@ -322,5 +313,6 @@ the License.
322313
2. Permission notice: Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
323314
1. The copyright notice (Item 1) and the permission notice (Item 2) shall be included in all copies or substantial portions of the Software.
324315
2. The software is provided "as is" without warranty of any kind, either express or implied, including, but not limited to, the warranties of fitness for a particular purpose, merchantability, and/or non-infringement. The authors or copyright holders shall not be liable in any manner whatsoever for any damages or other claims arising from, out of or in connection with the software or the use or other dealings with the software, whether in an action of contract, tort, or otherwise.
325-
3. We take open source license compliance very seriously. We are always striving to achieve compliance at all times and to improve our processes. If you find any issues or have any suggestions or comments, or if you see any other ways in which we can improve, please reach out to: ospo@gematik.de
326-
3. Please note: Parts of this code may have been generated using AI-supported technology. Please take this into account, especially when troubleshooting, for security analyses and possible adjustments.
316+
3. The software is the result of research and development activities, therefore not necessarily quality assured and without the character of a liable product. For this reason, gematik does not provide any support or other user assistance (unless otherwise stated in individual cases and without justification of a legal obligation). Furthermore, there is no claim to further development and adaptation of the results to a more current state of the art.
317+
3. Gematik may remove published results temporarily or permanently from the place of publication at any time without prior notice or justification.
318+
4. Please note: Parts of this code may have been generated using AI-supported technology. Please take this into account, especially when troubleshooting, for security analyses and possible adjustments.

ReleaseNotes.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,11 @@
22

33
# Release Notes ZETA Testfachdienst
44

5+
## Release 0.2.1
6+
7+
### added:
8+
- Support for WebSockets
9+
510
## Release 0.1.3
611

712
### added:

build.gradle.kts

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -43,11 +43,20 @@ dependencies {
4343
implementation("org.springframework.boot:spring-boot-starter-actuator")
4444
implementation("io.micrometer:micrometer-registry-prometheus")
4545
implementation("org.springframework.boot:spring-boot-starter-websocket")
46+
implementation("org.springframework:spring-websocket")
4647
implementation("org.springframework.boot:spring-boot-starter-json")
4748
implementation(libs.springdoc)
4849
implementation(libs.springwolfstomp)
4950
implementation(libs.springwolfstompbinding)
5051

52+
implementation(platform(libs.opentelemetrybom))
53+
implementation("io.opentelemetry:opentelemetry-exporter-otlp")
54+
implementation("io.opentelemetry:opentelemetry-sdk-testing")
55+
56+
implementation(libs.protobuf)
57+
implementation(libs.jobrunr)
58+
59+
5160
runtimeOnly(libs.springwolfui)
5261
runtimeOnly("com.h2database:h2")
5362

@@ -56,11 +65,9 @@ dependencies {
5665

5766
checkstyle {
5867
toolVersion = libs.versions.checkstyle.get()
59-
val archive =
60-
configurations.checkstyle.get().resolve().filter {
61-
it.name.startsWith("checkstyle")
62-
}
63-
config = resources.text.fromArchiveEntry(archive, "google_checks.xml")
68+
config = resources.text.fromFile(file("config/checkstyle/custom_google_checks.xml"))
69+
isIgnoreFailures = false
70+
maxWarnings = 0
6471
}
6572

6673
jacoco {
@@ -109,10 +116,6 @@ extensions.configure<JibExtension>("jib") {
109116
ports = listOf("8080", "8081")
110117
user = "65532:65532"
111118
creationTime = "USE_CURRENT_TIMESTAMP"
112-
environment =
113-
mapOf(
114-
"SPRING_PROFILES_ACTIVE" to "prod,k8s",
115-
)
116119
workingDirectory = "/app"
117120
labels =
118121
mapOf(

0 commit comments

Comments
 (0)