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