Skip to content

Commit

Permalink
Merge pull request #277 from com-pas/add-websocket-support
Browse files Browse the repository at this point in the history
Added Websocket support for creating and updating the SCL File
  • Loading branch information
Dennis Labordus authored Nov 16, 2022
2 parents 98ce5a8 + 3e83d94 commit ac4f611
Show file tree
Hide file tree
Showing 86 changed files with 3,206 additions and 105 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/build-project.yml
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ jobs:
servers: '[{ "id": "github-packages-compas", "username": "OWNER", "password": "${{ secrets.GITHUB_TOKEN }}" }]'
- name: Build with Maven (Pull Request)
if: ${{ github.event_name == 'pull_request' }}
run: ./mvnw -s custom_maven_settings.xml -B -Pnative-image clean verify
run: ./mvnw -s custom_maven_settings.xml -B -Pjvm-image clean verify
- name: Build with Maven (Push)
if: ${{ github.event_name == 'push' }}
run: ./mvnw -s custom_maven_settings.xml -B clean verify
2 changes: 1 addition & 1 deletion .github/workflows/release-project.yml
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,6 @@ jobs:
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Deploy with Maven to GitHub Packages and Docker Hub
run: ./mvnw -B -s custom_maven_settings.xml -Pnative-image,release clean deploy
run: ./mvnw -B -s custom_maven_settings.xml -Pjvm-image,release clean deploy
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
18 changes: 14 additions & 4 deletions app/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,11 @@ SPDX-License-Identifier: Apache-2.0
</dependency>
<dependency>
<groupId>org.lfenergy.compas.core</groupId>
<artifactId>jaxrs-commons</artifactId>
<artifactId>rest-commons</artifactId>
</dependency>
<dependency>
<groupId>org.lfenergy.compas.core</groupId>
<artifactId>websocket-commons</artifactId>
</dependency>

<dependency>
Expand All @@ -59,16 +63,17 @@ SPDX-License-Identifier: Apache-2.0
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-resteasy</artifactId>
<artifactId>quarkus-resteasy-reactive</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-resteasy-jaxb</artifactId>
<artifactId>quarkus-resteasy-reactive-jaxb</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-hibernate-validator</artifactId>
<artifactId>quarkus-websockets</artifactId>
</dependency>

<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-smallrye-jwt</artifactId>
Expand All @@ -81,6 +86,11 @@ SPDX-License-Identifier: Apache-2.0
<groupId>io.quarkus</groupId>
<artifactId>quarkus-smallrye-health</artifactId>
</dependency>

<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-hibernate-validator</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-agroal</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@
* Create Beans from other dependencies that are used in the application.
*/
@RegisterForReflection(targets = {
org.lfenergy.compas.core.jaxrs.model.ErrorResponse.class,
org.lfenergy.compas.core.jaxrs.model.ErrorMessage.class
org.lfenergy.compas.core.commons.model.ErrorResponse.class,
org.lfenergy.compas.core.commons.model.ErrorMessage.class
})
public class CompasSclDataServiceConfiguration {
@Produces
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
// SPDX-License-Identifier: Apache-2.0
package org.lfenergy.compas.scl.data.rest.exception;

import org.lfenergy.compas.core.jaxrs.model.ErrorResponse;
import org.lfenergy.compas.core.commons.model.ErrorResponse;
import org.lfenergy.compas.scl.data.exception.CompasNoDataFoundException;

import javax.ws.rs.core.Response;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
package org.lfenergy.compas.scl.data.rest.v1;

import io.quarkus.security.Authenticated;
import io.smallrye.mutiny.Uni;
import org.eclipse.microprofile.jwt.JsonWebToken;
import org.lfenergy.compas.scl.data.rest.UserInfoProperties;
import org.lfenergy.compas.scl.data.rest.v1.model.Type;
Expand Down Expand Up @@ -40,10 +41,10 @@ public class CompasCommonResource {
@GET
@Path("/type/list")
@Produces(MediaType.APPLICATION_XML)
public TypeListResponse list(@HeaderParam("Authorization") String authHeader) {
public Uni<TypeListResponse> list(@HeaderParam("Authorization") String authHeader) {
LOGGER.trace("Authorization Header '{}'", authHeader);

// Retrieve the roles the logged in user has.
// Retrieve the roles the logged-in user has.
var roles = jsonWebToken.getGroups();

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

@GET
@Path("/userinfo")
@Produces(MediaType.APPLICATION_XML)
public UserInfoResponse getUserInfo(@HeaderParam("Authorization") String authHeader) {
public Uni<UserInfoResponse> getUserInfo(@HeaderParam("Authorization") String authHeader) {
LOGGER.trace("Authorization Header '{}'", authHeader);

var response = new UserInfoResponse();
response.setName(jsonWebToken.getClaim(userInfoProperties.name()));
response.setSessionWarning(userInfoProperties.sessionWarning());
response.setSessionExpires(userInfoProperties.sessionExpires());
return response;
return Uni.createFrom().item(response);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
package org.lfenergy.compas.scl.data.rest.v1;

import io.quarkus.security.Authenticated;
import io.smallrye.common.annotation.Blocking;
import io.smallrye.mutiny.Uni;
import org.eclipse.microprofile.jwt.JsonWebToken;
import org.lfenergy.compas.scl.data.model.Version;
import org.lfenergy.compas.scl.data.rest.UserInfoProperties;
Expand Down Expand Up @@ -42,89 +44,95 @@ public CompasSclDataResource(CompasSclDataService compasSclDataService) {
}

@POST
@Blocking
@Consumes(MediaType.APPLICATION_XML)
@Produces(MediaType.APPLICATION_XML)
public CreateResponse create(@PathParam(TYPE_PATH_PARAM) SclFileType type,
@Valid CreateRequest request) {
public Uni<CreateResponse> create(@PathParam(TYPE_PATH_PARAM) SclFileType type,
@Valid CreateRequest request) {
String who = jsonWebToken.getClaim(userInfoProperties.who());
LOGGER.trace("Username used for Who {}", who);

var response = new CreateResponse();
response.setSclData(compasSclDataService.create(type, request.getName(), who, request.getComment(),
request.getSclData()));
return response;
return Uni.createFrom().item(response);
}

@GET
@Path("/list")
@Produces(MediaType.APPLICATION_XML)
public ListResponse list(@PathParam(TYPE_PATH_PARAM) SclFileType type) {
public Uni<ListResponse> list(@PathParam(TYPE_PATH_PARAM) SclFileType type) {
var response = new ListResponse();
response.setItems(compasSclDataService.list(type));
return response;
return Uni.createFrom().item(response);
}

@GET
@Path("/{" + ID_PATH_PARAM + "}/versions")
@Produces(MediaType.APPLICATION_XML)
public VersionsResponse listVersionsByUUID(@PathParam(TYPE_PATH_PARAM) SclFileType type,
@PathParam(ID_PATH_PARAM) UUID id) {
public Uni<VersionsResponse> listVersionsByUUID(@PathParam(TYPE_PATH_PARAM) SclFileType type,
@PathParam(ID_PATH_PARAM) UUID id) {
var response = new VersionsResponse();
response.setItems(compasSclDataService.listVersionsByUUID(type, id));
return response;
return Uni.createFrom().item(response);
}

@GET
@Path("/{" + ID_PATH_PARAM + "}")
@Produces(MediaType.APPLICATION_XML)
public GetResponse findByUUID(@PathParam(TYPE_PATH_PARAM) SclFileType type,
@PathParam(ID_PATH_PARAM) UUID id) {
public Uni<GetResponse> findByUUID(@PathParam(TYPE_PATH_PARAM) SclFileType type,
@PathParam(ID_PATH_PARAM) UUID id) {
var response = new GetResponse();
response.setSclData(compasSclDataService.findByUUID(type, id));
return response;
return Uni.createFrom().item(response);
}

@GET
@Path("/{" + ID_PATH_PARAM + "}/{" + VERSION_PATH_PARAM + "}")
@Produces(MediaType.APPLICATION_XML)
public GetResponse findByUUIDAndVersion(@PathParam(TYPE_PATH_PARAM) SclFileType type,
@PathParam(ID_PATH_PARAM) UUID id,
@PathParam(VERSION_PATH_PARAM) Version version) {
public Uni<GetResponse> findByUUIDAndVersion(@PathParam(TYPE_PATH_PARAM) SclFileType type,
@PathParam(ID_PATH_PARAM) UUID id,
@PathParam(VERSION_PATH_PARAM) Version version) {
var response = new GetResponse();
response.setSclData(compasSclDataService.findByUUID(type, id, version));
return response;
return Uni.createFrom().item(response);
}

@PUT
@Blocking
@Path("/{" + ID_PATH_PARAM + "}")
@Consumes(MediaType.APPLICATION_XML)
@Produces(MediaType.APPLICATION_XML)
public UpdateResponse update(@PathParam(TYPE_PATH_PARAM) SclFileType type,
@PathParam(ID_PATH_PARAM) UUID id,
@Valid UpdateRequest request) {
public Uni<UpdateResponse> update(@PathParam(TYPE_PATH_PARAM) SclFileType type,
@PathParam(ID_PATH_PARAM) UUID id,
@Valid UpdateRequest request) {
String who = jsonWebToken.getClaim(userInfoProperties.who());
LOGGER.trace("Username used for Who {}", who);

var response = new UpdateResponse();
response.setSclData(compasSclDataService.update(type, id, request.getChangeSetType(), who, request.getComment(),
request.getSclData()));
return response;
return Uni.createFrom().item(response);
}

@DELETE
@Blocking
@Path("/{" + ID_PATH_PARAM + "}")
@Produces(MediaType.APPLICATION_XML)
public void deleteAll(@PathParam(TYPE_PATH_PARAM) SclFileType type,
@PathParam(ID_PATH_PARAM) UUID id) {
public Uni<Void> deleteAll(@PathParam(TYPE_PATH_PARAM) SclFileType type,
@PathParam(ID_PATH_PARAM) UUID id) {
compasSclDataService.delete(type, id);
return Uni.createFrom().nullItem();
}

@DELETE
@Blocking
@Path("/{" + ID_PATH_PARAM + "}/{" + VERSION_PATH_PARAM + "}")
@Produces(MediaType.APPLICATION_XML)
public void deleteVersion(@PathParam(TYPE_PATH_PARAM) SclFileType type,
@PathParam(ID_PATH_PARAM) UUID id,
@PathParam(VERSION_PATH_PARAM) Version version) {
public Uni<Void> deleteVersion(@PathParam(TYPE_PATH_PARAM) SclFileType type,
@PathParam(ID_PATH_PARAM) UUID id,
@PathParam(VERSION_PATH_PARAM) Version version) {
compasSclDataService.delete(type, id, version);
return Uni.createFrom().nullItem();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import org.eclipse.microprofile.openapi.annotations.media.Schema;
import org.lfenergy.compas.core.commons.constraint.FilenameValid;

import javax.validation.constraints.NotBlank;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
Expand All @@ -30,6 +31,7 @@ public class CreateRequest {

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

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import org.eclipse.microprofile.openapi.annotations.media.Schema;
import org.lfenergy.compas.scl.data.model.ChangeSetType;

import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
Expand All @@ -32,6 +33,7 @@ public class UpdateRequest {

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

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
// SPDX-FileCopyrightText: 2022 Alliander N.V.
//
// SPDX-License-Identifier: Apache-2.0
package org.lfenergy.compas.scl.data.websocket.event;

import io.quarkus.vertx.ConsumeEvent;
import org.lfenergy.compas.core.websocket.WebsocketHandler;
import org.lfenergy.compas.scl.data.service.CompasSclDataService;
import org.lfenergy.compas.scl.data.websocket.event.model.CreateEventRequest;
import org.lfenergy.compas.scl.data.websocket.event.model.GetEventRequest;
import org.lfenergy.compas.scl.data.websocket.event.model.GetVersionEventRequest;
import org.lfenergy.compas.scl.data.websocket.event.model.UpdateEventRequest;
import org.lfenergy.compas.scl.data.websocket.v1.model.CreateWsResponse;
import org.lfenergy.compas.scl.data.websocket.v1.model.GetWsResponse;
import org.lfenergy.compas.scl.data.websocket.v1.model.UpdateWsResponse;

import javax.enterprise.context.ApplicationScoped;
import javax.inject.Inject;

/**
* Event Handler used to execute the validation asynchronized.
*/
@ApplicationScoped
public class CompasSclDataEventHandler {
private final CompasSclDataService compasSclDataService;

@Inject
public CompasSclDataEventHandler(CompasSclDataService compasSclDataService) {
this.compasSclDataService = compasSclDataService;
}

@ConsumeEvent(value = "create-ws", blocking = true)
public void createWebsocketsEvent(CreateEventRequest request) {
new WebsocketHandler<CreateWsResponse>().execute(request.getSession(), () -> {
var response = new CreateWsResponse();
response.setSclData(compasSclDataService.create(request.getType(), request.getName(), request.getWho(),
request.getComment(), request.getSclData()));
return response;
});
}

@ConsumeEvent(value = "get-ws")
public void getWebsocketsEvent(GetEventRequest request) {
new WebsocketHandler<GetWsResponse>().execute(request.getSession(), () -> {
var response = new GetWsResponse();
response.setSclData(compasSclDataService.findByUUID(request.getType(), request.getId()));
return response;
});
}

@ConsumeEvent(value = "get-version-ws")
public void getVersionWebsocketsEvent(GetVersionEventRequest request) {
new WebsocketHandler<GetWsResponse>().execute(request.getSession(), () -> {
var response = new GetWsResponse();
response.setSclData(compasSclDataService.findByUUID(request.getType(), request.getId(), request.getVersion()));
return response;
});
}

@ConsumeEvent(value = "update-ws", blocking = true)
public void updateWebsocketsEvent(UpdateEventRequest request) {
new WebsocketHandler<UpdateWsResponse>().execute(request.getSession(), () -> {
var response = new UpdateWsResponse();
response.setSclData(compasSclDataService.update(request.getType(), request.getId(), request.getChangeSetType(),
request.getWho(), request.getComment(), request.getSclData()));
return response;
});
}
}
Loading

0 comments on commit ac4f611

Please sign in to comment.