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