From 777a186248a2bcef1ab9ffc8b16a7190860302e2 Mon Sep 17 00:00:00 2001 From: "saul.gill" Date: Fri, 27 Jan 2023 14:58:05 +0000 Subject: Add element and definition map to ppnt endpoints Add element instance map Add node template state map Issue-ID: POLICY-4540 Change-Id: I6e7c2b27db78a090b0a1303c49e57d8675316f9b Signed-off-by: saul.gill --- .../acm/concepts/ParticipantInformation.java | 7 +- .../persistence/provider/ParticipantProvider.java | 31 +++++ .../AutomationCompositionElementRepository.java | 33 ++++++ .../repository/NodeTemplateStateRepository.java | 34 ++++++ .../acm/concepts/ParticipantInformationTest.java | 45 +++++++ .../provider/ParticipantProviderTest.java | 130 ++++++++++++++++++++- .../resources/providers/NodeTemplateState.json | 9 ++ .../participants/AcmParticipantProvider.java | 26 +++++ 8 files changed, 308 insertions(+), 7 deletions(-) create mode 100644 models/src/main/java/org/onap/policy/clamp/models/acm/persistence/repository/AutomationCompositionElementRepository.java create mode 100644 models/src/main/java/org/onap/policy/clamp/models/acm/persistence/repository/NodeTemplateStateRepository.java create mode 100644 models/src/test/java/org/onap/policy/clamp/models/acm/concepts/ParticipantInformationTest.java create mode 100644 models/src/test/resources/providers/NodeTemplateState.json diff --git a/models/src/main/java/org/onap/policy/clamp/models/acm/concepts/ParticipantInformation.java b/models/src/main/java/org/onap/policy/clamp/models/acm/concepts/ParticipantInformation.java index a6a65fec5..8d7d391f8 100644 --- a/models/src/main/java/org/onap/policy/clamp/models/acm/concepts/ParticipantInformation.java +++ b/models/src/main/java/org/onap/policy/clamp/models/acm/concepts/ParticipantInformation.java @@ -1,6 +1,6 @@ /*- * ============LICENSE_START======================================================= - * Copyright (C) 2022 Nordix Foundation. + * Copyright (C) 2022-2023 Nordix Foundation. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -38,7 +38,7 @@ public class ParticipantInformation { @NonNull private Participant participant; - private Map acElementDefinitionMap = new HashMap<>(); + private Map acNodeTemplateStateDefinitionMap = new HashMap<>(); private Map acElementInstanceMap = new HashMap<>(); /** @@ -47,6 +47,9 @@ public class ParticipantInformation { * @param otherInfo the participant information to copy from */ public ParticipantInformation(ParticipantInformation otherInfo) { + this.participant = otherInfo.participant; + this.acNodeTemplateStateDefinitionMap = otherInfo.getAcNodeTemplateStateDefinitionMap(); + this.acElementInstanceMap = otherInfo.getAcElementInstanceMap(); } } diff --git a/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/provider/ParticipantProvider.java b/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/provider/ParticipantProvider.java index 8e45c770b..65b72c436 100644 --- a/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/provider/ParticipantProvider.java +++ b/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/provider/ParticipantProvider.java @@ -28,8 +28,12 @@ import java.util.UUID; import javax.ws.rs.core.Response.Status; import lombok.NonNull; import lombok.RequiredArgsConstructor; +import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionElement; +import org.onap.policy.clamp.models.acm.concepts.NodeTemplateState; import org.onap.policy.clamp.models.acm.concepts.Participant; import org.onap.policy.clamp.models.acm.persistence.concepts.JpaParticipant; +import org.onap.policy.clamp.models.acm.persistence.repository.AutomationCompositionElementRepository; +import org.onap.policy.clamp.models.acm.persistence.repository.NodeTemplateStateRepository; import org.onap.policy.clamp.models.acm.persistence.repository.ParticipantRepository; import org.onap.policy.models.base.PfModelRuntimeException; import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; @@ -46,6 +50,11 @@ public class ParticipantProvider { private final ParticipantRepository participantRepository; + private final AutomationCompositionElementRepository automationCompositionElementRepository; + + private final NodeTemplateStateRepository nodeTemplateStateRepository; + + /** * Get all participants. * @@ -149,4 +158,26 @@ public class ParticipantProvider { return map; } + + /** + * Retrieve a list of automation composition elements associated with a participantId. + * + * @param participantId the participant id associated with the automation composition elements + * @return the list of associated elements + */ + public List getAutomationCompositionElements(@NonNull final UUID participantId) { + return ProviderUtils.asEntityList(automationCompositionElementRepository + .findByParticipantId(participantId.toString())); + } + + /** + * Retrieve a list of node template states elements associated with a participantId from ac definitions. + * + * @param participantId the participant id associated with the automation composition elements + * @return the list of associated elements + */ + public List getAcNodeTemplateStates(@NonNull final UUID participantId) { + return ProviderUtils.asEntityList(nodeTemplateStateRepository + .findByParticipantId(participantId.toString())); + } } diff --git a/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/repository/AutomationCompositionElementRepository.java b/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/repository/AutomationCompositionElementRepository.java new file mode 100644 index 000000000..19d791e6c --- /dev/null +++ b/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/repository/AutomationCompositionElementRepository.java @@ -0,0 +1,33 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2023 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.policy.clamp.models.acm.persistence.repository; + +import java.util.List; +import org.onap.policy.clamp.models.acm.persistence.concepts.JpaAutomationCompositionElement; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.repository.query.QueryByExampleExecutor; + +public interface AutomationCompositionElementRepository extends + JpaRepository, + QueryByExampleExecutor { + + List findByParticipantId(String participantId); +} diff --git a/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/repository/NodeTemplateStateRepository.java b/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/repository/NodeTemplateStateRepository.java new file mode 100644 index 000000000..3a879a78b --- /dev/null +++ b/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/repository/NodeTemplateStateRepository.java @@ -0,0 +1,34 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2023 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.policy.clamp.models.acm.persistence.repository; + +import java.util.List; +import org.onap.policy.clamp.models.acm.persistence.concepts.JpaNodeTemplateState; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.repository.query.QueryByExampleExecutor; + +public interface NodeTemplateStateRepository extends + JpaRepository, + QueryByExampleExecutor { + + List findByParticipantId(String participantId); +} + diff --git a/models/src/test/java/org/onap/policy/clamp/models/acm/concepts/ParticipantInformationTest.java b/models/src/test/java/org/onap/policy/clamp/models/acm/concepts/ParticipantInformationTest.java new file mode 100644 index 000000000..4c01f659c --- /dev/null +++ b/models/src/test/java/org/onap/policy/clamp/models/acm/concepts/ParticipantInformationTest.java @@ -0,0 +1,45 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2023 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.policy.clamp.models.acm.concepts; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.util.HashMap; +import java.util.UUID; +import org.junit.jupiter.api.Test; + +public class ParticipantInformationTest { + + @Test + void testCopyConstructor() { + var participant = new Participant(); + participant.setParticipantId(UUID.randomUUID()); + participant.setParticipantState(ParticipantState.ON_LINE); + participant.setParticipantSupportedElementTypes(new HashMap<>()); + var participantInfo1 = new ParticipantInformation(); + participantInfo1.setParticipant(participant); + participantInfo1.setAcElementInstanceMap(new HashMap<>()); + participantInfo1.setAcNodeTemplateStateDefinitionMap(new HashMap<>()); + + var participantInfo2 = new ParticipantInformation(participantInfo1); + assertEquals(participantInfo1, participantInfo2); + } +} diff --git a/models/src/test/java/org/onap/policy/clamp/models/acm/persistence/provider/ParticipantProviderTest.java b/models/src/test/java/org/onap/policy/clamp/models/acm/persistence/provider/ParticipantProviderTest.java index 0c5137824..3e100df18 100644 --- a/models/src/test/java/org/onap/policy/clamp/models/acm/persistence/provider/ParticipantProviderTest.java +++ b/models/src/test/java/org/onap/policy/clamp/models/acm/persistence/provider/ParticipantProviderTest.java @@ -22,6 +22,7 @@ package org.onap.policy.clamp.models.acm.persistence.provider; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.junit.jupiter.api.Assertions.assertThrows; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -30,19 +31,33 @@ import java.util.ArrayList; import java.util.List; import java.util.Optional; import java.util.UUID; +import java.util.stream.Collectors; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import org.onap.policy.clamp.models.acm.concepts.AcTypeState; +import org.onap.policy.clamp.models.acm.concepts.AutomationCompositions; +import org.onap.policy.clamp.models.acm.concepts.NodeTemplateState; import org.onap.policy.clamp.models.acm.concepts.Participant; +import org.onap.policy.clamp.models.acm.persistence.concepts.JpaAutomationComposition; +import org.onap.policy.clamp.models.acm.persistence.concepts.JpaNodeTemplateState; import org.onap.policy.clamp.models.acm.persistence.concepts.JpaParticipant; +import org.onap.policy.clamp.models.acm.persistence.repository.AutomationCompositionElementRepository; +import org.onap.policy.clamp.models.acm.persistence.repository.NodeTemplateStateRepository; import org.onap.policy.clamp.models.acm.persistence.repository.ParticipantRepository; import org.onap.policy.common.utils.coder.Coder; import org.onap.policy.common.utils.coder.StandardCoder; import org.onap.policy.common.utils.resources.ResourceUtils; +import org.onap.policy.models.base.PfModelRuntimeException; class ParticipantProviderTest { private static final Coder CODER = new StandardCoder(); private static final String PARTICIPANT_JSON = "src/test/resources/providers/TestParticipant.json"; + + private static final String AUTOMATION_COMPOSITION_JSON = + "src/test/resources/providers/TestAutomationCompositions.json"; + + private static final String NODE_TEMPLATE_STATE_JSON = "src/test/resources/providers/NodeTemplateState.json"; private static final String LIST_IS_NULL = ".*. is marked .*ull but is null"; private static final UUID INVALID_ID = UUID.randomUUID(); @@ -50,20 +65,43 @@ class ParticipantProviderTest { private List jpaParticipantList; private final String originalJson = ResourceUtils.getResourceAsString(PARTICIPANT_JSON); + private AutomationCompositions inputAutomationCompositions; + private List inputAutomationCompositionsJpa; + private final String originalAcJson = ResourceUtils.getResourceAsString(AUTOMATION_COMPOSITION_JSON); + + private final String nodeTemplateStatesJson = ResourceUtils.getResourceAsString(NODE_TEMPLATE_STATE_JSON); + + private List nodeTemplateStateList = new ArrayList<>(); + private List jpaNodeTemplateStateList; + @BeforeEach void beforeSetup() throws Exception { inputParticipants.add(CODER.decode(originalJson, Participant.class)); jpaParticipantList = ProviderUtils.getJpaAndValidateList(inputParticipants, JpaParticipant::new, "participant"); + + inputAutomationCompositions = CODER.decode(originalAcJson, AutomationCompositions.class); + inputAutomationCompositionsJpa = + ProviderUtils.getJpaAndValidateList(inputAutomationCompositions.getAutomationCompositionList(), + JpaAutomationComposition::new, "automation compositions"); + + nodeTemplateStateList.add(CODER.decode(nodeTemplateStatesJson, NodeTemplateState.class)); + nodeTemplateStateList.get(0).setState(AcTypeState.COMMISSIONED); + jpaNodeTemplateStateList = ProviderUtils.getJpaAndValidateList(nodeTemplateStateList, + JpaNodeTemplateState::new, "node template state"); } @Test void testParticipantSave() { var participantRepository = mock(ParticipantRepository.class); + var automationCompositionElementRepository = mock(AutomationCompositionElementRepository.class); + var nodeTemplateStateRepository = mock(NodeTemplateStateRepository.class); + for (var participant : jpaParticipantList) { when(participantRepository.getById(participant.getParticipantId())) .thenReturn(participant); } - var participantProvider = new ParticipantProvider(participantRepository); + var participantProvider = new ParticipantProvider(participantRepository, + automationCompositionElementRepository, nodeTemplateStateRepository); assertThatThrownBy(() -> participantProvider.saveParticipant(null)).hasMessageMatching(LIST_IS_NULL); @@ -78,11 +116,14 @@ class ParticipantProviderTest { @Test void testParticipantUpdate() { var participantRepository = mock(ParticipantRepository.class); + var automationCompositionElementRepository = mock(AutomationCompositionElementRepository.class); + var nodeTemplateStateRepository = mock(NodeTemplateStateRepository.class); for (var participant : jpaParticipantList) { when(participantRepository.getById(participant.getParticipantId())) .thenReturn(participant); } - var participantProvider = new ParticipantProvider(participantRepository); + var participantProvider = new ParticipantProvider(participantRepository, + automationCompositionElementRepository, nodeTemplateStateRepository); assertThatThrownBy(() -> participantProvider.updateParticipant(null)) .hasMessageMatching(LIST_IS_NULL); @@ -97,7 +138,11 @@ class ParticipantProviderTest { @Test void testGetAutomationCompositions() { var participantRepository = mock(ParticipantRepository.class); - var participantProvider = new ParticipantProvider(participantRepository); + var automationCompositionElementRepository = mock(AutomationCompositionElementRepository.class); + var nodeTemplateStateRepository = mock(NodeTemplateStateRepository.class); + var participantProvider = new ParticipantProvider(participantRepository, + automationCompositionElementRepository, nodeTemplateStateRepository); + assertThat(participantProvider.findParticipant(INVALID_ID)).isEmpty(); @@ -116,10 +161,25 @@ class ParticipantProviderTest { assertThat(inputParticipants.get(0)).usingRecursiveComparison().isEqualTo(participant); } + @Test + void testEmptyParticipant() { + var participantRepository = mock(ParticipantRepository.class); + var automationCompositionElementRepository = mock(AutomationCompositionElementRepository.class); + var nodeTemplateStateRepository = mock(NodeTemplateStateRepository.class); + var participantProvider = new ParticipantProvider(participantRepository, + automationCompositionElementRepository, nodeTemplateStateRepository); + + assertThatThrownBy(() -> participantProvider.getParticipantById(INVALID_ID)).isInstanceOf( + PfModelRuntimeException.class).hasMessageMatching("Participant Not Found with ID:.*."); + } + @Test void testDeleteParticipant() { var participantRepository = mock(ParticipantRepository.class); - var participantProvider = new ParticipantProvider(participantRepository); + var automationCompositionElementRepository = mock(AutomationCompositionElementRepository.class); + var nodeTemplateStateRepository = mock(NodeTemplateStateRepository.class); + var participantProvider = new ParticipantProvider(participantRepository, + automationCompositionElementRepository, nodeTemplateStateRepository); var participantId = inputParticipants.get(0).getParticipantId(); assertThatThrownBy(() -> participantProvider.deleteParticipant(participantId)) @@ -132,11 +192,71 @@ class ParticipantProviderTest { assertThat(inputParticipants.get(0)).usingRecursiveComparison().isEqualTo(deletedParticipant); } + @Test + void testGetAutomationCompositionElements() { + var participantRepository = mock(ParticipantRepository.class); + var automationCompositionElementRepository = mock(AutomationCompositionElementRepository.class); + var nodeTemplateStateRepository = mock(NodeTemplateStateRepository.class); + var participantProvider = new ParticipantProvider(participantRepository, + automationCompositionElementRepository, nodeTemplateStateRepository); + + var acElementList = inputAutomationCompositionsJpa + .stream().map(c -> c.getElements()).collect(Collectors.toList()); + + when(automationCompositionElementRepository.findByParticipantId(any())).thenReturn(acElementList.get(0)); + + var listOfAcElements = participantProvider.getAutomationCompositionElements(UUID.randomUUID()); + + assertThat(acElementList.get(0).equals(listOfAcElements)); + + + } + + @Test + void testGetAcNodeTemplateState() { + var participantRepository = mock(ParticipantRepository.class); + var automationCompositionElementRepository = mock(AutomationCompositionElementRepository.class); + var nodeTemplateStateRepository = mock(NodeTemplateStateRepository.class); + when(nodeTemplateStateRepository.findByParticipantId(any())).thenReturn(jpaNodeTemplateStateList); + + var participantProvider = new ParticipantProvider(participantRepository, + automationCompositionElementRepository, nodeTemplateStateRepository); + + var listOfNodeTemplateState = participantProvider.getAcNodeTemplateStates( + UUID.fromString(jpaParticipantList.get(0).getParticipantId())); + + assertThat(listOfNodeTemplateState.equals(nodeTemplateStateList)); + + } + + @Test + void testNotNullExceptions() { + var participantRepository = mock(ParticipantRepository.class); + var automationCompositionElementRepository = mock(AutomationCompositionElementRepository.class); + var nodeTemplateStateRepository = mock(NodeTemplateStateRepository.class); + + var participantProvider = new ParticipantProvider(participantRepository, + automationCompositionElementRepository, nodeTemplateStateRepository); + + assertThrows(NullPointerException.class, () -> participantProvider.getParticipantById(null)); + assertThrows(NullPointerException.class, () -> participantProvider.findParticipant(null)); + assertThrows(NullPointerException.class, () -> participantProvider.saveParticipant(null)); + assertThrows(NullPointerException.class, () -> participantProvider.updateParticipant(null)); + assertThrows(NullPointerException.class, () -> participantProvider.deleteParticipant(null)); + assertThrows(NullPointerException.class, () -> participantProvider.getAutomationCompositionElements(null)); + assertThrows(NullPointerException.class, () -> participantProvider.getAcNodeTemplateStates(null)); + + + } + @Test void testGetSupportedElementMap() { var participantRepository = mock(ParticipantRepository.class); + var automationCompositionElementRepository = mock(AutomationCompositionElementRepository.class); + var nodeTemplateStateRepository = mock(NodeTemplateStateRepository.class); when(participantRepository.findAll()).thenReturn(jpaParticipantList); - var participantProvider = new ParticipantProvider(participantRepository); + var participantProvider = new ParticipantProvider(participantRepository, + automationCompositionElementRepository, nodeTemplateStateRepository); var result = participantProvider.getSupportedElementMap(); assertThat(result).hasSize(2); diff --git a/models/src/test/resources/providers/NodeTemplateState.json b/models/src/test/resources/providers/NodeTemplateState.json new file mode 100644 index 000000000..ba21d739e --- /dev/null +++ b/models/src/test/resources/providers/NodeTemplateState.json @@ -0,0 +1,9 @@ +{ + "nodeTemplateStateId": "c836dc19-d13d-4506-9dbe-96223e1fbad4", + "participantId": "24b694d4-a07c-11ed-a8fc-0242ac120002", + "nodeTemplateId": { + "name": "testNodeTemplate", + "version": "1.0.0" + }, + "state": "COMMISSIONED" +} diff --git a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/participants/AcmParticipantProvider.java b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/participants/AcmParticipantProvider.java index 18a8e8a26..de3fc753b 100644 --- a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/participants/AcmParticipantProvider.java +++ b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/participants/AcmParticipantProvider.java @@ -21,10 +21,15 @@ package org.onap.policy.clamp.acm.runtime.participants; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.UUID; import lombok.RequiredArgsConstructor; +import org.apache.commons.collections4.MapUtils; import org.onap.policy.clamp.acm.runtime.supervision.comm.ParticipantStatusReqPublisher; +import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionElement; +import org.onap.policy.clamp.models.acm.concepts.NodeTemplateState; import org.onap.policy.clamp.models.acm.concepts.ParticipantInformation; import org.onap.policy.clamp.models.acm.concepts.ParticipantState; import org.onap.policy.clamp.models.acm.persistence.provider.ParticipantProvider; @@ -69,6 +74,10 @@ public class AcmParticipantProvider { var participant = this.participantProvider.getParticipantById(participantId); var participantInformation = new ParticipantInformation(); participantInformation.setParticipant(participant); + + participantInformation.setAcElementInstanceMap(getAutomationCompositionElementsForParticipant(participantId)); + participantInformation.setAcNodeTemplateStateDefinitionMap(getNodeTemplateStatesForParticipant(participantId)); + return participantInformation; } @@ -93,4 +102,21 @@ public class AcmParticipantProvider { public void sendAllParticipantStatusRequest() { this.participantStatusReqPublisher.send((UUID) null); } + + private Map getAutomationCompositionElementsForParticipant(UUID participantId) { + var automationCompositionElements = participantProvider + .getAutomationCompositionElements(participantId); + Map map = new HashMap<>(); + MapUtils.populateMap(map, automationCompositionElements, AutomationCompositionElement::getId); + + return map; + } + + private Map getNodeTemplateStatesForParticipant(UUID participantId) { + var acNodeTemplateStates = participantProvider.getAcNodeTemplateStates(participantId); + Map map = new HashMap<>(); + MapUtils.populateMap(map, acNodeTemplateStates, NodeTemplateState::getNodeTemplateStateId); + + return map; + } } -- cgit 1.2.3-korg