Skip to content

Commit

Permalink
Merge pull request #3 from com-pas/Fetch_Bay_Typicals
Browse files Browse the repository at this point in the history
Fetch Bay Typicals
  • Loading branch information
pascalwilbrink authored Mar 24, 2023
2 parents 6f801b6 + e76f624 commit 32056ed
Show file tree
Hide file tree
Showing 29 changed files with 769 additions and 127 deletions.
113 changes: 113 additions & 0 deletions DEVELOPMENT.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
<!--
SPDX-FileCopyrightText: 2023 Alliander N.V.
SPDX-License-Identifier: Apache-2.0
-->

# Development for Sitipe Service

This project uses Java 17 and Quarkus to build and run the application. The project is split into multi modules.
The app module will use Quarkus to expose the services as REST XML and JSON Endpoints. The service module contains all
the logic to retrieve data from a Sitipe database. This module uses no Quarkus dependencies, but mainly standard java. This way the service module can also be used in
other environment as Java library, for instance a Spring project.

## Building the application

You can use Maven to build the application and see if all tests are working using:

```shell script
./mvnw clean verify
```

This should normally be enough to also run the application, but there were cases that we need to build using:

```shell script
./mvnw clean install
```

This to make the local modules available for the app module to run the application.

## Running the application locally in dev mode

You can run your application in dev mode that enables live coding using:

```shell script
./mvnw package io.quarkus:quarkus-maven-plugin::dev
```

### Application depends on a running KeyCloak instance for dev mode

A KeyCloak instance needs to be running on port 8089 by default in dev mode. If a custom KeyCloak instance is used see
[Security](README.md#security) for more details.

There is a preconfigured Demo KeyCloak instance available for CoMPAS in the
[CoMPAS Deployment Repository](https://github.com/com-pas/compas-deployment). This repository can be cloned and
used to execute the following commands to create a local Docker Image with the CoMPAS Demo configuration.

```shell
cd <CoMPAS Deployment Repository Directory>/compas/keycloak
docker build -t compas_keycloak .
```

A Docker Image `compas_keycloak` is created that can be started using the following command

```shell
docker run --rm --name compas_keycloak \
-p 8089:8080
-d compas_keycloak:latest
```

There are now 3 users available to be used, `scl-data-editor`, `scl-data-reader`, `scd-reader`. See
[CoMPAS Deployment Repository](https://github.com/com-pas/compas-deployment) for more information about the users.

## Testing the application

The application is tested with unit and integration tests, but you can also manually test the application using for
instance Postman. And there is also a way to test this service with the CoMPAS OpenSCD Frontend application.

### Postman

To manually test the application there is a Postman collection in the directory `postman` that can be imported
and used to execute REST XML and JSON Calls.

To make the call work we also need to import an environment and authorisation collection. These files can be found
in [CoMPAS Deployment Repository](https://github.com/com-pas/compas-deployment) in the directory `postman`
(`auth.collection.json` and `local.environment.json`).

In the authorisation collection there are called for the 3 users known within the Demo KeyCloak instance.
If one of these calls are executed there is a variable `bearer` filled.

Now one of the Sitipe Service calls can be executed, the variable `bearer` is added to the header of the request.
After the call is executed the result should be shown in Postman.

### CoMPAS OpenSCD Frontend application

To test the Sitipe Service with the CoMPAS OpenSCD application just run the application in dev mode, including the
KeyCloak instance. For further instruction how to start the CoMPAS OpenSCD application and use this locally see
the file `DEVELOPMENT.md` in [CoMPAS OpenSCD application](https://github.com/com-pas/compas-open-scd).

## Docker Images

### Creating a Docker image with native executable

The releases created in the repository will create a docker image with a native executable. If you're running a Linux
system it's possible to create and run the executable locally. You can create a Docker image with native executable
using:

```shell script
./mvnw package -Pnative-image
```

You can then execute your native executable with: `./app/target/app-local-SNAPSHOT-runner`

### Creating a Docker image with JVM executable

There is also a profile to create a Docker Image which runs the application using a JVM. You can create a Docker Image
with JVM executable using:

```shell script
./mvnw package -Pjvm-image
```

The JVM Image can also (temporary) be created by the release action if there are problems creating or running the
native executable.
31 changes: 27 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,40 @@ SPDX-License-Identifier: Apache-2.0
[![CII Best Practices](https://bestpractices.coreinfrastructure.org/projects/5925/badge)](https://bestpractices.coreinfrastructure.org/projects/5925)
[![Slack](https://raw.githubusercontent.com/com-pas/compas-architecture/master/public/LFEnergy-slack.svg)](http://lfenergy.slack.com/)

# CoMPAS Sitipe Service
# CoMPAS Sitipe-service
The CoMPAS Sitipe-Service Allows users to integrate Siemens Sitipe within the CoMPAS environment.

### Local Development
## Development

Information about how to run and develop for this project check [Development](./DEVELOPMENT.md).

## Environment Variables

|Environment Variable | Default | Example |
|--|--|--|
| JWT_VERIFY_KEY | http://localhost:8089/auth/realms/compas/protocol/openid-connect/certs | http://localhost:8089/auth/realms/compas/protocol/openid-connect/certs |
| JWT_VERIFY_ISSUER | http://localhost/auth/realms/compas | http://localhost/auth/realms/compas |
| JWT_VERIFY_CLIENT | sitipe-service | sitipe-service |
| JWT_GROUPS_PATH | resource_access/sitipe-service/roles | resource_access/sitipe-service/roles |
| SITIPE_FRAMEWORK_ID | - | cf1 |
| SITIPE_VERSION | 1.00 | 1.00 |
| SITIPE_MSSQL_URL | _ | jdbc:sqlserver://localhost:1433;databaseName=DB_2019_IC1;ssl-mode=disabled;trustServerCertificate=true;encrypt=false;integratedSecurity=false;
| SITIPE_MSSQL_USER | sa | sa |
| SITIPE_MSSQL_PASSWORD | - | bigStrongPwd123! |

## Security

To use most of the endpoints the users needs to be authenticated using JWT in the authorization header. There are [4 environment variables](#environment-variables) that can be set in the container to configure the validation/processing of the JWT.

## Local Development
You can start the mssql database by running one of the following commands:

#### Mac M1
### Mac M1
```
docker-compose --env-file docker/.env -f docker/docker-compose-m1.yml up -d --build
```

#### AMD64
### AMD64
```
docker-compose --env-file docker/.env -f docker/docker-compose-amd64.yml up -d --build
```
Expand Down
9 changes: 9 additions & 0 deletions app/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,15 @@ SPDX-License-Identifier: Apache-2.0
<artifactId>openpojo</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-jdbc-h2</artifactId>
<version>3.0.0.Alpha5</version>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-flyway</artifactId>
</dependency>
</dependencies>

<build>
Expand Down
6 changes: 5 additions & 1 deletion app/src/main/docker/Dockerfile.native
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,11 @@ WORKDIR /work/
RUN chown 1001 /work \
&& chmod "g+rwX" /work \
&& chown 1001:root /work
COPY --chown=1001:root target/quarkus-app/*-runner /work/application
COPY --chown=1001:root target/*-runner /work/application

RUN mkdir -p /data/temp \
&& chown -R 1001 /data \
&& chmod -R "g+rwX" /data

EXPOSE 8080
USER 1001
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@

package org.lfenergy.compas.sitipe.rest.v1;

import io.quarkus.security.Authenticated;
import io.smallrye.common.annotation.Blocking;
import io.smallrye.mutiny.Uni;
import org.lfenergy.compas.sitipe.data.entity.BayTypical;
import org.lfenergy.compas.sitipe.rest.v1.model.BayTypicalResponse;
import org.lfenergy.compas.sitipe.service.BayTypicalService;

Expand All @@ -19,41 +19,30 @@
import javax.ws.rs.core.MediaType;
import java.util.stream.Collectors;

// @Authenticated
@Authenticated
@RequestScoped
@Path("/sitipe/v1")
public class CompasSitipeResource {
@Path("/v1/baytypicals")
public class BayTypicalResource {

private final BayTypicalService bayTypicalService;

@Inject
public CompasSitipeResource(final BayTypicalService bayTypicalService) {
public BayTypicalResource(final BayTypicalService bayTypicalService) {
this.bayTypicalService = bayTypicalService;
}

@GET
@Consumes(MediaType.APPLICATION_XML)
@Produces(MediaType.APPLICATION_XML)
@Blocking
public Uni<BayTypicalResponse> getHelloWorld() {
public Uni<BayTypicalResponse> getAssignedBayTypicals() {
var response = new BayTypicalResponse();

response.setBayTypicals(
this.bayTypicalService.getBayTypicals()
this.bayTypicalService.getAssignedBayTypicals()
.stream()
.map(bt -> new BayTypicalResponse.BayTypical(
bt.getId(),
bt.getAccessId(),
bt.getName(),
bt.getVersion(),
bt.getDescription(),
bt.getReleased(),
bt.getLockedBy(),
bt.getLockedOn(),
bt.getModifiedOn(),
bt.getSmrFile(),
bt.getContentVersion(),
bt.getReferenceAccessId()
)).collect(Collectors.toList())
.map(BayTypicalResponse.BayTypicalItem::new)
.collect(Collectors.toList())
);

return Uni.createFrom().item(response);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
// SPDX-FileCopyrightText: 2023 Alliander N.V.
//
// SPDX-License-Identifier: Apache-2.0

package org.lfenergy.compas.sitipe.rest.v1.model;

import org.eclipse.microprofile.openapi.annotations.media.Schema;
import org.lfenergy.compas.sitipe.data.entity.BayTypical;

import javax.persistence.Column;
import javax.persistence.Id;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
Expand All @@ -19,23 +22,23 @@ public class BayTypicalResponse {

@Schema(description = "List of found BayTypicals in the database.")
@XmlElement(name = "BayTypical", namespace = SITIPE_SERVICE_V1_NS_URI)
private List<BayTypical> bayTypicals;
private List<BayTypicalItem> bayTypicals;

public void setBayTypicals(final List<BayTypical> bayTypicals) {
public void setBayTypicals(final List<BayTypicalItem> bayTypicals) {
this.bayTypicals = bayTypicals;
}

public List<BayTypical> getBayTypicals() {
public List<BayTypicalItem> getBayTypicals() {
return bayTypicals;
}

@Schema(description = "BayTypical found in the database.")
@XmlAccessorType(XmlAccessType.FIELD)
public static class BayTypical {
public static class BayTypicalItem {

@Schema(description = "Id of the BayTypical.", example = "1")
@XmlElement(name = "Id", namespace = SITIPE_SERVICE_V1_NS_URI)
private int id;
private Integer id;

@Schema(description = "Access Id of the BayTypical.", example = "c50b3276-81f6-4bc3-82ab-b8adef829136")
@XmlElement(name = "AccessId", namespace = SITIPE_SERVICE_V1_NS_URI)
Expand All @@ -49,7 +52,7 @@ public static class BayTypical {
@XmlElement(name = "Version", namespace = SITIPE_SERVICE_V1_NS_URI)
private String version;

@Schema(description = "Description of the BayTypical.", example = "")
@Schema(description = "Description of the BayTypical.")
@XmlElement(name = "Description", namespace = SITIPE_SERVICE_V1_NS_URI)
private String description;

Expand Down Expand Up @@ -81,38 +84,27 @@ public static class BayTypical {
@XmlElement(name = "ReferenceAccessId", namespace = SITIPE_SERVICE_V1_NS_URI)
private String referenceAccessId;

public BayTypical(
final int id,
final String accessId,
final String name,
final String version,
final String description,
final int released,
final String lockedBy,
final Long lockedOn,
final Long modifiedOn,
final String smrFile,
final String contentVersion,
final String referenceAccessId
public BayTypicalItem(
final BayTypical bt
) {
this.id = id;
this.accessId = accessId;
this.name = name;
this.version = version;
this.description = description;
this.released = released;
this.lockedBy = lockedBy;
this.lockedOn = lockedOn;
this.modifiedOn = modifiedOn;
this.smrFile = smrFile;
this.contentVersion = contentVersion;
this.referenceAccessId = referenceAccessId;
}
public int getId() {
this.id = bt.getId();
this.accessId = bt.getAccessId();
this.name = bt.getName();
this.version = bt.getVersion();
this.description = bt.getDescription();
this.released = bt.getReleased();
this.lockedBy = bt.getLockedBy();
this.lockedOn = bt.getLockedOn();
this.modifiedOn = bt.getModifiedOn();
this.smrFile = bt.getSmrFile();
this.contentVersion = bt.getContentVersion();
this.referenceAccessId = bt.getReferenceAccessId();
}
public Integer getId() {
return id;
}

public void setId(int id) {
public void setId(Integer id) {
this.id = id;
}

Expand Down
Loading

0 comments on commit 32056ed

Please sign in to comment.