cce03cc2ae6b1e5c733754f3c4ef476bd3818c6e
[sdnc/northbound.git] / generic-resource-api / provider / src / test / java / org / onap / sdnc / northbound / ServiceTopologyOperationRPCTest.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * openECOMP : SDN-C
4  * ================================================================================
5  * Copyright (C) 2017 AT&T Intellectual Property. All rights
6  *                             reserved.
7  * ================================================================================
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  *      http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  * ============LICENSE_END=========================================================
20  */
21
22 package org.onap.sdnc.northbound;
23
24 import static org.junit.Assert.assertEquals;
25 import static org.mockito.Mockito.mock;
26 import static org.mockito.Mockito.when;
27 import static org.onap.sdnc.northbound.GenericResourceApiProvider.APP_NAME;
28 import static org.onap.sdnc.northbound.GenericResourceApiProvider.NO_SERVICE_LOGIC_ACTIVE;
29 import static org.onap.sdnc.northbound.GenericResourceApiProvider.NULL_OR_EMPTY_ERROR_PARAM;
30 import static org.onap.sdnc.northbound.util.MDSALUtil.build;
31 import static org.onap.sdnc.northbound.util.MDSALUtil.exec;
32 import static org.onap.sdnc.northbound.util.MDSALUtil.requestInformation;
33 import static org.onap.sdnc.northbound.util.MDSALUtil.sdncRequestHeader;
34 import static org.onap.sdnc.northbound.util.MDSALUtil.service;
35 import static org.onap.sdnc.northbound.util.MDSALUtil.serviceData;
36 import static org.onap.sdnc.northbound.util.MDSALUtil.serviceInformationBuilder;
37 import static org.onap.sdnc.northbound.util.MDSALUtil.serviceResponseInformation;
38 import static org.onap.sdnc.northbound.util.MDSALUtil.serviceStatus;
39 import static org.onap.sdnc.northbound.util.MDSALUtil.serviceTopologyOperationInput;
40 import static org.onap.sdnc.northbound.util.MDSALUtil.serviceTopologyOperationOutput;
41
42 import org.junit.Before;
43 import org.junit.Test;
44 import org.junit.runner.RunWith;
45 import org.mockito.Mockito;
46 import org.mockito.runners.MockitoJUnitRunner;
47 import org.onap.sdnc.northbound.util.PropBuilder;
48 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
49 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
50 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
51 import org.opendaylight.controller.md.sal.common.api.data.TransactionChainClosedException;
52 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.ServiceTopologyOperationInput;
53 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.ServiceTopologyOperationOutput;
54 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.request.information.RequestInformation;
55 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.sdnc.request.header.SdncRequestHeader;
56 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.sdnc.request.header.SdncRequestHeader.SvcAction;
57 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.service.information.ServiceInformation;
58 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.service.model.infrastructure.Service;
59 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.service.status.ServiceStatus;
60 import org.opendaylight.yangtools.yang.common.RpcResult;
61
62
63 /**
64  * This class test the ServiceTopologyOperation mdsal RPC.
65  */
66 @RunWith(MockitoJUnitRunner.class)
67 public class ServiceTopologyOperationRPCTest extends GenericResourceApiProviderTest {
68
69     final String SVC_OPERATION = "service-topology-operation";
70
71     @Before
72     public void setUp() throws Exception {
73         super.setUp();
74         svcClient.setScvOperation(SVC_OPERATION);
75     }
76
77     /**
78      * Verify  ServiceTopologyOperation RPC executes a DG then produces the expected {@link
79      * ServiceTopologyOperationOutput} and persisted the expected {@link Service} in the {@link DataBroker}
80      */
81     @Test
82     public void testServiceTopologyOperationRPC_ExecuteDG_Success() throws Exception {
83
84         //mock svcClient to perform a successful execution with the expected parameters
85         svcClient.mockHasGraph(true);
86         PropBuilder svcResultProp = svcClient.createExecuteOKResult();
87         svcClient.mockExecute(svcResultProp);
88
89         // create the ServiceTopologyOperationInput from the template
90         ServiceTopologyOperationInput input = createSTOI();
91
92         //execute the mdsal exec
93         ServiceTopologyOperationOutput output = exec(
94             genericResourceApiProvider::serviceTopologyOperation
95             , input
96             , RpcResult::getResult
97         );
98
99         assertEquals("200", output.getResponseCode());
100         assertEquals("OK", output.getResponseMessage());
101         assertEquals("Y", output.getAckFinalIndicator());
102
103         //verify the returned ServiceTopologyOperationOutput
104         ServiceTopologyOperationOutput expectedServiceTopologyOperationOutput = createExpectedSTOO(svcResultProp,
105             input);
106         assertEquals(expectedServiceTopologyOperationOutput, output);
107
108         //verify the persisted Service
109         Service actualService = db.read(input.getServiceInformation().getServiceInstanceId(),
110             LogicalDatastoreType.CONFIGURATION);
111         Service expectedService = createExpectedService(
112             expectedServiceTopologyOperationOutput,
113             input,
114             actualService);
115         assertEquals(expectedService, actualService);
116
117         LOG.debug("done");
118     }
119
120     @Test
121     public void should_fail_when_service_info_not_present() throws Exception {
122         // create the ServiceTopologyOperationInput from the template
123         ServiceTopologyOperationInput input = build(
124             serviceTopologyOperationInput()
125                 .setSdncRequestHeader(build(sdncRequestHeader()
126                     .setSvcRequestId("svc-request-id: xyz")
127                     .setSvcAction(SvcAction.Assign)
128                 ))
129                 .setRequestInformation(build(requestInformation()
130                     .setRequestId("request-id: xyz")
131                     .setRequestAction(RequestInformation.RequestAction.CreateServiceInstance)
132                 )));
133
134         //execute the mdsal exec
135         ServiceTopologyOperationOutput output = exec(
136             genericResourceApiProvider::serviceTopologyOperation
137             , input
138             , RpcResult::getResult
139         );
140
141         assertEquals("404", output.getResponseCode());
142         assertEquals(NULL_OR_EMPTY_ERROR_PARAM, output.getResponseMessage());
143         assertEquals("Y", output.getAckFinalIndicator());
144     }
145
146
147     @Test
148     public void should_fail_when_client_execution_failed() throws Exception {
149
150         svcClient.mockHasGraph(true);
151         svcClient.mockExecute(new RuntimeException("test exception"));
152
153         ServiceTopologyOperationInput input = createSTOI();
154
155         //execute the mdsal exec
156         ServiceTopologyOperationOutput output = exec(
157             genericResourceApiProvider::serviceTopologyOperation
158             , input
159             , RpcResult::getResult
160         );
161         
162         assertEquals("500", output.getResponseCode());
163         assertEquals("test exception", output.getResponseMessage());
164         assertEquals("Y", output.getAckFinalIndicator());
165     }
166
167     @Test
168     public void delete_fail_when_client_execution_failed() throws Exception {
169
170         //mock svcClient to perform a successful execution with the expected parameters
171         svcClient.mockHasGraph(true);
172         PropBuilder svcResultProp = svcClient.createExecuteOKResult();
173         svcClient.mockExecute(svcResultProp);
174
175         ServiceTopologyOperationInput input = deleteSTOI();
176
177         //execute the mdsal exec
178         ServiceTopologyOperationOutput output = exec(
179                 genericResourceApiProvider::serviceTopologyOperation
180                 , input
181                 , RpcResult::getResult
182         );
183
184         assertEquals("200", output.getResponseCode());
185         assertEquals("OK", output.getResponseMessage());
186         assertEquals("Y", output.getAckFinalIndicator());
187     }
188
189     @Test
190     public void delete_service_fail_when_client_execution_failed() throws Exception {
191
192         //mock svcClient to perform a successful execution with the expected parameters
193         svcClient.mockHasGraph(true);
194         PropBuilder svcResultProp = svcClient.createExecuteOKResult();
195         svcClient.mockExecute(svcResultProp);
196
197         ServiceTopologyOperationInput input = deleteServiceSTOI();
198
199         //execute the mdsal exec
200         ServiceTopologyOperationOutput output = exec(
201                 genericResourceApiProvider::serviceTopologyOperation
202                 , input
203                 , RpcResult::getResult
204         );
205
206         assertEquals("200", output.getResponseCode());
207         assertEquals("Y", output.getAckFinalIndicator());
208     }
209
210     @Test
211     public void should_fail_when_client_has_no_graph() throws Exception {
212         svcClient.mockHasGraph(false);
213
214         ServiceTopologyOperationInput input = createSTOI();
215
216         //execute the mdsal exec
217         ServiceTopologyOperationOutput output = exec(
218             genericResourceApiProvider::serviceTopologyOperation
219             , input
220             , RpcResult::getResult
221         );
222
223         assertEquals("503", output.getResponseCode());
224         assertEquals(NO_SERVICE_LOGIC_ACTIVE + APP_NAME + ": '" + SVC_OPERATION + "'", output.getResponseMessage());
225         assertEquals("Y", output.getAckFinalIndicator());
226     }
227
228
229     @Test
230     public void should_fail_when_failed_to_update_mdsal() throws Exception {
231
232         svcClient.mockHasGraph(true);
233         WriteTransaction mockWriteTransaction = mock(WriteTransaction.class);
234         when(mockWriteTransaction.submit()).thenThrow(new TransactionChainClosedException("test exception"));
235
236         DataBroker spyDataBroker = Mockito.spy(dataBroker);
237         when(spyDataBroker.newWriteOnlyTransaction()).thenReturn(mockWriteTransaction);
238         genericResourceApiProvider.setDataBroker(spyDataBroker);
239
240         ServiceTopologyOperationInput input = createSTOI();
241
242         //execute the mdsal exec
243         ServiceTopologyOperationOutput output = exec(
244             genericResourceApiProvider::serviceTopologyOperation
245             , input
246             , RpcResult::getResult
247         );
248
249         assertEquals("500", output.getResponseCode());
250         assertEquals("test exception", output.getResponseMessage());
251         assertEquals("Y", output.getAckFinalIndicator());
252     }
253
254     private ServiceTopologyOperationInput createSTOI() {
255
256         return build(
257             serviceTopologyOperationInput()
258                 .setSdncRequestHeader(build(sdncRequestHeader()
259                     .setSvcRequestId("svc-request-id: xyz")
260                     .setSvcAction(SvcAction.Assign)
261                 ))
262                 .setRequestInformation(build(requestInformation()
263                     .setRequestId("request-id: xyz")
264                     .setRequestAction(RequestInformation.RequestAction.CreateServiceInstance)
265                 ))
266                 .setServiceInformation(build(serviceInformationBuilder()
267                     .setServiceInstanceId("service-instance-id: xyz")
268                 ))
269         );
270     }
271
272     private ServiceTopologyOperationInput deleteSTOI() {
273
274         return build(
275                 serviceTopologyOperationInput()
276                         .setSdncRequestHeader(build(sdncRequestHeader()
277                                 .setSvcRequestId("svc-request-id: xyz")
278                                 .setSvcAction(SvcAction.Unassign)
279                         ))
280                         .setRequestInformation(build(requestInformation()
281                                 .setRequestId("request-id: xyz")
282                                 .setRequestAction(RequestInformation.RequestAction.DeleteServiceInstance)
283                         ))
284                         .setServiceInformation(build(serviceInformationBuilder()
285                                 .setServiceInstanceId("service-instance-id: xyz")
286                         ))
287         );
288     }
289
290     private ServiceTopologyOperationInput deleteServiceSTOI() {
291
292         return build(
293                 serviceTopologyOperationInput()
294                         .setSdncRequestHeader(build(sdncRequestHeader()
295                                 .setSvcRequestId("svc-request-id: xyz")
296                                 .setSvcAction(SvcAction.Delete)
297                         ))
298                         .setRequestInformation(build(requestInformation()
299                                 .setRequestId("request-id: xyz")
300                                 .setRequestAction(RequestInformation.RequestAction.DeleteServiceInstance)
301                         ))
302                         .setServiceInformation(build(serviceInformationBuilder()
303                                 .setServiceInstanceId("service-instance-id: xyz")
304                         ))
305         );
306     }
307
308
309     private ServiceTopologyOperationOutput createExpectedSTOO(PropBuilder expectedSvcResultProp,
310         ServiceTopologyOperationInput expectedServiceTopologyOperationInput) {
311         return build(
312             serviceTopologyOperationOutput()
313                 .setSvcRequestId(expectedServiceTopologyOperationInput.getSdncRequestHeader().getSvcRequestId())
314                 .setResponseCode(expectedSvcResultProp.get(svcClient.errorCode))
315                 .setAckFinalIndicator(expectedSvcResultProp.get(svcClient.ackFinal))
316                 .setResponseMessage(expectedSvcResultProp.get(svcClient.errorMessage))
317                 .setServiceResponseInformation(build(serviceResponseInformation()
318                     .setInstanceId(expectedServiceTopologyOperationInput.getServiceInformation().getServiceInstanceId())
319                     .setObjectPath(expectedSvcResultProp.get(svcClient.serviceObjectPath))
320                 ))
321         );
322     }
323
324     private Service createExpectedService(
325         ServiceTopologyOperationOutput expectedServiceTopologyOperationOutput,
326         ServiceTopologyOperationInput expectedServiceTopologyOperationInput,
327         Service actualService
328     ) {
329
330         //We cannot predict the timeStamp value so just steal it from the actual
331         //we need this to prevent the equals method from returning false as a result of the timestamp
332         String responseTimeStamp = actualService == null || actualService.getServiceStatus() == null ?
333             null : actualService.getServiceStatus().getResponseTimestamp();
334
335         SdncRequestHeader expectedSdncRequestHeader = expectedServiceTopologyOperationInput.getSdncRequestHeader();
336         ServiceInformation expectedServiceInformation = expectedServiceTopologyOperationInput.getServiceInformation();
337         RequestInformation expectedRequestInformation = expectedServiceTopologyOperationInput.getRequestInformation();
338
339         return build(
340             service()
341                 .setServiceInstanceId(expectedServiceInformation.getServiceInstanceId())
342                 .setServiceData(build(serviceData()))
343                 .setServiceStatus(
344                     build(
345                         serviceStatus()
346                             .setAction(expectedRequestInformation.getRequestAction().name())
347                             .setFinalIndicator(expectedServiceTopologyOperationOutput.getAckFinalIndicator())
348                             .setResponseCode(expectedServiceTopologyOperationOutput.getResponseCode())
349                             .setResponseMessage(expectedServiceTopologyOperationOutput.getResponseMessage())
350                             .setRpcAction(toRpcAction(expectedSdncRequestHeader.getSvcAction()))
351                             .setRpcName(SVC_OPERATION)
352                             .setRequestStatus(ServiceStatus.RequestStatus.Synccomplete)
353                             .setResponseTimestamp(responseTimeStamp)
354                     )
355                 )
356         );
357
358     }
359
360     public ServiceStatus.RpcAction toRpcAction(SvcAction fromEnum) {
361         return fromEnum == null ? null : ServiceStatus.RpcAction.valueOf(fromEnum.name());
362     }
363
364
365 }