f3471e6ee9cf6db1ef348ec759656d5f320616dc
[policy/clamp.git] /
1 /*-
2  * ============LICENSE_START=======================================================
3  *  Copyright (C) 2023-2024 Nordix Foundation.
4  * ================================================================================
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  * SPDX-License-Identifier: Apache-2.0
18  * ============LICENSE_END=========================================================
19  */
20
21 package org.onap.policy.clamp.acm.participant.intermediary.handler;
22
23 import static org.mockito.Mockito.clearInvocations;
24 import static org.mockito.Mockito.doThrow;
25 import static org.mockito.Mockito.mock;
26 import static org.mockito.Mockito.timeout;
27 import static org.mockito.Mockito.verify;
28
29 import jakarta.ws.rs.core.Response.Status;
30 import java.io.IOException;
31 import java.util.Map;
32 import java.util.UUID;
33 import org.junit.jupiter.api.Test;
34 import org.onap.policy.clamp.acm.participant.intermediary.api.AutomationCompositionElementListener;
35 import org.onap.policy.clamp.acm.participant.intermediary.api.CompositionDto;
36 import org.onap.policy.clamp.acm.participant.intermediary.api.CompositionElementDto;
37 import org.onap.policy.clamp.acm.participant.intermediary.api.InstanceElementDto;
38 import org.onap.policy.clamp.acm.participant.intermediary.api.ParticipantIntermediaryApi;
39 import org.onap.policy.clamp.models.acm.concepts.AcElementDeploy;
40 import org.onap.policy.clamp.models.acm.concepts.AcTypeState;
41 import org.onap.policy.clamp.models.acm.concepts.DeployState;
42 import org.onap.policy.clamp.models.acm.concepts.LockState;
43 import org.onap.policy.clamp.models.acm.concepts.StateChangeResult;
44 import org.onap.policy.models.base.PfModelException;
45 import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier;
46
47 class ThreadHandlerTest {
48
49     private static final int TIMEOUT = 400;
50
51     @Test
52     void test() throws PfModelException, IOException {
53         var listener = mock(AutomationCompositionElementListener.class);
54         var intermediaryApi = mock(ParticipantIntermediaryApi.class);
55         try (var threadHandler = new ThreadHandler(listener, intermediaryApi, mock(CacheProvider.class))) {
56
57             var compositionId = UUID.randomUUID();
58             var messageId = UUID.randomUUID();
59             var composition = new CompositionDto(compositionId, Map.of(), Map.of());
60             threadHandler.prime(messageId, composition);
61             verify(listener, timeout(TIMEOUT)).prime(composition);
62
63             clearInvocations(listener);
64             Map<String, Object> properties = Map.of("key", "value");
65             var compositionElement = new CompositionElementDto(UUID.randomUUID(), new ToscaConceptIdentifier(),
66                 properties, properties);
67             var instanceElement = new InstanceElementDto(UUID.randomUUID(), UUID.randomUUID(),
68                 null, properties, properties);
69             threadHandler.deploy(messageId, compositionElement, instanceElement);
70             verify(listener, timeout(TIMEOUT)).deploy(compositionElement, instanceElement);
71
72             clearInvocations(listener);
73             var element = new AcElementDeploy();
74             var elementId = UUID.randomUUID();
75             element.setId(elementId);
76             var instanceElementUpdated = new InstanceElementDto(instanceElement.instanceId(),
77                 instanceElement.elementId(), null, properties, properties);
78             threadHandler.update(messageId, compositionElement, instanceElement, instanceElementUpdated);
79             verify(listener, timeout(TIMEOUT)).update(compositionElement, instanceElement, instanceElementUpdated);
80
81             clearInvocations(listener);
82             var compositionTargetId = UUID.randomUUID();
83             var compositionElementTarget = new CompositionElementDto(compositionTargetId, new ToscaConceptIdentifier(),
84                 properties, properties);
85             threadHandler.migrate(messageId, compositionElement, compositionElementTarget,
86                 instanceElement, instanceElementUpdated);
87             verify(listener, timeout(TIMEOUT)).migrate(compositionElement, compositionElementTarget,
88                 instanceElement, instanceElementUpdated);
89
90             clearInvocations(listener);
91             threadHandler.lock(messageId, compositionElement, instanceElement);
92             verify(listener, timeout(TIMEOUT)).lock(compositionElement, instanceElement);
93
94             clearInvocations(listener);
95             threadHandler.unlock(messageId, compositionElement, instanceElement);
96             verify(listener, timeout(TIMEOUT)).unlock(compositionElement, instanceElement);
97
98             clearInvocations(listener);
99             threadHandler.undeploy(messageId, compositionElement, instanceElement);
100             verify(listener, timeout(TIMEOUT)).undeploy(compositionElement, instanceElement);
101
102             clearInvocations(listener);
103             threadHandler.delete(messageId, compositionElement, instanceElement);
104             verify(listener, timeout(TIMEOUT)).delete(compositionElement, instanceElement);
105
106             clearInvocations(listener);
107             threadHandler.deprime(messageId, composition);
108             verify(listener, timeout(TIMEOUT)).deprime(composition);
109         }
110     }
111
112     @Test
113     void testException() throws PfModelException, IOException {
114         var listener = mock(AutomationCompositionElementListener.class);
115         var intermediaryApi = mock(ParticipantIntermediaryApi.class);
116         try (var threadHandler = new ThreadHandler(listener, intermediaryApi, mock(CacheProvider.class))) {
117
118             var compositionId = UUID.randomUUID();
119             var composition = new CompositionDto(compositionId, Map.of(), Map.of());
120             doThrow(new PfModelException(Status.INTERNAL_SERVER_ERROR, "Error")).when(listener)
121                 .prime(composition);
122             var messageId = UUID.randomUUID();
123             threadHandler.prime(messageId, composition);
124             verify(intermediaryApi, timeout(TIMEOUT)).updateCompositionState(compositionId, AcTypeState.COMMISSIONED,
125                     StateChangeResult.FAILED, "Composition Defintion prime failed");
126
127             clearInvocations(intermediaryApi);
128             Map<String, Object> properties = Map.of("key", "value");
129             var compositionElement = new CompositionElementDto(UUID.randomUUID(), new ToscaConceptIdentifier(),
130                 properties, properties);
131             var instanceId = UUID.randomUUID();
132             var elementId = UUID.randomUUID();
133             var instanceElement = new InstanceElementDto(instanceId, elementId, null, properties, properties);
134             var element = new AcElementDeploy();
135             element.setId(elementId);
136             doThrow(new PfModelException(Status.INTERNAL_SERVER_ERROR, "Error")).when(listener)
137                 .deploy(compositionElement, instanceElement);
138             threadHandler.deploy(messageId, compositionElement, instanceElement);
139             verify(intermediaryApi, timeout(TIMEOUT)).updateAutomationCompositionElementState(instanceId, elementId,
140                     DeployState.UNDEPLOYED, null, StateChangeResult.FAILED,
141                     "Automation composition element deploy failed");
142
143             clearInvocations(listener);
144             var instanceElementUpdated = new InstanceElementDto(instanceElement.instanceId(),
145                 instanceElement.elementId(), null, properties, properties);
146             doThrow(new PfModelException(Status.INTERNAL_SERVER_ERROR, "Error")).when(listener)
147                 .update(compositionElement, instanceElement, instanceElementUpdated);
148             threadHandler.update(messageId, compositionElement, instanceElement, instanceElementUpdated);
149             verify(intermediaryApi, timeout(TIMEOUT)).updateAutomationCompositionElementState(instanceId, elementId,
150                     DeployState.DEPLOYED, null, StateChangeResult.FAILED,
151                     "Automation composition element update failed");
152
153             clearInvocations(listener);
154             doThrow(new PfModelException(Status.INTERNAL_SERVER_ERROR, "Error")).when(listener)
155                 .lock(compositionElement, instanceElement);
156             threadHandler.lock(messageId, compositionElement, instanceElement);
157             verify(intermediaryApi, timeout(TIMEOUT)).updateAutomationCompositionElementState(instanceId, elementId,
158                     null, LockState.UNLOCKED, StateChangeResult.FAILED, "Automation composition element lock failed");
159
160             clearInvocations(listener);
161             doThrow(new PfModelException(Status.INTERNAL_SERVER_ERROR, "Error")).when(listener)
162                 .unlock(compositionElement, instanceElement);
163             threadHandler.unlock(messageId, compositionElement, instanceElement);
164             verify(intermediaryApi, timeout(TIMEOUT)).updateAutomationCompositionElementState(instanceId, elementId,
165                     null, LockState.LOCKED, StateChangeResult.FAILED, "Automation composition element unlock failed");
166
167             clearInvocations(listener);
168             doThrow(new PfModelException(Status.INTERNAL_SERVER_ERROR, "Error")).when(listener)
169                 .undeploy(compositionElement, instanceElement);
170             threadHandler.undeploy(messageId, compositionElement, instanceElement);
171             verify(intermediaryApi, timeout(TIMEOUT)).updateAutomationCompositionElementState(instanceId, elementId,
172                     DeployState.DEPLOYED, null, StateChangeResult.FAILED,
173                     "Automation composition element undeploy failed");
174
175             clearInvocations(listener);
176             doThrow(new PfModelException(Status.INTERNAL_SERVER_ERROR, "Error")).when(listener)
177                 .delete(compositionElement, instanceElement);
178             threadHandler.delete(messageId, compositionElement, instanceElement);
179             verify(intermediaryApi, timeout(TIMEOUT)).updateAutomationCompositionElementState(instanceId, elementId,
180                     DeployState.UNDEPLOYED, null, StateChangeResult.FAILED,
181                     "Automation composition element delete failed");
182
183             clearInvocations(listener);
184             doThrow(new PfModelException(Status.INTERNAL_SERVER_ERROR, "Error")).when(listener).deprime(composition);
185             threadHandler.deprime(messageId, composition);
186             verify(intermediaryApi, timeout(TIMEOUT)).updateCompositionState(compositionId, AcTypeState.PRIMED,
187                     StateChangeResult.FAILED, "Composition Defintion deprime failed");
188         }
189     }
190 }