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