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