diff --git a/CHANGELOG.md b/CHANGELOG.md
index c7b37e9..2bf065a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,6 @@
+## 2.1.X
+- OpenAPI used to generate simple ER service used by lookup test.
+
## 2.1.14
- Made changes to /generate end-point to improve efficiency how result of event generation is handled
diff --git a/openapi/pom.xml b/openapi/pom.xml
new file mode 100644
index 0000000..10fa7f5
--- /dev/null
+++ b/openapi/pom.xml
@@ -0,0 +1,107 @@
+
+
+
+ 4.0.0
+
+ com.github.eiffel-community
+ eiffel-remrem-generate
+ ${eiffel-remrem-generate.version}
+
+
+ com.github.eiffel-community
+ openapi
+ ${eiffel-remrem-generate.version}
+ generate-openapi-test
+
+
+
+ com.github.eiffel-community
+ eiffel-remrem-semantics
+ 2.2.7
+
+
+ org.springframework.boot
+ spring-boot-starter-validation
+ 2.7.7
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ org.springdoc
+ springdoc-openapi-ui
+ 1.6.14
+
+
+ org.springframework.boot
+ spring-boot-starter
+ 2.7.7
+
+
+ io.swagger
+ swagger-annotations
+ 1.6.3
+
+
+ org.openapitools
+ jackson-databind-nullable
+ 0.2.4
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+ org.openapitools
+ openapi-generator-maven-plugin
+ 5.4.0
+
+
+
+ generate
+
+
+ ${project.basedir}/src/main/resources/openapi-spec.yaml
+ spring
+ com.ericsson.eiffel.remrem.api
+ com.ericsson.eiffel.remrem.model
+
+ ApiUtil.java
+
+
+ true
+ true
+
+
+
+
+
+
+ org.codehaus.mojo
+ build-helper-maven-plugin
+ 3.2.0
+
+
+ add-client-sources
+ generate-sources
+
+ add-source
+
+
+
+ ${project.build.directory}/generated-sources/openapi/src/main/java
+
+
+
+
+
+
+
+
diff --git a/openapi/src/main/java/com/ericsson/eiffel/remrem/OpenApiApplication.java b/openapi/src/main/java/com/ericsson/eiffel/remrem/OpenApiApplication.java
new file mode 100644
index 0000000..2d39629
--- /dev/null
+++ b/openapi/src/main/java/com/ericsson/eiffel/remrem/OpenApiApplication.java
@@ -0,0 +1,13 @@
+package com.ericsson.eiffel.remrem;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+@SpringBootApplication
+public class OpenApiApplication {
+ public static void main(String[] args) {
+ SpringApplication.run(OpenApiApplication.class, args);
+ }
+}
diff --git a/openapi/src/main/java/com/ericsson/eiffel/remrem/api/EventsApiService.java b/openapi/src/main/java/com/ericsson/eiffel/remrem/api/EventsApiService.java
new file mode 100644
index 0000000..1076232
--- /dev/null
+++ b/openapi/src/main/java/com/ericsson/eiffel/remrem/api/EventsApiService.java
@@ -0,0 +1,168 @@
+package com.ericsson.eiffel.remrem.api;
+
+import com.ericsson.eiffel.remrem.model.InlineResponse200;
+import com.ericsson.eiffel.remrem.model.EiffelEvent;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.JsonMappingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.jayway.jsonpath.Configuration;
+import com.jayway.jsonpath.JsonPath;
+import com.jayway.jsonpath.JsonPathException;
+import com.jayway.jsonpath.PathNotFoundException;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.media.Schema;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.stereotype.Service;
+import org.springframework.web.bind.annotation.*;
+
+
+import javax.validation.Valid;
+import java.io.File;
+import java.io.IOException;
+import java.net.URI;
+import java.nio.file.*;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+@Service
+@RestController
+public class EventsApiService implements EventsApiDelegate {
+ static private List events = new ArrayList();
+
+ static {
+ loadEventsFromFiles();
+ }
+
+ public static void loadEventsFromFiles() {
+ String dir = "src/test/resources/ER/events";
+ File directory = new File(dir);
+ File[] files = directory.listFiles();
+
+ for (File file : files) {
+ if (!file.isFile())
+ continue;
+
+ String filename = file.getAbsolutePath();
+
+ try {
+ String event = loadEventFromFile(filename);
+ events.add(event);
+ }
+ catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ static String loadEventFromFile(String filename) throws IOException {
+ return new String(Files.readAllBytes(Paths.get(filename)));
+ }
+
+ @RequestMapping(
+ method = RequestMethod.GET,
+ value = "/events/{id}",
+ produces = { "application/json" }
+ )
+ public ResponseEntity getEventUsingGET(
+ @Parameter(name = "id", description = "Id of the event.", required = true, schema = @Schema(description = "")) @PathVariable("id") String id
+ ) {
+
+ for (String event : events) {
+ try {
+ Object document = Configuration.defaultConfiguration().jsonProvider().parse(event);
+ Object value = JsonPath.read(document, "$.id");
+ if (value.equals(id)) {
+ try {
+ ObjectMapper mapper = new ObjectMapper();
+ return new ResponseEntity<>(mapper.readValue(event, EiffelEvent.class), HttpStatus.OK);
+ } catch (JsonProcessingException e) {
+ return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
+ }
+ }
+ } catch (PathNotFoundException e) {
+ // The given property path doesn't exist. No need to continue, the event doesn't match
+ // given criteria...
+ continue;
+ } catch (JsonPathException e) {
+ // The given path is mangled. Maybe handling of this, more general exception, is sufficient,
+ // but I split the handling as I don't know if it can be useful in a future...
+ continue;
+ }
+ }
+
+ return new ResponseEntity<>(HttpStatus.NOT_FOUND);
+ }
+
+ @Override
+ @RequestMapping(
+ method = RequestMethod.GET,
+ value = "/events",
+ produces = { "application/json" }
+ )
+ public ResponseEntity getEventsUsingGET(
+ @Parameter(name = "pageSize", description = "The number of events to be displayed per page.", schema = @Schema(description = "", defaultValue = "500")) @Valid @RequestParam(value = "pageSize", required = false, defaultValue = "500") Integer pageSize,
+ @Parameter(name = "params", description = "", schema = @Schema(description = "")) @Valid @RequestParam(value = "", required = false) Map params) {
+ String keysToIgnore[] = { "pageSize", "shallow" };
+ ObjectMapper mapper = new ObjectMapper();
+ List matchedEvents = new ArrayList<>();
+ for (String event : events) {
+ boolean matches = true;
+ try {
+ Object document = Configuration.defaultConfiguration().jsonProvider().parse(event);
+ process_keys:
+ for (String key : params.keySet()) {
+ for (String keyToIgnore : keysToIgnore) {
+ if (key.equals(keyToIgnore))
+ // This isn't a property path; take another key.
+ continue process_keys;
+ }
+
+ String expected = params.get(key);
+ Object value = JsonPath.read(document, "$." + key);
+ if (expected == null || expected.equals(""))
+ // If value of query parameter is not present, don't compare value, just test
+ // if the property (given by key) exists. As the flow reached this point it means
+ // that the property exists (otherwise PathNotFoundException would have been thrown).
+ continue;
+
+ if (!value.equals(expected)) {
+ matches = false;
+ // The criteria is not matched. As they're treated as AND, no need to continue.
+ // Try another event.
+ break;
+ }
+ }
+ }
+ catch (PathNotFoundException e) {
+ // The given property path doesn't exist. No need to continue, the event doesn't match
+ // given criteria...
+ continue;
+ }
+ catch (JsonPathException e) {
+ // The given path is mangled. Maybe handling of this, more general exception, is sufficient,
+ // but I split the handling as I don't know if it can be useful in a future...
+ continue;
+ }
+
+ if (matches) {
+ try {
+ matchedEvents.add(mapper.readValue(event, EiffelEvent.class));
+ }
+ catch (JsonProcessingException e) {
+ // Something went wrong...
+ // TODO: Should INTERNAL SERVER ERROR be responded?
+ e.printStackTrace();
+ }
+ }
+ }
+
+ InlineResponse200 response = new InlineResponse200();
+ response.pageSize(1).pageNo(1).items(matchedEvents);
+ return new ResponseEntity<>(response, HttpStatus.OK);
+ }
+}
\ No newline at end of file
diff --git a/openapi/src/main/java/com/ericsson/eiffel/remrem/api/SearchApiService.java b/openapi/src/main/java/com/ericsson/eiffel/remrem/api/SearchApiService.java
new file mode 100644
index 0000000..763e25e
--- /dev/null
+++ b/openapi/src/main/java/com/ericsson/eiffel/remrem/api/SearchApiService.java
@@ -0,0 +1,52 @@
+package com.ericsson.eiffel.remrem.api;
+
+import com.ericsson.eiffel.remrem.model.InlineResponse2001;
+import com.ericsson.eiffel.remrem.model.SearchParameters;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.media.Content;
+import io.swagger.v3.oas.annotations.media.Schema;
+import io.swagger.v3.oas.annotations.responses.ApiResponse;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.context.request.NativeWebRequest;
+
+import javax.validation.Valid;
+import java.util.Optional;
+
+@RestController
+public class SearchApiService implements SearchApiDelegate {
+ @Override
+ public Optional getRequest() {
+ return SearchApiDelegate.super.getRequest();
+ }
+
+ @Override
+ @Operation(
+ operationId = "searchUsingPOST",
+ summary = "To get upstream/downstream events for an event based on the searchParameters passed",
+ tags = { "API" },
+ responses = {
+ @ApiResponse(responseCode = "200", description = "OK", content = @Content(mediaType = "application/json", schema = @Schema(implementation = InlineResponse2001.class))),
+ @ApiResponse(responseCode = "400", description = "Bad Request"),
+ @ApiResponse(responseCode = "401", description = "Unauthorized"),
+ @ApiResponse(responseCode = "403", description = "Forbidden"),
+ @ApiResponse(responseCode = "404", description = "Not Found"),
+ @ApiResponse(responseCode = "422", description = "Content Too Large - use the limit flag to limit the amount of events")
+ }
+ )
+ @RequestMapping(
+ method = RequestMethod.POST,
+ value = "/search/{id}",
+ produces = { "application/json" },
+ consumes = { "application/json" }
+ )
+ public ResponseEntity searchUsingPOST(
+ @Parameter(name = "id", description = "Id of the event.", required = true, schema = @Schema(description = "")) @PathVariable("id") String id,
+ @Parameter(name = "limit", description = "Determines the maximum amount of events to be fetched. Use `-1` for maximum amount of the events the server can provide. ", schema = @Schema(description = "", defaultValue = "-1")) @Valid @RequestParam(value = "limit", required = false, defaultValue = "-1") Integer limit,
+ @Parameter(name = "levels", description = "Determines the maximum amount of levels to search. Use `-1` for maximum amount of levels the server can search ", schema = @Schema(description = "", defaultValue = "-1")) @Valid @RequestParam(value = "levels", required = false, defaultValue = "-1") Integer levels,
+ @Parameter(name = "searchParameters", description = "Select what types of links you want upstream/downstream search to follow. Examples: * Select `CAUSE` if you only want the search to follow `CAUSE` links disregarding other links. * Select `CONTEXT` and `ACTIVITY_EXECUTION` if you want to follow both `CONTEXT` and `ACTIVITY_EXECUTION` links. Link Types: - CAUSE - CONTEXT - FLOW_CONTEXT - ACTIVITY_EXECUTION - PREVIOUS_ACTIVITY_EXECUTION - PREVIOUS_VERSION - COMPOSITION - ENVIRONMENT - ARTIFACT - SUBJECT - ELEMENT - BASE - CHANGE - TEST_SUITE_EXECUTION - TEST_CASE_EXECUTION - IUT - TERC - MODIFIED_ANNOUNCEMENT - SUB_CONFIDENCE_LEVEL - REUSED_ARTIFACT - VERIFICATION_BASIS - PRECURSOR - ORIGINAL_TRIGGER - CONFIGURATION - ALL **Example** In the following example `dlt` stands for downlink and `ult` stands for uplink ", schema = @Schema(description = "")) @Valid @RequestBody(required = false) SearchParameters searchParameters
+ ) {
+ return SearchApiDelegate.super.searchUsingPOST(id, limit, levels, searchParameters);
+ }
+}
diff --git a/openapi/src/main/resources/openapi-spec.yaml b/openapi/src/main/resources/openapi-spec.yaml
new file mode 100644
index 0000000..0bbd0ea
--- /dev/null
+++ b/openapi/src/main/resources/openapi-spec.yaml
@@ -0,0 +1,408 @@
+openapi: 3.0.1
+info:
+ title: Event Repository REST API
+ description: Event Repository REST API for retrieving the event information
+ contact: {}
+ version: 0.0.1
+tags:
+- name: API
+ description: Event Repository API
+
+servers:
+ - url: http://localhost:8080/api
+ description: "Tests server"
+
+paths:
+ /hohoho:
+ get:
+ tags:
+ - API
+ summary: To get all events information
+ operationId: getHohohoUsingGET
+ parameters:
+ - name: pageSize
+ in: query
+ required: false
+ description: "The number of events to be displayed per page."
+ schema:
+ type: integer
+ format: int32
+ default: 500
+ - name: params
+ in: query
+ required: false
+ schema:
+ type: object
+ additionalProperties:
+ type: string
+ responses:
+ 200:
+ description: Successfully retrieved the events
+ content:
+ application/json:
+ schema:
+ type: object
+ required:
+ - pageSize
+ - totalNumberItems
+ properties:
+ pageNo:
+ type: integer
+ example: 1
+ pageSize:
+ type: integer
+ example: 500
+ totalNumberItems:
+ type: integer
+ example: 1
+ items:
+ type: array
+ items:
+ $ref: "#/components/schemas/EiffelEvent"
+ /events:
+ get:
+ tags:
+ - API
+ summary: To get all events information
+ operationId: getEventsUsingGET
+ parameters:
+ - name: pageSize
+ in: query
+ required: false
+ description: "The number of events to be displayed per page."
+ schema:
+ type: integer
+ format: int32
+ default: 500
+ - name: params
+ in: query
+ required: false
+ description: |
+ To search for specific events or artifacts, filtering with parameters is supported.
+
+ **Syntax:**
+
+ `?key[.key ...]=value[&key[.key ...]=value ...]`
+
+ To traverse into nested structures and filter on their keys, namespacing with
+ `.` (dot) is used.
+
+ **Examples, single key:**
+
+ `/events?meta.type=EiffelActivityStartedEvent`
+
+ **Examples multiple keys:**
+
+ ```
+ /events?key1=value1&key2=value2
+ /events?key1=value1&key2=value2&key3=value3
+ ```
+
+ **Examples nested structures:**
+ ```
+ /events?data.identity=pkg:maven/my.namespace/my-name@1.0.0
+ /events?meta.source.domainId=my.domain&data.identity=pkg:maven/my.namespace/my-name@1.0.0 #Multiple keys and nested structures
+ ```
+
+ Note that multiple keys only is allowed with logical AND (via `&`). There are no support for logical OR.
+
+ **No comparator:**
+
+ To search for data that contains a field, use a query parameter
+ without comparator and value. For example `/events?key`fetches all
+ events who has `key` as a field in the JSON documents. Here are some
+ examples:
+
+ ```
+ /events?data.identity #Get all the events containing field 'identity' in the 'data'
+ /events?meta.source.domainId=my.domain&data.identity #DomainId is 'my.domain' and has field 'identity' in 'data'
+ ```
+
+ **Example**
+
+ The example provided in the `example` property of the `params` object adds two search parameters as two query keys (see https://swagger.io/docs/specification/serialization/ for more information).
+ The result of the object will result in adding `meta.type=EiffelArtifactCreatedEvent&data.identity=pkg%3Amaven%2Fmy.namespace%2Fmy-name%401.0.0` to the search.
+
+
+ schema:
+ type: object
+ additionalProperties:
+ type: string
+ style: form
+ explode: true
+ example: |
+ {
+ "meta.type":"EiffelArtifactCreatedEvent",
+ "data.identity":"pkg:maven/my.namespace/my-name@1.0.0"
+ }
+ responses:
+ 200:
+ description: Successfully retrieved the events
+ content:
+ application/json:
+ schema:
+ type: object
+ required:
+ - pageSize
+ - totalNumberItems
+ properties:
+ pageNo:
+ type: integer
+ example: 1
+ pageSize:
+ type: integer
+ example: 500
+ totalNumberItems:
+ type: integer
+ example: 1
+ items:
+ type: array
+ items:
+ $ref: "#/components/schemas/EiffelEvent"
+ 401:
+ description: Unauthorized
+ content: {}
+ 403:
+ description: Forbidden
+ content: {}
+ 404:
+ description: No events matching the given query were found
+ content: {}
+ 500:
+ description: Internal server issue
+ content: {}
+ /events/{id}:
+ get:
+ tags:
+ - API
+ summary: To get single event information
+ operationId: getEventUsingGET
+ parameters:
+ - name: id
+ in: path
+ description: "Id of the event."
+ required: true
+ schema:
+ type: string
+ responses:
+ 200:
+ description: Successfully retrieved the Event
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/EiffelEvent"
+ 400:
+ description: Wrong type given for parameter
+ content: {}
+ 401:
+ description: Unauthorized
+ content: {}
+ 403:
+ description: Forbidden
+ content: {}
+ 404:
+ description: The requested event is not found
+ content:
+ application/json:
+ schema:
+ type: object
+ properties:
+ errorMsg:
+ type: string
+ example: "The requested event is not found"
+ 500:
+ description: Internal server issue
+ content: {}
+ /search/{id}:
+ post:
+ tags:
+ - API
+ summary: To get upstream/downstream events for an event based on the searchParameters
+ passed
+ operationId: searchUsingPOST
+ parameters:
+ - name: id
+ in: path
+ description: "Id of the event."
+ required: true
+ schema:
+ type: string
+ - name: limit
+ in: query
+ description: >
+ Determines the maximum amount of events to be fetched.
+ Use `-1` for maximum amount of the events the server can provide.
+ required: false
+ schema:
+ type: integer
+ format: int32
+ default: -1
+ - name: levels
+ in: query
+ description: >
+ Determines the maximum amount of levels to search.
+ Use `-1` for maximum amount of levels the server can search
+ required: false
+ schema:
+ type: integer
+ format: int32
+ default: -1
+ requestBody:
+ description: |
+ Select what types of links you want upstream/downstream search to follow.
+
+ Examples:
+
+ * Select `CAUSE` if you only want the search to follow `CAUSE` links
+ disregarding other links.
+ * Select `CONTEXT` and `ACTIVITY_EXECUTION` if you want to follow both `CONTEXT`
+ and `ACTIVITY_EXECUTION` links.
+
+ Link Types:
+
+ - CAUSE
+ - CONTEXT
+ - FLOW_CONTEXT
+ - ACTIVITY_EXECUTION
+ - PREVIOUS_ACTIVITY_EXECUTION
+ - PREVIOUS_VERSION
+ - COMPOSITION
+ - ENVIRONMENT
+ - ARTIFACT
+ - SUBJECT
+ - ELEMENT
+ - BASE
+ - CHANGE
+ - TEST_SUITE_EXECUTION
+ - TEST_CASE_EXECUTION
+ - IUT
+ - TERC
+ - MODIFIED_ANNOUNCEMENT
+ - SUB_CONFIDENCE_LEVEL
+ - REUSED_ARTIFACT
+ - VERIFICATION_BASIS
+ - PRECURSOR
+ - ORIGINAL_TRIGGER
+ - CONFIGURATION
+ - ALL
+
+ **Example**
+
+ In the following example `dlt` stands for downlink and `ult` stands for uplink
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/SearchParameters'
+ required: false
+ responses:
+ 200:
+ description: OK
+ content:
+ application/json:
+ schema:
+ type: object
+ properties:
+ upstreamLinkObjects:
+ type: array
+ items:
+ $ref: "#/components/schemas/EiffelEvent"
+ downstreamLinkObjects:
+ type: array
+ items:
+ $ref: "#/components/schemas/EiffelEvent"
+ example:
+ upstreamLinkObjects:
+ - meta:
+ id: 1a4bc724-95f7-43c9-b5de-6348ddddbafe
+ type: EiffelCompositionDefinedEvent
+ version: 4.0.0
+ time: 657718729693
+ data:
+ name: My Composition
+ links:
+ - target: a77fc96e-847c-4828-9a16-2c2edd3c9580
+ type: ELEMENT
+ - meta:
+ id: a77fc96e-847c-4828-9a16-2c2edd3c9580
+ type: EiffelCompositionDefinedEvent
+ version: 4.0.0
+ time: 657718729600
+ data:
+ name: My Sub Composition
+ links: []
+ downstreamLinkObjects:
+ - meta:
+ id: 1a4bc724-95f7-43c9-b5de-6348ddddbafe
+ type: EiffelCompositionDefinedEvent
+ version: 4.0.0
+ time: 657718729693
+ data:
+ name: My Composition
+ links:
+ - target: a77fc96e-847c-4828-9a16-2c2edd3c9580
+ type: ELEMENT
+ - meta:
+ id: a55dc69d-662c-489f-af35-097b8b97ef02
+ type: EiffelCompositionDefinedEvent
+ version: 4.0.0
+ time: 657718729700
+ data:
+ name: My Top Composition
+ links:
+ - target: 1a4bc724-95f7-43c9-b5de-6348ddddbafe
+ type: ELEMENT
+ 400:
+ description: Bad Request
+ content: {}
+ 401:
+ description: Unauthorized
+ content: {}
+ 403:
+ description: Forbidden
+ content: {}
+ 404:
+ description: Not Found
+ content: {}
+ 422:
+ description: Content Too Large - use the limit flag to limit the amount of events
+ content: {}
+ x-codegen-request-body-name: searchParameters
+components:
+ schemas:
+ SearchParameters:
+ type: object
+ properties:
+ dlt:
+ type: array
+ items:
+ type: string
+ pattern: '^[A-Z_]+$'
+ default: ALL
+ ult:
+ type: array
+ items:
+ type: string
+ pattern: '^[A-Z_]+$'
+ default: ALL
+ EiffelEvent:
+ type: object
+ properties:
+ meta:
+ type: object
+ data:
+ type: object
+ links:
+ type: array
+ items:
+ type: object
+ example:
+ meta:
+ id: 1a4bc724-95f7-43c9-b5de-6348ddddbafe
+ type: EiffelCompositionDefinedEvent
+ version: 4.0.0
+ time: 657718729693
+ data:
+ name: "My Composition"
+ links:
+ - target: a77fc96e-847c-4828-9a16-2c2edd3c9580
+ type: ELEMENT
diff --git a/pom.xml b/pom.xml
index 76c4add..ddc13ec 100644
--- a/pom.xml
+++ b/pom.xml
@@ -28,6 +28,7 @@
cli
service
+ openapi
diff --git a/service/pom.xml b/service/pom.xml
index cf15585..30a3dbc 100644
--- a/service/pom.xml
+++ b/service/pom.xml
@@ -105,6 +105,12 @@
3.0.1
provided
+
+ com.github.eiffel-community
+ openapi
+ ${eiffel-remrem-generate.version}
+ test
+
diff --git a/service/src/test/java/com/ericsson/eiffel/remrem/generate/service/EiffelRemERLookupControllerUnitTest.java b/service/src/test/java/com/ericsson/eiffel/remrem/generate/service/EiffelRemERLookupControllerUnitTestWithMock.java
similarity index 99%
rename from service/src/test/java/com/ericsson/eiffel/remrem/generate/service/EiffelRemERLookupControllerUnitTest.java
rename to service/src/test/java/com/ericsson/eiffel/remrem/generate/service/EiffelRemERLookupControllerUnitTestWithMock.java
index b0e38ce..459a930 100644
--- a/service/src/test/java/com/ericsson/eiffel/remrem/generate/service/EiffelRemERLookupControllerUnitTest.java
+++ b/service/src/test/java/com/ericsson/eiffel/remrem/generate/service/EiffelRemERLookupControllerUnitTestWithMock.java
@@ -44,7 +44,7 @@
import com.google.gson.JsonParser;
@RunWith(SpringRunner.class)
-public class EiffelRemERLookupControllerUnitTest {
+public class EiffelRemERLookupControllerUnitTestWithMock {
@Mock
RestTemplate restTemplate;
diff --git a/service/src/test/java/com/ericsson/eiffel/remrem/generate/service/EiffelRemERLookupControllerUnitTestWithOpenAPI.java b/service/src/test/java/com/ericsson/eiffel/remrem/generate/service/EiffelRemERLookupControllerUnitTestWithOpenAPI.java
new file mode 100644
index 0000000..cd80c5c
--- /dev/null
+++ b/service/src/test/java/com/ericsson/eiffel/remrem/generate/service/EiffelRemERLookupControllerUnitTestWithOpenAPI.java
@@ -0,0 +1,244 @@
+/*
+ Copyright 2018 Ericsson AB.
+ For a full list of individual contributors, please see the commit history.
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+package com.ericsson.eiffel.remrem.generate.service;
+
+import com.ericsson.eiffel.remrem.OpenApiApplication;
+import com.ericsson.eiffel.remrem.generate.config.ErLookUpConfig;
+import com.ericsson.eiffel.remrem.generate.controller.RemremGenerateController;
+import com.ericsson.eiffel.remrem.protocol.MsgService;
+import com.ericsson.eiffel.remrem.semantics.EiffelEventType;
+import com.ericsson.eiffel.remrem.semantics.SemanticsService;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.*;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.builder.SpringApplicationBuilder;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.core.env.ConfigurableEnvironment;
+import org.springframework.core.env.PropertiesPropertySource;
+import org.springframework.core.env.StandardEnvironment;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.TestPropertySource;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+import org.springframework.web.client.RestTemplate;
+
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Properties;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+
+// Simulate enabled ER for lookup.
+@TestPropertySource(properties = {
+ "event-repository.enabled: true",
+ "event-repository.url: http://localhost:" + EiffelRemERLookupControllerUnitTestWithOpenAPI.ER_REST_API_PORT
+})
+
+// Start service
+@SpringBootTest(/*classes = OpenApiApplication.class,*/ webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration
+public class EiffelRemERLookupControllerUnitTestWithOpenAPI {
+ public static final String RESOURCES_DIR = "src/test/resources";
+ public static final String JSON_SUFFIX = ".json";
+ public static final String EIFFEL_SEMANTICS = "eiffelsemantics";
+
+ // Ideally, a dynamic port should have been used, but I don't know how to do that
+ // in this case.
+ public static final int ER_REST_API_PORT = 8765;
+
+ @Spy
+ ErLookUpConfig erLookupConfig;
+
+ @Autowired
+ RemremGenerateController unit = new RemremGenerateController();
+
+ MsgService service = new SemanticsService();
+ @Mock
+ MsgService service2;
+
+ @Spy
+ private List msgServices = new ArrayList<>();
+
+ static private SpringApplication erService;
+ static private int erServicePort = 0;
+
+ public void initErService() throws Exception {
+ if (erService != null)
+ return;
+
+ // Set to constant. Hopefully this will be randomly generated one day...
+ erServicePort = ER_REST_API_PORT;
+
+ // Create an OpenAPI having interface defined for ER.
+ erService = new SpringApplicationBuilder(OpenApiApplication.class).build();
+
+ Properties properties = new Properties();
+ properties.put("server.port", erServicePort);
+ ConfigurableEnvironment env = new StandardEnvironment();
+ env.getPropertySources().addFirst(new PropertiesPropertySource("initProps", properties));
+
+ erService.setEnvironment(env);
+ erService.run();
+ }
+
+ @SuppressWarnings("resource")
+ @Before
+ public void setUp() throws Exception {
+ initErService();
+
+ MockitoAnnotations.openMocks(this);
+
+ msgServices.add(service);
+ msgServices.add(service2);
+ }
+
+ /**
+ * Returns content of given event as an JsonObject.
+ *
+ * @param fileName Name of an event. Corresponding file named RESOURCE_DIR + "/" + fileName + JSON_SUFFIX
+ * is expected to contain the event data.
+ *
+ * @return A JsonObject representing given event.
+ *
+ * @throws IOException
+ */
+ private JsonObject inputAsJsonObject(String fileName) throws IOException {
+ File file = new File(RESOURCES_DIR + "/" + "ER/inputs/" + fileName + JSON_SUFFIX);
+ JsonObject json = JsonParser.parseReader(new FileReader(file)).getAsJsonObject();
+
+ return json;
+ }
+
+ @Test
+ public void testErLookupSuccessWithMultipleIds() throws Exception {
+ JsonObject json = inputAsJsonObject("success-lookup-confidence-level");
+ ResponseEntity> response = unit.generate(EIFFEL_SEMANTICS,
+ EiffelEventType.CONFIDENCELEVEL_MODIFIED.getEventName(),
+ false, false, true, 1, false, json);
+ assertEquals(HttpStatus.OK, response.getStatusCode());
+ }
+
+ @Test
+ public void testErLookupMultipleFound() throws Exception {
+ JsonObject json = inputAsJsonObject("fail-lookup-composition-defined");
+ ResponseEntity> response = unit.generate(EIFFEL_SEMANTICS,
+ EiffelEventType.COMPOSITION_DEFINED.getEventName(),
+ true, false, true, 1, false, json);
+ assertEquals(HttpStatus.EXPECTATION_FAILED, response.getStatusCode());
+ }
+
+ @Test
+ public void testErLookupMultipleTraces() throws Exception {
+ JsonObject json = inputAsJsonObject("fail-lookup-artifact-published");
+ ResponseEntity> response = unit.generate(EIFFEL_SEMANTICS,
+ EiffelEventType.ARTIFACT_PUBLISHED.getEventName(),
+ false, true, true, 1, false, json);
+ assertEquals(HttpStatus.BAD_REQUEST, response.getStatusCode());
+ }
+
+ @Test
+ public void testErLookupSuccessWithOneId() throws Exception {
+ JsonObject json = inputAsJsonObject("success-lookup-with-one-id");
+ ResponseEntity> result = unit.generate(EIFFEL_SEMANTICS,
+ EiffelEventType.COMPOSITION_DEFINED.getEventName(), true, true,
+ true, 1, false, json);
+ assertEquals(HttpStatus.OK, result.getStatusCode());
+ }
+
+ @Test
+ public void testErLookupNoneFound() throws Exception {
+ JsonObject json = inputAsJsonObject("fail-lookup-none-found");
+ ResponseEntity> result = unit.generate(EIFFEL_SEMANTICS,
+ EiffelEventType.COMPOSITION_DEFINED.getEventName(), true, true,
+ true, 1, false, json);
+ assertEquals(HttpStatus.NOT_ACCEPTABLE, result.getStatusCode());
+ }
+
+ @Test
+ public void testErLookupMultipleTrace() throws Exception {
+ JsonObject json = inputAsJsonObject("fail-lookup-multiple-trace");
+ ResponseEntity> response = unit.generate(EIFFEL_SEMANTICS,
+ EiffelEventType.SOURCECHANGE_SUBMITTED.getEventName(),
+ false, true, true,
+ 1, false, json);
+ assertEquals(HttpStatus.BAD_REQUEST, response.getStatusCode());
+ }
+
+ @Test
+ public void testErLookupOptions() throws Exception {
+ JsonObject json = inputAsJsonObject("success-lookup-multiple-with-options");
+ ResponseEntity> response = unit.generate(EIFFEL_SEMANTICS,
+ EiffelEventType.ENVIRONMENT_DEFINED.getEventName(),
+ false, false, true, 2, false, json);
+ assertEquals(HttpStatus.OK, response.getStatusCode());
+ }
+
+ @Test
+ public void testErLookupOptionsWithEmptyResponse() throws Exception {
+ JsonObject json = inputAsJsonObject("success-lookup-options-with-empty-response");
+ ResponseEntity> response = unit.generate(EIFFEL_SEMANTICS,
+ EiffelEventType.ENVIRONMENT_DEFINED.getEventName(), true, true, true, 2, false, json);
+ assertEquals(HttpStatus.OK, response.getStatusCode());
+ }
+
+ @Test
+ public void testErLookupOptionsWithMultipleFound() throws Exception {
+ JsonObject json = inputAsJsonObject("fail-lookup-options-with-multiple-found");
+ ResponseEntity> response = unit.generate(EIFFEL_SEMANTICS,
+ EiffelEventType.ENVIRONMENT_DEFINED.getEventName(),
+ false, false, true, 2, false, json);
+ assertEquals(HttpStatus.EXPECTATION_FAILED, response.getStatusCode());
+ }
+
+ @Test
+ public void testErLookupOptionsWithNoneFound() throws Exception {
+ JsonObject json = inputAsJsonObject("fail-lookup-options-with-none-found");
+ ResponseEntity> response = unit.generate(EIFFEL_SEMANTICS,
+ EiffelEventType.ENVIRONMENT_DEFINED.getEventName(),
+ false, false, true, 2, false, json);
+ assertEquals(HttpStatus.NOT_ACCEPTABLE, response.getStatusCode());
+ }
+
+ @Test
+ public void testErLookupFailedWithOptions() throws Exception {
+ JsonObject json = inputAsJsonObject("fail-lookup-with-options");
+ ResponseEntity> response = unit.generate(EIFFEL_SEMANTICS,
+ EiffelEventType.TESTCASE_STARTED.getEventName(),
+ false, false, true, 2, false, json);
+ assertEquals(HttpStatus.UNPROCESSABLE_ENTITY, response.getStatusCode());
+ }
+
+ @Test
+ public void testErLookUpLimitZero() throws Exception {
+ JsonObject json = inputAsJsonObject("fail-lookup-with-options");
+ ResponseEntity> response = unit.generate(EIFFEL_SEMANTICS,
+ EiffelEventType.TESTCASE_STARTED.getEventName(),
+ false, false, true, 0, false, json);
+ assertEquals(HttpStatus.BAD_REQUEST, response.getStatusCode());
+ }
+}
\ No newline at end of file
diff --git a/service/src/test/resources/ActivityFinished.json b/service/src/test/resources/ActivityFinished.json
index ed4bc50..6921590 100644
--- a/service/src/test/resources/ActivityFinished.json
+++ b/service/src/test/resources/ActivityFinished.json
@@ -1,52 +1,52 @@
{
- "msgParams": {
- "meta": {
- "type": "EiffelActivityFinishedEvent",
- "version": "3.0.0",
- "tags": [
- "tag1",
- "tag2"
- ],
- "source": {
- "domainId": "domainID",
- "host": "host",
- "name": "name",
- "uri": "http:\/\/java.sun.com\/j2se\/1.3\/"
- }
+ "meta": {
+ "id": "54afb9be-45b0-44fb-9230-54be6e71da79",
+ "type": "EiffelActivityFinishedEvent",
+ "version": "3.0.0",
+ "time": 1743684441445,
+ "tags": [
+ "tag1",
+ "tag2"
+ ],
+ "source": {
+ "domainId": "domainID",
+ "host": "host",
+ "name": "name",
+ "serializer": "pkg:maven/com.github.eiffel-community/eiffel-remrem-semantics@2.1.7",
+ "uri": "http://java.sun.com/j2se/1.3/"
}
},
- "eventParams": {
- "data": {
- "customData": [
- {
- "key": "firstLog",
- "value": "http:\/\/myHost.com\/firstLog"
- },
- {
- "key": "otherLog",
- "value": "http:\/\/myHost.com\/firstLog33"
- }
- ],
- "outcome": {
- "conclusion": "TIMED_OUT",
- "description": "Compilation timed out."
- },
- "persistentLogs": [
- {
- "name": "firstLog",
- "uri": "http:\/\/myHost.com\/firstLog"
- },
- {
- "name": "otherLog",
- "uri": "http:\/\/myHost.com\/firstLog33"
- }
- ]
+ "data": {
+ "outcome": {
+ "conclusion": "TIMED_OUT",
+ "description": "Compilation timed out."
},
- "links": [
+ "persistentLogs": [
+ {
+ "name": "firstLog",
+ "uri": "http://myHost.com/firstLog"
+ },
+ {
+ "name": "otherLog",
+ "uri": "http://myHost.com/firstLog33"
+ }
+ ],
+ "customData": [
+ {
+ "key": "firstLog",
+ "value": "http://myHost.com/firstLog"
+ },
{
- "type": "ACTIVITY_EXECUTION",
- "target": "aaaaaaaa-bbbb-5ccc-8ddd-eeeeeeeeeee1"
+ "key": "otherLog",
+ "value": "http://myHost.com/firstLog33"
}
]
- }
-}
\ No newline at end of file
+ },
+ "links": [
+ {
+ "type": "ACTIVITY_EXECUTION",
+ "target": "aaaaaaaa-bbbb-5ccc-8ddd-eeeeeeeeeee1"
+ }
+ ]
+}
+
diff --git a/service/src/test/resources/CompositionDefinedwith_SCCreatedResponse.json b/service/src/test/resources/CompositionDefinedwith_SCCreatedResponse.json
index f719eb3..2f88221 100644
--- a/service/src/test/resources/CompositionDefinedwith_SCCreatedResponse.json
+++ b/service/src/test/resources/CompositionDefinedwith_SCCreatedResponse.json
@@ -13,7 +13,7 @@
"data": {
"gitIdentifier": {
"commitId": "fd090b60a4aedc5161da9c035a49b14a319829b4",
- "branch": "myBranch",
+ "branch": "myBranch_hohoho",
"repoName": "myPrivateRepo",
"repoUri": "https://github.com/johndoe/myPrivateRepo.git"
},
diff --git a/service/src/test/resources/ER/README b/service/src/test/resources/ER/README
new file mode 100644
index 0000000..1d235a0
--- /dev/null
+++ b/service/src/test/resources/ER/README
@@ -0,0 +1,3 @@
+Events defined in the files must adhere to eiffel-remrem-semantics version
+specified in pom.xml. Otherwise some tests may fail during validation process
+done by generate service.
\ No newline at end of file
diff --git a/service/src/test/resources/ER/events/ArtifactCreated-1.json b/service/src/test/resources/ER/events/ArtifactCreated-1.json
new file mode 100644
index 0000000..8efafab
--- /dev/null
+++ b/service/src/test/resources/ER/events/ArtifactCreated-1.json
@@ -0,0 +1,65 @@
+{
+ "meta": {
+ "id": "76fea106-dfbc-473b-a9e6-968208db73ec",
+ "type": "EiffelArtifactCreatedEvent",
+ "version": "3.0.0",
+ "time": 1743684973864,
+ "tags": [
+ "tag1",
+ "tag2"
+ ],
+ "source": {
+ "domainId": "domainID",
+ "host": "host",
+ "name": "name",
+ "serializer": "pkg:maven",
+ "uri": "http://java.sun.com/j2se/1.3/"
+ },
+ "security": {
+ "authorIdentity": "test",
+ "sequenceProtection": []
+ }
+ },
+ "data": {
+ "identity": "pkg:maven/swdi.up/CXP102051_22@R21EK?type=xml",
+ "fileInformation": [
+ {
+ "name": "name",
+ "tags": []
+ }
+ ],
+ "buildCommand": "trigger",
+ "requiresImplementation": "NONE",
+ "dependsOn": [],
+ "implements": [],
+ "name": "event",
+ "customData": [
+ {
+ "key": "firstLog",
+ "value": "http://myHost.com/firstLog"
+ },
+ {
+ "key": "otherLog",
+ "value": "http://myHost.com/firstLog33"
+ }
+ ]
+ },
+ "links": [
+ {
+ "type": "CAUSE",
+ "target": "aaaaaaaa-bbbb-5ccc-8ddd-eeeeeeeeeee1"
+ },
+ {
+ "type": "PREVIOUS_VERSION",
+ "target": "aaaaaaaa-bbbb-5ccc-8ddd-eeeeeeeeeee2"
+ },
+ {
+ "type": "COMPOSITION",
+ "target": "aaaaaaaa-bbbb-5ccc-8ddd-eeeeeeeeeee1"
+ },
+ {
+ "type": "ENVIRONMENT",
+ "target": "aaaaaaaa-bbbb-5ccc-8ddd-eeeeeeeeeee3"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/service/src/test/resources/ER/events/ArtifactCreated-2.json b/service/src/test/resources/ER/events/ArtifactCreated-2.json
new file mode 100644
index 0000000..1a2f18b
--- /dev/null
+++ b/service/src/test/resources/ER/events/ArtifactCreated-2.json
@@ -0,0 +1,65 @@
+{
+ "meta": {
+ "id": "76fea106-dfbc-473b-a9e6-968208db73fd",
+ "type": "EiffelArtifactCreatedEvent",
+ "version": "3.0.0",
+ "time": 1743684973864,
+ "tags": [
+ "tag1",
+ "tag2"
+ ],
+ "source": {
+ "domainId": "domainID",
+ "host": "host",
+ "name": "name",
+ "serializer": "pkg:maven",
+ "uri": "http://java.sun.com/j2se/1.3/"
+ },
+ "security": {
+ "authorIdentity": "test",
+ "sequenceProtection": []
+ }
+ },
+ "data": {
+ "identity": "pkg:maven/swdi.up/CXP102051_22@R21EK?type=xml",
+ "fileInformation": [
+ {
+ "name": "name",
+ "tags": []
+ }
+ ],
+ "buildCommand": "trigger",
+ "requiresImplementation": "NONE",
+ "dependsOn": [],
+ "implements": [],
+ "name": "event",
+ "customData": [
+ {
+ "key": "firstLog",
+ "value": "http://myHost.com/firstLog"
+ },
+ {
+ "key": "otherLog",
+ "value": "http://myHost.com/firstLog33"
+ }
+ ]
+ },
+ "links": [
+ {
+ "type": "CAUSE",
+ "target": "aaaaaaaa-bbbb-5ccc-8ddd-eeeeeeeeeee1"
+ },
+ {
+ "type": "PREVIOUS_VERSION",
+ "target": "aaaaaaaa-bbbb-5ccc-8ddd-eeeeeeeeeee2"
+ },
+ {
+ "type": "COMPOSITION",
+ "target": "aaaaaaaa-bbbb-5ccc-8ddd-eeeeeeeeeee1"
+ },
+ {
+ "type": "ENVIRONMENT",
+ "target": "aaaaaaaa-bbbb-5ccc-8ddd-eeeeeeeeeee3"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/service/src/test/resources/ER/events/SourceChangeCreated-1.json b/service/src/test/resources/ER/events/SourceChangeCreated-1.json
new file mode 100644
index 0000000..9ebe9e4
--- /dev/null
+++ b/service/src/test/resources/ER/events/SourceChangeCreated-1.json
@@ -0,0 +1,36 @@
+{
+ "meta": {
+ "type": "EiffelSourceChangeCreatedEvent",
+ "version": "4.0.0",
+ "time": 1234567890,
+ "id": "aaaaaaaa-bbbb-5ccc-8ddd-eeeeeeeeeee6"
+ },
+ "data": {
+ "gitIdentifier": {
+ "commitId": "fd090b60a4aedc5161da9c035a49b14a319829b4",
+ "branch": "myBranch",
+ "repoName": "myPrivateRepo",
+ "repoUri": "https://github.com/johndoe/myPrivateRepo.git"
+ },
+ "author": {
+ "name": "John Doe",
+ "email": "john.doe@company.com",
+ "id": "johndoe",
+ "group": "Team Gophers"
+ },
+ "change": {
+ "files": "https://company.com/changes/fd090b60a4aedc5161da9c035a49b14a319829b4",
+ "insertions": 173,
+ "deletions": 79,
+ "tracker": "GitHub",
+ "details": "https://github.com/johndoe/myPrivateRepo/commit/fd090b60a4aedc5161da9c035a49b14a319829b4",
+ "id": "42"
+ }
+ },
+ "links": [
+ {
+ "type": "BASE",
+ "target": "aaaaaaaa-bbbb-5ccc-8ddd-eeeeeeeeeee1"
+ }
+ ]
+},
diff --git a/service/src/test/resources/ER/events/SourceChangeCreated-2.json b/service/src/test/resources/ER/events/SourceChangeCreated-2.json
new file mode 100644
index 0000000..24f77de
--- /dev/null
+++ b/service/src/test/resources/ER/events/SourceChangeCreated-2.json
@@ -0,0 +1,36 @@
+{
+ "meta": {
+ "type": "EiffelSourceChangeCreatedEvent",
+ "version": "4.0.0",
+ "time": 1234567890,
+ "id": "aaaaaaaa-bbbb-5ccc-8ddd-eeeeeeeeeee7"
+ },
+ "data": {
+ "gitIdentifier": {
+ "commitId": "fd090b60a4aedc5161da9c035a49b14a319829b5",
+ "branch": "myBranch",
+ "repoName": "myPrivateRepo",
+ "repoUri": "https://github.com/johndoe/myPrivateRepo.git"
+ },
+ "author": {
+ "name": "John Doe",
+ "email": "john.doe@company.com",
+ "id": "johndoe",
+ "group": "Team Gophers"
+ },
+ "change": {
+ "files": "https://company.com/changes/fd090b60a4aedc5161da9c035a49b14a319829b4",
+ "insertions": 173,
+ "deletions": 79,
+ "tracker": "GitHub",
+ "details": "https://github.com/johndoe/myPrivateRepo/commit/fd090b60a4aedc5161da9c035a49b14a319829b4",
+ "id": "42"
+ }
+ },
+ "links": [
+ {
+ "type": "BASE",
+ "target": "aaaaaaaa-bbbb-5ccc-8ddd-eeeeeeeeeee1"
+ }
+ ]
+},
diff --git a/service/src/test/resources/ER/events/SourceChangeSubmitted.json b/service/src/test/resources/ER/events/SourceChangeSubmitted.json
new file mode 100644
index 0000000..e7b0325
--- /dev/null
+++ b/service/src/test/resources/ER/events/SourceChangeSubmitted.json
@@ -0,0 +1,40 @@
+{
+ "meta": {
+ "id": "b80d73d6-e9b3-4e96-92dd-78030eeaf8b1",
+ "type": "EiffelSourceChangeSubmittedEvent",
+ "version": "3.0.0",
+ "time": 1744558318813,
+ "tags": [
+ ""
+ ],
+ "source": {
+ "domainId": "",
+ "host": "",
+ "name": "",
+ "serializer": "pkg:maven/com.github.eiffel-community/eiffel-remrem-semantics@2.1.7",
+ "uri": ""
+ }
+ },
+ "data": {
+ "submitter": {
+ "name": "Jane Doe",
+ "email": "jane.doe@company.com",
+ "id": "j_doe",
+ "group": "Team Wombats"
+ },
+ "gitIdentifier": {
+ "commitId": "fd090b60a4aedc5161da9c035a49b14a319829b4",
+ "branch": "",
+ "repoName": "",
+ "repoUri": "https://github.com/johndoe/myPrivateRepo.git"
+ },
+ "svnIdentifier": {
+ "revision": 42,
+ "directory": "trunk",
+ "repoName": "Mainline",
+ "repoUri": "svn://repohost/mainline"
+ },
+ "customData": []
+ },
+ "links": []
+}
\ No newline at end of file
diff --git a/service/src/test/resources/ER/inputs/fail-lookup-artifact-published.json b/service/src/test/resources/ER/inputs/fail-lookup-artifact-published.json
new file mode 100644
index 0000000..35dfadc
--- /dev/null
+++ b/service/src/test/resources/ER/inputs/fail-lookup-artifact-published.json
@@ -0,0 +1,42 @@
+{
+ "msgParams": {
+ "meta": {
+ "type": "EiffelArtifactPublishedEvent",
+ "version": "3.0.0",
+ "tags": [
+ ""
+ ],
+ "source": {
+ "domainId": "",
+ "host": "",
+ "name": "",
+ "uri": ""
+ }
+ }
+ },
+ "eventParams": {
+ "data": {
+ "locations": [{
+ "type": "OTHER",
+ "uri": "required"
+ }],
+ "customData": [
+
+ ]
+ },
+ "links": [{
+ "type": "ARTIFACT",
+ "%lookup%": {
+ "eventType": "EiffelArtifactCreatedEvent",
+ "properties": [{
+ "data.identity": "pkg:maven/swdi.up/CXP102051_22@R21EK?type=xml"
+ }]
+ }
+ },
+ {
+ "type": "CAUSE",
+ "target": "b5a2c3e0-3515-49d8-baa8-9b0f6cec025c"
+ }
+ ]
+ }
+}
diff --git a/service/src/test/resources/ER/inputs/fail-lookup-composition-defined.json b/service/src/test/resources/ER/inputs/fail-lookup-composition-defined.json
new file mode 100644
index 0000000..1595fd2
--- /dev/null
+++ b/service/src/test/resources/ER/inputs/fail-lookup-composition-defined.json
@@ -0,0 +1,35 @@
+{
+ "msgParams": {
+ "meta": {
+ "type": "EiffelCompositionDefinedEvent",
+ "version": "3.0.0",
+ "tags": [
+ ""
+ ],
+ "source": {
+ "domainId": "",
+ "host": "",
+ "name": "",
+ "uri": ""
+ }
+ }
+ },
+ "eventParams": {
+ "data": {
+ "name": "required",
+ "version": "",
+ "customData": [
+
+ ]
+ },
+ "links": [{
+ "type": "ELEMENT",
+ "%lookup%": {
+ "eventType": "EiffelArtifactCreatedEvent",
+ "properties": [{
+ "data.identity": "pkg:maven/swdi.up/CXP102051_22@R21EK?type=xml"
+ }]
+ }
+ }]
+ }
+}
\ No newline at end of file
diff --git a/service/src/test/resources/ER/inputs/fail-lookup-multiple-trace.json b/service/src/test/resources/ER/inputs/fail-lookup-multiple-trace.json
new file mode 100644
index 0000000..a64d6f3
--- /dev/null
+++ b/service/src/test/resources/ER/inputs/fail-lookup-multiple-trace.json
@@ -0,0 +1,66 @@
+{
+ "msgParams": {
+ "meta": {
+ "type": "EiffelSourceChangeSubmittedEvent",
+ "version": "3.0.0",
+ "tags": [
+ ""
+ ],
+ "source": {
+ "domainId": "",
+ "host": "",
+ "name": "",
+ "uri": ""
+ }
+ }
+ },
+ "eventParams": {
+ "data": {
+
+ "gitIdentifier": {
+ "commitId": "fd090b60a4aedc5161da9c035a49b14a319829b4",
+ "repoUri": "https://github.com/johndoe/myPrivateRepo.git",
+ "branch": "",
+ "repoName": ""
+ },
+ "svnIdentifier": {
+ "revision": 42,
+ "directory": "trunk",
+ "repoName": "Mainline",
+ "repoUri": "svn://repohost/mainline"
+ },
+ "submitter": {
+ "name": "Jane Doe",
+ "email": "jane.doe@company.com",
+ "id": "j_doe",
+ "group": "Team Wombats"
+ },
+ "customData": [
+
+ ]
+ },
+ "links": [{
+ "type": "CHANGE",
+ "%lookup%": {
+ "eventType": "EiffelSourceChangeCreatedEvent",
+ "properties": [{
+ "data.gitIdentifier.branch": "myBranch",
+ "data.gitIdentifier.repoUri": "https://github.com/johndoe/myPrivateRepo.git"
+ }]
+ }
+ },
+ {
+ "type": "PREVIOUS_VERSION",
+ "target": "aaaaaaaa-bbbb-5ccc-8ddd-eeeeeeeeeee6"
+ },
+ {
+ "type": "FLOW_CONTEXT",
+ "target": "aaaaaaaa-bbbb-5ccc-8ddd-eeeeeeeeeee5"
+ },
+ {
+ "type": "FLOW_CONTEXT",
+ "target": "aaaaaaaa-bbbb-5ccc-8ddd-eeeeeeeeeee6"
+ }
+ ]
+ }
+}
\ No newline at end of file
diff --git a/service/src/test/resources/ER/inputs/fail-lookup-none-found.json b/service/src/test/resources/ER/inputs/fail-lookup-none-found.json
new file mode 100644
index 0000000..b971185
--- /dev/null
+++ b/service/src/test/resources/ER/inputs/fail-lookup-none-found.json
@@ -0,0 +1,36 @@
+{
+ "msgParams": {
+ "meta": {
+ "type": "EiffelCompositionDefinedEvent",
+ "version": "3.1.0",
+ "tags": [
+ ""
+ ],
+ "source": {
+ "domainId": "",
+ "host": "",
+ "name": "",
+ "uri": ""
+ }
+ }
+ },
+ "eventParams": {
+ "data": {
+ "name": "required",
+ "version": "",
+ "customData": [
+
+ ]
+ },
+ "links": [{
+ "type": "ELEMENT",
+ "%lookup%": {
+ "eventType": "EiffelSourceChangeSubmittedEvent",
+ "properties": [{
+ "data.gitIdentifier.commitId": "fd090b60aedc535a49b14a",
+ "data.gitIdentifier.repoUri": "https://github.com/johndoe/myPrivateRepo.git"
+ }]
+ }
+ }]
+ }
+}
\ No newline at end of file
diff --git a/service/src/test/resources/ER/inputs/fail-lookup-options-with-multiple-found.json b/service/src/test/resources/ER/inputs/fail-lookup-options-with-multiple-found.json
new file mode 100644
index 0000000..a0087eb
--- /dev/null
+++ b/service/src/test/resources/ER/inputs/fail-lookup-options-with-multiple-found.json
@@ -0,0 +1,52 @@
+{
+ "msgParams": {
+ "meta": {
+ "type": "EiffelCompositionDefinedEvent",
+ "version": "3.0.0",
+ "tags": [
+ ""
+ ],
+ "source": {
+ "domainId": "",
+ "host": "",
+ "name": "",
+ "uri": ""
+ }
+ }
+ },
+ "eventParams": {
+ "data": {
+ "name": "required",
+ "version": "",
+ "customData": [
+
+ ]
+ },
+ "links": [{
+ "type": "ELEMENT",
+ "%lookup%": {
+ "eventType": "EiffelArtifactCreatedEvent",
+ "properties": [{
+ "data.identity": "pkg:maven/swdi.up/CXP102051_22@R21EK?type=xml"
+ }],
+ "options": {
+ "failIfNoneFound": "true",
+ "failIfMultipleFound": "true"
+ }
+ }
+ },{
+ "type": "CAUSE",
+ "%lookup%": {
+ "eventType": "EiffelSourceChangeSubmittedEvent",
+ "properties": [{
+ "data.gitIdentifier.commitId": "ad090b60a4aedc5161da9c035a49b14a319829b4",
+ "data.gitIdentifier.repoUri": "https://github.com/johndoe/myPrivateRepo.git"
+ }],
+ "options": {
+ "failIfNoneFound": "false",
+ "failIfMultipleFound": "true"
+ }
+ }
+ }]
+ }
+}
\ No newline at end of file
diff --git a/service/src/test/resources/ER/inputs/fail-lookup-options-with-none-found.json b/service/src/test/resources/ER/inputs/fail-lookup-options-with-none-found.json
new file mode 100644
index 0000000..38db3e5
--- /dev/null
+++ b/service/src/test/resources/ER/inputs/fail-lookup-options-with-none-found.json
@@ -0,0 +1,55 @@
+{
+ "msgParams": {
+ "meta": {
+ "type": "EiffelConfidenceLevelModifiedEvent",
+ "version": "3.0.0",
+ "tags": [
+ ""
+ ],
+ "source": {
+ "domainId": "",
+ "host": "",
+ "name": "",
+ "uri": ""
+ }
+ }
+ },
+ "eventParams": {
+ "data": {
+ "name": "0",
+ "value": "SUCCESS",
+ "issuer": {
+ "name": "",
+ "email": "",
+ "id": "",
+ "group": ""
+ },
+ "customData": [
+
+ ]
+ },
+ "links": [{
+ "type": "SUBJECT",
+ "%lookup%": {
+ "eventType": "EiffelArtifactCreatedEvent",
+ "properties": [{
+ "data.identity": "pkg:maven/swdi.up/CXP102051_22@R21EK?type=xml&classifier=test"
+ }]
+ }
+ },
+ {
+ "type": "CAUSE",
+ "%lookup%": {
+ "eventType": "EiffelSourceChangeSubmittedEvent",
+ "properties": [{
+ "data.gitIdentifier.commitId": "ad090b60a4aedc5161da9c035a49b14a319829e1",
+ "data.gitIdentifier.repoUri": "https://github.com/myPrivateRepo.git"
+ }],
+ "options": {
+ "failIfNoneFound": "true"
+ }
+ }
+ }
+ ]
+ }
+}
\ No newline at end of file
diff --git a/service/src/test/resources/ER/inputs/fail-lookup-with-options.json b/service/src/test/resources/ER/inputs/fail-lookup-with-options.json
new file mode 100644
index 0000000..d41cd6c
--- /dev/null
+++ b/service/src/test/resources/ER/inputs/fail-lookup-with-options.json
@@ -0,0 +1,54 @@
+{
+ "msgParams": {
+ "meta": {
+ "type": "EiffelTestCaseStartedEvent",
+ "version": "3.0.0",
+ "tags": [
+ ""
+ ],
+ "source": {
+ "domainId": "",
+ "host": "",
+ "name": "",
+ "uri": ""
+ }
+ }
+ },
+ "eventParams": {
+ "data": {
+ "executor": "",
+ "liveLogs": [],
+ "customData": []
+ },
+ "links": [
+ {
+ "type": "TEST_CASE_EXECUTION",
+ "%lookup%": {
+ "eventType": "EiffelArtifactCreatedEvent",
+ "properties": [{
+ "data.identity": "pkg:maven/swdi.up/CXP102051_22@R21EK?type=xml"
+ }],
+ "options": {
+ "failIfNoneFound": "true",
+ "failIfMultipleFound": "false",
+ "unsupportedOption": "true"
+ }
+ }
+ },
+ {
+ "type": "CAUSE",
+ "%lookup%": {
+ "eventType": "EiffelSourceChangeSubmittedEvent",
+ "properties": [{
+ "data.gitIdentifier.commitId": "ad090b60a4aedc5161da9c035a49b14a319829b4",
+ "data.gitIdentifier.repoUri": "https://github.com/johndoe/myPrivateRepo.git"
+ }],
+ "options": {
+ "failIfNoneFound": "true",
+ "falIfMultipleFoud": "true"
+ }
+ }
+ }
+ ]
+ }
+}
\ No newline at end of file
diff --git a/service/src/test/resources/ER/inputs/success-lookup-confidence-level.json b/service/src/test/resources/ER/inputs/success-lookup-confidence-level.json
new file mode 100644
index 0000000..1f5875b
--- /dev/null
+++ b/service/src/test/resources/ER/inputs/success-lookup-confidence-level.json
@@ -0,0 +1,46 @@
+{
+ "msgParams": {
+ "meta": {
+ "type": "EiffelConfidenceLevelModifiedEvent",
+ "version": "3.0.0",
+ "tags": [
+ ""
+ ],
+ "source": {
+ "domainId": "",
+ "host": "",
+ "name": "",
+ "uri": ""
+ }
+ }
+ },
+ "eventParams": {
+ "data": {
+ "name": "0",
+ "value": "SUCCESS",
+ "issuer": {
+ "name": "",
+ "email": "",
+ "id": "",
+ "group": ""
+ },
+ "customData": [
+
+ ]
+ },
+ "links": [{
+ "type": "SUBJECT",
+ "target": "b5a2c3e0-3515-49d8-baa8-9b0f6cec025c"
+ },
+ {
+ "type": "SUBJECT",
+ "%lookup%": {
+ "eventType": "EiffelArtifactCreatedEvent",
+ "properties": [{
+ "data.identity": "swdi.up/CXP102051_22@R21EK"
+ }]
+ }
+ }
+ ]
+ }
+}
\ No newline at end of file
diff --git a/service/src/test/resources/ER/inputs/success-lookup-multiple-with-options.json b/service/src/test/resources/ER/inputs/success-lookup-multiple-with-options.json
new file mode 100644
index 0000000..4af186d
--- /dev/null
+++ b/service/src/test/resources/ER/inputs/success-lookup-multiple-with-options.json
@@ -0,0 +1,50 @@
+
+{
+ "msgParams": {
+ "meta": {
+ "type": "EiffelEnvironmentDefinedEvent",
+ "version": "3.0.0",
+ "tags": [
+ ""
+ ],
+ "source": {
+ "domainId": "",
+ "host": "",
+ "name": "",
+ "uri": ""
+ }
+ }
+ },
+ "eventParams": {
+ "data": {
+ "name": "required",
+ "version": "",
+ "image": "",
+ "customData": [],
+ "uri": ""
+ },
+ "links": [{
+ "type": "PREVIOUS_VERSION",
+ "%lookup%": {
+ "eventType": "EiffelArtifactCreatedEvent",
+ "properties": [{
+ "data.identity": "pkg:maven/swdi.up/CXP102051_22@R21EK?type=xml"
+ }],
+ "options": {
+ "failIfNoneFound": "true"
+ }
+ }
+ },
+ {
+ "type": "CAUSE",
+ "%lookup%": {
+ "eventType": "EiffelSourceChangeSubmittedEvent",
+ "properties": [{
+ "data.gitIdentifier.commitId": "ad090b60a4aedc5161da9c035a49b14a319829b4",
+ "data.gitIdentifier.repoUri": "https://github.com/johndoe/myPrivateRepo.git"
+ }]
+ }
+ }
+ ]
+ }
+}
\ No newline at end of file
diff --git a/service/src/test/resources/ER/inputs/success-lookup-options-with-empty-response.json b/service/src/test/resources/ER/inputs/success-lookup-options-with-empty-response.json
new file mode 100644
index 0000000..790ba6d
--- /dev/null
+++ b/service/src/test/resources/ER/inputs/success-lookup-options-with-empty-response.json
@@ -0,0 +1,53 @@
+
+{
+ "msgParams": {
+ "meta": {
+ "type": "EiffelEnvironmentDefinedEvent",
+ "version": "3.0.0",
+ "tags": [
+ ""
+ ],
+ "source": {
+ "domainId": "",
+ "host": "",
+ "name": "",
+ "uri": ""
+ }
+ }
+ },
+ "eventParams": {
+ "data": {
+ "name": "required",
+ "version": "",
+ "image": "",
+ "customData": [],
+ "uri": ""
+ },
+ "links": [{
+ "type": "PREVIOUS_VERSION",
+ "%lookup%": {
+ "eventType": "EiffelArtifactCreatedEvent",
+ "properties": [{
+ "data.identity": "pkg:maven/swdi.up/CXP102051_22@R21EK?classifier=test"
+ }],
+ "options": {
+ "failIfNoneFound": "false"
+ }
+ }
+ },
+ {
+ "type": "CAUSE",
+ "%lookup%": {
+ "eventType": "EiffelSourceChangeSubmittedEvent",
+ "properties": [{
+ "data.gitIdentifier.commitId": "ad090b60a4aedc5161da9c035a49b14a319829e1",
+ "data.gitIdentifier.repoUri": "https://github.com/myPrivateRepo.git"
+ }],
+ "options": {
+ "failIfNoneFound": "false"
+ }
+ }
+ }
+ ]
+ }
+}
\ No newline at end of file
diff --git a/service/src/test/resources/ER/inputs/success-lookup-with-one-id.json b/service/src/test/resources/ER/inputs/success-lookup-with-one-id.json
new file mode 100644
index 0000000..7c7e4cc
--- /dev/null
+++ b/service/src/test/resources/ER/inputs/success-lookup-with-one-id.json
@@ -0,0 +1,36 @@
+{
+ "msgParams": {
+ "meta": {
+ "type": "EiffelCompositionDefinedEvent",
+ "version": "3.1.0",
+ "tags": [
+ ""
+ ],
+ "source": {
+ "domainId": "",
+ "host": "",
+ "name": "",
+ "uri": ""
+ }
+ }
+ },
+ "eventParams": {
+ "data": {
+ "name": "required",
+ "version": "",
+ "customData": [
+
+ ]
+ },
+ "links": [{
+ "type": "ELEMENT",
+ "%lookup%": {
+ "eventType": "EiffelSourceChangeCreatedEvent",
+ "properties": [{
+ "data.gitIdentifier.commitId": "fd090b60a4aedc5161da9c035a49b14a319829b4",
+ "data.gitIdentifier.repoUri": "https://github.com/johndoe/myPrivateRepo.git"
+ }]
+ }
+ }]
+ }
+}
\ No newline at end of file
diff --git a/service/src/test/resources/application.yml b/service/src/test/resources/application.yml
index 900e927..d153ee8 100644
--- a/service/src/test/resources/application.yml
+++ b/service/src/test/resources/application.yml
@@ -5,4 +5,7 @@ spring:
activedirectory:
enabled: true
domain:
- url:
\ No newline at end of file
+ url:
+event-repository:
+ url: http://localhost:8080
+ enabled: true
\ No newline at end of file