Skip to content

Commit

Permalink
Merge pull request #66 from com-pas/develop
Browse files Browse the repository at this point in the history
Merge Develop to Main (Release)
  • Loading branch information
Dennis Labordus authored Aug 24, 2021
2 parents 3641696 + 9712ce5 commit f71cef5
Show file tree
Hide file tree
Showing 9 changed files with 128 additions and 17 deletions.
2 changes: 2 additions & 0 deletions MAPPING.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ There is an IEC document describing the mapping, namely IEC/TS 62361-102, but no
| *cim:VoltageLevel* | *TVoltageLevel* | |
| name or id | name | |
| nominalV | voltage.value | |
| 'k' | voltage.multiplier | |
| 'V' | voltage.unit | |
| List<Bay> | List<TBay> | (1) |

(1): The list of Bays that belong to the VoltageLevel.
Expand Down
9 changes: 9 additions & 0 deletions app/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,10 @@ SPDX-License-Identifier: Apache-2.0
<groupId>io.quarkus</groupId>
<artifactId>quarkus-resteasy</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-smallrye-jwt</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-smallrye-openapi</artifactId>
Expand Down Expand Up @@ -88,6 +92,11 @@ SPDX-License-Identifier: Apache-2.0
<artifactId>quarkus-junit5-mockito</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-test-security</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.rest-assured</groupId>
<artifactId>rest-assured</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,13 @@
// SPDX-License-Identifier: Apache-2.0
package org.lfenergy.compas.cim.mapping.rest.v1;

import io.quarkus.security.Authenticated;
import io.quarkus.security.identity.SecurityIdentity;
import org.lfenergy.compas.cim.mapping.rest.v1.model.MapRequest;
import org.lfenergy.compas.cim.mapping.rest.v1.model.MapResponse;
import org.lfenergy.compas.cim.mapping.service.CompasCimMappingService;

import javax.enterprise.context.RequestScoped;
import javax.inject.Inject;
import javax.validation.Valid;
import javax.ws.rs.Consumes;
Expand All @@ -15,10 +18,15 @@
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

@Authenticated
@RequestScoped
@Path("/cim/v1/")
public class CompasCimMappingResource {
private CompasCimMappingService compasCimMappingService;

@Inject
SecurityIdentity securityIdentity;

@Inject
public CompasCimMappingResource(CompasCimMappingService compasCimMappingService) {
this.compasCimMappingService = compasCimMappingService;
Expand All @@ -30,7 +38,7 @@ public CompasCimMappingResource(CompasCimMappingService compasCimMappingService)
@Produces(MediaType.APPLICATION_XML)
public MapResponse mapCimToScl(@Valid MapRequest request) {
var response = new MapResponse();
response.setScl(compasCimMappingService.map(request.getCimData()));
response.setScl(compasCimMappingService.map(request.getCimData(), securityIdentity.getPrincipal()));
return response;
}
}
15 changes: 15 additions & 0 deletions app/src/main/resources/application.properties
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,18 @@ quarkus.log.category."org.lfenergy.compas.cim.mapping".level = INFO

%dev.quarkus.log.level = DEBUG
%dev.quarkus.log.category."org.lfenergy.compas.cim.mapping".level = DEBUG

# Smallrye JWT Properties (Microprofile)
smallrye.jwt.verify.key.location = ${JWT_VERIFY_KEY:http://localhost:8089/auth/realms/compas/protocol/openid-connect/certs}
mp.jwt.verify.issuer = ${JWT_VERIFY_ISSUER:http://localhost:8089/auth/realms/compas}
mp.jwt.verify.audiences = ${JWT_VERIFY_CLIENT_ID:cim-mapping}
smallrye.jwt.path.groups = ${JWT_GROUPS_PATH:resource_access/cim-mapping/roles}

quarkus.http.auth.permission.deny-default.paths=/*
quarkus.http.auth.permission.deny-default.policy=deny

quarkus.http.auth.permission.allow-quarkus-services.paths=/compas-cim-mapping/q/health/live,/compas-cim-mapping/q/health/ready,/compas-cim-mapping/q/openapi
quarkus.http.auth.permission.allow-quarkus-services.policy=permit

quarkus.http.auth.permission.common.paths=/compas-cim-mapping/cim/v1/*
quarkus.http.auth.permission.common.policy=authenticated
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import io.quarkus.test.common.http.TestHTTPEndpoint;
import io.quarkus.test.junit.QuarkusTest;
import io.quarkus.test.junit.mockito.InjectMock;
import io.quarkus.test.security.TestSecurity;
import io.restassured.http.ContentType;
import org.junit.jupiter.api.Test;
import org.lfenergy.compas.cim.mapping.model.CimData;
Expand All @@ -17,6 +18,7 @@
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.security.Principal;
import java.util.List;

import static io.restassured.RestAssured.given;
Expand All @@ -29,6 +31,7 @@

@QuarkusTest
@TestHTTPEndpoint(CompasCimMappingResource.class)
@TestSecurity(user = "test-mapper")
class CompasCimMappingResourceTest {
@InjectMock
private CompasCimMappingService compasCimMappingService;
Expand All @@ -44,7 +47,7 @@ void mapCimToScl_WhenCalled_ThenCorrectMessageIsRetrieved() throws IOException {

var scl = new SCL();
scl.setVersion("2007");
when(compasCimMappingService.map(any())).thenReturn(scl);
when(compasCimMappingService.map(any(), any(Principal.class))).thenReturn(scl);

var response = given()
.contentType(ContentType.XML)
Expand All @@ -62,7 +65,7 @@ void mapCimToScl_WhenCalled_ThenCorrectMessageIsRetrieved() throws IOException {
var sclVersion = xmlPath.getString("cms:MapResponse.scl:SCL.@version");
assertNotNull(sclVersion);
assertEquals("2007", sclVersion);
verify(compasCimMappingService, times(1)).map(any());
verify(compasCimMappingService, times(1)).map(any(), any(Principal.class));
}

private String readFile() throws IOException {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@ protected void afterSubstationToTSubstation(CgmesSubstation substation,

@Mapping(target = "name", source = "nameOrId")
@Mapping(target = "voltage.value", source = "nominalV")
@Mapping(target = "voltage.multiplier", constant = "k")
@Mapping(target = "voltage.unit", constant = "V")
protected abstract TVoltageLevel mapVoltageLevelToTVoltageLevel(CgmesVoltageLevel voltageLevel,
@Context CimToSclMapperContext context);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,26 @@
import org.lfenergy.compas.scl2007b4.model.ObjectFactory;
import org.lfenergy.compas.scl2007b4.model.SCL;
import org.lfenergy.compas.scl2007b4.model.THeader;
import org.lfenergy.compas.scl2007b4.model.THitem;

import javax.enterprise.context.ApplicationScoped;
import javax.inject.Inject;
import java.security.Principal;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;

/**
* Mapping Service to process the passed CIM XML(s) (RDF Format) and convert these to a IIDM Model
* that is used to create a IEC SCL Model, including some basic data being filled in the Header.
*/
@ApplicationScoped
public class CompasCimMappingService {
private static final String INITIAL_VERSION = "0.0.1";
private static final String INITIAL_REVISION = "";

private final CgmesCimReader cgmesCimReader;
private final CimToSclMapper cimToSclMapper;

Expand All @@ -35,11 +43,12 @@ public CompasCimMappingService(CgmesCimReader cgmesCimReader,
/**
* Map the passed CIM XML to IEC SCL Model.
*
* @param cimData The CIM XML Data.
* @param cimData The CIM XML Data.
* @param principal
* @return The created SCL Model.
*/
public SCL map(List<CimData> cimData) {
var scl = createBasicSCL();
public SCL map(List<CimData> cimData, Principal principal) {
var scl = createBasicSCL(cimData, principal);

if (cimData != null && !cimData.isEmpty()) {
// Convert the Data to the Network Model from PowSyBl
Expand All @@ -55,20 +64,41 @@ public SCL map(List<CimData> cimData) {
*
* @return The created SCL Model.
*/
SCL createBasicSCL() {
SCL createBasicSCL(List<CimData> cimData, Principal principal) {
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd'T'hh:mm:ss");
ObjectFactory factory = new ObjectFactory();

// Create the SCL and set some default values.
var scl = factory.createSCL();
scl.setVersion("2007");
scl.setRevision("B");
scl.setRelease((short) 4);

// Create the Header and set some default values.
THeader header = factory.createTHeader();
header.setId(UUID.randomUUID().toString());
header.setVersion("1.0.0");
header.setVersion(INITIAL_VERSION);
header.setRevision(INITIAL_REVISION);
header.setHistory(new THeader.History());
scl.setHeader(header);

// Add a History Item with info about who/when/what created the SCL.
var item = new THitem();
item.setVersion(INITIAL_VERSION);
item.setRevision(INITIAL_REVISION);
item.setWhen(formatter.format(new Date()));
item.setWho(principal.getName());

// Add all CIM filenames that where used to create the SCL Content.
String what = "SCL created from CIM File(s)";
if (cimData != null && !cimData.isEmpty()) {
what += ": " + cimData.stream()
.map(CimData::getName)
.collect(Collectors.joining(", "));
}
item.setWhat(what);
header.getHistory().getHitem().add(item);

return scl;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,8 @@ void map_WhenWithCimData_ThenSclMapped() throws IOException {
assertEquals("S1 380kV", voltageLevel.getName());
assertNotNull(voltageLevel.getVoltage());
assertEquals(BigDecimal.valueOf(380.0), voltageLevel.getVoltage().getValue());
assertEquals("k", voltageLevel.getVoltage().getMultiplier());
assertEquals("V", voltageLevel.getVoltage().getUnit());

assertEquals(3, voltageLevel.getBay().size());
var bay = voltageLevel.getBay().get(0);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,20 @@
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;

import java.security.Principal;
import java.util.Collections;
import java.util.List;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.*;

@ExtendWith(MockitoExtension.class)
class CompasCimMappingServiceTest {
@Mock
private CgmesModel cgmesModel;
@Mock
private Principal principal;

@Mock
private CgmesCimReader cgmesCimReader;
Expand All @@ -41,7 +43,7 @@ void map_WhenCalledWithData_ThenReaderAndMapperAreCalled() {
when(cgmesCimReader.readModel(any())).thenReturn(cgmesModel);

var cimDataList = List.of(new CimData());
var scl = compasCimMappingService.map(cimDataList);
var scl = compasCimMappingService.map(cimDataList, principal);

assertNotNull(scl);
verify(cgmesCimReader, times(1)).readModel(cimDataList);
Expand All @@ -51,30 +53,68 @@ void map_WhenCalledWithData_ThenReaderAndMapperAreCalled() {

@Test
void map_WhenCalledWithoutData_ThenReaderAndMapperAreNotCalled() {
var scl = compasCimMappingService.map(Collections.emptyList());
var scl = compasCimMappingService.map(Collections.emptyList(), principal);

assertNotNull(scl);
verifyNoInteractions(cgmesCimReader, cimToSclMapper);
}

@Test
void map_WhenCalledWithNullValue_ThenReaderAndMapperAreNotCalled() {
var scl = compasCimMappingService.map(null);
var scl = compasCimMappingService.map(null, principal);

assertNotNull(scl);
verifyNoInteractions(cgmesCimReader, cimToSclMapper);
}

@Test
void createBasicSCL_WhenCalled_ThenNewSCLInstanceReturnedWithPartsFilled() {
var scl = compasCimMappingService.createBasicSCL();
void createBasicSCL_WhenCalledWithData_ThenNewSCLInstanceReturnedWithPartsFilled() {
var cimData = new CimData();
cimData.setName("FILE1.xml");
var cimDataList = List.of(cimData);

createBasicSCL_WhenCalled_ThenExpectedName(cimDataList);
}

@Test
void createBasicSCL_WhenCalledWithoutData_ThenNewSCLInstanceReturnedWithPartsFilled() {
createBasicSCL_WhenCalled_ThenExpectedName(Collections.emptyList());
}

@Test
void createBasicSCL_WhenCalledWithNullValue_ThenNewSCLInstanceReturnedWithPartsFilled() {
createBasicSCL_WhenCalled_ThenExpectedName(null);
}

private void createBasicSCL_WhenCalled_ThenExpectedName(List<CimData> cimDataList) {
var expectedName = "Mr. Name";
when(principal.getName()).thenReturn(expectedName);

var scl = compasCimMappingService.createBasicSCL(cimDataList, principal);

assertNotNull(scl);
assertEquals("2007", scl.getVersion());
assertEquals("B", scl.getRevision());
assertEquals((short) 4, scl.getRelease());

assertNotNull(scl.getHeader());
assertNotNull(scl.getHeader().getHistory());
var header = scl.getHeader();
assertNotNull(header);
assertNotNull(header.getId());
assertEquals("0.0.1", header.getVersion());
assertEquals("", header.getRevision());

assertNotNull(header.getHistory());
assertEquals(1, header.getHistory().getHitem().size());

var item = header.getHistory().getHitem().get(0);
assertEquals("0.0.1", item.getVersion());
assertEquals("", item.getRevision());
assertNotNull(item.getWhen());
assertEquals(expectedName, item.getWho());

assertNotNull(item.getWhat());
if (cimDataList != null && !cimDataList.isEmpty()) {
cimDataList.forEach(cimData -> assertTrue(item.getWhat().contains(cimData.getName())));
}
}
}

0 comments on commit f71cef5

Please sign in to comment.