0b63c395a505aef4c3dc4031f8db41e8a5720d1c
[policy/clamp.git] /
1 /*-
2  * ============LICENSE_START=======================================================
3  *  Copyright (C) 2021 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.controlloop.participant.simulator.endtoend;
22
23 import static org.assertj.core.api.Assertions.assertThat;
24 import static org.junit.jupiter.api.Assertions.assertEquals;
25 import static org.junit.jupiter.api.Assertions.assertNotNull;
26 import static org.junit.jupiter.api.Assertions.assertTrue;
27
28 import java.util.Collections;
29 import java.util.List;
30 import java.util.Map;
31 import java.util.UUID;
32 import org.junit.jupiter.api.Test;
33 import org.junit.jupiter.api.extension.ExtendWith;
34 import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoop;
35 import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopElement;
36 import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopOrderedState;
37 import org.onap.policy.clamp.controlloop.models.controlloop.concepts.Participant;
38 import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ParticipantState;
39 import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantControlLoopUpdate;
40 import org.onap.policy.clamp.controlloop.models.messages.rest.TypedSimpleResponse;
41 import org.onap.policy.clamp.controlloop.participant.intermediary.api.ParticipantIntermediaryApi;
42 import org.onap.policy.clamp.controlloop.participant.intermediary.comm.ControlLoopUpdateListener;
43 import org.onap.policy.clamp.controlloop.participant.intermediary.handler.ParticipantHandler;
44 import org.onap.policy.clamp.controlloop.participant.simulator.main.parameters.CommonTestData;
45 import org.onap.policy.clamp.controlloop.participant.simulator.main.rest.AbstractRestController;
46 import org.onap.policy.clamp.controlloop.participant.simulator.main.rest.TestListenerUtils;
47 import org.onap.policy.common.endpoints.event.comm.Topic.CommInfrastructure;
48 import org.onap.policy.common.utils.coder.Coder;
49 import org.onap.policy.common.utils.coder.StandardCoder;
50 import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier;
51 import org.springframework.beans.factory.annotation.Autowired;
52 import org.springframework.beans.factory.annotation.Value;
53 import org.springframework.boot.test.context.SpringBootTest;
54 import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
55 import org.springframework.boot.test.web.client.TestRestTemplate;
56 import org.springframework.boot.web.server.LocalServerPort;
57 import org.springframework.core.ParameterizedTypeReference;
58 import org.springframework.http.HttpEntity;
59 import org.springframework.http.HttpHeaders;
60 import org.springframework.http.HttpMethod;
61 import org.springframework.http.MediaType;
62 import org.springframework.http.ResponseEntity;
63 import org.springframework.test.context.TestPropertySource;
64 import org.springframework.test.context.junit.jupiter.SpringExtension;
65
66 @ExtendWith(SpringExtension.class)
67 @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
68 @TestPropertySource(locations = {"classpath:application_test.properties"})
69 class ParticipantSimulatorTest {
70
71     private static final String PARTICIPANTS_ENDPOINT = "participants";
72     private static final String ELEMENTS_ENDPOINT = "elements";
73     private static final CommInfrastructure INFRA = CommInfrastructure.NOOP;
74     private static final String TOPIC = "my-topic";
75
76     public static final Coder coder = new StandardCoder();
77
78     @Value("${spring.security.user.name}")
79     private String user;
80
81     @Value("${spring.security.user.password}")
82     private String password;
83
84     @LocalServerPort
85     private int randomServerPort;
86
87     @Autowired
88     private TestRestTemplate restTemplate;
89
90     @Autowired
91     private ParticipantIntermediaryApi participantIntermediaryApi;
92
93     @Autowired
94     private ParticipantHandler participantHandler;
95
96     private static final Object lockit = new Object();
97     private boolean check = false;
98
99     private void setUp() throws Exception {
100         synchronized (lockit) {
101             if (!check) {
102                 check = true;
103                 ControlLoopUpdateListener clUpdateListener =
104                         new ControlLoopUpdateListener(participantHandler);
105
106                 ParticipantControlLoopUpdate participantControlLoopUpdateMsg =
107                         TestListenerUtils.createControlLoopUpdateMsg();
108                 participantControlLoopUpdateMsg.getControlLoop().setOrderedState(ControlLoopOrderedState.PASSIVE);
109                 clUpdateListener.onTopicEvent(INFRA, TOPIC, null, participantControlLoopUpdateMsg);
110
111             }
112         }
113     }
114
115     private String getPath(String path) {
116         return "http://localhost:" + randomServerPort + "/onap/participantsim/v2/" + path;
117     }
118
119     void testSwagger(String endPoint) {
120         HttpEntity<Void> request = new HttpEntity<>(null, createHttpHeaders());
121         ResponseEntity<String> response =
122                 restTemplate.exchange(getPath("api-docs"), HttpMethod.GET, request, String.class);
123         assertThat(response.getStatusCodeValue()).isEqualTo(200);
124         assertTrue(response.getBody().contains("/onap/participantsim/v2/" + endPoint));
125     }
126
127     @Test
128     void testEndParticipatsSwagger() {
129         testSwagger(PARTICIPANTS_ENDPOINT);
130     }
131
132     @Test
133     void testElementsSwagger() {
134         testSwagger(ELEMENTS_ENDPOINT);
135     }
136
137     @Test
138     void testProducerYaml() {
139         MediaType yamlMediaType = new MediaType("application", "yaml");
140         HttpHeaders headers = createHttpHeaders();
141         headers.setAccept(Collections.singletonList(yamlMediaType));
142         HttpEntity<Void> request = new HttpEntity<>(null, headers);
143         String path = getPath(PARTICIPANTS_ENDPOINT + "/org.onap.PM_CDS_Blueprint/1");
144
145         ResponseEntity<String> response = restTemplate.exchange(path, HttpMethod.GET, request, String.class);
146
147         assertThat(response.getStatusCodeValue()).isEqualTo(200);
148         assertTrue(response.getHeaders().getContentType().isCompatibleWith(yamlMediaType));
149     }
150
151     @Test
152     void testQuery_Unauthorized() throws Exception {
153         String path = getPath(PARTICIPANTS_ENDPOINT + "/org.onap.PM_CDS_Blueprint/1");
154
155         // authorized call
156         ResponseEntity<String> response =
157                 restTemplate.exchange(path, HttpMethod.GET, new HttpEntity<>(null, createHttpHeaders()), String.class);
158         assertThat(response.getStatusCodeValue()).isEqualTo(200);
159
160         // unauthorized call
161         response = restTemplate.exchange(path, HttpMethod.GET, new HttpEntity<>(null, new HttpHeaders()), String.class);
162         assertThat(response.getStatusCodeValue()).isEqualTo(401);
163     }
164
165     private HttpHeaders createHttpHeaders() {
166         HttpHeaders headers = new HttpHeaders();
167         headers.setBasicAuth(user, password);
168         return headers;
169     }
170
171     protected <T> ResponseEntity<T> performGet(String endpoint, Class<T> responseType, UUID uuid) throws Exception {
172         HttpHeaders httpHeaders = createHttpHeaders();
173         if (uuid != null) {
174             httpHeaders.add(AbstractRestController.REQUEST_ID_NAME, uuid.toString());
175         }
176         HttpEntity<Void> request = new HttpEntity<>(null, httpHeaders);
177         return restTemplate.exchange(getPath(endpoint), HttpMethod.GET, request, responseType);
178     }
179
180     protected <T> ResponseEntity<T> performGet(String endpoint, Class<T> responseType) throws Exception {
181         return performGet(endpoint, responseType, null);
182     }
183
184     protected <T, R> ResponseEntity<R> performPut(String path, T body, ParameterizedTypeReference<R> responseType,
185             UUID uuid) throws Exception {
186         HttpHeaders httpHeaders = createHttpHeaders();
187         if (uuid != null) {
188             httpHeaders.add(AbstractRestController.REQUEST_ID_NAME, uuid.toString());
189         }
190         HttpEntity<T> request = new HttpEntity<>(body, httpHeaders);
191         return restTemplate.exchange(getPath(path), HttpMethod.PUT, request, responseType);
192     }
193
194     @Test
195     void testQueryParticipants() throws Exception {
196         Participant participant = new Participant();
197         ToscaConceptIdentifier participantId = CommonTestData.getParticipantId();
198         participant.setDefinition(participantId);
199         participant.setName(participantId.getName());
200         participant.setVersion(participantId.getVersion());
201         UUID uuid = UUID.randomUUID();
202
203         // GET REST call for querying the participants
204         ResponseEntity<String> response = performGet(
205                 PARTICIPANTS_ENDPOINT + "/" + participant.getKey().getName() + "/" + participant.getKey().getVersion(),
206                 String.class, uuid);
207         checkResponseEntity(response, 200, uuid);
208
209         Participant[] returnValue = coder.decode(response.getBody(), Participant[].class);
210         assertThat(returnValue).hasSize(1);
211         // Verify the result of GET participants with what is stored
212         assertEquals(participant.getDefinition(), returnValue[0].getDefinition());
213     }
214
215     private <T> void checkResponseEntity(ResponseEntity<T> response, int status, UUID uuid) {
216         assertThat(response.getStatusCodeValue()).isEqualTo(status);
217         assertThat(getHeader(response.getHeaders(), AbstractRestController.VERSION_MINOR_NAME)).isEqualTo("0");
218         assertThat(getHeader(response.getHeaders(), AbstractRestController.VERSION_PATCH_NAME)).isEqualTo("0");
219         assertThat(getHeader(response.getHeaders(), AbstractRestController.VERSION_LATEST_NAME)).isEqualTo("1.0.0");
220         assertThat(getHeader(response.getHeaders(), AbstractRestController.REQUEST_ID_NAME)).isEqualTo(uuid.toString());
221     }
222
223     private String getHeader(HttpHeaders httpHeaders, String param) {
224         List<String> list = httpHeaders.get(param);
225         assertThat(list).hasSize(1);
226         return list.get(0);
227     }
228
229     @Test
230     void testQueryControlLoopElements() throws Exception {
231         setUp();
232         UUID uuid = UUID.randomUUID();
233         ToscaConceptIdentifier participantId = CommonTestData.getParticipantId();
234
235         // GET REST call for querying the controlLoop elements
236         ResponseEntity<String> response =
237                 performGet(ELEMENTS_ENDPOINT + "/" + participantId.getName() + "/" + participantId.getVersion(),
238                         String.class, uuid);
239         checkResponseEntity(response, 200, uuid);
240
241         Map<?, ?> returnValue = coder.decode(response.getBody(), Map.class);
242         // Verify the result of GET controlloop elements with what is stored
243         assertThat(returnValue).isEmpty();
244     }
245
246     @Test
247     void testUpdateParticipant() throws Exception {
248         setUp();
249         List<Participant> participants = participantIntermediaryApi.getParticipants(
250                 CommonTestData.getParticipantId().getName(), CommonTestData.getParticipantId().getVersion());
251         assertEquals(ParticipantState.UNKNOWN, participants.get(0).getParticipantState());
252         // Change the state of the participant to PASSIVE from UNKNOWN
253         participants.get(0).setParticipantState(ParticipantState.PASSIVE);
254         UUID uuid = UUID.randomUUID();
255
256         // PUT REST call for updating Participant
257         ResponseEntity<TypedSimpleResponse<Participant>> response = performPut(PARTICIPANTS_ENDPOINT,
258                 participants.get(0), new ParameterizedTypeReference<TypedSimpleResponse<Participant>>() {}, uuid);
259         checkResponseEntity(response, 200, uuid);
260
261         TypedSimpleResponse<Participant> resp = response.getBody();
262         assertNotNull(resp.getResponse());
263         // Verify the response and state returned by PUT REST call for updating participants
264         assertEquals(participants.get(0).getDefinition(), resp.getResponse().getDefinition());
265         assertEquals(ParticipantState.PASSIVE, resp.getResponse().getParticipantState());
266     }
267
268     @Test
269     void testUpdateControlLoopElement() throws Exception {
270         setUp();
271         ControlLoop controlLoop = TestListenerUtils.createControlLoop();
272         Map<UUID, ControlLoopElement> controlLoopElements = participantIntermediaryApi.getControlLoopElements(
273                 controlLoop.getDefinition().getName(), controlLoop.getDefinition().getVersion());
274
275         UUID uuid = controlLoopElements.keySet().iterator().next();
276         ControlLoopElement controlLoopElement = controlLoopElements.get(uuid);
277
278         // Check the initial state on the ControlLoopElement, which is UNINITIALISED
279         assertEquals(ControlLoopOrderedState.UNINITIALISED, controlLoopElement.getOrderedState());
280
281         // Change the state of the ControlLoopElement to PASSIVE from UNINITIALISED
282         controlLoopElement.setOrderedState(ControlLoopOrderedState.PASSIVE);
283
284         // PUT REST call for updating ControlLoopElement
285         ResponseEntity<TypedSimpleResponse<ControlLoopElement>> response = performPut(ELEMENTS_ENDPOINT,
286                 controlLoopElement, new ParameterizedTypeReference<TypedSimpleResponse<ControlLoopElement>>() {}, uuid);
287         checkResponseEntity(response, 200, uuid);
288
289         TypedSimpleResponse<ControlLoopElement> resp = response.getBody();
290         assertNotNull(resp.getResponse());
291         // Verify the response and state returned by PUT REST call for updating participants
292         assertEquals(controlLoopElement.getDefinition(), resp.getResponse().getDefinition());
293         assertEquals(ControlLoopOrderedState.PASSIVE, resp.getResponse().getOrderedState());
294     }
295 }