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