Skip to content

Commit ac4f611

Browse files
author
Dennis Labordus
authored
Merge pull request #277 from com-pas/add-websocket-support
Added Websocket support for creating and updating the SCL File
2 parents 98ce5a8 + 3e83d94 commit ac4f611

File tree

86 files changed

+3206
-105
lines changed

Some content is hidden

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

86 files changed

+3206
-105
lines changed

.github/workflows/build-project.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ jobs:
5151
servers: '[{ "id": "github-packages-compas", "username": "OWNER", "password": "${{ secrets.GITHUB_TOKEN }}" }]'
5252
- name: Build with Maven (Pull Request)
5353
if: ${{ github.event_name == 'pull_request' }}
54-
run: ./mvnw -s custom_maven_settings.xml -B -Pnative-image clean verify
54+
run: ./mvnw -s custom_maven_settings.xml -B -Pjvm-image clean verify
5555
- name: Build with Maven (Push)
5656
if: ${{ github.event_name == 'push' }}
5757
run: ./mvnw -s custom_maven_settings.xml -B clean verify

.github/workflows/release-project.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,6 @@ jobs:
6060
env:
6161
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
6262
- name: Deploy with Maven to GitHub Packages and Docker Hub
63-
run: ./mvnw -B -s custom_maven_settings.xml -Pnative-image,release clean deploy
63+
run: ./mvnw -B -s custom_maven_settings.xml -Pjvm-image,release clean deploy
6464
env:
6565
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

app/pom.xml

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,11 @@ SPDX-License-Identifier: Apache-2.0
5050
</dependency>
5151
<dependency>
5252
<groupId>org.lfenergy.compas.core</groupId>
53-
<artifactId>jaxrs-commons</artifactId>
53+
<artifactId>rest-commons</artifactId>
54+
</dependency>
55+
<dependency>
56+
<groupId>org.lfenergy.compas.core</groupId>
57+
<artifactId>websocket-commons</artifactId>
5458
</dependency>
5559

5660
<dependency>
@@ -59,16 +63,17 @@ SPDX-License-Identifier: Apache-2.0
5963
</dependency>
6064
<dependency>
6165
<groupId>io.quarkus</groupId>
62-
<artifactId>quarkus-resteasy</artifactId>
66+
<artifactId>quarkus-resteasy-reactive</artifactId>
6367
</dependency>
6468
<dependency>
6569
<groupId>io.quarkus</groupId>
66-
<artifactId>quarkus-resteasy-jaxb</artifactId>
70+
<artifactId>quarkus-resteasy-reactive-jaxb</artifactId>
6771
</dependency>
6872
<dependency>
6973
<groupId>io.quarkus</groupId>
70-
<artifactId>quarkus-hibernate-validator</artifactId>
74+
<artifactId>quarkus-websockets</artifactId>
7175
</dependency>
76+
7277
<dependency>
7378
<groupId>io.quarkus</groupId>
7479
<artifactId>quarkus-smallrye-jwt</artifactId>
@@ -81,6 +86,11 @@ SPDX-License-Identifier: Apache-2.0
8186
<groupId>io.quarkus</groupId>
8287
<artifactId>quarkus-smallrye-health</artifactId>
8388
</dependency>
89+
90+
<dependency>
91+
<groupId>io.quarkus</groupId>
92+
<artifactId>quarkus-hibernate-validator</artifactId>
93+
</dependency>
8494
<dependency>
8595
<groupId>io.quarkus</groupId>
8696
<artifactId>quarkus-agroal</artifactId>

app/src/main/java/org/lfenergy/compas/scl/data/rest/CompasSclDataServiceConfiguration.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@
1414
* Create Beans from other dependencies that are used in the application.
1515
*/
1616
@RegisterForReflection(targets = {
17-
org.lfenergy.compas.core.jaxrs.model.ErrorResponse.class,
18-
org.lfenergy.compas.core.jaxrs.model.ErrorMessage.class
17+
org.lfenergy.compas.core.commons.model.ErrorResponse.class,
18+
org.lfenergy.compas.core.commons.model.ErrorMessage.class
1919
})
2020
public class CompasSclDataServiceConfiguration {
2121
@Produces

app/src/main/java/org/lfenergy/compas/scl/data/rest/exception/CompasNoDataFoundExceptionHandler.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
// SPDX-License-Identifier: Apache-2.0
44
package org.lfenergy.compas.scl.data.rest.exception;
55

6-
import org.lfenergy.compas.core.jaxrs.model.ErrorResponse;
6+
import org.lfenergy.compas.core.commons.model.ErrorResponse;
77
import org.lfenergy.compas.scl.data.exception.CompasNoDataFoundException;
88

99
import javax.ws.rs.core.Response;

app/src/main/java/org/lfenergy/compas/scl/data/rest/v1/CompasCommonResource.java

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
package org.lfenergy.compas.scl.data.rest.v1;
55

66
import io.quarkus.security.Authenticated;
7+
import io.smallrye.mutiny.Uni;
78
import org.eclipse.microprofile.jwt.JsonWebToken;
89
import org.lfenergy.compas.scl.data.rest.UserInfoProperties;
910
import org.lfenergy.compas.scl.data.rest.v1.model.Type;
@@ -40,10 +41,10 @@ public class CompasCommonResource {
4041
@GET
4142
@Path("/type/list")
4243
@Produces(MediaType.APPLICATION_XML)
43-
public TypeListResponse list(@HeaderParam("Authorization") String authHeader) {
44+
public Uni<TypeListResponse> list(@HeaderParam("Authorization") String authHeader) {
4445
LOGGER.trace("Authorization Header '{}'", authHeader);
4546

46-
// Retrieve the roles the logged in user has.
47+
// Retrieve the roles the logged-in user has.
4748
var roles = jsonWebToken.getGroups();
4849

4950
var response = new TypeListResponse();
@@ -54,19 +55,19 @@ public TypeListResponse list(@HeaderParam("Authorization") String authHeader) {
5455
.map(sclFileType -> new Type(sclFileType.name(), sclFileType.getDescription()))
5556
.sorted(Comparator.comparing(Type::getDescription))
5657
.toList());
57-
return response;
58+
return Uni.createFrom().item(response);
5859
}
5960

6061
@GET
6162
@Path("/userinfo")
6263
@Produces(MediaType.APPLICATION_XML)
63-
public UserInfoResponse getUserInfo(@HeaderParam("Authorization") String authHeader) {
64+
public Uni<UserInfoResponse> getUserInfo(@HeaderParam("Authorization") String authHeader) {
6465
LOGGER.trace("Authorization Header '{}'", authHeader);
6566

6667
var response = new UserInfoResponse();
6768
response.setName(jsonWebToken.getClaim(userInfoProperties.name()));
6869
response.setSessionWarning(userInfoProperties.sessionWarning());
6970
response.setSessionExpires(userInfoProperties.sessionExpires());
70-
return response;
71+
return Uni.createFrom().item(response);
7172
}
7273
}

app/src/main/java/org/lfenergy/compas/scl/data/rest/v1/CompasSclDataResource.java

Lines changed: 33 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
package org.lfenergy.compas.scl.data.rest.v1;
55

66
import io.quarkus.security.Authenticated;
7+
import io.smallrye.common.annotation.Blocking;
8+
import io.smallrye.mutiny.Uni;
79
import org.eclipse.microprofile.jwt.JsonWebToken;
810
import org.lfenergy.compas.scl.data.model.Version;
911
import org.lfenergy.compas.scl.data.rest.UserInfoProperties;
@@ -42,89 +44,95 @@ public CompasSclDataResource(CompasSclDataService compasSclDataService) {
4244
}
4345

4446
@POST
47+
@Blocking
4548
@Consumes(MediaType.APPLICATION_XML)
4649
@Produces(MediaType.APPLICATION_XML)
47-
public CreateResponse create(@PathParam(TYPE_PATH_PARAM) SclFileType type,
48-
@Valid CreateRequest request) {
50+
public Uni<CreateResponse> create(@PathParam(TYPE_PATH_PARAM) SclFileType type,
51+
@Valid CreateRequest request) {
4952
String who = jsonWebToken.getClaim(userInfoProperties.who());
5053
LOGGER.trace("Username used for Who {}", who);
5154

5255
var response = new CreateResponse();
5356
response.setSclData(compasSclDataService.create(type, request.getName(), who, request.getComment(),
5457
request.getSclData()));
55-
return response;
58+
return Uni.createFrom().item(response);
5659
}
5760

5861
@GET
5962
@Path("/list")
6063
@Produces(MediaType.APPLICATION_XML)
61-
public ListResponse list(@PathParam(TYPE_PATH_PARAM) SclFileType type) {
64+
public Uni<ListResponse> list(@PathParam(TYPE_PATH_PARAM) SclFileType type) {
6265
var response = new ListResponse();
6366
response.setItems(compasSclDataService.list(type));
64-
return response;
67+
return Uni.createFrom().item(response);
6568
}
6669

6770
@GET
6871
@Path("/{" + ID_PATH_PARAM + "}/versions")
6972
@Produces(MediaType.APPLICATION_XML)
70-
public VersionsResponse listVersionsByUUID(@PathParam(TYPE_PATH_PARAM) SclFileType type,
71-
@PathParam(ID_PATH_PARAM) UUID id) {
73+
public Uni<VersionsResponse> listVersionsByUUID(@PathParam(TYPE_PATH_PARAM) SclFileType type,
74+
@PathParam(ID_PATH_PARAM) UUID id) {
7275
var response = new VersionsResponse();
7376
response.setItems(compasSclDataService.listVersionsByUUID(type, id));
74-
return response;
77+
return Uni.createFrom().item(response);
7578
}
7679

7780
@GET
7881
@Path("/{" + ID_PATH_PARAM + "}")
7982
@Produces(MediaType.APPLICATION_XML)
80-
public GetResponse findByUUID(@PathParam(TYPE_PATH_PARAM) SclFileType type,
81-
@PathParam(ID_PATH_PARAM) UUID id) {
83+
public Uni<GetResponse> findByUUID(@PathParam(TYPE_PATH_PARAM) SclFileType type,
84+
@PathParam(ID_PATH_PARAM) UUID id) {
8285
var response = new GetResponse();
8386
response.setSclData(compasSclDataService.findByUUID(type, id));
84-
return response;
87+
return Uni.createFrom().item(response);
8588
}
8689

8790
@GET
8891
@Path("/{" + ID_PATH_PARAM + "}/{" + VERSION_PATH_PARAM + "}")
8992
@Produces(MediaType.APPLICATION_XML)
90-
public GetResponse findByUUIDAndVersion(@PathParam(TYPE_PATH_PARAM) SclFileType type,
91-
@PathParam(ID_PATH_PARAM) UUID id,
92-
@PathParam(VERSION_PATH_PARAM) Version version) {
93+
public Uni<GetResponse> findByUUIDAndVersion(@PathParam(TYPE_PATH_PARAM) SclFileType type,
94+
@PathParam(ID_PATH_PARAM) UUID id,
95+
@PathParam(VERSION_PATH_PARAM) Version version) {
9396
var response = new GetResponse();
9497
response.setSclData(compasSclDataService.findByUUID(type, id, version));
95-
return response;
98+
return Uni.createFrom().item(response);
9699
}
97100

98101
@PUT
102+
@Blocking
99103
@Path("/{" + ID_PATH_PARAM + "}")
100104
@Consumes(MediaType.APPLICATION_XML)
101105
@Produces(MediaType.APPLICATION_XML)
102-
public UpdateResponse update(@PathParam(TYPE_PATH_PARAM) SclFileType type,
103-
@PathParam(ID_PATH_PARAM) UUID id,
104-
@Valid UpdateRequest request) {
106+
public Uni<UpdateResponse> update(@PathParam(TYPE_PATH_PARAM) SclFileType type,
107+
@PathParam(ID_PATH_PARAM) UUID id,
108+
@Valid UpdateRequest request) {
105109
String who = jsonWebToken.getClaim(userInfoProperties.who());
106110
LOGGER.trace("Username used for Who {}", who);
107111

108112
var response = new UpdateResponse();
109113
response.setSclData(compasSclDataService.update(type, id, request.getChangeSetType(), who, request.getComment(),
110114
request.getSclData()));
111-
return response;
115+
return Uni.createFrom().item(response);
112116
}
113117

114118
@DELETE
119+
@Blocking
115120
@Path("/{" + ID_PATH_PARAM + "}")
116121
@Produces(MediaType.APPLICATION_XML)
117-
public void deleteAll(@PathParam(TYPE_PATH_PARAM) SclFileType type,
118-
@PathParam(ID_PATH_PARAM) UUID id) {
122+
public Uni<Void> deleteAll(@PathParam(TYPE_PATH_PARAM) SclFileType type,
123+
@PathParam(ID_PATH_PARAM) UUID id) {
119124
compasSclDataService.delete(type, id);
125+
return Uni.createFrom().nullItem();
120126
}
121127

122128
@DELETE
129+
@Blocking
123130
@Path("/{" + ID_PATH_PARAM + "}/{" + VERSION_PATH_PARAM + "}")
124131
@Produces(MediaType.APPLICATION_XML)
125-
public void deleteVersion(@PathParam(TYPE_PATH_PARAM) SclFileType type,
126-
@PathParam(ID_PATH_PARAM) UUID id,
127-
@PathParam(VERSION_PATH_PARAM) Version version) {
132+
public Uni<Void> deleteVersion(@PathParam(TYPE_PATH_PARAM) SclFileType type,
133+
@PathParam(ID_PATH_PARAM) UUID id,
134+
@PathParam(VERSION_PATH_PARAM) Version version) {
128135
compasSclDataService.delete(type, id, version);
136+
return Uni.createFrom().nullItem();
129137
}
130-
}
138+
}

app/src/main/java/org/lfenergy/compas/scl/data/rest/v1/model/CreateRequest.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import org.eclipse.microprofile.openapi.annotations.media.Schema;
88
import org.lfenergy.compas.core.commons.constraint.FilenameValid;
99

10+
import javax.validation.constraints.NotBlank;
1011
import javax.xml.bind.annotation.XmlAccessType;
1112
import javax.xml.bind.annotation.XmlAccessorType;
1213
import javax.xml.bind.annotation.XmlElement;
@@ -30,6 +31,7 @@ public class CreateRequest {
3031

3132
@Schema(description = "The XML Content of the SCL added as CDATA. The content should contain a XML according to the IEC 61850 standard.",
3233
example = "<![CDATA[<SCL xmlns=\"http://www.iec.ch/61850/2003/SCL\">....</SCL>]]")
34+
@NotBlank
3335
@XmlElement(name = "SclData", namespace = SCL_DATA_SERVICE_V1_NS_URI)
3436
private String sclData;
3537

app/src/main/java/org/lfenergy/compas/scl/data/rest/v1/model/UpdateRequest.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import org.eclipse.microprofile.openapi.annotations.media.Schema;
88
import org.lfenergy.compas.scl.data.model.ChangeSetType;
99

10+
import javax.validation.constraints.NotBlank;
1011
import javax.validation.constraints.NotNull;
1112
import javax.xml.bind.annotation.XmlAccessType;
1213
import javax.xml.bind.annotation.XmlAccessorType;
@@ -32,6 +33,7 @@ public class UpdateRequest {
3233

3334
@Schema(description = "The XML Content of the SCL added as CDATA. The content should contain a XML according to the IEC 61850 standard.",
3435
example = "<![CDATA[<SCL xmlns=\"http://www.iec.ch/61850/2003/SCL\">....</SCL>]]")
36+
@NotBlank
3537
@XmlElement(name = "SclData", namespace = SCL_DATA_SERVICE_V1_NS_URI)
3638
private String sclData;
3739

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
// SPDX-FileCopyrightText: 2022 Alliander N.V.
2+
//
3+
// SPDX-License-Identifier: Apache-2.0
4+
package org.lfenergy.compas.scl.data.websocket.event;
5+
6+
import io.quarkus.vertx.ConsumeEvent;
7+
import org.lfenergy.compas.core.websocket.WebsocketHandler;
8+
import org.lfenergy.compas.scl.data.service.CompasSclDataService;
9+
import org.lfenergy.compas.scl.data.websocket.event.model.CreateEventRequest;
10+
import org.lfenergy.compas.scl.data.websocket.event.model.GetEventRequest;
11+
import org.lfenergy.compas.scl.data.websocket.event.model.GetVersionEventRequest;
12+
import org.lfenergy.compas.scl.data.websocket.event.model.UpdateEventRequest;
13+
import org.lfenergy.compas.scl.data.websocket.v1.model.CreateWsResponse;
14+
import org.lfenergy.compas.scl.data.websocket.v1.model.GetWsResponse;
15+
import org.lfenergy.compas.scl.data.websocket.v1.model.UpdateWsResponse;
16+
17+
import javax.enterprise.context.ApplicationScoped;
18+
import javax.inject.Inject;
19+
20+
/**
21+
* Event Handler used to execute the validation asynchronized.
22+
*/
23+
@ApplicationScoped
24+
public class CompasSclDataEventHandler {
25+
private final CompasSclDataService compasSclDataService;
26+
27+
@Inject
28+
public CompasSclDataEventHandler(CompasSclDataService compasSclDataService) {
29+
this.compasSclDataService = compasSclDataService;
30+
}
31+
32+
@ConsumeEvent(value = "create-ws", blocking = true)
33+
public void createWebsocketsEvent(CreateEventRequest request) {
34+
new WebsocketHandler<CreateWsResponse>().execute(request.getSession(), () -> {
35+
var response = new CreateWsResponse();
36+
response.setSclData(compasSclDataService.create(request.getType(), request.getName(), request.getWho(),
37+
request.getComment(), request.getSclData()));
38+
return response;
39+
});
40+
}
41+
42+
@ConsumeEvent(value = "get-ws")
43+
public void getWebsocketsEvent(GetEventRequest request) {
44+
new WebsocketHandler<GetWsResponse>().execute(request.getSession(), () -> {
45+
var response = new GetWsResponse();
46+
response.setSclData(compasSclDataService.findByUUID(request.getType(), request.getId()));
47+
return response;
48+
});
49+
}
50+
51+
@ConsumeEvent(value = "get-version-ws")
52+
public void getVersionWebsocketsEvent(GetVersionEventRequest request) {
53+
new WebsocketHandler<GetWsResponse>().execute(request.getSession(), () -> {
54+
var response = new GetWsResponse();
55+
response.setSclData(compasSclDataService.findByUUID(request.getType(), request.getId(), request.getVersion()));
56+
return response;
57+
});
58+
}
59+
60+
@ConsumeEvent(value = "update-ws", blocking = true)
61+
public void updateWebsocketsEvent(UpdateEventRequest request) {
62+
new WebsocketHandler<UpdateWsResponse>().execute(request.getSession(), () -> {
63+
var response = new UpdateWsResponse();
64+
response.setSclData(compasSclDataService.update(request.getType(), request.getId(), request.getChangeSetType(),
65+
request.getWho(), request.getComment(), request.getSclData()));
66+
return response;
67+
});
68+
}
69+
}

0 commit comments

Comments
 (0)