--- /dev/null
+/*
+ * ============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.Single;
+import java.io.BufferedInputStream;
+import java.io.InputStream;
+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.api.HttpRestClient;
+import org.o.ran.oam.nf.oam.adopter.pm.rest.manager.pojos.Adapter;
+
+public class HttpRestClientMock implements HttpRestClient {
+
+ @Override
+ public Single<ZipInputStream> readFiles(@NonNull final Adapter adapter) {
+ final InputStream file = HttpRestClientMock.class.getResourceAsStream("/zip/nfOamAdapter1.zip");
+ if (file == null) {
+ return Single.error(new Exception("Failed to read test file"));
+ }
+ final BufferedInputStream bis = new BufferedInputStream(file);
+ return Single.just(new ZipInputStream(bis));
+ }
+
+ @Override
+ public @NonNull Single<ZoneId> getTimeZone(@NonNull final Adapter adapter) {
+ return Single.just(ZoneId.of("+02:00"));
+ }
+}
--- /dev/null
+/*
+ * ============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.junit.jupiter.api.Assertions.assertEquals;
+
+import com.google.gson.JsonArray;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.util.Arrays;
+import java.util.List;
+import lombok.experimental.UtilityClass;
+import org.apache.commons.io.IOUtils;
+
+@UtilityClass
+final class JsonUtils {
+ private static final List<String> WHITE_LIST = Arrays.asList("eventId", "startEpochMicrosec", "lastEpochMicrosec");
+ private static final String EVENT_LIST = "eventList";
+ private static final String COMMON_EVENT_HEADER = "commonEventHeader";
+
+ static String readJson(final String url) throws IOException {
+ return IOUtils.toString(JsonUtils.class.getResourceAsStream(url), StandardCharsets.UTF_8);
+ }
+
+ public static void compareResult(final String expected, final String actual) {
+ final JsonObject expectedJO = JsonParser.parseString(expected).getAsJsonObject();
+ final JsonObject actualJO = JsonParser.parseString(actual).getAsJsonObject();
+ removeCommonEventHeaderFields(expectedJO.get(EVENT_LIST).getAsJsonArray(),
+ actualJO.get(EVENT_LIST).getAsJsonArray(), WHITE_LIST);
+ assertEquals(expectedJO, actualJO);
+ }
+
+ private static void removeCommonEventHeaderFields(final JsonArray expectedJO, final JsonArray actualJO,
+ final List<String> asList) {
+ asList.forEach(wipe -> {
+ expectedJO.forEach(jsonElement -> removeCommonEventHeaderFields(jsonElement, wipe));
+ actualJO.forEach(jsonElement -> removeCommonEventHeaderFields(jsonElement, wipe));
+ });
+ }
+
+ private static void removeCommonEventHeaderFields(final JsonElement jsonElement, final String wipe) {
+ jsonElement.getAsJsonObject().getAsJsonObject(COMMON_EVENT_HEADER).remove(wipe);
+ }
+}
--- /dev/null
+/*
+ * ============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.lang.Thread.sleep;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import java.io.IOException;
+import java.time.ZoneId;
+import java.time.ZonedDateTime;
+import java.time.format.DateTimeFormatter;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.Timeout;
+import org.junit.jupiter.api.extension.ExtendWith;
+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.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.beans.factory.annotation.Qualifier;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit.jupiter.SpringExtension;
+
+@ExtendWith(SpringExtension.class)
+@SpringBootTest(classes = {VesEventNotifierMock.class, PerformanceManagementMapperConfigProvider.class,
+ PerformanceManagementFile2VesMapper.class, PerformanceManagementAdaptersDeployer.class})
+public class PerformanceManagementManagerTest {
+
+ @Autowired
+ @Qualifier("test")
+ private VesEventNotifierMock eventListener;
+ @Autowired
+ private PerformanceManagementFile2VesMapper fileMapper;
+ private PerformanceManagementAdaptersDeployer deployer;
+
+ /**
+ * Initialize test.
+ */
+ @BeforeEach
+ public void init() {
+ final HttpRestClientMock httpRestClientMock = new HttpRestClientMock();
+ final PerformanceManagementManagerProperties properties = new PerformanceManagementManagerProperties();
+ final ZonedDateTime now = ZonedDateTime.now(ZoneId.of("+02:00")).plusSeconds(5);
+ final String formattedString = now.format(DateTimeFormatter.ofPattern("HH:mm:ss"));
+ properties.setSynchronizationTimeStart(formattedString);
+ properties.setSynchronizationTimeFrequency(30);
+ deployer = new AdaptersDeployer(
+ new PerformanceManagementRestAgentFactory(eventListener, fileMapper, properties, httpRestClientMock));
+ }
+
+ @Test
+ @Timeout(value = 10000, unit = TimeUnit.MILLISECONDS)
+ public void testMapping() throws IOException, InterruptedException, AlreadyPresentException {
+ assertTrue(deployer.getAll().isEmpty());
+ deployer.create("172.0.10.2", "admin", "admin");
+ assertFalse(deployer.getAll().isEmpty());
+
+ final String expected = JsonUtils.readJson("/json/PMVESMessage.json");
+ final List<String> notifications = getVesNotification(eventListener, 2);
+ final String actual = notifications.get(0);
+ JsonUtils.compareResult(expected, actual);
+ }
+
+ @Test
+ public void testDelete() throws AlreadyPresentException, NotFoundException {
+ assertTrue(deployer.getAll().isEmpty());
+ deployer.create("172.0.10.2", "admin", "admin");
+ assertFalse(deployer.getAll().isEmpty());
+
+ deployer.delete("172.0.10.2");
+ assertTrue(deployer.getAll().isEmpty());
+ }
+
+ @Test
+ public void testAlreadyPresent() throws AlreadyPresentException {
+ assertTrue(deployer.getAll().isEmpty());
+ deployer.create("172.0.10.2", "admin", "admin");
+ assertFalse(deployer.getAll().isEmpty());
+
+ final Exception alreadyPresentException = assertThrows(AlreadyPresentException.class,
+ () -> deployer.create("172.0.10.2", "admin", "admin"));
+ assertEquals(alreadyPresentException.getMessage(), "Adapter 172.0.10.2 already present.");
+ }
+
+ @Test
+ public void testNotPresent() {
+ final Exception exception = assertThrows(NotFoundException.class, () -> deployer.delete("172.0.10.2"));
+ assertEquals(exception.getMessage(), "Adapter 172.0.10.2 is not present.");
+ }
+
+ @Test
+ public void testTimeZone() throws AlreadyPresentException {
+ deployer.create("172.0.10.2", "admin", "admin");
+ assertEquals(deployer.getTimeZone("172.0.10.2"), ZoneId.of("+02:00"));
+ }
+
+ private static List<String> getVesNotification(final VesEventNotifierMock listener, final int expectedSize)
+ throws InterruptedException {
+ List<String> events = null;
+ for (int i = 0; i < 100000; i++) {
+ sleep(1000);
+ events = listener.getEvents();
+ if (events != null && !events.isEmpty() && events.size() == expectedSize) {
+ break;
+ }
+ }
+ return events;
+ }
+
+ @AfterEach
+ public final void after() {
+ ((AdaptersDeployer) deployer).close();
+ assertTrue(deployer.getAll().isEmpty());
+ }
+}
--- /dev/null
+/*
+ * ============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 com.google.gson.Gson;
+import io.reactivex.rxjava3.core.Completable;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Collectors;
+import org.o.ran.oam.nf.oam.adopter.api.CommonEventFormat302ONAP;
+import org.o.ran.oam.nf.oam.adopter.api.VesEventNotifier;
+import org.springframework.stereotype.Service;
+
+@Service("test")
+final class VesEventNotifierMock implements VesEventNotifier {
+
+ private static final Gson GSON = new Gson();
+ private final List<CommonEventFormat302ONAP> event = new ArrayList<>();
+
+ @Override
+ public Completable notifyEvents(final CommonEventFormat302ONAP event) {
+ this.event.add(event);
+ return Completable.complete();
+ }
+
+ protected synchronized List<String> getEvents() {
+ return event.stream().map(e -> GSON.toJson(e, CommonEventFormat302ONAP.class)).collect(Collectors.toList());
+ }
+}
--- /dev/null
+pm-rest-manager:
+ synchronization-time-start: "00:05:00"
+ synchronization-time-frequency: 60
+ mapping-config-path: "src/test/resources/pm-ves-message-mapping.yaml"
--- /dev/null
+{
+ "eventList":[
+ {
+ "commonEventHeader":{
+ "domain":"measurement",
+ "eventId":"ba10db33-9e27-3296-9bfd-a8d232bbe0a8",
+ "eventName":"FAULT_NF-OAM-ADOPTER_PM_Notification",
+ "lastEpochMicrosec":1618483581744,
+ "nfVendorName":"SOME-VENDOR",
+ "priority":"High",
+ "reportingEntityId":"ONAP-NF-OAM-SOME-VENDOR-ADAPTER",
+ "reportingEntityName":"NF-OAM-ADOPTER",
+ "sequence":0,
+ "sourceName":"OAM-BOX",
+ "startEpochMicrosec":1618483581744,
+ "version":"4.0",
+ "vesEventListenerVersion":"7.1"
+ },
+ "measurementFields":{
+ "additionalFields":{
+ "PortId":"2",
+ "Time":"12:02:12 AM",
+ "Date":"15/4/2021",
+ "Name":"OAM-BOX"
+ },
+ "additionalMeasurements":[
+ {
+ "name":"Port measurements",
+ "hashMap":{
+ "C_Parameter":"y26",
+ "A_Parameter":"1100",
+ "E_Parameter":"+10.2",
+ "B_Parameter":"0.5",
+ "D_Parameter":"x25"
+ }
+ }
+ ],
+ "measurementInterval":40,
+ "measurementFieldsVersion":"4.0"
+ }
+ },
+ {
+ "commonEventHeader":{
+ "domain":"measurement",
+ "eventId":"f75fd549-18dc-389c-90b6-f975f3ff2a70",
+ "eventName":"FAULT_NF-OAM-ADOPTER_PM_Notification",
+ "lastEpochMicrosec":1618483581763,
+ "nfVendorName":"SOME-VENDOR",
+ "priority":"High",
+ "reportingEntityId":"ONAP-NF-OAM-SOME-VENDOR-ADAPTER",
+ "reportingEntityName":"NF-OAM-ADOPTER",
+ "sequence":1,
+ "sourceName":"OAM-BOX",
+ "startEpochMicrosec":1618483581763,
+ "version":"4.0",
+ "vesEventListenerVersion":"7.1"
+ },
+ "measurementFields":{
+ "additionalFields":{
+ "PortId":"2",
+ "Time":"12:02:52 AM",
+ "Date":"15/4/2021",
+ "Name":"OAM-BOX"
+ },
+ "additionalMeasurements":[
+ {
+ "name":"Port measurements",
+ "hashMap":{
+ "C_Parameter":"y26",
+ "A_Parameter":"2100",
+ "E_Parameter":"+10.01",
+ "B_Parameter":"0.5",
+ "D_Parameter":"x25"
+ }
+ }
+ ],
+ "measurementInterval":40,
+ "measurementFieldsVersion":"4.0"
+ }
+ },
+ {
+ "commonEventHeader":{
+ "domain":"measurement",
+ "eventId":"da259c3e-b66d-311d-9fb9-946b241f2fed",
+ "eventName":"FAULT_NF-OAM-ADOPTER_PM_Notification",
+ "lastEpochMicrosec":1618483581763,
+ "nfVendorName":"SOME-VENDOR",
+ "priority":"High",
+ "reportingEntityId":"ONAP-NF-OAM-SOME-VENDOR-ADAPTER",
+ "reportingEntityName":"NF-OAM-ADOPTER",
+ "sequence":2,
+ "sourceName":"OAM-BOX",
+ "startEpochMicrosec":1618483581763,
+ "version":"4.0",
+ "vesEventListenerVersion":"7.1"
+ },
+ "measurementFields":{
+ "additionalFields":{
+ "PortId":"2",
+ "Time":"12:03:32 AM",
+ "Date":"15/4/2021",
+ "Name":"OAM-BOX"
+ },
+ "additionalMeasurements":[
+ {
+ "name":"Port measurements",
+ "hashMap":{
+ "C_Parameter":"y26",
+ "A_Parameter":"3100",
+ "E_Parameter":"+10.02",
+ "B_Parameter":"0.5",
+ "D_Parameter":"x25"
+ }
+ }
+ ],
+ "measurementInterval":40,
+ "measurementFieldsVersion":"4.0"
+ }
+ },
+ {
+ "commonEventHeader":{
+ "domain":"measurement",
+ "eventId":"e0bedb4a-4ded-3480-92c4-9c8cec77b28e",
+ "eventName":"FAULT_NF-OAM-ADOPTER_PM_Notification",
+ "lastEpochMicrosec":1618483581764,
+ "nfVendorName":"SOME-VENDOR",
+ "priority":"High",
+ "reportingEntityId":"ONAP-NF-OAM-SOME-VENDOR-ADAPTER",
+ "reportingEntityName":"NF-OAM-ADOPTER",
+ "sequence":3,
+ "sourceName":"OAM-BOX",
+ "startEpochMicrosec":1618483581764,
+ "version":"4.0",
+ "vesEventListenerVersion":"7.1"
+ },
+ "measurementFields":{
+ "additionalFields":{
+ "PortId":"2",
+ "Time":"12:04:12 AM",
+ "Date":"15/4/2021",
+ "Name":"OAM-BOX"
+ },
+ "additionalMeasurements":[
+ {
+ "name":"Port measurements",
+ "hashMap":{
+ "C_Parameter":"y26",
+ "A_Parameter":"4100",
+ "E_Parameter":"+10.03",
+ "B_Parameter":"0.5",
+ "D_Parameter":"x25"
+ }
+ }
+ ],
+ "measurementInterval":40,
+ "measurementFieldsVersion":"4.0"
+ }
+ }
+ ]
+}
\ No newline at end of file
--- /dev/null
+reporting-entity-name: "NF-OAM-ADOPTER"
+reporting-entity-id: "ONAP-NF-OAM-SOME-VENDOR-ADAPTER"
+nf-vendor-name: "SOME-VENDOR"
+event-source-type: "SNMP Agent"
+event-name: "PM_Notification"
+measurement-interval: 40
+priority: "High"
+batch-size: 5
+csv:
+ source-name: Name
+ event-id:
+ - PortId
+ - Date
+ - Time
+ additional-fields:
+ - PortId
+ - Name
+ - Date
+ - Time
+ additional-measurements-name: "Port measurements"
+ additional-measurements:
+ - A_Parameter
+ - B_Parameter
+ - C_Parameter
+ - D_Parameter
+ - E_Parameter