use of com.telefonica.iot.cygnus.containers.NotifyContextRequestNGSIv2 in project fiware-cygnus by telefonicaid.
the class NGSIRestHandler method getEvents.
// configure
@Override
public List<Event> getEvents(javax.servlet.http.HttpServletRequest request) throws Exception {
// Set some MDC logging fields to 'N/A' for this thread
// Value for the component field is inherited from main thread (CygnusApplication.java)
org.apache.log4j.MDC.put(CommonConstants.LOG4J_CORR, CommonConstants.NA);
org.apache.log4j.MDC.put(CommonConstants.LOG4J_TRANS, CommonConstants.NA);
org.apache.log4j.MDC.put(CommonConstants.LOG4J_SVC, CommonConstants.NA);
org.apache.log4j.MDC.put(CommonConstants.LOG4J_SUBSVC, CommonConstants.NA);
// Result
ArrayList<Event> ngsiEvents = new ArrayList<>();
// Update the counters
numReceivedEvents++;
// Check the headers looking for not supported content type and/or invalid FIWARE service and service path
Enumeration headerNames = request.getHeaderNames();
String corrId = null;
String contentType = null;
String service = defaultService;
String servicePath = defaultServicePath;
String ngsiVersion = null;
while (headerNames.hasMoreElements()) {
String headerName = ((String) headerNames.nextElement()).toLowerCase(Locale.ENGLISH);
String headerValue = request.getHeader(headerName);
LOGGER.debug("[NGSIRestHandler] Header " + headerName + " received with value " + headerValue);
switch(headerName) {
case CommonConstants.HEADER_CORRELATOR_ID:
corrId = headerValue;
break;
case CommonConstants.HTTP_HEADER_CONTENT_TYPE:
if (wrongContentType(headerValue)) {
LOGGER.warn("[NGSIRestHandler] Bad HTTP notification (" + headerValue + " content type not supported)");
throw new HTTPBadRequestException(headerValue + " content type not supported");
} else {
contentType = headerValue;
}
break;
case CommonConstants.HEADER_FIWARE_SERVICE:
if (wrongServiceHeaderLength(headerValue)) {
LOGGER.warn("[NGSIRestHandler] Bad HTTP notification ('" + CommonConstants.HEADER_FIWARE_SERVICE + "' header length greater than " + NGSIConstants.SERVICE_HEADER_MAX_LEN + ")");
throw new HTTPBadRequestException("'" + CommonConstants.HEADER_FIWARE_SERVICE + "' header length greater than " + NGSIConstants.SERVICE_HEADER_MAX_LEN + ")");
} else {
service = headerValue;
}
break;
case CommonConstants.HEADER_FIWARE_SERVICE_PATH:
String[] splitValues = headerValue.split(",");
for (String splitValue : splitValues) {
if (wrongServicePathHeaderLength(splitValue)) {
LOGGER.warn("[NGSIRestHandler] Bad HTTP notification ('" + CommonConstants.HEADER_FIWARE_SERVICE_PATH + "' header value length greater than " + NGSIConstants.SERVICE_PATH_HEADER_MAX_LEN + ")");
throw new HTTPBadRequestException("'fiware-servicePath' header length greater than " + NGSIConstants.SERVICE_PATH_HEADER_MAX_LEN + ")");
} else if (wrongServicePathHeaderInitialCharacter(splitValue)) {
LOGGER.warn("[NGSIRestHandler] Bad HTTP notification ('" + CommonConstants.HEADER_FIWARE_SERVICE_PATH + "' header value must start with '/'");
throw new HTTPBadRequestException("'" + CommonConstants.HEADER_FIWARE_SERVICE_PATH + "' header value must start with '/'");
}
// if else
}
// for
servicePath = headerValue;
break;
case CommonConstants.HEADER_NGSI_VERSION:
ngsiVersion = headerValue;
break;
default:
LOGGER.debug("[NGSIRestHandler] Unnecessary header");
}
// switch
}
// while
// Get a service and servicePath and store it in the log4j Mapped Diagnostic Context (MDC)
MDC.put(CommonConstants.LOG4J_SVC, service == null ? defaultService : service);
MDC.put(CommonConstants.LOG4J_SUBSVC, servicePath == null ? defaultServicePath : servicePath);
// If the configuration is invalid, nothing has to be done but to return null
if (invalidConfiguration) {
serviceMetrics.add(service, servicePath, 1, request.getContentLength(), 0, 0, 0, 0, 0, 0, 0);
LOGGER.debug("[NGSIRestHandler] Invalid configuration, thus returning an empty list of Flume events");
return new ArrayList<>();
}
// if
// Check the method
String method = request.getMethod().toUpperCase(Locale.ENGLISH);
if (!method.equals("POST")) {
serviceMetrics.add(service, servicePath, 1, request.getContentLength(), 0, 1, 0, 0, 0, 0, 0);
LOGGER.warn("[NGSIRestHandler] Bad HTTP notification (" + method + " method not supported)");
// so we HTTPBadRequestException for 400 Bad Request instead
throw new HTTPBadRequestException(method + " method not supported");
}
// if
// Check the notificationTarget
String target = request.getRequestURI();
if (!target.equals(notificationTarget)) {
serviceMetrics.add(service, servicePath, 1, request.getContentLength(), 0, 1, 0, 0, 0, 0, 0);
LOGGER.warn("[NGSIRestHandler] Bad HTTP notification (" + target + " target not supported, " + notificationTarget + " expected.)");
throw new HTTPBadRequestException(target + " target not supported, " + notificationTarget + " expected.");
}
// Check if received content type is null
if (contentType == null) {
serviceMetrics.add(service, servicePath, 1, request.getContentLength(), 0, 1, 0, 0, 0, 0, 0);
LOGGER.warn("[NGSIRestHandler] Missing content type. Required 'application/json; charset=utf-8'");
throw new HTTPBadRequestException("Missing content type. Required 'application/json; charset=utf-8'");
}
// if
// Get an internal transaction ID.
String transId = CommonUtils.generateUniqueId(null, null);
// Get also a correlator ID if not sent in the notification. Id correlator ID is not notified
// then correlator ID and transaction ID must have the same value.
corrId = CommonUtils.generateUniqueId(corrId, transId);
// Store both of them in the log4j Mapped Diagnostic Context (MDC), this way it will be accessible
// by the whole source code.
MDC.put(CommonConstants.LOG4J_CORR, corrId);
MDC.put(CommonConstants.LOG4J_TRANS, transId);
LOGGER.debug("[NGSIRestHandler] Starting internal transaction (" + transId + ")");
// Get the data content
String data = "";
String line;
try (BufferedReader reader = request.getReader()) {
while ((line = reader.readLine()) != null) {
data += line;
}
// while
}
if (data.length() == 0) {
serviceMetrics.add(service, servicePath, 1, request.getContentLength(), 0, 1, 0, 0, 0, 0, 0);
LOGGER.warn("[NGSIRestHandler] Bad HTTP notification (No content in the request)");
throw new HTTPBadRequestException("No content in the request");
}
// if
LOGGER.info("[NGSIRestHandler] Received data (" + data + ")");
// Parse the original data into a NotifyContextRequest object
NotifyContextRequest ncr = null;
NotifyContextRequestNGSIv2 notifyContextRequestNGSIv2 = null;
Gson gson = new Gson();
try {
if (ngsiVersion != null) {
switch(ngsiVersion) {
case "legacy":
ncr = gson.fromJson(data, NotifyContextRequest.class);
LOGGER.debug("[NGSIRestHandler] Parsed NotifyContextRequest on legacy NGSI: " + ncr.toString());
break;
case "normalized":
gson = new GsonBuilder().registerTypeAdapter(NotifyContextRequestNGSIv2.class, new NotifyContextRequestNGSIv2Deserializer()).create();
notifyContextRequestNGSIv2 = gson.fromJson(data, NotifyContextRequestNGSIv2.class);
ncr = notifyContextRequestNGSIv2.toNotifyContextRequest();
LOGGER.debug("[NGSIRestHandler] Parsed NotifyContextRequest on normalized NGSIv2: " + ncr.toString());
break;
default:
LOGGER.warn("Unknown value: " + ngsiVersion + " for NGSI format");
throw new HTTPBadRequestException(ngsiVersion + " format not supported");
}
} else {
ncr = gson.fromJson(data, NotifyContextRequest.class);
LOGGER.debug("[NGSIRestHandler] Parsed NotifyContextRequest on legacy NGSI: " + ncr.toString());
}
} catch (JsonSyntaxException e) {
serviceMetrics.add(service, servicePath, 1, request.getContentLength(), 0, 1, 0, 0, 0, 0, 0);
LOGGER.error("[NGSIRestHandler] Runtime error (" + e.getMessage() + ")");
return null;
}
// try catch
// Split the notified service path and check if it matches the number of notified context responses
String[] servicePaths = servicePath.split(",");
// when subservice is /
if (ngsiVersion != null && ngsiVersion.equals("normalized")) {
if (servicePaths.length < ncr.getContextResponses().size() && servicePaths.length == 1) /*&& servicePath.equals("/")*/
{
LOGGER.debug("[NGSIRestHandler] normalizing servicePath " + servicePath);
String[] newServicePaths = new String[ncr.getContextResponses().size()];
for (int i = 0; i < ncr.getContextResponses().size(); i++) {
newServicePaths[i] = servicePaths[0];
}
servicePaths = newServicePaths;
}
}
if (servicePaths.length != ncr.getContextResponses().size()) {
serviceMetrics.add(service, servicePath, 1, request.getContentLength(), 0, 1, 0, 0, 0, 0, 0);
LOGGER.warn("[NGSIRestHandler] Bad HTTP notification ('" + CommonConstants.HEADER_FIWARE_SERVICE_PATH + "' header value: " + servicePath + " does not match the number of notified context responses: " + ncr.getContextResponses().size());
throw new HTTPBadRequestException("'" + CommonConstants.HEADER_FIWARE_SERVICE_PATH + "' header value does not match the number of notified context responses");
}
// if
// Iterate on the NotifyContextRequest object in order to create an event per ContextElement
String ids = "";
for (int i = 0; i < ncr.getContextResponses().size(); i++) {
ContextElementResponse cer = ncr.getContextResponses().get(i);
LOGGER.debug("[NGSIRestHandler] NGSI event created for ContextElementResponse: " + cer.toString());
// Create the appropiate headers
Map<String, String> headers = new HashMap<>();
headers.put(CommonConstants.HEADER_FIWARE_SERVICE, service);
LOGGER.debug("[NGSIRestHandler] Header added to NGSI event (" + CommonConstants.HEADER_FIWARE_SERVICE + ": " + service + ")");
headers.put(CommonConstants.HEADER_FIWARE_SERVICE_PATH, servicePaths[i]);
LOGGER.debug("[NGSIRestHandler] Header added to NGSI event (" + CommonConstants.HEADER_FIWARE_SERVICE_PATH + ": " + servicePaths[i] + ")");
headers.put(CommonConstants.HEADER_CORRELATOR_ID, corrId);
LOGGER.debug("[NGSIRestHandler] Header added to NGSI event (" + CommonConstants.HEADER_CORRELATOR_ID + ": " + corrId + ")");
headers.put(NGSIConstants.FLUME_HEADER_TRANSACTION_ID, transId);
LOGGER.debug("[NGSIRestHandler] Header added to NGSI event (" + NGSIConstants.FLUME_HEADER_TRANSACTION_ID + ": " + transId + ")");
if (ngsiVersion != null) {
headers.put(CommonConstants.HEADER_NGSI_VERSION, ngsiVersion);
LOGGER.debug("[NGSIRestHandler] Header added to NGSI event (" + CommonConstants.HEADER_NGSI_VERSION + ": " + ngsiVersion + ")");
}
// Create the NGSI event and add it to the list
NGSIEvent ngsiEvent = new NGSIEvent(// Headers
headers, // Bytes version of the notified ContextElement
(cer.getContextElement().toString() + CommonConstants.CONCATENATOR).getBytes(), // Object version of the notified ContextElement
cer.getContextElement(), // NGSINameMappingsInterceptor (if configured). Currently, null
null);
ngsiEvents.add(ngsiEvent);
if (ids.isEmpty()) {
ids += ngsiEvent.hashCode();
} else {
ids += "," + ngsiEvent.hashCode();
}
// if else
}
// for
// Return the NGSIEvent list
serviceMetrics.add(service, servicePath, 1, request.getContentLength(), 0, 0, 0, 0, 0, 0, 0);
LOGGER.debug("[NGSIRestHandler] NGSI events put in the channel, ids=" + ids);
numProcessedEvents++;
return ngsiEvents;
}
use of com.telefonica.iot.cygnus.containers.NotifyContextRequestNGSIv2 in project fiware-cygnus by telefonicaid.
the class NotifyContextRequestNGSIv2Deserializer method deserialize.
@Override
public NotifyContextRequestNGSIv2 deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
JsonObject jsonObject = json.getAsJsonObject();
String subscriptionId = jsonObject.get("subscriptionId").getAsString();
ArrayList<Data> data = deserializeAllData(jsonObject.getAsJsonArray("data"));
NotifyContextRequestNGSIv2 ncr = new NotifyContextRequestNGSIv2();
ncr.setSubscriptionId(subscriptionId);
ncr.setData(data);
return ncr;
}
Aggregations