-
Notifications
You must be signed in to change notification settings - Fork 70
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Modified generate's endpoint generate to accept array of events #226
Changes from 5 commits
6eb83b3
d33c54c
1476f2d
e58d75b
55d720d
037c273
89b52ef
145f2b8
dfa1799
7ea6195
3a3fd1c
962cabb
dbb2ed3
ddca4e6
b5ed6b4
cd2a736
6456f81
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -18,12 +18,12 @@ | |
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.google.gson.Gson; | ||
import com.google.gson.GsonBuilder; | ||
import com.google.gson.JsonArray; | ||
import com.google.gson.JsonElement; | ||
import com.google.gson.JsonObject; | ||
import com.google.gson.JsonParser; | ||
import com.fasterxml.jackson.core.JsonFactory; | ||
import com.fasterxml.jackson.core.JsonProcessingException; | ||
import com.fasterxml.jackson.databind.JsonMappingException; | ||
import com.fasterxml.jackson.databind.JsonNode; | ||
import com.fasterxml.jackson.databind.ObjectMapper; | ||
import com.google.gson.*; | ||
|
||
import ch.qos.logback.classic.Logger; | ||
import io.swagger.annotations.*; | ||
|
@@ -46,14 +46,13 @@ | |
|
||
import springfox.documentation.annotations.ApiIgnore; | ||
|
||
import java.io.BufferedReader; | ||
import java.io.FileInputStream; | ||
import java.io.IOException; | ||
import java.io.InputStreamReader; | ||
import java.io.*; | ||
import java.util.List; | ||
import java.util.Map; | ||
import java.util.Map.Entry; | ||
|
||
import static com.ericsson.eiffel.remrem.generate.constants.RemremGenerateServiceConstants.*; | ||
|
||
@RestController | ||
@RequestMapping("/*") | ||
@Api(value = "REMReM Generate Service", description = "REST API for generating Eiffel messages") | ||
|
@@ -99,64 +98,158 @@ public void setRestTemplate(RestTemplate restTemplate) { | |
* <p> | ||
* Returns: The event information as a json element | ||
*/ | ||
|
||
@ApiOperation(value = "To generate eiffel event based on the message protocol", response = String.class) | ||
@ApiResponses(value = { @ApiResponse(code = 200, message = "Event sent successfully"), | ||
@ApiResponse(code = 400, message = "Malformed JSON"), | ||
@ApiResponse(code = 500, message = "Internal server error"), | ||
@ApiResponse(code = 503, message = "Message protocol is invalid") }) | ||
@RequestMapping(value = "/{mp" + REGEX + "}", method = RequestMethod.POST) | ||
public ResponseEntity<?> generate( | ||
@ApiParam(value = "message protocol", required = true) @PathVariable("mp") final String msgProtocol, | ||
@ApiParam(value = "message type", required = true) @RequestParam("msgType") final String msgType, | ||
@ApiParam(value = "ER lookup result multiple found, Generate will fail") @RequestParam(value = "failIfMultipleFound", required = false, defaultValue = "false") final Boolean failIfMultipleFound, | ||
@ApiParam(value = "ER lookup result none found, Generate will fail") @RequestParam(value = "failIfNoneFound", required = false, defaultValue = "false") final Boolean failIfNoneFound, | ||
@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 = "JSON message", required = true) @RequestBody JsonObject bodyJson) { | ||
public ResponseEntity<?> generate(@ApiParam(value = "message protocol", required = true) @PathVariable("mp") final String msgProtocol, | ||
@ApiParam(value = "message type", required = true) @RequestParam("msgType") final String msgType, | ||
@ApiParam(value = "ER lookup result multiple found, Generate will fail") @RequestParam(value = "failIfMultipleFound", required = false, defaultValue = "false") final Boolean failIfMultipleFound, | ||
@ApiParam(value = "ER lookup result none found, Generate will fail") @RequestParam(value = "failIfNoneFound", required = false, defaultValue = "false") final Boolean failIfNoneFound, | ||
@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 = "JSON message", required = true) @RequestBody String body) { | ||
JsonObject errorResponse = null; | ||
try { | ||
errorResponse = new JsonObject(); | ||
JsonFactory jsonFactory = JsonFactory.builder().build().enable(com.fasterxml.jackson.core.JsonParser.Feature.STRICT_DUPLICATE_DETECTION); | ||
ObjectMapper mapper = new ObjectMapper(jsonFactory); | ||
JsonNode node = mapper.readTree(body); | ||
Gson gson = new Gson(); | ||
JsonElement inputJson = gson.fromJson(node.toString(), JsonElement.class); | ||
return generate(msgProtocol, msgType, failIfMultipleFound, failIfNoneFound, lookupInExternalERs, | ||
lookupLimit, okToLeaveOutInvalidOptionalFields, inputJson); | ||
} catch (JsonSyntaxException e) { | ||
String exceptionMessage = e.getMessage(); | ||
log.error("Invalid JSON parse data format due to:", e.getMessage()); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Remove ':'. |
||
return createResponseEntity(HttpStatus.BAD_REQUEST,"Invalid JSON parse data format due to: " + exceptionMessage, "fatal", | ||
errorResponse); | ||
} catch (JsonProcessingException e) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think JsonSyntaxException and JsonProcessingException can be handled together. No need to distinguish between them. |
||
String exceptionMessage = e.getMessage(); | ||
log.info("Incorrect Json data", exceptionMessage); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should be log.error |
||
return createResponseEntity(HttpStatus.BAD_REQUEST,"Incorrect Json data: " + exceptionMessage, "fatal", | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Json -> JSON |
||
errorResponse); | ||
} | ||
} | ||
|
||
public ResponseEntity<?> generate(final String msgProtocol, final String msgType, final Boolean failIfMultipleFound, final Boolean failIfNoneFound, final Boolean lookupInExternalERs, final int lookupLimit, final Boolean okToLeaveOutInvalidOptionalFields, JsonElement inputData) { | ||
|
||
JsonArray generatedEventResults = new JsonArray(); | ||
JsonObject errorResponse = new JsonObject(); | ||
try { | ||
bodyJson = erLookup(bodyJson, failIfMultipleFound, failIfNoneFound, lookupInExternalERs, lookupLimit); | ||
MsgService msgService = getMessageService(msgProtocol); | ||
String response; | ||
if (msgService != null) { | ||
response = msgService.generateMsg(msgType, bodyJson, isLenientEnabled(okToLeaveOutInvalidOptionalFields)); | ||
JsonElement parsedResponse = parser.parse(response); | ||
if(lookupLimit <= 0) { | ||
return new ResponseEntity<>("LookupLimit must be greater than or equals to 1", HttpStatus.BAD_REQUEST); | ||
if (lookupLimit <= 0) { | ||
return new ResponseEntity<>("LookupLimit must be greater than or equals to 1", HttpStatus.BAD_REQUEST); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should createResponseEntity be used? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. i don't think here we need, here we just need to return one response not as many like in other scenerio |
||
} | ||
if (inputData == null) { | ||
log.error("Json event must not be null"); | ||
errorResponse.addProperty(JSON_ERROR_MESSAGE_FIELD, "inputData must not be null"); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should createResponseEntity be used? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. same here as well |
||
return new ResponseEntity<>(errorResponse, HttpStatus.BAD_REQUEST); | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why to continue when inputData is null? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. done |
||
if (inputData.isJsonArray()) { | ||
JsonArray inputEventJsonArray = inputData.getAsJsonArray(); | ||
for (JsonElement element : inputEventJsonArray) { | ||
JsonObject generatedEvent = (processEvent(msgProtocol, msgType, | ||
failIfMultipleFound, failIfNoneFound, lookupInExternalERs, lookupLimit, | ||
okToLeaveOutInvalidOptionalFields, element.getAsJsonObject())); | ||
generatedEventResults.add(generatedEvent); | ||
} | ||
if (!parsedResponse.getAsJsonObject().has(RemremGenerateServiceConstants.JSON_ERROR_MESSAGE_FIELD)) { | ||
return new ResponseEntity<>(parsedResponse, HttpStatus.OK); | ||
boolean success = true; | ||
for (JsonElement result : generatedEventResults) { | ||
JsonObject jsonObject = result.getAsJsonObject(); | ||
success &= jsonObject.has(META); | ||
} | ||
return new ResponseEntity<>(generatedEventResults, success ? HttpStatus.OK : HttpStatus.BAD_REQUEST); | ||
|
||
} else if (inputData.isJsonObject()) { | ||
JsonObject inputJsonObject = inputData.getAsJsonObject(); | ||
JsonObject processedJson = processEvent(msgProtocol, msgType, failIfMultipleFound, failIfNoneFound, | ||
lookupInExternalERs, lookupLimit, okToLeaveOutInvalidOptionalFields, inputJsonObject); | ||
|
||
if (processedJson.has(META)) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Handle result as inside loop at line 162. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. not getting clearly here, |
||
return new ResponseEntity<>(processedJson, HttpStatus.OK); | ||
} | ||
if (processedJson.has(JSON_STATUS_CODE) && "400".equals(processedJson.get(JSON_STATUS_CODE).toString())) { | ||
return new ResponseEntity<>(processedJson, HttpStatus.BAD_REQUEST); | ||
} else { | ||
return new ResponseEntity<>(parsedResponse, HttpStatus.BAD_REQUEST); | ||
return new ResponseEntity<>(processedJson, HttpStatus.SERVICE_UNAVAILABLE); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This strange state should be logged. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yeah we can logged like this? log.error("Unexpected error caught, due to service property is missing or wrong"); |
||
} | ||
|
||
} else { | ||
return new ResponseEntity<>(parser.parse(RemremGenerateServiceConstants.NO_SERVICE_ERROR), | ||
HttpStatus.SERVICE_UNAVAILABLE); | ||
return createResponseEntity(HttpStatus.BAD_REQUEST, "Invalid JSON format,expected either single template or array of templates", | ||
"fail", errorResponse); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There should be a constant for "fail". |
||
} | ||
} catch (REMGenerateException e1) { | ||
if (e1.getMessage().contains(Integer.toString(HttpStatus.NOT_ACCEPTABLE.value()))) { | ||
return new ResponseEntity<>(parser.parse(e1.getMessage()), HttpStatus.NOT_ACCEPTABLE); | ||
} | ||
else if (e1.getMessage().contains(Integer.toString(HttpStatus.EXPECTATION_FAILED.value()))) { | ||
return new ResponseEntity<>(parser.parse(e1.getMessage()), HttpStatus.EXPECTATION_FAILED); | ||
} | ||
else if (e1.getMessage().contains(Integer.toString(HttpStatus.EXPECTATION_FAILED.value()))) { | ||
return new ResponseEntity<>(parser.parse(e1.getMessage()), HttpStatus.EXPECTATION_FAILED); | ||
} | ||
else if (e1.getMessage() | ||
.contains(Integer.toString(HttpStatus.SERVICE_UNAVAILABLE.value()))) { | ||
return new ResponseEntity<>(parser.parse(RemremGenerateServiceConstants.NO_ER), | ||
HttpStatus.SERVICE_UNAVAILABLE); | ||
} catch (REMGenerateException | JsonSyntaxException e) { | ||
return handleException(e); | ||
} | ||
} | ||
|
||
public ResponseEntity<JsonObject> createResponseEntity(HttpStatus status, String errorMessage, String resultMessage, | ||
JsonObject errorResponse) { | ||
initializeResponse(status, errorMessage, resultMessage, errorResponse); | ||
return new ResponseEntity<>(errorResponse, status); | ||
} | ||
|
||
public void initializeResponse(HttpStatus status, String errorMessage, String resultMessage, | ||
JsonObject errorResponse) { | ||
errorResponse.addProperty(JSON_STATUS_CODE, status.value()); | ||
errorResponse.addProperty(JSON_STATUS_RESULT, resultMessage); | ||
errorResponse.addProperty(JSON_ERROR_MESSAGE_FIELD, errorMessage); | ||
} | ||
|
||
private ResponseEntity<JsonObject> handleException(Exception e) { | ||
JsonObject errorResponse = new JsonObject(); | ||
String exceptionMessage = e.getMessage(); | ||
if (e instanceof REMGenerateException) { | ||
List<HttpStatus> statuses = List.of( | ||
HttpStatus.NOT_ACCEPTABLE, HttpStatus.EXPECTATION_FAILED, HttpStatus.SERVICE_UNAVAILABLE, HttpStatus.UNPROCESSABLE_ENTITY | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Split the line. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. done |
||
); | ||
for (HttpStatus status : statuses) { | ||
if (exceptionMessage.contains(Integer.toString(status.value()))) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I guess there should be more strict test, not just test for occurrence in message. The message is a JSON data. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah but whatever the test is handled by these exception error, it is same like as earlier.. |
||
return createResponseEntity( | ||
status, e.getMessage(), "fail", errorResponse); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Use constant for "fail". The same for lines 216 and 219. |
||
} | ||
} | ||
else { | ||
return new ResponseEntity<>(parser.parse(e1.getMessage()), HttpStatus.UNPROCESSABLE_ENTITY); | ||
return createResponseEntity(HttpStatus.BAD_REQUEST, e.getMessage(), "fail", errorResponse); | ||
} else if (e instanceof JsonSyntaxException) { | ||
log.error("Failed to parse JSON: ", exceptionMessage); | ||
return createResponseEntity(HttpStatus.BAD_REQUEST, e.getMessage(), "fail", errorResponse); | ||
} else { | ||
log.error("Unexpected exception caught", exceptionMessage); | ||
return createResponseEntity(HttpStatus.INTERNAL_SERVER_ERROR, exceptionMessage, "fail", errorResponse); | ||
} | ||
} | ||
|
||
/** | ||
* This helper method basically generate or process one event | ||
* @return JsonObject generated event | ||
*/ | ||
|
||
public JsonObject processEvent(String msgProtocol, String msgType, Boolean failIfMultipleFound, | ||
Boolean failIfNoneFound, Boolean lookupInExternalERs, int lookupLimit, | ||
Boolean okToLeaveOutInvalidOptionalFields, JsonObject jsonObject) throws REMGenerateException, JsonSyntaxException { | ||
JsonObject eventResponse = new JsonObject(); | ||
JsonElement parsedResponse; | ||
|
||
JsonObject event = erLookup(jsonObject, failIfMultipleFound, failIfNoneFound, lookupInExternalERs, lookupLimit); | ||
MsgService msgService = getMessageService(msgProtocol); | ||
|
||
if (msgService != null) { | ||
String response = msgService.generateMsg(msgType, event, isLenientEnabled(okToLeaveOutInvalidOptionalFields)); | ||
parsedResponse = JsonParser.parseString(response); | ||
JsonObject parsedJson = parsedResponse.getAsJsonObject(); | ||
|
||
if (parsedJson.has(JSON_ERROR_MESSAGE_FIELD)) { | ||
createResponseEntity(HttpStatus.BAD_REQUEST, "fail", TEMPLATE_ERROR, eventResponse); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Use constants for "fail". |
||
return eventResponse; | ||
} else { | ||
return parsedJson; | ||
} | ||
} catch (Exception e) { | ||
log.error("Unexpected exception caught", e); | ||
return new ResponseEntity<>(parser.parse(RemremGenerateServiceConstants.INTERNAL_SERVER_ERROR), | ||
HttpStatus.INTERNAL_SERVER_ERROR); | ||
} | ||
return eventResponse; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We cannot return an empty JSON object. Situation when msgService == null must be handled. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yeah right we can handle this in same as original one means the how it handle earlier right? else { |
||
} | ||
|
||
private JsonObject erLookup(final JsonObject bodyJson, Boolean failIfMultipleFound, Boolean failIfNoneFound, | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use exceptionMessage at line 122, too.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done