summaryrefslogtreecommitdiffstats
path: root/datacollector/src/main/java/org/onap/rapp/datacollector/service/FileReadyParserImpl.java
diff options
context:
space:
mode:
Diffstat (limited to 'datacollector/src/main/java/org/onap/rapp/datacollector/service/FileReadyParserImpl.java')
-rw-r--r--datacollector/src/main/java/org/onap/rapp/datacollector/service/FileReadyParserImpl.java197
1 files changed, 197 insertions, 0 deletions
diff --git a/datacollector/src/main/java/org/onap/rapp/datacollector/service/FileReadyParserImpl.java b/datacollector/src/main/java/org/onap/rapp/datacollector/service/FileReadyParserImpl.java
new file mode 100644
index 0000000..d7f517e
--- /dev/null
+++ b/datacollector/src/main/java/org/onap/rapp/datacollector/service/FileReadyParserImpl.java
@@ -0,0 +1,197 @@
+/*
+ * Copyright (C) 2021 Samsung Electronics
+ * 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 org.onap.rapp.datacollector.service;
+
+import static java.util.Objects.nonNull;
+import static org.onap.rapp.datacollector.service.PMService.CELL_FIELD_NAME;
+import static org.onap.rapp.datacollector.service.PMService.VALUE_NAME;
+
+import java.lang.reflect.Type;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+
+import org.onap.rapp.datacollector.entity.fileready.FileReadyEvent;
+import org.onap.rapp.datacollector.entity.fileready.MeasDataCollection;
+import org.onap.rapp.datacollector.entity.fileready.MeasDataCollection.MeasInfo;
+import org.onap.rapp.datacollector.entity.fileready.MeasDataCollection.MeasInfo.MeasValue;
+import org.onap.rapp.datacollector.entity.ves.AdditionalMeasurements;
+import org.onap.rapp.datacollector.entity.ves.CommonEventHeader;
+import org.onap.rapp.datacollector.entity.ves.Event;
+import org.onap.rapp.datacollector.entity.ves.MeasurementFields;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Service;
+
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+import com.google.gson.JsonDeserializationContext;
+import com.google.gson.JsonDeserializer;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParseException;
+
+@Service
+public class FileReadyParserImpl extends ParserAbstractClass implements VesParser {
+
+ private static final Logger logger = LoggerFactory.getLogger(FileReadyParserImpl.class);
+
+ /**
+ * Parse incoming Json string into list of Events
+ *
+ * @param eventString json from PM Mapper
+ * @return list of events
+ */
+ @Override
+ public List<Event> parse(final String eventString) {
+ logger.debug("parsing ves event {}", eventString);
+ FileReadyEvent fileReadyEvent = gson.fromJson(eventString, FileReadyEvent.class);
+ return convertFileReadyEventToEventList(fileReadyEvent, eventString);
+ }
+
+ /**
+ * Convert FileReadyEvent event into list of events which will be stored in database
+ *
+ * @param fileReadyEvent object created from PM Mapper response
+ * @param eventString Json event in string
+ * @return list of events
+ */
+ private List<Event> convertFileReadyEventToEventList(FileReadyEvent fileReadyEvent, String eventString) {
+ List<Event> events = new ArrayList<>();
+ long averageMeasInterval = getAverageMeasInterval(fileReadyEvent);
+ fileReadyEvent.getMeasDataCollection().getMeasInfoList()
+ .forEach(measInfo -> measInfo.getMeasValuesList().stream()
+ .filter(measValue -> hasListOfTypesSameSizeAsListOfResults(measInfo, measValue))
+ .forEach(measValue -> events.add(createEvent(fileReadyEvent, measInfo, measValue, eventString, averageMeasInterval))));
+ return events;
+ }
+
+ /**
+ * Creates individual event from FileReadyEvent data
+ *
+ * @param fileReadyEvent bject created from PM Mapper response
+ * @param measInfo measurement Info object
+ * @param measValue measurement Value object
+ * @param eventString Json event in string
+ * @param averageMeasInterval calculated average interval
+ * @return Event object
+ */
+ private Event createEvent(FileReadyEvent fileReadyEvent, MeasInfo measInfo, MeasValue measValue, String eventString, long averageMeasInterval) {
+ List<AdditionalMeasurements> additionalMeasList = new ArrayList<>();
+ // Adding measurement's results to additionalMeasList
+ measValue.getMeasResults()
+ .forEach(measResult -> {
+ Map<String, String> hashMap = new HashMap<>();
+ hashMap.put(VALUE_NAME, measResult.getSValue());
+ additionalMeasList.add(AdditionalMeasurements.builder()
+ .withName(measInfo.getMeasTypes().getSMeasTypesList().get(measResult.getP() - 1))
+ .withHashMap(hashMap).build());
+ }
+ );
+ // Adding cell identifier record to additionalMeasList
+ additionalMeasList.add(AdditionalMeasurements.builder()
+ .withName(CELL_FIELD_NAME)
+ .withHashMap(Collections.singletonMap(CELL_FIELD_NAME, measValue.getMeasObjInstId())).build());
+
+ MeasurementFields measurementFields = MeasurementFields.builder()
+ .measurementInterval(averageMeasInterval)
+ .additionalMeasurements(additionalMeasList)
+ .build();
+ Event createdEvent = Event.of(createEventHeader(fileReadyEvent, averageMeasInterval), measurementFields);
+ createdEvent.raw = eventString;
+ return createdEvent;
+ }
+
+ /**
+ * Creates CommonEventHeader as new copy of initial CommonEventHeader and sets its start/end date by average interval
+ *
+ * @param fileReadyEvent object created from PM Mapper response
+ * @param averageMeasInterval calculated average interval
+ * @return created CommonEventHeader
+ */
+ private CommonEventHeader createEventHeader(FileReadyEvent fileReadyEvent, long averageMeasInterval) {
+ CommonEventHeader headerCopy = gson.fromJson(gson.toJson(fileReadyEvent.getCommonEventHeader()), CommonEventHeader.class);
+ headerCopy.setStartEpochMicrosec(headerCopy.getStartEpochMicrosec() - averageMeasInterval);
+ headerCopy.setLastEpochMicrosec(fileReadyEvent.getCommonEventHeader().getStartEpochMicrosec());
+ fileReadyEvent.getCommonEventHeader().setStartEpochMicrosec(headerCopy.getLastEpochMicrosec() + averageMeasInterval);
+ return headerCopy;
+ }
+
+ /**
+ * As MeansType will be selected by its position in the list we need to make sure that MeasTypesList's size is the same size of MeasResults
+ *
+ * @param measInfo measurement Info object
+ * @param measValue measurement Value object
+ * @return true=size is the same, false=size is different we can not process it
+ */
+ private boolean hasListOfTypesSameSizeAsListOfResults(MeasInfo measInfo, MeasValue measValue) {
+ return measInfo.getMeasTypes().getSMeasTypesList().size() == measValue.getMeasResults().size();
+ }
+
+ /**
+ * Average interval between last and start day, divided by number of measurements
+ *
+ * @param fileReadyEvent object created from PM Mapper response
+ * @return Average interval in microseconds
+ */
+ private long getAverageMeasInterval(FileReadyEvent fileReadyEvent) {
+ int noOfMeasurment = fileReadyEvent.getMeasDataCollection().getMeasInfoList().size();
+ int dividedBy = (noOfMeasurment == 0 || noOfMeasurment == 1) ? 1 : (noOfMeasurment - 1);
+ long difference = fileReadyEvent.getCommonEventHeader().getLastEpochMicrosec() - fileReadyEvent.getCommonEventHeader().getStartEpochMicrosec();
+ return difference / dividedBy;
+ }
+
+ /**
+ * Class which deserialize json event into FileReadyEvent object
+ */
+ private static class FileReadyEventDeserializer implements JsonDeserializer<FileReadyEvent> {
+
+ @Override
+ public FileReadyEvent deserialize(JsonElement jsonElement, Type type, JsonDeserializationContext jsonDeserializationContext)
+ throws JsonParseException {
+ Optional<JsonObject> eventJsonObject = getEventJsonObject(jsonElement);
+ CommonEventHeader header = getHeaderJsonObject(eventJsonObject.orElse(null), jsonDeserializationContext);
+ header.setStartEpochMicrosec(header.getStartEpochMicrosec() * 1000);
+ header.setLastEpochMicrosec(header.getLastEpochMicrosec() * 1000);
+
+ Optional<JsonObject> measDataCollectionJson = getMeasDataCollectionJson(eventJsonObject.orElse(null));
+ if (measDataCollectionJson.isPresent()) {
+ MeasDataCollection measDataCollection = jsonDeserializationContext.deserialize(measDataCollectionJson.get(), MeasDataCollection.class);
+ logger.trace("measDataCollection {}", measDataCollection);
+ return FileReadyEvent.builder().commonEventHeader(header).measDataCollection(measDataCollection).build();
+ } else {
+ logger.error("MeasDataCollection was not found {}", eventJsonObject);
+ throw new JsonParseException("MeasDataCollection was not found");
+ }
+ }
+
+ private Optional<JsonObject> getMeasDataCollectionJson(JsonObject obj) {
+ if (nonNull(obj)) {
+ Optional<JsonObject> fileReadyJson = Optional.ofNullable(obj.getAsJsonObject(FILE_READY_EVENT_UNIQUE_ELEMENT));
+ if (fileReadyJson.isPresent()) {
+ return Optional.ofNullable(fileReadyJson.get().getAsJsonObject("measDataCollection"));
+ }
+ }
+ return Optional.empty();
+ }
+ }
+
+ private final Gson gson = new GsonBuilder()
+ .registerTypeAdapter(FileReadyEvent.class, new FileReadyEventDeserializer()).create();
+
+}