<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>
/*-
* ============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.
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;
/**
* 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) {
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);
}
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) {
-/*-\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);
+ }
+}
/*-
* ============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.
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;
**/
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());
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;
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()
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());
}
}
- 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();
/*-
* ============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.
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;
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;
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);
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);
/*-
* ============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.
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.
@NonNull
private String publishIdentity;
- private MeasCollecFile measCollecFile;
+ private MeasurementFile measurement;
private Filter filter;
+++ /dev/null
-/*-\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
--- /dev/null
+/*-
+ * ============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();
+}
--- /dev/null
+/*-
+ * ============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);
+}
--- /dev/null
+/*-
+ * ============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
--- /dev/null
+/*-\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
--- /dev/null
+/*-
+ * ============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;
+ }
+
+ }
+
+}
/*-\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
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
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
/*-\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
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
* 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
/*-
* ============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 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;
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;
#
# ============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.
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
--- /dev/null
+<?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
--- /dev/null
+<?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
--- /dev/null
+<#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
--- /dev/null
+<#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
/*-
* ============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.
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;
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;
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;
}
@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();
}
@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();
}
@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);
}
@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);
}
/*-
* ============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.
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);
@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"));
@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
@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");
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);
+
}
+
}
/*-
* ============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)
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);
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
/*-
* ============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.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;
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;
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/");
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
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));
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);
}
}
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;
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;
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));
}
}
/*-\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
}\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
/*-\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
/*-
* ============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
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);
}
-
}
--- /dev/null
+/*-
+ * ============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);
+}
/*-
* ============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.
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 {
.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.
* 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.
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;
+ }
}
--- /dev/null
+<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
--- /dev/null
+<?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>
--- /dev/null
+<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
--- /dev/null
+<?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>
--- /dev/null
+<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
--- /dev/null
+<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
--- /dev/null
+<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
--- /dev/null
+<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
--- /dev/null
+<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
--- /dev/null
+<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
--- /dev/null
+{
+ "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
--- /dev/null
+<?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>
--- /dev/null
+{
+ "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
--- /dev/null
+<?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>
--- /dev/null
+{
+ "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
--- /dev/null
+<?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>
--- /dev/null
+{
+ "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
--- /dev/null
+<?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>
--- /dev/null
+{
+ "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
--- /dev/null
+<?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>
--- /dev/null
+{
+ "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
--- /dev/null
+<?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>
--- /dev/null
+{
+ "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
--- /dev/null
+{
+ "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
--- /dev/null
+{
+ "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
--- /dev/null
+{
+ "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
--- /dev/null
+{
+ "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
--- /dev/null
+{
+ "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
--- /dev/null
+{
+ "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
--- /dev/null
+{
+ "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
--- /dev/null
+{
+ "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
--- /dev/null
+eventCount=1
+measInfoIds=Singular measInfoId
\ No newline at end of file
--- /dev/null
+<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>
--- /dev/null
+eventCount=3
+measInfoIds=First measInfoId,Second measInfoId,Third measInfoId
\ No newline at end of file
--- /dev/null
+<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>
--- /dev/null
+eventCount=1
+measInfoIds=Singular measInfoId
\ No newline at end of file
--- /dev/null
+<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>
--- /dev/null
+eventCount=3
+measInfoIds=First measInfoId,Second measInfoId,Third measInfoId
\ No newline at end of file
--- /dev/null
+<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>
--- /dev/null
+valid=false
\ No newline at end of file
--- /dev/null
+valid=false
\ No newline at end of file
--- /dev/null
+valid=true
\ No newline at end of file
--- /dev/null
+<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>
--- /dev/null
+valid=false
\ No newline at end of file
--- /dev/null
+<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>
--- /dev/null
+valid=true
\ No newline at end of file
--- /dev/null
+<?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>
--- /dev/null
+valid=false
\ No newline at end of file
major=1
-minor=2
+minor=3
patch=0
base_version=${major}.${minor}.${patch}
release_version=${base_version}