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