5ced1173ba90cfc649527ea096471b50bba5b714
[policy/clamp.git] /
1 /*-
2  * ============LICENSE_START=======================================================
3  *  Copyright (C) 2021-2025 OpenInfra Foundation Europe. All rights reserved.
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.policy.main.handler;
22
23 import static org.assertj.core.api.Assertions.assertThatThrownBy;
24 import static org.mockito.ArgumentMatchers.any;
25 import static org.mockito.Mockito.clearInvocations;
26 import static org.mockito.Mockito.mock;
27 import static org.mockito.Mockito.verify;
28 import static org.mockito.Mockito.when;
29
30 import java.util.List;
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.CompositionElementDto;
35 import org.onap.policy.clamp.acm.participant.intermediary.api.InstanceElementDto;
36 import org.onap.policy.clamp.acm.participant.intermediary.api.ParticipantIntermediaryApi;
37 import org.onap.policy.clamp.acm.participant.policy.client.PolicyApiHttpClient;
38 import org.onap.policy.clamp.acm.participant.policy.client.PolicyPapHttpClient;
39 import org.onap.policy.clamp.models.acm.concepts.DeployState;
40 import org.onap.policy.clamp.models.acm.concepts.StateChangeResult;
41 import org.onap.policy.common.utils.coder.Coder;
42 import org.onap.policy.common.utils.coder.CoderException;
43 import org.onap.policy.common.utils.coder.StandardCoder;
44 import org.onap.policy.models.base.PfModelException;
45 import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier;
46 import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicy;
47 import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicyType;
48 import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate;
49 import org.onap.policy.models.tosca.authorative.concepts.ToscaTopologyTemplate;
50 import org.springframework.http.HttpStatus;
51 import org.springframework.web.reactive.function.client.WebClientResponseException;
52
53 class AutomationCompositionElementHandlerTest {
54
55     private static final Coder CODER = new StandardCoder();
56
57     private static final ToscaConceptIdentifier DEFINITION =
58             new ToscaConceptIdentifier("1.0.1", "org.onap.PM_CDS_Blueprint");
59
60     @Test
61     void testHandlerUndeployNoPolicy() throws PfModelException {
62         var intermediaryApi = mock(ParticipantIntermediaryApi.class);
63         var handler = new AutomationCompositionElementHandler(mock(PolicyApiHttpClient.class),
64                 mock(PolicyPapHttpClient.class), intermediaryApi);
65
66         var compositionElement = getCompositionElement();
67         var instanceElement = getInstanceElementWithNullTopology();
68
69         handler.undeploy(compositionElement, instanceElement);
70         verify(intermediaryApi).updateAutomationCompositionElementState(instanceElement.instanceId(),
71                 instanceElement.elementId(), DeployState.UNDEPLOYED, null, StateChangeResult.NO_ERROR,
72                 "Undeployed");
73     }
74
75     private CompositionElementDto getCompositionElement() {
76         return new CompositionElementDto(UUID.randomUUID(), DEFINITION, Map.of(), Map.of());
77     }
78
79     private InstanceElementDto getInstanceElement() {
80         var template = new ToscaServiceTemplate();
81         template.setToscaTopologyTemplate(new ToscaTopologyTemplate());
82         template.getToscaTopologyTemplate().setPolicies(List.of(Map.of("DummyPolicy", new ToscaPolicy())));
83         template.setPolicyTypes(Map.of("dummy policy type", new ToscaPolicyType()));
84         var inProperties = getProperties(template);
85         return new InstanceElementDto(UUID.randomUUID(), UUID.randomUUID(), inProperties, Map.of());
86     }
87
88     private Map<String, Object> getProperties(ToscaServiceTemplate template) {
89         try {
90             var json = CODER.encode(template);
91             return CODER.decode(json, Map.class);
92         } catch (CoderException e) {
93             throw new RuntimeException(e);
94         }
95     }
96
97     @Test
98     void testDeploy() throws PfModelException {
99         // Mock success scenario for policy creation and deployment
100         var api = mock(PolicyApiHttpClient.class);
101         var pap = mock(PolicyPapHttpClient.class);
102         var intermediaryApi = mock(ParticipantIntermediaryApi.class);
103         var handler = new AutomationCompositionElementHandler(api, pap, intermediaryApi);
104
105         var compositionElement = getCompositionElement();
106         var instanceElement = getInstanceElement();
107
108         handler.deploy(compositionElement, instanceElement);
109         verify(intermediaryApi).updateAutomationCompositionElementState(instanceElement.instanceId(),
110                 instanceElement.elementId(), DeployState.DEPLOYED, null, StateChangeResult.NO_ERROR,
111                 "Deployed");
112
113         clearInvocations(intermediaryApi);
114         handler.undeploy(compositionElement, instanceElement);
115         verify(intermediaryApi).updateAutomationCompositionElementState(instanceElement.instanceId(),
116                 instanceElement.elementId(), DeployState.UNDEPLOYED, null, StateChangeResult.NO_ERROR,
117                 "Undeployed");
118     }
119
120     @Test
121     void testDeployError() {
122         var api = mock(PolicyApiHttpClient.class);
123         var pap = mock(PolicyPapHttpClient.class);
124         var intermediaryApi = mock(ParticipantIntermediaryApi.class);
125         var handler = new AutomationCompositionElementHandler(api, pap, intermediaryApi);
126
127         var compositionElement = getCompositionElement();
128         var instanceElement = new InstanceElementDto(UUID.randomUUID(), UUID.randomUUID(),
129                 Map.of("data_types", 100), Map.of());
130         assertThatThrownBy(() -> handler.deploy(compositionElement, instanceElement))
131                 .isInstanceOf(PfModelException.class);
132     }
133
134     @Test
135     void testDeployNoPolicy() throws PfModelException {
136         var intermediaryApi = mock(ParticipantIntermediaryApi.class);
137         var handler = new AutomationCompositionElementHandler(mock(PolicyApiHttpClient.class),
138                 mock(PolicyPapHttpClient.class), intermediaryApi);
139
140         var compositionElement = getCompositionElement();
141         var instanceElement = getInstanceElementWithNullTopology();
142         handler.deploy(compositionElement, instanceElement);
143         verify(intermediaryApi).updateAutomationCompositionElementState(instanceElement.instanceId(),
144                 instanceElement.elementId(), DeployState.UNDEPLOYED, null, StateChangeResult.FAILED,
145                 "ToscaTopologyTemplate not defined");
146
147         clearInvocations(intermediaryApi);
148         instanceElement = getInstanceElementWithNoPolicy();
149         handler.deploy(compositionElement, instanceElement);
150         verify(intermediaryApi).updateAutomationCompositionElementState(instanceElement.instanceId(),
151                 instanceElement.elementId(), DeployState.DEPLOYED, null, StateChangeResult.NO_ERROR,
152                 "Deployed");
153
154         clearInvocations(intermediaryApi);
155         handler.undeploy(compositionElement, instanceElement);
156         verify(intermediaryApi).updateAutomationCompositionElementState(instanceElement.instanceId(),
157                 instanceElement.elementId(), DeployState.UNDEPLOYED, null, StateChangeResult.NO_ERROR,
158                 "Undeployed");
159     }
160
161     private InstanceElementDto getInstanceElementWithNullTopology() {
162         var template = new ToscaServiceTemplate();
163         template.setToscaTopologyTemplate(null);
164         var inProperties = getProperties(template);
165         return new InstanceElementDto(UUID.randomUUID(), UUID.randomUUID(), inProperties, Map.of());
166     }
167
168     private InstanceElementDto getInstanceElementWithNoPolicy() {
169         var template = new ToscaServiceTemplate();
170         template.setToscaTopologyTemplate(new ToscaTopologyTemplate());
171         var inProperties = getProperties(template);
172         return new InstanceElementDto(UUID.randomUUID(), UUID.randomUUID(), inProperties, Map.of());
173     }
174
175     @Test
176     void testApiPolicyTypeException() throws PfModelException {
177         var api = mock(PolicyApiHttpClient.class);
178         when(api.createPolicyType(any()))
179                 .thenThrow(new WebClientResponseException(HttpStatus.BAD_REQUEST.value(), "", null, null, null));
180
181         var pap = mock(PolicyPapHttpClient.class);
182         var intermediaryApi = mock(ParticipantIntermediaryApi.class);
183         var handler = new AutomationCompositionElementHandler(api, pap, intermediaryApi);
184
185         var compositionElement = getCompositionElement();
186         var instanceElement = getInstanceElement();
187
188         // Mock failure in policy type creation
189         handler.deploy(compositionElement, instanceElement);
190         verify(intermediaryApi).updateAutomationCompositionElementState(instanceElement.instanceId(),
191                 instanceElement.elementId(), DeployState.UNDEPLOYED, null, StateChangeResult.FAILED,
192                 "Creation of PolicyTypes/Policies failed. Policies will not be deployed.");
193     }
194
195     @Test
196     void testApiPolicyException() throws PfModelException {
197         var api = mock(PolicyApiHttpClient.class);
198         when(api.createPolicy(any()))
199                 .thenThrow(new WebClientResponseException(HttpStatus.BAD_REQUEST.value(), "", null, null, null));
200
201         var pap = mock(PolicyPapHttpClient.class);
202         var intermediaryApi = mock(ParticipantIntermediaryApi.class);
203         var handler = new AutomationCompositionElementHandler(api, pap, intermediaryApi);
204
205         var compositionElement = getCompositionElement();
206         var instanceElement = getInstanceElement();
207
208         // Mock failure in policy creation
209         handler.deploy(compositionElement, instanceElement);
210         verify(intermediaryApi).updateAutomationCompositionElementState(instanceElement.instanceId(),
211                 instanceElement.elementId(), DeployState.UNDEPLOYED, null, StateChangeResult.FAILED,
212                 "Creation of PolicyTypes/Policies failed. Policies will not be deployed.");
213     }
214
215     @Test
216     void testDeployPapException() {
217         var pap = mock(PolicyPapHttpClient.class);
218         when(pap.handlePolicyDeployOrUndeploy(any(), any(), any()))
219                 .thenThrow(new WebClientResponseException(HttpStatus.BAD_REQUEST.value(), "", null, null, null));
220
221         var intermediaryApi = mock(ParticipantIntermediaryApi.class);
222         var api = mock(PolicyApiHttpClient.class);
223         var handler = new AutomationCompositionElementHandler(api, pap, intermediaryApi);
224
225         var compositionElement = getCompositionElement();
226         var instanceElement = getInstanceElement();
227         assertThatThrownBy(() -> handler.deploy(compositionElement, instanceElement))
228                 .hasMessageMatching("Deploy of Policy failed.");
229     }
230 }