OAM NF Adopter REST PM 00/6000/4
authorClaudio D. Gasparini <claudio.gasparini@intl.att.com>
Mon, 3 May 2021 14:36:20 +0000 (16:36 +0200)
committerClaudio D. Gasparini <claudio.gasparini@intl.att.com>
Mon, 17 May 2021 07:58:24 +0000 (09:58 +0200)
PM to VES

Issue-ID: OAM-206
Signed-off-by: Claudio D. Gasparini <claudio.gasparini@intl.att.com>
Change-Id: If25ad51ca5ff346f5d9fd27d2f6514f5f9a55ecc

24 files changed:
ves-nf-oam-adopter/pom.xml
ves-nf-oam-adopter/ves-nf-oam-adopter-artifacts/pom.xml
ves-nf-oam-adopter/ves-nf-oam-adopter-parent/pom.xml
ves-nf-oam-adopter/ves-nf-oam-adopter-pm-manager/pom.xml [new file with mode: 0644]
ves-nf-oam-adopter/ves-nf-oam-adopter-pm-manager/src/main/java/org/o/ran/oam/nf/oam/adopter/pm/rest/manager/AdaptersDeployer.java [new file with mode: 0644]
ves-nf-oam-adopter/ves-nf-oam-adopter-pm-manager/src/main/java/org/o/ran/oam/nf/oam/adopter/pm/rest/manager/PerformanceManagementMapperConfigProvider.java [new file with mode: 0644]
ves-nf-oam-adopter/ves-nf-oam-adopter-pm-manager/src/main/java/org/o/ran/oam/nf/oam/adopter/pm/rest/manager/PerformanceManagementRestAgent.java [new file with mode: 0644]
ves-nf-oam-adopter/ves-nf-oam-adopter-pm-manager/src/main/java/org/o/ran/oam/nf/oam/adopter/pm/rest/manager/PerformanceManagementRestAgentFactory.java [new file with mode: 0644]
ves-nf-oam-adopter/ves-nf-oam-adopter-pm-manager/src/main/java/org/o/ran/oam/nf/oam/adopter/pm/rest/manager/api/HttpRestClient.java [new file with mode: 0644]
ves-nf-oam-adopter/ves-nf-oam-adopter-pm-manager/src/main/java/org/o/ran/oam/nf/oam/adopter/pm/rest/manager/api/PerformanceManagementAdaptersDeployer.java [new file with mode: 0644]
ves-nf-oam-adopter/ves-nf-oam-adopter-pm-manager/src/main/java/org/o/ran/oam/nf/oam/adopter/pm/rest/manager/configurations/PerformanceManagementRestManagerConfig.java [new file with mode: 0644]
ves-nf-oam-adopter/ves-nf-oam-adopter-pm-manager/src/main/java/org/o/ran/oam/nf/oam/adopter/pm/rest/manager/exceptions/AlreadyPresentException.java [new file with mode: 0644]
ves-nf-oam-adopter/ves-nf-oam-adopter-pm-manager/src/main/java/org/o/ran/oam/nf/oam/adopter/pm/rest/manager/exceptions/NotFoundException.java [new file with mode: 0644]
ves-nf-oam-adopter/ves-nf-oam-adopter-pm-manager/src/main/java/org/o/ran/oam/nf/oam/adopter/pm/rest/manager/exceptions/PerformanceManagementEmptyOutputException.java [new file with mode: 0644]
ves-nf-oam-adopter/ves-nf-oam-adopter-pm-manager/src/main/java/org/o/ran/oam/nf/oam/adopter/pm/rest/manager/exceptions/PerformanceManagementException.java [new file with mode: 0644]
ves-nf-oam-adopter/ves-nf-oam-adopter-pm-manager/src/main/java/org/o/ran/oam/nf/oam/adopter/pm/rest/manager/exceptions/TokenGenerationException.java [new file with mode: 0644]
ves-nf-oam-adopter/ves-nf-oam-adopter-pm-manager/src/main/java/org/o/ran/oam/nf/oam/adopter/pm/rest/manager/exceptions/ZoneIdException.java [new file with mode: 0644]
ves-nf-oam-adopter/ves-nf-oam-adopter-pm-manager/src/main/java/org/o/ran/oam/nf/oam/adopter/pm/rest/manager/mapper/CommonEventHeaderHandler.java [new file with mode: 0644]
ves-nf-oam-adopter/ves-nf-oam-adopter-pm-manager/src/main/java/org/o/ran/oam/nf/oam/adopter/pm/rest/manager/mapper/MeasurementFieldsHandler.java [new file with mode: 0644]
ves-nf-oam-adopter/ves-nf-oam-adopter-pm-manager/src/main/java/org/o/ran/oam/nf/oam/adopter/pm/rest/manager/mapper/PerformanceManagementFile2VesMapper.java [new file with mode: 0644]
ves-nf-oam-adopter/ves-nf-oam-adopter-pm-manager/src/main/java/org/o/ran/oam/nf/oam/adopter/pm/rest/manager/pojos/Adapter.java [new file with mode: 0644]
ves-nf-oam-adopter/ves-nf-oam-adopter-pm-manager/src/main/java/org/o/ran/oam/nf/oam/adopter/pm/rest/manager/pojos/CsvConfiguration.java [new file with mode: 0644]
ves-nf-oam-adopter/ves-nf-oam-adopter-pm-manager/src/main/java/org/o/ran/oam/nf/oam/adopter/pm/rest/manager/pojos/VesMappingConfiguration.java [new file with mode: 0644]
ves-nf-oam-adopter/ves-nf-oam-adopter-pm-manager/src/main/java/org/o/ran/oam/nf/oam/adopter/pm/rest/manager/properties/PerformanceManagementManagerProperties.java [new file with mode: 0644]

index aa53ec3..c116ba1 100644 (file)
@@ -50,5 +50,6 @@
         <module>ves-nf-oam-adopter-api</module>
         <module>ves-nf-oam-adopter-event-notifier</module>
         <module>ves-nf-oam-adopter-snmp-manager</module>
+        <module>ves-nf-oam-adopter-pm-manager</module>
     </modules>
 </project>
\ No newline at end of file
index 63cb23f..eac13ad 100644 (file)
                 <artifactId>ves-nf-oam-adopter-snmp-manager</artifactId>
                 <version>${project.version}</version>
             </dependency>
+            <dependency>
+                <groupId>${project.groupId}</groupId>
+                <artifactId>ves-nf-oam-adopter-pm-manager</artifactId>
+                <version>${project.version}</version>
+            </dependency>
         </dependencies>
     </dependencyManagement>
 </project>
\ No newline at end of file
index a694efe..aa697e4 100644 (file)
@@ -44,7 +44,9 @@
             ../ves-nf-oam-adopter-event-notifier/target/site/jacoco-ut/jacoco.xml,
             ../ves-nf-oam-adopter-event-notifier/target/site/jacoco-aggregate/jacoco.xml,
             ../ves-nf-oam-adopter-snmp-manager/target/site/jacoco-ut/jacoco.xml,
-            ../ves-nf-oam-adopter-snmp-manager/target/site/jacoco-aggregate/jacoco.xml
+            ../ves-nf-oam-adopter-snmp-manager/target/site/jacoco-aggregate/jacoco.xml,
+            ../ves-nf-oam-adopter-pm-manager/target/site/jacoco-ut/jacoco.xml,
+            ../ves-nf-oam-adopter-pm-manager/target/site/jacoco-aggregate/jacoco.xml
         </sonar.coverage.jacoco.xmlReportPaths>
         <sonar.scanner.version>3.8.0.2131</sonar.scanner.version>
         <!--Dependency Versions-->
@@ -52,6 +54,7 @@
         <commons-io.version>2.6</commons-io.version>
         <commons-beanutils.version>1.9.4</commons-beanutils.version>
         <gson.version>2.8.6</gson.version>
+        <guava.version>30.1-jre</guava.version>
         <httpclient5.version>5.0.3</httpclient5.version>
         <jdt.annotation.version>2.2.600</jdt.annotation.version>
         <lombok.version>1.18.20</lombok.version>
                 <artifactId>commons-beanutils</artifactId>
                 <version>${commons-beanutils.version}</version>
             </dependency>
+            <dependency>
+                <groupId>com.google.guava</groupId>
+                <artifactId>guava</artifactId>
+                <version>${guava.version}</version>
+            </dependency>
             <dependency>
                 <groupId>com.github.spotbugs</groupId>
                 <artifactId>spotbugs-annotations</artifactId>
diff --git a/ves-nf-oam-adopter/ves-nf-oam-adopter-pm-manager/pom.xml b/ves-nf-oam-adopter/ves-nf-oam-adopter-pm-manager/pom.xml
new file mode 100644 (file)
index 0000000..02b4f98
--- /dev/null
@@ -0,0 +1,108 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+* ============LICENSE_START=======================================================
+* O-RAN-SC
+* ================================================================================
+* Copyright (C) 2021 AT&T Intellectual Property. All rights reserved.
+* ================================================================================
+* 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.
+* ============LICENSE_END============================================
+*
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.o-ran-sc.oam</groupId>
+        <artifactId>ves-nf-oam-adopter-parent</artifactId>
+        <version>1.0.0-SNAPSHOT</version>
+        <relativePath>../ves-nf-oam-adopter-parent/pom.xml</relativePath>
+    </parent>
+
+    <artifactId>ves-nf-oam-adopter-pm-manager</artifactId>
+
+    <dependencies>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>ves-nf-oam-adopter-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.httpcomponents.client5</groupId>
+            <artifactId>httpclient5</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.fasterxml.jackson.dataformat</groupId>
+            <artifactId>jackson-dataformat-yaml</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.fasterxml.jackson.dataformat</groupId>
+            <artifactId>jackson-dataformat-csv</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>commons-io</groupId>
+            <artifactId>commons-io</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-configuration2</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>commons-beanutils</groupId>
+            <artifactId>commons-beanutils</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.google.guava</groupId>
+            <artifactId>guava</artifactId>
+            <version>30.1-jre</version>
+        </dependency>
+        <dependency>
+            <groupId>io.reactivex.rxjava3</groupId>
+            <artifactId>rxjava</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.projectlombok</groupId>
+            <artifactId>lombok</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.google.code.gson</groupId>
+            <artifactId>gson</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.github.spotbugs</groupId>
+            <artifactId>spotbugs-annotations</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-actuator</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-validation</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-test</artifactId>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+</project>
\ No newline at end of file
diff --git a/ves-nf-oam-adopter/ves-nf-oam-adopter-pm-manager/src/main/java/org/o/ran/oam/nf/oam/adopter/pm/rest/manager/AdaptersDeployer.java b/ves-nf-oam-adopter/ves-nf-oam-adopter-pm-manager/src/main/java/org/o/ran/oam/nf/oam/adopter/pm/rest/manager/AdaptersDeployer.java
new file mode 100644 (file)
index 0000000..924373d
--- /dev/null
@@ -0,0 +1,100 @@
+/*
+ *  ============LICENSE_START=======================================================
+ *  O-RAN-SC
+ *  ================================================================================
+ *  Copyright © 2021 AT&T Intellectual Property. All rights reserved.
+ *  ================================================================================
+ *  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.
+ *  ============LICENSE_END=========================================================
+ */
+
+package org.o.ran.oam.nf.oam.adopter.pm.rest.manager;
+
+import static org.eclipse.jdt.annotation.Checks.requireNonNull;
+
+import com.google.common.collect.ImmutableList;
+import java.time.ZoneId;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.concurrent.ConcurrentHashMap;
+import org.o.ran.oam.nf.oam.adopter.pm.rest.manager.api.PerformanceManagementAdaptersDeployer;
+import org.o.ran.oam.nf.oam.adopter.pm.rest.manager.exceptions.AlreadyPresentException;
+import org.o.ran.oam.nf.oam.adopter.pm.rest.manager.exceptions.NotFoundException;
+import org.o.ran.oam.nf.oam.adopter.pm.rest.manager.pojos.Adapter;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+@Service
+public final class AdaptersDeployer implements PerformanceManagementAdaptersDeployer, AutoCloseable {
+
+    private static final Logger LOG = LoggerFactory.getLogger(AdaptersDeployer.class);
+
+    private final PerformanceManagementRestAgentFactory pmRestAgentFactory;
+    private final Map<String, PerformanceManagementRestAgent> adapters = new ConcurrentHashMap<>();
+
+    @Autowired
+    public AdaptersDeployer(final PerformanceManagementRestAgentFactory pmRestAgentFactory) {
+        this.pmRestAgentFactory = pmRestAgentFactory;
+    }
+
+    @Override
+    public synchronized void create(final String hostIpAddress, final String username, final String password)
+            throws AlreadyPresentException {
+        LOG.info("Create device PM adapter {}", hostIpAddress);
+        if (adapters.get(hostIpAddress) != null) {
+            throw new AlreadyPresentException(hostIpAddress);
+        }
+        final Adapter adapter =
+                Adapter.builder().username(username).password(password).hostIpAddress(hostIpAddress).build();
+        final PerformanceManagementRestAgent pmRestAgent =
+                pmRestAgentFactory.createPerformanceManagementRestAgent(adapter).blockingGet();
+        pmRestAgent.init();
+        adapters.put(hostIpAddress, pmRestAgent);
+    }
+
+    @Override
+    public synchronized void delete(final String host) throws NotFoundException {
+        LOG.info("Adapter PM adapter removed {}", requireNonNull(host));
+        final PerformanceManagementRestAgent adapter = adapters.remove(host);
+        if (adapter == null) {
+            throw new NotFoundException(host);
+        }
+        adapter.close();
+    }
+
+    @Override
+    public List<String> getAll() {
+        return ImmutableList.copyOf(adapters.keySet());
+    }
+
+    @Override
+    public ZoneId getTimeZone(final String host) {
+        LOG.debug("Read time zone for {}", host);
+        return Optional.ofNullable(adapters.get(host)).map(
+                PerformanceManagementRestAgent::getTimeZone).orElse(null);
+    }
+
+    @Override
+    public synchronized void close() {
+        for (final String host : ImmutableList.copyOf(adapters.keySet())) {
+            try {
+                delete(host);
+            } catch (final Exception e) {
+                LOG.warn("Failed to delete device PM adapter {}", host);
+            }
+        }
+        adapters.clear();
+    }
+}
diff --git a/ves-nf-oam-adopter/ves-nf-oam-adopter-pm-manager/src/main/java/org/o/ran/oam/nf/oam/adopter/pm/rest/manager/PerformanceManagementMapperConfigProvider.java b/ves-nf-oam-adopter/ves-nf-oam-adopter-pm-manager/src/main/java/org/o/ran/oam/nf/oam/adopter/pm/rest/manager/PerformanceManagementMapperConfigProvider.java
new file mode 100644 (file)
index 0000000..b7c24f8
--- /dev/null
@@ -0,0 +1,85 @@
+/*
+ *  ============LICENSE_START=======================================================
+ *  O-RAN-SC
+ *  ================================================================================
+ *  Copyright © 2021 AT&T Intellectual Property. All rights reserved.
+ *  ================================================================================
+ *  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.
+ *  ============LICENSE_END=========================================================
+ */
+
+package org.o.ran.oam.nf.oam.adopter.pm.rest.manager;
+
+import static java.util.Objects.requireNonNull;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
+import java.io.IOException;
+import java.io.StringWriter;
+import java.net.URI;
+import java.nio.file.Paths;
+import javax.annotation.PostConstruct;
+import org.apache.commons.configuration2.YAMLConfiguration;
+import org.apache.commons.configuration2.builder.ConfigurationBuilderEvent;
+import org.apache.commons.configuration2.builder.ReloadingFileBasedConfigurationBuilder;
+import org.apache.commons.configuration2.builder.fluent.Parameters;
+import org.apache.commons.configuration2.event.EventListener;
+import org.apache.commons.configuration2.ex.ConfigurationException;
+import org.o.ran.oam.nf.oam.adopter.pm.rest.manager.pojos.VesMappingConfiguration;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Service;
+
+@Service
+public class PerformanceManagementMapperConfigProvider  {
+
+    private static final Logger LOG = LoggerFactory.getLogger(PerformanceManagementMapperConfigProvider.class);
+
+    private static final ObjectMapper YAML_READER = new ObjectMapper(new YAMLFactory());
+    @Value("${pm-rest-manager.mapping-config-path:#{null}}")
+    private String mappingFilePath;
+    private ReloadingFileBasedConfigurationBuilder<YAMLConfiguration> builder;
+
+    @Autowired
+    public PerformanceManagementMapperConfigProvider() {
+
+    }
+
+    /**
+     * Initialize Service.
+     */
+    @PostConstruct
+    public void init() throws IOException, ConfigurationException {
+        requireNonNull(mappingFilePath);
+        final URI filePath = Paths.get(mappingFilePath).toUri();
+        builder = new ReloadingFileBasedConfigurationBuilder<>(YAMLConfiguration.class)
+                          .configure(new Parameters().hierarchical().setURL(filePath.toURL()));
+        builder.addEventListener(ConfigurationBuilderEvent.CONFIGURATION_REQUEST, (EventListener) event -> {
+            builder.getReloadingController().checkForReloading(null);
+            LOG.debug("Reloading {}", filePath.toString());
+        });
+        //Test initial configuration
+        builder.getConfiguration();
+    }
+
+    /**
+     * Provide VES Mapping configuration.
+     */
+    public VesMappingConfiguration getVesMappingConfiguration() throws ConfigurationException, IOException {
+        final YAMLConfiguration configuration = builder.getConfiguration();
+        final StringWriter output = new StringWriter();
+        configuration.write(output);
+        return YAML_READER.readValue(output.toString(), VesMappingConfiguration.class);
+    }
+}
diff --git a/ves-nf-oam-adopter/ves-nf-oam-adopter-pm-manager/src/main/java/org/o/ran/oam/nf/oam/adopter/pm/rest/manager/PerformanceManagementRestAgent.java b/ves-nf-oam-adopter/ves-nf-oam-adopter-pm-manager/src/main/java/org/o/ran/oam/nf/oam/adopter/pm/rest/manager/PerformanceManagementRestAgent.java
new file mode 100644 (file)
index 0000000..66693fc
--- /dev/null
@@ -0,0 +1,80 @@
+/*
+ *  ============LICENSE_START=======================================================
+ *  O-RAN-SC
+ *  ================================================================================
+ *  Copyright © 2021 AT&T Intellectual Property. All rights reserved.
+ *  ================================================================================
+ *  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.
+ *  ============LICENSE_END=========================================================
+ */
+
+package org.o.ran.oam.nf.oam.adopter.pm.rest.manager;
+
+import java.time.Duration;
+import java.time.LocalTime;
+import java.time.ZoneId;
+import java.time.ZonedDateTime;
+import java.time.format.DateTimeFormatter;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+
+public final class PerformanceManagementRestAgent implements AutoCloseable {
+
+    private static final DateTimeFormatter TIME_INPUT_FORMAT = DateTimeFormatter.ofPattern("HH:mm:ss");
+    private final ScheduledExecutorService scheduler;
+    private final Runnable pmAgent;
+    private final LocalTime synchronizationTimeStart;
+    private final int synchronizationTimeFrequency;
+    private final ZoneId zoneId;
+
+
+    PerformanceManagementRestAgent(final Runnable pmAgent, final String synchronizationTimeStart,
+            final int synchronizationTimeFrequency, final ZoneId zoneId) {
+        this.scheduler = Executors.newSingleThreadScheduledExecutor();
+        this.pmAgent = pmAgent;
+        this.synchronizationTimeStart = LocalTime.parse(synchronizationTimeStart, TIME_INPUT_FORMAT);
+        this.synchronizationTimeFrequency = synchronizationTimeFrequency;
+        this.zoneId = zoneId;
+    }
+
+    /**
+     * Initialize service at fixed rate.
+     */
+    public void init() {
+        final long initialDelay = initialDelay();
+        scheduler.scheduleAtFixedRate(pmAgent, initialDelay, synchronizationTimeFrequency, TimeUnit.SECONDS);
+    }
+
+    private long initialDelay() {
+        final ZonedDateTime now = ZonedDateTime.now(zoneId);
+
+        ZonedDateTime nextRun = now
+                .withHour(synchronizationTimeStart.getHour())
+                .withMinute(synchronizationTimeStart.getMinute())
+                .withSecond(synchronizationTimeStart.getSecond());
+        if (now.compareTo(nextRun) > 0) {
+            nextRun = nextRun.plusSeconds(synchronizationTimeFrequency);
+        }
+        final Duration duration = Duration.between(now, nextRun);
+        return duration.getSeconds();
+    }
+
+    public ZoneId getTimeZone() {
+        return zoneId;
+    }
+
+    @Override
+    public void close() {
+        scheduler.shutdown();
+    }
+}
diff --git a/ves-nf-oam-adopter/ves-nf-oam-adopter-pm-manager/src/main/java/org/o/ran/oam/nf/oam/adopter/pm/rest/manager/PerformanceManagementRestAgentFactory.java b/ves-nf-oam-adopter/ves-nf-oam-adopter-pm-manager/src/main/java/org/o/ran/oam/nf/oam/adopter/pm/rest/manager/PerformanceManagementRestAgentFactory.java
new file mode 100644 (file)
index 0000000..0ebaa6c
--- /dev/null
@@ -0,0 +1,97 @@
+/*
+ *  ============LICENSE_START=======================================================
+ *  O-RAN-SC
+ *  ================================================================================
+ *  Copyright © 2021 AT&T Intellectual Property. All rights reserved.
+ *  ================================================================================
+ *  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.
+ *  ============LICENSE_END=========================================================
+ */
+
+package org.o.ran.oam.nf.oam.adopter.pm.rest.manager;
+
+import io.reactivex.rxjava3.core.Observable;
+import io.reactivex.rxjava3.core.Single;
+import io.reactivex.rxjava3.schedulers.Schedulers;
+import org.o.ran.oam.nf.oam.adopter.api.VesEventNotifier;
+import org.o.ran.oam.nf.oam.adopter.pm.rest.manager.api.HttpRestClient;
+import org.o.ran.oam.nf.oam.adopter.pm.rest.manager.mapper.PerformanceManagementFile2VesMapper;
+import org.o.ran.oam.nf.oam.adopter.pm.rest.manager.pojos.Adapter;
+import org.o.ran.oam.nf.oam.adopter.pm.rest.manager.properties.PerformanceManagementManagerProperties;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class PerformanceManagementRestAgentFactory {
+    private static final Logger LOG = LoggerFactory.getLogger(PerformanceManagementRestAgentFactory.class);
+
+    private final VesEventNotifier eventListener;
+    private final PerformanceManagementManagerProperties properties;
+    private final PerformanceManagementFile2VesMapper pmFileMapper;
+    private final HttpRestClient httpRestClient;
+
+    /**
+     * Default constructor.
+     */
+    public PerformanceManagementRestAgentFactory(final VesEventNotifier eventListener,
+            final PerformanceManagementFile2VesMapper pmFileMapper,
+            final PerformanceManagementManagerProperties properties, final HttpRestClient httpRestClient) {
+        this.eventListener = eventListener;
+        this.pmFileMapper = pmFileMapper;
+        this.properties = properties;
+        this.httpRestClient = httpRestClient;
+    }
+
+    /**
+     * Generates new PM Agent which will get pm files via rest at specific time each day and
+     * send it as CommonEventFormat302ONAP event via rest.
+     * @param adapter IP address fo the adapter, adapter login username, adapter login password
+     * @return PMRestAgent
+     */
+    public final Single<PerformanceManagementRestAgent> createPerformanceManagementRestAgent(final Adapter adapter) {
+        return httpRestClient.getTimeZone(adapter).map(timeZone -> {
+            final PerformanceManagementAgentRunnable pmAgentRunnable =
+                    new PerformanceManagementAgentRunnable(httpRestClient, eventListener, pmFileMapper, adapter);
+            return new PerformanceManagementRestAgent(pmAgentRunnable, properties.getSynchronizationTimeStart(),
+                    properties.getSynchronizationTimeFrequency(), timeZone);
+        });
+    }
+
+    private static class PerformanceManagementAgentRunnable implements Runnable {
+        final HttpRestClient httpClient;
+        private final VesEventNotifier pmEventListener;
+        private final PerformanceManagementFile2VesMapper pmFileMapper;
+        private final Adapter adapter;
+
+        public PerformanceManagementAgentRunnable(final HttpRestClient httpClient,
+                final VesEventNotifier pmEventListener,
+                final PerformanceManagementFile2VesMapper pmFileMapper, final Adapter adapter) {
+            this.httpClient = httpClient;
+            this.pmEventListener = pmEventListener;
+            this.pmFileMapper = pmFileMapper;
+            this.adapter = adapter;
+        }
+
+        @Override
+        public synchronized void run() {
+            final String hostIp = adapter.getHostIpAddress();
+            httpClient.readFiles(adapter)
+                    .flatMap(zip -> pmFileMapper.map(zip, hostIp))
+                    .flatMapCompletable(events -> Observable.fromIterable(events)
+                            .concatMapCompletable(pmEventListener::notifyEvents))
+                    .doOnSubscribe(result -> LOG.info("PM VES notification forwarding for adapter {} started", hostIp))
+                    .doOnComplete(() -> LOG.info("PM VES notification forwarding for adapter {} finished", hostIp))
+                    .doOnError(error -> LOG.warn("PM VES notification forwarding for adapter {} failed", hostIp))
+                    .subscribeOn(Schedulers.single())
+                    .subscribe();
+        }
+    }
+}
diff --git a/ves-nf-oam-adopter/ves-nf-oam-adopter-pm-manager/src/main/java/org/o/ran/oam/nf/oam/adopter/pm/rest/manager/api/HttpRestClient.java b/ves-nf-oam-adopter/ves-nf-oam-adopter-pm-manager/src/main/java/org/o/ran/oam/nf/oam/adopter/pm/rest/manager/api/HttpRestClient.java
new file mode 100644 (file)
index 0000000..71a27ea
--- /dev/null
@@ -0,0 +1,13 @@
+package org.o.ran.oam.nf.oam.adopter.pm.rest.manager.api;
+
+import io.reactivex.rxjava3.core.Single;
+import java.time.ZoneId;
+import java.util.zip.ZipInputStream;
+import org.eclipse.jdt.annotation.NonNull;
+import org.o.ran.oam.nf.oam.adopter.pm.rest.manager.pojos.Adapter;
+
+public interface HttpRestClient {
+    @NonNull Single<ZipInputStream> readFiles(@NonNull Adapter adapter);
+
+    @NonNull Single<ZoneId> getTimeZone(@NonNull Adapter adapter);
+}
diff --git a/ves-nf-oam-adopter/ves-nf-oam-adopter-pm-manager/src/main/java/org/o/ran/oam/nf/oam/adopter/pm/rest/manager/api/PerformanceManagementAdaptersDeployer.java b/ves-nf-oam-adopter/ves-nf-oam-adopter-pm-manager/src/main/java/org/o/ran/oam/nf/oam/adopter/pm/rest/manager/api/PerformanceManagementAdaptersDeployer.java
new file mode 100644 (file)
index 0000000..01be898
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ *  ============LICENSE_START=======================================================
+ *  O-RAN-SC
+ *  ================================================================================
+ *  Copyright © 2021 AT&T Intellectual Property. All rights reserved.
+ *  ================================================================================
+ *  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.
+ *  ============LICENSE_END=========================================================
+ */
+
+package org.o.ran.oam.nf.oam.adopter.pm.rest.manager.api;
+
+import java.time.ZoneId;
+import java.util.List;
+import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.jdt.annotation.Nullable;
+import org.o.ran.oam.nf.oam.adopter.pm.rest.manager.exceptions.AlreadyPresentException;
+import org.o.ran.oam.nf.oam.adopter.pm.rest.manager.exceptions.NotFoundException;
+
+public interface PerformanceManagementAdaptersDeployer {
+
+    /**
+     * Creates PM Adapter.
+     *
+     * @param hostIpAddress adapter ip address
+     * @param username mechid username
+     * @param password mechid password
+     * @throws AlreadyPresentException if already present
+     */
+    void create(@NonNull String hostIpAddress, @NonNull String username, @NonNull String password)
+            throws AlreadyPresentException;
+
+    /**
+     * Removes PM Adapter by host ip address.
+     *
+     * @param host ip address
+     * @throws NotFoundException if not present
+     */
+    void delete(@NonNull String host) throws NotFoundException;
+
+    /**
+     * Returns list of Adapters host Ip.
+     */
+    @NonNull List<String> getAll();
+
+    /**
+     * Returns time zone of specific device.
+     */
+    @Nullable ZoneId getTimeZone(@NonNull String host);
+}
diff --git a/ves-nf-oam-adopter/ves-nf-oam-adopter-pm-manager/src/main/java/org/o/ran/oam/nf/oam/adopter/pm/rest/manager/configurations/PerformanceManagementRestManagerConfig.java b/ves-nf-oam-adopter/ves-nf-oam-adopter-pm-manager/src/main/java/org/o/ran/oam/nf/oam/adopter/pm/rest/manager/configurations/PerformanceManagementRestManagerConfig.java
new file mode 100644 (file)
index 0000000..0a88e80
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ *  ============LICENSE_START=======================================================
+ *  O-RAN-SC
+ *  ================================================================================
+ *  Copyright © 2021 AT&T Intellectual Property. All rights reserved.
+ *  ================================================================================
+ *  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.
+ *  ============LICENSE_END=========================================================
+ */
+
+package org.o.ran.oam.nf.oam.adopter.pm.rest.manager.configurations;
+
+import org.o.ran.oam.nf.oam.adopter.api.VesEventNotifier;
+import org.o.ran.oam.nf.oam.adopter.pm.rest.manager.PerformanceManagementRestAgentFactory;
+import org.o.ran.oam.nf.oam.adopter.pm.rest.manager.api.HttpRestClient;
+import org.o.ran.oam.nf.oam.adopter.pm.rest.manager.mapper.PerformanceManagementFile2VesMapper;
+import org.o.ran.oam.nf.oam.adopter.pm.rest.manager.properties.PerformanceManagementManagerProperties;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+@EnableConfigurationProperties
+public class PerformanceManagementRestManagerConfig {
+    private final PerformanceManagementManagerProperties pmManagerProperties;
+    private final VesEventNotifier eventListener;
+    private final PerformanceManagementFile2VesMapper pmFileMapper;
+
+    /**
+     * Default constructor.
+     */
+    @Autowired
+    public PerformanceManagementRestManagerConfig(final VesEventNotifier eventListener,
+            final PerformanceManagementFile2VesMapper pmFileMapper,
+            final PerformanceManagementManagerProperties pmManagerProperties) {
+        this.eventListener = eventListener;
+        this.pmFileMapper = pmFileMapper;
+        this.pmManagerProperties = pmManagerProperties;
+    }
+
+    @Bean
+    PerformanceManagementRestAgentFactory getPerformanceManagementRestManagerFactoryService(
+            final HttpRestClient httpRestClient) {
+        return new PerformanceManagementRestAgentFactory(eventListener, pmFileMapper, pmManagerProperties,
+                httpRestClient);
+    }
+}
diff --git a/ves-nf-oam-adopter/ves-nf-oam-adopter-pm-manager/src/main/java/org/o/ran/oam/nf/oam/adopter/pm/rest/manager/exceptions/AlreadyPresentException.java b/ves-nf-oam-adopter/ves-nf-oam-adopter-pm-manager/src/main/java/org/o/ran/oam/nf/oam/adopter/pm/rest/manager/exceptions/AlreadyPresentException.java
new file mode 100644 (file)
index 0000000..9199daa
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ *  ============LICENSE_START=======================================================
+ *  O-RAN-SC
+ *  ================================================================================
+ *  Copyright © 2021 AT&T Intellectual Property. All rights reserved.
+ *  ================================================================================
+ *  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.
+ *  ============LICENSE_END=========================================================
+ */
+
+package org.o.ran.oam.nf.oam.adopter.pm.rest.manager.exceptions;
+
+public class AlreadyPresentException extends PerformanceManagementException {
+    private static final long serialVersionUID = -1852996415384288431L;
+
+    public AlreadyPresentException(final String adapter) {
+        super("Adapter " + adapter + " already present.");
+    }
+}
diff --git a/ves-nf-oam-adopter/ves-nf-oam-adopter-pm-manager/src/main/java/org/o/ran/oam/nf/oam/adopter/pm/rest/manager/exceptions/NotFoundException.java b/ves-nf-oam-adopter/ves-nf-oam-adopter-pm-manager/src/main/java/org/o/ran/oam/nf/oam/adopter/pm/rest/manager/exceptions/NotFoundException.java
new file mode 100644 (file)
index 0000000..4179fb9
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ *  ============LICENSE_START=======================================================
+ *  O-RAN-SC
+ *  ================================================================================
+ *  Copyright © 2021 AT&T Intellectual Property. All rights reserved.
+ *  ================================================================================
+ *  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.
+ *  ============LICENSE_END=========================================================
+ */
+
+package org.o.ran.oam.nf.oam.adopter.pm.rest.manager.exceptions;
+
+public class NotFoundException extends PerformanceManagementException {
+    private static final long serialVersionUID = -1852996415384288431L;
+
+    public NotFoundException(final String adapter) {
+        super("Adapter " + adapter + " is not present.");
+    }
+}
diff --git a/ves-nf-oam-adopter/ves-nf-oam-adopter-pm-manager/src/main/java/org/o/ran/oam/nf/oam/adopter/pm/rest/manager/exceptions/PerformanceManagementEmptyOutputException.java b/ves-nf-oam-adopter/ves-nf-oam-adopter-pm-manager/src/main/java/org/o/ran/oam/nf/oam/adopter/pm/rest/manager/exceptions/PerformanceManagementEmptyOutputException.java
new file mode 100644 (file)
index 0000000..492e13c
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ *  ============LICENSE_START=======================================================
+ *  O-RAN-SC
+ *  ================================================================================
+ *  Copyright © 2021 AT&T Intellectual Property. All rights reserved.
+ *  ================================================================================
+ *  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.
+ *  ============LICENSE_END=========================================================
+ */
+
+package org.o.ran.oam.nf.oam.adopter.pm.rest.manager.exceptions;
+
+/**
+ * Object already exists exception.
+ */
+public class PerformanceManagementEmptyOutputException extends PerformanceManagementException {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * Create object already exists exception.
+     *
+     * @param message exception message
+     */
+    public PerformanceManagementEmptyOutputException(final String message) {
+        super(message);
+    }
+}
diff --git a/ves-nf-oam-adopter/ves-nf-oam-adopter-pm-manager/src/main/java/org/o/ran/oam/nf/oam/adopter/pm/rest/manager/exceptions/PerformanceManagementException.java b/ves-nf-oam-adopter/ves-nf-oam-adopter-pm-manager/src/main/java/org/o/ran/oam/nf/oam/adopter/pm/rest/manager/exceptions/PerformanceManagementException.java
new file mode 100644 (file)
index 0000000..f39dac8
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ *  ============LICENSE_START=======================================================
+ *  O-RAN-SC
+ *  ================================================================================
+ *  Copyright © 2021 AT&T Intellectual Property. All rights reserved.
+ *  ================================================================================
+ *  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.
+ *  ============LICENSE_END=========================================================
+ */
+
+package org.o.ran.oam.nf.oam.adopter.pm.rest.manager.exceptions;
+
+/**
+ * Object already exists exception.
+ */
+public class PerformanceManagementException extends RuntimeException {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * Create object already exists exception.
+     *
+     * @param message exception message
+     */
+    public PerformanceManagementException(final String message) {
+        super(message);
+    }
+
+    public PerformanceManagementException(final String message, final Throwable cause) {
+        super(message, cause);
+    }
+}
diff --git a/ves-nf-oam-adopter/ves-nf-oam-adopter-pm-manager/src/main/java/org/o/ran/oam/nf/oam/adopter/pm/rest/manager/exceptions/TokenGenerationException.java b/ves-nf-oam-adopter/ves-nf-oam-adopter-pm-manager/src/main/java/org/o/ran/oam/nf/oam/adopter/pm/rest/manager/exceptions/TokenGenerationException.java
new file mode 100644 (file)
index 0000000..6441e98
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ *  ============LICENSE_START=======================================================
+ *  O-RAN-SC
+ *  ================================================================================
+ *  Copyright © 2021 AT&T Intellectual Property. All rights reserved.
+ *  ================================================================================
+ *  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.
+ *  ============LICENSE_END=========================================================
+ */
+
+package org.o.ran.oam.nf.oam.adopter.pm.rest.manager.exceptions;
+
+/**
+ * Object already exists exception.
+ */
+public class TokenGenerationException extends PerformanceManagementException {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * Create object already exists exception.
+     *
+     * @param message exception message
+     */
+    public TokenGenerationException(final String message) {
+        super(message);
+    }
+
+}
diff --git a/ves-nf-oam-adopter/ves-nf-oam-adopter-pm-manager/src/main/java/org/o/ran/oam/nf/oam/adopter/pm/rest/manager/exceptions/ZoneIdException.java b/ves-nf-oam-adopter/ves-nf-oam-adopter-pm-manager/src/main/java/org/o/ran/oam/nf/oam/adopter/pm/rest/manager/exceptions/ZoneIdException.java
new file mode 100644 (file)
index 0000000..4552533
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ *  ============LICENSE_START=======================================================
+ *  O-RAN-SC
+ *  ================================================================================
+ *  Copyright © 2021 AT&T Intellectual Property. All rights reserved.
+ *  ================================================================================
+ *  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.
+ *  ============LICENSE_END=========================================================
+ */
+
+package org.o.ran.oam.nf.oam.adopter.pm.rest.manager.exceptions;
+
+/**
+ * Object already exists exception.
+ */
+public class ZoneIdException extends PerformanceManagementException {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * Create object already exists exception.
+     *
+     * @param message exception message
+     */
+    public ZoneIdException(final String message, final Throwable cause) {
+        super(message, cause);
+    }
+
+}
diff --git a/ves-nf-oam-adopter/ves-nf-oam-adopter-pm-manager/src/main/java/org/o/ran/oam/nf/oam/adopter/pm/rest/manager/mapper/CommonEventHeaderHandler.java b/ves-nf-oam-adopter/ves-nf-oam-adopter-pm-manager/src/main/java/org/o/ran/oam/nf/oam/adopter/pm/rest/manager/mapper/CommonEventHeaderHandler.java
new file mode 100644 (file)
index 0000000..7049285
--- /dev/null
@@ -0,0 +1,83 @@
+/*
+ *  ============LICENSE_START=======================================================
+ *  O-RAN-SC
+ *  ================================================================================
+ *  Copyright © 2021 AT&T Intellectual Property. All rights reserved.
+ *  ================================================================================
+ *  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.
+ *  ============LICENSE_END=========================================================
+ */
+
+package org.o.ran.oam.nf.oam.adopter.pm.rest.manager.mapper;
+
+import java.nio.charset.StandardCharsets;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.UUID;
+import java.util.stream.Collectors;
+import lombok.AccessLevel;
+import lombok.NoArgsConstructor;
+import org.o.ran.oam.nf.oam.adopter.api.CommonEventHeader;
+import org.o.ran.oam.nf.oam.adopter.pm.rest.manager.pojos.CsvConfiguration;
+import org.o.ran.oam.nf.oam.adopter.pm.rest.manager.pojos.VesMappingConfiguration;
+
+@NoArgsConstructor(access = AccessLevel.PRIVATE)
+final class CommonEventHeaderHandler {
+    private static final String PM_NOTIFICATIONS = "PM_Notification";
+
+    static CommonEventHeader toCommonEventHeader(final VesMappingConfiguration config, final String hostIp,
+            final CsvConfiguration csv, final Map<String, String> record, final int sequence) {
+        final CommonEventHeader header = new CommonEventHeader();
+        setMandatoryFields(config, hostIp, csv, header, record, sequence);
+        setOptionalFields(config, header);
+        return header;
+    }
+
+    private static void setOptionalFields(final VesMappingConfiguration config, final CommonEventHeader header) {
+        header.setNfVendorName(Optional.ofNullable(config.getNfVendorName()).orElse(null));
+        header.setReportingEntityId(config.getReportingEntityId());
+        header.setNfNamingCode(null); //NOP
+        header.setNfcNamingCode(null); //NOP
+        header.setTimeZoneOffset(null); //NOP
+    }
+
+    private static void setMandatoryFields(final VesMappingConfiguration config, final String hostIp,
+            final CsvConfiguration csv, final CommonEventHeader header, final Map<String, String> record,
+            final int sequence) {
+        header.setDomain(CommonEventHeader.Domain.MEASUREMENT);
+        header.setEventName(CommonEventHeader.Domain.FAULT.name()
+                + "_" + config.getReportingEntityName()
+                + "_" + Optional.ofNullable(config.getEventName()).orElse(PM_NOTIFICATIONS));
+        header.setStartEpochMicrosec(System.currentTimeMillis());
+        header.setLastEpochMicrosec(System.currentTimeMillis());
+        header.setPriority(CommonEventHeader.Priority.fromValue(config.getPriority()));
+        header.setReportingEntityName(config.getReportingEntityName());
+        header.setSequence((long) sequence);
+        final String sourceNameField = csv.getSourceName();
+        final String sourceNameRecordValue = Optional.ofNullable(sourceNameField).map(record::get).orElse(hostIp);
+        final Optional<String> optRegex = Optional.ofNullable(csv.getSourceNameRegex());
+        header.setSourceName(optRegex.map(regex -> sourceNameRecordValue.replaceAll(regex, ""))
+            .orElse(sourceNameRecordValue));
+        header.setVersion(CommonEventHeader.Version._4_0);
+        header.setVesEventListenerVersion(Optional.ofNullable(config.getVesEventListenerVersion())
+                .map(CommonEventHeader.VesEventListenerVersion::fromValue)
+                .orElse(CommonEventHeader.VesEventListenerVersion._7_1));
+
+        final List<String> eventId = csv.getEventId();
+        final String keyIdConcat =  eventId.stream()
+                .filter(record::containsKey)
+                .map(record::get)
+                .collect(Collectors.joining());
+        header.setEventId(UUID.nameUUIDFromBytes(keyIdConcat.getBytes(StandardCharsets.UTF_8)).toString());
+    }
+}
diff --git a/ves-nf-oam-adopter/ves-nf-oam-adopter-pm-manager/src/main/java/org/o/ran/oam/nf/oam/adopter/pm/rest/manager/mapper/MeasurementFieldsHandler.java b/ves-nf-oam-adopter/ves-nf-oam-adopter-pm-manager/src/main/java/org/o/ran/oam/nf/oam/adopter/pm/rest/manager/mapper/MeasurementFieldsHandler.java
new file mode 100644 (file)
index 0000000..166af50
--- /dev/null
@@ -0,0 +1,82 @@
+/*
+ *  ============LICENSE_START=======================================================
+ *  O-RAN-SC
+ *  ================================================================================
+ *  Copyright © 2021 AT&T Intellectual Property. All rights reserved.
+ *  ================================================================================
+ *  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.
+ *  ============LICENSE_END=========================================================
+ */
+
+package org.o.ran.oam.nf.oam.adopter.pm.rest.manager.mapper;
+
+import java.util.Collections;
+import java.util.Map;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+import lombok.AccessLevel;
+import lombok.NoArgsConstructor;
+import org.o.ran.oam.nf.oam.adopter.api.MeasurementFields;
+import org.o.ran.oam.nf.oam.adopter.api.NamedHashMap;
+import org.o.ran.oam.nf.oam.adopter.pm.rest.manager.pojos.CsvConfiguration;
+import org.o.ran.oam.nf.oam.adopter.pm.rest.manager.pojos.VesMappingConfiguration;
+
+@NoArgsConstructor(access = AccessLevel.PRIVATE)
+final class MeasurementFieldsHandler {
+    private static void setOptionalsFields(final MeasurementFields measurementFields, final Map<String, String> records,
+            final VesMappingConfiguration config) {
+        final CsvConfiguration csv = config.getCsv();
+        measurementFields.setAdditionalFields(csv.getAdditionalFields()
+                .stream().filter(records::containsKey)
+                .collect(Collectors.toMap(Function.identity(), records::get)));
+
+        final NamedHashMap namedHashMap = new NamedHashMap();
+        namedHashMap.setName(csv.getAdditionalMeasurementsName());
+        namedHashMap.setHashMap(csv.getAdditionalMeasurements().stream()
+                .filter(records::containsKey)
+                .collect(Collectors.toMap(Function.identity(), records::get)));
+        measurementFields.setAdditionalMeasurements(Collections.singletonList(namedHashMap));
+        measurementFields.setAdditionalObjects(null);
+        measurementFields.setCodecUsageArray(null);
+        measurementFields.setConfiguredEntities(null);
+        measurementFields.setCpuUsageArray(null);
+        measurementFields.setDiskUsageArray(null);
+        measurementFields.setFeatureUsageArray(null);
+        measurementFields.setFilesystemUsageArray(null);
+        measurementFields.setHugePagesArray(null);
+        measurementFields.setIpmi(null);
+        measurementFields.setLatencyDistribution(null);
+        measurementFields.setLoadArray(null);
+        measurementFields.setMachineCheckExceptionArray(null);
+        measurementFields.setMeanRequestLatency(null);
+        measurementFields.setMemoryUsageArray(null);
+        measurementFields.setNfcScalingMetric(null);
+        measurementFields.setNicPerformanceArray(null);
+        measurementFields.setNumberOfMediaPortsInUse(null);
+        measurementFields.setProcessStatsArray(null);
+        measurementFields.setRequestRate(null);
+    }
+
+    static MeasurementFields toMeasurementFields(final VesMappingConfiguration config,
+            final Map<String, String> records) {
+        final MeasurementFields measurementFields = new MeasurementFields();
+        setMandatoryFields(measurementFields, config);
+        setOptionalsFields(measurementFields, records, config);
+        return measurementFields;
+    }
+
+    private static void setMandatoryFields(final MeasurementFields measurementFields,
+            final VesMappingConfiguration config) {
+        measurementFields.setMeasurementFieldsVersion(MeasurementFields.MeasurementFieldsVersion._4_0);
+        measurementFields.setMeasurementInterval(config.getMeasurementInterval());
+    }
+}
diff --git a/ves-nf-oam-adopter/ves-nf-oam-adopter-pm-manager/src/main/java/org/o/ran/oam/nf/oam/adopter/pm/rest/manager/mapper/PerformanceManagementFile2VesMapper.java b/ves-nf-oam-adopter/ves-nf-oam-adopter-pm-manager/src/main/java/org/o/ran/oam/nf/oam/adopter/pm/rest/manager/mapper/PerformanceManagementFile2VesMapper.java
new file mode 100644 (file)
index 0000000..6036a93
--- /dev/null
@@ -0,0 +1,127 @@
+/*
+ *  ============LICENSE_START=======================================================
+ *  O-RAN-SC
+ *  ================================================================================
+ *  Copyright © 2021 AT&T Intellectual Property. All rights reserved.
+ *  ================================================================================
+ *  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.
+ *  ============LICENSE_END=========================================================
+ */
+
+package org.o.ran.oam.nf.oam.adopter.pm.rest.manager.mapper;
+
+import com.fasterxml.jackson.core.JsonParser;
+import com.fasterxml.jackson.dataformat.csv.CsvMapper;
+import com.fasterxml.jackson.dataformat.csv.CsvSchema;
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
+import io.reactivex.rxjava3.core.Single;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipInputStream;
+import org.o.ran.oam.nf.oam.adopter.api.CommonEventFormat302ONAP;
+import org.o.ran.oam.nf.oam.adopter.api.Event;
+import org.o.ran.oam.nf.oam.adopter.pm.rest.manager.PerformanceManagementMapperConfigProvider;
+import org.o.ran.oam.nf.oam.adopter.pm.rest.manager.pojos.CsvConfiguration;
+import org.o.ran.oam.nf.oam.adopter.pm.rest.manager.pojos.VesMappingConfiguration;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+@Service
+public class PerformanceManagementFile2VesMapper {
+    private static final Logger LOG = LoggerFactory.getLogger(PerformanceManagementFile2VesMapper.class);
+
+    private static final String CSV_EXTENSION = ".csv";
+    private final PerformanceManagementMapperConfigProvider pmConfigProvider;
+
+    @Autowired
+    public PerformanceManagementFile2VesMapper(final PerformanceManagementMapperConfigProvider pmConfigProvider) {
+        this.pmConfigProvider = pmConfigProvider;
+    }
+
+    /**
+     * Translate CSV in ZipInputStream format to list of CommonEventFormat302ONAP events.
+     *
+     * @param zipInputStream csv
+     * @param hostIp source Ip Address
+     * @return CommonEventFormat302ONAP events
+     */
+    @SuppressFBWarnings("REC_CATCH_EXCEPTION")
+    public Single<List<CommonEventFormat302ONAP>> map(final ZipInputStream zipInputStream, final String hostIp) {
+        LOG.info("Converting ZIP files to VES Message started");
+        final List<CommonEventFormat302ONAP> listOfNotifications = new ArrayList<>();
+        final CsvSchema schema = CsvSchema.emptySchema().withHeader();
+        final CsvMapper mapper = new CsvMapper();
+        mapper.configure(JsonParser.Feature.AUTO_CLOSE_SOURCE, false);
+        try {
+            ZipEntry entry;
+            final VesMappingConfiguration mappingConfiguration = pmConfigProvider.getVesMappingConfiguration();
+            while ((entry = zipInputStream.getNextEntry()) != null) {
+                final String entryName = entry.getName();
+                if (!entryName.endsWith(CSV_EXTENSION)) {
+                    return Single.error(new Exception("Wrong file type :" + entryName));
+                }
+
+                final Iterator<Map<String, String>> iterator =
+                        mapper.readerFor(Map.class).with(schema).readValues(zipInputStream);
+                final List<List<Event>> mappedEvents = toEvent(mappingConfiguration, hostIp, iterator);
+
+                mappedEvents.forEach(mapped -> {
+                    final CommonEventFormat302ONAP eventFormat = new CommonEventFormat302ONAP();
+                    eventFormat.setEventList(mapped);
+                    listOfNotifications.add(eventFormat);
+                });
+            }
+        } catch (final Exception e) {
+            return Single.error(new Exception("Failed to process file", e));
+        } finally {
+            try {
+                zipInputStream.closeEntry();
+            } catch (final IOException e) {
+                LOG.warn("Failed to close zip stream", e);
+            }
+        }
+        LOG.info("Converting ZIP files to VES Message finished");
+        return Single.just(listOfNotifications);
+    }
+
+    private static List<List<Event>> toEvent(final VesMappingConfiguration mappingConfiguration, final String hostIp,
+            final Iterator<Map<String, String>> iterator) {
+        final List<List<Event>> globalList = new ArrayList<>();
+        final int batchSize = mappingConfiguration.getBatchSize();
+        int sequence = 0;
+        List<Event> events = new ArrayList<>();
+        final CsvConfiguration csv = mappingConfiguration.getCsv();
+        while (iterator.hasNext()) {
+            final Event event = new Event();
+            final Map<String, String> record = iterator.next();
+            event.setCommonEventHeader(
+                    CommonEventHeaderHandler.toCommonEventHeader(mappingConfiguration, hostIp, csv, record, sequence));
+            event.setMeasurementFields(MeasurementFieldsHandler.toMeasurementFields(mappingConfiguration, record));
+            events.add(event);
+            sequence++;
+            if (sequence % batchSize == 0) {
+                globalList.add(events);
+                events = new ArrayList<>();
+            }
+        }
+        if (!events.isEmpty()) {
+            globalList.add(events);
+        }
+        return globalList;
+    }
+}
diff --git a/ves-nf-oam-adopter/ves-nf-oam-adopter-pm-manager/src/main/java/org/o/ran/oam/nf/oam/adopter/pm/rest/manager/pojos/Adapter.java b/ves-nf-oam-adopter/ves-nf-oam-adopter-pm-manager/src/main/java/org/o/ran/oam/nf/oam/adopter/pm/rest/manager/pojos/Adapter.java
new file mode 100644 (file)
index 0000000..555634b
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ *  ============LICENSE_START=======================================================
+ *  O-RAN-SC
+ *  ================================================================================
+ *  Copyright © 2021 AT&T Intellectual Property. All rights reserved.
+ *  ================================================================================
+ *  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.
+ *  ============LICENSE_END=========================================================
+ */
+
+package org.o.ran.oam.nf.oam.adopter.pm.rest.manager.pojos;
+
+import lombok.Builder;
+import lombok.EqualsAndHashCode;
+import lombok.Getter;
+import lombok.NonNull;
+
+@EqualsAndHashCode
+@Getter
+@Builder
+public final class Adapter {
+    private @NonNull final String hostIpAddress;
+    private @NonNull final String username;
+    private @NonNull final String password;
+}
diff --git a/ves-nf-oam-adopter/ves-nf-oam-adopter-pm-manager/src/main/java/org/o/ran/oam/nf/oam/adopter/pm/rest/manager/pojos/CsvConfiguration.java b/ves-nf-oam-adopter/ves-nf-oam-adopter-pm-manager/src/main/java/org/o/ran/oam/nf/oam/adopter/pm/rest/manager/pojos/CsvConfiguration.java
new file mode 100644 (file)
index 0000000..cdb7617
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ *  ============LICENSE_START=======================================================
+ *  O-RAN-SC
+ *  ================================================================================
+ *  Copyright © 2021 AT&T Intellectual Property. All rights reserved.
+ *  ================================================================================
+ *  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.
+ *  ============LICENSE_END=========================================================
+ */
+
+package org.o.ran.oam.nf.oam.adopter.pm.rest.manager.pojos;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.util.List;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@Data
+@NoArgsConstructor
+public class CsvConfiguration {
+    @JsonProperty("additional-fields")
+    private List<String> additionalFields;
+    @JsonProperty("additional-measurements-name")
+    private String additionalMeasurementsName;
+    @JsonProperty("additional-measurements")
+    private List<String> additionalMeasurements;
+    @JsonProperty("event-id")
+    private List<String> eventId;
+    @JsonProperty("source-name")
+    private String sourceName;
+    @JsonProperty("source-name-regex")
+    private String sourceNameRegex;
+}
diff --git a/ves-nf-oam-adopter/ves-nf-oam-adopter-pm-manager/src/main/java/org/o/ran/oam/nf/oam/adopter/pm/rest/manager/pojos/VesMappingConfiguration.java b/ves-nf-oam-adopter/ves-nf-oam-adopter-pm-manager/src/main/java/org/o/ran/oam/nf/oam/adopter/pm/rest/manager/pojos/VesMappingConfiguration.java
new file mode 100644 (file)
index 0000000..3d4ea11
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ *  ============LICENSE_START=======================================================
+ *  O-RAN-SC
+ *  ================================================================================
+ *  Copyright © 2021 AT&T Intellectual Property. All rights reserved.
+ *  ================================================================================
+ *  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.
+ *  ============LICENSE_END=========================================================
+ */
+
+package org.o.ran.oam.nf.oam.adopter.pm.rest.manager.pojos;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@Data
+@NoArgsConstructor
+public class VesMappingConfiguration {
+    @JsonProperty("reporting-entity-name")
+    private String reportingEntityName;
+    @JsonProperty("reporting-entity-id")
+    private String reportingEntityId;
+    @JsonProperty("nf-vendor-name")
+    private String nfVendorName;
+    @JsonProperty("event-source-type")
+    private String eventSourceType;
+    @JsonProperty("event-name")
+    private String eventName;
+    @JsonProperty("measurement-interval")
+    private Long measurementInterval;
+    @JsonProperty("csv")
+    private CsvConfiguration csv;
+    @JsonProperty("batch-size")
+    private int batchSize;
+    @JsonProperty("priority")
+    private String priority;
+    @JsonProperty("ves-event-listener-version")
+    private String vesEventListenerVersion;
+}
diff --git a/ves-nf-oam-adopter/ves-nf-oam-adopter-pm-manager/src/main/java/org/o/ran/oam/nf/oam/adopter/pm/rest/manager/properties/PerformanceManagementManagerProperties.java b/ves-nf-oam-adopter/ves-nf-oam-adopter-pm-manager/src/main/java/org/o/ran/oam/nf/oam/adopter/pm/rest/manager/properties/PerformanceManagementManagerProperties.java
new file mode 100644 (file)
index 0000000..2a3af54
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ *  ============LICENSE_START=======================================================
+ *  O-RAN-SC
+ *  ================================================================================
+ *  Copyright © 2021 AT&T Intellectual Property. All rights reserved.
+ *  ================================================================================
+ *  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.
+ *  ============LICENSE_END=========================================================
+ */
+
+package org.o.ran.oam.nf.oam.adopter.pm.rest.manager.properties;
+
+import javax.validation.constraints.NotEmpty;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.stereotype.Component;
+
+@Component
+@ConfigurationProperties(prefix = "pm-rest-manager")
+@Data
+@NoArgsConstructor
+public class PerformanceManagementManagerProperties {
+    @NotEmpty
+    private String synchronizationTimeStart;
+    private int synchronizationTimeFrequency;
+}