e4c34845ebf31fd4b7d72058aadc801443fba311
[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.ArgumentMatchers.any;
24 import static org.mockito.Mockito.clearInvocations;
25 import static org.mockito.Mockito.doThrow;
26 import static org.mockito.Mockito.mock;
27 import static org.mockito.Mockito.timeout;
28 import static org.mockito.Mockito.verify;
29
30 import jakarta.ws.rs.core.Response.Status;
31 import java.io.IOException;
32 import java.util.List;
33 import java.util.Map;
34 import java.util.UUID;
35 import org.junit.jupiter.api.Test;
36 import org.onap.policy.clamp.acm.participant.intermediary.api.AutomationCompositionElementListener;
37 import org.onap.policy.clamp.acm.participant.intermediary.api.CompositionDto;
38 import org.onap.policy.clamp.acm.participant.intermediary.api.CompositionElementDto;
39 import org.onap.policy.clamp.acm.participant.intermediary.api.InstanceElementDto;
40 import org.onap.policy.clamp.acm.participant.intermediary.api.ParticipantIntermediaryApi;
41 import org.onap.policy.clamp.models.acm.concepts.AcElementDeploy;
42 import org.onap.policy.clamp.models.acm.concepts.AcElementRestart;
43 import org.onap.policy.clamp.models.acm.concepts.AcTypeState;
44 import org.onap.policy.clamp.models.acm.concepts.DeployState;
45 import org.onap.policy.clamp.models.acm.concepts.LockState;
46 import org.onap.policy.clamp.models.acm.concepts.ParticipantRestartAc;
47 import org.onap.policy.clamp.models.acm.concepts.StateChangeResult;
48 import org.onap.policy.models.base.PfModelException;
49 import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier;
50
51 class ThreadHandlerTest {
52
53     private static final int TIMEOUT = 400;
54
55     @Test
56     void test() throws PfModelException, IOException {
57         var listener = mock(AutomationCompositionElementListener.class);
58         var intermediaryApi = mock(ParticipantIntermediaryApi.class);
59         try (var threadHandler = new ThreadHandler(listener, intermediaryApi, mock(CacheProvider.class))) {
60
61             var compositionId = UUID.randomUUID();
62             var messageId = UUID.randomUUID();
63             var composition = new CompositionDto(compositionId, Map.of(), Map.of());
64             threadHandler.prime(messageId, composition);
65             verify(listener, timeout(TIMEOUT)).prime(composition);
66
67             clearInvocations(listener);
68             Map<String, Object> properties = Map.of("key", "value");
69             var compositionElement = new CompositionElementDto(UUID.randomUUID(), new ToscaConceptIdentifier(),
70                 properties, properties);
71             var instanceElement = new InstanceElementDto(UUID.randomUUID(), UUID.randomUUID(),
72                 null, properties, properties);
73             threadHandler.deploy(messageId, compositionElement, instanceElement);
74             verify(listener, timeout(TIMEOUT)).deploy(compositionElement, instanceElement);
75
76             clearInvocations(listener);
77             var element = new AcElementDeploy();
78             var elementId = UUID.randomUUID();
79             element.setId(elementId);
80             var instanceElementUpdated = new InstanceElementDto(instanceElement.instanceId(),
81                 instanceElement.elementId(), null, properties, properties);
82             threadHandler.update(messageId, compositionElement, instanceElement, instanceElementUpdated);
83             verify(listener, timeout(TIMEOUT)).update(compositionElement, instanceElement, instanceElementUpdated);
84
85             clearInvocations(listener);
86             var compositionTargetId = UUID.randomUUID();
87             var compositionElementTarget = new CompositionElementDto(compositionTargetId, new ToscaConceptIdentifier(),
88                 properties, properties);
89             threadHandler.migrate(messageId, compositionElement, compositionElementTarget,
90                 instanceElement, instanceElementUpdated);
91             verify(listener, timeout(TIMEOUT)).migrate(compositionElement, compositionElementTarget,
92                 instanceElement, instanceElementUpdated);
93
94             clearInvocations(listener);
95             threadHandler.lock(messageId, compositionElement, instanceElement);
96             verify(listener, timeout(TIMEOUT)).lock(compositionElement, instanceElement);
97
98             clearInvocations(listener);
99             threadHandler.unlock(messageId, compositionElement, instanceElement);
100             verify(listener, timeout(TIMEOUT)).unlock(compositionElement, instanceElement);
101
102             clearInvocations(listener);
103             threadHandler.undeploy(messageId, compositionElement, instanceElement);
104             verify(listener, timeout(TIMEOUT)).undeploy(compositionElement, instanceElement);
105
106             clearInvocations(listener);
107             threadHandler.delete(messageId, compositionElement, instanceElement);
108             verify(listener, timeout(TIMEOUT)).delete(compositionElement, instanceElement);
109
110             clearInvocations(listener);
111             threadHandler.deprime(messageId, composition);
112             verify(listener, timeout(TIMEOUT)).deprime(composition);
113         }
114     }
115
116     @Test
117     void testException() throws PfModelException, IOException {
118         var listener = mock(AutomationCompositionElementListener.class);
119         var intermediaryApi = mock(ParticipantIntermediaryApi.class);
120         try (var threadHandler = new ThreadHandler(listener, intermediaryApi, mock(CacheProvider.class))) {
121
122             var compositionId = UUID.randomUUID();
123             var composition = new CompositionDto(compositionId, Map.of(), Map.of());
124             doThrow(new PfModelException(Status.INTERNAL_SERVER_ERROR, "Error")).when(listener)
125                 .prime(composition);
126             var messageId = UUID.randomUUID();
127             threadHandler.prime(messageId, composition);
128             verify(intermediaryApi, timeout(TIMEOUT)).updateCompositionState(compositionId, AcTypeState.COMMISSIONED,
129                     StateChangeResult.FAILED, "Composition Defintion prime failed");
130
131             clearInvocations(intermediaryApi);
132             Map<String, Object> properties = Map.of("key", "value");
133             var compositionElement = new CompositionElementDto(UUID.randomUUID(), new ToscaConceptIdentifier(),
134                 properties, properties);
135             var instanceId = UUID.randomUUID();
136             var elementId = UUID.randomUUID();
137             var instanceElement = new InstanceElementDto(instanceId, elementId, null, properties, properties);
138             var element = new AcElementDeploy();
139             element.setId(elementId);
140             doThrow(new PfModelException(Status.INTERNAL_SERVER_ERROR, "Error")).when(listener)
141                 .deploy(compositionElement, instanceElement);
142             threadHandler.deploy(messageId, compositionElement, instanceElement);
143             verify(intermediaryApi, timeout(TIMEOUT)).updateAutomationCompositionElementState(instanceId, elementId,
144                     DeployState.UNDEPLOYED, null, StateChangeResult.FAILED,
145                     "Automation composition element deploy failed");
146
147             clearInvocations(listener);
148             var instanceElementUpdated = new InstanceElementDto(instanceElement.instanceId(),
149                 instanceElement.elementId(), null, properties, properties);
150             doThrow(new PfModelException(Status.INTERNAL_SERVER_ERROR, "Error")).when(listener)
151                 .update(compositionElement, instanceElement, instanceElementUpdated);
152             threadHandler.update(messageId, compositionElement, instanceElement, instanceElementUpdated);
153             verify(intermediaryApi, timeout(TIMEOUT)).updateAutomationCompositionElementState(instanceId, elementId,
154                     DeployState.DEPLOYED, null, StateChangeResult.FAILED,
155                     "Automation composition element update failed");
156
157             clearInvocations(listener);
158             doThrow(new PfModelException(Status.INTERNAL_SERVER_ERROR, "Error")).when(listener)
159                 .lock(compositionElement, instanceElement);
160             threadHandler.lock(messageId, compositionElement, instanceElement);
161             verify(intermediaryApi, timeout(TIMEOUT)).updateAutomationCompositionElementState(instanceId, elementId,
162                     null, LockState.UNLOCKED, StateChangeResult.FAILED, "Automation composition element lock failed");
163
164             clearInvocations(listener);
165             doThrow(new PfModelException(Status.INTERNAL_SERVER_ERROR, "Error")).when(listener)
166                 .unlock(compositionElement, instanceElement);
167             threadHandler.unlock(messageId, compositionElement, instanceElement);
168             verify(intermediaryApi, timeout(TIMEOUT)).updateAutomationCompositionElementState(instanceId, elementId,
169                     null, LockState.LOCKED, StateChangeResult.FAILED, "Automation composition element unlock failed");
170
171             clearInvocations(listener);
172             doThrow(new PfModelException(Status.INTERNAL_SERVER_ERROR, "Error")).when(listener)
173                 .undeploy(compositionElement, instanceElement);
174             threadHandler.undeploy(messageId, compositionElement, instanceElement);
175             verify(intermediaryApi, timeout(TIMEOUT)).updateAutomationCompositionElementState(instanceId, elementId,
176                     DeployState.DEPLOYED, null, StateChangeResult.FAILED,
177                     "Automation composition element undeploy failed");
178
179             clearInvocations(listener);
180             doThrow(new PfModelException(Status.INTERNAL_SERVER_ERROR, "Error")).when(listener)
181                 .delete(compositionElement, instanceElement);
182             threadHandler.delete(messageId, compositionElement, instanceElement);
183             verify(intermediaryApi, timeout(TIMEOUT)).updateAutomationCompositionElementState(instanceId, elementId,
184                     DeployState.UNDEPLOYED, null, StateChangeResult.FAILED,
185                     "Automation composition element delete failed");
186
187             clearInvocations(listener);
188             doThrow(new PfModelException(Status.INTERNAL_SERVER_ERROR, "Error")).when(listener).deprime(composition);
189             threadHandler.deprime(messageId, composition);
190             verify(intermediaryApi, timeout(TIMEOUT)).updateCompositionState(compositionId, AcTypeState.PRIMED,
191                     StateChangeResult.FAILED, "Composition Defintion deprime failed");
192
193             clearInvocations(listener);
194             doThrow(new PfModelException(Status.INTERNAL_SERVER_ERROR, "Error")).when(listener)
195                     .handleRestartComposition(composition, AcTypeState.PRIMING);
196             threadHandler.restarted(messageId, composition, AcTypeState.PRIMING, List.of());
197             verify(intermediaryApi).updateCompositionState(compositionId, AcTypeState.PRIMED, StateChangeResult.FAILED,
198                     "Composition Defintion deprime failed");
199         }
200     }
201
202     @Test
203     void testRestarted() throws IOException, PfModelException {
204         var listener = mock(AutomationCompositionElementListener.class);
205         var intermediaryApi = mock(ParticipantIntermediaryApi.class);
206         var cacheProvider = mock(CacheProvider.class);
207         try (var threadHandler = new ThreadHandler(listener, intermediaryApi, cacheProvider)) {
208             var messageId = UUID.randomUUID();
209             var compositionId = UUID.randomUUID();
210             var participantRestartAc = new ParticipantRestartAc();
211             participantRestartAc.setAutomationCompositionId(UUID.randomUUID());
212             participantRestartAc.getAcElementList().add(new AcElementRestart());
213             var composition = new CompositionDto(compositionId, Map.of(), Map.of());
214             threadHandler.restarted(messageId, composition, AcTypeState.PRIMED, List.of(participantRestartAc));
215             verify(listener, timeout(TIMEOUT)).handleRestartInstance(any(), any(), any(), any());
216         }
217     }
218 }