From f467b5c21468f35427088a4e66e434d4e204d96b Mon Sep 17 00:00:00 2001 From: Roman Szturc Date: Wed, 17 Apr 2024 16:09:13 +0200 Subject: [PATCH 1/2] Support of default domain added --- .../controller/RemremGenerateController.java | 118 ++++++++++++++++++ .../src/main/resources/application.properties | 4 +- .../EiffelRemERLookupControllerUnitTest.java | 24 ++-- .../EiffelRemremControllerUnitTest.java | 12 +- .../src/test/resources/ActivityFinished.json | 8 +- 5 files changed, 143 insertions(+), 23 deletions(-) diff --git a/service/src/main/java/com/ericsson/eiffel/remrem/generate/controller/RemremGenerateController.java b/service/src/main/java/com/ericsson/eiffel/remrem/generate/controller/RemremGenerateController.java index 9d5d0ba7..653c2873 100644 --- a/service/src/main/java/com/ericsson/eiffel/remrem/generate/controller/RemremGenerateController.java +++ b/service/src/main/java/com/ericsson/eiffel/remrem/generate/controller/RemremGenerateController.java @@ -18,6 +18,7 @@ import com.ericsson.eiffel.remrem.generate.constants.RemremGenerateServiceConstants; import com.ericsson.eiffel.remrem.generate.exception.REMGenerateException; import com.ericsson.eiffel.remrem.protocol.MsgService; +import com.ericsson.eiffel.remrem.semantics.schemas.EiffelConstants; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.google.gson.JsonArray; @@ -77,6 +78,11 @@ public class RemremGenerateController { @Value("${lenientValidationEnabledToUsers:false}") private boolean lenientValidationEnabledToUsers; + public static final String PARAM_GENERATE_EIFFEL_DOMAIN_ID = "generate.eiffel.domainId"; + @Value("${" + PARAM_GENERATE_EIFFEL_DOMAIN_ID + ":#{null}}") + private String defaultDomainId; + private boolean defaultDomainIdStripped = false; + public void setLenientValidationEnabledToUsers(boolean lenientValidationEnabledToUsers) { this.lenientValidationEnabledToUsers = lenientValidationEnabledToUsers; } @@ -87,6 +93,115 @@ public void setRestTemplate(RestTemplate restTemplate) { this.restTemplate = restTemplate; } + // TODO Should be moved to semantics library + public static final String EiffelConstants_SOURCE = "source"; + public static final String EiffelConstants_ID = "id"; + public static final String EiffelConstants_DOMAIN_ID = "domainId"; + + private static final String DOMAIN_ID_FULL_PATH = EiffelConstants.META + "." + + EiffelConstants_SOURCE + "." + EiffelConstants_DOMAIN_ID; + + private String getDefaultDomainId() { + if (defaultDomainId != null && !defaultDomainIdStripped) { + String strippedDefaultDomainId = defaultDomainId.strip(); + defaultDomainIdStripped = true; + if (strippedDefaultDomainId.isBlank()) { + defaultDomainId = null; + log.error("Value of configuration parameter '" + PARAM_GENERATE_EIFFEL_DOMAIN_ID + + "' is blank ('" + strippedDefaultDomainId + "'); ignoring..."); + } + } + + return defaultDomainId; + } + + protected void addDomainId(JsonObject generated, String domainId) { + // Handle default domain ID. + JsonObject meta = generated.getAsJsonObject().getAsJsonObject(EiffelConstants.META); + if (meta == null) { + // Nothing to do. + log.warn("Generated event doesn't contain '" + EiffelConstants.META + "' section; strange..."); + return; + } + + JsonElement idElement = meta.get(EiffelConstants_ID); + String id = null; + if (idElement != null) { + id = idElement.getAsString(); + } + + JsonObject source = meta.getAsJsonObject(EiffelConstants_SOURCE); + if (source == null) { + // Nothing to do. + log.warn("[" + id + "] Generated event doesn't contain '" + EiffelConstants.META + + "." + EiffelConstants_SOURCE + "' section; strange..."); + return; + } + + // Is domainId present in generated event? + JsonElement existingDomainIdElement = source.get(EiffelConstants_DOMAIN_ID); + String existingDomainId = null; + String strippedExistingDomainId = null; + boolean existingDomainIdIsValid = false; + if (existingDomainIdElement != null) { + existingDomainId = existingDomainIdElement.getAsString(); + strippedExistingDomainId = existingDomainId.strip(); + existingDomainIdIsValid = !strippedExistingDomainId.isBlank(); + } + + String defaultDomainId = getDefaultDomainId(); + String domainIdToSet = null; + String domainIdInfoMessage = null; + if (domainId != null) { + // Use domain ID passed as REST API param. This is the highest-priority + // value and is used whenever available. + String strippedDomainId = domainId.strip(); + if (!strippedDomainId.isBlank()) { + domainIdToSet = strippedDomainId; + domainIdInfoMessage = "[" + id + "] Setting '" + DOMAIN_ID_FULL_PATH + "' to '" + domainIdToSet + + "', value of RESTAPI param '" + RESTAPI_PARAM_DOMAIN_ID + "'"; + } + else { + log.warn("Value of REST API parameter '" + RESTAPI_PARAM_DOMAIN_ID + "' is blank; ignoring..."); + } + } + else { + // Domain id not specified by REST API or its value is not valid. + // Try to use default value from configuration file. + if (defaultDomainId != null) { + // Default value is available. + if (existingDomainIdIsValid) { + // Value of domainId in generated event exists and is valid, keep it. + } + else { + domainIdToSet = defaultDomainId; + + domainIdInfoMessage = "[" + id + "] Setting '" + DOMAIN_ID_FULL_PATH + "' to '" + domainIdToSet + + "', value of configuration param '" + PARAM_GENERATE_EIFFEL_DOMAIN_ID + "'"; + } + } + } + + if (domainIdToSet != null) { + if (existingDomainIdElement != null) { + if (domainIdToSet == defaultDomainId && !existingDomainIdIsValid) { + // Value of domainId of generated event is not valid and will be replaced + // by defaultDomainId. + log.warn("[" + id + "] Element '" + DOMAIN_ID_FULL_PATH + "' of event exists," + + "but is invalid ('" + existingDomainId + "') and will be replaced"); + } + + // Element domainId already exists, remove it first. + source.remove(EiffelConstants_DOMAIN_ID); + } + + log.info(domainIdInfoMessage); + source.addProperty(EiffelConstants_DOMAIN_ID, domainIdToSet); + } + } + + public static final String RESTAPI_PARAM_DOMAIN_ID = "domainId"; + /** * Returns event information as json element based on the message protocol, * taking message type and json body as input. @@ -113,6 +228,7 @@ public ResponseEntity generate( @ApiParam(value = RemremGenerateServiceConstants.LOOKUP_IN_EXTERNAL_ERS) @RequestParam(value = "lookupInExternalERs", required = false, defaultValue = "false") final Boolean lookupInExternalERs, @ApiParam(value = RemremGenerateServiceConstants.LOOKUP_LIMIT) @RequestParam(value = "lookupLimit", required = false, defaultValue = "1") final int lookupLimit, @ApiParam(value = RemremGenerateServiceConstants.LenientValidation) @RequestParam(value = "okToLeaveOutInvalidOptionalFields", required = false, defaultValue = "false") final Boolean okToLeaveOutInvalidOptionalFields, + @ApiParam(value = "Domain ID") @RequestParam(value = RESTAPI_PARAM_DOMAIN_ID, required = false, defaultValue = "") final String domainId, @ApiParam(value = "JSON message", required = true) @RequestBody JsonObject bodyJson) { try { @@ -122,6 +238,8 @@ public ResponseEntity generate( if (msgService != null) { response = msgService.generateMsg(msgType, bodyJson, isLenientEnabled(okToLeaveOutInvalidOptionalFields)); JsonElement parsedResponse = parser.parse(response); + addDomainId(parsedResponse.getAsJsonObject(), domainId); + if(lookupLimit <= 0) { return new ResponseEntity<>("LookupLimit must be greater than or equals to 1", HttpStatus.BAD_REQUEST); } diff --git a/service/src/main/resources/application.properties b/service/src/main/resources/application.properties index 157ee167..944c367c 100644 --- a/service/src/main/resources/application.properties +++ b/service/src/main/resources/application.properties @@ -28,4 +28,6 @@ event-repository.enabled: false event-repository.url: http://:/ # lenientValidationEnabledToUsers true will perform the validation only on mandatory fields, non-mandatory validation failures add into Eiffel message as property remremGenerateFailures -lenientValidationEnabledToUsers: false \ No newline at end of file +lenientValidationEnabledToUsers: false + +generate.source.domainId: test-domain 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/EiffelRemERLookupControllerUnitTest.java index b0e38cea..9e57a75a 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/EiffelRemERLookupControllerUnitTest.java @@ -218,7 +218,7 @@ public void testErlookupSuccesswithMultipleIds() throws Exception { JsonParser parser = new JsonParser(); JsonObject json = parser.parse(new FileReader(file)).getAsJsonObject(); - ResponseEntity elem = unit.generate("eiffelsemantics", "eiffelconfidencelevel", false, false, true, 1, false, json); + ResponseEntity elem = unit.generate("eiffelsemantics", "eiffelconfidencelevel", false, false, true, 1, false, null, json); assertEquals(elem.getStatusCode(), HttpStatus.OK); } @@ -229,7 +229,7 @@ public void testErlookupMultipleFound() throws Exception { JsonParser parser = new JsonParser(); JsonObject json = parser.parse(new FileReader(file)).getAsJsonObject(); - ResponseEntity elem = unit.generate("eiffelsemantics", "eiffelcompositiondefined", true, false, true, 1, false, json); + ResponseEntity elem = unit.generate("eiffelsemantics", "eiffelcompositiondefined", true, false, true, 1, false, null, json); assertEquals(elem.getStatusCode(), HttpStatus.EXPECTATION_FAILED); } @@ -239,7 +239,7 @@ public void testErlookupMultipleTraces() throws Exception { JsonParser parser = new JsonParser(); JsonObject json = parser.parse(new FileReader(file)).getAsJsonObject(); - ResponseEntity elem = unit.generate("eiffelsemantics", "eiffelartifactpublished", false, true, true, 1, false, json); + ResponseEntity elem = unit.generate("eiffelsemantics", "eiffelartifactpublished", false, true, true, 1, false, null, json); assertEquals(elem.getStatusCode(), HttpStatus.BAD_REQUEST); } @@ -249,7 +249,7 @@ public void testErlookupSuccesswithOneId() throws Exception { JsonParser parser = new JsonParser(); JsonObject json = parser.parse(new FileReader(file)).getAsJsonObject(); - ResponseEntity elem = unit.generate("eiffelsemantics", "eiffelCompositionDefined", true, true, true, 1, false, json); + ResponseEntity elem = unit.generate("eiffelsemantics", "eiffelCompositionDefined", true, true, true, 1, false, null, json); assertEquals(elem.getStatusCode(), HttpStatus.OK); } @@ -259,7 +259,7 @@ public void testErlookupNoneFound() throws Exception { JsonParser parser = new JsonParser(); JsonObject json = parser.parse(new FileReader(file)).getAsJsonObject(); - ResponseEntity elem = unit.generate("eiffelsemantics", "eiffelCompositionDefinedEvent", true, true, true, 1, false, json); + ResponseEntity elem = unit.generate("eiffelsemantics", "eiffelCompositionDefinedEvent", true, true, true, 1, false, null, json); assertEquals(elem.getStatusCode(), HttpStatus.NOT_ACCEPTABLE); } @@ -269,7 +269,7 @@ public void testErlookupMultipleTrace() throws Exception { JsonParser parser = new JsonParser(); JsonObject json = parser.parse(new FileReader(file)).getAsJsonObject(); - ResponseEntity elem = unit.generate("eiffelsemantics", "eiffelSCSubmitted", false, true, true, 1, false, json); + ResponseEntity elem = unit.generate("eiffelsemantics", "eiffelSCSubmitted", false, true, true, 1, false, null, json); assertEquals(elem.getStatusCode(), HttpStatus.BAD_REQUEST); } @@ -279,7 +279,7 @@ public void testErlookupOptions() throws Exception { JsonParser parser = new JsonParser(); JsonObject json = parser.parse(new FileReader(file)).getAsJsonObject(); - ResponseEntity elem = unit.generate("eiffelsemantics", "eiffelEnvironmentDefined", false, false, true, 2, false, json); + ResponseEntity elem = unit.generate("eiffelsemantics", "eiffelEnvironmentDefined", false, false, true, 2, false, null, json); assertEquals(elem.getStatusCode(), HttpStatus.OK); } @@ -289,7 +289,7 @@ public void testErlookupOptionsWithEmptyResponse() throws Exception { JsonParser parser = new JsonParser(); JsonObject json = parser.parse(new FileReader(file)).getAsJsonObject(); - ResponseEntity elem = unit.generate("eiffelsemantics", "eiffelEnvironmentDefinedEvent", true, true, true, 2, false, json); + ResponseEntity elem = unit.generate("eiffelsemantics", "eiffelEnvironmentDefinedEvent", true, true, true, 2, false, null, json); assertEquals(elem.getStatusCode(), HttpStatus.OK); } @@ -299,7 +299,7 @@ public void testErlookupOptionsWithMultipleFound() throws Exception { JsonParser parser = new JsonParser(); JsonObject json = parser.parse(new FileReader(file)).getAsJsonObject(); - ResponseEntity elem = unit.generate("eiffelsemantics", "eiffelCompositionDefinedEventt", false, false, true, 2, false, json); + ResponseEntity elem = unit.generate("eiffelsemantics", "eiffelCompositionDefinedEventt", false, false, true, 2, false, null, json); assertEquals(elem.getStatusCode(), HttpStatus.EXPECTATION_FAILED); } @@ -309,7 +309,7 @@ public void testErlookupOptionsWithNoneFound() throws Exception { JsonParser parser = new JsonParser(); JsonObject json = parser.parse(new FileReader(file)).getAsJsonObject(); - ResponseEntity elem = unit.generate("eiffelsemantics", "eiffelConfidenceLevelModified", false, false, true, 2, false, json); + ResponseEntity elem = unit.generate("eiffelsemantics", "eiffelConfidenceLevelModified", false, false, true, 2, false, null, json); assertEquals(elem.getStatusCode(), HttpStatus.NOT_ACCEPTABLE); } @@ -319,7 +319,7 @@ public void testErlookupFailedWithOptions() throws Exception { JsonParser parser = new JsonParser(); JsonObject json = parser.parse(new FileReader(file)).getAsJsonObject(); - ResponseEntity elem = unit.generate("eiffelsemantics", "eiffelTestCaseStarted", false, false, true, 2, false, json); + ResponseEntity elem = unit.generate("eiffelsemantics", "eiffelTestCaseStarted", false, false, true, 2, false, null, json); assertEquals(elem.getStatusCode(), HttpStatus.UNPROCESSABLE_ENTITY); } @@ -329,7 +329,7 @@ public void testErLookUpLimitZero() throws Exception { JsonParser parser = new JsonParser(); JsonObject json = parser.parse(new FileReader(file)).getAsJsonObject(); - ResponseEntity elem = unit.generate("eiffelsemantics", "eiffelTestCaseStarted", false, false, true, 0, false, json); + ResponseEntity elem = unit.generate("eiffelsemantics", "eiffelTestCaseStarted", false, false, true, 0, false, null, json); assertEquals(elem.getStatusCode(), HttpStatus.BAD_REQUEST); } } \ No newline at end of file diff --git a/service/src/test/java/com/ericsson/eiffel/remrem/generate/service/EiffelRemremControllerUnitTest.java b/service/src/test/java/com/ericsson/eiffel/remrem/generate/service/EiffelRemremControllerUnitTest.java index a2c1deac..8b9d4677 100644 --- a/service/src/test/java/com/ericsson/eiffel/remrem/generate/service/EiffelRemremControllerUnitTest.java +++ b/service/src/test/java/com/ericsson/eiffel/remrem/generate/service/EiffelRemremControllerUnitTest.java @@ -111,38 +111,38 @@ public void setUp() throws Exception { @Test public void testSemanticsSuccessEvent() throws Exception { - ResponseEntity elem = unit.generate("eiffelsemantics", "eiffelactivityfinished", false, false, true, 1, false, body.getAsJsonObject()); + ResponseEntity elem = unit.generate("eiffelsemantics", "eiffelactivityfinished", false, false, true, 1, false, null, body.getAsJsonObject()); assertEquals(elem.getStatusCode(), HttpStatus.OK); } @Test public void testSemanticsFailureEvent() throws Exception { - ResponseEntity elem = unit.generate("eiffelsemantics", "EiffelActivityFinished", false, false, true, 1, false, body.getAsJsonObject()); + ResponseEntity elem = unit.generate("eiffelsemantics", "EiffelActivityFinished", false, false, true, 1, false, null, body.getAsJsonObject()); assertEquals(elem.getStatusCode(), HttpStatus.BAD_REQUEST); } @Test public void testEiffel3SuccessEvent() throws Exception { - ResponseEntity elem = unit.generate("eiffel3", "eiffelartifactnew", false, false, true, 1, false, body.getAsJsonObject()); + ResponseEntity elem = unit.generate("eiffel3", "eiffelartifactnew", false, false, true, 1, false, null, body.getAsJsonObject()); assertEquals(elem.getStatusCode(), HttpStatus.OK); } @Test public void testEiffel3FailureEvent() throws Exception { - ResponseEntity elem = unit.generate("eiffel3", "eiffelartifactnewevent", false, false, true, 1, false, body.getAsJsonObject()); + ResponseEntity elem = unit.generate("eiffel3", "eiffelartifactnewevent", false, false, true, 1, false, null, body.getAsJsonObject()); assertEquals(elem.getStatusCode(), HttpStatus.BAD_REQUEST); } @Test public void testMessageServiceUnavailableEvent() throws Exception { - ResponseEntity elem = unit.generate("other", "EiffelActivityFinishedEvent", false, false, true, 1, false, body.getAsJsonObject()); + ResponseEntity elem = unit.generate("other", "EiffelActivityFinishedEvent", false, false, true, 1, false, null, body.getAsJsonObject()); assertEquals(elem.getStatusCode(), HttpStatus.SERVICE_UNAVAILABLE); } @Test public void testlenientValidation() throws Exception { unit.setLenientValidationEnabledToUsers(true); - ResponseEntity elem = unit.generate("eiffelsemantics", "EiffelArtifactCreatedEvent", false, false, true, 1, true, body.getAsJsonObject()); + ResponseEntity elem = unit.generate("eiffelsemantics", "EiffelArtifactCreatedEvent", false, false, true, 1, true, null, body.getAsJsonObject()); assertEquals(elem.getStatusCode(), HttpStatus.OK); } diff --git a/service/src/test/resources/ActivityFinished.json b/service/src/test/resources/ActivityFinished.json index ed4bc50e..a39f91b2 100644 --- a/service/src/test/resources/ActivityFinished.json +++ b/service/src/test/resources/ActivityFinished.json @@ -2,16 +2,16 @@ "msgParams": { "meta": { "type": "EiffelActivityFinishedEvent", - "version": "3.0.0", + "version": "4.0.0", "tags": [ - "tag1", - "tag2" + "tag2", + "tag3" ], "source": { "domainId": "domainID", "host": "host", "name": "name", - "uri": "http:\/\/java.sun.com\/j2se\/1.3\/" + "uri": "http:\/\/java.sun.com\/j3se\/1.3\/" } } }, From abbb358283e8c9e388a383084b8272581cb8ea71 Mon Sep 17 00:00:00 2001 From: Roman Szturc Date: Tue, 30 Apr 2024 08:16:55 +0200 Subject: [PATCH 2/2] Documentation added --- CHANGELOG.md | 3 ++ wiki/markdown/usage/configuration.md | 21 +++++++- wiki/markdown/usage/service.md | 74 +++++++++++++++++++++++++--- 3 files changed, 90 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6c96269c..714c9e8a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +## 2.1.11 +- REST API parameter `domainId` added. + ## 2.1.10 - Mockito framework upgraded to 5.3.1 diff --git a/wiki/markdown/usage/configuration.md b/wiki/markdown/usage/configuration.md index a1549286..8f52c2db 100644 --- a/wiki/markdown/usage/configuration.md +++ b/wiki/markdown/usage/configuration.md @@ -30,7 +30,7 @@ When using maven command, Spring properties can also be changed by editing servi Eiffel REMReM Service **generate-service.war** file should be deployed in Tomcat Server. For doing this, generate-service.war file should deployed in directory: _tomcat/webapps_. -Configuration is done in Tomcat using a config.properties file: _tomcat/conf/config.properties_. +Configuration is done in Tomcat using a config.properties file:�_tomcat/conf/config.properties_. **NOTE:** in each example assuming the generate-service.war is deployed in tomcat as **generate**. @@ -164,3 +164,22 @@ More about [Lenient Validation](../usage/lenientvalidation.md). ``` lenientValidationEnabledToUsers : ``` + +### Configuration of Default Domain Identifier +Default domain identifier can be specified using property `generate.source.domainId`: +``` +generate.source.domainId: +``` +The default domain ID is used by endpoint `/` and presents it as value of property +`msgParams.meta.source.domainId` unless the property is specified by submitted +template or REST API param `domainId` of request to endpoint `/`. + +Note, that domain identifier can be submitted in several ways: +1. application property `generate.source.domainId`; +2. REST API request parameter `domainId`, see section [Usage](../service.md#usage); +3. property `msgParams.meta.source.domainId` sent as part of REST API parameter bodyJson. + +and they are prioritized like follows: +* if case 3. is specified, cases 2. and 1. are ignored; +* if case 2. is submitted, case 1. is ignored; +* domain id given by case 1. is used when neither case 3. nor case 2. is applied. \ No newline at end of file diff --git a/wiki/markdown/usage/service.md b/wiki/markdown/usage/service.md index 81cb92ab..00ee330e 100644 --- a/wiki/markdown/usage/service.md +++ b/wiki/markdown/usage/service.md @@ -25,15 +25,75 @@ http://localhost:8080/generate/ Configuration of REMReM Generate can be found [here](configuration.md) +## Usage Available REST resources for REMReM Generate Service are described below: -| Resource | Method | Parameters | Request body | Description | -|-----------------------|--------|---------------------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| /mp | POST | mp - message protocol, required msgType - Eiffel event type, required failIfMultipleFound - default: false failIfNoneFound - default: false, lookupInExternalERs - default: false, lookupLimit - default: 1 *lookupLimit must be greater than or equals to 1, okToLeaveOutInvalidOptionalFields - default: false| { "msgParams": {"meta": {# Matches the meta object }},"eventParams": {"data": {# Matches the data object},"links": { # Matches the links object } }} | This endpoint is used to generate Eiffel events and then the obtained event could be published by [Eiffel REMReM Publish](https://github.com/eiffel-community/eiffel-remrem-publish). | -| /event_types/{mp} | GET | mp - message protocol, required | | This endpoint is used to obtain Eiffel event types implemented in [Eiffel REMReM Semantics](https://github.com/eiffel-community/eiffel-remrem-semantics). | -| /template/{type}/{mp} | GET | type - Eiffel event type mp - message protocol, required | | This endpoint is used to obtain Eiffel event templates implemented in [Eiffel REMReM Semantics](https://github.com/eiffel-community/eiffel-remrem-semantics). | -| /versions | GET | | | This endpoint is used to get versions of generate service and all loaded protocols versions in JSON format. | -| /message_protocols | GET | |This endpoint is used to obtain the message protocols list and edition names in JSON format. | +### `/{mp}` +This endpoint is used to generate Eiffel events and then the obtained event could be published by [Eiffel REMReM Publish](https://github.com/eiffel-community/eiffel-remrem-publish). + +##### HTTP Method +POST + +| Name | Description | Required | Default value | +|-------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------|---------------------| +| `mp` | Message protocol. | yes || +| `msgType` | Eiffel event type. | yes || +| `domainId` | Eiffel domain identificator. | no | | +| `failIfMultipleFound` | If value is set to `true` and multiple event ids are found through any of the provided lookup definitions, then no event will be generated. | no | `false` | +| `failIfNoneFound` | If value is set to `true` and no event id is found through (at least one of) the provided lookup definitions, then no event will be generated. | no | `false` | +| `lookupInExternalERs` | If value is set to `true` then REMReM will query external ERs and not just the locally used ER. The reason for the default value to be `false` is to decrease the load on external ERs. Here local ER means single ER which is using REMReM generate. External ER means multiple ER's which are configured in local ER. | no | `false` | +| `lookupLimit` | The number of events returned, through any lookup definition given, is limited to this number. | no | `1` | +| `okToLeaveOutInvalidOptionalFields` | | no | `false` | + +##### Request +``` +{ + "msgParams": { + "meta": {# Matches the meta object } + }, + "eventParams": { + "data": {# Matches the data object}, + "links": { # Matches the links object } + } +} +``` + +### `/versions` +This endpoint is used to get versions of publish service and all loaded protocols. + +##### HTTP Method +GET + + +### `/event_types/{mp}` +#This endpoint is used to obtain Eiffel event types implemented in [Eiffel REMReM Semantics](https://github.com/eiffel-community/eiffel-remrem-semantics). + +##### HTTP Method +GET + +| Name | Description | Required | Default value | +|-------------------------------------|-------------------|------------------------|---------------------| +| `mp` | Message protocol. | yes || + + +### `/template/{type}/{mp}` +This endpoint is used to obtain Eiffel event templates implemented in [Eiffel REMReM Semantics](https://github.com/eiffel-community/eiffel-remrem-semantics). + +##### HTTP Method +GET + +| Name | Description | Required | Default value | +|-------------------------------------|--------------------|------------------------|---------------------| +| `type` | Eiffel event type. | yes | +| `mp` | Message protocol. | yes || + + + +### `/message_protocols` +This endpoint is used to obtain the message protocols list and edition names in JSON format. + +##### HTTP Method +GET ## Examples