Add support for TS 28.550/28.532 09/100309/2
authorJoeOLeary <joseph.o.leary@est.tech>
Tue, 14 Jan 2020 10:54:59 +0000 (10:54 +0000)
committerJoeOLeary <joseph.o.leary@est.tech>
Tue, 21 Jan 2020 13:50:18 +0000 (13:50 +0000)
Issue-ID: DCAEGEN2-1912
Change-Id: If05c3673a240e6ea5e3d1caca3ff5bf5828590d3
Signed-off-by: JoeOLeary <joseph.o.leary@est.tech>
98 files changed:
pom.xml
src/main/java/org/onap/dcaegen2/services/pmmapper/App.java
src/main/java/org/onap/dcaegen2/services/pmmapper/exceptions/TemplateIdentificationException.java [moved from src/main/java/org/onap/dcaegen2/services/pmmapper/model/package-info.java with 71% similarity]
src/main/java/org/onap/dcaegen2/services/pmmapper/filtering/MeasFilterHandler.java
src/main/java/org/onap/dcaegen2/services/pmmapper/mapping/Mapper.java
src/main/java/org/onap/dcaegen2/services/pmmapper/model/Event.java
src/main/java/org/onap/dcaegen2/services/pmmapper/model/MeasCollecFile.java [deleted file]
src/main/java/org/onap/dcaegen2/services/pmmapper/model/measurement/common/MeasurementData.java [new file with mode: 0644]
src/main/java/org/onap/dcaegen2/services/pmmapper/model/measurement/common/MeasurementFile.java [new file with mode: 0644]
src/main/java/org/onap/dcaegen2/services/pmmapper/model/measurement/common/MeasurementInfo.java [new file with mode: 0644]
src/main/java/org/onap/dcaegen2/services/pmmapper/model/measurement/lte/MeasCollecFile.java [new file with mode: 0644]
src/main/java/org/onap/dcaegen2/services/pmmapper/model/measurement/nr/MeasDataFile.java [new file with mode: 0644]
src/main/java/org/onap/dcaegen2/services/pmmapper/utils/MeasConverter.java
src/main/java/org/onap/dcaegen2/services/pmmapper/utils/MeasSplitter.java
src/main/java/org/onap/dcaegen2/services/pmmapper/utils/XMLValidator.java
src/main/resources/Dockerfile
src/main/resources/schemas/org.3GPP.28.550#measData [new file with mode: 0644]
src/main/resources/schemas/org.3GPP.32.435#measCollec [new file with mode: 0644]
src/main/resources/templates/org.3GPP.28.550#measData [new file with mode: 0644]
src/main/resources/templates/org.3GPP.32.435#measCollec [new file with mode: 0644]
src/test/java/org/onap/dcaegen2/services/pmmapper/AppTest.java
src/test/java/org/onap/dcaegen2/services/pmmapper/filtering/MeasFilterHandlerTest.java
src/test/java/org/onap/dcaegen2/services/pmmapper/filtering/MetadataFilterTest.java
src/test/java/org/onap/dcaegen2/services/pmmapper/mapping/MapperTest.java
src/test/java/org/onap/dcaegen2/services/pmmapper/utils/DataRouterUtilsTest.java
src/test/java/org/onap/dcaegen2/services/pmmapper/utils/MeasConverterTest.java
src/test/java/org/onap/dcaegen2/services/pmmapper/utils/MeasSplitterTest.java
src/test/java/org/onap/dcaegen2/services/pmmapper/utils/XMLValidatorTest.java
src/test/java/utils/ArgumentCreator.java [new file with mode: 0644]
src/test/java/utils/EventUtils.java
src/test/resources/filter_test/lte/meas_results/expected.xml [moved from src/test/resources/filter_test/meas_results_filtered.xml with 100% similarity]
src/test/resources/filter_test/lte/meas_results/test.xml [moved from src/test/resources/filter_test/meas_results.xml with 100% similarity]
src/test/resources/filter_test/lte/meas_results_manyinfo/expected.xml [moved from src/test/resources/filter_test/meas_results_manyInfo_filtered.xml with 100% similarity]
src/test/resources/filter_test/lte/meas_results_manyinfo/test.xml [moved from src/test/resources/filter_test/meas_results_manyInfo.xml with 100% similarity]
src/test/resources/filter_test/lte/meas_type_and_r/expected.xml [moved from src/test/resources/filter_test/meas_type_and_r_filtered.xml with 100% similarity]
src/test/resources/filter_test/lte/meas_type_and_r/test.xml [moved from src/test/resources/filter_test/meas_type_and_r.xml with 100% similarity]
src/test/resources/filter_test/lte/meas_type_and_r_many_measvalue/expected.xml [moved from src/test/resources/filter_test/meas_type_and_r_manyMeasvalue_filtered.xml with 100% similarity]
src/test/resources/filter_test/lte/meas_type_and_r_many_measvalue/test.xml [moved from src/test/resources/filter_test/meas_type_and_r_manyMeasvalue.xml with 100% similarity]
src/test/resources/filter_test/lte/meas_type_and_r_manyinfo/expected.xml [moved from src/test/resources/filter_test/meas_type_and_r_manyInfo_filtered.xml with 100% similarity]
src/test/resources/filter_test/lte/meas_type_and_r_manyinfo/test.xml [moved from src/test/resources/filter_test/meas_type_and_r_manyInfo.xml with 100% similarity]
src/test/resources/filter_test/nr/meas_results/expected.xml [new file with mode: 0644]
src/test/resources/filter_test/nr/meas_results/test.xml [new file with mode: 0644]
src/test/resources/filter_test/nr/meas_results_manyinfo/expected.xml [new file with mode: 0644]
src/test/resources/filter_test/nr/meas_results_manyinfo/test.xml [new file with mode: 0644]
src/test/resources/filter_test/nr/meas_type_and_r/expected.xml [new file with mode: 0644]
src/test/resources/filter_test/nr/meas_type_and_r/test.xml [new file with mode: 0644]
src/test/resources/filter_test/nr/meas_type_and_r_many_measvalue/expected.xml [new file with mode: 0644]
src/test/resources/filter_test/nr/meas_type_and_r_many_measvalue/test.xml [new file with mode: 0644]
src/test/resources/filter_test/nr/meas_type_and_r_manyinfo/expected.xml [new file with mode: 0644]
src/test/resources/filter_test/nr/meas_type_and_r_manyinfo/test.xml [new file with mode: 0644]
src/test/resources/mapper_test/mapping_data/28.550/meas_results/metadata.json [new file with mode: 0644]
src/test/resources/mapper_test/mapping_data/28.550/meas_results/test.xml [new file with mode: 0644]
src/test/resources/mapper_test/mapping_data/28.550/meas_type_and_r/metadata.json [new file with mode: 0644]
src/test/resources/mapper_test/mapping_data/28.550/meas_type_and_r/test.xml [new file with mode: 0644]
src/test/resources/mapper_test/mapping_data/28.550/meas_type_and_r_many_meas_values/metadata.json [new file with mode: 0644]
src/test/resources/mapper_test/mapping_data/28.550/meas_type_and_r_many_meas_values/test.xml [new file with mode: 0644]
src/test/resources/mapper_test/mapping_data/28.550/meas_types_and_meas_results_many_meas_values/metadata.json [new file with mode: 0644]
src/test/resources/mapper_test/mapping_data/28.550/meas_types_and_meas_results_many_meas_values/test.xml [new file with mode: 0644]
src/test/resources/mapper_test/mapping_data/28.550/no_measdata/metadata.json [new file with mode: 0644]
src/test/resources/mapper_test/mapping_data/28.550/no_measdata/test.xml [new file with mode: 0644]
src/test/resources/mapper_test/mapping_data/28.550/no_sw_version/metadata.json [new file with mode: 0644]
src/test/resources/mapper_test/mapping_data/28.550/no_sw_version/test.xml [new file with mode: 0644]
src/test/resources/mapper_test/mapping_data/32.435/meas_results/metadata.json [new file with mode: 0644]
src/test/resources/mapper_test/mapping_data/32.435/meas_results/test.xml [moved from src/test/resources/mapper_test/mapping_data/valid_data/meas_results.xml with 100% similarity]
src/test/resources/mapper_test/mapping_data/32.435/meas_type_and_r/metadata.json [new file with mode: 0644]
src/test/resources/mapper_test/mapping_data/32.435/meas_type_and_r/test.xml [moved from src/test/resources/mapper_test/mapping_data/valid_data/meas_type_and_r.xml with 100% similarity]
src/test/resources/mapper_test/mapping_data/32.435/meas_type_and_r_many_meas_values/metadata.json [new file with mode: 0644]
src/test/resources/mapper_test/mapping_data/32.435/meas_type_and_r_many_meas_values/test.xml [moved from src/test/resources/mapper_test/mapping_data/valid_data/meas_type_and_r_many_meas_values.xml with 100% similarity]
src/test/resources/mapper_test/mapping_data/32.435/meas_types_and_meas_results_many_meas_values/metadata.json [new file with mode: 0644]
src/test/resources/mapper_test/mapping_data/32.435/meas_types_and_meas_results_many_meas_values/test.xml [moved from src/test/resources/mapper_test/mapping_data/valid_data/meas_types_and_meas_results_many_meas_values.xml with 100% similarity]
src/test/resources/mapper_test/mapping_data/32.435/no_measdata/metadata.json [new file with mode: 0644]
src/test/resources/mapper_test/mapping_data/32.435/no_measdata/test.xml [moved from src/test/resources/mapper_test/mapping_data/valid_data/no_measdata.xml with 100% similarity]
src/test/resources/mapper_test/mapping_data/32.435/no_sw_version/metadata.json [new file with mode: 0644]
src/test/resources/mapper_test/mapping_data/32.435/no_sw_version/test.xml [moved from src/test/resources/mapper_test/mapping_data/valid_data/no_sw_version.xml with 100% similarity]
src/test/resources/metadata/invalid_metadata.json [new file with mode: 0644]
src/test/resources/metadata/valid_4g_metadata.json [new file with mode: 0644]
src/test/resources/metadata/valid_5g_metadata.json [new file with mode: 0644]
src/test/resources/split_test/lte/type_a_1_event/split.props [new file with mode: 0644]
src/test/resources/split_test/lte/type_a_1_event/test.xml [new file with mode: 0644]
src/test/resources/split_test/lte/type_c_3_events/split.props [new file with mode: 0644]
src/test/resources/split_test/lte/type_c_3_events/test.xml [new file with mode: 0644]
src/test/resources/split_test/nr/type_a_1_event/split.props [new file with mode: 0644]
src/test/resources/split_test/nr/type_a_1_event/test.xml [new file with mode: 0644]
src/test/resources/split_test/nr/type_c_3_events/split.props [new file with mode: 0644]
src/test/resources/split_test/nr/type_c_3_events/test.xml [new file with mode: 0644]
src/test/resources/xml_validator_test/test_data/lte/no_file_header/test.xml [moved from src/test/resources/xml_validator_test/test_data/invalid/no_file_header.xml with 100% similarity]
src/test/resources/xml_validator_test/test_data/lte/no_file_header/validity.props [new file with mode: 0644]
src/test/resources/xml_validator_test/test_data/lte/no_managed_element/test.xml [moved from src/test/resources/xml_validator_test/test_data/invalid/no_managed_element.xml with 100% similarity]
src/test/resources/xml_validator_test/test_data/lte/no_managed_element/validity.props [new file with mode: 0644]
src/test/resources/xml_validator_test/test_data/lte/no_measdata/test.xml [moved from src/test/resources/xml_validator_test/test_data/valid/no_measdata.xml with 100% similarity]
src/test/resources/xml_validator_test/test_data/lte/no_measdata/validity.props [new file with mode: 0644]
src/test/resources/xml_validator_test/test_data/nr/no_file_header/test.xml [new file with mode: 0644]
src/test/resources/xml_validator_test/test_data/nr/no_file_header/validity.props [new file with mode: 0644]
src/test/resources/xml_validator_test/test_data/nr/no_measdata/test.xml [new file with mode: 0644]
src/test/resources/xml_validator_test/test_data/nr/no_measdata/validity.props [new file with mode: 0644]
src/test/resources/xml_validator_test/test_data/nr/no_measured_entity/test.xml [new file with mode: 0644]
src/test/resources/xml_validator_test/test_data/nr/no_measured_entity/validity.props [new file with mode: 0644]
version.properties

diff --git a/pom.xml b/pom.xml
index 91588b9..f085ec2 100644 (file)
--- a/pom.xml
+++ b/pom.xml
@@ -26,7 +26,7 @@
 
     <groupId>org.onap.dcaegen2.services</groupId>
     <artifactId>pm-mapper</artifactId>
-    <version>1.2.0-SNAPSHOT</version>
+    <version>1.3.0-SNAPSHOT</version>
 
     <parent>
         <groupId>org.onap.oparent</groupId>
index c7d56e5..21e4441 100644 (file)
@@ -1,6 +1,6 @@
 /*-
  * ============LICENSE_START=======================================================
- *  Copyright (C) 2019 Nordix Foundation.
+ *  Copyright (C) 2019-2020 Nordix Foundation.
  * ================================================================================
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -71,8 +71,8 @@ public class App {
     private static final ONAPLogAdapter logger = new ONAPLogAdapter(LoggerFactory.getLogger(App.class));
     private static final int HTTP_PORT = 8081;
     private static final int HTTPS_PORT = 8443;
-    private static Path mappingTemplate = Paths.get("/opt/app/pm-mapper/etc/mapping.ftl");
-    private static Path xmlSchema = Paths.get("/opt/app/pm-mapper/etc/measCollec_plusString.xsd");
+    private static Path templates = Paths.get("/opt/app/pm-mapper/etc/templates/");
+    private static Path schemas = Paths.get("/opt/app/pm-mapper/etc/schemas/");
 
     private MapperConfig mapperConfig;
     private MetadataFilter metadataFilter;
@@ -95,13 +95,13 @@ public class App {
 
     /**
      * Creates an instance of the application.
-     * @param mappingTemplate path to template used to convert xml to VES.
-     * @param xmlSchema path to schema used to verify incoming XML will work with template.
+     * @param templatesDirectory path to directory containing templates used for mapping.
+     * @param schemasDirectory path to directory containing schemas used to verify incoming XML will work with templates.
      * @param httpPort http port to start http server on.
      * @param httpsPort https port to start https server on.
      * @param configHandler instance of the ConfigurationHandler used to acquire config.
      */
-    public App(Path mappingTemplate, Path xmlSchema, int httpPort, int httpsPort, ConfigHandler configHandler) {
+    public App(Path templatesDirectory, Path schemasDirectory, int httpPort, int httpsPort, ConfigHandler configHandler) {
         try {
             this.mapperConfig = configHandler.getMapperConfig();
         } catch (EnvironmentConfigException | CBSServerError | MapperConfigException e) {
@@ -113,9 +113,9 @@ public class App {
         this.metadataFilter = new MetadataFilter(mapperConfig);
         this.measConverter = new MeasConverter();
         this.filterHandler = new MeasFilterHandler(measConverter);
-        this.mapper = new Mapper(mappingTemplate, this.measConverter);
+        this.mapper = new Mapper(templatesDirectory, this.measConverter);
         this.splitter =  new MeasSplitter(measConverter);
-        this.validator = new XMLValidator(xmlSchema);
+        this.validator = new XMLValidator(schemasDirectory);
         this.vesPublisher = new VESPublisher(mapperConfig);
         this.flux = Flux.create(eventFluxSink -> this.fluxSink = eventFluxSink);
 
@@ -176,7 +176,7 @@ public class App {
     }
 
     public static void main(String[] args) {
-        new App(mappingTemplate, xmlSchema, HTTP_PORT, HTTPS_PORT, new ConfigHandler()).start();
+        new App(templates, schemas, HTTP_PORT, HTTPS_PORT, new ConfigHandler()).start();
     }
 
     public static boolean filterByFileType(MeasFilterHandler filterHandler,Event event, MapperConfig config) {
@@ -1,24 +1,28 @@
-/*-\r
- * ============LICENSE_START=======================================================\r
- *  Copyright (C) 2019 Nordix Foundation.\r
- * ================================================================================\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- *      http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- *\r
- * SPDX-License-Identifier: Apache-2.0\r
- * ============LICENSE_END=========================================================\r
- */\r
-\r
-@XmlSchema(namespace = "http://www.3gpp.org/ftp/specs/archive/32_series/32.435#measCollec", elementFormDefault = XmlNsForm.QUALIFIED)\r
-package org.onap.dcaegen2.services.pmmapper.model;\r
-import javax.xml.bind.annotation.XmlSchema;\r
-import javax.xml.bind.annotation.XmlNsForm;
\ No newline at end of file
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2020 Nordix Foundation.
+ * ================================================================================
+ * 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.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.dcaegen2.services.pmmapper.exceptions;
+
+public class TemplateIdentificationException extends RuntimeException {
+
+    public TemplateIdentificationException(String message) {
+        super(message);
+    }
+}
index 562f46c..fb5772e 100644 (file)
@@ -1,6 +1,6 @@
 /*-
  * ============LICENSE_START=======================================================
- *  Copyright (C) 2019 Nordix Foundation.
+ *  Copyright (C) 2019-2020 Nordix Foundation.
  * ================================================================================
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -27,13 +27,11 @@ import java.util.stream.Collectors;
 
 import org.apache.commons.io.FilenameUtils;
 import org.onap.dcaegen2.services.pmmapper.model.Event;
-import org.onap.dcaegen2.services.pmmapper.model.MeasCollecFile;
-import org.onap.dcaegen2.services.pmmapper.model.MeasCollecFile.MeasData;
-import org.onap.dcaegen2.services.pmmapper.model.MeasCollecFile.MeasData.MeasInfo;
-import org.onap.dcaegen2.services.pmmapper.model.MeasCollecFile.MeasData.MeasInfo.MeasType;
-import org.onap.dcaegen2.services.pmmapper.model.MeasCollecFile.MeasData.MeasInfo.MeasValue;
-import org.onap.dcaegen2.services.pmmapper.model.MeasCollecFile.MeasData.MeasInfo.MeasValue.R;
 import org.onap.dcaegen2.services.pmmapper.model.MeasFilterConfig.Filter;
+import org.onap.dcaegen2.services.pmmapper.model.measurement.common.MeasurementData;
+import org.onap.dcaegen2.services.pmmapper.model.measurement.common.MeasurementFile;
+import org.onap.dcaegen2.services.pmmapper.model.measurement.common.MeasurementInfo;
+import org.onap.dcaegen2.services.pmmapper.model.measurement.common.MeasurementInfo.MeasValue;
 import org.onap.dcaegen2.services.pmmapper.utils.MeasConverter;
 import org.onap.logging.ref.slf4j.ONAPLogAdapter;
 import org.slf4j.LoggerFactory;
@@ -55,24 +53,24 @@ public class MeasFilterHandler {
      **/
     public boolean filterByMeasType(Event event) {
         Optional<Filter> filter = Optional.ofNullable(event.getFilter());
-        MeasCollecFile measCollecFile = event.getMeasCollecFile();
+        MeasurementFile measurementFile = event.getMeasurement();
 
         if (hasNoFilters(filter)) {
             logger.unwrap().info("Skipping filtering by measTypes as filter config does not contain measTypes.");
             return true;
         }
 
-        if (measCollecFile.getMeasData().isEmpty()) {
+        if (!measurementFile.getMeasurementData().isPresent() || measurementFile.getMeasurementData().get().isEmpty()) {
             logger.unwrap().info("Measurement file will not be processed further as MeasData is empty.");
             return false;
         }
 
         logger.unwrap().info("Filtering the measurement file by measTypes.");
-        MeasData measData = measCollecFile.getMeasData().get(0);
-        List<MeasInfo> measInfos = measData.getMeasInfo();
-        List<MeasInfo> filteredMeasInfos = new ArrayList<>();
+        MeasurementData measData = measurementFile.getMeasurementData().get().get(0);
+        List<MeasurementInfo> measInfos = measData.getMeasurementInfo();
+        List<MeasurementInfo> filteredMeasInfos = new ArrayList<>();
 
-        for (MeasInfo currentMeasInfo : measInfos) {
+        for (MeasurementInfo currentMeasInfo : measInfos) {
             List<String> measTypesNode = currentMeasInfo.getMeasTypes();
             if (measTypesNode != null && !measTypesNode.isEmpty()) {
                 setMeasInfosFromMeasTypes(currentMeasInfo, filteredMeasInfos, filter.get());
@@ -85,8 +83,8 @@ public class MeasFilterHandler {
             logger.unwrap().info("No filter match from the current measurement file.");
             return false;
         }
-        measData.setMeasInfo(filteredMeasInfos);
-        String filteredXMl = converter.convert(measCollecFile);
+        measData.setMeasurementInfo(filteredMeasInfos);
+        String filteredXMl = converter.convert(measurementFile);
         event.setBody(filteredXMl);
         logger.unwrap().info("Successfully filtered the measurement by measTypes.");
         return true;
@@ -147,8 +145,8 @@ public class MeasFilterHandler {
         return FilenameUtils.getExtension(fileName).equals(XML_EXTENSION);
     }
 
-    private boolean hasMatchingResults(List<MeasType> filteredMeasTypes, MeasValue measValue ) {
-        List<R> filteredResults = new ArrayList<>();
+    private boolean hasMatchingResults(List<MeasurementInfo.MeasType> filteredMeasTypes, MeasValue measValue ) {
+        List<MeasValue.R> filteredResults = new ArrayList<>();
 
         filteredMeasTypes.forEach( mst ->
             measValue.getR().stream()
@@ -164,8 +162,8 @@ public class MeasFilterHandler {
        return hasResults;
     }
 
-    private void setMeasInfoFromMeasType(MeasInfo currentMeasInfo, List<MeasInfo> filteredMeasInfos, Filter filter) {
-        List<MeasType> filteredMeasTypes = currentMeasInfo.getMeasType().stream()
+    private void setMeasInfoFromMeasType(MeasurementInfo currentMeasInfo, List<MeasurementInfo> filteredMeasInfos, Filter filter) {
+        List<MeasurementInfo.MeasType> filteredMeasTypes = currentMeasInfo.getMeasType().stream()
                 .filter(mt -> filter.getMeasTypes().contains(mt.getValue()))
                 .collect(Collectors.toList());
 
@@ -179,7 +177,7 @@ public class MeasFilterHandler {
         }
     }
 
-    private void setMeasInfosFromMeasTypes(MeasInfo currentMeasInfo, List<MeasInfo> filteredMeasInfos, Filter filter) {
+    private void setMeasInfosFromMeasTypes(MeasurementInfo currentMeasInfo, List<MeasurementInfo> filteredMeasInfos, Filter filter) {
         MeasValue currentMeasValue = currentMeasInfo.getMeasValue()
                 .get(0);
         List<String> measTypesNode = currentMeasInfo.getMeasTypes();
index a9b7e86..89a4acc 100644 (file)
@@ -1,6 +1,6 @@
 /*-
  * ============LICENSE_START=======================================================
- *  Copyright (C) 2019 Nordix Foundation.
+ *  Copyright (C) 2019-2020 Nordix Foundation.
  * ================================================================================
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -24,8 +24,11 @@ import freemarker.ext.dom.NodeModel;
 import freemarker.template.Configuration;
 import freemarker.template.Template;
 import freemarker.template.TemplateException;
+import java.util.Optional;
+import java.util.stream.Stream;
 import lombok.NonNull;
 import org.onap.dcaegen2.services.pmmapper.exceptions.MappingException;
+import org.onap.dcaegen2.services.pmmapper.exceptions.TemplateIdentificationException;
 import org.onap.dcaegen2.services.pmmapper.exceptions.XMLParseException;
 import org.onap.dcaegen2.services.pmmapper.model.Event;
 import org.onap.dcaegen2.services.pmmapper.utils.MeasConverter;
@@ -49,23 +52,33 @@ import java.util.UUID;
 
 public class Mapper {
     private static final ONAPLogAdapter logger = new ONAPLogAdapter(LoggerFactory.getLogger(Mapper.class));
-    private Template mappingTemplate;
+
+    private HashMap<String, Template> templates;
     private MeasConverter converter;
 
-    public Mapper(@NonNull Path pathToTemplate, MeasConverter converter) {
-        logger.unwrap().trace("Constructing Mapper from {}", pathToTemplate);
+    public Mapper(@NonNull Path templatesDirectory, MeasConverter converter) {
+        logger.unwrap().trace("Constructing Mapper from {}", templatesDirectory);
+        templates = new HashMap<>();
         this.converter = converter;
         Configuration configuration = new Configuration(Configuration.VERSION_2_3_28);
         configuration.setTagSyntax(Configuration.ANGLE_BRACKET_TAG_SYNTAX);
-        try {
-            InputStreamReader templateInputStreamReader = new InputStreamReader(Files.newInputStream(pathToTemplate));
-            mappingTemplate = new Template("pm", templateInputStreamReader, configuration, StandardCharsets.UTF_8.name());
+        try (Stream<Path> paths = Files.walk(templatesDirectory)) {
+            paths.filter(Files::isRegularFile)
+                    .forEach(template -> addTemplate(template, configuration));
+        } catch (IOException exception) {
+            logger.unwrap().error("Failed to walk template directory {}", templatesDirectory, exception);
+            throw new IllegalArgumentException("Failed to walk template directory {}", exception);
+        }
+    }
+    private void addTemplate(Path template, Configuration config) {
+        logger.unwrap().debug("Loading template from {}", template.toString());
+        try (InputStreamReader templateInputStreamReader = new InputStreamReader(Files.newInputStream(template))){
+            templates.put(template.getFileName().toString(), new Template(template.getFileName().toString(), templateInputStreamReader, config, StandardCharsets.UTF_8.name()));
         } catch (IOException exception) {
-            logger.unwrap().error("Failed to read template from location {}", pathToTemplate, exception);
+            logger.unwrap().error("Failed to read template from location {}", template, exception);
             throw new IllegalArgumentException("Failed to read template from path", exception);
         }
     }
-
     public List<Event> mapEvents(List<Event> events) {
         events.forEach(event -> event.setVes(this.map(event)));
         return events;
@@ -75,8 +88,8 @@ public class Mapper {
         logger.unwrap().info("Mapping event");
         NodeModel pmNodeModel;
         try {
-            String measCollecFile = converter.convert(event.getMeasCollecFile());
-            pmNodeModel = NodeModel.parse(new InputSource(new StringReader(measCollecFile)));
+            String measurements = converter.convert(event.getMeasurement());
+            pmNodeModel = NodeModel.parse(new InputSource(new StringReader(measurements)));
         } catch (IOException | SAXException | ParserConfigurationException exception) {
             logger.unwrap().error("Failed to parse input as XML", exception);
             throw new XMLParseException("Failed to parse input as XML", exception);
@@ -86,8 +99,10 @@ public class Mapper {
         mappingData.put("metadata", event.getMetadata());
         mappingData.put("eventId", makeEventId());
         StringWriter mappedOutputWriter = new StringWriter();
+        Template template = Optional.ofNullable(templates.get(event.getMetadata().getFileFormatType()))
+                                    .orElseThrow(() -> new TemplateIdentificationException("Failed to identify template"));
         try {
-            mappingTemplate.process(mappingData, mappedOutputWriter);
+            template.process(mappingData, mappedOutputWriter);
         } catch (IOException | TemplateException exception) {
             logger.unwrap().error("Failed to map XML", exception);
             throw new MappingException("Mapping failure", exception);
index 9eadb8a..57d9570 100644 (file)
@@ -1,6 +1,6 @@
 /*-
  * ============LICENSE_START=======================================================
- *  Copyright (C) 2019 Nordix Foundation.
+ *  Copyright (C) 2020 Nordix Foundation.
  * ================================================================================
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -25,6 +25,7 @@ import lombok.NonNull;
 
 import java.util.Map;
 import org.onap.dcaegen2.services.pmmapper.model.MeasFilterConfig.Filter;
+import org.onap.dcaegen2.services.pmmapper.model.measurement.common.MeasurementFile;
 
 /**
  * Class used to pass around relevant inbound event data.
@@ -42,7 +43,7 @@ public class Event {
     @NonNull
     private String publishIdentity;
 
-    private MeasCollecFile measCollecFile;
+    private MeasurementFile measurement;
 
     private Filter filter;
 
diff --git a/src/main/java/org/onap/dcaegen2/services/pmmapper/model/MeasCollecFile.java b/src/main/java/org/onap/dcaegen2/services/pmmapper/model/MeasCollecFile.java
deleted file mode 100644 (file)
index cc6ca0f..0000000
+++ /dev/null
@@ -1,270 +0,0 @@
-/*-\r
- * ============LICENSE_START=======================================================\r
- *  Copyright (C) 2019 Nordix Foundation.\r
- * ================================================================================\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- *      http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- *\r
- * SPDX-License-Identifier: Apache-2.0\r
- * ============LICENSE_END=========================================================\r
- */\r
-\r
-package org.onap.dcaegen2.services.pmmapper.model;\r
-\r
-import java.math.BigInteger;\r
-import java.util.List;\r
-\r
-import javax.xml.bind.annotation.XmlAccessType;\r
-import javax.xml.bind.annotation.XmlAccessorType;\r
-import javax.xml.bind.annotation.XmlAttribute;\r
-import javax.xml.bind.annotation.XmlElement;\r
-import javax.xml.bind.annotation.XmlList;\r
-import javax.xml.bind.annotation.XmlRootElement;\r
-import javax.xml.bind.annotation.XmlSchemaType;\r
-import javax.xml.bind.annotation.XmlType;\r
-import javax.xml.bind.annotation.XmlValue;\r
-import javax.xml.bind.annotation.adapters.CollapsedStringAdapter;\r
-import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;\r
-import javax.xml.datatype.Duration;\r
-import javax.xml.datatype.XMLGregorianCalendar;\r
-import lombok.Data;\r
-\r
-@XmlAccessorType(XmlAccessType.FIELD)\r
-@XmlType(name = "", propOrder = {\r
-    "fileHeader",\r
-    "measData",\r
-    "fileFooter"\r
-})\r
-@XmlRootElement(name = "measCollecFile")\r
-@Data\r
-public class MeasCollecFile {\r
-\r
-    @XmlElement(required = true)\r
-    protected MeasCollecFile.FileHeader fileHeader;\r
-    protected List<MeasCollecFile.MeasData> measData;\r
-    @XmlElement(required = true)\r
-    protected MeasCollecFile.FileFooter fileFooter;\r
-    @XmlAccessorType(XmlAccessType.FIELD)\r
-    @XmlType(name = "", propOrder = {\r
-        "measCollec"\r
-    })\r
-    @Data\r
-    public static class FileFooter {\r
-\r
-        @XmlElement(required = true)\r
-        protected MeasCollecFile.FileFooter.MeasCollec measCollec;\r
-\r
-        @XmlAccessorType(XmlAccessType.FIELD)\r
-        @XmlType(name = "")\r
-        public static class MeasCollec {\r
-            @XmlAttribute(name = "endTime", required = true)\r
-            @XmlSchemaType(name = "dateTime")\r
-            protected XMLGregorianCalendar endTime;\r
-        }\r
-\r
-    }\r
-\r
-\r
-    @XmlAccessorType(XmlAccessType.FIELD)\r
-    @XmlType(name = "", propOrder = {\r
-        "fileSender",\r
-        "measCollec"\r
-    })\r
-    @Data\r
-    public static class FileHeader {\r
-        @XmlElement(required = true)\r
-        protected MeasCollecFile.FileHeader.FileSender fileSender;\r
-        @XmlElement(required = true)\r
-        protected MeasCollecFile.FileHeader.MeasCollec measCollec;\r
-        @XmlAttribute(name = "fileFormatVersion", required = true)\r
-        protected String fileFormatVersion;\r
-        @XmlAttribute(name = "vendorName")\r
-        protected String vendorName;\r
-        @XmlAttribute(name = "dnPrefix")\r
-        protected String dnPrefix;\r
-\r
-        @XmlAccessorType(XmlAccessType.FIELD)\r
-        @XmlType(name = "")\r
-        @Data\r
-        public static class FileSender {\r
-            @XmlAttribute(name = "localDn")\r
-            protected String localDn;\r
-            @XmlAttribute(name = "elementType")\r
-            protected String elementType;\r
-        }\r
-\r
-\r
-        @XmlAccessorType(XmlAccessType.FIELD)\r
-        @XmlType(name = "")\r
-        @Data\r
-        public static class MeasCollec {\r
-            @XmlAttribute(name = "beginTime", required = true)\r
-            @XmlSchemaType(name = "dateTime")\r
-            protected XMLGregorianCalendar beginTime;\r
-        }\r
-\r
-    }\r
-\r
-\r
-    @XmlAccessorType(XmlAccessType.FIELD)\r
-    @XmlType(name = "", propOrder = {\r
-        "managedElement",\r
-        "measInfo"\r
-    })\r
-    @Data\r
-    public static class MeasData {\r
-        @XmlElement(required = true)\r
-        protected MeasCollecFile.MeasData.ManagedElement managedElement;\r
-        protected List<MeasCollecFile.MeasData.MeasInfo> measInfo;\r
-\r
-        @XmlAccessorType(XmlAccessType.FIELD)\r
-        @XmlType(name = "")\r
-        @Data\r
-        public static class ManagedElement {\r
-            @XmlAttribute(name = "localDn")\r
-            protected String localDn;\r
-            @XmlAttribute(name = "userLabel")\r
-            protected String userLabel;\r
-            @XmlAttribute(name = "swVersion")\r
-            protected String swVersion;\r
-        }\r
-\r
-        @XmlAccessorType(XmlAccessType.FIELD)\r
-        @XmlType(name = "", propOrder = {\r
-            "job",\r
-            "granPeriod",\r
-            "repPeriod",\r
-            "measTypes",\r
-            "measType",\r
-            "measValue"\r
-        })\r
-        @Data\r
-        public static class MeasInfo {\r
-\r
-            protected MeasCollecFile.MeasData.MeasInfo.Job job;\r
-            @XmlElement(required = true)\r
-            protected MeasCollecFile.MeasData.MeasInfo.GranPeriod granPeriod;\r
-            protected MeasCollecFile.MeasData.MeasInfo.RepPeriod repPeriod;\r
-            @XmlList\r
-            protected List<String> measTypes;\r
-            protected List<MeasCollecFile.MeasData.MeasInfo.MeasType> measType;\r
-            protected List<MeasCollecFile.MeasData.MeasInfo.MeasValue> measValue;\r
-            @XmlAttribute(name = "measInfoId")\r
-            protected String measInfoId;\r
-\r
-            @XmlAccessorType(XmlAccessType.FIELD)\r
-            @XmlType(name = "")\r
-            @Data\r
-            public static class GranPeriod {\r
-                @XmlAttribute(name = "duration", required = true)\r
-                protected Duration duration;\r
-                @XmlAttribute(name = "endTime", required = true)\r
-                @XmlSchemaType(name = "dateTime")\r
-                protected XMLGregorianCalendar endTime;\r
-            }\r
-\r
-\r
-            @XmlAccessorType(XmlAccessType.FIELD)\r
-            @XmlType(name = "")\r
-            @Data\r
-            public static class Job {\r
-                @XmlAttribute(name = "jobId", required = true)\r
-                protected String jobId;\r
-            }\r
-\r
-            @XmlAccessorType(XmlAccessType.FIELD)\r
-            @XmlType(name = "", propOrder = {\r
-                "value"\r
-            })\r
-            @Data\r
-            public static class MeasType {\r
-                @XmlValue\r
-                @XmlJavaTypeAdapter(CollapsedStringAdapter.class)\r
-                @XmlSchemaType(name = "Name")\r
-                protected String value;\r
-                @XmlAttribute(name = "p", required = true)\r
-                @XmlSchemaType(name = "positiveInteger")\r
-                protected BigInteger p;\r
-            }\r
-\r
-            @XmlAccessorType(XmlAccessType.FIELD)\r
-            @XmlType(name = "", propOrder = {\r
-                "measResults",\r
-                "r",\r
-                "suspect"\r
-            })\r
-            @Data\r
-            public static class MeasValue {\r
-                @XmlList\r
-                protected List<String> measResults;\r
-                protected List<MeasCollecFile.MeasData.MeasInfo.MeasValue.R> r;\r
-                protected Boolean suspect;\r
-                @XmlAttribute(name = "measObjLdn", required = true)\r
-                protected String measObjLdn;\r
-\r
-                @XmlAccessorType(XmlAccessType.FIELD)\r
-                @XmlType(name = "", propOrder = {\r
-                    "value"\r
-                })\r
-                @Data\r
-                public static class R {\r
-                    @XmlValue\r
-                    protected String value;\r
-                    @XmlAttribute(name = "p", required = true)\r
-                    @XmlSchemaType(name = "positiveInteger")\r
-                    protected BigInteger p;\r
-                }\r
-                public void replaceR(List<R> filteredRs) {\r
-                    this.r = filteredRs;\r
-\r
-                }\r
-                public void replaceMeasResults(List<String> filteredMeasResults) {\r
-                   this.measResults = filteredMeasResults;\r
-\r
-                }\r
-            }\r
-            @XmlAccessorType(XmlAccessType.FIELD)\r
-            @XmlType(name = "")\r
-            @Data\r
-            public static class RepPeriod {\r
-\r
-                @XmlAttribute(name = "duration", required = true)\r
-                protected Duration duration;\r
-            }\r
-\r
-            public void replaceMeasTypes(List<String> newMeasTypes) {\r
-                this.measTypes = newMeasTypes;\r
-            }\r
-\r
-            public void replaceMeasType(List<MeasType> filteredMeasTypes) {\r
-                this.measType = filteredMeasTypes;\r
-            }\r
-\r
-            public void replaceMeasValue(List<MeasValue> filteredMeasValues) {\r
-                this.measValue = filteredMeasValues;\r
-            }\r
-\r
-        }\r
-\r
-\r
-        public void setMeasInfo(List<MeasInfo> filteredMeasInfos) {\r
-            this.measInfo  = filteredMeasInfos;\r
-        }\r
-\r
-    }\r
-\r
-\r
-    public void replaceMeasData(List<MeasData> measDataList) {\r
-        this.measData = measDataList;\r
-    }\r
-\r
-}\r
diff --git a/src/main/java/org/onap/dcaegen2/services/pmmapper/model/measurement/common/MeasurementData.java b/src/main/java/org/onap/dcaegen2/services/pmmapper/model/measurement/common/MeasurementData.java
new file mode 100644 (file)
index 0000000..f299064
--- /dev/null
@@ -0,0 +1,29 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2020 Nordix Foundation.
+ * ================================================================================
+ * 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.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.dcaegen2.services.pmmapper.model.measurement.common;
+
+import java.util.List;
+
+public interface MeasurementData {
+    public List<MeasurementInfo> getMeasurementInfo();
+    public void setMeasurementInfo(List<MeasurementInfo> measurementInfo);
+    public Object getManagedEntity();
+}
diff --git a/src/main/java/org/onap/dcaegen2/services/pmmapper/model/measurement/common/MeasurementFile.java b/src/main/java/org/onap/dcaegen2/services/pmmapper/model/measurement/common/MeasurementFile.java
new file mode 100644 (file)
index 0000000..3c44780
--- /dev/null
@@ -0,0 +1,30 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2020 Nordix Foundation.
+ * ================================================================================
+ * 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.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.dcaegen2.services.pmmapper.model.measurement.common;
+
+import java.util.List;
+import java.util.Optional;
+
+public interface MeasurementFile {
+
+    public Optional<List<MeasurementData>> getMeasurementData();
+    public void replacementMeasurementData(List<MeasurementData> measurementData);
+}
diff --git a/src/main/java/org/onap/dcaegen2/services/pmmapper/model/measurement/common/MeasurementInfo.java b/src/main/java/org/onap/dcaegen2/services/pmmapper/model/measurement/common/MeasurementInfo.java
new file mode 100644 (file)
index 0000000..c6042b1
--- /dev/null
@@ -0,0 +1,147 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2020 Nordix Foundation.
+ * ================================================================================
+ * 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.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.dcaegen2.services.pmmapper.model.measurement.common;
+
+import java.math.BigInteger;
+import java.util.List;
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlList;
+import javax.xml.bind.annotation.XmlSchemaType;
+import javax.xml.bind.annotation.XmlType;
+import javax.xml.bind.annotation.XmlValue;
+import javax.xml.bind.annotation.adapters.CollapsedStringAdapter;
+import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
+import javax.xml.datatype.Duration;
+import javax.xml.datatype.XMLGregorianCalendar;
+import lombok.Data;
+
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlType(name = "", propOrder = {"job", "granPeriod", "repPeriod", "measTypes", "measType", "measValue", "measInfoId"})
+@Data
+public class MeasurementInfo {
+
+    @XmlElement
+    protected Job job;
+    @XmlElement(required = true)
+    protected GranPeriod granPeriod;
+    protected RepPeriod repPeriod;
+    @XmlList
+    protected List<String> measTypes;
+    protected List<MeasType> measType;
+    protected List<MeasValue> measValue;
+    @XmlAttribute
+    protected String measInfoId;
+
+    @XmlAccessorType(XmlAccessType.FIELD)
+    @XmlType(name = "")
+    @Data
+    public static class GranPeriod {
+
+        @XmlAttribute(name = "duration", required = true)
+        protected Duration duration;
+        @XmlAttribute(name = "endTime", required = true)
+        @XmlSchemaType(name = "dateTime")
+        protected XMLGregorianCalendar endTime;
+    }
+
+
+    @XmlAccessorType(XmlAccessType.FIELD)
+    @XmlType(name = "")
+    @Data
+    public static class Job {
+
+        @XmlAttribute(name = "jobId", required = true)
+        protected String jobId;
+    }
+
+    @XmlAccessorType(XmlAccessType.FIELD)
+    @XmlType(name = "", propOrder = {"value"})
+    @Data
+    public static class MeasType {
+
+        @XmlValue
+        @XmlJavaTypeAdapter(CollapsedStringAdapter.class)
+        @XmlSchemaType(name = "Name")
+        protected String value;
+        @XmlAttribute(name = "p", required = true)
+        @XmlSchemaType(name = "positiveInteger")
+        protected BigInteger p;
+    }
+
+    @XmlAccessorType(XmlAccessType.FIELD)
+    @XmlType(name = "", propOrder = {"measResults", "r", "suspect"})
+    @Data
+    public static class MeasValue {
+
+        @XmlList
+        protected List<String> measResults;
+        protected List<MeasurementInfo.MeasValue.R> r;
+        protected Boolean suspect;
+        @XmlAttribute(name = "measObjLdn", required = true)
+        protected String measObjLdn;
+
+        @XmlAccessorType(XmlAccessType.FIELD)
+        @XmlType(name = "", propOrder = {"value"})
+        @Data
+        public static class R {
+
+            @XmlValue
+            protected String value;
+            @XmlAttribute(name = "p", required = true)
+            @XmlSchemaType(name = "positiveInteger")
+            protected BigInteger p;
+        }
+
+        public void replaceR(List<R> filteredRs) {
+            this.r = filteredRs;
+
+        }
+
+        public void replaceMeasResults(List<String> filteredMeasResults) {
+            this.measResults = filteredMeasResults;
+        }
+    }
+
+    @XmlAccessorType(XmlAccessType.FIELD)
+    @XmlType(name = "")
+    @Data
+    public static class RepPeriod {
+
+        @XmlAttribute(name = "duration", required = true)
+        protected Duration duration;
+    }
+
+    public void replaceMeasTypes(List<String> newMeasTypes) {
+        this.measTypes = newMeasTypes;
+    }
+
+    public void replaceMeasType(List<MeasType> filteredMeasTypes) {
+        this.measType = filteredMeasTypes;
+    }
+
+    public void replaceMeasValue(List<MeasValue> filteredMeasValues) {
+        this.measValue = filteredMeasValues;
+    }
+
+}
\ No newline at end of file
diff --git a/src/main/java/org/onap/dcaegen2/services/pmmapper/model/measurement/lte/MeasCollecFile.java b/src/main/java/org/onap/dcaegen2/services/pmmapper/model/measurement/lte/MeasCollecFile.java
new file mode 100644 (file)
index 0000000..d4dccef
--- /dev/null
@@ -0,0 +1,179 @@
+/*-\r
+ * ============LICENSE_START=======================================================\r
+ *  Copyright (C) 2019-2020 Nordix Foundation.\r
+ * ================================================================================\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *      http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ *\r
+ * SPDX-License-Identifier: Apache-2.0\r
+ * ============LICENSE_END=========================================================\r
+ */\r
+\r
+package org.onap.dcaegen2.services.pmmapper.model.measurement.lte;\r
+\r
+import java.util.ArrayList;\r
+import java.util.List;\r
+\r
+import java.util.Optional;\r
+import javax.xml.bind.annotation.XmlAccessType;\r
+import javax.xml.bind.annotation.XmlAccessorType;\r
+import javax.xml.bind.annotation.XmlAttribute;\r
+import javax.xml.bind.annotation.XmlElement;\r
+import javax.xml.bind.annotation.XmlRootElement;\r
+import javax.xml.bind.annotation.XmlSchemaType;\r
+import javax.xml.bind.annotation.XmlType;\r
+import javax.xml.datatype.XMLGregorianCalendar;\r
+import lombok.Data;\r
+import org.onap.dcaegen2.services.pmmapper.model.measurement.common.MeasurementData;\r
+import org.onap.dcaegen2.services.pmmapper.model.measurement.common.MeasurementFile;\r
+import org.onap.dcaegen2.services.pmmapper.model.measurement.common.MeasurementInfo;\r
+\r
+@XmlAccessorType(XmlAccessType.FIELD)\r
+@XmlType(name = "", propOrder = {\r
+    "fileHeader",\r
+    "measData",\r
+    "fileFooter"\r
+})\r
+@XmlRootElement(name = "measCollecFile")\r
+@Data\r
+public class MeasCollecFile implements MeasurementFile {\r
+\r
+    @XmlElement(required = true)\r
+    protected MeasCollecFile.FileHeader fileHeader;\r
+    protected List<MeasCollecFile.MeasData> measData;\r
+    @XmlElement(required = true)\r
+    protected MeasCollecFile.FileFooter fileFooter;\r
+\r
+    @Override\r
+    public Optional<List<MeasurementData>> getMeasurementData() {\r
+        try {\r
+            List<MeasurementData> measurementDataList = new ArrayList<>(this.measData);\r
+            return Optional.of(measurementDataList);\r
+        } catch (NullPointerException exception) {\r
+            return Optional.empty();\r
+        }\r
+    }\r
+\r
+    @Override\r
+    public void replacementMeasurementData(List<MeasurementData> measurementData) {\r
+        measData.clear();\r
+        measurementData.forEach(measurementDatum -> {\r
+            MeasData measDatum = new MeasData();\r
+            measDatum.setManagedElement((MeasData.ManagedElement) measurementDatum.getManagedEntity());\r
+            measDatum.setMeasInfo(measurementDatum.getMeasurementInfo());\r
+            this.measData.add(measDatum);\r
+        });\r
+    }\r
+\r
+    @XmlAccessorType(XmlAccessType.FIELD)\r
+    @XmlType(name = "", propOrder = {\r
+        "measCollec"\r
+    })\r
+    @Data\r
+    public static class FileFooter {\r
+\r
+        @XmlElement(required = true)\r
+        protected MeasCollecFile.FileFooter.MeasCollec measCollec;\r
+\r
+        @XmlAccessorType(XmlAccessType.FIELD)\r
+        @XmlType(name = "")\r
+        public static class MeasCollec {\r
+            @XmlAttribute(name = "endTime", required = true)\r
+            @XmlSchemaType(name = "dateTime")\r
+            protected XMLGregorianCalendar endTime;\r
+        }\r
+\r
+    }\r
+\r
+\r
+    @XmlAccessorType(XmlAccessType.FIELD)\r
+    @XmlType(name = "", propOrder = {\r
+        "fileSender",\r
+        "measCollec"\r
+    })\r
+    @Data\r
+    public static class FileHeader {\r
+        @XmlElement(required = true)\r
+        protected MeasCollecFile.FileHeader.FileSender fileSender;\r
+        @XmlElement(required = true)\r
+        protected MeasCollecFile.FileHeader.MeasCollec measCollec;\r
+        @XmlAttribute(name = "fileFormatVersion", required = true)\r
+        protected String fileFormatVersion;\r
+        @XmlAttribute(name = "vendorName")\r
+        protected String vendorName;\r
+        @XmlAttribute(name = "dnPrefix")\r
+        protected String dnPrefix;\r
+\r
+        @XmlAccessorType(XmlAccessType.FIELD)\r
+        @XmlType(name = "")\r
+        @Data\r
+        public static class FileSender {\r
+            @XmlAttribute(name = "localDn")\r
+            protected String localDn;\r
+            @XmlAttribute(name = "elementType")\r
+            protected String elementType;\r
+        }\r
+\r
+\r
+        @XmlAccessorType(XmlAccessType.FIELD)\r
+        @XmlType(name = "")\r
+        @Data\r
+        public static class MeasCollec {\r
+            @XmlAttribute(name = "beginTime", required = true)\r
+            @XmlSchemaType(name = "dateTime")\r
+            protected XMLGregorianCalendar beginTime;\r
+        }\r
+\r
+    }\r
+\r
+\r
+    @XmlAccessorType(XmlAccessType.FIELD)\r
+    @XmlType(name = "", propOrder = {\r
+        "managedElement",\r
+        "measInfo"\r
+    })\r
+    @Data\r
+    public static class MeasData implements MeasurementData {\r
+        @XmlElement(required = true)\r
+        protected MeasCollecFile.MeasData.ManagedElement managedElement;\r
+        @XmlElement(required = true)\r
+        protected List<MeasurementInfo> measInfo;\r
+\r
+        @Override\r
+        public List<MeasurementInfo> getMeasurementInfo() {\r
+            return this.measInfo;\r
+        }\r
+\r
+        @Override\r
+        public void setMeasurementInfo(List<MeasurementInfo> measurementInfo) {\r
+            this.measInfo = measurementInfo;\r
+        }\r
+\r
+        @Override\r
+        public Object getManagedEntity() {\r
+            return this.managedElement;\r
+        }\r
+\r
+        @XmlAccessorType(XmlAccessType.FIELD)\r
+        @XmlType(name = "")\r
+        @Data\r
+        public static class ManagedElement {\r
+            @XmlAttribute(name = "localDn")\r
+            protected String localDn;\r
+            @XmlAttribute(name = "userLabel")\r
+            protected String userLabel;\r
+            @XmlAttribute(name = "swVersion")\r
+            protected String swVersion;\r
+        }\r
+    }\r
+\r
+}\r
diff --git a/src/main/java/org/onap/dcaegen2/services/pmmapper/model/measurement/nr/MeasDataFile.java b/src/main/java/org/onap/dcaegen2/services/pmmapper/model/measurement/nr/MeasDataFile.java
new file mode 100644 (file)
index 0000000..1ef1a8b
--- /dev/null
@@ -0,0 +1,180 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2020 Nordix Foundation.
+ * ================================================================================
+ * 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.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.dcaegen2.services.pmmapper.model.measurement.nr;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import java.util.Optional;
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlSchemaType;
+import javax.xml.bind.annotation.XmlType;
+import javax.xml.datatype.XMLGregorianCalendar;
+import lombok.Data;
+import org.onap.dcaegen2.services.pmmapper.model.measurement.common.MeasurementData;
+import org.onap.dcaegen2.services.pmmapper.model.measurement.common.MeasurementFile;
+import org.onap.dcaegen2.services.pmmapper.model.measurement.common.MeasurementInfo;
+
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlType(name = "", propOrder = {
+        "fileHeader",
+        "measData",
+        "fileFooter"
+})
+@XmlRootElement(name = "MeasDataFile")
+@Data
+public class MeasDataFile implements MeasurementFile {
+
+    @XmlElement(required = true)
+    protected MeasDataFile.FileHeader fileHeader;
+    protected List<MeasDataFile.MeasData> measData;
+    @XmlElement(required = true)
+    protected MeasDataFile.FileFooter fileFooter;
+
+    @Override
+    public Optional<List<MeasurementData>> getMeasurementData() {
+        try {
+            List<MeasurementData> measDataList = new ArrayList<>(this.measData);
+            return Optional.of(measDataList);
+        } catch (NullPointerException exception) {
+            return Optional.empty();
+        }
+    }
+
+    @Override
+    public void replacementMeasurementData(List<MeasurementData> measurementData) {
+        measData.clear();
+        measurementData.forEach(measurementDatum -> {
+            MeasData measDatum = new MeasData();
+            measDatum.setMeasuredEntity((MeasData.MeasuredEntity) measurementDatum.getManagedEntity());
+            measDatum.setMeasInfo(measurementDatum.getMeasurementInfo());
+            this.measData.add(measDatum);
+        });
+    }
+
+    @XmlAccessorType(XmlAccessType.FIELD)
+    @XmlType(name = "", propOrder = {
+            "measData"
+    })
+    @Data
+    public static class FileFooter {
+
+        @XmlElement(name = "MeasData", required = true)
+        protected MeasDataFile.FileFooter.MeasData measData;
+
+        @XmlAccessorType(XmlAccessType.FIELD)
+        @XmlType(name = "")
+        public static class MeasData {
+            @XmlAttribute(name = "endTime", required = true)
+            @XmlSchemaType(name = "dateTime")
+            protected XMLGregorianCalendar endTime;
+        }
+
+    }
+
+
+    @XmlAccessorType(XmlAccessType.FIELD)
+    @XmlType(name = "", propOrder = {
+            "fileSender",
+            "measData"
+    })
+    @Data
+    public static class FileHeader {
+        @XmlElement(required = true)
+        protected MeasDataFile.FileHeader.FileSender fileSender;
+        @XmlElement(name = "MeasData", required = true)
+        protected MeasDataFile.FileHeader.MeasData measData;
+        @XmlAttribute(name = "fileFormatVersion", required = true)
+        protected String fileFormatVersion;
+        @XmlAttribute(name = "vendorName")
+        protected String vendorName;
+        @XmlAttribute(name = "dnPrefix")
+        protected String dnPrefix;
+
+        @XmlAccessorType(XmlAccessType.FIELD)
+        @XmlType(name = "")
+        @Data
+        public static class FileSender {
+            @XmlAttribute(name = "senderName")
+            protected String senderName;
+            @XmlAttribute(name = "elementType")
+            protected String elementType;
+        }
+
+
+        @XmlAccessorType(XmlAccessType.FIELD)
+        @XmlType(name = "")
+        @Data
+        public static class MeasData {
+            @XmlAttribute(name = "beginTime", required = true)
+            @XmlSchemaType(name = "dateTime")
+            protected XMLGregorianCalendar beginTime;
+        }
+
+    }
+
+
+    @XmlAccessorType(XmlAccessType.FIELD)
+    @XmlType(name = "", propOrder = {
+            "measuredEntity",
+            "measInfo"
+    })
+    @Data
+    public static class MeasData implements MeasurementData {
+        @XmlElement(required = true)
+        protected MeasDataFile.MeasData.MeasuredEntity measuredEntity;
+        @XmlElement()
+        protected List<MeasurementInfo> measInfo;
+
+        @Override
+        public List<MeasurementInfo> getMeasurementInfo() {
+            return this.measInfo;
+        }
+
+        @Override
+        public void setMeasurementInfo(List<MeasurementInfo> measurementInfo) {
+            this.measInfo = measurementInfo;
+        }
+
+        @Override
+        public Object getManagedEntity() {
+            return this.measuredEntity;
+        }
+
+        @XmlAccessorType(XmlAccessType.FIELD)
+        @XmlType(name = "")
+        @Data
+        public static class MeasuredEntity {
+            @XmlAttribute(name = "localDn")
+            protected String localDn;
+            @XmlAttribute(name = "userLabel")
+            protected String userLabel;
+            @XmlAttribute(name = "swVersion")
+            protected String swVersion;
+        }
+
+    }
+
+}
index b9c01e6..70ad8ab 100644 (file)
@@ -1,6 +1,6 @@
 /*-\r
  * ============LICENSE_START=======================================================\r
- *  Copyright (C) 2019 Nordix Foundation.\r
+ *  Copyright (C) 2019-2020 Nordix Foundation.\r
  * ================================================================================\r
  * Licensed under the Apache License, Version 2.0 (the "License");\r
  * you may not use this file except in compliance with the License.\r
@@ -28,10 +28,19 @@ import javax.xml.bind.JAXBException;
 import javax.xml.bind.Marshaller;\r
 import javax.xml.bind.Unmarshaller;\r
 \r
+import javax.xml.parsers.ParserConfigurationException;\r
+import javax.xml.parsers.SAXParserFactory;\r
+import javax.xml.transform.sax.SAXSource;\r
 import org.onap.dcaegen2.services.pmmapper.exceptions.MappingException;\r
-import org.onap.dcaegen2.services.pmmapper.model.MeasCollecFile;\r
+import org.onap.dcaegen2.services.pmmapper.model.Event;\r
+import org.onap.dcaegen2.services.pmmapper.model.measurement.common.MeasurementFile;\r
+import org.onap.dcaegen2.services.pmmapper.model.measurement.lte.MeasCollecFile;\r
+import org.onap.dcaegen2.services.pmmapper.model.measurement.nr.MeasDataFile;\r
 import org.onap.logging.ref.slf4j.ONAPLogAdapter;\r
 import org.slf4j.LoggerFactory;\r
+import org.xml.sax.InputSource;\r
+import org.xml.sax.SAXException;\r
+import org.xml.sax.XMLReader;\r
 \r
 /**\r
  * Converts 3GPP PM Measurement xml string to MeasCollecFil and vice versa.\r
@@ -39,38 +48,57 @@ import org.slf4j.LoggerFactory;
 public class MeasConverter {\r
     private static final ONAPLogAdapter logger = new ONAPLogAdapter(LoggerFactory.getLogger(MeasConverter.class));\r
 \r
+    public static final String LTE_FILE_TYPE = "org.3GPP.32.435#measCollec";\r
+    public static final String NR_FILE_TYPE = "org.3GPP.28.550#measData";\r
+\r
+\r
     /**\r
      * Converts 3GPP Measurement xml string to MeasCollecFile.\r
      **/\r
-    public MeasCollecFile convert(String eventBody) {\r
-        logger.unwrap().debug("Converting 3GPP xml string to MeasCollecFile");\r
-        MeasCollecFile measCollecFile = null;\r
+    public MeasurementFile convert(Event event) {\r
+        logger.unwrap().debug("Converting 3GPP xml string to PM object");\r
+        Class targetClass = getPMFileClass(event);\r
         try {\r
-            JAXBContext jaxbContext = null;\r
-            jaxbContext = JAXBContext.newInstance(MeasCollecFile.class);\r
+            JAXBContext jaxbContext = JAXBContext.newInstance(targetClass);\r
             Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();\r
-            measCollecFile = (MeasCollecFile) unmarshaller.unmarshal(new StringReader(eventBody));\r
-        } catch (JAXBException e) {\r
-            throw new MappingException("Unable to convert 3GPP xml to MeasCollecFile", e);\r
+            SAXParserFactory saxFactory = SAXParserFactory.newInstance();\r
+            saxFactory.setNamespaceAware(false);\r
+            XMLReader reader = saxFactory.newSAXParser().getXMLReader();\r
+            SAXSource source = new SAXSource(reader,new InputSource(new StringReader(event.getBody())));\r
+            return (MeasurementFile) unmarshaller.unmarshal(source);\r
+        } catch (JAXBException | ParserConfigurationException | SAXException e) {\r
+            throw new MappingException("Unable to convert 3GPP xml to PM Measurement", e);\r
         }\r
-        return measCollecFile;\r
     }\r
 \r
     /**\r
      * Converts MeasCollecFile to 3GPP Measurement xml string.\r
      **/\r
-    public String convert(MeasCollecFile measCollecFile) {\r
-        logger.unwrap().debug("Converting MeasCollecFile to 3GPP xml string");\r
+    public String convert(MeasurementFile measurement) {\r
+        logger.unwrap().debug("Converting Measurement to 3GPP xml string");\r
         StringWriter writer = new StringWriter();\r
         try {\r
-            JAXBContext jaxbContext = JAXBContext.newInstance(MeasCollecFile.class);\r
+            JAXBContext jaxbContext = JAXBContext.newInstance(measurement.getClass());\r
             Marshaller marshaller = jaxbContext.createMarshaller();\r
             marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);\r
             marshaller.setProperty(Marshaller.JAXB_FRAGMENT, Boolean.TRUE);\r
-            marshaller.marshal(measCollecFile, writer);\r
+            marshaller.marshal(measurement, writer);\r
         } catch (JAXBException e) {\r
-            throw new MappingException("Unable to convert MeasCollecFile to 3GPP xml", e);\r
+            throw new MappingException("Unable to convert Measurement to 3GPP xml", e);\r
         }\r
         return writer.toString();\r
     }\r
+\r
+    private Class getPMFileClass(Event event) {\r
+        Class pmFileClass;\r
+        if (event.getMetadata().getFileFormatType().equals(MeasConverter.LTE_FILE_TYPE)) {\r
+            pmFileClass = MeasCollecFile.class;\r
+        } else if(event.getMetadata().getFileFormatType().equals(NR_FILE_TYPE)) {\r
+            pmFileClass = MeasDataFile.class;\r
+        } else {\r
+            throw new MappingException("Failed to discover file type with first class support", new RuntimeException());\r
+        }\r
+        return pmFileClass;\r
+    }\r
+\r
 }\r
index 92d9e17..b3e73fd 100644 (file)
@@ -1,6 +1,6 @@
 /*-\r
  * ============LICENSE_START=======================================================\r
- *  Copyright (C) 2019 Nordix Foundation.\r
+ *  Copyright (C) 2019-2020 Nordix Foundation.\r
  * ================================================================================\r
  * Licensed under the Apache License, Version 2.0 (the "License");\r
  * you may not use this file except in compliance with the License.\r
@@ -27,8 +27,8 @@ import java.util.stream.Collectors;
 import org.onap.dcaegen2.services.pmmapper.model.Event;\r
 import java.util.NoSuchElementException;\r
 \r
-import org.onap.dcaegen2.services.pmmapper.model.MeasCollecFile;\r
-import org.onap.dcaegen2.services.pmmapper.model.MeasCollecFile.MeasData;\r
+import org.onap.dcaegen2.services.pmmapper.model.measurement.common.MeasurementData;\r
+import org.onap.dcaegen2.services.pmmapper.model.measurement.common.MeasurementFile;\r
 import org.onap.logging.ref.slf4j.ONAPLogAdapter;\r
 import org.slf4j.LoggerFactory;\r
 \r
@@ -47,33 +47,32 @@ public class MeasSplitter {
      * Splits the MeasCollecFile to multiple MeasCollecFile based on the number of MeasData\r
      **/\r
     public List<Event> split(Event event) {\r
-        logger.unwrap().debug("Splitting 3GPP xml MeasData to individual MeasCollecFile");\r
-        MeasCollecFile currentMeasurement = converter.convert(event.getBody());\r
-        event.setMeasCollecFile(currentMeasurement);\r
-        if (currentMeasurement.getMeasData() == null || currentMeasurement.getMeasData().isEmpty()) {\r
+        logger.unwrap().debug("Splitting 3GPP xml MeasData to individual Measurements");\r
+        MeasurementFile currentMeasurement = converter.convert(event);\r
+        event.setMeasurement(currentMeasurement);\r
+\r
+        if (!currentMeasurement.getMeasurementData().isPresent()  || currentMeasurement.getMeasurementData().get().isEmpty()) {\r
             throw new NoSuchElementException("MeasData is empty.");\r
         }\r
-        return currentMeasurement.getMeasData().stream().map(measData -> {\r
+        return currentMeasurement.getMeasurementData().get().stream().map(measData -> {\r
             Event newEvent  = generateNewEvent(event);\r
-            MeasCollecFile newMeasCollec = generateNewMeasCollec(newEvent,measData);\r
-            newEvent.setMeasCollecFile(newMeasCollec);\r
+            MeasurementFile newMeasurement = makeMeasurement(newEvent,measData);\r
+            newEvent.setMeasurement(newMeasurement);\r
             return newEvent;\r
         }).collect(Collectors.toList());\r
     }\r
 \r
-    private MeasCollecFile generateNewMeasCollec(Event event, MeasData measData) {\r
-        MeasCollecFile measCollec = new MeasCollecFile();\r
-        measCollec.replaceMeasData(Arrays.asList(measData));\r
-        measCollec.setFileHeader(event.getMeasCollecFile().getFileHeader());\r
-        measCollec.setFileFooter(event.getMeasCollecFile().getFileFooter());\r
-        return measCollec;\r
+    private MeasurementFile makeMeasurement(Event event, MeasurementData measData) {\r
+        MeasurementFile measurement = converter.convert(event);\r
+        measurement.replacementMeasurementData(Arrays.asList(measData));\r
+        return measurement;\r
     }\r
 \r
     private Event generateNewEvent(Event event) {\r
         Event modifiedEvent =  new Event(event.getHttpServerExchange(),\r
                 event.getBody(), event.getMetadata(), event.getMdc(),\r
                 event.getPublishIdentity());\r
-        modifiedEvent.setMeasCollecFile(event.getMeasCollecFile());\r
+        modifiedEvent.setMeasurement(event.getMeasurement());\r
         modifiedEvent.setFilter(event.getFilter());\r
         return modifiedEvent;\r
     }\r
index a00f80b..9fa3e85 100644 (file)
@@ -1,6 +1,6 @@
 /*-
  * ============LICENSE_START=======================================================
- *  Copyright (C) 2019 Nordix Foundation.
+ *  Copyright (C) 2019-2020 Nordix Foundation.
  * ================================================================================
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -20,6 +20,9 @@
 
 package org.onap.dcaegen2.services.pmmapper.utils;
 
+import java.nio.file.Files;
+import java.util.HashMap;
+import java.util.stream.Stream;
 import lombok.NonNull;
 import org.onap.dcaegen2.services.pmmapper.mapping.Mapper;
 import org.onap.dcaegen2.services.pmmapper.model.Event;
@@ -38,20 +41,32 @@ import java.nio.file.Path;
 
 public class XMLValidator {
     private static final ONAPLogAdapter logger = new ONAPLogAdapter(LoggerFactory.getLogger(Mapper.class));
-    private Schema schema;
-    public XMLValidator(Path xmlSchemaDefinition) {
-        SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
-        try {
-            schema = schemaFactory.newSchema(xmlSchemaDefinition.toFile());
-        } catch (SAXException exception) {
-            logger.unwrap().error("Failed to read schema", exception);
-            throw new IllegalArgumentException("Bad Schema", exception);
+    private HashMap<String, Schema> schemas;
+    private SchemaFactory schemaFactory;
+    public XMLValidator(Path schemaDirectory) {
+        logger.unwrap().trace("Constructing schema from {}", schemaDirectory);
+        schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
+        schemas = new HashMap<>();
+        try (Stream<Path> paths = Files.walk(schemaDirectory)) {
+            paths.filter(Files::isRegularFile).forEach(this::addSchema);
+        } catch (IOException exception) {
+            logger.unwrap().error("Failed to walk schema directory {}", schemaDirectory, exception);
+            throw new IllegalArgumentException("Failed to walk template directory {}", exception);
         }
     }
 
+    private void addSchema(Path schema) {
+        logger.unwrap().debug("Loading schema from {}", schema.toString());
+        try {
+            schemas.put(schema.getFileName().toString(), schemaFactory.newSchema(schema.toFile()));
+        } catch(SAXException exception) {
+            logger.unwrap().error("Failed to discover a valid schema at {}", schema, exception);
+            throw new IllegalArgumentException("Failed to discover a valid schema from given path", exception);
+        }
+    }
     public boolean validate(@NonNull Event event) {
         try {
-            Validator validator =  schema.newValidator();
+            Validator validator =  schemas.get(event.getMetadata().getFileFormatType()).newValidator();
             validator.validate(new StreamSource(new StringReader(event.getBody())));
             logger.unwrap().info("XML validation successful {}", event);
             return true;
index bf59524..c4eeb2e 100644 (file)
@@ -1,6 +1,6 @@
 #
 # ============LICENSE_START=======================================================
-#  Copyright (C) 2019 Nordix Foundation.
+#  Copyright (C) 2019-2020 Nordix Foundation.
 # ================================================================================
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
@@ -34,8 +34,8 @@ USER pm-mapper
 COPY ${project.build.directory}/${ext.dep.dir.path}/ ${ext.dep.dir.path}/
 COPY ${project.build.directory}/${JAR} .
 
-COPY ${project.build.directory}/classes/mapping.ftl ./etc/mapping.ftl
-COPY ${project.build.directory}/classes/measCollec_plusString.xsd ./etc/measCollec_plusString.xsd
+COPY ${project.build.directory}/classes/schemas ./etc/schemas/
+COPY ${project.build.directory}/classes/templates ./etc/templates/
 COPY ${project.build.directory}/classes/reconfigure.sh ./etc/reconfigure.sh
 COPY --chown=pm-mapper ${project.build.directory}/classes/logback.xml ./etc/logback.xml
 
diff --git a/src/main/resources/schemas/org.3GPP.28.550#measData b/src/main/resources/schemas/org.3GPP.28.550#measData
new file mode 100644 (file)
index 0000000..d3a9fef
--- /dev/null
@@ -0,0 +1,131 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  3GPP TS 28.550 Measurements data XML file format definition
+  data file XML schema
+  measData.xsd
+-->
+<schema xmlns="http://www.w3.org/2001/XMLSchema" xmlns:md="http://www.3gpp.org/ftp/specs/archive/28_series/28.550#measData" targetNamespace="http://www.3gpp.org/ftp/specs/archive/28_series/28.550#measData" elementFormDefault="qualified">
+    <!-- Measurement collection data file root XML element -->
+    <element name="MeasDataFile">
+        <complexType>
+            <sequence>
+                <element name="fileHeader">
+                    <complexType>
+                        <sequence>
+                            <element name="fileSender">
+                                <complexType>
+                                    <attribute name="senderName" type="string" use="optional"/>
+                                    <attribute name="senderType" type="string" use="optional"/>
+                                </complexType>
+                            </element>
+                            <element name="MeasData">
+                                <complexType>
+                                    <attribute name="beginTime" type="dateTime" use="required"/>
+                                </complexType>
+                            </element>
+                        </sequence>
+                        <attribute name="fileFormatVersion" type="string" use="required"/>
+                        <attribute name="vendorName" type="string" use="optional"/>
+                        <attribute name="dnPrefix" type="string" use="optional"/>
+                    </complexType>
+                </element>
+                <element name="measData" minOccurs="0" maxOccurs="unbounded">
+                    <complexType>
+                        <sequence>
+                            <element name="measuredEntity">
+                                <complexType>
+                                    <attribute name="userLabel" type="string" use="optional"/>
+                                    <attribute name="localDn" type="string" use="optional"/>
+                                    <attribute name="swVersion" type="string" use="optional"/>
+                                </complexType>
+                            </element>
+                            <element name="measInfo" minOccurs="0" maxOccurs="unbounded">
+                                <complexType>
+                                    <sequence>
+                                        <element name="job" minOccurs="0">
+                                            <complexType>
+                                                <attribute name="jobId" type="string" use="required"/>
+                                            </complexType>
+                                        </element>
+                                        <element name="granPeriod">
+                                            <complexType>
+                                                <attribute name="duration" type="duration" use="required"/>
+                                                <attribute name="endTime" type="dateTime" use="required"/>
+                                            </complexType>
+                                        </element>
+                                        <element name="repPeriod" minOccurs="0">
+                                            <complexType>
+                                                <attribute name="duration" type="duration" use="required"/>
+                                            </complexType>
+                                        </element>
+                                        <choice>
+                                            <element name="measTypes">
+                                                <simpleType>
+                                                    <list itemType="Name"/>
+                                                </simpleType>
+                                            </element>
+                                            <element name="measType" minOccurs="0" maxOccurs="unbounded">
+                                                <complexType>
+                                                    <simpleContent>
+                                                        <extension base="Name">
+                                                            <attribute name="p" type="positiveInteger" use="required"/>
+                                                        </extension>
+                                                    </simpleContent>
+                                                </complexType>
+                                            </element>
+                                        </choice>
+                                        <element name="measValue" minOccurs="0" maxOccurs="unbounded">
+                                            <complexType>
+                                                <sequence>
+                                                    <choice>
+                                                        <element name="measResults">
+                                                            <simpleType>
+                                                                <list itemType="md:measResultType"/>
+                                                            </simpleType>
+                                                        </element>
+                                                        <element name="r" minOccurs="0" maxOccurs="unbounded">
+                                                            <complexType>
+                                                                <simpleContent>
+                                                                    <extension base="md:measResultType">
+                                                                        <attribute name="p" type="positiveInteger" use="required"/>
+                                                                    </extension>
+                                                                </simpleContent>
+                                                            </complexType>
+                                                        </element>
+                                                    </choice>
+                                                    <element name="suspect" type="boolean" minOccurs="0"/>
+                                                </sequence>
+                                                <attribute name="measObjLdn" type="string" use="required"/>
+                                            </complexType>
+                                        </element>
+                                    </sequence>
+                                    <attribute name="measInfoId" type="string" use="optional"/>
+                                </complexType>
+                            </element>
+                        </sequence>
+                    </complexType>
+                </element>
+                <element name="fileFooter">
+                    <complexType>
+                        <sequence>
+                            <element name="MeasData">
+                                <complexType>
+                                    <attribute name="endTime" type="dateTime" use="required"/>
+                                </complexType>
+                            </element>
+                        </sequence>
+                    </complexType>
+                </element>
+            </sequence>
+        </complexType>
+    </element>
+    <simpleType name="measResultType">
+        <union memberTypes="integer float string">
+            <simpleType>
+                <restriction base="string">
+                    <enumeration value="NULL"/>
+                </restriction>
+            </simpleType>
+        </union>
+    </simpleType>
+</schema>
\ No newline at end of file
diff --git a/src/main/resources/schemas/org.3GPP.32.435#measCollec b/src/main/resources/schemas/org.3GPP.32.435#measCollec
new file mode 100644 (file)
index 0000000..309bcb9
--- /dev/null
@@ -0,0 +1,159 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+  Modified PM XML file format definition to allow arbitrary string values.
+  Based on 3GPP TS 32.435 Performance Measurement XML file format definition
+  data file XML schema
+  measCollec.xsd
+-->
+
+<schema
+        targetNamespace=
+                "http://www.3gpp.org/ftp/specs/archive/32_series/32.435#measCollec"
+        elementFormDefault="qualified"
+        xmlns="http://www.w3.org/2001/XMLSchema"
+        xmlns:mc=
+                "http://www.3gpp.org/ftp/specs/archive/32_series/32.435#measCollec"
+>
+
+    <!-- Measurement collection data file root XML element -->
+
+    <element name="measCollecFile">
+        <complexType>
+            <sequence>
+                <element name="fileHeader">
+                    <complexType>
+                        <sequence>
+                            <element name="fileSender">
+                                <complexType>
+                                    <attribute name="localDn" type="string" use="optional"/>
+                                    <attribute name="elementType" type="string" use="optional"/>
+                                </complexType>
+                            </element>
+                            <element name="measCollec">
+                                <complexType>
+                                    <attribute name="beginTime" type="dateTime" use="required"/>
+                                </complexType>
+                            </element>
+                        </sequence>
+                        <attribute name="fileFormatVersion" type="string" use="required"/>
+                        <attribute name="vendorName" type="string" use="optional"/>
+                        <attribute name="dnPrefix" type="string" use="optional"/>
+                    </complexType>
+                </element>
+                <element name="measData" minOccurs="0" maxOccurs="unbounded">
+                    <complexType>
+                        <sequence>
+                            <element name="managedElement">
+                                <complexType>
+                                    <attribute name="localDn" type="string" use="optional"/>
+                                    <attribute name="userLabel" type="string" use="optional"/>
+                                    <attribute name="swVersion" type="string" use="optional"/>
+                                </complexType>
+                            </element>
+                            <element name="measInfo" minOccurs="0" maxOccurs="unbounded">
+                                <complexType>
+                                    <sequence>
+                                        <element name="job" minOccurs="0">
+                                            <complexType>
+                                                <attribute name="jobId" type="string" use="required"/>
+                                            </complexType>
+                                        </element>
+                                        <element name="granPeriod">
+                                            <complexType>
+                                                <attribute
+                                                        name="duration"
+                                                        type="duration"
+                                                        use="required"
+                                                />
+                                                <attribute
+                                                        name="endTime"
+                                                        type="dateTime"
+                                                        use="required"
+                                                />
+                                            </complexType>
+                                        </element>
+                                        <element name="repPeriod" minOccurs="0">
+                                            <complexType>
+                                                <attribute name="duration"
+                                                           type="duration" use="required"/>
+                                            </complexType>
+                                        </element>
+                                        <choice>
+                                            <element name="measTypes">
+                                                <simpleType>
+                                                    <list itemType="Name"/>
+                                                </simpleType>
+                                            </element>
+                                            <element name="measType"
+                                                     minOccurs="0" maxOccurs="unbounded">
+                                                <complexType>
+                                                    <simpleContent>
+                                                        <extension base="Name">
+                                                            <attribute name="p"
+                                                                       type="positiveInteger" use="required"/>
+                                                        </extension>
+                                                    </simpleContent>
+                                                </complexType>
+                                            </element>
+                                        </choice>
+                                        <element name="measValue"
+                                                 minOccurs="0" maxOccurs="unbounded">
+                                            <complexType>
+                                                <sequence>
+                                                    <choice>
+                                                        <element name="measResults">
+                                                            <simpleType>
+                                                                <list itemType="mc:measResultType"/>
+                                                            </simpleType>
+                                                        </element>
+                                                        <element name="r"
+                                                                 minOccurs="0" maxOccurs="unbounded">
+                                                            <complexType>
+                                                                <simpleContent>
+                                                                    <extension base="mc:measResultType">
+                                                                        <attribute name="p" type="positiveInteger"
+                                                                                   use="required"/>
+                                                                    </extension>
+                                                                </simpleContent>
+                                                            </complexType>
+                                                        </element>
+                                                    </choice>
+                                                    <element name="suspect" type="boolean" minOccurs="0"/>
+                                                </sequence>
+                                                <attribute name="measObjLdn"
+                                                           type="string" use="required"/>
+                                            </complexType>
+                                        </element>
+                                    </sequence>
+                                    <attribute name="measInfoId" type="string" use="optional"/>
+                                </complexType>
+                            </element>
+                        </sequence>
+                    </complexType>
+                </element>
+                <element name="fileFooter">
+                    <complexType>
+                        <sequence>
+                            <element name="measCollec">
+                                <complexType>
+                                    <attribute name="endTime" type="dateTime" use="required"/>
+                                </complexType>
+                            </element>
+                        </sequence>
+                    </complexType>
+                </element>
+            </sequence>
+        </complexType>
+    </element>
+
+    <!--
+      Removed the 'NIL' restriction.
+    -->
+
+    <simpleType name="measResultType">
+        <union memberTypes="float string">
+        </union>
+    </simpleType>
+
+</schema>
\ No newline at end of file
diff --git a/src/main/resources/templates/org.3GPP.28.550#measData b/src/main/resources/templates/org.3GPP.28.550#measData
new file mode 100644 (file)
index 0000000..653077e
--- /dev/null
@@ -0,0 +1,132 @@
+<#ftl>
+<#--
+  ============LICENSE_START=======================================================
+   Copyright (C) 2019-2020 Nordix Foundation.
+  ================================================================================
+  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.
+
+  SPDX-License-Identifier: Apache-2.0
+  ============LICENSE_END=========================================================
+ -->
+<#compress>
+<#assign fileHeader = xml.MeasDataFile.fileHeader>
+<#assign fileFooter = xml.MeasDataFile.fileFooter>
+<#assign measData = xml.MeasDataFile.measData>
+<#setting datetime_format="iso">
+{
+    "event": {
+        "commonEventHeader": <@commonEventHeader/>
+    <#if measData?has_content>,
+        "perf3gppFields": <@perf3gppFields/>
+        </#if>
+    }
+}
+
+
+<#macro commonEventHeader>
+{
+    "domain": "perf3gpp",
+    "eventId": "${eventId}",
+    "sequence": 0,
+    "eventName": "perf3gpp_${metadata.productName}-${metadata.vendorName}_pmMeasResult",
+    "sourceName": "${metadata.sourceName}",
+    "reportingEntityName": "",
+    "priority": "Normal",
+    "startEpochMicrosec": ${fileHeader.MeasData.@beginTime?datetime?long?c},
+    "lastEpochMicrosec": ${fileFooter.MeasData.@endTime?datetime?long?c},
+    "version": "4.0",
+    "vesEventListenerVersion": "7.1",
+    "timeZoneOffset": "${metadata.timeZoneOffset}"
+}
+</#macro>
+
+
+<#macro measTypes measInfo>
+{
+    "sMeasTypesList":[
+     <#if measInfo.measType?has_content>
+       <#list measInfo.measType as measType>
+       "${measType}"<#sep>,</#sep>
+       </#list>
+     <#else>
+       <#list measInfo.measTypes?split(" ") as measType>
+       "${measType}"<#sep>,</#sep>
+   </#list>
+ </#if>
+    ]
+}
+</#macro>
+
+
+<#macro measValuesList measInfo>
+[
+<#list measInfo.measValue as measValue>
+    {
+        "measObjInstId": "${measValue.@measObjLdn[0]!}",
+        "suspectFlag": "${measValue.suspect[0]! "false"}",
+        "measResults": [
+        <#if measValue.r?has_content>
+        <#list measValue.r as r>
+            {
+                "p": ${r.@p},
+                "sValue": "${r}"
+            }<#sep>,</#sep>
+        </#list>
+        <#else>
+        <#list measValue.measResults?split(" ") as r>
+            {
+                "p":${r?index+1},
+                "sValue": "${r}"
+            }<#sep>,</#sep>
+        </#list>
+        </#if>
+        ]
+   }
+<#sep>,</#sep>
+</#list>
+]
+</#macro>
+
+
+<#macro measInfoList>
+[
+<#list measData.measInfo as measInfo>
+    {
+        "measInfoId": {
+            "sMeasInfoId": "${measInfo.@measInfoId[0]!}"
+        },
+        "measTypes": <@measTypes measInfo/>,
+        "measValuesList": <@measValuesList measInfo/>
+    }<#sep>,</#sep>
+</#list>
+]
+</#macro>
+
+
+<#macro measDataCollection>
+{
+    "granularityPeriod": ${measData.measInfo.granPeriod.@endTime[0]!?datetime?long?c},
+    "measuredEntityUserName": "${measData.measuredEntity.@userLabel[0]!}",
+    "measuredEntityDn": "${measData.measuredEntity.@localDn[0]!}",
+    "measuredEntitySoftwareVersion": "${measData.measuredEntity.@swVersion[0]!}",
+    "measInfoList": <@measInfoList/>
+}
+</#macro>
+
+<#macro perf3gppFields>
+{
+    "perf3gppFieldsVersion": "1.0",
+    "measDataCollection": <@measDataCollection/>
+}
+</#macro>
+</#compress>
\ No newline at end of file
diff --git a/src/main/resources/templates/org.3GPP.32.435#measCollec b/src/main/resources/templates/org.3GPP.32.435#measCollec
new file mode 100644 (file)
index 0000000..422977e
--- /dev/null
@@ -0,0 +1,133 @@
+<#ftl>
+<#--
+  ============LICENSE_START=======================================================
+   Copyright (C) 2019-2020 Nordix Foundation.
+  ================================================================================
+  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.
+
+  SPDX-License-Identifier: Apache-2.0
+  ============LICENSE_END=========================================================
+ -->
+<#compress>
+<#assign fileHeader = xml.measCollecFile.fileHeader>
+<#assign fileFooter = xml.measCollecFile.fileFooter>
+<#assign measData = xml.measCollecFile.measData>
+<#setting datetime_format="iso">
+{
+    "event": {
+        "commonEventHeader": <@commonEventHeader/>
+    <#if measData?has_content>,
+        "perf3gppFields": <@perf3gppFields/>
+        </#if>
+    }
+}
+
+
+<#macro commonEventHeader>
+{
+    "domain": "perf3gpp",
+    "eventId": "${eventId}",
+    "sequence": 0,
+    "eventName": "perf3gpp_${metadata.productName}-${metadata.vendorName}_pmMeasResult",
+    "sourceName": "${metadata.sourceName}",
+    "reportingEntityName": "",
+    "priority": "Normal",
+    "startEpochMicrosec": ${fileHeader.measCollec.@beginTime?datetime?long?c},
+    "lastEpochMicrosec": ${fileFooter.measCollec.@endTime?datetime?long?c},
+    "version": "4.0",
+    "vesEventListenerVersion": "7.1",
+    "timeZoneOffset": "${metadata.timeZoneOffset}"
+}
+</#macro>
+
+
+<#macro measTypes measInfo>
+{
+    "sMeasTypesList":[
+     <#if measInfo.measType?has_content>
+       <#list measInfo.measType as measType>
+       "${measType}"<#sep>,</#sep>
+       </#list>
+     <#else>
+       <#list measInfo.measTypes?split(" ") as measType>
+       "${measType}"<#sep>,</#sep>
+   </#list>
+ </#if>
+    ]
+}
+</#macro>
+
+
+<#macro measValuesList measInfo>
+[
+<#list measInfo.measValue as measValue>
+    {
+        "measObjInstId": "${measValue.@measObjLdn[0]!}",
+        "suspectFlag": "${measValue.suspect[0]! "false"}",
+        "measResults": [
+        <#if measValue.r?has_content>
+        <#list measValue.r as r>
+            {
+                "p": ${r.@p},
+                "sValue": "${r}"
+            }<#sep>,</#sep>
+        </#list>
+        <#else>
+        <#list measValue.measResults?split(" ") as r>
+            {
+                "p":${r?index+1},
+                "sValue": "${r}"
+            }<#sep>,</#sep>
+        </#list>
+        </#if>
+        ]
+   }
+<#sep>,</#sep>
+</#list>
+]
+</#macro>
+
+
+<#macro measInfoList>
+[
+<#list measData.measInfo as measInfo>
+    {
+        "measInfoId": {
+            "sMeasInfoId": "${measInfo.@measInfoId[0]!}"
+        },
+        "measTypes": <@measTypes measInfo/>,
+        "measValuesList": <@measValuesList measInfo/>
+    }<#sep>,</#sep>
+</#list>
+]
+</#macro>
+
+
+<#macro measDataCollection>
+{
+    "granularityPeriod": ${measData.measInfo.granPeriod.@endTime[0]!?datetime?long?c},
+    "measuredEntityUserName": "${measData.managedElement.@userLabel[0]!}",
+    "measuredEntityDn": "${measData.managedElement.@localDn[0]!}",
+    "measuredEntitySoftwareVersion": "${measData.managedElement.@swVersion[0]!}",
+    "measInfoList": <@measInfoList/>
+}
+</#macro>
+
+
+<#macro perf3gppFields>
+{
+    "perf3gppFieldsVersion": "1.0",
+    "measDataCollection": <@measDataCollection/>
+}
+</#macro>
+</#compress>
\ No newline at end of file
index 46994b3..ce051e4 100644 (file)
@@ -1,6 +1,6 @@
 /*-
  * ============LICENSE_START=======================================================
- *  Copyright (C) 2019 Nordix Foundation.
+ *  Copyright (C) 2019-2020 Nordix Foundation.
  * ================================================================================
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -24,6 +24,7 @@ import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.mockito.Mockito.RETURNS_DEEP_STUBS;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
@@ -37,6 +38,7 @@ import java.nio.file.Files;
 import java.nio.file.Path;
 import java.nio.file.Paths;
 import java.util.Arrays;
+import java.util.HashMap;
 import java.util.List;
 
 import com.google.gson.Gson;
@@ -83,7 +85,7 @@ class AppTest {
     private static final Path dataDirectory = Paths.get("src/test/resources/mapper_test/mapping_data/");
     private static final Path metadata = Paths.get("src/test/resources/valid_metadata.json");
     private static final Path template = Paths.get("src/main/resources/mapping.ftl");
-    private static final Path schema = Paths.get("src/main/resources/measCollec_plusString.xsd");
+    private static final Path schema = Paths.get("src/main/resources/schemas/");
     private static final String config = "valid_mapper_config.json";
 
     private App objUnderTest;
@@ -153,8 +155,9 @@ class AppTest {
     }
 
     @Test
-    void testHandleBackPressure() {
-        Event event = utils.EventUtils.makeMockEvent("", mock(EventMetadata.class));
+    void testHandleBackPressure() throws Exception{
+        Event event = new Event(mock(HttpServerExchange.class, RETURNS_DEEP_STUBS),
+                "", mock(EventMetadata.class), new HashMap<>(), "");
         App.handleBackPressure(event);
         verify(event.getHttpServerExchange(), times(1)).setStatusCode(StatusCodes.TOO_MANY_REQUESTS);
         verify(event.getHttpServerExchange(), times(1)).unDispatch();
@@ -166,8 +169,9 @@ class AppTest {
     }
 
     @Test
-    void testReceiveRequest() {
-        Event event = utils.EventUtils.makeMockEvent("", mock(EventMetadata.class));
+    void testReceiveRequest() throws Exception {
+        Event event = new Event(mock(HttpServerExchange.class, RETURNS_DEEP_STUBS),
+                "", mock(EventMetadata.class), new HashMap<>(), "");
         App.receiveRequest(event);
         verify(event.getHttpServerExchange(), times(1)).setStatusCode(StatusCodes.OK);
         verify(event.getHttpServerExchange(), times(1)).unDispatch();
@@ -212,14 +216,14 @@ class AppTest {
     }
 
     @Test
-    void testValidateXML_success() throws IOException {
+    void testValidateXML_success() throws Exception {
         XMLValidator mockValidator = new XMLValidator(schema);
         MapperConfig mockConfig = Mockito.mock(MapperConfig.class);
 
-        String metadataFileContents = new String(Files.readAllBytes(metadata));
+        String metadataFileContents = new String(Files.readAllBytes(Paths.get(dataDirectory + "/32.435/meas_results/metadata.json")));
         eventMetadata = new Gson().fromJson(metadataFileContents, EventMetadata.class);
 
-        Path testFile = Paths.get(dataDirectory + "/valid_data/meas_results.xml");
+        Path testFile = Paths.get(dataDirectory + "/32.435/meas_results/test.xml");
         Event mockEvent = EventUtils.makeMockEvent(EventUtils.fileContentsToString(testFile), eventMetadata);
 
         boolean result = App.validate(mockValidator, mockEvent, mockConfig);
@@ -228,17 +232,16 @@ class AppTest {
     }
 
     @Test
-    void testValidateXML_failure() throws IOException {
+    void testValidateXML_failure() throws Exception {
         XMLValidator mockValidator = new XMLValidator(schema);
         MapperConfig mockConfig = Mockito.mock(MapperConfig.class);
 
         String metadataFileContents = new String(Files.readAllBytes(metadata));
         eventMetadata = new Gson().fromJson(metadataFileContents, EventMetadata.class);
-
-        Path testFile = Paths.get("src/test/resources/xml_validator_test/test_data/invalid/no_managed_element.xml");
-        Event mockEvent = EventUtils.makeMockEvent(EventUtils.fileContentsToString(testFile), eventMetadata);
-
-        boolean result = App.validate(mockValidator, mockEvent, mockConfig);
+        Path testFile = Paths.get("src/test/resources/xml_validator_test/test_data/lte/no_managed_element/test.xml");
+        Event event = new Event(mock(HttpServerExchange.class, RETURNS_DEEP_STUBS),
+                EventUtils.fileContentsToString(testFile), eventMetadata, new HashMap<>(), "");
+        boolean result = App.validate(mockValidator, event, mockConfig);
 
         assertFalse(result);
     }
index 34b71f4..5cd1634 100644 (file)
@@ -1,6 +1,6 @@
 /*-
  * ============LICENSE_START=======================================================
- *  Copyright (C) 2019 Nordix Foundation.
+ *  Copyright (C) 2019-2020 Nordix Foundation.
  * ================================================================================
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -26,78 +26,49 @@ import static org.junit.Assert.assertTrue;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
-import java.io.IOException;
 import java.nio.file.Path;
 import java.nio.file.Paths;
 import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.HashMap;
 import java.util.List;
-import java.util.stream.Collectors;
 
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.ExtendWith;
 import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
 import org.junit.jupiter.params.provider.MethodSource;
 import org.mockito.Mock;
 import org.mockito.junit.jupiter.MockitoExtension;
 import org.onap.dcaegen2.services.pmmapper.model.Event;
 import org.onap.dcaegen2.services.pmmapper.model.EventMetadata;
-import org.onap.dcaegen2.services.pmmapper.model.MeasCollecFile;
 import org.onap.dcaegen2.services.pmmapper.model.MeasFilterConfig;
 import org.onap.dcaegen2.services.pmmapper.model.MeasFilterConfig.Filter;
+import org.onap.dcaegen2.services.pmmapper.model.measurement.common.MeasurementFile;
 import org.onap.dcaegen2.services.pmmapper.utils.MeasConverter;
 
 import io.undertow.server.HttpServerExchange;
+import utils.ArgumentCreator;
 import utils.EventUtils;
 
 @ExtendWith(MockitoExtension.class)
 class MeasFilterHandlerTest {
 
+    private static final Path FILTER_DIRECTORY = Paths.get("src/test/resources/filter_test/");
     private static final String baseDir = "src/test/resources/filter_test/";
-    private static final Path dataDirectory = Paths.get("src/test/resources/mapper_test/mapping_data/");
     private static MeasConverter converter = new MeasConverter();
     private MeasFilterHandler objUnderTest;
     @Mock
     private HttpServerExchange exchange;
-    @Mock
-    private EventMetadata metaData;
 
     @BeforeEach
     void setup() {
         objUnderTest = new MeasFilterHandler(new MeasConverter());
     }
 
-    @Test
-    void measTypes_byCommaSeparation() throws IOException {
-        String inputPath = baseDir + "meas_results";
-        String expected = EventUtils.fileContentsToString(Paths.get(inputPath + "_filtered.xml"));
-        Event event = generateEvent(inputPath, generateValidFilter());
-
-        objUnderTest.filterByMeasType(event);
-
-        String actual = converter.convert(event.getMeasCollecFile());
-        assertEquals(expected, actual);
-    }
-
-    @Test
-    void measType_byID() throws IOException {
-        String inputPath = baseDir + "meas_type_and_r";
-        String filteredString = EventUtils.fileContentsToString(Paths.get(inputPath + "_filtered.xml"));
-        Event event = generateEvent(inputPath, generateValidFilter());
-        MeasCollecFile f = converter.convert(filteredString);
-        String expected = converter.convert(f);
-
-        objUnderTest.filterByMeasType(event);
-
-        String actual = converter.convert(event.getMeasCollecFile());
-        assertEquals(expected, actual);
-    }
-
     @Test
     void skip_mapping_when_no_Filters_match() {
-        String inputPath = baseDir + "meas_results";
+        String inputPath = baseDir + "lte/meas_results/test.xml";
         Filter noMatchFilter = new MeasFilterConfig().new Filter();
         noMatchFilter.setMeasTypes(Arrays.asList("nomatch1", "nomatch2"));
         Event event = generateEvent(inputPath, noMatchFilter);
@@ -111,7 +82,7 @@ class MeasFilterHandlerTest {
 
     @Test
     void remove_events_that_does_not_match_filter() {
-        String inputPath = baseDir + "meas_type_and_r_manyInfo";
+        String inputPath = baseDir + "lte/meas_type_and_r_manyinfo/test.xml";
 
         Filter matchFilter = new MeasFilterConfig().new Filter();
         matchFilter.setMeasTypes(Arrays.asList("a", "b"));
@@ -129,71 +100,29 @@ class MeasFilterHandlerTest {
 
     @Test
     void skip_mapping_when_MeasData_isEmpty() {
-        String inputPath = baseDir + "meas_results";
+        String inputPath = baseDir + "lte/meas_results/test.xml";
         Event event = generateEvent(inputPath, generateValidFilter());
-        event.getMeasCollecFile().replaceMeasData(Arrays.asList());
+        event.getMeasurement().replacementMeasurementData(Arrays.asList());
 
         assertFalse(objUnderTest.filterByMeasType(event));
     }
 
     @Test
     void skip_filtering_if_filter_or_meastypes_isEmpty() {
-        String inputPath = baseDir + "meas_results";
+        String inputPath = baseDir + "lte/meas_results/test.xml";
 
         Filter emptyMeastypesFilter = new MeasFilterConfig().new Filter();
         emptyMeastypesFilter.setMeasTypes(Arrays.asList());
 
         Event event = generateEvent(inputPath, emptyMeastypesFilter);
-        MeasCollecFile originalMeasCollec = event.getMeasCollecFile();
+        MeasurementFile originalMeasCollec = event.getMeasurement();
 
         assertTrue(objUnderTest.filterByMeasType(event));
-        assertEquals(originalMeasCollec,event.getMeasCollecFile());
+        assertEquals(originalMeasCollec,event.getMeasurement());
 
         event.setFilter(null);
         assertTrue(objUnderTest.filterByMeasType(event));
-        assertEquals(originalMeasCollec,event.getMeasCollecFile());
-    }
-
-    @Test
-    void multiple_measInfos_measResults() {
-        String inputPath = baseDir + "meas_results_manyInfo";
-        String filteredString = EventUtils.fileContentsToString(Paths.get(inputPath + "_filtered.xml"));
-        Event event = generateEvent(inputPath, generateValidFilter());
-
-        MeasCollecFile f = converter.convert(filteredString);
-        String expected = converter.convert(f);
-        objUnderTest.filterByMeasType(event);
-
-        String actual = converter.convert(event.getMeasCollecFile());
-        assertEquals(expected, actual);
-    }
-
-    @Test
-    void multiple_measInfos_measTypeAndR() {
-        String inputPath = baseDir + "meas_type_and_r_manyInfo";
-        String filteredString = EventUtils.fileContentsToString(Paths.get(inputPath + "_filtered.xml"));
-        Event event = generateEvent(inputPath, generateValidFilter());
-
-        MeasCollecFile f = converter.convert(filteredString);
-        String expected = converter.convert(f);
-        objUnderTest.filterByMeasType(event);
-
-        String actual = converter.convert(event.getMeasCollecFile());
-        assertEquals(expected, actual);
-    }
-
-    @Test
-    void multiple_measValues() {
-        String inputPath = baseDir + "meas_type_and_r_manyMeasvalue";
-        String filteredString = EventUtils.fileContentsToString(Paths.get(inputPath + "_filtered.xml"));
-        Event event = generateEvent(inputPath, generateValidFilter());
-
-        MeasCollecFile f = converter.convert(filteredString);
-        String expected = converter.convert(f);
-        objUnderTest.filterByMeasType(event);
-
-        String actual = converter.convert(event.getMeasCollecFile());
-        assertEquals(expected, actual);
+        assertEquals(originalMeasCollec,event.getMeasurement());
     }
 
     @Test
@@ -208,30 +137,34 @@ class MeasFilterHandlerTest {
     @Test
     void invalid_fileType() {
         Event event = mock(Event.class);
-        List<String> invalidFiletypes = Arrays.asList("Bpm.xml","Dpm.xml","Apm.xml.gz","Apm.xm1","asdf","bsdf");
+        List<String> invalidFileTypes = Arrays.asList("Bpm.xml","Dpm.xml","Apm.xml.gz","Apm.xm1","asdf","bsdf");
         when(event.getHttpServerExchange()).thenReturn(exchange);
-        when(exchange.getRequestPath())
-            .thenReturn(invalidFiletypes.toString());
-
-        invalidFiletypes.forEach(c -> assertFalse(objUnderTest.filterByFileType(event)));
+        invalidFileTypes.forEach(fileName -> {
+            when(exchange.getRequestPath())
+                    .thenReturn(fileName);
+            assertFalse(objUnderTest.filterByFileType(event));
+        });
     }
 
-
     @ParameterizedTest
-    @MethodSource("getValidMeas")
-    void applyFilterToValidMeasurements(Event testEvent) {
+    @MethodSource("getEvents")
+    void filter_valid_measurements(Event expectedEvent, Event testEvent) {
         objUnderTest.filterByMeasType(testEvent);
+        String actual = converter.convert(testEvent.getMeasurement());
+        String expected = converter.convert(expectedEvent.getMeasurement());
+        assertEquals(expected, actual);
+
     }
 
     private Event generateEvent(String inputPath, Filter filter) {
-        String inputXml = EventUtils.fileContentsToString(Paths.get(inputPath + ".xml"));
-        Event event = new Event(exchange, inputXml, metaData, new HashMap<>(), "");
-        event.setMeasCollecFile(converter.convert(inputXml));
+        EventMetadata metadata = new EventMetadata();
+        metadata.setFileFormatType(MeasConverter.LTE_FILE_TYPE);
+        Event event = EventUtils.makeMockEvent(EventUtils.fileContentsToString(Paths.get(inputPath)), metadata);
         event.setFilter(filter);
         return event;
     }
 
-    private Filter generateValidFilter() {
+    private static Filter generateValidFilter() {
         Filter filter;
         filter = new MeasFilterConfig().new Filter();
         filter.setDictionaryVersion("1.0");
@@ -239,17 +172,17 @@ class MeasFilterHandlerTest {
         return filter;
     }
 
-    static List<Event> getValidMeas() throws IOException {
-        final Path metadata = Paths.get("src/test/resources/valid_metadata.json");
-        List<Event> events = EventUtils
-                .eventsFromDirectory(Paths.get(dataDirectory.toString() + "/valid_data/"), metadata)
-                .stream()
-                .map(e -> {
-                    MeasCollecFile m = converter.convert(e.getBody());
-                    e.setMeasCollecFile(m);
-                    return e;
-                })
-                .collect(Collectors.toList());
-        return events;
+    private static List<Arguments> getEvents() {
+        ArgumentCreator creator = (Path path, EventMetadata metadata) -> {
+            Path expectedEventPath = Paths.get(path.toString()+"/expected.xml");
+            Path testEventPath = Paths.get(path.toString()+"/test.xml");
+            Event expectedEvent = EventUtils.makeMockEvent(EventUtils.fileContentsToString(expectedEventPath), metadata);
+            Event testEvent = EventUtils.makeMockEvent(EventUtils.fileContentsToString(testEventPath), metadata);
+            testEvent.setFilter(generateValidFilter());
+            return Arguments.of(expectedEvent, testEvent);
+        };
+        return EventUtils.generateEventArguments(FILTER_DIRECTORY, "/nr", creator);
+
     }
+
 }
index abe1b39..bf232ea 100644 (file)
@@ -1,6 +1,6 @@
 /*-
  * ============LICENSE_START=======================================================
- *  Copyright (C) 2019 Nordix Foundation.
+ *  Copyright (C) 2019-2020 Nordix Foundation.
  * ================================================================================
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
 
 package org.onap.dcaegen2.services.pmmapper.filtering;
 
+import com.google.gson.Gson;
+import io.undertow.server.HttpServerExchange;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.util.HashMap;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.extension.ExtendWith;
 import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
 import org.junit.jupiter.params.provider.MethodSource;
 import org.mockito.junit.jupiter.MockitoExtension;
 import org.onap.dcaegen2.services.pmmapper.model.Event;
+import org.onap.dcaegen2.services.pmmapper.model.EventMetadata;
 import org.onap.dcaegen2.services.pmmapper.model.MapperConfig;
 import org.powermock.core.classloader.annotations.PrepareForTest;
+import utils.ArgumentCreator;
 import utils.ConfigUtils;
 import utils.EventUtils;
 
-import java.io.IOException;
 import java.nio.file.Path;
 import java.nio.file.Paths;
 import java.util.List;
 
 import static org.junit.jupiter.api.Assertions.assertFalse;
 import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assertions.fail;
+import static org.mockito.Mockito.RETURNS_DEEP_STUBS;
+import static org.mockito.Mockito.mock;
 
 @ExtendWith(MockitoExtension.class)
 @PrepareForTest(MapperConfig.class)
@@ -56,7 +66,7 @@ public class MetadataFilterTest {
     private static MapperConfig multipleFilterConfig;
 
     @BeforeEach
-    void setup() throws Exception {
+    void setup() {
         validConfig = ConfigUtils.getMapperConfigFromFile(VALID_MAPPER_CONFIG_FILE);
         noFilterConfig = ConfigUtils.getMapperConfigFromFile(NO_FILTER_CONFIG_FILE);
         multipleFilterConfig = ConfigUtils.getMapperConfigFromFile(MULTIPLE_FILTER_CONFIG_FILE);
@@ -89,13 +99,30 @@ public class MetadataFilterTest {
         assertFalse(metadataFilter.filter(testEvent));
     }
 
-    private static List<Event> getEventsWithValidMetadata() throws IOException {
-        Path validDataDirectory = Paths.get(DATA_DIRECTORY.toString() + "/valid/");
-        return EventUtils.eventsFromDirectory(validDataDirectory, VALID_METADATA);
+    private static List<Arguments> getEventsWithValidMetadata() {
+        return getEvents(VALID_METADATA);
     }
 
-    private static List<Event> getEventsWithInvalidMetadata() throws IOException {
-        Path validDataDirectory = Paths.get(DATA_DIRECTORY.toString() + "/valid/");
-        return EventUtils.eventsFromDirectory(validDataDirectory, INCORRECT_METADATA);
+    private static List<Arguments> getEventsWithInvalidMetadata() {
+        return getEvents(INCORRECT_METADATA);
+    }
+
+    private static List<Arguments> getEvents(Path metadataFile) {
+        ArgumentCreator creator = (Path path, EventMetadata metadata) -> {
+            EventMetadata testMetadata = null;
+            try {
+                testMetadata = new Gson().fromJson(new String(Files.readAllBytes(metadataFile)), EventMetadata.class);
+            } catch (IOException e) {
+                fail("Failed to read contents of metadata file");
+            }
+            testMetadata.setFileFormatType(metadata.getFileFormatType());
+            Path testEventPath = Paths.get(path.toString()+"/test.xml");
+            Event testEvent = new Event(mock(
+                    HttpServerExchange.class, RETURNS_DEEP_STUBS),
+                    EventUtils.fileContentsToString(testEventPath), testMetadata, new HashMap<>(), "");
+
+            return Arguments.of(testEvent);
+        };
+        return EventUtils.generateEventArguments(DATA_DIRECTORY, "/nr", creator);
     }
 }
\ No newline at end of file
index f623d57..2356a57 100644 (file)
@@ -1,6 +1,6 @@
 /*-
  * ============LICENSE_START=======================================================
- *  Copyright (C) 2019 Nordix Foundation.
+ *  Copyright (C) 2019-2020 Nordix Foundation.
  * ================================================================================
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -20,8 +20,8 @@
 
 package org.onap.dcaegen2.services.pmmapper.mapping;
 
-import static org.junit.Assert.assertNotNull;
 import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.fail;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.Mockito.RETURNS_DEEP_STUBS;
 import static org.mockito.Mockito.doThrow;
@@ -37,6 +37,7 @@ import java.io.IOException;
 import java.nio.file.Files;
 import java.nio.file.Path;
 import java.nio.file.Paths;
+import java.util.HashMap;
 import java.util.List;
 
 import org.everit.json.schema.Schema;
@@ -47,28 +48,33 @@ import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.ExtendWith;
 import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
 import org.junit.jupiter.params.provider.MethodSource;
 import org.mockito.junit.jupiter.MockitoExtension;
 import org.onap.dcaegen2.services.pmmapper.exceptions.MappingException;
+import org.onap.dcaegen2.services.pmmapper.exceptions.TemplateIdentificationException;
 import org.onap.dcaegen2.services.pmmapper.model.Event;
 import org.onap.dcaegen2.services.pmmapper.model.EventMetadata;
-import org.onap.dcaegen2.services.pmmapper.model.MeasCollecFile;
 import org.onap.dcaegen2.services.pmmapper.utils.MeasConverter;
 import org.powermock.reflect.Whitebox;
+import utils.ArgumentCreator;
 import utils.EventUtils;
 
 
 @ExtendWith(MockitoExtension.class)
 class MapperTest {
 
-    private static EventMetadata eventMetadata;
+    private static EventMetadata fourthGenerationMetadata;
+    private static EventMetadata fifthGenerationMetadata;
     private static Schema vesSchema;
     private static MeasConverter converter;
     private Mapper objUnderTest;
 
     private static final Path schema = Paths.get("src/test/resources/mapper_test/CommonEventFormat_30.1-ONAP.json");
-    private static final Path metadata = Paths.get("src/test/resources/valid_metadata.json");
-    private static final Path mapping = Paths.get("src/main/resources/mapping.ftl");
+    private static final Path METADATA_DIRECTORY = Paths.get("src/test/resources/metadata/");
+    private static final Path FIFTH_GENERATION_METADATA = Paths.get(METADATA_DIRECTORY.toString()+"/valid_5g_metadata.json");
+    private static final Path FOURTH_GENERATION_METADATA = Paths.get(METADATA_DIRECTORY.toString()+"/valid_4g_metadata.json");
+    private static final Path TEMPLATES_DIRECTORY = Paths.get("src/main/resources/templates/");
     private static final Path dataDirectory = Paths.get("src/test/resources/mapper_test/mapping_data/");
 
 
@@ -77,40 +83,60 @@ class MapperTest {
         JSONObject ves = new JSONObject(new String(Files.readAllBytes(schema)));
         vesSchema = SchemaLoader.load(ves);
 
-        String metadataFileContents = new String(Files.readAllBytes(metadata));
-        eventMetadata = new Gson().fromJson(metadataFileContents, EventMetadata.class);
-        converter = mock(MeasConverter.class);
+        String fourthGenMetadataFileContents = new String(Files.readAllBytes(FOURTH_GENERATION_METADATA));
+        fourthGenerationMetadata = new Gson().fromJson(fourthGenMetadataFileContents, EventMetadata.class);
+        String fifthGenMetadataFileContents = new String(Files.readAllBytes(FIFTH_GENERATION_METADATA));
+        fifthGenerationMetadata =  new Gson().fromJson(fifthGenMetadataFileContents, EventMetadata.class);
+        converter = new MeasConverter();
     }
 
     @BeforeEach
     void setup() {
-        objUnderTest = new Mapper(mapping,converter);
+        objUnderTest = new Mapper(TEMPLATES_DIRECTORY, converter);
     }
 
     @ParameterizedTest
     @MethodSource("getValidEvents")
     void testValidEvent(Event testEvent) {
-        when(converter.convert(any(MeasCollecFile.class))).thenReturn(testEvent.getBody());
         vesSchema.validate(new JSONObject(objUnderTest.map(testEvent)));
     }
 
     @Test
-    void testFailureToProcess() throws IOException, TemplateException {
+    void testFailureToProcessLte() throws Exception {
         Template mappingTemplateMock = mock(Template.class, RETURNS_DEEP_STUBS);
         doThrow(new TemplateException(mock(Environment.class))).when(mappingTemplateMock)
                 .process(any(), any());
-        Whitebox.setInternalState(objUnderTest, "mappingTemplate", mappingTemplateMock);
-        Path testFile = Paths.get(dataDirectory + "/valid_data/no_measdata.xml");
-        Event testEvent = EventUtils.makeMockEvent(EventUtils.fileContentsToString(testFile), eventMetadata);
+        HashMap<String, Template> templates = new HashMap<>();
+        templates.put("org.3GPP.32.435#measCollec", mappingTemplateMock);
+        Whitebox.setInternalState(objUnderTest, "templates", templates);
+        Path testFile = Paths.get(dataDirectory + "/32.435/no_measdata/test.xml");
+        Event testEvent = EventUtils.makeMockEvent(EventUtils.fileContentsToString(testFile), fourthGenerationMetadata);
+        assertThrows(MappingException.class, () -> objUnderTest.map(testEvent));
+    }
+
+    @Test
+    void testFailureToProcessNr() throws Exception {
+        Template mappingTemplateMock = mock(Template.class, RETURNS_DEEP_STUBS);
+        doThrow(new TemplateException(mock(Environment.class))).when(mappingTemplateMock)
+                .process(any(), any());
+        HashMap<String, Template> templates = new HashMap<>();
+        templates.put("org.3GPP.28.550#measData", mappingTemplateMock);
+        Whitebox.setInternalState(objUnderTest, "templates", templates);
+        Path testFile = Paths.get(dataDirectory + "/28.550/no_measdata/test.xml");
+        Event testEvent = EventUtils.makeMockEvent(EventUtils.fileContentsToString(testFile), fifthGenerationMetadata);
+        assertThrows(MappingException.class, () -> objUnderTest.map(testEvent));
+    }
+
+    @Test
+    void testFailureToParseLte() {
         assertThrows(MappingException.class, () ->
-                objUnderTest.map(testEvent));
+                objUnderTest.map(EventUtils.makeMockEvent("not xml", fourthGenerationMetadata)));
     }
 
     @Test
-    void testFailureToParse() {
-        when(converter.convert(any(MeasCollecFile.class))).thenCallRealMethod();
+    void testFailureToParseNr() {
         assertThrows(MappingException.class, () ->
-                objUnderTest.map(EventUtils.makeMockEvent("not xml", eventMetadata)));
+                 objUnderTest.map(EventUtils.makeMockEvent("not xml", fifthGenerationMetadata)));
     }
 
     @Test
@@ -118,6 +144,19 @@ class MapperTest {
         assertThrows(IllegalArgumentException.class, () -> new Mapper(Paths.get("not a path"),converter));
     }
 
+    @Test
+    void testInvalidTemplateDirectory() {
+        assertThrows(IllegalArgumentException.class, () -> new Mapper(Paths.get("fake dir"), new MeasConverter()));
+    }
+    @Test
+    void testTemplateNotFound() {
+        EventMetadata testMetadata = mock(EventMetadata.class);
+        when(testMetadata.getFileFormatType()).thenReturn(MeasConverter.LTE_FILE_TYPE, "InvalidFormat");
+        Path testFile = Paths.get(dataDirectory + "/32.435/no_measdata/test.xml");
+        Event testEvent = EventUtils.makeMockEvent(EventUtils.fileContentsToString(testFile), testMetadata);
+        assertThrows(TemplateIdentificationException.class, () -> objUnderTest.map(testEvent));
+    }
+
     @Test
     void testNullPath() {
         assertThrows(NullPointerException.class, () -> new Mapper(null,converter));
@@ -133,22 +172,20 @@ class MapperTest {
         assertThrows(NullPointerException.class, () -> objUnderTest.map(mock(Event.class)));
     }
 
-    @Test
-    void testMapEvents() throws IOException {
-        List<Event> events = getValidEvents();
-        List<Event> expectedEvents = objUnderTest.mapEvents(events);
-        expectedEvents.forEach(event -> {
-            when(converter.convert(any(MeasCollecFile.class))).thenReturn(event.getBody());
-            assertNotNull(event.getVes());
-        });
-    }
-
-    static List<Event> getValidEvents() throws IOException {
-        return EventUtils.eventsFromDirectory(Paths.get(dataDirectory.toString() + "/valid_data/"), metadata);
-    }
-
-    static List<Event> getInvalidEvents() throws IOException {
-        return EventUtils.eventsFromDirectory(Paths.get(dataDirectory.toString() + "/invalid_data/"), metadata);
+    static List<Arguments> getValidEvents() {
+        ArgumentCreator creator = (Path path, EventMetadata metadata) -> {
+            Path testEventPath = Paths.get(path.toString()+"/test.xml");
+            Path metadataPath = Paths.get(path.toString()+"/metadata.json");
+            EventMetadata eventMetadata = null;
+            try {
+                eventMetadata = new Gson().fromJson(new String(Files.readAllBytes(metadataPath)), EventMetadata.class);
+            } catch (IOException e) {
+                fail("Failed to read contents of Metadata");
+            }
+            Event testEvent = EventUtils.makeMockEvent(EventUtils.fileContentsToString(testEventPath), eventMetadata);
+            return Arguments.of(testEvent);
+        };
+        return EventUtils.generateEventArguments(dataDirectory, "/28.550", creator);
     }
 }
 
index b2e6308..c308840 100644 (file)
@@ -28,6 +28,7 @@ import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
+import io.undertow.server.HttpServerExchange;
 import java.io.ByteArrayInputStream;
 import java.net.HttpURLConnection;
 import java.net.URL;
@@ -38,6 +39,7 @@ import java.nio.file.Paths;
 import com.google.gson.Gson;
 import com.google.gson.JsonObject;
 import com.google.gson.JsonParser;
+import java.util.HashMap;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.onap.dcaegen2.services.pmmapper.exceptions.ProcessEventException;
@@ -162,14 +164,16 @@ public class DataRouterUtilsTest {
         URL mockURL = mock(URL.class);
         HttpsURLConnection mockConnection = mock(HttpsURLConnection.class, RETURNS_DEEP_STUBS);
         when(mockConnection.getResponseCode()).thenReturn(503);
-
+        EventMetadata metadata = new EventMetadata();
+        metadata.setFileFormatType(MeasConverter.LTE_FILE_TYPE);
         when(mockURL.openConnection()).thenReturn(mockConnection);
         when(mockURL.getProtocol()).thenReturn("https");
         when(mockMapperConfig.getDmaapDRDeleteEndpoint()).thenReturn("dmaap-dr-node/delete/");
         when(mockMapperConfig.getSubscriberIdentity()).thenReturn("12");
 
         PowerMockito.whenNew(URL.class).withAnyArguments().thenReturn(mockURL);
-        Event testEvent = EventUtils.makeMockEvent("", mock(EventMetadata.class));
+        Event testEvent = new Event(mock(
+                HttpServerExchange.class, RETURNS_DEEP_STUBS), "", metadata, new HashMap<>(), "12");
         assertThrows(ProcessEventException.class, () -> DataRouterUtils.processEvent(mockMapperConfig, testEvent));
     }
 }
index f51ec5c..c3412eb 100644 (file)
@@ -1,6 +1,6 @@
 /*-\r
  * ============LICENSE_START=======================================================\r
- *  Copyright (C) 2019 Nordix Foundation.\r
+ *  Copyright (C) 2019-2020 Nordix Foundation.\r
  * ================================================================================\r
  * Licensed under the Apache License, Version 2.0 (the "License");\r
  * you may not use this file except in compliance with the License.\r
  */\r
 package org.onap.dcaegen2.services.pmmapper.utils;\r
 import static org.junit.jupiter.api.Assertions.assertThrows;\r
+import static org.mockito.Mockito.RETURNS_DEEP_STUBS;\r
+import static org.mockito.Mockito.mock;\r
 \r
-import java.io.StringReader;\r
+import io.undertow.server.HttpServerExchange;\r
 import java.io.StringWriter;\r
 \r
+import java.util.HashMap;\r
 import javax.xml.bind.JAXBContext;\r
 import javax.xml.bind.JAXBException;\r
 import javax.xml.bind.Marshaller;\r
-import javax.xml.bind.Unmarshaller;\r
 \r
 import org.junit.Before;\r
 import org.junit.Test;\r
 import org.junit.runner.RunWith;\r
 import org.mockito.Mockito;\r
 import org.onap.dcaegen2.services.pmmapper.exceptions.MappingException;\r
-import org.onap.dcaegen2.services.pmmapper.model.MeasCollecFile;\r
+import org.onap.dcaegen2.services.pmmapper.model.Event;\r
+import org.onap.dcaegen2.services.pmmapper.model.EventMetadata;\r
+import org.onap.dcaegen2.services.pmmapper.model.measurement.lte.MeasCollecFile;\r
 import org.powermock.api.mockito.PowerMockito;\r
 import org.powermock.core.classloader.annotations.PrepareForTest;\r
 import org.powermock.modules.junit4.PowerMockRunner;\r
@@ -68,16 +72,23 @@ public class MeasConverterTest {
     }\r
 \r
     @Test\r
-    public void convertToMeasCollec_throws_mappingException() throws JAXBException {\r
-        PowerMockito.mockStatic(JAXBContext.class);\r
-        Unmarshaller unmarshallerMock = PowerMockito.mock(Unmarshaller.class);\r
-        JAXBContext jaxbContext = PowerMockito.mock(JAXBContext.class);\r
-        PowerMockito.when(JAXBContext.newInstance(MeasCollecFile.class)).thenReturn(jaxbContext);\r
-        PowerMockito.when(jaxbContext.createUnmarshaller()).thenReturn(unmarshallerMock);\r
-        PowerMockito.when(unmarshallerMock.unmarshal(Mockito.any(StringReader.class))).thenThrow(JAXBException.class);\r
+    public void convertToMeasCollec_throws_mappingException() {\r
+        EventMetadata metadata = new EventMetadata();\r
+        metadata.setFileFormatType(MeasConverter.LTE_FILE_TYPE);\r
+        Event event = new Event(mock(HttpServerExchange.class, RETURNS_DEEP_STUBS), "xmlString", metadata, new HashMap<>(), "");\r
+        assertThrows(MappingException.class, () -> {\r
+            objUnderTest.convert(event);\r
+        });\r
+    }\r
 \r
+    @Test\r
+    public void convertToMeasData_throws_mappingException() {\r
+        EventMetadata metadata = new EventMetadata();\r
+        metadata.setFileFormatType(MeasConverter.NR_FILE_TYPE);\r
+        Event event = new Event(mock(HttpServerExchange.class, RETURNS_DEEP_STUBS), "xmlString", metadata, new HashMap<>(), "");\r
         assertThrows(MappingException.class, () -> {\r
-            objUnderTest.convert("xmlString");\r
+            objUnderTest.convert(event);\r
         });\r
     }\r
-}\r
+\r
+}
\ No newline at end of file
index 5028464..82921e6 100644 (file)
@@ -1,6 +1,6 @@
 /*-\r
  * ============LICENSE_START=======================================================\r
- *  Copyright (C) 2019 Nordix Foundation.\r
+ *  Copyright (C) 2019-2020 Nordix Foundation.\r
  * ================================================================================\r
  * Licensed under the Apache License, Version 2.0 (the "License");\r
  * you may not use this file except in compliance with the License.\r
  * ============LICENSE_END=========================================================\r
  */\r
 package org.onap.dcaegen2.services.pmmapper.utils;\r
+import static junit.framework.TestCase.fail;\r
 import static org.junit.Assert.assertEquals;\r
+import static org.junit.jupiter.api.Assertions.assertThrows;\r
 \r
+import java.io.FileInputStream;\r
+import java.io.IOException;\r
+import java.nio.file.Path;\r
 import java.nio.file.Paths;\r
-import java.util.HashMap;\r
 import java.util.List;\r
 import java.util.NoSuchElementException;\r
 \r
-import javax.xml.bind.JAXBException;\r
+import java.util.Properties;\r
 \r
-import org.junit.jupiter.api.Assertions;\r
 import org.junit.jupiter.api.BeforeEach;\r
 import org.junit.jupiter.api.Test;\r
 import org.junit.jupiter.api.extension.ExtendWith;\r
-import org.mockito.Mock;\r
+import org.junit.jupiter.params.ParameterizedTest;\r
+import org.junit.jupiter.params.provider.Arguments;\r
+import org.junit.jupiter.params.provider.MethodSource;\r
+\r
 import org.mockito.Mockito;\r
 import org.mockito.junit.jupiter.MockitoExtension;\r
 import org.onap.dcaegen2.services.pmmapper.model.Event;\r
 import org.onap.dcaegen2.services.pmmapper.model.EventMetadata;\r
-import org.onap.dcaegen2.services.pmmapper.model.MapperConfig;\r
-import org.onap.dcaegen2.services.pmmapper.model.MeasCollecFile;\r
 \r
-import io.undertow.server.HttpServerExchange;\r
+import utils.ArgumentCreator;\r
 import utils.EventUtils;\r
 \r
 @ExtendWith(MockitoExtension.class)\r
 class MeasSplitterTest {\r
     private static final String baseDir = "src/test/resources/split_test/";\r
     private MeasSplitter objUnderTest;\r
-    private MeasConverter converter;\r
-    @Mock\r
-    HttpServerExchange exchange;\r
-    @Mock\r
-    EventMetadata meta;\r
-    @Mock\r
-    Event event;\r
-    @Mock\r
-    MapperConfig config;\r
 \r
     @BeforeEach\r
     void setup() {\r
-        converter =  new MeasConverter();\r
-        objUnderTest = new MeasSplitter(converter);\r
-    }\r
-\r
-    void setupBaseEvent() {\r
-        Mockito.when(event.getHttpServerExchange()).thenReturn(exchange);\r
-        Mockito.when(event.getMetadata()).thenReturn(meta);\r
-        Mockito.when(event.getMdc()).thenReturn(new HashMap<>());\r
-        Mockito.when(event.getMetadata()).thenReturn(meta);\r
-        Mockito.when(event.getPublishIdentity()).thenReturn("");\r
+        objUnderTest = new MeasSplitter(new MeasConverter());\r
     }\r
 \r
-\r
     @Test\r
     void no_measData() {\r
         String inputPath = baseDir + "no_measdata";\r
+        EventMetadata metadata = new EventMetadata();\r
+        metadata.setFileFormatType(MeasConverter.LTE_FILE_TYPE);\r
         String inputXml = EventUtils.fileContentsToString(Paths.get(inputPath + ".xml"));\r
-        Mockito.when(event.getBody()).thenReturn(inputXml);\r
+        Event testEvent = EventUtils.makeMockEvent(inputXml, metadata);\r
 \r
-        Assertions.assertThrows(NoSuchElementException.class, () -> objUnderTest.split(event));\r
+        assertThrows(NoSuchElementException.class, () -> objUnderTest.split(testEvent));\r
     }\r
 \r
-    @Test\r
-    void typeA_returns_only_one_event() throws JAXBException {\r
-        String inputPath = baseDir + "meas_results_typeA";\r
-        String inputXml = EventUtils.fileContentsToString(Paths.get(inputPath + ".xml"));\r
-        MeasCollecFile measToBeSplit = converter.convert(inputXml);\r
-        setupBaseEvent();\r
-        Mockito.when(event.getBody()).thenReturn(inputXml);\r
-        Mockito.when(event.getMeasCollecFile()).thenReturn(measToBeSplit);\r
-\r
-        List<Event> splitEvents = objUnderTest.split(event);\r
 \r
-        assertEquals(1,splitEvents.size());\r
+    @ParameterizedTest\r
+    @MethodSource("getEvents")\r
+    void testSplit(int numberOfEvents, String[] measInfoIds, Event testEvent) {\r
+        List<Event> splitEvents = objUnderTest.split(testEvent);\r
+        assertEquals(numberOfEvents, splitEvents.size());\r
+        for (int i = 0; i<splitEvents.size(); i++) {\r
+            String measInfoId = splitEvents.get(i).getMeasurement()\r
+                                        .getMeasurementData().get().get(0).getMeasurementInfo().get(0).getMeasInfoId();\r
+            assertEquals(measInfoIds[i], measInfoId);\r
+        }\r
     }\r
 \r
-    @Test\r
-    void typeC_returns_multiple_events() throws JAXBException {\r
-        String inputPath = baseDir + "meas_results_typeC";\r
-        String inputXml = EventUtils.fileContentsToString(Paths.get(inputPath + ".xml"));\r
-        setupBaseEvent();\r
-        Mockito.when(event.getBody()).thenReturn(inputXml);\r
-        MeasCollecFile measToBeSplit = converter.convert(inputXml);\r
-        Mockito.when(event.getMeasCollecFile()).thenReturn(measToBeSplit);\r
-\r
-        List<Event> splitEvents = objUnderTest.split(event);\r
 \r
-        assertEquals(3,splitEvents.size());\r
-        for (int i = 0; i < splitEvents.size(); i++) {\r
-          String measInfoId = splitEvents.get(i).getMeasCollecFile()\r
-                  .getMeasData().get(0).getMeasInfo().get(0).getMeasInfoId();\r
-            Assertions.assertEquals(measInfoId, "measInfoId" + (i + 1));\r
-        }\r
+    private static List<Arguments> getEvents() {\r
+        ArgumentCreator splitterCreator = (Path path, EventMetadata metadata) -> {\r
+            Path propsPath = Paths.get(path.toString()+"/split.props");\r
+            Path testEventPath = Paths.get(path.toString()+"/test.xml");\r
+            Properties splitProperties = new Properties();\r
+            try {\r
+                splitProperties.load(new FileInputStream(propsPath.toFile()));\r
+            } catch (IOException e) {\r
+                fail("Failed to load properties for test");\r
+            }\r
+            int numberOfEvents = Integer.parseInt(splitProperties.getProperty("eventCount"));\r
+            String [] measInfoIds = splitProperties.getProperty("measInfoIds").split(",");\r
+            Event testEvent = EventUtils.makeMockEvent(EventUtils.fileContentsToString(testEventPath), metadata);\r
+            return Arguments.of(numberOfEvents, measInfoIds, testEvent);\r
+        };\r
+        return EventUtils.generateEventArguments(Paths.get(baseDir), "/nr", splitterCreator);\r
     }\r
 }\r
index aca0fe6..cc39563 100644 (file)
@@ -1,6 +1,6 @@
 /*-
  * ============LICENSE_START=======================================================
- *  Copyright (C) 2019 Nordix Foundation.
+ *  Copyright (C) 2019 - 2020 Nordix Foundation.
  * ================================================================================
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
 
 package org.onap.dcaegen2.services.pmmapper.utils;
 
-import static org.junit.jupiter.api.Assertions.assertFalse;
+import static junit.framework.TestCase.fail;
+import static org.junit.Assert.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertThrows;
-import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.mockito.Mockito.RETURNS_DEEP_STUBS;
+import static org.mockito.Mockito.mock;
 
+import io.undertow.server.HttpServerExchange;
+import java.io.FileInputStream;
 import java.io.IOException;
 import java.nio.file.Path;
 import java.nio.file.Paths;
+import java.util.HashMap;
 import java.util.List;
 
+import java.util.Properties;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.ExtendWith;
 import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
 import org.junit.jupiter.params.provider.MethodSource;
 import org.mockito.junit.jupiter.MockitoExtension;
 import org.onap.dcaegen2.services.pmmapper.model.Event;
+import org.onap.dcaegen2.services.pmmapper.model.EventMetadata;
+import utils.ArgumentCreator;
 import utils.EventUtils;
 
 
 @ExtendWith(MockitoExtension.class)
 class XMLValidatorTest {
-    private static final Path metadata = Paths.get("src/test/resources/valid_metadata.json");
     private static final Path dataDirectory = Paths.get("src/test/resources/xml_validator_test/test_data/");
-    private static final Path xsd = Paths.get("src/main/resources/measCollec_plusString.xsd");
+    private static final Path schemas = Paths.get("src/main/resources/schemas/");
     private XMLValidator objUnderTest;
 
     @BeforeEach
     void setup() {
-        objUnderTest = new XMLValidator(xsd);
+        objUnderTest = new XMLValidator(schemas);
     }
 
     @Test
@@ -62,26 +70,38 @@ class XMLValidatorTest {
         assertThrows(NullPointerException.class, () -> objUnderTest.validate(null));
     }
 
-    @ParameterizedTest
-    @MethodSource("getValidEvents")
-    void testValidEventsPass(Event testEvent) {
-        assertTrue(objUnderTest.validate(testEvent));
+    @Test
+    void testInvalidSchemaDirectory() {
+        assertThrows(IllegalArgumentException.class, () -> new XMLValidator(Paths.get("fake dir")));
     }
 
-    @ParameterizedTest
-    @MethodSource("getInvalidEvents")
-    void testInvalidEventsFail(Event testEvent) {
-        assertFalse(objUnderTest.validate(testEvent));
+    @Test
+    void testInvalidSchemaFormat() {
+        assertThrows(IllegalArgumentException.class, () -> new XMLValidator(Paths.get("src/test/resources/invalid_configs")));
     }
 
-    private static List<Event> getValidEvents() throws IOException {
-        Path validDataDirectory = Paths.get(dataDirectory.toString() + "/valid/");
-        return EventUtils.eventsFromDirectory(validDataDirectory, metadata);
+    @ParameterizedTest
+    @MethodSource("getEvents")
+    void testXmlValidation(boolean validity, Event testEvent) {
+        assertEquals(validity, objUnderTest.validate(testEvent));
     }
 
-    private static List<Event> getInvalidEvents() throws IOException {
-        Path invalidDataDirectory = Paths.get(dataDirectory.toString() + "/invalid/");
-        return EventUtils.eventsFromDirectory(invalidDataDirectory, metadata);
+    private static List<Arguments> getEvents() {
+        ArgumentCreator creator = (Path path, EventMetadata metadata) -> {
+            Path props = Paths.get(path.toString()+"/validity.props");
+            Path testEventPath = Paths.get(path.toString()+"/test.xml");
+            Properties validityProps = new Properties();
+            try {
+                validityProps.load(new FileInputStream(props.toFile()));
+            } catch (IOException e) {
+                fail("Failed to load properties for test");
+            }
+            boolean valid = Boolean.parseBoolean(validityProps.getProperty("valid"));
+            Event testEvent = new Event(mock(
+                    HttpServerExchange.class, RETURNS_DEEP_STUBS),
+                    EventUtils.fileContentsToString(testEventPath), metadata, new HashMap<>(), "");
+            return Arguments.of(valid, testEvent);
+        };
+        return EventUtils.generateEventArguments(dataDirectory, "/nr", creator);
     }
-
 }
diff --git a/src/test/java/utils/ArgumentCreator.java b/src/test/java/utils/ArgumentCreator.java
new file mode 100644 (file)
index 0000000..a552a0c
--- /dev/null
@@ -0,0 +1,36 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2019 - 2020 Nordix Foundation.
+ * ================================================================================
+ * 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.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package utils;
+
+import java.nio.file.Path;
+import org.junit.jupiter.params.provider.Arguments;
+import org.onap.dcaegen2.services.pmmapper.model.EventMetadata;
+
+public interface ArgumentCreator {
+
+    /**
+     * Makes an Argument containing an event from an path to an XML body and a corresponding metadata object.
+     * @param path path to file containing xml.
+     * @param metadata instance of a metadata object with fileFormatType set.
+     * @return Arguments containing what is necessary for a test to complete its checks.
+     */
+    public Arguments makeArgument(Path path, EventMetadata metadata);
+}
index 0051629..ffa02b0 100644 (file)
@@ -1,6 +1,6 @@
 /*-
  * ============LICENSE_START=======================================================
- *  Copyright (C) 2019 Nordix Foundation.
+ *  Copyright (C) 2019-2020 Nordix Foundation.
  * ================================================================================
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -29,13 +29,17 @@ import io.undertow.server.HttpServerExchange;
 import java.io.IOException;
 import java.nio.file.Files;
 import java.nio.file.Path;
+import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 import java.util.stream.Collectors;
 
+import java.util.stream.Stream;
+import junit.framework.TestCase;
+import org.junit.jupiter.params.provider.Arguments;
 import org.onap.dcaegen2.services.pmmapper.model.Event;
 import org.onap.dcaegen2.services.pmmapper.model.EventMetadata;
-import org.onap.dcaegen2.services.pmmapper.model.MeasCollecFile;
+import org.onap.dcaegen2.services.pmmapper.utils.MeasConverter;
 
 public class EventUtils {
 
@@ -55,6 +59,27 @@ public class EventUtils {
                        .map(contents -> EventUtils.makeMockEvent(contents, eventMetadata))
                        .collect(Collectors.toList());
     }
+    /**
+     * Create a List of Arguments containing an Event (Defaults to LTE events), and an expected outcome.
+     * Fails test in the event of failure to read a file.
+     * @param baseDirectory Directory containing multiple formats of events separated by a directory.
+     * @param nrQualifier String representing a unique part of the path that will exist only in the NR path.
+     * @param argCreator Callback to method that will generate the appropriate set of arguments for each test.
+     */
+    public static List<Arguments> generateEventArguments(Path baseDirectory, String nrQualifier, ArgumentCreator argCreator ) {
+        List<Arguments> events = new ArrayList<>();
+        try (Stream<Path> paths = Files.list(baseDirectory)) {
+            paths.filter(Files::isDirectory).forEach(path -> {
+                String fileFormatType = path.toString().contains(nrQualifier) ? MeasConverter.NR_FILE_TYPE : MeasConverter.LTE_FILE_TYPE;
+                EventMetadata eventMetadata = new EventMetadata();
+                eventMetadata.setFileFormatType(fileFormatType);
+                events.addAll(getEventsArgument(path, eventMetadata, argCreator));
+            });
+        } catch (IOException e) {
+            TestCase.fail("IOException occurred while generating test data");
+        }
+        return events;
+    }
 
     /**
      * reads contents of file into a string.
@@ -75,15 +100,14 @@ public class EventUtils {
      * Makes an event with a mock http server exchange, empty mdc and publish identity
      * @param body body for the event.
      * @param eventMetadata metadata for the event.
-     * @return event with mock HttpServerExchange
+     * @return event with mock HttpServerExchange.
      */
     public static Event makeMockEvent(String body, EventMetadata eventMetadata) {
         Event event = new Event(mock(HttpServerExchange.class, RETURNS_DEEP_STUBS), body, eventMetadata, new HashMap<>(), "");
-        event.setMeasCollecFile(new MeasCollecFile());
+        event.setMeasurement(new MeasConverter().convert(event));
         return event;
     }
 
-
     /**
      * Makes an event with a mock http server exchange and empty mdc
      * @param body body for the event.
@@ -95,5 +119,16 @@ public class EventUtils {
         return new Event(mockHttpServerExchange, body, eventMetadata, new HashMap<>(), publishIdentity);
     }
 
+    private static List<Arguments> getEventsArgument(Path basePath, EventMetadata metadata, ArgumentCreator argCreator) {
+        List<Arguments> events = new ArrayList<>();
+        try (Stream<Path> paths = Files.list(basePath)) {
+            paths.filter(Files::isDirectory).forEach(path->{
+                events.add(argCreator.makeArgument(path, metadata));
+            });
+        } catch (IOException e) {
+            TestCase.fail("IOException occurred while generating test data");
+        }
+        return events;
+    }
 
 }
diff --git a/src/test/resources/filter_test/nr/meas_results/expected.xml b/src/test/resources/filter_test/nr/meas_results/expected.xml
new file mode 100644 (file)
index 0000000..834b54a
--- /dev/null
@@ -0,0 +1,22 @@
+<MeasDataFile xmlns="http://www.3gpp.org/ftp/specs/archive/28_series/28.550#measData">
+    <fileHeader fileFormatVersion="32.435 V10.0" vendorName="FooBar Ltd" dnPrefix="some dnPrefix">
+        <fileSender senderName="Dublin"/>
+        <MeasData beginTime="2018-10-02T12:00:00+01:00"/>
+    </fileHeader>
+    <measData>
+        <measuredEntity localDn="Dublin" swVersion="r0.1"/>
+        <measInfo measInfoId="some measInfoId">
+            <job jobId="jobId"/>
+            <granPeriod duration="PT900S" endTime="2018-10-02T12:15:00Z"/>
+            <repPeriod duration="PT900S"/>
+            <measTypes>a b</measTypes>
+            <measValue measObjLdn="objLdn">
+                <measResults>1 2</measResults>
+                <suspect>false</suspect>
+            </measValue>
+        </measInfo>
+    </measData>
+    <fileFooter>
+        <MeasData endTime="2018-10-02T12:15:00+01:00"/>
+    </fileFooter>
+</MeasDataFile>
\ No newline at end of file
diff --git a/src/test/resources/filter_test/nr/meas_results/test.xml b/src/test/resources/filter_test/nr/meas_results/test.xml
new file mode 100644 (file)
index 0000000..0b84ff6
--- /dev/null
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<MeasDataFile xmlns="http://www.3gpp.org/ftp/specs/archive/28_series/28.550#measData">
+    <fileHeader dnPrefix="some dnPrefix" vendorName="FooBar Ltd"
+                fileFormatVersion="32.435 V10.0">
+        <fileSender senderName="Dublin"/>
+        <MeasData beginTime="2018-10-02T12:00:00+01:00"/>
+    </fileHeader>
+    <measData>
+        <measuredEntity swVersion="r0.1" localDn="Dublin"/>
+        <measInfo measInfoId="some measInfoId">
+            <job jobId="jobId"/>
+            <granPeriod endTime="2018-10-02T12:15:00Z" duration="PT900S"/>
+            <repPeriod duration="PT900S"/>
+            <measTypes>z a zz b</measTypes>
+            <measValue measObjLdn="objLdn">
+                <measResults>99 1 27 2</measResults>
+                <suspect>false</suspect>
+            </measValue>
+        </measInfo>
+    </measData>
+    <fileFooter>
+        <MeasData endTime="2018-10-02T12:15:00+01:00"/>
+    </fileFooter>
+</MeasDataFile>
diff --git a/src/test/resources/filter_test/nr/meas_results_manyinfo/expected.xml b/src/test/resources/filter_test/nr/meas_results_manyinfo/expected.xml
new file mode 100644 (file)
index 0000000..1f9cfbf
--- /dev/null
@@ -0,0 +1,32 @@
+<MeasDataFile xmlns="http://www.3gpp.org/ftp/specs/archive/28_series/28.550#measData">
+    <fileHeader fileFormatVersion="32.435 V10.0" vendorName="FooBar Ltd" dnPrefix="some dnPrefix">
+        <fileSender senderName="Dublin"/>
+        <MeasData beginTime="2018-10-02T12:00:00+01:00"/>
+    </fileHeader>
+    <measData>
+        <measuredEntity localDn="Dublin" swVersion="r0.1"/>
+        <measInfo measInfoId="some measInfoId">
+            <job jobId="jobId"/>
+            <granPeriod duration="PT900S" endTime="2018-10-02T12:15:00Z"/>
+            <repPeriod duration="PT900S"/>
+            <measTypes>a b</measTypes>
+            <measValue measObjLdn="objLdn">
+                <measResults>1 2</measResults>
+                <suspect>false</suspect>
+            </measValue>
+        </measInfo>
+        <measInfo measInfoId="some measInfoId2">
+            <job jobId="jobId"/>
+            <granPeriod duration="PT900S" endTime="2018-10-02T12:15:00Z"/>
+            <repPeriod duration="PT900S"/>
+            <measTypes>a b</measTypes>
+            <measValue measObjLdn="objLdn">
+                <measResults>1 2</measResults>
+                <suspect>false</suspect>
+            </measValue>
+        </measInfo>
+    </measData>
+    <fileFooter>
+        <MeasData endTime="2018-10-02T12:15:00+01:00"/>
+    </fileFooter>
+</MeasDataFile>
\ No newline at end of file
diff --git a/src/test/resources/filter_test/nr/meas_results_manyinfo/test.xml b/src/test/resources/filter_test/nr/meas_results_manyinfo/test.xml
new file mode 100644 (file)
index 0000000..217d339
--- /dev/null
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<MeasDataFile xmlns="http://www.3gpp.org/ftp/specs/archive/28_series/28.550#measData">
+    <fileHeader dnPrefix="some dnPrefix" vendorName="FooBar Ltd"
+                fileFormatVersion="32.435 V10.0">
+        <fileSender senderName="Dublin"/>
+        <MeasData beginTime="2018-10-02T12:00:00+01:00"/>
+    </fileHeader>
+    <measData>
+        <measuredEntity swVersion="r0.1" localDn="Dublin"/>
+        <measInfo measInfoId="this will be filtered out">
+            <job jobId="jobId"/>
+            <granPeriod endTime="2018-10-02T12:15:00Z" duration="PT900S"/>
+            <repPeriod duration="PT900S"/>
+            <measTypes>z aa zz bb</measTypes>
+            <measValue measObjLdn="objLdn">
+                <measResults>99 1 27 2</measResults>
+                <suspect>false</suspect>
+            </measValue>
+        </measInfo>
+        <measInfo measInfoId="some measInfoId">
+            <job jobId="jobId"/>
+            <granPeriod endTime="2018-10-02T12:15:00Z" duration="PT900S"/>
+            <repPeriod duration="PT900S"/>
+            <measTypes>z a zz b</measTypes>
+            <measValue measObjLdn="objLdn">
+                <measResults>99 1 27 2</measResults>
+                <suspect>false</suspect>
+            </measValue>
+        </measInfo>
+        <measInfo measInfoId="some measInfoId2">
+            <job jobId="jobId"/>
+            <granPeriod endTime="2018-10-02T12:15:00Z" duration="PT900S"/>
+            <repPeriod duration="PT900S"/>
+            <measTypes>z a zz b</measTypes>
+            <measValue measObjLdn="objLdn">
+                <measResults>99 1 27 2</measResults>
+                <suspect>false</suspect>
+            </measValue>
+        </measInfo>
+    </measData>
+    <fileFooter>
+        <MeasData endTime="2018-10-02T12:15:00+01:00"/>
+    </fileFooter>
+</MeasDataFile>
diff --git a/src/test/resources/filter_test/nr/meas_type_and_r/expected.xml b/src/test/resources/filter_test/nr/meas_type_and_r/expected.xml
new file mode 100644 (file)
index 0000000..74090c6
--- /dev/null
@@ -0,0 +1,24 @@
+<MeasDataFile xmlns="http://www.3gpp.org/ftp/specs/archive/28_series/28.550#measData">\r
+    <fileHeader fileFormatVersion="32.435 V10.0" vendorName="FooBar Ltd" dnPrefix="some dnPrefix">\r
+        <fileSender senderName="Dublin"/>\r
+        <MeasData beginTime="2018-10-02T12:00:00+01:00"/>\r
+    </fileHeader>\r
+    <measData>\r
+        <measuredEntity localDn="Dublin" swVersion="r0.1"/>\r
+        <measInfo measInfoId="some measInfoId">\r
+            <job jobId="jobId"/>\r
+            <granPeriod duration="PT900S" endTime="2018-10-02T12:15:00Z"/>\r
+            <repPeriod duration="PT900S"/>\r
+            <measType p="1">a</measType>\r
+            <measType p="3">b</measType>\r
+            <measValue measObjLdn="some measObjLdn">\r
+                <r p="1">1</r>\r
+                <r p="3">2</r>\r
+                <suspect>false</suspect>\r
+            </measValue>\r
+        </measInfo>\r
+    </measData>\r
+    <fileFooter>\r
+        <MeasData endTime="2018-10-02T12:15:00+01:00"/>\r
+    </fileFooter>\r
+</MeasDataFile>
\ No newline at end of file
diff --git a/src/test/resources/filter_test/nr/meas_type_and_r/test.xml b/src/test/resources/filter_test/nr/meas_type_and_r/test.xml
new file mode 100644 (file)
index 0000000..e55d303
--- /dev/null
@@ -0,0 +1,26 @@
+<MeasDataFile xmlns="http://www.3gpp.org/ftp/specs/archive/28_series/28.550#measData">\r
+    <fileHeader fileFormatVersion="32.435 V10.0" vendorName="FooBar Ltd" dnPrefix="some dnPrefix">\r
+        <fileSender senderName="Dublin"/>\r
+        <MeasData beginTime="2018-10-02T12:00:00+01:00"/>\r
+    </fileHeader>\r
+    <measData>\r
+        <measuredEntity localDn="Dublin" swVersion="r0.1"/>\r
+        <measInfo measInfoId="some measInfoId">\r
+            <job jobId="jobId"/>\r
+            <granPeriod duration="PT900S" endTime="2018-10-02T12:15:00Z"/>\r
+            <repPeriod duration="PT900S"/>\r
+            <measType p="1">a</measType>\r
+            <measType p="2">z</measType>\r
+            <measType p="3">b</measType>\r
+            <measValue measObjLdn="some measObjLdn">\r
+                <r p="1">1</r>\r
+                <r p="2">99</r>\r
+                <r p="3">2</r>\r
+                <suspect>false</suspect>\r
+            </measValue>\r
+        </measInfo>\r
+    </measData>\r
+    <fileFooter>\r
+        <MeasData endTime="2018-10-02T12:15:00+01:00"/>\r
+    </fileFooter>\r
+</MeasDataFile>
\ No newline at end of file
diff --git a/src/test/resources/filter_test/nr/meas_type_and_r_many_measvalue/expected.xml b/src/test/resources/filter_test/nr/meas_type_and_r_many_measvalue/expected.xml
new file mode 100644 (file)
index 0000000..afc8e6f
--- /dev/null
@@ -0,0 +1,30 @@
+<MeasDataFile xmlns="http://www.3gpp.org/ftp/specs/archive/28_series/28.550#measData">\r
+    <fileHeader fileFormatVersion="32.435 V10.0" vendorName="FooBar Ltd" dnPrefix="some dnPrefix">\r
+        <fileSender senderName="Dublin"/>\r
+        <MeasData beginTime="2018-10-02T12:00:00+01:00"/>\r
+    </fileHeader>\r
+    <measData>\r
+        <measuredEntity localDn="Dublin" swVersion="r0.1"/>\r
+        <measInfo measInfoId="some measInfoId">\r
+            <job jobId="jobId"/>\r
+            <granPeriod duration="PT900S" endTime="2018-10-02T12:15:00Z"/>\r
+            <repPeriod duration="PT900S"/>\r
+            <measTypes></measTypes>\r
+            <measType p="1">a</measType>\r
+            <measType p="2">b</measType>\r
+            <measValue measObjLdn="some measObjLdn 1">\r
+                <r p="1">1</r>\r
+                <r p="2">2</r>\r
+                <suspect>false</suspect>\r
+            </measValue>\r
+            <measValue measObjLdn="some measObjLdn 3">\r
+                <r p="1">111</r>\r
+                <r p="2">222</r>\r
+                <suspect>false</suspect>\r
+            </measValue>\r
+        </measInfo>\r
+    </measData>\r
+    <fileFooter>\r
+        <MeasData endTime="2018-10-02T12:15:00+01:00"/>\r
+    </fileFooter>\r
+</MeasDataFile>
\ No newline at end of file
diff --git a/src/test/resources/filter_test/nr/meas_type_and_r_many_measvalue/test.xml b/src/test/resources/filter_test/nr/meas_type_and_r_many_measvalue/test.xml
new file mode 100644 (file)
index 0000000..f268ca2
--- /dev/null
@@ -0,0 +1,36 @@
+<MeasDataFile xmlns="http://www.3gpp.org/ftp/specs/archive/28_series/28.550#measData">\r
+    <fileHeader fileFormatVersion="32.435 V10.0" vendorName="FooBar Ltd" dnPrefix="some dnPrefix">\r
+        <fileSender senderName="Dublin"/>\r
+        <MeasData beginTime="2018-10-02T12:00:00+01:00"/>\r
+    </fileHeader>\r
+    <measData>\r
+        <measuredEntity localDn="Dublin" swVersion="r0.1"/>\r
+        <measInfo measInfoId="some measInfoId">\r
+            <job jobId="jobId"/>\r
+            <granPeriod duration="PT900S" endTime="2018-10-02T12:15:00Z"/>\r
+            <repPeriod duration="PT900S"/>\r
+            <measTypes></measTypes>\r
+            <measType p="1">a</measType>\r
+            <measType p="2">b</measType>\r
+            <measType p="3">c</measType>\r
+            <measValue measObjLdn="some measObjLdn 1">\r
+                <r p="1">1</r>\r
+                <r p="2">2</r>\r
+                <suspect>false</suspect>\r
+            </measValue>\r
+            <measValue measObjLdn="some measObjLdn 2">\r
+                <r p="88">88</r>\r
+                <r p="99">99</r>\r
+                <suspect>false</suspect>\r
+            </measValue>\r
+            <measValue measObjLdn="some measObjLdn 3">\r
+                <r p="1">111</r>\r
+                <r p="2">222</r>\r
+                <suspect>false</suspect>\r
+            </measValue>\r
+        </measInfo>\r
+    </measData>\r
+    <fileFooter>\r
+        <MeasData endTime="2018-10-02T12:15:00+01:00"/>\r
+    </fileFooter>\r
+</MeasDataFile>
\ No newline at end of file
diff --git a/src/test/resources/filter_test/nr/meas_type_and_r_manyinfo/expected.xml b/src/test/resources/filter_test/nr/meas_type_and_r_manyinfo/expected.xml
new file mode 100644 (file)
index 0000000..03c42ab
--- /dev/null
@@ -0,0 +1,36 @@
+<MeasDataFile xmlns="http://www.3gpp.org/ftp/specs/archive/28_series/28.550#measData">\r
+    <fileHeader fileFormatVersion="32.435 V10.0" vendorName="FooBar Ltd" dnPrefix="some dnPrefix">\r
+        <fileSender senderName="Dublin"/>\r
+        <MeasData beginTime="2018-10-02T12:00:00+01:00"/>\r
+    </fileHeader>\r
+    <measData>\r
+        <measuredEntity localDn="Dublin" swVersion="r0.1"/>\r
+        <measInfo measInfoId="some measInfoId">\r
+            <job jobId="jobId"/>\r
+            <granPeriod duration="PT900S" endTime="2018-10-02T12:15:00Z"/>\r
+            <repPeriod duration="PT900S"/>\r
+            <measType p="1">a</measType>\r
+            <measType p="3">b</measType>\r
+            <measValue measObjLdn="some measObjLdn">\r
+                <r p="1">1</r>\r
+                <r p="3">2</r>\r
+                <suspect>false</suspect>\r
+            </measValue>\r
+        </measInfo>\r
+        <measInfo measInfoId="some measInfoId2">\r
+            <job jobId="jobId"/>\r
+            <granPeriod duration="PT900S" endTime="2018-10-02T12:15:00Z"/>\r
+            <repPeriod duration="PT900S"/>\r
+            <measType p="1">a</measType>\r
+            <measType p="3">b</measType>\r
+            <measValue measObjLdn="some measObjLdn">\r
+                <r p="1">1</r>\r
+                <r p="3">2</r>\r
+                <suspect>false</suspect>\r
+            </measValue>\r
+        </measInfo>\r
+    </measData>\r
+    <fileFooter>\r
+        <MeasData endTime="2018-10-02T12:15:00+01:00"/>\r
+    </fileFooter>\r
+</MeasDataFile>
\ No newline at end of file
diff --git a/src/test/resources/filter_test/nr/meas_type_and_r_manyinfo/test.xml b/src/test/resources/filter_test/nr/meas_type_and_r_manyinfo/test.xml
new file mode 100644 (file)
index 0000000..beda93f
--- /dev/null
@@ -0,0 +1,54 @@
+<MeasDataFile xmlns="http://www.3gpp.org/ftp/specs/archive/28_series/28.550#measData">\r
+    <fileHeader fileFormatVersion="32.435 V10.0" vendorName="FooBar Ltd" dnPrefix="some dnPrefix">\r
+        <fileSender senderName="Dublin"/>\r
+        <MeasData beginTime="2018-10-02T12:00:00+01:00"/>\r
+    </fileHeader>\r
+    <measData>\r
+        <measuredEntity localDn="Dublin" swVersion="r0.1"/>\r
+        <measInfo measInfoId="some measInfoId">\r
+            <job jobId="jobId"/>\r
+            <granPeriod duration="PT900S" endTime="2018-10-02T12:15:00Z"/>\r
+            <repPeriod duration="PT900S"/>\r
+            <measType p="1">a</measType>\r
+            <measType p="2">z</measType>\r
+            <measType p="3">b</measType>\r
+            <measValue measObjLdn="some measObjLdn">\r
+                <r p="1">1</r>\r
+                <r p="2">99</r>\r
+                <r p="3">2</r>\r
+                <suspect>false</suspect>\r
+            </measValue>\r
+        </measInfo>\r
+        <measInfo measInfoId="filter will disregard this measInfo">\r
+            <job jobId="jobId"/>\r
+            <granPeriod duration="PT900S" endTime="2018-10-02T12:15:00Z"/>\r
+            <repPeriod duration="PT900S"/>\r
+            <measType p="1">aa</measType>\r
+            <measType p="2">z</measType>\r
+            <measType p="3">bb</measType>\r
+            <measValue measObjLdn="some measObjLdn">\r
+                <r p="1">1</r>\r
+                <r p="2">99</r>\r
+                <r p="3">2</r>\r
+                <suspect>false</suspect>\r
+            </measValue>\r
+        </measInfo>\r
+        <measInfo measInfoId="some measInfoId2">\r
+            <job jobId="jobId"/>\r
+            <granPeriod duration="PT900S" endTime="2018-10-02T12:15:00Z"/>\r
+            <repPeriod duration="PT900S"/>\r
+            <measType p="1">a</measType>\r
+            <measType p="2">z</measType>\r
+            <measType p="3">b</measType>\r
+            <measValue measObjLdn="some measObjLdn">\r
+                <r p="1">1</r>\r
+                <r p="2">99</r>\r
+                <r p="3">2</r>\r
+                <suspect>false</suspect>\r
+            </measValue>\r
+        </measInfo>\r
+    </measData>\r
+    <fileFooter>\r
+        <MeasData endTime="2018-10-02T12:15:00+01:00"/>\r
+    </fileFooter>\r
+</MeasDataFile>
\ No newline at end of file
diff --git a/src/test/resources/mapper_test/mapping_data/28.550/meas_results/metadata.json b/src/test/resources/mapper_test/mapping_data/28.550/meas_results/metadata.json
new file mode 100644 (file)
index 0000000..3456b7c
--- /dev/null
@@ -0,0 +1,12 @@
+{
+  "productName": "NrRadio",
+  "vendorName": "Ericsson",
+  "lastEpochMicrosec": "1538478000000",
+  "sourceName": "oteNB5309",
+  "startEpochMicrosec": "1538478900000",
+  "timeZoneOffset": "UTC+05.00",
+  "location": "ftpes://192.168.0.101:22/ftp/rop/A20161224.1045-1100.bin.gz",
+  "compression": "gzip",
+  "fileFormatType": "org.3GPP.28.550#measData",
+  "fileFormatVersion": "V9"
+}
\ No newline at end of file
diff --git a/src/test/resources/mapper_test/mapping_data/28.550/meas_results/test.xml b/src/test/resources/mapper_test/mapping_data/28.550/meas_results/test.xml
new file mode 100644 (file)
index 0000000..29747dc
--- /dev/null
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<MeasDataFile xmlns="http://www.3gpp.org/ftp/specs/archive/28_series/28.550#measData">
+    <fileHeader dnPrefix="some dnPrefix" vendorName="FooBar Ltd"
+                fileFormatVersion="28.550 V1">
+        <fileSender senderName="Dublin"/>
+        <MeasData beginTime="2018-10-02T12:00:00+01:00"/>
+    </fileHeader>
+    <measData>
+        <measuredEntity swVersion="r0.1" localDn="Dublin"/>
+        <measInfo measInfoId="some measInfoId">
+            <job jobId="jobId"/>
+            <granPeriod endTime="2018-10-02T12:15:00Z" duration="PT900S"/>
+            <repPeriod duration="PT900S"/>
+            <measTypes>a b c</measTypes>
+            <measValue measObjLdn="objLdn">
+                <measResults>76 27 98</measResults>
+                <suspect>false</suspect>
+            </measValue>
+        </measInfo>
+    </measData>
+    <fileFooter>
+        <MeasData endTime="2018-10-02T12:15:00+01:00"/>
+    </fileFooter>
+</MeasDataFile>
diff --git a/src/test/resources/mapper_test/mapping_data/28.550/meas_type_and_r/metadata.json b/src/test/resources/mapper_test/mapping_data/28.550/meas_type_and_r/metadata.json
new file mode 100644 (file)
index 0000000..3456b7c
--- /dev/null
@@ -0,0 +1,12 @@
+{
+  "productName": "NrRadio",
+  "vendorName": "Ericsson",
+  "lastEpochMicrosec": "1538478000000",
+  "sourceName": "oteNB5309",
+  "startEpochMicrosec": "1538478900000",
+  "timeZoneOffset": "UTC+05.00",
+  "location": "ftpes://192.168.0.101:22/ftp/rop/A20161224.1045-1100.bin.gz",
+  "compression": "gzip",
+  "fileFormatType": "org.3GPP.28.550#measData",
+  "fileFormatVersion": "V9"
+}
\ No newline at end of file
diff --git a/src/test/resources/mapper_test/mapping_data/28.550/meas_type_and_r/test.xml b/src/test/resources/mapper_test/mapping_data/28.550/meas_type_and_r/test.xml
new file mode 100644 (file)
index 0000000..1757f4a
--- /dev/null
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<MeasDataFile xmlns="http://www.3gpp.org/ftp/specs/archive/28_series/28.550#measData">
+    <fileHeader dnPrefix="some dnPrefix" vendorName="FooBar Ltd"
+                fileFormatVersion="28.550 V1">
+        <fileSender senderName="Dublin"/>
+        <MeasData beginTime="2018-10-02T12:00:00+01:00"/>
+    </fileHeader>
+    <measData>
+        <measuredEntity swVersion="r0.1" localDn="Dublin"/>
+        <measInfo measInfoId="some measInfoId">
+            <job jobId="some Job Id"/>
+            <granPeriod endTime="2018-10-02T12:15:00Z" duration="PT900S"/>
+            <repPeriod duration="PT900S"/>
+            <measType p="1">a</measType>
+            <measType p="2">b</measType>
+            <measType p="3">c</measType>
+            <measValue measObjLdn="some measObjLdn">
+                <r p="1">86</r>
+                <r p="2">67</r>
+                <r p="3">14</r>
+                <suspect>false</suspect>
+            </measValue>
+        </measInfo>
+    </measData>
+    <fileFooter>
+        <MeasData endTime="2018-10-02T12:15:00+01:00"/>
+    </fileFooter>
+</MeasDataFile>
diff --git a/src/test/resources/mapper_test/mapping_data/28.550/meas_type_and_r_many_meas_values/metadata.json b/src/test/resources/mapper_test/mapping_data/28.550/meas_type_and_r_many_meas_values/metadata.json
new file mode 100644 (file)
index 0000000..3456b7c
--- /dev/null
@@ -0,0 +1,12 @@
+{
+  "productName": "NrRadio",
+  "vendorName": "Ericsson",
+  "lastEpochMicrosec": "1538478000000",
+  "sourceName": "oteNB5309",
+  "startEpochMicrosec": "1538478900000",
+  "timeZoneOffset": "UTC+05.00",
+  "location": "ftpes://192.168.0.101:22/ftp/rop/A20161224.1045-1100.bin.gz",
+  "compression": "gzip",
+  "fileFormatType": "org.3GPP.28.550#measData",
+  "fileFormatVersion": "V9"
+}
\ No newline at end of file
diff --git a/src/test/resources/mapper_test/mapping_data/28.550/meas_type_and_r_many_meas_values/test.xml b/src/test/resources/mapper_test/mapping_data/28.550/meas_type_and_r_many_meas_values/test.xml
new file mode 100644 (file)
index 0000000..3a0c608
--- /dev/null
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<MeasDataFile xmlns="http://www.3gpp.org/ftp/specs/archive/28_series/28.550#measData">
+    <fileHeader dnPrefix="some dnPrefix" vendorName="FooBar Ltd"
+                fileFormatVersion="28.550 V1">
+        <fileSender senderName="Dublin"/>
+        <MeasData beginTime="2018-10-02T12:00:00+01:00"/>
+    </fileHeader>
+    <measData>
+        <measuredEntity swVersion="r0.1" localDn="Dublin"/>
+        <measInfo measInfoId="some measInfoId">
+            <job jobId="some Job Id"/>
+            <granPeriod endTime="2018-10-02T12:15:00Z" duration="PT900S"/>
+            <repPeriod duration="PT900S"/>
+            <measType p="1">a</measType>
+            <measType p="2">b</measType>
+            <measType p="3">c</measType>
+            <measValue measObjLdn="some measObjLdn">
+                <r p="1">86</r>
+                <r p="2">67</r>
+                <r p="3">14</r>
+                <suspect>false</suspect>
+            </measValue>
+            <measValue measObjLdn="some other measObjLdn">
+                <r p="1">5</r>
+                <r p="2">6</r>
+                <r p="3">14</r>
+                <suspect>false</suspect>
+            </measValue>
+        </measInfo>
+    </measData>
+    <fileFooter>
+        <MeasData endTime="2018-10-02T12:15:00+01:00"/>
+    </fileFooter>
+</MeasDataFile>
diff --git a/src/test/resources/mapper_test/mapping_data/28.550/meas_types_and_meas_results_many_meas_values/metadata.json b/src/test/resources/mapper_test/mapping_data/28.550/meas_types_and_meas_results_many_meas_values/metadata.json
new file mode 100644 (file)
index 0000000..3456b7c
--- /dev/null
@@ -0,0 +1,12 @@
+{
+  "productName": "NrRadio",
+  "vendorName": "Ericsson",
+  "lastEpochMicrosec": "1538478000000",
+  "sourceName": "oteNB5309",
+  "startEpochMicrosec": "1538478900000",
+  "timeZoneOffset": "UTC+05.00",
+  "location": "ftpes://192.168.0.101:22/ftp/rop/A20161224.1045-1100.bin.gz",
+  "compression": "gzip",
+  "fileFormatType": "org.3GPP.28.550#measData",
+  "fileFormatVersion": "V9"
+}
\ No newline at end of file
diff --git a/src/test/resources/mapper_test/mapping_data/28.550/meas_types_and_meas_results_many_meas_values/test.xml b/src/test/resources/mapper_test/mapping_data/28.550/meas_types_and_meas_results_many_meas_values/test.xml
new file mode 100644 (file)
index 0000000..23f9429
--- /dev/null
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<MeasDataFile xmlns="http://www.3gpp.org/ftp/specs/archive/28_series/28.550#measData">
+    <fileHeader dnPrefix="some dnPrefix" vendorName="FooBar Ltd"
+                fileFormatVersion="28.550 V1">
+        <fileSender senderName="Dublin"/>
+        <MeasData beginTime="2018-10-02T12:00:00+01:00"/>
+    </fileHeader>
+    <measData>
+        <measuredEntity swVersion="r0.1" localDn="Dublin"/>
+        <measInfo measInfoId="some measInfoId">
+            <job jobId="jobId"/>
+            <granPeriod endTime="2018-10-02T12:15:00Z" duration="PT900S"/>
+            <repPeriod duration="PT900S"/>
+            <measTypes>a b c</measTypes>
+            <measValue measObjLdn="objLdn">
+                <measResults>76 27 98</measResults>
+                <suspect>false</suspect>
+            </measValue>
+            <measValue measObjLdn="some other objLdn">
+                <measResults>1 2 9</measResults>
+                <suspect>false</suspect>
+            </measValue>
+        </measInfo>
+    </measData>
+    <fileFooter>
+        <MeasData endTime="2018-10-02T12:15:00+01:00"/>
+    </fileFooter>
+</MeasDataFile>
diff --git a/src/test/resources/mapper_test/mapping_data/28.550/no_measdata/metadata.json b/src/test/resources/mapper_test/mapping_data/28.550/no_measdata/metadata.json
new file mode 100644 (file)
index 0000000..3456b7c
--- /dev/null
@@ -0,0 +1,12 @@
+{
+  "productName": "NrRadio",
+  "vendorName": "Ericsson",
+  "lastEpochMicrosec": "1538478000000",
+  "sourceName": "oteNB5309",
+  "startEpochMicrosec": "1538478900000",
+  "timeZoneOffset": "UTC+05.00",
+  "location": "ftpes://192.168.0.101:22/ftp/rop/A20161224.1045-1100.bin.gz",
+  "compression": "gzip",
+  "fileFormatType": "org.3GPP.28.550#measData",
+  "fileFormatVersion": "V9"
+}
\ No newline at end of file
diff --git a/src/test/resources/mapper_test/mapping_data/28.550/no_measdata/test.xml b/src/test/resources/mapper_test/mapping_data/28.550/no_measdata/test.xml
new file mode 100644 (file)
index 0000000..30bb82b
--- /dev/null
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<MeasDataFile xmlns="http://www.3gpp.org/ftp/specs/archive/28_series/28.550#measData">
+    <fileHeader dnPrefix="some dnPrefix" vendorName="FooBar Ltd"
+                fileFormatVersion="28.550 V1">
+        <fileSender senderName="Dublin"/>
+        <MeasData beginTime="2018-10-02T12:00:00+01:00"/>
+    </fileHeader>
+    <fileFooter>
+        <MeasData endTime="2018-10-02T12:15:00+01:00"/>
+    </fileFooter>
+</MeasDataFile>
diff --git a/src/test/resources/mapper_test/mapping_data/28.550/no_sw_version/metadata.json b/src/test/resources/mapper_test/mapping_data/28.550/no_sw_version/metadata.json
new file mode 100644 (file)
index 0000000..3456b7c
--- /dev/null
@@ -0,0 +1,12 @@
+{
+  "productName": "NrRadio",
+  "vendorName": "Ericsson",
+  "lastEpochMicrosec": "1538478000000",
+  "sourceName": "oteNB5309",
+  "startEpochMicrosec": "1538478900000",
+  "timeZoneOffset": "UTC+05.00",
+  "location": "ftpes://192.168.0.101:22/ftp/rop/A20161224.1045-1100.bin.gz",
+  "compression": "gzip",
+  "fileFormatType": "org.3GPP.28.550#measData",
+  "fileFormatVersion": "V9"
+}
\ No newline at end of file
diff --git a/src/test/resources/mapper_test/mapping_data/28.550/no_sw_version/test.xml b/src/test/resources/mapper_test/mapping_data/28.550/no_sw_version/test.xml
new file mode 100644 (file)
index 0000000..92fd1ff
--- /dev/null
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<MeasDataFile xmlns="http://www.3gpp.org/ftp/specs/archive/28_series/28.550#measData">
+    <fileHeader dnPrefix="some dnPrefix" vendorName="FooBar Ltd"
+                fileFormatVersion="28.550 V1">
+        <fileSender senderName="Dublin"/>
+        <MeasData beginTime="2018-10-02T12:00:00+01:00"/>
+    </fileHeader>
+    <measData>
+        <measuredEntity localDn="Dublin"/>
+        <measInfo measInfoId="some measInfoId">
+            <job jobId="some Job Id"/>
+            <granPeriod endTime="2018-10-02T12:15:00Z" duration="PT900S"/>
+            <repPeriod duration="PT900S"/>
+            <measType p="1">a</measType>
+            <measType p="2">b</measType>
+            <measType p="3">c</measType>
+            <measValue measObjLdn="some measObjLdn">
+                <r p="1">86</r>
+                <r p="2">67</r>
+                <r p="3">14</r>
+                <suspect>false</suspect>
+            </measValue>
+        </measInfo>
+    </measData>
+    <fileFooter>
+        <MeasData endTime="2018-10-02T12:15:00+01:00"/>
+    </fileFooter>
+</MeasDataFile>
diff --git a/src/test/resources/mapper_test/mapping_data/32.435/meas_results/metadata.json b/src/test/resources/mapper_test/mapping_data/32.435/meas_results/metadata.json
new file mode 100644 (file)
index 0000000..5a84d99
--- /dev/null
@@ -0,0 +1,12 @@
+{
+  "productName": "lteRadio",
+  "vendorName": "Ericsson",
+  "lastEpochMicrosec": "1538478000000",
+  "sourceName": "oteNB5309",
+  "startEpochMicrosec": "1538478900000",
+  "timeZoneOffset": "UTC+05.00",
+  "location": "ftpes://192.168.0.101:22/ftp/rop/A20161224.1045-1100.bin.gz",
+  "compression": "gzip",
+  "fileFormatType": "org.3GPP.32.435#measCollec",
+  "fileFormatVersion": "V9"
+}
\ No newline at end of file
diff --git a/src/test/resources/mapper_test/mapping_data/32.435/meas_type_and_r/metadata.json b/src/test/resources/mapper_test/mapping_data/32.435/meas_type_and_r/metadata.json
new file mode 100644 (file)
index 0000000..5a84d99
--- /dev/null
@@ -0,0 +1,12 @@
+{
+  "productName": "lteRadio",
+  "vendorName": "Ericsson",
+  "lastEpochMicrosec": "1538478000000",
+  "sourceName": "oteNB5309",
+  "startEpochMicrosec": "1538478900000",
+  "timeZoneOffset": "UTC+05.00",
+  "location": "ftpes://192.168.0.101:22/ftp/rop/A20161224.1045-1100.bin.gz",
+  "compression": "gzip",
+  "fileFormatType": "org.3GPP.32.435#measCollec",
+  "fileFormatVersion": "V9"
+}
\ No newline at end of file
diff --git a/src/test/resources/mapper_test/mapping_data/32.435/meas_type_and_r_many_meas_values/metadata.json b/src/test/resources/mapper_test/mapping_data/32.435/meas_type_and_r_many_meas_values/metadata.json
new file mode 100644 (file)
index 0000000..5a84d99
--- /dev/null
@@ -0,0 +1,12 @@
+{
+  "productName": "lteRadio",
+  "vendorName": "Ericsson",
+  "lastEpochMicrosec": "1538478000000",
+  "sourceName": "oteNB5309",
+  "startEpochMicrosec": "1538478900000",
+  "timeZoneOffset": "UTC+05.00",
+  "location": "ftpes://192.168.0.101:22/ftp/rop/A20161224.1045-1100.bin.gz",
+  "compression": "gzip",
+  "fileFormatType": "org.3GPP.32.435#measCollec",
+  "fileFormatVersion": "V9"
+}
\ No newline at end of file
diff --git a/src/test/resources/mapper_test/mapping_data/32.435/meas_types_and_meas_results_many_meas_values/metadata.json b/src/test/resources/mapper_test/mapping_data/32.435/meas_types_and_meas_results_many_meas_values/metadata.json
new file mode 100644 (file)
index 0000000..5a84d99
--- /dev/null
@@ -0,0 +1,12 @@
+{
+  "productName": "lteRadio",
+  "vendorName": "Ericsson",
+  "lastEpochMicrosec": "1538478000000",
+  "sourceName": "oteNB5309",
+  "startEpochMicrosec": "1538478900000",
+  "timeZoneOffset": "UTC+05.00",
+  "location": "ftpes://192.168.0.101:22/ftp/rop/A20161224.1045-1100.bin.gz",
+  "compression": "gzip",
+  "fileFormatType": "org.3GPP.32.435#measCollec",
+  "fileFormatVersion": "V9"
+}
\ No newline at end of file
diff --git a/src/test/resources/mapper_test/mapping_data/32.435/no_measdata/metadata.json b/src/test/resources/mapper_test/mapping_data/32.435/no_measdata/metadata.json
new file mode 100644 (file)
index 0000000..5a84d99
--- /dev/null
@@ -0,0 +1,12 @@
+{
+  "productName": "lteRadio",
+  "vendorName": "Ericsson",
+  "lastEpochMicrosec": "1538478000000",
+  "sourceName": "oteNB5309",
+  "startEpochMicrosec": "1538478900000",
+  "timeZoneOffset": "UTC+05.00",
+  "location": "ftpes://192.168.0.101:22/ftp/rop/A20161224.1045-1100.bin.gz",
+  "compression": "gzip",
+  "fileFormatType": "org.3GPP.32.435#measCollec",
+  "fileFormatVersion": "V9"
+}
\ No newline at end of file
diff --git a/src/test/resources/mapper_test/mapping_data/32.435/no_sw_version/metadata.json b/src/test/resources/mapper_test/mapping_data/32.435/no_sw_version/metadata.json
new file mode 100644 (file)
index 0000000..5a84d99
--- /dev/null
@@ -0,0 +1,12 @@
+{
+  "productName": "lteRadio",
+  "vendorName": "Ericsson",
+  "lastEpochMicrosec": "1538478000000",
+  "sourceName": "oteNB5309",
+  "startEpochMicrosec": "1538478900000",
+  "timeZoneOffset": "UTC+05.00",
+  "location": "ftpes://192.168.0.101:22/ftp/rop/A20161224.1045-1100.bin.gz",
+  "compression": "gzip",
+  "fileFormatType": "org.3GPP.32.435#measCollec",
+  "fileFormatVersion": "V9"
+}
\ No newline at end of file
diff --git a/src/test/resources/metadata/invalid_metadata.json b/src/test/resources/metadata/invalid_metadata.json
new file mode 100644 (file)
index 0000000..31600b0
--- /dev/null
@@ -0,0 +1,11 @@
+{
+  "vendorName": "Ericsson",
+  "lastEpochMicrosec": "1538478000000",
+  "sourceName": "oteNB5309",
+  "startEpochMicrosec": "1538478900000",
+  "timeZoneOffset": "UTC+05.00",
+  "location": "ftpes://192.168.0.101:22/ftp/rop/A20161224.1045-1100.bin.gz",
+  "compression": "gzip",
+  "fileFormatType": "org.3GPP.32.435#measCollec",
+  "fileFormatVersion": "V9"
+}
\ No newline at end of file
diff --git a/src/test/resources/metadata/valid_4g_metadata.json b/src/test/resources/metadata/valid_4g_metadata.json
new file mode 100644 (file)
index 0000000..5a84d99
--- /dev/null
@@ -0,0 +1,12 @@
+{
+  "productName": "lteRadio",
+  "vendorName": "Ericsson",
+  "lastEpochMicrosec": "1538478000000",
+  "sourceName": "oteNB5309",
+  "startEpochMicrosec": "1538478900000",
+  "timeZoneOffset": "UTC+05.00",
+  "location": "ftpes://192.168.0.101:22/ftp/rop/A20161224.1045-1100.bin.gz",
+  "compression": "gzip",
+  "fileFormatType": "org.3GPP.32.435#measCollec",
+  "fileFormatVersion": "V9"
+}
\ No newline at end of file
diff --git a/src/test/resources/metadata/valid_5g_metadata.json b/src/test/resources/metadata/valid_5g_metadata.json
new file mode 100644 (file)
index 0000000..3456b7c
--- /dev/null
@@ -0,0 +1,12 @@
+{
+  "productName": "NrRadio",
+  "vendorName": "Ericsson",
+  "lastEpochMicrosec": "1538478000000",
+  "sourceName": "oteNB5309",
+  "startEpochMicrosec": "1538478900000",
+  "timeZoneOffset": "UTC+05.00",
+  "location": "ftpes://192.168.0.101:22/ftp/rop/A20161224.1045-1100.bin.gz",
+  "compression": "gzip",
+  "fileFormatType": "org.3GPP.28.550#measData",
+  "fileFormatVersion": "V9"
+}
\ No newline at end of file
diff --git a/src/test/resources/split_test/lte/type_a_1_event/split.props b/src/test/resources/split_test/lte/type_a_1_event/split.props
new file mode 100644 (file)
index 0000000..3598e18
--- /dev/null
@@ -0,0 +1,2 @@
+eventCount=1
+measInfoIds=Singular measInfoId
\ No newline at end of file
diff --git a/src/test/resources/split_test/lte/type_a_1_event/test.xml b/src/test/resources/split_test/lte/type_a_1_event/test.xml
new file mode 100644 (file)
index 0000000..b49f7f0
--- /dev/null
@@ -0,0 +1,23 @@
+<measCollecFile xmlns="http://www.3gpp.org/ftp/specs/archive/32_series/32.435#measCollec">
+    <fileHeader dnPrefix="some dnPrefix" vendorName="FooBar Ltd"
+                fileFormatVersion="32.435 V10.0">
+        <fileSender localDn="Dublin"/>
+        <measCollec beginTime="2018-10-02T12:00:00+01:00"/>
+    </fileHeader>
+    <measData>
+        <managedElement swVersion="r0.1" localDn="Dublin"/>
+        <measInfo measInfoId="Singular measInfoId">
+            <job jobId="jobId"/>
+            <granPeriod endTime="2018-10-02T12:15:00Z" duration="PT900S"/>
+            <repPeriod duration="PT900S"/>
+            <measTypes>z a zz b</measTypes>
+            <measValue measObjLdn="objLdn">
+                <measResults>99 1 27 2</measResults>
+                <suspect>false</suspect>
+            </measValue>
+        </measInfo>
+    </measData>
+    <fileFooter>
+        <measCollec endTime="2018-10-02T12:15:00+01:00"/>
+    </fileFooter>
+</measCollecFile>
diff --git a/src/test/resources/split_test/lte/type_c_3_events/split.props b/src/test/resources/split_test/lte/type_c_3_events/split.props
new file mode 100644 (file)
index 0000000..35d90f4
--- /dev/null
@@ -0,0 +1,2 @@
+eventCount=3
+measInfoIds=First measInfoId,Second measInfoId,Third measInfoId
\ No newline at end of file
diff --git a/src/test/resources/split_test/lte/type_c_3_events/test.xml b/src/test/resources/split_test/lte/type_c_3_events/test.xml
new file mode 100644 (file)
index 0000000..7680f9d
--- /dev/null
@@ -0,0 +1,49 @@
+<measCollecFile xmlns="http://www.3gpp.org/ftp/specs/archive/32_series/32.435#measCollec">
+    <fileHeader dnPrefix="some dnPrefix" vendorName="FooBar Ltd"
+                fileFormatVersion="32.435 V10.0">
+        <fileSender localDn="Dublin"/>
+        <measCollec beginTime="2018-10-02T12:00:00+01:00"/>
+    </fileHeader>
+    <measData>
+        <managedElement swVersion="r0.1" localDn="Dublin1"/>
+        <measInfo measInfoId="First measInfoId">
+            <job jobId="jobId1"/>
+            <granPeriod endTime="2001-10-02T12:15:00Z" duration="PT100S"/>
+            <repPeriod duration="PT100S"/>
+            <measTypes>z1 a1 zz1 b1</measTypes>
+            <measValue measObjLdn="objLdn">
+                <measResults>1 11 111 1111</measResults>
+                <suspect>false</suspect>
+            </measValue>
+        </measInfo>
+    </measData>
+    <measData>
+        <managedElement swVersion="r0.2" localDn="Dublin2"/>
+        <measInfo measInfoId="Second measInfoId">
+            <job jobId="jobId"/>
+            <granPeriod endTime="2002-10-02T12:15:00Z" duration="PT200S"/>
+            <repPeriod duration="PT200S"/>
+            <measTypes>z2 a2 zz2 b2</measTypes>
+            <measValue measObjLdn="objLdn">
+                <measResults>2 22 222 2222</measResults>
+                <suspect>false</suspect>
+            </measValue>
+        </measInfo>
+    </measData>
+    <measData>
+        <managedElement swVersion="r0.3" localDn="Dublin3"/>
+        <measInfo measInfoId="Third measInfoId">
+            <job jobId="jobId"/>
+            <granPeriod endTime="2003-10-02T12:15:00Z" duration="PT300S"/>
+            <repPeriod duration="PT300S"/>
+            <measTypes>z3 a3 zz3 b3</measTypes>
+            <measValue measObjLdn="objLdn">
+                <measResults>3 33 333 3333</measResults>
+                <suspect>false</suspect>
+            </measValue>
+        </measInfo>
+    </measData>
+    <fileFooter>
+        <measCollec endTime="2018-10-02T12:15:00+01:00"/>
+    </fileFooter>
+</measCollecFile>
diff --git a/src/test/resources/split_test/nr/type_a_1_event/split.props b/src/test/resources/split_test/nr/type_a_1_event/split.props
new file mode 100644 (file)
index 0000000..3598e18
--- /dev/null
@@ -0,0 +1,2 @@
+eventCount=1
+measInfoIds=Singular measInfoId
\ No newline at end of file
diff --git a/src/test/resources/split_test/nr/type_a_1_event/test.xml b/src/test/resources/split_test/nr/type_a_1_event/test.xml
new file mode 100644 (file)
index 0000000..f88e0c5
--- /dev/null
@@ -0,0 +1,23 @@
+<MeasDataFile xmlns="http://www.3gpp.org/ftp/specs/archive/28_series/28.550#measData">
+    <fileHeader dnPrefix="some dnPrefix" vendorName="FooBar Ltd"
+                fileFormatVersion="32.435 V10.0">
+        <fileSender senderName="Dublin"/>
+        <MeasData beginTime="2018-10-02T12:00:00+01:00"/>
+    </fileHeader>
+    <measData>
+        <measuredEntity swVersion="r0.1" localDn="Dublin"/>
+        <measInfo measInfoId="Singular measInfoId">
+            <job jobId="jobId"/>
+            <granPeriod endTime="2018-10-02T12:15:00Z" duration="PT900S"/>
+            <repPeriod duration="PT900S"/>
+            <measTypes>z a zz b</measTypes>
+            <measValue measObjLdn="objLdn">
+                <measResults>99 1 27 2</measResults>
+                <suspect>false</suspect>
+            </measValue>
+        </measInfo>
+    </measData>
+    <fileFooter>
+        <MeasData endTime="2018-10-02T12:15:00+01:00"/>
+    </fileFooter>
+</MeasDataFile>
diff --git a/src/test/resources/split_test/nr/type_c_3_events/split.props b/src/test/resources/split_test/nr/type_c_3_events/split.props
new file mode 100644 (file)
index 0000000..35d90f4
--- /dev/null
@@ -0,0 +1,2 @@
+eventCount=3
+measInfoIds=First measInfoId,Second measInfoId,Third measInfoId
\ No newline at end of file
diff --git a/src/test/resources/split_test/nr/type_c_3_events/test.xml b/src/test/resources/split_test/nr/type_c_3_events/test.xml
new file mode 100644 (file)
index 0000000..ccbb09b
--- /dev/null
@@ -0,0 +1,49 @@
+<MeasDataFile xmlns="http://www.3gpp.org/ftp/specs/archive/28_series/28.550#measData">
+    <fileHeader dnPrefix="some dnPrefix" vendorName="FooBar Ltd"
+                fileFormatVersion="32.435 V10.0">
+        <fileSender senderName="Dublin"/>
+        <MeasData beginTime="2018-10-02T12:00:00+01:00"/>
+    </fileHeader>
+    <measData>
+        <measuredEntity swVersion="r0.1" localDn="Dublin1"/>
+        <measInfo measInfoId="First measInfoId">
+            <job jobId="jobId1"/>
+            <granPeriod endTime="2001-10-02T12:15:00Z" duration="PT100S"/>
+            <repPeriod duration="PT100S"/>
+            <measTypes>z1 a1 zz1 b1</measTypes>
+            <measValue measObjLdn="objLdn">
+                <measResults>1 11 111 1111</measResults>
+                <suspect>false</suspect>
+            </measValue>
+        </measInfo>
+    </measData>
+    <measData>
+        <measuredEntity swVersion="r0.2" localDn="Dublin2"/>
+        <measInfo measInfoId="Second measInfoId">
+            <job jobId="jobId"/>
+            <granPeriod endTime="2002-10-02T12:15:00Z" duration="PT200S"/>
+            <repPeriod duration="PT200S"/>
+            <measTypes>z2 a2 zz2 b2</measTypes>
+            <measValue measObjLdn="objLdn">
+                <measResults>2 22 222 2222</measResults>
+                <suspect>false</suspect>
+            </measValue>
+        </measInfo>
+    </measData>
+    <measData>
+        <measuredEntity swVersion="r0.3" localDn="Dublin3"/>
+        <measInfo measInfoId="Third measInfoId">
+            <job jobId="jobId"/>
+            <granPeriod endTime="2003-10-02T12:15:00Z" duration="PT300S"/>
+            <repPeriod duration="PT300S"/>
+            <measTypes>z3 a3 zz3 b3</measTypes>
+            <measValue measObjLdn="objLdn">
+                <measResults>3 33 333 3333</measResults>
+                <suspect>false</suspect>
+            </measValue>
+        </measInfo>
+    </measData>
+    <fileFooter>
+        <MeasData endTime="2018-10-02T12:15:00+01:00"/>
+    </fileFooter>
+</MeasDataFile>
diff --git a/src/test/resources/xml_validator_test/test_data/lte/no_file_header/validity.props b/src/test/resources/xml_validator_test/test_data/lte/no_file_header/validity.props
new file mode 100644 (file)
index 0000000..80da24e
--- /dev/null
@@ -0,0 +1 @@
+valid=false
\ No newline at end of file
diff --git a/src/test/resources/xml_validator_test/test_data/lte/no_managed_element/validity.props b/src/test/resources/xml_validator_test/test_data/lte/no_managed_element/validity.props
new file mode 100644 (file)
index 0000000..80da24e
--- /dev/null
@@ -0,0 +1 @@
+valid=false
\ No newline at end of file
diff --git a/src/test/resources/xml_validator_test/test_data/lte/no_measdata/validity.props b/src/test/resources/xml_validator_test/test_data/lte/no_measdata/validity.props
new file mode 100644 (file)
index 0000000..6e5af27
--- /dev/null
@@ -0,0 +1 @@
+valid=true
\ No newline at end of file
diff --git a/src/test/resources/xml_validator_test/test_data/nr/no_file_header/test.xml b/src/test/resources/xml_validator_test/test_data/nr/no_file_header/test.xml
new file mode 100644 (file)
index 0000000..3450b98
--- /dev/null
@@ -0,0 +1,22 @@
+<MeasDataFile xmlns="http://www.3gpp.org/ftp/specs/archive/28_series/28.550#measData">
+    <measData>
+        <measuredEntity swVersion="r0.1" localDn="Dublin"/>
+        <measInfo measInfoId="some meas info id">
+            <job jobId="some jobId"/>
+            <granPeriod endTime="2018-10-02T12:15:00Z" duration="PT900S"/>
+            <repPeriod duration="PT900S"/>
+            <measType p="1">a</measType>
+            <measType p="2">b</measType>
+            <measType p="3">c</measType>
+            <measValue measObjLdn="some measObjLdn">
+                <r p="1">86</r>
+                <r p="2">67</r>
+                <r p="3">14</r>
+                <suspect>false</suspect>
+            </measValue>
+        </measInfo>
+    </measData>
+    <fileFooter>
+        <MeasData endTime="2018-10-02T12:15:00+01:00"/>
+    </fileFooter>
+</MeasDataFile>
diff --git a/src/test/resources/xml_validator_test/test_data/nr/no_file_header/validity.props b/src/test/resources/xml_validator_test/test_data/nr/no_file_header/validity.props
new file mode 100644 (file)
index 0000000..80da24e
--- /dev/null
@@ -0,0 +1 @@
+valid=false
\ No newline at end of file
diff --git a/src/test/resources/xml_validator_test/test_data/nr/no_measdata/test.xml b/src/test/resources/xml_validator_test/test_data/nr/no_measdata/test.xml
new file mode 100644 (file)
index 0000000..fb141ad
--- /dev/null
@@ -0,0 +1,10 @@
+<MeasDataFile xmlns="http://www.3gpp.org/ftp/specs/archive/28_series/28.550#measData">
+    <fileHeader dnPrefix="some dnPrefix" vendorName="FooBar Ltd"
+                fileFormatVersion="32.435 V10.0">
+        <fileSender senderName="Dublin"/>
+        <MeasData beginTime="2018-10-02T12:00:00+01:00"/>
+    </fileHeader>
+    <fileFooter>
+        <MeasData endTime="2018-10-02T12:15:00+01:00"/>
+    </fileFooter>
+</MeasDataFile>
diff --git a/src/test/resources/xml_validator_test/test_data/nr/no_measdata/validity.props b/src/test/resources/xml_validator_test/test_data/nr/no_measdata/validity.props
new file mode 100644 (file)
index 0000000..6e5af27
--- /dev/null
@@ -0,0 +1 @@
+valid=true
\ No newline at end of file
diff --git a/src/test/resources/xml_validator_test/test_data/nr/no_measured_entity/test.xml b/src/test/resources/xml_validator_test/test_data/nr/no_measured_entity/test.xml
new file mode 100644 (file)
index 0000000..0d4216e
--- /dev/null
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<MeasDataFile xmlns="http://www.3gpp.org/ftp/specs/archive/28_series/28.550#measData">
+    <fileHeader dnPrefix="some dnPrefix" vendorName="FooBar Ltd"
+                fileFormatVersion="32.435 V10.0">
+        <fileSender senderName="Dublin"/>
+        <MeasData beginTime="2018-10-02T12:00:00+01:00"/>
+    </fileHeader>
+    <measData>
+        <measInfo measInfoId="some measInfoId">
+            <job jobId="some job Id"/>
+            <granPeriod endTime="2018-10-02T12:15:00Z" duration="some duration"/>
+            <repPeriod duration="PT900S"/>
+            <measType p="1">a</measType>
+            <measType p="2">b</measType>
+            <measType p="3">c</measType>
+            <measValue measObjLdn="some measObjLdn">
+                <r p="1">86</r>
+                <r p="2">67</r>
+                <r p="3">14</r>
+                <suspect>false</suspect>
+            </measValue>
+        </measInfo>
+    </measData>
+    <fileFooter>
+        <MeasData endTime="2018-10-02T12:15:00+01:00"/>
+    </fileFooter>
+</MeasDataFile>
diff --git a/src/test/resources/xml_validator_test/test_data/nr/no_measured_entity/validity.props b/src/test/resources/xml_validator_test/test_data/nr/no_measured_entity/validity.props
new file mode 100644 (file)
index 0000000..80da24e
--- /dev/null
@@ -0,0 +1 @@
+valid=false
\ No newline at end of file
index 12d377c..88d216c 100644 (file)
@@ -1,5 +1,5 @@
 major=1
-minor=2
+minor=3
 patch=0
 base_version=${major}.${minor}.${patch}
 release_version=${base_version}