021daddb9c99e9a330e71b12174e0c5f30ecda30
[sdnc/northbound.git] / generic-resource-api / provider / src / main / java / org / onap / sdnc / northbound / GenericResourceApiProvider.java
1 package org.onap.sdnc.northbound;
2
3 import com.google.common.base.Optional;
4 import com.google.common.util.concurrent.CheckedFuture;
5 import com.google.common.util.concurrent.Futures;
6 import java.text.DateFormat;
7 import java.text.SimpleDateFormat;
8 import java.util.Date;
9 import java.util.Properties;
10 import java.util.TimeZone;
11 import java.util.concurrent.ExecutionException;
12 import java.util.concurrent.ExecutorService;
13 import java.util.concurrent.Executors;
14 import java.util.concurrent.Future;
15 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
16 import org.opendaylight.controller.md.sal.binding.api.NotificationPublishService;
17 import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
18 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
19 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
20 import org.opendaylight.controller.md.sal.common.api.data.OptimisticLockFailedException;
21 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
22 import org.opendaylight.controller.sal.binding.api.BindingAwareBroker;
23 import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
24 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.BrgTopologyOperationInput;
25 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.BrgTopologyOperationInputBuilder;
26 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.BrgTopologyOperationOutput;
27 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.BrgTopologyOperationOutputBuilder;
28 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.ContrailRouteTopologyOperationInput;
29 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.ContrailRouteTopologyOperationInputBuilder;
30 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.ContrailRouteTopologyOperationOutput;
31 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.ContrailRouteTopologyOperationOutputBuilder;
32 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.GENERICRESOURCEAPIService;
33 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.NetworkTopologyOperationInput;
34 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.NetworkTopologyOperationInputBuilder;
35 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.NetworkTopologyOperationOutput;
36 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.NetworkTopologyOperationOutputBuilder;
37 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.PreloadNetworkTopologyOperationInput;
38 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.PreloadNetworkTopologyOperationInputBuilder;
39 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.PreloadNetworkTopologyOperationOutput;
40 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.PreloadNetworkTopologyOperationOutputBuilder;
41 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.PreloadVnfTopologyOperationInput;
42 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.PreloadVnfTopologyOperationInputBuilder;
43 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.PreloadVnfTopologyOperationOutput;
44 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.PreloadVnfTopologyOperationOutputBuilder;
45 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.PreloadVnfs;
46 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.PreloadVnfsBuilder;
47 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.SecurityZoneTopologyOperationInput;
48 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.SecurityZoneTopologyOperationInputBuilder;
49 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.SecurityZoneTopologyOperationOutput;
50 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.SecurityZoneTopologyOperationOutputBuilder;
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.ServiceTopologyOperationInputBuilder;
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.ServiceTopologyOperationOutputBuilder;
55 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.Services;
56 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.ServicesBuilder;
57 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.TunnelxconnTopologyOperationInput;
58 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.TunnelxconnTopologyOperationInputBuilder;
59 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.TunnelxconnTopologyOperationOutput;
60 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.TunnelxconnTopologyOperationOutputBuilder;
61 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.VfModuleTopologyOperationInput;
62 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.VfModuleTopologyOperationInputBuilder;
63 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.VfModuleTopologyOperationOutput;
64 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.VfModuleTopologyOperationOutputBuilder;
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.VnfTopologyOperationInputBuilder;
67 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.VnfTopologyOperationOutput;
68 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.VnfTopologyOperationOutputBuilder;
69 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.brg.response.information.BrgResponseInformationBuilder;
70 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.contrail.route.response.information.ContrailRouteResponseInformationBuilder;
71 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.network.response.information.NetworkResponseInformationBuilder;
72 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.preload.data.PreloadData;
73 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.preload.data.PreloadDataBuilder;
74 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.preload.model.information.VnfPreloadList;
75 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.preload.model.information.VnfPreloadListBuilder;
76 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.preload.model.information.VnfPreloadListKey;
77 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.request.information.RequestInformation;
78 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.sdnc.request.header.SdncRequestHeader;
79 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.sdnc.request.header.SdncRequestHeader.SvcAction;
80 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.security.zone.response.information.SecurityZoneResponseInformationBuilder;
81 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.service.data.ServiceData;
82 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.service.data.ServiceDataBuilder;
83 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.service.model.infrastructure.Service;
84 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.service.model.infrastructure.ServiceBuilder;
85 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.service.model.infrastructure.ServiceKey;
86 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.service.response.information.ServiceResponseInformationBuilder;
87 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.service.status.ServiceStatus.RequestStatus;
88 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.service.status.ServiceStatus.RpcAction;
89 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.service.status.ServiceStatusBuilder;
90 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.tunnelxconn.response.information.TunnelxconnResponseInformationBuilder;
91 import org.opendaylight.yangtools.yang.binding.DataObject;
92 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
93 import org.opendaylight.yangtools.yang.common.RpcResult;
94 import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
95 import org.slf4j.Logger;
96 import org.slf4j.LoggerFactory;
97
98 /**
99  * Defines a base implementation for your provider. This class extends from a helper class which provides storage for
100  * the most commonly used components of the MD-SAL. Additionally the base class provides some basic logging and
101  * initialization / clean up methods.
102  *
103  * To use this, copy and paste (overwrite) the following method into the TestApplicationProviderModule class which is
104  * auto generated under src/main/java in this project (created only once during first compilation):
105  *
106  * <pre>
107  *
108  * &#64;Override
109  * public java.lang.AutoCloseable createInstance() {
110  *
111  *      // final GENERIC-RESOURCE-APIProvider provider = new
112  *      // GENERIC-RESOURCE-APIProvider();
113  *      final GenericResourceApiProvider provider = new GenericResourceApiProvider();
114  *      provider.setDataBroker(getDataBrokerDependency());
115  *      provider.setNotificationService(getNotificationServiceDependency());
116  *      provider.setRpcRegistry(getRpcRegistryDependency());
117  *      provider.initialize();
118  *      return new AutoCloseable() {
119  *
120  *              &#64;Override
121  *              public void close() throws Exception {
122  *                      // TODO: CLOSE ANY REGISTRATION OBJECTS CREATED USING ABOVE
123  *                      // BROKER/NOTIFICATION
124  *                      // SERVIE/RPC REGISTRY
125  *                      provider.close();
126  *        }
127  *    };
128  * }
129  *
130  * </pre>
131  */
132
133 public class GenericResourceApiProvider implements AutoCloseable, GENERICRESOURCEAPIService {
134
135     protected static final String APP_NAME = "generic-resource-api";
136     private static final String CALLED_STR = "{} called.";
137     private static final String NULL_OR_EMPTY_ERROR_MESSAGE = "exiting {} because of null or empty service-instance-id";
138     protected static final String NULL_OR_EMPTY_ERROR_PARAM = "invalid input, null or empty service-instance-id";
139     private static final String ADDING_INPUT_DATA_LOG = "Adding INPUT data for {} [{}] input: {}";
140     private static final String ADDING_OPERATIONAL_DATA_LOG = "Adding OPERATIONAL data for {} [{}] operational-data: {}";
141     private static final String OPERATIONAL_DATA_PARAM = "operational-data";
142     protected static final String NO_SERVICE_LOGIC_ACTIVE = "No service logic active for ";
143     private static final String SERVICE_LOGIC_SEARCH_ERROR_MESSAGE = "Caught exception looking for service logic";
144     private static final String ERROR_CODE_PARAM = "error-code";
145     private static final String ERROR_MESSAGE_PARAM = "error-message";
146     private static final String ACK_FINAL_PARAM = "ack-final";
147     private static final String SERVICE_OBJECT_PATH_PARAM = "service-object-path";
148     private static final String UPDATING_MDSAL_ERROR_MESSAGE = "Caught Exception updating MD-SAL for {} [{}] \n";
149     private static final String UPDATING_MDSAL_ERROR_MESSAGE_2 = "Caught Exception updating MD-SAL for {} [{},{}] \n";
150     private static final String RETURNED_FAILED_MESSAGE = "Returned FAILED for {} [{}] {}";
151     private static final String UPDATING_MDSAL_INFO_MESSAGE = "Updating MD-SAL for {} [{}] ServiceData: {}";
152     private static final String UPDATED_MDSAL_INFO_MESSAGE = "Updated MD-SAL for {} [{}]";
153     private static final String RETURNED_SUCCESS_MESSAGE = "Returned SUCCESS for {} [{}] {}";
154     private static final String NON_NULL_PARAM = "non-null";
155     private static final String NULL_PARAM = "null";
156     private static final String SERVICE_LOGIC_EXECUTION_ERROR_MESSAGE = "Caught exception executing service logic for {} ";
157     private static final String UPDATING_TREE_INFO_MESSAGE = "Updating OPERATIONAL tree.";
158     private static final String EMPTY_SERVICE_INSTANCE_MESSAGE = "exiting {} because the service-instance does not have any service data in SDNC";
159     private static final String INVALID_INPUT_ERROR_MESSAGE = "invalid input: the service-instance does not have any service data in SDNC";
160     private static final String ALLOTTED_RESOURCE_ID_PARAM = "allotted-resource-id";
161     private static final String ERROR_NETWORK_ID = "error";
162
163     private final Logger log = LoggerFactory.getLogger(GenericResourceApiProvider.class);
164     private final ExecutorService executor;
165     private final GenericResourceApiSvcLogicServiceClient svcLogicClient;
166
167     protected DataBroker dataBroker;
168     protected NotificationPublishService notificationService;
169     protected RpcProviderRegistry rpcRegistry;
170     protected BindingAwareBroker.RpcRegistration<GENERICRESOURCEAPIService> rpcRegistration;
171
172     public GenericResourceApiProvider(
173         DataBroker dataBroker,
174         NotificationPublishService notificationPublishService,
175         RpcProviderRegistry rpcProviderRegistry,
176         GenericResourceApiSvcLogicServiceClient client
177     ) {
178         log.info("Creating provider for {}", APP_NAME);
179         executor = Executors.newFixedThreadPool(1);
180         setDataBroker(dataBroker);
181         setNotificationService(notificationPublishService);
182         setRpcRegistry(rpcProviderRegistry);
183         svcLogicClient = client;
184         initialize();
185
186     }
187
188     public void initialize() {
189         log.info("Initializing provider for {}", APP_NAME);
190         // Create the top level containers
191         createContainers();
192         try {
193             GenericResourceApiUtil.loadProperties();
194         } catch (Exception e) {
195             log.error("Caught Exception while trying to load properties file", e);
196         }
197
198         log.info("Initialization complete for {}", APP_NAME);
199     }
200
201     protected void initializeChild() {
202         // Override if you have custom initialization intelligence
203     }
204
205     @Override
206     public void close() throws Exception {
207         log.info("Closing provider for {}", APP_NAME);
208         executor.shutdown();
209         rpcRegistration.close();
210         log.info("Successfully closed provider for {}", APP_NAME);
211     }
212
213     private static class Iso8601Util {
214
215         private static TimeZone timeZone = TimeZone.getTimeZone("UTC");
216         private static DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
217
218         private Iso8601Util() {
219         }
220
221         static {
222             dateFormat.setTimeZone(timeZone);
223         }
224
225         private static String now() {
226             return dateFormat.format(new Date());
227         }
228     }
229
230     public void setDataBroker(DataBroker dataBroker) {
231         this.dataBroker = dataBroker;
232         if (log.isDebugEnabled()) {
233             log.debug("DataBroker set to {}", dataBroker == null ? NULL_PARAM : NON_NULL_PARAM);
234         }
235     }
236
237     public void setNotificationService(NotificationPublishService notificationService) {
238         this.notificationService = notificationService;
239         if (log.isDebugEnabled()) {
240             log.debug("Notification Service set to {}", notificationService == null ? NULL_PARAM : NON_NULL_PARAM);
241         }
242     }
243
244     public void setRpcRegistry(RpcProviderRegistry rpcRegistry) {
245         this.rpcRegistry = rpcRegistry;
246         if (log.isDebugEnabled()) {
247             log.debug("RpcRegistry set to {}", rpcRegistry == null ? NULL_PARAM : NON_NULL_PARAM);
248         }
249     }
250
251     private void createContainers() {
252
253         final WriteTransaction t = dataBroker.newReadWriteTransaction();
254
255         // Create the service-instance container
256         t.merge(LogicalDatastoreType.CONFIGURATION, InstanceIdentifier.create(Services.class),
257             new ServicesBuilder().build());
258         t.merge(LogicalDatastoreType.OPERATIONAL, InstanceIdentifier.create(Services.class),
259             new ServicesBuilder().build());
260
261         // Create the PreloadVnfs container
262         t.merge(LogicalDatastoreType.CONFIGURATION, InstanceIdentifier.create(PreloadVnfs.class),
263             new PreloadVnfsBuilder().build());
264         t.merge(LogicalDatastoreType.OPERATIONAL, InstanceIdentifier.create(PreloadVnfs.class),
265             new PreloadVnfsBuilder().build());
266
267         try {
268             CheckedFuture<Void, TransactionCommitFailedException> checkedFuture = t.submit();
269             checkedFuture.get();
270             log.info("Create containers succeeded!");
271
272         } catch (InterruptedException | ExecutionException e) {
273             log.error("Create containers failed: ", e);
274         }
275     }
276
277     private void setServiceStatus(ServiceStatusBuilder serviceStatusBuilder, String errorCode, String errorMessage,
278         String ackFinal) {
279         serviceStatusBuilder.setResponseCode(errorCode);
280         serviceStatusBuilder.setResponseMessage(errorMessage);
281         serviceStatusBuilder.setFinalIndicator(ackFinal);
282         serviceStatusBuilder.setResponseTimestamp(Iso8601Util.now());
283     }
284
285     private void setServiceStatus(ServiceStatusBuilder serviceStatusBuilder, RequestInformation requestInformation) {
286         if (requestInformation != null && requestInformation.getRequestAction() != null) {
287             serviceStatusBuilder.setAction(requestInformation.getRequestAction().toString());
288         }
289     }
290
291     private void setServiceStatus(ServiceStatusBuilder serviceStatusBuilder, SdncRequestHeader requestHeader) {
292         if (requestHeader != null && requestHeader.getSvcAction() != null) {
293             switch (requestHeader.getSvcAction()) {
294                 case Assign:
295                     serviceStatusBuilder.setRpcAction(RpcAction.Assign);
296                     break;
297                 case Unassign:
298                     serviceStatusBuilder.setRpcAction(RpcAction.Unassign);
299                     break;
300                 case Activate:
301                     serviceStatusBuilder.setRpcAction(RpcAction.Activate);
302                     break;
303                 case Deactivate:
304                     serviceStatusBuilder.setRpcAction(RpcAction.Deactivate);
305                     break;
306                 case Delete:
307                     serviceStatusBuilder.setRpcAction(RpcAction.Delete);
308                     break;
309                 default:
310                     log.error("Unknown SvcAction: {}", requestHeader.getSvcAction());
311                     break;
312             }
313         }
314     }
315
316     private void getServiceData(String siid, ServiceDataBuilder serviceDataBuilder) {
317         // default to config
318         getServiceData(siid, serviceDataBuilder, LogicalDatastoreType.CONFIGURATION);
319     }
320
321     private void getServiceData(String siid, ServiceDataBuilder serviceDataBuilder, LogicalDatastoreType type) {
322         // See if any data exists yet for this siid, if so grab it.
323         InstanceIdentifier<Service> serviceInstanceIdentifier = InstanceIdentifier
324             .builder(Services.class)
325             .child(Service.class, new ServiceKey(siid))
326             .build();
327
328         ReadOnlyTransaction readTx = dataBroker.newReadOnlyTransaction();
329         Optional<Service> data = Optional.absent();
330         try {
331             data = readTx.read(type, serviceInstanceIdentifier).get();
332         } catch (InterruptedException | ExecutionException e) {
333             log.error("Caught Exception reading MD-SAL ({}) data for [{}] ", type, siid, e);
334         }
335
336         if (data != null && data.isPresent()) {
337             ServiceData serviceData = data.get().getServiceData();
338             if (serviceData != null) {
339                 log.info("Read MD-SAL ({}) data for [{}] ServiceData: {}", type, siid, serviceData);
340                 serviceDataBuilder.setSdncRequestHeader(serviceData.getSdncRequestHeader());
341                 serviceDataBuilder.setRequestInformation(serviceData.getRequestInformation());
342                 serviceDataBuilder.setServiceInformation(serviceData.getServiceInformation());
343                 serviceDataBuilder.setServiceRequestInput(serviceData.getServiceRequestInput());
344                 serviceDataBuilder.setServiceTopology(serviceData.getServiceTopology());
345                 serviceDataBuilder.setServiceLevelOperStatus(serviceData.getServiceLevelOperStatus());
346                 serviceDataBuilder.setNetworks(serviceData.getNetworks());
347                 serviceDataBuilder.setVnfs(serviceData.getVnfs());
348                 serviceDataBuilder.setProvidedAllottedResources(serviceData.getProvidedAllottedResources());
349                 serviceDataBuilder.setConsumedAllottedResources(serviceData.getConsumedAllottedResources());
350                 // service-instance-id needs to be set
351             } else {
352                 log.info("No service-data found in MD-SAL ({}) for [{}]", type, siid);
353             }
354         } else {
355             log.info("No data found in MD-SAL ({}) for [{}]", type, siid);
356         }
357     }
358
359     private void getPreloadData(String vnfName, String vnfType, PreloadDataBuilder preloadDataBuilder) {
360         // default to config
361         getPreloadData(vnfName, vnfType, preloadDataBuilder, LogicalDatastoreType.CONFIGURATION);
362     }
363
364     private void getPreloadData(String preloadName, String preloadType, PreloadDataBuilder preloadDataBuilder,
365         LogicalDatastoreType type) {
366         // See if any data exists yet for this name/type, if so grab it.
367         InstanceIdentifier<VnfPreloadList> preloadInstanceIdentifier = InstanceIdentifier
368             .builder(PreloadVnfs.class)
369             .child(VnfPreloadList.class, new VnfPreloadListKey(preloadName, preloadType))
370             .build();
371
372         ReadOnlyTransaction readTx = dataBroker.newReadOnlyTransaction();
373         Optional<VnfPreloadList> data = Optional.absent();
374         try {
375             data = readTx.read(type, preloadInstanceIdentifier).get();
376         } catch (InterruptedException | ExecutionException e) {
377             log.error("Caught Exception reading MD-SAL ({}) for [{},{}] ", type, preloadName, preloadType, e);
378         }
379
380         if (data != null && data.isPresent()) {
381             PreloadData preloadData = data.get().getPreloadData();
382             if (preloadData != null) {
383                 log.info("Read MD-SAL ({}) data for [{},{}] PreloadData: {}", type, preloadName, preloadType,
384                     preloadData);
385                 preloadDataBuilder.setVnfTopologyInformation(preloadData.getVnfTopologyInformation());
386                 preloadDataBuilder.setNetworkTopologyInformation(preloadData.getNetworkTopologyInformation());
387                 preloadDataBuilder.setOperStatus(preloadData.getOperStatus());
388             } else {
389                 log.info("No preload-data found in MD-SAL ({}) for [{},{}] ", type, preloadName, preloadType);
390             }
391         } else {
392             log.info("No data found in MD-SAL ({}) for [{},{}] ", type, preloadName, preloadType);
393         }
394     }
395
396     private void saveService(final Service entry, boolean merge, LogicalDatastoreType storeType) {
397         // Each entry will be identifiable by a unique key, we have to create that
398         // identifier
399         InstanceIdentifier<Service> path = InstanceIdentifier
400             .builder(Services.class)
401             .child(Service.class, entry.getKey())
402             .build();
403
404         trySaveEntry(entry, merge, storeType, path);
405     }
406
407     private void savePreloadList(final VnfPreloadList entry, boolean merge, LogicalDatastoreType storeType) {
408
409         // Each entry will be identifiable by a unique key, we have to create that
410         // identifier
411         InstanceIdentifier<VnfPreloadList> path = InstanceIdentifier
412             .builder(PreloadVnfs.class)
413             .child(VnfPreloadList.class, entry.getKey())
414             .build();
415
416         trySaveEntry(entry, merge, storeType, path);
417     }
418
419     private <T extends DataObject> void trySaveEntry(T entry, boolean merge, LogicalDatastoreType storeType,
420         InstanceIdentifier<T> path) {
421         int tries = 2;
422         while (true) {
423             try {
424                 save(entry, merge, storeType, path);
425                 break;
426             } catch (OptimisticLockFailedException e) {
427                 if (--tries <= 0) {
428                     log.debug("Got OptimisticLockFailedException on last try - failing ");
429                     throw new IllegalStateException(e);
430                 }
431                 log.debug("Got OptimisticLockFailedException - trying again ");
432             } catch (TransactionCommitFailedException ex) {
433                 log.debug("Update DataStore failed");
434                 throw new IllegalStateException(ex);
435             }
436         }
437     }
438
439     private <T extends DataObject> void save(T entry, boolean merge, LogicalDatastoreType storeType,
440         InstanceIdentifier<T> path)
441         throws TransactionCommitFailedException {
442         WriteTransaction tx = dataBroker.newWriteOnlyTransaction();
443         if (merge) {
444             tx.merge(storeType, path, entry);
445         } else {
446             tx.put(storeType, path, entry);
447         }
448         tx.submit().checkedGet();
449         log.debug("Update DataStore succeeded");
450     }
451
452     private void deleteService(final Service entry, LogicalDatastoreType storeType) {
453         // Each entry will be identifiable by a unique key, we have to create
454         // that identifier
455         InstanceIdentifier<Service> path = InstanceIdentifier
456             .builder(Services.class)
457             .child(Service.class, entry.getKey())
458             .build();
459
460         tryDeleteEntry(storeType, path);
461     }
462
463     private void tryDeleteEntry(LogicalDatastoreType storeType, InstanceIdentifier<Service> path) {
464         int tries = 2;
465         while (true) {
466             try {
467                 delete(storeType, path);
468                 break;
469             } catch (OptimisticLockFailedException e) {
470                 if (--tries <= 0) {
471                     log.debug("Got OptimisticLockFailedException on last try - failing ");
472                     throw new IllegalStateException(e);
473                 }
474                 log.debug("Got OptimisticLockFailedException - trying again ");
475             } catch (TransactionCommitFailedException ex) {
476                 log.debug("Update DataStore failed");
477                 throw new IllegalStateException(ex);
478             }
479         }
480     }
481
482     private void delete(LogicalDatastoreType storeType, InstanceIdentifier<Service> path)
483         throws TransactionCommitFailedException {
484         WriteTransaction tx = dataBroker.newWriteOnlyTransaction();
485         tx.delete(storeType, path);
486         tx.submit().checkedGet();
487         log.debug("DataStore delete succeeded");
488     }
489
490     @Override
491     public Future<RpcResult<ServiceTopologyOperationOutput>> serviceTopologyOperation(
492         ServiceTopologyOperationInput input) {
493
494         final String svcOperation = "service-topology-operation";
495         ServiceData serviceData;
496         ServiceStatusBuilder serviceStatusBuilder = new ServiceStatusBuilder();
497         Properties parms = new Properties();
498
499         log.info(CALLED_STR, svcOperation);
500         // create a new response object
501         ServiceTopologyOperationOutputBuilder responseBuilder = new ServiceTopologyOperationOutputBuilder();
502
503         if (hasInvalidService(input)) {
504             log.debug(NULL_OR_EMPTY_ERROR_MESSAGE, svcOperation);
505             responseBuilder.setResponseCode("404");
506             responseBuilder.setResponseMessage(NULL_OR_EMPTY_ERROR_PARAM);
507             responseBuilder.setAckFinalIndicator("Y");
508
509             RpcResult<ServiceTopologyOperationOutput> rpcResult = RpcResultBuilder
510                 .<ServiceTopologyOperationOutput>status(true)
511                 .withResult(responseBuilder.build())
512                 .build();
513
514             return Futures.immediateFuture(rpcResult);
515         }
516
517         // Grab the service instance ID from the input buffer
518         String siid = input.getServiceInformation().getServiceInstanceId();
519
520         trySetSvcRequestId(input, responseBuilder);
521
522         ServiceDataBuilder serviceDataBuilder = new ServiceDataBuilder();
523         getServiceData(siid, serviceDataBuilder);
524
525         ServiceDataBuilder operDataBuilder = new ServiceDataBuilder();
526         getServiceData(siid, operDataBuilder, LogicalDatastoreType.OPERATIONAL);
527
528         // Set the serviceStatus based on input
529         setServiceStatus(serviceStatusBuilder, input.getSdncRequestHeader());
530         setServiceStatus(serviceStatusBuilder, input.getRequestInformation());
531
532                 /*
533          * // setup a service-data object builder // ACTION service-topology-operation
534                  * // INPUT: // USES uses service-operation-information // OUTPUT: // uses
535                  * topology-response-common; // uses service-response-information;
536                  */
537
538         log.info(ADDING_INPUT_DATA_LOG, svcOperation, siid, input);
539         ServiceTopologyOperationInputBuilder inputBuilder = new ServiceTopologyOperationInputBuilder(input);
540         GenericResourceApiUtil.toProperties(parms, inputBuilder.build());
541
542         log.info(ADDING_OPERATIONAL_DATA_LOG, svcOperation, siid,
543             operDataBuilder.build());
544         GenericResourceApiUtil.toProperties(parms, OPERATIONAL_DATA_PARAM, operDataBuilder);
545
546         // Call SLI sync method
547         // Get SvcLogicService reference
548
549         ResponseObject responseObject = new ResponseObject("200", "");
550         String ackFinal = "Y";
551         String serviceObjectPath = null;
552         Properties respProps = tryGetProperties(svcOperation, parms, serviceDataBuilder, responseObject);
553
554         if (respProps != null) {
555             responseObject.setStatusCode(respProps.getProperty(ERROR_CODE_PARAM));
556             responseObject.setMessage(respProps.getProperty(ERROR_MESSAGE_PARAM));
557             ackFinal = respProps.getProperty(ACK_FINAL_PARAM, "Y");
558             serviceObjectPath = respProps.getProperty(SERVICE_OBJECT_PATH_PARAM);
559         }
560
561         setServiceStatus(serviceStatusBuilder, responseObject.getStatusCode(), responseObject.getMessage(), ackFinal);
562         serviceStatusBuilder.setRequestStatus(RequestStatus.Synccomplete);
563         serviceStatusBuilder.setRpcName(svcOperation);
564
565         if (failed(responseObject)) {
566             responseBuilder.setResponseCode(responseObject.getStatusCode());
567             responseBuilder.setResponseMessage(responseObject.getMessage());
568             responseBuilder.setAckFinalIndicator(ackFinal);
569
570             ServiceBuilder serviceBuilder = new ServiceBuilder();
571             serviceBuilder.setServiceInstanceId(siid);
572             serviceBuilder.setServiceStatus(serviceStatusBuilder.build());
573             try {
574                 saveService(serviceBuilder.build(), true, LogicalDatastoreType.CONFIGURATION);
575             } catch (Exception e) {
576                 log.error(UPDATING_MDSAL_ERROR_MESSAGE, svcOperation, siid, e);
577             }
578             log.error(RETURNED_FAILED_MESSAGE, svcOperation, siid, responseBuilder.build());
579
580             RpcResult<ServiceTopologyOperationOutput> rpcResult = RpcResultBuilder
581                 .<ServiceTopologyOperationOutput>status(true)
582                 .withResult(responseBuilder.build())
583                 .build();
584
585             return Futures.immediateFuture(rpcResult);
586         }
587
588         // Got success from SLI
589         try {
590             serviceData = serviceDataBuilder.build();
591             log.info(UPDATING_MDSAL_INFO_MESSAGE, svcOperation, siid, serviceData);
592
593             // service object
594             ServiceBuilder serviceBuilder = new ServiceBuilder();
595             serviceBuilder.setServiceData(serviceData);
596             serviceBuilder.setServiceInstanceId(siid);
597             serviceBuilder.setServiceStatus(serviceStatusBuilder.build());
598             saveService(serviceBuilder.build(), false, LogicalDatastoreType.CONFIGURATION);
599
600             tryDeleteService(input, serviceBuilder);
601
602             ServiceResponseInformationBuilder serviceResponseInformationBuilder = new ServiceResponseInformationBuilder();
603             serviceResponseInformationBuilder.setInstanceId(siid);
604             serviceResponseInformationBuilder.setObjectPath(serviceObjectPath);
605             responseBuilder.setServiceResponseInformation(serviceResponseInformationBuilder.build());
606
607         } catch (Exception e) {
608             log.error(UPDATING_MDSAL_ERROR_MESSAGE, svcOperation, siid, e);
609             responseBuilder.setResponseCode("500");
610             responseBuilder.setResponseMessage(e.getMessage());
611             responseBuilder.setAckFinalIndicator("Y");
612             log.error(RETURNED_FAILED_MESSAGE, svcOperation, siid, responseBuilder.build());
613
614             RpcResult<ServiceTopologyOperationOutput> rpcResult = RpcResultBuilder
615                 .<ServiceTopologyOperationOutput>status(true)
616                 .withResult(responseBuilder.build())
617                 .build();
618
619             return Futures.immediateFuture(rpcResult);
620         }
621
622         // Update succeeded
623         responseBuilder.setResponseCode(responseObject.getStatusCode());
624         responseBuilder.setAckFinalIndicator(ackFinal);
625         trySetResponseMessage(responseBuilder, responseObject);
626         log.info(UPDATED_MDSAL_INFO_MESSAGE, svcOperation, siid);
627         log.info(RETURNED_SUCCESS_MESSAGE, svcOperation, siid, responseBuilder.build());
628
629         RpcResult<ServiceTopologyOperationOutput> rpcResult = RpcResultBuilder
630             .<ServiceTopologyOperationOutput>status(true)
631             .withResult(responseBuilder.build())
632             .build();
633
634         return Futures.immediateFuture(rpcResult);
635     }
636
637     private void trySetResponseMessage(ServiceTopologyOperationOutputBuilder responseBuilder, ResponseObject error) {
638         if (!error.getMessage().isEmpty()) {
639             responseBuilder.setResponseMessage(error.getMessage());
640         }
641     }
642
643     private boolean hasInvalidService(ServiceTopologyOperationInput input) {
644         return input == null || input.getServiceInformation() == null
645             || input.getServiceInformation().getServiceInstanceId() == null
646             || input.getServiceInformation().getServiceInstanceId().length() == 0;
647     }
648
649     private void trySetSvcRequestId(ServiceTopologyOperationInput input,
650         ServiceTopologyOperationOutputBuilder responseBuilder) {
651         if (input.getSdncRequestHeader() != null) {
652             responseBuilder.setSvcRequestId(input.getSdncRequestHeader().getSvcRequestId());
653         }
654     }
655
656     private void tryDeleteService(ServiceTopologyOperationInput input, ServiceBuilder serviceBuilder) {
657         if (isValidRequest(input) && input.getSdncRequestHeader().getSvcAction().equals(SvcAction.Delete)) {
658             // Only update operational tree on delete
659             log.info("Delete from both CONFIGURATION and OPERATIONAL tree.");
660             deleteService(serviceBuilder.build(), LogicalDatastoreType.OPERATIONAL);
661             deleteService(serviceBuilder.build(), LogicalDatastoreType.CONFIGURATION);
662         }
663     }
664
665     private Properties tryGetProperties(String svcOperation, Properties parms, ServiceDataBuilder serviceDataBuilder,
666         ResponseObject responseObject) {
667         try {
668             if (svcLogicClient.hasGraph(APP_NAME, svcOperation, null, "sync")) {
669                 try {
670                     return svcLogicClient.execute(APP_NAME, svcOperation, null, "sync", serviceDataBuilder, parms);
671                 } catch (Exception e) {
672                     log.error(SERVICE_LOGIC_EXECUTION_ERROR_MESSAGE, svcOperation, e);
673                     responseObject.setMessage(e.getMessage());
674                     responseObject.setStatusCode("500");
675                 }
676             } else {
677                 responseObject.setMessage(NO_SERVICE_LOGIC_ACTIVE + APP_NAME + ": '" + svcOperation + "'");
678                 responseObject.setStatusCode("503");
679             }
680         } catch (Exception e) {
681             responseObject.setMessage(e.getMessage());
682             responseObject.setStatusCode("500");
683             log.error(SERVICE_LOGIC_SEARCH_ERROR_MESSAGE, e);
684         }
685
686         return null;
687     }
688
689     private boolean failed(ResponseObject error) {
690         return
691             !error.getStatusCode().isEmpty() && !("0".equals(error.getStatusCode()) || "200"
692                 .equals(error.getStatusCode()));
693     }
694
695     private boolean isValidRequest(ServiceTopologyOperationInput input) {
696         return input.getSdncRequestHeader() != null && input.getSdncRequestHeader().getSvcAction() != null;
697     }
698
699     @Override
700     public Future<RpcResult<VnfTopologyOperationOutput>> vnfTopologyOperation(VnfTopologyOperationInput input) {
701
702         final String svcOperation = "vnf-topology-operation";
703         ServiceData serviceData;
704         ServiceStatusBuilder serviceStatusBuilder = new ServiceStatusBuilder();
705         Properties properties = new Properties();
706
707         log.info(CALLED_STR, svcOperation);
708         // create a new response object
709         VnfTopologyOperationOutputBuilder responseBuilder = new VnfTopologyOperationOutputBuilder();
710
711         if (hasInvalidService(input)) {
712
713             log.debug(NULL_OR_EMPTY_ERROR_MESSAGE, svcOperation);
714             responseBuilder.setResponseCode("404");
715             responseBuilder.setResponseMessage(NULL_OR_EMPTY_ERROR_PARAM);
716             responseBuilder.setAckFinalIndicator("Y");
717             RpcResult<VnfTopologyOperationOutput> rpcResult = RpcResultBuilder.<VnfTopologyOperationOutput>status(true)
718                 .withResult(responseBuilder.build()).build();
719             // return error
720             return Futures.immediateFuture(rpcResult);
721         }
722
723         // Grab the service instance ID from the input buffer
724         String siid = input.getServiceInformation().getServiceInstanceId();
725
726         trySetSvcRequestId(input, responseBuilder);
727
728         if (hasInvalidVnfId(input)) {
729             log.debug("exiting {} because of null or empty vnf-id", svcOperation);
730             responseBuilder.setResponseCode("404");
731             responseBuilder.setResponseMessage("invalid input, null or empty vnf-id");
732             responseBuilder.setAckFinalIndicator("Y");
733
734             RpcResult<VnfTopologyOperationOutput> rpcResult = RpcResultBuilder
735                 .<VnfTopologyOperationOutput>status(true)
736                 .withResult(responseBuilder.build())
737                 .build();
738
739             return Futures.immediateFuture(rpcResult);
740         }
741
742         ServiceDataBuilder serviceDataBuilder = new ServiceDataBuilder();
743         getServiceData(siid, serviceDataBuilder);
744
745         ServiceDataBuilder operDataBuilder = new ServiceDataBuilder();
746         getServiceData(siid, operDataBuilder, LogicalDatastoreType.OPERATIONAL);
747
748         // Set the serviceStatus based on input
749         setServiceStatus(serviceStatusBuilder, input.getSdncRequestHeader());
750         setServiceStatus(serviceStatusBuilder, input.getRequestInformation());
751
752         //
753         // setup a service-data object builder
754         // ACTION vnf-topology-operation
755         // INPUT:
756         // USES sdnc-request-header;
757         // USES request-information;
758         // USES service-information;
759         // USES vnf-request-information
760         // OUTPUT:
761         // USES vnf-topology-response-body;
762         // USES vnf-information
763         // USES service-information
764         //
765         // container service-data
766         // uses vnf-configuration-information;
767         // uses oper-status;
768
769         log.info(ADDING_INPUT_DATA_LOG, svcOperation, siid, input);
770         VnfTopologyOperationInputBuilder inputBuilder = new VnfTopologyOperationInputBuilder(input);
771         GenericResourceApiUtil.toProperties(properties, inputBuilder.build());
772
773         log.info(ADDING_OPERATIONAL_DATA_LOG, svcOperation, siid,
774             operDataBuilder.build());
775         GenericResourceApiUtil.toProperties(properties, OPERATIONAL_DATA_PARAM, operDataBuilder);
776
777         // Call SLI sync method
778         // Get SvcLogicService reference
779
780         ResponseObject responseObject = new ResponseObject("200", "");
781         String ackFinal = "Y";
782         String serviceObjectPath = null;
783         Properties respProps = tryGetProperties(svcOperation, properties, serviceDataBuilder, responseObject);
784
785         if (respProps != null) {
786             responseObject.setMessage(respProps.getProperty(ERROR_MESSAGE_PARAM));
787             responseObject.setStatusCode(respProps.getProperty(ERROR_CODE_PARAM));
788             ackFinal = respProps.getProperty(ACK_FINAL_PARAM, "Y");
789             serviceObjectPath = respProps.getProperty("vnf-object-path");
790         }
791
792         setServiceStatus(serviceStatusBuilder, responseObject.getStatusCode(), responseObject.getMessage(), ackFinal);
793         serviceStatusBuilder.setRequestStatus(RequestStatus.Synccomplete);
794         serviceStatusBuilder.setRpcName(svcOperation);
795
796         if (failed(responseObject)) {
797             responseBuilder.setResponseCode(responseObject.getStatusCode());
798             responseBuilder.setResponseMessage(responseObject.getMessage());
799             responseBuilder.setAckFinalIndicator(ackFinal);
800
801             ServiceBuilder serviceBuilder = new ServiceBuilder();
802             serviceBuilder.setServiceInstanceId(siid);
803             serviceBuilder.setServiceStatus(serviceStatusBuilder.build());
804             try {
805                 saveService(serviceBuilder.build(), true, LogicalDatastoreType.CONFIGURATION);
806                 trySaveService(input, serviceBuilder);
807             } catch (Exception e) {
808                 log.error(UPDATING_MDSAL_ERROR_MESSAGE, svcOperation, siid, e);
809             }
810             log.error(RETURNED_FAILED_MESSAGE, svcOperation, siid, responseBuilder.build());
811
812             RpcResult<VnfTopologyOperationOutput> rpcResult = RpcResultBuilder
813                 .<VnfTopologyOperationOutput>status(true)
814                 .withResult(responseBuilder.build())
815                 .build();
816
817             // return error
818             return Futures.immediateFuture(rpcResult);
819         }
820
821         // Got success from SLI
822         try {
823             serviceData = serviceDataBuilder.build();
824             log.info(UPDATING_MDSAL_INFO_MESSAGE, svcOperation, siid, serviceData);
825
826             // service object
827             ServiceBuilder serviceBuilder = new ServiceBuilder();
828             serviceBuilder.setServiceData(serviceData);
829             serviceBuilder.setServiceInstanceId(siid);
830             serviceBuilder.setServiceStatus(serviceStatusBuilder.build());
831             saveService(serviceBuilder.build(), false, LogicalDatastoreType.CONFIGURATION);
832
833             if (isValidRequest(input) && input.getSdncRequestHeader().getSvcAction().equals(SvcAction.Activate)) {
834                 // Only update operational tree on Assign
835
836                 log.info(UPDATING_TREE_INFO_MESSAGE);
837                 saveService(serviceBuilder.build(), false, LogicalDatastoreType.OPERATIONAL);
838             }
839
840             ServiceResponseInformationBuilder serviceResponseInformationBuilder = new ServiceResponseInformationBuilder();
841             serviceResponseInformationBuilder.setInstanceId(siid);
842             serviceResponseInformationBuilder.setObjectPath(serviceObjectPath);
843             responseBuilder.setServiceResponseInformation(serviceResponseInformationBuilder.build());
844
845         } catch (Exception e) {
846             log.error(UPDATING_MDSAL_ERROR_MESSAGE, svcOperation, siid, e);
847             responseBuilder.setResponseCode("500");
848             responseBuilder.setResponseMessage(e.getMessage());
849             responseBuilder.setAckFinalIndicator("Y");
850             log.error(RETURNED_FAILED_MESSAGE, svcOperation, siid, responseBuilder.build());
851
852             RpcResult<VnfTopologyOperationOutput> rpcResult = RpcResultBuilder
853                 .<VnfTopologyOperationOutput>status(true)
854                 .withResult(responseBuilder.build())
855                 .build();
856
857             return Futures.immediateFuture(rpcResult);
858         }
859
860         // Update succeeded
861         responseBuilder.setResponseCode(responseObject.getStatusCode());
862         responseBuilder.setAckFinalIndicator(ackFinal);
863         trySetResponseMessage(responseBuilder, responseObject);
864         log.info(UPDATED_MDSAL_INFO_MESSAGE, svcOperation, siid);
865         log.info(RETURNED_SUCCESS_MESSAGE, svcOperation, siid, responseBuilder.build());
866
867         RpcResult<VnfTopologyOperationOutput> rpcResult = RpcResultBuilder
868             .<VnfTopologyOperationOutput>status(true)
869             .withResult(responseBuilder.build())
870             .build();
871
872         // return success
873         return Futures.immediateFuture(rpcResult);
874     }
875
876     private void trySetResponseMessage(VnfTopologyOperationOutputBuilder responseBuilder, ResponseObject error) {
877         if (!error.getMessage().isEmpty()) {
878             responseBuilder.setResponseMessage(error.getMessage());
879         }
880     }
881
882     private void trySaveService(VnfTopologyOperationInput input, ServiceBuilder serviceBuilder) {
883         if (isValidRequest(input) &&
884             (input.getSdncRequestHeader().getSvcAction().equals(SvcAction.Delete) ||
885                 input.getSdncRequestHeader().getSvcAction().equals(SvcAction.Activate))) {
886
887             // Only update operational tree on activate or delete
888             log.info(UPDATING_TREE_INFO_MESSAGE);
889             saveService(serviceBuilder.build(), false, LogicalDatastoreType.OPERATIONAL);
890         }
891     }
892
893     private boolean hasInvalidVnfId(VnfTopologyOperationInput input) {
894         return input.getVnfInformation() == null || input.getVnfInformation().getVnfId() == null
895             || input.getVnfInformation().getVnfId().length() == 0;
896     }
897
898     private boolean hasInvalidService(VnfTopologyOperationInput input) {
899         return input == null || input.getServiceInformation() == null
900             || input.getServiceInformation().getServiceInstanceId() == null
901             || input.getServiceInformation().getServiceInstanceId().length() == 0;
902     }
903
904     private void trySetSvcRequestId(VnfTopologyOperationInput input,
905         VnfTopologyOperationOutputBuilder responseBuilder) {
906         if (input.getSdncRequestHeader() != null) {
907             responseBuilder.setSvcRequestId(input.getSdncRequestHeader().getSvcRequestId());
908         }
909     }
910
911     private boolean isValidRequest(VnfTopologyOperationInput input) {
912         return input.getSdncRequestHeader() != null && input.getSdncRequestHeader().getSvcAction() != null;
913     }
914
915     @Override
916     public Future<RpcResult<VfModuleTopologyOperationOutput>> vfModuleTopologyOperation(
917         VfModuleTopologyOperationInput input) {
918
919         final String svcOperation = "vf-module-topology-operation";
920         ServiceData serviceData;
921         ServiceStatusBuilder serviceStatusBuilder = new ServiceStatusBuilder();
922         Properties parms = new Properties();
923
924         log.info(CALLED_STR, svcOperation);
925         // create a new response object
926         VfModuleTopologyOperationOutputBuilder responseBuilder = new VfModuleTopologyOperationOutputBuilder();
927
928         if (hasInvalidService(input)) {
929             log.debug(NULL_OR_EMPTY_ERROR_MESSAGE, svcOperation);
930             responseBuilder.setResponseCode("403");
931             responseBuilder.setResponseMessage(NULL_OR_EMPTY_ERROR_PARAM);
932             responseBuilder.setAckFinalIndicator("Y");
933
934             RpcResult<VfModuleTopologyOperationOutput> rpcResult = RpcResultBuilder
935                 .<VfModuleTopologyOperationOutput>status(true)
936                 .withResult(responseBuilder.build())
937                 .build();
938
939             // return error
940             return Futures.immediateFuture(rpcResult);
941         }
942
943         if (hasInvalidVnfId(input)) {
944             log.debug("exiting {} because of null or empty vnf-id", svcOperation);
945             responseBuilder.setResponseCode("403");
946             responseBuilder.setResponseMessage("invalid input, null or empty vnf-id");
947             responseBuilder.setAckFinalIndicator("Y");
948             RpcResult<VfModuleTopologyOperationOutput> rpcResult = RpcResultBuilder
949                 .<VfModuleTopologyOperationOutput>status(true).withResult(responseBuilder.build()).build();
950             return Futures.immediateFuture(rpcResult);
951         }
952
953         if (hasInvalidVfModule(input)) {
954             log.debug("exiting {} because of null or empty vf-module-id", svcOperation);
955             responseBuilder.setResponseCode("403");
956             responseBuilder.setResponseMessage("invalid input, vf-module-id is null or empty");
957             responseBuilder.setAckFinalIndicator("Y");
958
959             RpcResult<VfModuleTopologyOperationOutput> rpcResult = RpcResultBuilder
960                 .<VfModuleTopologyOperationOutput>status(true)
961                 .withResult(responseBuilder.build())
962                 .build();
963
964             return Futures.immediateFuture(rpcResult);
965         }
966
967         // Grab the service instance ID from the input buffer
968         String siid = input.getServiceInformation().getServiceInstanceId();
969
970         trySetSvcRequestId(input, responseBuilder);
971
972         ServiceDataBuilder serviceDataBuilder = new ServiceDataBuilder();
973         getServiceData(siid, serviceDataBuilder);
974
975         ServiceDataBuilder operDataBuilder = new ServiceDataBuilder();
976         getServiceData(siid, operDataBuilder, LogicalDatastoreType.OPERATIONAL);
977
978         // Set the serviceStatus based on input
979         setServiceStatus(serviceStatusBuilder, input.getSdncRequestHeader());
980         setServiceStatus(serviceStatusBuilder, input.getRequestInformation());
981
982         //
983         // setup a service-data object builder
984         // ACTION vnf-topology-operation
985         // INPUT:
986         // USES sdnc-request-header;
987         // USES request-information;
988         // USES service-information;
989         // USES vnf-request-information
990         // OUTPUT:
991         // USES vnf-topology-response-body;
992         // USES vnf-information
993         // USES service-information
994         //
995         // container service-data
996         // uses vnf-configuration-information;
997         // uses oper-status;
998
999         log.info(ADDING_INPUT_DATA_LOG, svcOperation, siid, input);
1000         VfModuleTopologyOperationInputBuilder inputBuilder = new VfModuleTopologyOperationInputBuilder(input);
1001         GenericResourceApiUtil.toProperties(parms, inputBuilder.build());
1002
1003         log.info(ADDING_OPERATIONAL_DATA_LOG, svcOperation, siid,
1004             operDataBuilder.build());
1005         GenericResourceApiUtil.toProperties(parms, OPERATIONAL_DATA_PARAM, operDataBuilder);
1006
1007         // Call SLI sync method
1008         // Get SvcLogicService reference
1009
1010         ResponseObject error = new ResponseObject("200", "");
1011         String ackFinal = "Y";
1012         String serviceObjectPath = null;
1013         Properties respProps = tryGetProperties(svcOperation, parms, serviceDataBuilder, error);
1014
1015         if (respProps != null) {
1016             error.setStatusCode(respProps.getProperty(ERROR_CODE_PARAM));
1017             error.setMessage(respProps.getProperty(ERROR_MESSAGE_PARAM));
1018             ackFinal = respProps.getProperty(ACK_FINAL_PARAM, "Y");
1019             serviceObjectPath = respProps.getProperty("vf-module-object-path");
1020         }
1021
1022         setServiceStatus(serviceStatusBuilder, error.getStatusCode(), error.getMessage(), ackFinal);
1023         serviceStatusBuilder.setRequestStatus(RequestStatus.Synccomplete);
1024         serviceStatusBuilder.setRpcName(svcOperation);
1025
1026         if (failed(error)) {
1027             responseBuilder.setResponseCode(error.getStatusCode());
1028             responseBuilder.setResponseMessage(error.getStatusCode());
1029             responseBuilder.setAckFinalIndicator(ackFinal);
1030
1031             ServiceBuilder serviceBuilder = new ServiceBuilder();
1032             serviceBuilder.setServiceInstanceId(siid);
1033             serviceBuilder.setServiceStatus(serviceStatusBuilder.build());
1034             try {
1035                 saveService(serviceBuilder.build(), true, LogicalDatastoreType.CONFIGURATION);
1036             } catch (Exception e) {
1037                 log.error(UPDATING_MDSAL_ERROR_MESSAGE, svcOperation, siid, e);
1038             }
1039             log.error(RETURNED_FAILED_MESSAGE, svcOperation, siid, responseBuilder.build());
1040
1041             RpcResult<VfModuleTopologyOperationOutput> rpcResult = RpcResultBuilder
1042                 .<VfModuleTopologyOperationOutput>status(true)
1043                 .withResult(responseBuilder.build())
1044                 .build();
1045
1046             // return error
1047             return Futures.immediateFuture(rpcResult);
1048         }
1049
1050         // Got success from SLI
1051         try {
1052             serviceData = serviceDataBuilder.build();
1053             log.info(UPDATING_MDSAL_INFO_MESSAGE, svcOperation, siid, serviceData);
1054
1055             // service object
1056             ServiceBuilder serviceBuilder = new ServiceBuilder();
1057             serviceBuilder.setServiceData(serviceData);
1058             serviceBuilder.setServiceInstanceId(siid);
1059             serviceBuilder.setServiceStatus(serviceStatusBuilder.build());
1060             saveService(serviceBuilder.build(), false, LogicalDatastoreType.CONFIGURATION);
1061
1062             trySaveService(input, serviceBuilder);
1063
1064             ServiceResponseInformationBuilder serviceResponseInformationBuilder = new ServiceResponseInformationBuilder();
1065             serviceResponseInformationBuilder.setInstanceId(siid);
1066             serviceResponseInformationBuilder.setObjectPath(serviceObjectPath);
1067             responseBuilder.setServiceResponseInformation(serviceResponseInformationBuilder.build());
1068
1069         } catch (Exception e) {
1070             log.error(UPDATING_MDSAL_ERROR_MESSAGE, svcOperation, siid, e);
1071             responseBuilder.setResponseCode("500");
1072             responseBuilder.setResponseMessage(e.toString());
1073             responseBuilder.setAckFinalIndicator("Y");
1074             log.error(RETURNED_FAILED_MESSAGE, svcOperation, siid, responseBuilder.build());
1075
1076             RpcResult<VfModuleTopologyOperationOutput> rpcResult = RpcResultBuilder
1077                 .<VfModuleTopologyOperationOutput>status(true)
1078                 .withResult(responseBuilder.build())
1079                 .build();
1080
1081             return Futures.immediateFuture(rpcResult);
1082         }
1083
1084         // Update succeeded
1085         responseBuilder.setResponseCode(error.getStatusCode());
1086         responseBuilder.setAckFinalIndicator(ackFinal);
1087         trySetResponseMessage(responseBuilder, error);
1088         log.info(UPDATED_MDSAL_INFO_MESSAGE, svcOperation, siid);
1089         log.info(RETURNED_SUCCESS_MESSAGE, svcOperation, siid, responseBuilder.build());
1090
1091         RpcResult<VfModuleTopologyOperationOutput> rpcResult = RpcResultBuilder
1092             .<VfModuleTopologyOperationOutput>status(true)
1093             .withResult(responseBuilder.build())
1094             .build();
1095
1096         // return success
1097         return Futures.immediateFuture(rpcResult);
1098     }
1099
1100     private void trySetResponseMessage(VfModuleTopologyOperationOutputBuilder responseBuilder, ResponseObject error) {
1101         if (!error.getMessage().isEmpty()) {
1102             responseBuilder.setResponseMessage(error.getMessage());
1103         }
1104     }
1105
1106     private void trySaveService(VfModuleTopologyOperationInput input, ServiceBuilder serviceBuilder) {
1107         if (isValidRequest(input) &&
1108             (input.getSdncRequestHeader().getSvcAction().equals(SvcAction.Unassign) ||
1109                 input.getSdncRequestHeader().getSvcAction().equals(SvcAction.Activate))) {
1110             // Only update operational tree on activate or delete
1111
1112             log.info(UPDATING_TREE_INFO_MESSAGE);
1113             saveService(serviceBuilder.build(), false, LogicalDatastoreType.OPERATIONAL);
1114         }
1115     }
1116
1117     private void trySetSvcRequestId(VfModuleTopologyOperationInput input,
1118         VfModuleTopologyOperationOutputBuilder responseBuilder) {
1119         if (input.getSdncRequestHeader() != null) {
1120             responseBuilder.setSvcRequestId(input.getSdncRequestHeader().getSvcRequestId());
1121         }
1122     }
1123
1124     private boolean hasInvalidVfModule(VfModuleTopologyOperationInput input) {
1125         return input.getVfModuleInformation() == null || input.getVfModuleInformation().getVfModuleId() == null
1126             || input.getVfModuleInformation().getVfModuleId().length() == 0;
1127     }
1128
1129     private boolean hasInvalidVnfId(VfModuleTopologyOperationInput input) {
1130         return input.getVnfInformation() == null || input.getVnfInformation().getVnfId() == null
1131             || input.getVnfInformation().getVnfId().length() == 0;
1132     }
1133
1134     private boolean hasInvalidService(VfModuleTopologyOperationInput input) {
1135         return input == null || input.getServiceInformation() == null
1136             || input.getServiceInformation().getServiceInstanceId() == null
1137             || input.getServiceInformation().getServiceInstanceId().length() == 0;
1138     }
1139
1140     private boolean isValidRequest(VfModuleTopologyOperationInput input) {
1141         return input.getSdncRequestHeader() != null && input.getSdncRequestHeader().getSvcAction() != null;
1142     }
1143
1144     @Override
1145     public Future<RpcResult<NetworkTopologyOperationOutput>> networkTopologyOperation(
1146         NetworkTopologyOperationInput input) {
1147
1148         final String svcOperation = "network-topology-operation";
1149         ServiceData serviceData;
1150         ServiceStatusBuilder serviceStatusBuilder = new ServiceStatusBuilder();
1151         Properties parms = new Properties();
1152
1153         log.info(CALLED_STR, svcOperation);
1154         // create a new response object
1155         NetworkTopologyOperationOutputBuilder responseBuilder = new NetworkTopologyOperationOutputBuilder();
1156
1157         if (this.hasInvalidService(input)) {
1158             log.debug(NULL_OR_EMPTY_ERROR_MESSAGE, svcOperation);
1159             return buildRpcResultFuture(responseBuilder, NULL_OR_EMPTY_ERROR_PARAM);
1160         }
1161
1162         String siid = input.getServiceInformation().getServiceInstanceId();
1163
1164         // Get the service-instance service data from MD-SAL
1165         ServiceDataBuilder serviceDataBuilder = new ServiceDataBuilder();
1166         getServiceData(siid, serviceDataBuilder);
1167
1168         this.trySetSvcRequestId(input, responseBuilder);
1169
1170         ServiceData sd = serviceDataBuilder.build();
1171         if (isInvalidServiceData(sd)) {
1172             log.debug(EMPTY_SERVICE_INSTANCE_MESSAGE, svcOperation);
1173             return buildRpcResultFuture(responseBuilder, INVALID_INPUT_ERROR_MESSAGE);
1174         }
1175
1176         log.info(ADDING_INPUT_DATA_LOG, svcOperation, siid, input);
1177         NetworkTopologyOperationInputBuilder inputBuilder = new NetworkTopologyOperationInputBuilder(input);
1178         GenericResourceApiUtil.toProperties(parms, inputBuilder.build());
1179
1180         // Call SLI sync method
1181         // Get SvcLogicService reference
1182
1183         ResponseObject error = new ResponseObject("200", "");
1184         String ackFinal = "Y";
1185         String networkId = ERROR_NETWORK_ID;
1186         String serviceObjectPath = null;
1187         String networkObjectPath = null;
1188         Properties respProps = tryGetProperties(svcOperation, parms, serviceDataBuilder, error);
1189
1190         if (respProps != null) {
1191             error.setStatusCode(respProps.getProperty(ERROR_CODE_PARAM));
1192             error.setMessage(respProps.getProperty(ERROR_MESSAGE_PARAM));
1193             ackFinal = respProps.getProperty(ACK_FINAL_PARAM, "Y");
1194             networkId = respProps.getProperty("networkId");
1195             serviceObjectPath = respProps.getProperty(SERVICE_OBJECT_PATH_PARAM);
1196             networkObjectPath = respProps.getProperty("network-object-path");
1197         }
1198
1199         if (failed(error)) {
1200             responseBuilder.setResponseCode(error.getStatusCode());
1201             responseBuilder.setResponseMessage(error.getMessage());
1202             responseBuilder.setAckFinalIndicator(ackFinal);
1203
1204             log.error(RETURNED_FAILED_MESSAGE, svcOperation, siid, responseBuilder.build());
1205
1206             RpcResult<NetworkTopologyOperationOutput> rpcResult = RpcResultBuilder
1207                 .<NetworkTopologyOperationOutput>status(true)
1208                 .withResult(responseBuilder.build())
1209                 .build();
1210
1211             return Futures.immediateFuture(rpcResult);
1212         }
1213
1214         // Got success from SLI
1215         try {
1216
1217             serviceData = serviceDataBuilder.build();
1218             log.info(UPDATING_MDSAL_INFO_MESSAGE, svcOperation, siid, serviceData);
1219
1220             // service object
1221             ServiceBuilder serviceBuilder = new ServiceBuilder();
1222             serviceBuilder.setServiceData(serviceData);
1223             serviceBuilder.setServiceInstanceId(siid);
1224             serviceBuilder.setServiceStatus(serviceStatusBuilder.build());
1225             saveService(serviceBuilder.build(), false, LogicalDatastoreType.CONFIGURATION);
1226
1227             trySaveService(input, serviceBuilder);
1228
1229             NetworkResponseInformationBuilder networkResponseInformationBuilder = new NetworkResponseInformationBuilder();
1230             networkResponseInformationBuilder.setInstanceId(networkId);
1231             networkResponseInformationBuilder.setObjectPath(networkObjectPath);
1232             responseBuilder.setNetworkResponseInformation(networkResponseInformationBuilder.build());
1233
1234             ServiceResponseInformationBuilder serviceResponseInformationBuilder = new ServiceResponseInformationBuilder();
1235             serviceResponseInformationBuilder.setInstanceId(siid);
1236             serviceResponseInformationBuilder.setObjectPath(serviceObjectPath);
1237             responseBuilder.setServiceResponseInformation(serviceResponseInformationBuilder.build());
1238
1239         } catch (IllegalStateException e) {
1240             log.error(UPDATING_MDSAL_ERROR_MESSAGE, svcOperation, siid, e);
1241             responseBuilder.setResponseCode("500");
1242             responseBuilder.setResponseMessage(e.toString());
1243             responseBuilder.setAckFinalIndicator("Y");
1244             log.error(RETURNED_FAILED_MESSAGE, svcOperation, siid, responseBuilder.build());
1245
1246             RpcResult<NetworkTopologyOperationOutput> rpcResult = RpcResultBuilder
1247                 .<NetworkTopologyOperationOutput>status(true)
1248                 .withResult(responseBuilder.build())
1249                 .build();
1250
1251             return Futures.immediateFuture(rpcResult);
1252         }
1253
1254         // Update succeeded
1255         responseBuilder.setResponseCode(error.getStatusCode());
1256         responseBuilder.setAckFinalIndicator(ackFinal);
1257         trySetResponseMessage(responseBuilder, error);
1258         log.info(UPDATED_MDSAL_INFO_MESSAGE, svcOperation, siid);
1259         log.info(RETURNED_SUCCESS_MESSAGE, svcOperation, siid, responseBuilder.build());
1260
1261         RpcResult<NetworkTopologyOperationOutput> rpcResult = RpcResultBuilder
1262             .<NetworkTopologyOperationOutput>status(true)
1263             .withResult(responseBuilder.build())
1264             .build();
1265
1266         return Futures.immediateFuture(rpcResult);
1267     }
1268
1269     private void trySetResponseMessage(NetworkTopologyOperationOutputBuilder responseBuilder, ResponseObject error) {
1270         if (!error.getMessage().isEmpty()) {
1271             responseBuilder.setResponseMessage(error.getMessage());
1272         }
1273     }
1274
1275     private void trySetSvcRequestId(NetworkTopologyOperationInput input,
1276         NetworkTopologyOperationOutputBuilder responseBuilder) {
1277         if (input.getSdncRequestHeader() != null) {
1278             responseBuilder.setSvcRequestId(input.getSdncRequestHeader().getSvcRequestId());
1279         }
1280     }
1281
1282     private void trySaveService(NetworkTopologyOperationInput input, ServiceBuilder serviceBuilder) {
1283         if (isValidRequest(input) &&
1284             (input.getSdncRequestHeader().getSvcAction().equals(SvcAction.Activate) ||
1285                 input.getSdncRequestHeader().getSvcAction().equals(SvcAction.Create))) {
1286             // Only update operational tree on Activate
1287             log.info(UPDATING_TREE_INFO_MESSAGE);
1288             saveService(serviceBuilder.build(), false, LogicalDatastoreType.OPERATIONAL);
1289         }
1290     }
1291
1292     private boolean hasInvalidService(NetworkTopologyOperationInput input) {
1293         return input == null || input.getServiceInformation() == null
1294             || input.getServiceInformation().getServiceInstanceId() == null
1295             || input.getServiceInformation().getServiceInstanceId().length() == 0;
1296     }
1297
1298     private Future<RpcResult<NetworkTopologyOperationOutput>> buildRpcResultFuture(
1299         NetworkTopologyOperationOutputBuilder responseBuilder, String responseMessage) {
1300
1301         responseBuilder.setResponseCode("404");
1302         responseBuilder
1303             .setResponseMessage(responseMessage);
1304         responseBuilder.setAckFinalIndicator("Y");
1305
1306         RpcResult<NetworkTopologyOperationOutput> rpcResult = RpcResultBuilder
1307             .<NetworkTopologyOperationOutput>status(true)
1308             .withResult(responseBuilder.build())
1309             .build();
1310
1311         return Futures.immediateFuture(rpcResult);
1312     }
1313
1314     private boolean isValidRequest(NetworkTopologyOperationInput input) {
1315         return input.getSdncRequestHeader() != null && input.getSdncRequestHeader().getSvcAction() != null;
1316     }
1317
1318     @Override
1319     public Future<RpcResult<ContrailRouteTopologyOperationOutput>> contrailRouteTopologyOperation(
1320         ContrailRouteTopologyOperationInput input) {
1321
1322         final String svcOperation = "contrail-route-topology-operation";
1323         ServiceData serviceData;
1324         ServiceStatusBuilder serviceStatusBuilder = new ServiceStatusBuilder();
1325         Properties parms = new Properties();
1326
1327         log.info(CALLED_STR, svcOperation);
1328         // create a new response object
1329         ContrailRouteTopologyOperationOutputBuilder responseBuilder = new ContrailRouteTopologyOperationOutputBuilder();
1330
1331         if (hasInvalidService(input)) {
1332             log.debug(NULL_OR_EMPTY_ERROR_MESSAGE, svcOperation);
1333             return buildRpcResultFuture(responseBuilder, NULL_OR_EMPTY_ERROR_PARAM);
1334         }
1335
1336         String siid = input.getServiceInformation().getServiceInstanceId();
1337
1338         // Get the service-instance service data from MD-SAL
1339         ServiceDataBuilder serviceDataBuilder = new ServiceDataBuilder();
1340         getServiceData(siid, serviceDataBuilder);
1341
1342         trySetSvcRequestId(input, responseBuilder);
1343
1344         ServiceData sd = serviceDataBuilder.build();
1345         if (isInvalidServiceData(sd)) {
1346             log.debug(EMPTY_SERVICE_INSTANCE_MESSAGE, svcOperation);
1347             return buildRpcResultFuture(responseBuilder, INVALID_INPUT_ERROR_MESSAGE);
1348         }
1349
1350         log.info("Adding INPUT data for " + svcOperation + " [" + siid + "] input: " + input);
1351         ContrailRouteTopologyOperationInputBuilder inputBuilder = new ContrailRouteTopologyOperationInputBuilder(input);
1352         GenericResourceApiUtil.toProperties(parms, inputBuilder.build());
1353
1354         // Call SLI sync method
1355         // Get SvcLogicService reference
1356         ResponseObject error = new ResponseObject("200", "");
1357         String ackFinal = "Y";
1358         String allottedResourceId = ERROR_NETWORK_ID;
1359         String serviceObjectPath = null;
1360         String contrailRouteObjectPath = null;
1361         Properties respProps = tryGetProperties(svcOperation, parms, serviceDataBuilder, error);
1362
1363         if (respProps != null) {
1364             error.setStatusCode(respProps.getProperty(ERROR_CODE_PARAM));
1365             error.setMessage(respProps.getProperty(ERROR_MESSAGE_PARAM));
1366             ackFinal = respProps.getProperty(ACK_FINAL_PARAM, "Y");
1367             allottedResourceId = respProps.getProperty(ALLOTTED_RESOURCE_ID_PARAM);
1368             serviceObjectPath = respProps.getProperty(SERVICE_OBJECT_PATH_PARAM);
1369             contrailRouteObjectPath = respProps.getProperty("contrail-route-object-path");
1370         }
1371
1372         if (failed(error)) {
1373             responseBuilder.setResponseCode(error.getStatusCode());
1374             responseBuilder.setResponseMessage(error.getMessage());
1375             responseBuilder.setAckFinalIndicator(ackFinal);
1376             log.error(RETURNED_FAILED_MESSAGE, svcOperation, siid, responseBuilder.build());
1377
1378             RpcResult<ContrailRouteTopologyOperationOutput> rpcResult = RpcResultBuilder
1379                 .<ContrailRouteTopologyOperationOutput>status(true)
1380                 .withResult(responseBuilder.build())
1381                 .build();
1382
1383             return Futures.immediateFuture(rpcResult);
1384         }
1385
1386         // Got success from SLI
1387         try {
1388             serviceData = serviceDataBuilder.build();
1389             log.info(UPDATING_MDSAL_INFO_MESSAGE, svcOperation, siid, serviceData);
1390
1391             // service object
1392             ServiceBuilder serviceBuilder = new ServiceBuilder();
1393             serviceBuilder.setServiceData(serviceData);
1394             serviceBuilder.setServiceInstanceId(siid);
1395             serviceBuilder.setServiceStatus(serviceStatusBuilder.build());
1396             saveService(serviceBuilder.build(), false, LogicalDatastoreType.CONFIGURATION);
1397
1398             trySaveService(input, serviceBuilder);
1399
1400             ContrailRouteResponseInformationBuilder contrailRouteResponseInformationBuilder = new ContrailRouteResponseInformationBuilder();
1401             contrailRouteResponseInformationBuilder.setInstanceId(allottedResourceId);
1402             contrailRouteResponseInformationBuilder.setObjectPath(contrailRouteObjectPath);
1403             responseBuilder.setContrailRouteResponseInformation(contrailRouteResponseInformationBuilder.build());
1404
1405             ServiceResponseInformationBuilder serviceResponseInformationBuilder = new ServiceResponseInformationBuilder();
1406             serviceResponseInformationBuilder.setInstanceId(siid);
1407             serviceResponseInformationBuilder.setObjectPath(serviceObjectPath);
1408             responseBuilder.setServiceResponseInformation(serviceResponseInformationBuilder.build());
1409
1410         } catch (IllegalStateException e) {
1411             log.error(UPDATING_MDSAL_ERROR_MESSAGE, svcOperation, siid, e);
1412             responseBuilder.setResponseCode("500");
1413             responseBuilder.setResponseMessage(e.toString());
1414             responseBuilder.setAckFinalIndicator("Y");
1415             log.error(RETURNED_FAILED_MESSAGE, svcOperation, siid, responseBuilder.build());
1416
1417             RpcResult<ContrailRouteTopologyOperationOutput> rpcResult = RpcResultBuilder
1418                 .<ContrailRouteTopologyOperationOutput>status(true)
1419                 .withResult(responseBuilder.build())
1420                 .build();
1421
1422             return Futures.immediateFuture(rpcResult);
1423         }
1424
1425         // Update succeeded
1426         responseBuilder.setResponseCode(error.getStatusCode());
1427         responseBuilder.setAckFinalIndicator(ackFinal);
1428         trySetResponseMessage(responseBuilder, error);
1429         log.info(UPDATED_MDSAL_INFO_MESSAGE, svcOperation, siid);
1430         log.info(RETURNED_SUCCESS_MESSAGE, svcOperation, siid, responseBuilder.build());
1431
1432         RpcResult<ContrailRouteTopologyOperationOutput> rpcResult = RpcResultBuilder
1433             .<ContrailRouteTopologyOperationOutput>status(true)
1434             .withResult(responseBuilder.build())
1435             .build();
1436
1437         return Futures.immediateFuture(rpcResult);
1438     }
1439
1440     private void trySetResponseMessage(ContrailRouteTopologyOperationOutputBuilder responseBuilder,
1441         ResponseObject error) {
1442         if (!error.getMessage().isEmpty()) {
1443             responseBuilder.setResponseMessage(error.getMessage());
1444         }
1445     }
1446
1447     private void trySaveService(ContrailRouteTopologyOperationInput input, ServiceBuilder serviceBuilder) {
1448         if (isValidRequest(input) &&
1449             (input.getSdncRequestHeader().getSvcAction().equals(SvcAction.Unassign) ||
1450                 input.getSdncRequestHeader().getSvcAction().equals(SvcAction.Activate))) {
1451             // Only update operational tree on activate or delete
1452             log.info(UPDATING_TREE_INFO_MESSAGE);
1453             saveService(serviceBuilder.build(), false, LogicalDatastoreType.OPERATIONAL);
1454         }
1455     }
1456
1457     private void trySetSvcRequestId(ContrailRouteTopologyOperationInput input,
1458         ContrailRouteTopologyOperationOutputBuilder responseBuilder) {
1459         if (input.getSdncRequestHeader() != null) {
1460             responseBuilder.setSvcRequestId(input.getSdncRequestHeader().getSvcRequestId());
1461         }
1462     }
1463
1464     private boolean hasInvalidService(ContrailRouteTopologyOperationInput input) {
1465         return input == null || input.getServiceInformation() == null
1466             || input.getServiceInformation().getServiceInstanceId() == null
1467             || input.getServiceInformation().getServiceInstanceId().length() == 0;
1468     }
1469
1470     private Future<RpcResult<ContrailRouteTopologyOperationOutput>>
1471     buildRpcResultFuture(ContrailRouteTopologyOperationOutputBuilder responseBuilder, String responseMessage) {
1472
1473         responseBuilder.setResponseCode("404");
1474         responseBuilder.setResponseMessage(responseMessage);
1475         responseBuilder.setAckFinalIndicator("Y");
1476
1477         RpcResult<ContrailRouteTopologyOperationOutput> rpcResult = RpcResultBuilder
1478             .<ContrailRouteTopologyOperationOutput>status(true)
1479             .withResult(responseBuilder.build())
1480             .build();
1481
1482         return Futures.immediateFuture(rpcResult);
1483     }
1484
1485     private boolean isValidRequest(ContrailRouteTopologyOperationInput input) {
1486         return input.getSdncRequestHeader() != null && input.getSdncRequestHeader().getSvcAction() != null;
1487     }
1488
1489     @Override
1490     public Future<RpcResult<SecurityZoneTopologyOperationOutput>> securityZoneTopologyOperation(
1491         SecurityZoneTopologyOperationInput input) {
1492
1493         final String svcOperation = "security-zone-topology-operation";
1494         ServiceData serviceData;
1495         ServiceStatusBuilder serviceStatusBuilder = new ServiceStatusBuilder();
1496         Properties parms = new Properties();
1497
1498         log.info(CALLED_STR, svcOperation);
1499         // create a new response object
1500         SecurityZoneTopologyOperationOutputBuilder responseBuilder = new SecurityZoneTopologyOperationOutputBuilder();
1501
1502         if (this.hasInvalidService(input)) {
1503             log.debug(NULL_OR_EMPTY_ERROR_MESSAGE, svcOperation);
1504             return buildRpcResultFuture(responseBuilder, NULL_OR_EMPTY_ERROR_PARAM);
1505         }
1506
1507         String siid = input.getServiceInformation().getServiceInstanceId();
1508
1509         // Get the service-instance service data from MD-SAL
1510         ServiceDataBuilder serviceDataBuilder = new ServiceDataBuilder();
1511         getServiceData(siid, serviceDataBuilder);
1512         trySetSvcRequestId(input, responseBuilder);
1513
1514         ServiceData sd = serviceDataBuilder.build();
1515         if (isInvalidServiceData(sd)) {
1516             log.debug(EMPTY_SERVICE_INSTANCE_MESSAGE, svcOperation);
1517             return buildRpcResultFuture(responseBuilder, INVALID_INPUT_ERROR_MESSAGE);
1518         }
1519
1520         log.info(ADDING_INPUT_DATA_LOG, svcOperation, siid, input);
1521         SecurityZoneTopologyOperationInputBuilder inputBuilder = new SecurityZoneTopologyOperationInputBuilder(input);
1522         GenericResourceApiUtil.toProperties(parms, inputBuilder.build());
1523
1524         // Call SLI sync method
1525         // Get SvcLogicService reference
1526
1527         Properties respProps = null;
1528
1529         ResponseObject error = new ResponseObject("200", "");
1530         String ackFinal = "Y";
1531         String allottedResourceId = ERROR_NETWORK_ID;
1532         String serviceObjectPath = null;
1533         String securityZoneObjectPath = null;
1534
1535         try {
1536             if (svcLogicClient.hasGraph(APP_NAME, svcOperation, null, "sync")) {
1537
1538                 try {
1539                     respProps = svcLogicClient.execute(APP_NAME, svcOperation, null, "sync", serviceDataBuilder, parms);
1540                 } catch (Exception e) {
1541                     log.error(SERVICE_LOGIC_EXECUTION_ERROR_MESSAGE, svcOperation, e);
1542                     error.setMessage(e.getMessage());
1543                     error.setStatusCode("500");
1544                 }
1545             } else {
1546                 error.setMessage(NO_SERVICE_LOGIC_ACTIVE + APP_NAME + ": '" + svcOperation + "'");
1547                 error.setStatusCode("503");
1548             }
1549         } catch (Exception e) {
1550             error.setStatusCode("500");
1551             error.setMessage(e.getMessage());
1552             log.error(SERVICE_LOGIC_SEARCH_ERROR_MESSAGE, e);
1553         }
1554
1555         if (respProps != null) {
1556             error.setStatusCode(respProps.getProperty(ERROR_CODE_PARAM));
1557             error.setMessage(respProps.getProperty(ERROR_MESSAGE_PARAM));
1558             ackFinal = respProps.getProperty(ACK_FINAL_PARAM, "Y");
1559             allottedResourceId = respProps.getProperty(ALLOTTED_RESOURCE_ID_PARAM);
1560             serviceObjectPath = respProps.getProperty(SERVICE_OBJECT_PATH_PARAM);
1561             securityZoneObjectPath = respProps.getProperty("security-zone-object-path");
1562         }
1563
1564         if (failed(error)) {
1565             responseBuilder.setResponseCode(error.getStatusCode());
1566             responseBuilder.setResponseMessage(error.getMessage());
1567             responseBuilder.setAckFinalIndicator(ackFinal);
1568             log.error(RETURNED_FAILED_MESSAGE, svcOperation, siid, responseBuilder.build());
1569
1570             RpcResult<SecurityZoneTopologyOperationOutput> rpcResult = RpcResultBuilder
1571                 .<SecurityZoneTopologyOperationOutput>status(true)
1572                 .withResult(responseBuilder.build())
1573                 .build();
1574
1575             return Futures.immediateFuture(rpcResult);
1576         }
1577
1578         // Got success from SLI
1579         try {
1580
1581             serviceData = serviceDataBuilder.build();
1582             log.info(UPDATING_MDSAL_INFO_MESSAGE, svcOperation, siid, serviceData);
1583
1584             // service object
1585             ServiceBuilder serviceBuilder = new ServiceBuilder();
1586             serviceBuilder.setServiceData(serviceData);
1587             serviceBuilder.setServiceInstanceId(siid);
1588             serviceBuilder.setServiceStatus(serviceStatusBuilder.build());
1589             saveService(serviceBuilder.build(), false, LogicalDatastoreType.CONFIGURATION);
1590
1591             trySaveService(input, serviceBuilder);
1592
1593             SecurityZoneResponseInformationBuilder securityZoneResponseInformationBuilder = new SecurityZoneResponseInformationBuilder();
1594             securityZoneResponseInformationBuilder.setInstanceId(allottedResourceId);
1595             securityZoneResponseInformationBuilder.setObjectPath(securityZoneObjectPath);
1596             responseBuilder.setSecurityZoneResponseInformation(securityZoneResponseInformationBuilder.build());
1597
1598             ServiceResponseInformationBuilder serviceResponseInformationBuilder = new ServiceResponseInformationBuilder();
1599             serviceResponseInformationBuilder.setInstanceId(siid);
1600             serviceResponseInformationBuilder.setObjectPath(serviceObjectPath);
1601             responseBuilder.setServiceResponseInformation(serviceResponseInformationBuilder.build());
1602
1603         } catch (IllegalStateException e) {
1604             log.error(UPDATING_MDSAL_ERROR_MESSAGE, svcOperation, siid, e);
1605             responseBuilder.setResponseCode("500");
1606             responseBuilder.setResponseMessage(e.toString());
1607             responseBuilder.setAckFinalIndicator("Y");
1608             log.error(RETURNED_FAILED_MESSAGE, svcOperation, siid, responseBuilder.build());
1609
1610             RpcResult<SecurityZoneTopologyOperationOutput> rpcResult = RpcResultBuilder
1611                 .<SecurityZoneTopologyOperationOutput>status(true)
1612                 .withResult(responseBuilder.build())
1613                 .build();
1614
1615             return Futures.immediateFuture(rpcResult);
1616         }
1617
1618         // Update succeeded
1619         responseBuilder.setResponseCode(error.getStatusCode());
1620         responseBuilder.setAckFinalIndicator(ackFinal);
1621         trySetResponseMessage(responseBuilder, error);
1622         log.info(UPDATED_MDSAL_INFO_MESSAGE, svcOperation, siid);
1623         log.info(RETURNED_SUCCESS_MESSAGE, svcOperation, siid, responseBuilder.build());
1624
1625         RpcResult<SecurityZoneTopologyOperationOutput> rpcResult = RpcResultBuilder
1626             .<SecurityZoneTopologyOperationOutput>status(true)
1627             .withResult(responseBuilder.build())
1628             .build();
1629
1630         return Futures.immediateFuture(rpcResult);
1631     }
1632
1633     private void trySetResponseMessage(SecurityZoneTopologyOperationOutputBuilder responseBuilder,
1634         ResponseObject error) {
1635         if (!error.getMessage().isEmpty()) {
1636             responseBuilder.setResponseMessage(error.getMessage());
1637         }
1638     }
1639
1640     private void trySaveService(SecurityZoneTopologyOperationInput input, ServiceBuilder serviceBuilder) {
1641         if (isValidRequest(input) &&
1642             (input.getSdncRequestHeader().getSvcAction().equals(SvcAction.Unassign) ||
1643                 input.getSdncRequestHeader().getSvcAction().equals(SvcAction.Activate))) {
1644             // Only update operational tree on activate or delete
1645             log.info(UPDATING_TREE_INFO_MESSAGE);
1646             saveService(serviceBuilder.build(), false, LogicalDatastoreType.OPERATIONAL);
1647         }
1648     }
1649
1650     private void trySetSvcRequestId(SecurityZoneTopologyOperationInput input,
1651         SecurityZoneTopologyOperationOutputBuilder responseBuilder) {
1652         if (input.getSdncRequestHeader() != null) {
1653             responseBuilder.setSvcRequestId(input.getSdncRequestHeader().getSvcRequestId());
1654         }
1655     }
1656
1657     private boolean isInvalidServiceData(ServiceData sd) {
1658         return sd == null || sd.getServiceLevelOperStatus() == null;
1659     }
1660
1661     private boolean hasInvalidService(SecurityZoneTopologyOperationInput input) {
1662         return input == null || input.getServiceInformation() == null
1663             || input.getServiceInformation().getServiceInstanceId() == null
1664             || input.getServiceInformation().getServiceInstanceId().length() == 0;
1665     }
1666
1667     private Future<RpcResult<SecurityZoneTopologyOperationOutput>>
1668     buildRpcResultFuture(SecurityZoneTopologyOperationOutputBuilder responseBuilder, String responseMessage) {
1669
1670         responseBuilder.setResponseCode("404");
1671         responseBuilder.setResponseMessage(responseMessage);
1672         responseBuilder.setAckFinalIndicator("Y");
1673
1674         RpcResult<SecurityZoneTopologyOperationOutput> rpcResult = RpcResultBuilder
1675             .<SecurityZoneTopologyOperationOutput>status(true)
1676             .withResult(responseBuilder.build())
1677             .build();
1678
1679         return Futures.immediateFuture(rpcResult);
1680     }
1681
1682     private boolean isValidRequest(SecurityZoneTopologyOperationInput input) {
1683         return input.getSdncRequestHeader() != null && input.getSdncRequestHeader().getSvcAction() != null;
1684     }
1685
1686     @Override
1687     public Future<RpcResult<TunnelxconnTopologyOperationOutput>> tunnelxconnTopologyOperation(
1688         TunnelxconnTopologyOperationInput input) {
1689
1690         final String svcOperation = "tunnelxconn-topology-operation";
1691         Properties parms = new Properties();
1692         log.info(CALLED_STR, svcOperation);
1693
1694         // create a new response object
1695         TunnelxconnTopologyOperationOutputBuilder responseBuilder = new TunnelxconnTopologyOperationOutputBuilder();
1696         if (hasInvalidService(input)) {
1697             log.debug(NULL_OR_EMPTY_ERROR_MESSAGE, svcOperation);
1698             responseBuilder.setResponseCode("404");
1699             responseBuilder.setResponseMessage(NULL_OR_EMPTY_ERROR_PARAM);
1700             responseBuilder.setAckFinalIndicator("Y");
1701
1702             RpcResult<TunnelxconnTopologyOperationOutput> rpcResult = RpcResultBuilder
1703                 .<TunnelxconnTopologyOperationOutput>status(true)
1704                 .withResult(responseBuilder.build())
1705                 .build();
1706
1707             return Futures.immediateFuture(rpcResult);
1708         }
1709         String siid = input.getServiceInformation().getServiceInstanceId();
1710         log.info(ADDING_INPUT_DATA_LOG, svcOperation, siid, input);
1711         TunnelxconnTopologyOperationInputBuilder inputBuilder = new TunnelxconnTopologyOperationInputBuilder(input);
1712         GenericResourceApiUtil.toProperties(parms, inputBuilder.build());
1713
1714         // Call SLI sync method
1715         // Get SvcLogicService reference
1716         ResponseObject error = new ResponseObject("200", "");
1717         String ackFinal = "Y";
1718         String allottedResourceId = ERROR_NETWORK_ID;
1719         String serviceObjectPath = null;
1720         String tunnelxconnObjectPath = null;
1721         Properties respProps = tryGetProperties(svcOperation, parms, error);
1722
1723         if (respProps != null) {
1724             error.setStatusCode(respProps.getProperty(ERROR_CODE_PARAM));
1725             error.setMessage(respProps.getProperty(ERROR_MESSAGE_PARAM));
1726             ackFinal = respProps.getProperty(ACK_FINAL_PARAM, "Y");
1727             allottedResourceId = respProps.getProperty(ALLOTTED_RESOURCE_ID_PARAM);
1728             serviceObjectPath = respProps.getProperty(SERVICE_OBJECT_PATH_PARAM);
1729             tunnelxconnObjectPath = respProps.getProperty("tunnelxconn-object-path");
1730         }
1731
1732         if (failed(error)) {
1733             responseBuilder.setResponseCode(error.getStatusCode());
1734             responseBuilder.setResponseMessage(error.getMessage());
1735             responseBuilder.setAckFinalIndicator(ackFinal);
1736
1737             log.error(RETURNED_FAILED_MESSAGE, svcOperation, siid, responseBuilder.build());
1738
1739             RpcResult<TunnelxconnTopologyOperationOutput> rpcResult = RpcResultBuilder
1740                 .<TunnelxconnTopologyOperationOutput>status(true)
1741                 .withResult(responseBuilder.build())
1742                 .build();
1743
1744             return Futures.immediateFuture(rpcResult);
1745         }
1746
1747         // Got success from SLI
1748         try {
1749             TunnelxconnResponseInformationBuilder tunnelxconnResponseInformationBuilder = new TunnelxconnResponseInformationBuilder();
1750             tunnelxconnResponseInformationBuilder.setInstanceId(allottedResourceId);
1751             tunnelxconnResponseInformationBuilder.setObjectPath(tunnelxconnObjectPath);
1752             responseBuilder.setTunnelxconnResponseInformation(tunnelxconnResponseInformationBuilder.build());
1753
1754             ServiceResponseInformationBuilder serviceResponseInformationBuilder = new ServiceResponseInformationBuilder();
1755             serviceResponseInformationBuilder.setInstanceId(siid);
1756             serviceResponseInformationBuilder.setObjectPath(serviceObjectPath);
1757             responseBuilder.setServiceResponseInformation(serviceResponseInformationBuilder.build());
1758
1759         } catch (IllegalStateException e) {
1760             log.error(UPDATING_MDSAL_ERROR_MESSAGE, svcOperation, siid, e);
1761             responseBuilder.setResponseCode("500");
1762             responseBuilder.setResponseMessage(e.toString());
1763             responseBuilder.setAckFinalIndicator("Y");
1764             log.error(RETURNED_FAILED_MESSAGE, svcOperation, siid, responseBuilder.build());
1765
1766             RpcResult<TunnelxconnTopologyOperationOutput> rpcResult = RpcResultBuilder
1767                 .<TunnelxconnTopologyOperationOutput>status(true)
1768                 .withResult(responseBuilder.build())
1769                 .build();
1770
1771             return Futures.immediateFuture(rpcResult);
1772         }
1773
1774         // Update succeeded
1775         responseBuilder.setResponseCode(error.getStatusCode());
1776         responseBuilder.setAckFinalIndicator(ackFinal);
1777         trySetResponseMessage(responseBuilder, error);
1778         log.info(UPDATED_MDSAL_INFO_MESSAGE, svcOperation, siid);
1779         log.info(RETURNED_SUCCESS_MESSAGE, svcOperation, siid, responseBuilder.build());
1780
1781         RpcResult<TunnelxconnTopologyOperationOutput> rpcResult = RpcResultBuilder
1782             .<TunnelxconnTopologyOperationOutput>status(true)
1783             .withResult(responseBuilder.build())
1784             .build();
1785
1786         return Futures.immediateFuture(rpcResult);
1787     }
1788
1789     private void trySetResponseMessage(TunnelxconnTopologyOperationOutputBuilder responseBuilder,
1790         ResponseObject error) {
1791         if (!error.getMessage().isEmpty()) {
1792             responseBuilder.setResponseMessage(error.getMessage());
1793         }
1794     }
1795
1796     private boolean hasInvalidService(TunnelxconnTopologyOperationInput input) {
1797         return input == null || input.getServiceInformation() == null
1798             || input.getServiceInformation().getServiceInstanceId() == null
1799             || input.getServiceInformation().getServiceInstanceId().length() == 0;
1800     }
1801
1802     private Properties tryGetProperties(String svcOperation, Properties parms, ResponseObject error) {
1803         try {
1804             if (svcLogicClient.hasGraph(APP_NAME, svcOperation, null, "sync")) {
1805
1806                 try {
1807                     return svcLogicClient.execute(APP_NAME, svcOperation, null, "sync", parms);
1808                 } catch (Exception e) {
1809                     log.error(SERVICE_LOGIC_EXECUTION_ERROR_MESSAGE, svcOperation, e);
1810                     error.setMessage(e.getMessage());
1811                     error.setStatusCode("500");
1812                 }
1813             } else {
1814                 error.setMessage(NO_SERVICE_LOGIC_ACTIVE + APP_NAME + ": '" + svcOperation + "'");
1815                 error.setStatusCode("503");
1816             }
1817         } catch (Exception e) {
1818             error.setMessage(e.getMessage());
1819             error.setStatusCode("500");
1820             log.error(SERVICE_LOGIC_SEARCH_ERROR_MESSAGE, e);
1821         }
1822         return null;
1823     }
1824
1825     @Override
1826     public Future<RpcResult<BrgTopologyOperationOutput>> brgTopologyOperation(BrgTopologyOperationInput input) {
1827         final String svcOperation = "brg-topology-operation";
1828         Properties parms = new Properties();
1829
1830         log.info(CALLED_STR, svcOperation);
1831         // create a new response object
1832         BrgTopologyOperationOutputBuilder responseBuilder = new BrgTopologyOperationOutputBuilder();
1833
1834         if (this.hasInvalidService(input)) {
1835
1836             log.debug(NULL_OR_EMPTY_ERROR_MESSAGE, svcOperation);
1837             responseBuilder.setResponseCode("404");
1838             responseBuilder.setResponseMessage(NULL_OR_EMPTY_ERROR_PARAM);
1839             responseBuilder.setAckFinalIndicator("Y");
1840
1841             RpcResult<BrgTopologyOperationOutput> rpcResult = RpcResultBuilder
1842                 .<BrgTopologyOperationOutput>status(true)
1843                 .withResult(responseBuilder.build())
1844                 .build();
1845
1846             return Futures.immediateFuture(rpcResult);
1847         }
1848
1849         String siid = input.getServiceInformation().getServiceInstanceId();
1850
1851         log.info(ADDING_INPUT_DATA_LOG, svcOperation, siid, input);
1852         BrgTopologyOperationInputBuilder inputBuilder = new BrgTopologyOperationInputBuilder(input);
1853         GenericResourceApiUtil.toProperties(parms, inputBuilder.build());
1854
1855         // Call SLI sync method
1856         // Get SvcLogicService reference
1857         ResponseObject error = new ResponseObject("200", "");
1858         String ackFinal = "Y";
1859         String allottedResourceId = ERROR_NETWORK_ID;
1860         String serviceObjectPath = null;
1861         String brgObjectPath = null;
1862         Properties respProps = tryGetProperties(svcOperation, parms, error);
1863
1864         if (respProps != null) {
1865             error.setStatusCode(respProps.getProperty(ERROR_CODE_PARAM));
1866             error.setMessage(respProps.getProperty(ERROR_MESSAGE_PARAM));
1867             ackFinal = respProps.getProperty(ACK_FINAL_PARAM, "Y");
1868             allottedResourceId = respProps.getProperty(ALLOTTED_RESOURCE_ID_PARAM);
1869             serviceObjectPath = respProps.getProperty(SERVICE_OBJECT_PATH_PARAM);
1870             brgObjectPath = respProps.getProperty("brg-object-path");
1871         }
1872
1873         if (failed(error)) {
1874             responseBuilder.setResponseCode(error.getStatusCode());
1875             responseBuilder.setResponseMessage(error.getMessage());
1876             responseBuilder.setAckFinalIndicator(ackFinal);
1877
1878             log.error(RETURNED_FAILED_MESSAGE, svcOperation, siid, responseBuilder.build());
1879             RpcResult<BrgTopologyOperationOutput> rpcResult = RpcResultBuilder
1880                 .<BrgTopologyOperationOutput>status(true)
1881                 .withResult(responseBuilder.build())
1882                 .build();
1883
1884             return Futures.immediateFuture(rpcResult);
1885         }
1886
1887         // Got success from SLI
1888         try {
1889
1890             BrgResponseInformationBuilder brgResponseInformationBuilder = new BrgResponseInformationBuilder();
1891             brgResponseInformationBuilder.setInstanceId(allottedResourceId);
1892             brgResponseInformationBuilder.setObjectPath(brgObjectPath);
1893             responseBuilder.setBrgResponseInformation(brgResponseInformationBuilder.build());
1894
1895             ServiceResponseInformationBuilder serviceResponseInformationBuilder = new ServiceResponseInformationBuilder();
1896             serviceResponseInformationBuilder.setInstanceId(siid);
1897             serviceResponseInformationBuilder.setObjectPath(serviceObjectPath);
1898             responseBuilder.setServiceResponseInformation(serviceResponseInformationBuilder.build());
1899
1900         } catch (IllegalStateException e) {
1901             log.error(UPDATING_MDSAL_ERROR_MESSAGE, svcOperation, siid, e);
1902             responseBuilder.setResponseCode("500");
1903             responseBuilder.setResponseMessage(e.toString());
1904             responseBuilder.setAckFinalIndicator("Y");
1905             log.error(RETURNED_FAILED_MESSAGE, svcOperation, siid, responseBuilder.build());
1906
1907             RpcResult<BrgTopologyOperationOutput> rpcResult = RpcResultBuilder
1908                 .<BrgTopologyOperationOutput>status(true)
1909                 .withResult(responseBuilder.build())
1910                 .build();
1911
1912             return Futures.immediateFuture(rpcResult);
1913         }
1914
1915         // Update succeeded
1916         responseBuilder.setResponseCode(error.getStatusCode());
1917         responseBuilder.setAckFinalIndicator(ackFinal);
1918         trySetResponseMessage(responseBuilder, error);
1919         log.info(UPDATED_MDSAL_INFO_MESSAGE, svcOperation, siid);
1920         log.info(RETURNED_SUCCESS_MESSAGE, svcOperation, siid, responseBuilder.build());
1921
1922         RpcResult<BrgTopologyOperationOutput> rpcResult = RpcResultBuilder
1923             .<BrgTopologyOperationOutput>status(true)
1924             .withResult(responseBuilder.build())
1925             .build();
1926
1927         return Futures.immediateFuture(rpcResult);
1928     }
1929
1930     private void trySetResponseMessage(BrgTopologyOperationOutputBuilder responseBuilder, ResponseObject error) {
1931         if (!error.getMessage().isEmpty()) {
1932             responseBuilder.setResponseMessage(error.getMessage());
1933         }
1934     }
1935
1936     private boolean hasInvalidService(BrgTopologyOperationInput input) {
1937         return input == null || input.getServiceInformation() == null
1938             || input.getServiceInformation().getServiceInstanceId() == null
1939             || input.getServiceInformation().getServiceInstanceId().length() == 0;
1940     }
1941
1942     @Override
1943     public Future<RpcResult<PreloadVnfTopologyOperationOutput>> preloadVnfTopologyOperation(
1944         PreloadVnfTopologyOperationInput input) {
1945
1946         final String svcOperation = "preload-vnf-topology-operation";
1947         Properties parms = new Properties();
1948
1949         log.info(CALLED_STR, svcOperation);
1950         // create a new response object
1951         PreloadVnfTopologyOperationOutputBuilder responseBuilder = new PreloadVnfTopologyOperationOutputBuilder();
1952
1953         if (hasInvalidVnfTopology(input)) {
1954
1955             log.debug("exiting {} because of null input", svcOperation);
1956             responseBuilder.setResponseCode("403");
1957             responseBuilder.setResponseMessage("invalid input: input is null");
1958             responseBuilder.setAckFinalIndicator("Y");
1959
1960             RpcResult<PreloadVnfTopologyOperationOutput> rpcResult = RpcResultBuilder
1961                 .<PreloadVnfTopologyOperationOutput>status(true)
1962                 .withResult(responseBuilder.build())
1963                 .build();
1964
1965             return Futures.immediateFuture(rpcResult);
1966         }
1967
1968         // Grab the name and type from the input buffer
1969         String preloadName = input.getVnfTopologyInformation().getVnfTopologyIdentifier().getVnfName();
1970         String preloadType = input.getVnfTopologyInformation().getVnfTopologyIdentifier().getVnfType();
1971
1972         // Make sure we have a preload_name and preload_type
1973         if (isValidPreloadData(preloadName, preloadType)) {
1974             log.debug("exiting {} vnf-name or vnf-type is null or empty", svcOperation);
1975             responseBuilder.setResponseCode("403");
1976             responseBuilder.setResponseMessage("invalid input: vnf-name or vnf-type is null or empty");
1977             responseBuilder.setAckFinalIndicator("Y");
1978
1979             RpcResult<PreloadVnfTopologyOperationOutput> rpcResult = RpcResultBuilder
1980                 .<PreloadVnfTopologyOperationOutput>status(true)
1981                 .withResult(responseBuilder.build())
1982                 .build();
1983
1984             return Futures.immediateFuture(rpcResult);
1985         }
1986
1987         this.trySetSvcRequestId(input, responseBuilder);
1988
1989         PreloadDataBuilder preloadDataBuilder = new PreloadDataBuilder();
1990         getPreloadData(preloadName, preloadType, preloadDataBuilder);
1991
1992         PreloadDataBuilder operDataBuilder = new PreloadDataBuilder();
1993         getPreloadData(preloadName, preloadType, operDataBuilder, LogicalDatastoreType.OPERATIONAL);
1994
1995         // setup a preload-data object builder
1996         // ACTION preload-vnf-topology-operation
1997         // INPUT:
1998         // USES sdnc-request-header;
1999         // USES request-information;
2000         // uses vnf-topology-information;
2001         // OUTPUT:
2002         // USES vnf-topology-response-body;
2003         //
2004         // container preload-data
2005         // uses vnf-topology-information;
2006         // uses network-topology-information;
2007         // uses oper-status;
2008
2009         log.info("Adding INPUT data for {} [{},{}] input: {}", svcOperation, preloadName, preloadType, input);
2010         PreloadVnfTopologyOperationInputBuilder inputBuilder = new PreloadVnfTopologyOperationInputBuilder(input);
2011         GenericResourceApiUtil.toProperties(parms, inputBuilder.build());
2012         log.info("Adding OPERATIONAL data for {} [{},{}] operational-data: {}", svcOperation, preloadName,
2013             preloadType, operDataBuilder.build());
2014         GenericResourceApiUtil.toProperties(parms, OPERATIONAL_DATA_PARAM, operDataBuilder);
2015
2016         // Call SLI sync method
2017         // Get SvcLogicService reference
2018         ResponseObject error = new ResponseObject("200", "");
2019         Properties respProps = tryGetProperties(svcOperation, parms, error);
2020         String ackFinal = resolveAckFinal(error, respProps);
2021
2022         if (failed(error)) {
2023
2024             responseBuilder.setResponseCode(error.getStatusCode());
2025             responseBuilder.setResponseMessage(error.getMessage());
2026             responseBuilder.setAckFinalIndicator(ackFinal);
2027
2028             VnfPreloadListBuilder preloadVnfListBuilder = new VnfPreloadListBuilder();
2029             preloadVnfListBuilder.setVnfName(preloadName);
2030             preloadVnfListBuilder.setVnfType(preloadType);
2031             preloadVnfListBuilder.setPreloadData(preloadDataBuilder.build());
2032             log.error("Returned FAILED for {} [{},{}] error code: '{}', Reason: '{}'", svcOperation, preloadName,
2033                 preloadType, error.getStatusCode(), error.getMessage());
2034             try {
2035                 savePreloadList(preloadVnfListBuilder.build(), true, LogicalDatastoreType.CONFIGURATION);
2036             } catch (Exception e) {
2037                 log.error(UPDATING_MDSAL_ERROR_MESSAGE_2, svcOperation, preloadName,
2038                     preloadType, e);
2039             }
2040             log.debug("Sending Success rpc result due to external error");
2041
2042             RpcResult<PreloadVnfTopologyOperationOutput> rpcResult = RpcResultBuilder
2043                 .<PreloadVnfTopologyOperationOutput>status(true)
2044                 .withResult(responseBuilder.build())
2045                 .build();
2046
2047             return Futures.immediateFuture(rpcResult);
2048         }
2049
2050         // Got success from SLI
2051         try {
2052             updatePreloadData(svcOperation, preloadName, preloadType, preloadDataBuilder);
2053         } catch (Exception e) {
2054             log.error(UPDATING_MDSAL_ERROR_MESSAGE_2, svcOperation, preloadName, preloadType,
2055                 e);
2056             responseBuilder.setResponseCode("500");
2057             responseBuilder.setResponseMessage(e.toString());
2058             responseBuilder.setAckFinalIndicator("Y");
2059             log.error("Returned FAILED for {} [{},{}] {}", svcOperation, preloadName, preloadType,
2060                 responseBuilder.build());
2061
2062             RpcResult<PreloadVnfTopologyOperationOutput> rpcResult = RpcResultBuilder
2063                 .<PreloadVnfTopologyOperationOutput>status(false)
2064                 .withResult(responseBuilder.build())
2065                 .build();
2066
2067             return Futures.immediateFuture(rpcResult);
2068         }
2069
2070         // Update succeeded
2071         responseBuilder.setResponseCode(error.getStatusCode());
2072         responseBuilder.setAckFinalIndicator(ackFinal);
2073         trySetResponseMessage(responseBuilder, error);
2074
2075         log.info("Updated MD-SAL for {} [{},{}]", svcOperation, preloadName, preloadType);
2076         log.info("Returned SUCCESS for {} [{},{}] {}", svcOperation, preloadName, preloadType,
2077             responseBuilder.build());
2078
2079         RpcResult<PreloadVnfTopologyOperationOutput> rpcResult = RpcResultBuilder
2080             .<PreloadVnfTopologyOperationOutput>status(true)
2081             .withResult(responseBuilder.build())
2082             .build();
2083
2084         return Futures.immediateFuture(rpcResult);
2085     }
2086
2087     private String resolveAckFinal(ResponseObject error, Properties respProps) {
2088         if (respProps != null) {
2089             error.setStatusCode(respProps.getProperty(ERROR_CODE_PARAM));
2090             error.setMessage(respProps.getProperty(ERROR_MESSAGE_PARAM));
2091             return respProps.getProperty(ACK_FINAL_PARAM, "Y");
2092         }
2093         return "Y";
2094     }
2095
2096     private void trySetResponseMessage(PreloadVnfTopologyOperationOutputBuilder responseBuilder, ResponseObject error) {
2097         if (!error.getMessage().isEmpty()) {
2098             responseBuilder.setResponseMessage(error.getMessage());
2099         }
2100     }
2101
2102     private void trySetSvcRequestId(PreloadVnfTopologyOperationInput input,
2103         PreloadVnfTopologyOperationOutputBuilder responseBuilder) {
2104         if (input.getSdncRequestHeader() != null) {
2105             responseBuilder.setSvcRequestId(input.getSdncRequestHeader().getSvcRequestId());
2106         }
2107     }
2108
2109     private boolean hasInvalidVnfTopology(PreloadVnfTopologyOperationInput input) {
2110         return input == null || input.getVnfTopologyInformation() == null
2111             || input.getVnfTopologyInformation().getVnfTopologyIdentifier() == null;
2112     }
2113
2114     private void updatePreloadData(String svcOperation, String preloadName, String preloadType,
2115         PreloadDataBuilder preloadDataBuilder) {
2116         PreloadData preloadData;
2117         preloadData = preloadDataBuilder.build();
2118         log.info("Updating MD-SAL for {} [{},{}] preloadData: {}", svcOperation, preloadName, preloadType,
2119             preloadData);
2120         // svc-configuration-list
2121         VnfPreloadListBuilder preloadVnfListBuilder = new VnfPreloadListBuilder();
2122         preloadVnfListBuilder.setVnfName(preloadName);
2123         preloadVnfListBuilder.setVnfType(preloadType);
2124         preloadVnfListBuilder.setPreloadData(preloadData);
2125
2126         // merge flag sets to false to allow it to be overwritten (not appended)
2127         savePreloadList(preloadVnfListBuilder.build(), false, LogicalDatastoreType.CONFIGURATION);
2128         log.info(UPDATING_TREE_INFO_MESSAGE);
2129         savePreloadList(preloadVnfListBuilder.build(), false, LogicalDatastoreType.OPERATIONAL);
2130     }
2131
2132     @Override
2133     public Future<RpcResult<PreloadNetworkTopologyOperationOutput>> preloadNetworkTopologyOperation(
2134         PreloadNetworkTopologyOperationInput input) {
2135
2136         final String svcOperation = "preload-network-topology-operation";
2137         Properties parms = new Properties();
2138
2139         log.info(CALLED_STR, svcOperation);
2140         // create a new response object
2141         PreloadNetworkTopologyOperationOutputBuilder responseBuilder = new PreloadNetworkTopologyOperationOutputBuilder();
2142
2143         if (hasInvalidNetworkTopology(input)) {
2144
2145             log.debug("exiting {} because of null input", svcOperation);
2146             responseBuilder.setResponseCode("403");
2147             responseBuilder.setResponseMessage("input is null");
2148             responseBuilder.setAckFinalIndicator("Y");
2149
2150             RpcResult<PreloadNetworkTopologyOperationOutput> rpcResult = RpcResultBuilder
2151                 .<PreloadNetworkTopologyOperationOutput>status(true)
2152                 .withResult(responseBuilder.build())
2153                 .build();
2154
2155             return Futures.immediateFuture(rpcResult);
2156         }
2157
2158         // Grab the name and type from the input buffer
2159         String preloadName = input.getNetworkTopologyInformation().getNetworkTopologyIdentifier().getNetworkName();
2160         String preloadType = input.getNetworkTopologyInformation().getNetworkTopologyIdentifier().getNetworkType();
2161
2162         // Make sure we have a preload_name and preload_type
2163         if (isValidPreloadData(preloadName, preloadType)) {
2164             log.debug("exiting {} because of invalid preload-name", svcOperation);
2165             responseBuilder.setResponseCode("403");
2166             responseBuilder.setResponseMessage("input, invalid preload-name");
2167             responseBuilder.setAckFinalIndicator("Y");
2168
2169             RpcResult<PreloadNetworkTopologyOperationOutput> rpcResult = RpcResultBuilder
2170                 .<PreloadNetworkTopologyOperationOutput>status(true)
2171                 .withResult(responseBuilder.build())
2172                 .build();
2173
2174             return Futures.immediateFuture(rpcResult);
2175         }
2176
2177         trySetSvcRequestId(input, responseBuilder);
2178
2179         PreloadDataBuilder preloadDataBuilder = new PreloadDataBuilder();
2180         getPreloadData(preloadName, preloadType, preloadDataBuilder);
2181
2182         PreloadDataBuilder operDataBuilder = new PreloadDataBuilder();
2183         getPreloadData(preloadName, preloadType, operDataBuilder, LogicalDatastoreType.OPERATIONAL);
2184
2185         //
2186         // setup a preload-data object builder
2187         // ACTION preload-network-topology-operation
2188         // INPUT:
2189         // USES sdnc-request-header;
2190         // USES request-information;
2191         // uses network-topology-information;
2192         // OUTPUT:
2193         // USES vnf-topology-response-body;
2194         //
2195         // container preload-data
2196         // uses vnf-topology-information;
2197         // uses network-topology-information;
2198         // uses oper-status;
2199
2200         log.info("Adding INPUT data for {} [{},{}] input: {}", svcOperation, preloadName, preloadType, input);
2201         PreloadNetworkTopologyOperationInputBuilder inputBuilder = new PreloadNetworkTopologyOperationInputBuilder(
2202             input);
2203         GenericResourceApiUtil.toProperties(parms, inputBuilder.build());
2204         log.info("Adding OPERATIONAL data for {} [{},{}] operational-data: {}", svcOperation, preloadName,
2205             preloadType, operDataBuilder.build());
2206         GenericResourceApiUtil.toProperties(parms, OPERATIONAL_DATA_PARAM, operDataBuilder);
2207
2208         // Call SLI sync method
2209         // Get SvcLogicService reference
2210         ResponseObject error = new ResponseObject("200", "");
2211         Properties respProps = tryGetProperties(svcOperation, parms, error);
2212
2213         String ackFinal = resolveAckFinal(error, respProps);
2214
2215         if (failed(error)) {
2216
2217             responseBuilder.setResponseCode(error.getStatusCode());
2218             responseBuilder.setResponseMessage(error.getMessage());
2219             responseBuilder.setAckFinalIndicator(ackFinal);
2220
2221             VnfPreloadListBuilder preloadVnfListBuilder = new VnfPreloadListBuilder();
2222             preloadVnfListBuilder.setVnfName(preloadName);
2223             preloadVnfListBuilder.setVnfType(preloadType);
2224             preloadVnfListBuilder.setPreloadData(preloadDataBuilder.build());
2225             log.error("Returned FAILED for {} [{},{}] error code: '{}', Reason: '{}'", svcOperation, preloadName,
2226                 preloadType, error.getStatusCode(), error.getMessage());
2227             try {
2228                 savePreloadList(preloadVnfListBuilder.build(), true, LogicalDatastoreType.CONFIGURATION);
2229             } catch (Exception e) {
2230                 log.error(UPDATING_MDSAL_ERROR_MESSAGE_2, svcOperation, preloadName,
2231                     preloadType, e);
2232
2233             }
2234             log.debug("Sending Success rpc result due to external error");
2235
2236             RpcResult<PreloadNetworkTopologyOperationOutput> rpcResult = RpcResultBuilder
2237                 .<PreloadNetworkTopologyOperationOutput>status(true)
2238                 .withResult(responseBuilder.build())
2239                 .build();
2240
2241             return Futures.immediateFuture(rpcResult);
2242         }
2243
2244         // Got success from SLI
2245         try {
2246             updatePreloadData(svcOperation, preloadName, preloadType, preloadDataBuilder);
2247         } catch (Exception e) {
2248             log.error(UPDATING_MDSAL_ERROR_MESSAGE_2, svcOperation, preloadName, preloadType, e);
2249             responseBuilder.setResponseCode("500");
2250             responseBuilder.setResponseMessage(e.toString());
2251             responseBuilder.setAckFinalIndicator("Y");
2252             log.error("Returned FAILED for {} [{},{}] {}", svcOperation, preloadName, preloadType,
2253                 responseBuilder.build());
2254
2255             RpcResult<PreloadNetworkTopologyOperationOutput> rpcResult = RpcResultBuilder
2256                 .<PreloadNetworkTopologyOperationOutput>status(false)
2257                 .withResult(responseBuilder.build())
2258                 .build();
2259
2260             return Futures.immediateFuture(rpcResult);
2261         }
2262
2263         // Update succeeded
2264         responseBuilder.setResponseCode(error.getStatusCode());
2265         responseBuilder.setAckFinalIndicator(ackFinal);
2266         trySetResponseMessage(responseBuilder, error);
2267
2268         log.info("Updated MD-SAL for {} [{},{}]", svcOperation, preloadName, preloadType);
2269         log.info("Returned SUCCESS for {} [{},{}] {}", svcOperation, preloadName, preloadType,
2270             responseBuilder.build());
2271
2272         RpcResult<PreloadNetworkTopologyOperationOutput> rpcResult = RpcResultBuilder
2273             .<PreloadNetworkTopologyOperationOutput>status(true)
2274             .withResult(responseBuilder.build())
2275             .build();
2276
2277         return Futures.immediateFuture(rpcResult);
2278     }
2279
2280     private void trySetResponseMessage(PreloadNetworkTopologyOperationOutputBuilder responseBuilder,
2281         ResponseObject error) {
2282         if (!error.getMessage().isEmpty()) {
2283             responseBuilder.setResponseMessage(error.getMessage());
2284         }
2285     }
2286
2287     private void trySetSvcRequestId(PreloadNetworkTopologyOperationInput input,
2288         PreloadNetworkTopologyOperationOutputBuilder responseBuilder) {
2289         if (input.getSdncRequestHeader() != null) {
2290             responseBuilder.setSvcRequestId(input.getSdncRequestHeader().getSvcRequestId());
2291         }
2292     }
2293
2294     private boolean isValidPreloadData(String preloadName, String preloadType) {
2295         return preloadName == null || preloadName.length() == 0 || preloadType == null || preloadType.length() == 0;
2296     }
2297
2298     private boolean hasInvalidNetworkTopology(PreloadNetworkTopologyOperationInput input) {
2299         return input == null || input.getNetworkTopologyInformation() == null
2300             || input.getNetworkTopologyInformation().getNetworkTopologyIdentifier() == null;
2301     }
2302
2303 }