aea201ed1205efa07e1a7523a7cd328414368d61
[sdnc/northbound.git] / generic-resource-api / provider / src / main / java / org / onap / sdnc / northbound / GenericResourceApiProvider.java
1 package org.onap.sdnc.northbound;
2
3 import com.google.common.base.Optional;
4 import com.google.common.util.concurrent.CheckedFuture;
5 import com.google.common.util.concurrent.Futures;
6 import java.text.DateFormat;
7 import java.text.SimpleDateFormat;
8 import java.util.Date;
9 import java.util.Properties;
10 import java.util.TimeZone;
11 import java.util.concurrent.ExecutionException;
12 import java.util.concurrent.ExecutorService;
13 import java.util.concurrent.Executors;
14 import java.util.concurrent.Future;
15 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
16 import org.opendaylight.controller.md.sal.binding.api.NotificationPublishService;
17 import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
18 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
19 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
20 import org.opendaylight.controller.md.sal.common.api.data.OptimisticLockFailedException;
21 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
22 import org.opendaylight.controller.sal.binding.api.BindingAwareBroker;
23 import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
24 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.BrgTopologyOperationInput;
25 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.BrgTopologyOperationInputBuilder;
26 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.BrgTopologyOperationOutput;
27 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.BrgTopologyOperationOutputBuilder;
28 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.ConnectionAttachmentTopologyOperationInput;
29 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.ConnectionAttachmentTopologyOperationOutput;
30 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.ContrailRouteTopologyOperationInput;
31 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.ContrailRouteTopologyOperationInputBuilder;
32 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.ContrailRouteTopologyOperationOutput;
33 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.ContrailRouteTopologyOperationOutputBuilder;
34 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.GENERICRESOURCEAPIService;
35 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.NetworkTopologyOperationInput;
36 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.NetworkTopologyOperationInputBuilder;
37 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.NetworkTopologyOperationOutput;
38 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.NetworkTopologyOperationOutputBuilder;
39 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.PreloadNetworkTopologyOperationInput;
40 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.PreloadNetworkTopologyOperationInputBuilder;
41 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.PreloadNetworkTopologyOperationOutput;
42 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.PreloadNetworkTopologyOperationOutputBuilder;
43 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.PreloadVnfTopologyOperationInput;
44 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.PreloadVnfTopologyOperationInputBuilder;
45 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.PreloadVnfTopologyOperationOutput;
46 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.PreloadVnfTopologyOperationOutputBuilder;
47 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.PreloadVnfs;
48 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.PreloadVnfsBuilder;
49 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.SecurityZoneTopologyOperationInput;
50 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.SecurityZoneTopologyOperationInputBuilder;
51 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.SecurityZoneTopologyOperationOutput;
52 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.SecurityZoneTopologyOperationOutputBuilder;
53 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.ServiceTopologyOperationInput;
54 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.ServiceTopologyOperationInputBuilder;
55 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.ServiceTopologyOperationOutput;
56 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.ServiceTopologyOperationOutputBuilder;
57 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.Services;
58 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.ServicesBuilder;
59 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.TunnelxconnTopologyOperationInput;
60 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.TunnelxconnTopologyOperationInputBuilder;
61 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.TunnelxconnTopologyOperationOutput;
62 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.TunnelxconnTopologyOperationOutputBuilder;
63 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.VfModuleTopologyOperationInput;
64 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.VfModuleTopologyOperationInputBuilder;
65 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.VfModuleTopologyOperationOutput;
66 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.VfModuleTopologyOperationOutputBuilder;
67 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.VnfTopologyOperationInput;
68 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.VnfTopologyOperationInputBuilder;
69 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.VnfTopologyOperationOutput;
70 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.VnfTopologyOperationOutputBuilder;
71 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.brg.response.information.BrgResponseInformationBuilder;
72 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.contrail.route.response.information.ContrailRouteResponseInformationBuilder;
73 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.network.response.information.NetworkResponseInformationBuilder;
74 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.preload.data.PreloadData;
75 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.preload.data.PreloadDataBuilder;
76 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.preload.model.information.VnfPreloadList;
77 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.preload.model.information.VnfPreloadListBuilder;
78 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.preload.model.information.VnfPreloadListKey;
79 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.request.information.RequestInformation;
80 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.sdnc.request.header.SdncRequestHeader;
81 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.sdnc.request.header.SdncRequestHeader.SvcAction;
82 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.security.zone.response.information.SecurityZoneResponseInformationBuilder;
83 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.service.data.ServiceData;
84 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.service.data.ServiceDataBuilder;
85 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.service.model.infrastructure.Service;
86 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.service.model.infrastructure.ServiceBuilder;
87 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.service.model.infrastructure.ServiceKey;
88 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.service.response.information.ServiceResponseInformationBuilder;
89 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.service.status.ServiceStatus.RequestStatus;
90 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.service.status.ServiceStatus.RpcAction;
91 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.service.status.ServiceStatusBuilder;
92 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.tunnelxconn.response.information.TunnelxconnResponseInformationBuilder;
93 import org.opendaylight.yangtools.yang.binding.DataObject;
94 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
95 import org.opendaylight.yangtools.yang.common.RpcResult;
96 import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
97 import org.slf4j.Logger;
98 import org.slf4j.LoggerFactory;
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     protected 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     protected 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     protected 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     protected 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 (hasInvalidServiceId(input)) {
506             log.debug(NULL_OR_EMPTY_ERROR_MESSAGE, svcOperation);
507             responseBuilder.setResponseCode("404");
508             responseBuilder.setResponseMessage(NULL_OR_EMPTY_ERROR_PARAM);
509             responseBuilder.setAckFinalIndicator("Y");
510
511             RpcResult<ServiceTopologyOperationOutput> rpcResult = RpcResultBuilder
512                 .<ServiceTopologyOperationOutput>status(true)
513                 .withResult(responseBuilder.build())
514                 .build();
515
516             return Futures.immediateFuture(rpcResult);
517         }
518
519         // Grab the service instance ID from the input buffer
520         String siid = input.getServiceInformation().getServiceInstanceId();
521
522         trySetSvcRequestId(input, responseBuilder);
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         ResponseObject responseObject = new ResponseObject("200", "");
552         String ackFinal = "Y";
553         String serviceObjectPath = null;
554         Properties respProps = tryGetProperties(svcOperation, parms, serviceDataBuilder, responseObject);
555
556         if (respProps != null) {
557             responseObject.setStatusCode(respProps.getProperty(ERROR_CODE_PARAM));
558             responseObject.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, responseObject.getStatusCode(), responseObject.getMessage(), ackFinal);
564         serviceStatusBuilder.setRequestStatus(RequestStatus.Synccomplete);
565         serviceStatusBuilder.setRpcName(svcOperation);
566
567         if (failed(responseObject)) {
568             responseBuilder.setResponseCode(responseObject.getStatusCode());
569             responseBuilder.setResponseMessage(responseObject.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             tryDeleteService(input, serviceBuilder);
603
604             ServiceResponseInformationBuilder serviceResponseInformationBuilder = new ServiceResponseInformationBuilder();
605             serviceResponseInformationBuilder.setInstanceId(siid);
606             serviceResponseInformationBuilder.setObjectPath(serviceObjectPath);
607             responseBuilder.setServiceResponseInformation(serviceResponseInformationBuilder.build());
608
609         } catch (Exception e) {
610             log.error(UPDATING_MDSAL_ERROR_MESSAGE, svcOperation, siid, e);
611             responseBuilder.setResponseCode("500");
612             responseBuilder.setResponseMessage(e.getMessage());
613             responseBuilder.setAckFinalIndicator("Y");
614             log.error(RETURNED_FAILED_MESSAGE, svcOperation, siid, responseBuilder.build());
615
616             RpcResult<ServiceTopologyOperationOutput> rpcResult = RpcResultBuilder
617                 .<ServiceTopologyOperationOutput>status(true)
618                 .withResult(responseBuilder.build())
619                 .build();
620
621             return Futures.immediateFuture(rpcResult);
622         }
623
624         // Update succeeded
625         responseBuilder.setResponseCode(responseObject.getStatusCode());
626         responseBuilder.setAckFinalIndicator(ackFinal);
627         trySetResponseMessage(responseBuilder, responseObject);
628         log.info(UPDATED_MDSAL_INFO_MESSAGE, svcOperation, siid);
629         log.info(RETURNED_SUCCESS_MESSAGE, svcOperation, siid, responseBuilder.build());
630
631         RpcResult<ServiceTopologyOperationOutput> rpcResult = RpcResultBuilder
632             .<ServiceTopologyOperationOutput>status(true)
633             .withResult(responseBuilder.build())
634             .build();
635
636         return Futures.immediateFuture(rpcResult);
637     }
638
639     private void trySetResponseMessage(ServiceTopologyOperationOutputBuilder responseBuilder, ResponseObject error) {
640         if (!error.getMessage().isEmpty()) {
641             responseBuilder.setResponseMessage(error.getMessage());
642         }
643     }
644
645     private boolean hasInvalidServiceId(ServiceTopologyOperationInput input) {
646         return input == null || input.getServiceInformation() == null
647             || input.getServiceInformation().getServiceInstanceId() == null
648             || input.getServiceInformation().getServiceInstanceId().length() == 0;
649     }
650
651     private void trySetSvcRequestId(ServiceTopologyOperationInput input,
652         ServiceTopologyOperationOutputBuilder responseBuilder) {
653         if (input.getSdncRequestHeader() != null) {
654             responseBuilder.setSvcRequestId(input.getSdncRequestHeader().getSvcRequestId());
655         }
656     }
657
658     private void tryDeleteService(ServiceTopologyOperationInput input, ServiceBuilder serviceBuilder) {
659         if (isValidRequest(input) && input.getSdncRequestHeader().getSvcAction().equals(SvcAction.Delete)) {
660             // Only update operational tree on delete
661             log.info("Delete from both CONFIGURATION and OPERATIONAL tree.");
662             deleteService(serviceBuilder.build(), LogicalDatastoreType.OPERATIONAL);
663             deleteService(serviceBuilder.build(), LogicalDatastoreType.CONFIGURATION);
664         }
665     }
666
667     private Properties tryGetProperties(String svcOperation, Properties parms, ServiceDataBuilder serviceDataBuilder,
668         ResponseObject responseObject) {
669         try {
670             if (svcLogicClient.hasGraph(APP_NAME, svcOperation, null, "sync")) {
671                 try {
672                     return svcLogicClient.execute(APP_NAME, svcOperation, null, "sync", serviceDataBuilder, parms);
673                 } catch (Exception e) {
674                     log.error(SERVICE_LOGIC_EXECUTION_ERROR_MESSAGE, svcOperation, e);
675                     responseObject.setMessage(e.getMessage());
676                     responseObject.setStatusCode("500");
677                 }
678             } else {
679                 responseObject.setMessage(NO_SERVICE_LOGIC_ACTIVE + APP_NAME + ": '" + svcOperation + "'");
680                 responseObject.setStatusCode("503");
681             }
682         } catch (Exception e) {
683             responseObject.setMessage(e.getMessage());
684             responseObject.setStatusCode("500");
685             log.error(SERVICE_LOGIC_SEARCH_ERROR_MESSAGE, e);
686         }
687
688         return null;
689     }
690
691     private boolean failed(ResponseObject error) {
692         return
693             !error.getStatusCode().isEmpty() && !("0".equals(error.getStatusCode()) || "200"
694                 .equals(error.getStatusCode()));
695     }
696
697     private boolean isValidRequest(ServiceTopologyOperationInput input) {
698         return input.getSdncRequestHeader() != null && input.getSdncRequestHeader().getSvcAction() != null;
699     }
700
701     @Override
702     public Future<RpcResult<VnfTopologyOperationOutput>> vnfTopologyOperation(VnfTopologyOperationInput input) {
703
704         final String svcOperation = "vnf-topology-operation";
705         ServiceData serviceData;
706         ServiceStatusBuilder serviceStatusBuilder = new ServiceStatusBuilder();
707         Properties properties = new Properties();
708
709         log.info(CALLED_STR, svcOperation);
710         // create a new response object
711         VnfTopologyOperationOutputBuilder responseBuilder = new VnfTopologyOperationOutputBuilder();
712
713         if (hasInvalidServiceId(input)) {
714
715             log.debug(NULL_OR_EMPTY_ERROR_MESSAGE, svcOperation);
716             responseBuilder.setResponseCode("404");
717             responseBuilder.setResponseMessage(NULL_OR_EMPTY_ERROR_PARAM);
718             responseBuilder.setAckFinalIndicator("Y");
719             RpcResult<VnfTopologyOperationOutput> rpcResult = RpcResultBuilder.<VnfTopologyOperationOutput>status(true)
720                 .withResult(responseBuilder.build()).build();
721             // return error
722             return Futures.immediateFuture(rpcResult);
723         }
724
725         // Grab the service instance ID from the input buffer
726         String siid = input.getServiceInformation().getServiceInstanceId();
727
728         trySetSvcRequestId(input, responseBuilder);
729
730         if (hasInvalidVnfId(input)) {
731             log.debug("exiting {} because of null or empty vnf-id", svcOperation);
732             responseBuilder.setResponseCode("404");
733             responseBuilder.setResponseMessage("invalid input, null or empty vnf-id");
734             responseBuilder.setAckFinalIndicator("Y");
735
736             RpcResult<VnfTopologyOperationOutput> rpcResult = RpcResultBuilder
737                 .<VnfTopologyOperationOutput>status(true)
738                 .withResult(responseBuilder.build())
739                 .build();
740
741             return Futures.immediateFuture(rpcResult);
742         }
743
744         ServiceDataBuilder serviceDataBuilder = new ServiceDataBuilder();
745         getServiceData(siid, serviceDataBuilder);
746
747         ServiceDataBuilder operDataBuilder = new ServiceDataBuilder();
748         getServiceData(siid, operDataBuilder, LogicalDatastoreType.OPERATIONAL);
749
750         // Set the serviceStatus based on input
751         setServiceStatus(serviceStatusBuilder, input.getSdncRequestHeader());
752         setServiceStatus(serviceStatusBuilder, input.getRequestInformation());
753
754         //
755         // setup a service-data object builder
756         // ACTION vnf-topology-operation
757         // INPUT:
758         // USES sdnc-request-header;
759         // USES request-information;
760         // USES service-information;
761         // USES vnf-request-information
762         // OUTPUT:
763         // USES vnf-topology-response-body;
764         // USES vnf-information
765         // USES service-information
766         //
767         // container service-data
768         // uses vnf-configuration-information;
769         // uses oper-status;
770
771         log.info(ADDING_INPUT_DATA_LOG, svcOperation, siid, input);
772         VnfTopologyOperationInputBuilder inputBuilder = new VnfTopologyOperationInputBuilder(input);
773         GenericResourceApiUtil.toProperties(properties, inputBuilder.build());
774
775         log.info(ADDING_OPERATIONAL_DATA_LOG, svcOperation, siid,
776             operDataBuilder.build());
777         GenericResourceApiUtil.toProperties(properties, OPERATIONAL_DATA_PARAM, operDataBuilder);
778
779         // Call SLI sync method
780         // Get SvcLogicService reference
781
782         ResponseObject responseObject = new ResponseObject("200", "");
783         String ackFinal = "Y";
784         String serviceObjectPath = null;
785         Properties respProps = tryGetProperties(svcOperation, properties, serviceDataBuilder, responseObject);
786
787         if (respProps != null) {
788             responseObject.setMessage(respProps.getProperty(ERROR_MESSAGE_PARAM));
789             responseObject.setStatusCode(respProps.getProperty(ERROR_CODE_PARAM));
790             ackFinal = respProps.getProperty(ACK_FINAL_PARAM, "Y");
791
792             //FIXME if needed
793             /*before was "vfn-object-path", but it didn't make sense, since everywhere else,
794               when extracting service object path the "service-object-path" property is used*/
795             serviceObjectPath = respProps.getProperty(SERVICE_OBJECT_PATH_PARAM);
796         }
797
798         setServiceStatus(serviceStatusBuilder, responseObject.getStatusCode(), responseObject.getMessage(), ackFinal);
799         serviceStatusBuilder.setRequestStatus(RequestStatus.Synccomplete);
800         serviceStatusBuilder.setRpcName(svcOperation);
801
802         if (failed(responseObject)) {
803             responseBuilder.setResponseCode(responseObject.getStatusCode());
804             responseBuilder.setResponseMessage(responseObject.getMessage());
805             responseBuilder.setAckFinalIndicator(ackFinal);
806
807             ServiceBuilder serviceBuilder = new ServiceBuilder();
808             serviceBuilder.setServiceInstanceId(siid);
809             serviceBuilder.setServiceStatus(serviceStatusBuilder.build());
810             try {
811                 saveService(serviceBuilder.build(), true, LogicalDatastoreType.CONFIGURATION);
812                 trySaveService(input, serviceBuilder);
813             } catch (Exception e) {
814                 log.error(UPDATING_MDSAL_ERROR_MESSAGE, svcOperation, siid, e);
815             }
816             log.error(RETURNED_FAILED_MESSAGE, svcOperation, siid, responseBuilder.build());
817
818             RpcResult<VnfTopologyOperationOutput> rpcResult = RpcResultBuilder
819                 .<VnfTopologyOperationOutput>status(true)
820                 .withResult(responseBuilder.build())
821                 .build();
822
823             // return error
824             return Futures.immediateFuture(rpcResult);
825         }
826
827         // Got success from SLI
828         try {
829             serviceData = serviceDataBuilder.build();
830             log.info(UPDATING_MDSAL_INFO_MESSAGE, svcOperation, siid, serviceData);
831
832             // service object
833             ServiceBuilder serviceBuilder = new ServiceBuilder();
834             serviceBuilder.setServiceData(serviceData);
835             serviceBuilder.setServiceInstanceId(siid);
836             serviceBuilder.setServiceStatus(serviceStatusBuilder.build());
837             saveService(serviceBuilder.build(), false, LogicalDatastoreType.CONFIGURATION);
838
839             if (isValidRequest(input) && input.getSdncRequestHeader().getSvcAction().equals(SvcAction.Activate)) {
840                 // Only update operational tree on Assign
841
842                 log.info(UPDATING_TREE_INFO_MESSAGE);
843                 saveService(serviceBuilder.build(), false, LogicalDatastoreType.OPERATIONAL);
844             }
845
846             ServiceResponseInformationBuilder serviceResponseInformationBuilder = new ServiceResponseInformationBuilder();
847             serviceResponseInformationBuilder.setInstanceId(siid);
848             serviceResponseInformationBuilder.setObjectPath(serviceObjectPath);
849             responseBuilder.setServiceResponseInformation(serviceResponseInformationBuilder.build());
850
851         } catch (Exception e) {
852             log.error(UPDATING_MDSAL_ERROR_MESSAGE, svcOperation, siid, e);
853             responseBuilder.setResponseCode("500");
854             responseBuilder.setResponseMessage(e.getMessage());
855             responseBuilder.setAckFinalIndicator("Y");
856             log.error(RETURNED_FAILED_MESSAGE, svcOperation, siid, responseBuilder.build());
857
858             RpcResult<VnfTopologyOperationOutput> rpcResult = RpcResultBuilder
859                 .<VnfTopologyOperationOutput>status(true)
860                 .withResult(responseBuilder.build())
861                 .build();
862
863             return Futures.immediateFuture(rpcResult);
864         }
865
866         // Update succeeded
867         responseBuilder.setResponseCode(responseObject.getStatusCode());
868         responseBuilder.setAckFinalIndicator(ackFinal);
869         trySetResponseMessage(responseBuilder, responseObject);
870         log.info(UPDATED_MDSAL_INFO_MESSAGE, svcOperation, siid);
871         log.info(RETURNED_SUCCESS_MESSAGE, svcOperation, siid, responseBuilder.build());
872
873         RpcResult<VnfTopologyOperationOutput> rpcResult = RpcResultBuilder
874             .<VnfTopologyOperationOutput>status(true)
875             .withResult(responseBuilder.build())
876             .build();
877
878         // return success
879         return Futures.immediateFuture(rpcResult);
880     }
881
882     private void trySetResponseMessage(VnfTopologyOperationOutputBuilder responseBuilder, ResponseObject error) {
883         if (!error.getMessage().isEmpty()) {
884             responseBuilder.setResponseMessage(error.getMessage());
885         }
886     }
887
888     private void trySaveService(VnfTopologyOperationInput input, ServiceBuilder serviceBuilder) {
889         if (isValidRequest(input) &&
890             (input.getSdncRequestHeader().getSvcAction().equals(SvcAction.Delete) ||
891                 input.getSdncRequestHeader().getSvcAction().equals(SvcAction.Activate))) {
892
893             // Only update operational tree on activate or delete
894             log.info(UPDATING_TREE_INFO_MESSAGE);
895             saveService(serviceBuilder.build(), false, LogicalDatastoreType.OPERATIONAL);
896         }
897     }
898
899     private boolean hasInvalidVnfId(VnfTopologyOperationInput input) {
900         return input.getVnfInformation() == null || input.getVnfInformation().getVnfId() == null
901             || input.getVnfInformation().getVnfId().length() == 0;
902     }
903
904     private boolean hasInvalidServiceId(VnfTopologyOperationInput input) {
905         return input == null || input.getServiceInformation() == null
906             || input.getServiceInformation().getServiceInstanceId() == null
907             || input.getServiceInformation().getServiceInstanceId().length() == 0;
908     }
909
910     private void trySetSvcRequestId(VnfTopologyOperationInput input,
911         VnfTopologyOperationOutputBuilder responseBuilder) {
912         if (input.getSdncRequestHeader() != null) {
913             responseBuilder.setSvcRequestId(input.getSdncRequestHeader().getSvcRequestId());
914         }
915     }
916
917     private boolean isValidRequest(VnfTopologyOperationInput input) {
918         return input.getSdncRequestHeader() != null && input.getSdncRequestHeader().getSvcAction() != null;
919     }
920
921     @Override
922     public Future<RpcResult<VfModuleTopologyOperationOutput>> vfModuleTopologyOperation(
923         VfModuleTopologyOperationInput input) {
924
925         final String svcOperation = "vf-module-topology-operation";
926         ServiceData serviceData;
927         ServiceStatusBuilder serviceStatusBuilder = new ServiceStatusBuilder();
928         Properties parms = new Properties();
929
930         log.info(CALLED_STR, svcOperation);
931         // create a new response object
932         VfModuleTopologyOperationOutputBuilder responseBuilder = new VfModuleTopologyOperationOutputBuilder();
933
934         if (hasInvalidServiceId(input)) {
935             log.debug(NULL_OR_EMPTY_ERROR_MESSAGE, svcOperation);
936             responseBuilder.setResponseCode("403");
937             responseBuilder.setResponseMessage(NULL_OR_EMPTY_ERROR_PARAM);
938             responseBuilder.setAckFinalIndicator("Y");
939
940             RpcResult<VfModuleTopologyOperationOutput> rpcResult = RpcResultBuilder
941                 .<VfModuleTopologyOperationOutput>status(true)
942                 .withResult(responseBuilder.build())
943                 .build();
944
945             // return error
946             return Futures.immediateFuture(rpcResult);
947         }
948
949         if (hasInvalidVnfId(input)) {
950             log.debug("exiting {} because of null or empty vnf-id", svcOperation);
951             responseBuilder.setResponseCode("403");
952             responseBuilder.setResponseMessage("invalid input, null or empty vnf-id");
953             responseBuilder.setAckFinalIndicator("Y");
954             RpcResult<VfModuleTopologyOperationOutput> rpcResult = RpcResultBuilder
955                 .<VfModuleTopologyOperationOutput>status(true).withResult(responseBuilder.build()).build();
956             return Futures.immediateFuture(rpcResult);
957         }
958
959         if (hasInvalidVfModuleId(input)) {
960             log.debug("exiting {} because of null or empty vf-module-id", svcOperation);
961             responseBuilder.setResponseCode("403");
962             responseBuilder.setResponseMessage("invalid input, vf-module-id is null or empty");
963             responseBuilder.setAckFinalIndicator("Y");
964
965             RpcResult<VfModuleTopologyOperationOutput> rpcResult = RpcResultBuilder
966                 .<VfModuleTopologyOperationOutput>status(true)
967                 .withResult(responseBuilder.build())
968                 .build();
969
970             return Futures.immediateFuture(rpcResult);
971         }
972
973         // Grab the service instance ID from the input buffer
974         String siid = input.getServiceInformation().getServiceInstanceId();
975
976         trySetSvcRequestId(input, responseBuilder);
977
978         ServiceDataBuilder serviceDataBuilder = new ServiceDataBuilder();
979         getServiceData(siid, serviceDataBuilder);
980
981         ServiceDataBuilder operDataBuilder = new ServiceDataBuilder();
982         getServiceData(siid, operDataBuilder, LogicalDatastoreType.OPERATIONAL);
983
984         // Set the serviceStatus based on input
985         setServiceStatus(serviceStatusBuilder, input.getSdncRequestHeader());
986         setServiceStatus(serviceStatusBuilder, input.getRequestInformation());
987
988         //
989         // setup a service-data object builder
990         // ACTION vnf-topology-operation
991         // INPUT:
992         // USES sdnc-request-header;
993         // USES request-information;
994         // USES service-information;
995         // USES vnf-request-information
996         // OUTPUT:
997         // USES vnf-topology-response-body;
998         // USES vnf-information
999         // USES service-information
1000         //
1001         // container service-data
1002         // uses vnf-configuration-information;
1003         // uses oper-status;
1004
1005         log.info(ADDING_INPUT_DATA_LOG, svcOperation, siid, input);
1006         VfModuleTopologyOperationInputBuilder inputBuilder = new VfModuleTopologyOperationInputBuilder(input);
1007         GenericResourceApiUtil.toProperties(parms, inputBuilder.build());
1008
1009         log.info(ADDING_OPERATIONAL_DATA_LOG, svcOperation, siid,
1010             operDataBuilder.build());
1011         GenericResourceApiUtil.toProperties(parms, OPERATIONAL_DATA_PARAM, operDataBuilder);
1012
1013         // Call SLI sync method
1014         // Get SvcLogicService reference
1015
1016         ResponseObject responseObject = new ResponseObject("200", "");
1017         String ackFinal = "Y";
1018         String serviceObjectPath = null;
1019         Properties respProps = tryGetProperties(svcOperation, parms, serviceDataBuilder, responseObject);
1020
1021         if (respProps != null) {
1022             responseObject.setStatusCode(respProps.getProperty(ERROR_CODE_PARAM));
1023             responseObject.setMessage(respProps.getProperty(ERROR_MESSAGE_PARAM));
1024             ackFinal = respProps.getProperty(ACK_FINAL_PARAM, "Y");
1025
1026
1027             //FIXME if needed
1028             /*before was "vf-module-object-path", but it didnt make sense, since everywhere else,
1029               when extracting service object path the "service-object-path" property is used*/
1030             serviceObjectPath = respProps.getProperty(SERVICE_OBJECT_PATH_PARAM);
1031         }
1032
1033         setServiceStatus(serviceStatusBuilder, responseObject.getStatusCode(), responseObject.getMessage(), ackFinal);
1034         serviceStatusBuilder.setRequestStatus(RequestStatus.Synccomplete);
1035         serviceStatusBuilder.setRpcName(svcOperation);
1036
1037         if (failed(responseObject)) {
1038             responseBuilder.setResponseCode(responseObject.getStatusCode());
1039             responseBuilder.setResponseMessage(responseObject.getMessage());
1040             responseBuilder.setAckFinalIndicator(ackFinal);
1041
1042             ServiceBuilder serviceBuilder = new ServiceBuilder();
1043             serviceBuilder.setServiceInstanceId(siid);
1044             serviceBuilder.setServiceStatus(serviceStatusBuilder.build());
1045             try {
1046                 saveService(serviceBuilder.build(), true, LogicalDatastoreType.CONFIGURATION);
1047             } catch (Exception e) {
1048                 log.error(UPDATING_MDSAL_ERROR_MESSAGE, svcOperation, siid, e);
1049             }
1050             log.error(RETURNED_FAILED_MESSAGE, svcOperation, siid, responseBuilder.build());
1051
1052             RpcResult<VfModuleTopologyOperationOutput> rpcResult = RpcResultBuilder
1053                 .<VfModuleTopologyOperationOutput>status(true)
1054                 .withResult(responseBuilder.build())
1055                 .build();
1056
1057             // return error
1058             return Futures.immediateFuture(rpcResult);
1059         }
1060
1061         // Got success from SLI
1062         try {
1063             serviceData = serviceDataBuilder.build();
1064             log.info(UPDATING_MDSAL_INFO_MESSAGE, svcOperation, siid, serviceData);
1065
1066             // service object
1067             ServiceBuilder serviceBuilder = new ServiceBuilder();
1068             serviceBuilder.setServiceData(serviceData);
1069             serviceBuilder.setServiceInstanceId(siid);
1070             serviceBuilder.setServiceStatus(serviceStatusBuilder.build());
1071             saveService(serviceBuilder.build(), false, LogicalDatastoreType.CONFIGURATION);
1072
1073             trySaveService(input, serviceBuilder);
1074
1075             ServiceResponseInformationBuilder serviceResponseInformationBuilder = new ServiceResponseInformationBuilder();
1076             serviceResponseInformationBuilder.setInstanceId(siid);
1077             serviceResponseInformationBuilder.setObjectPath(serviceObjectPath);
1078             responseBuilder.setServiceResponseInformation(serviceResponseInformationBuilder.build());
1079
1080         } catch (Exception e) {
1081             log.error(UPDATING_MDSAL_ERROR_MESSAGE, svcOperation, siid, e);
1082             responseBuilder.setResponseCode("500");
1083             responseBuilder.setResponseMessage(e.getMessage());
1084             responseBuilder.setAckFinalIndicator("Y");
1085             log.error(RETURNED_FAILED_MESSAGE, svcOperation, siid, responseBuilder.build());
1086
1087             RpcResult<VfModuleTopologyOperationOutput> rpcResult = RpcResultBuilder
1088                 .<VfModuleTopologyOperationOutput>status(true)
1089                 .withResult(responseBuilder.build())
1090                 .build();
1091
1092             return Futures.immediateFuture(rpcResult);
1093         }
1094
1095         // Update succeeded
1096         responseBuilder.setResponseCode(responseObject.getStatusCode());
1097         responseBuilder.setAckFinalIndicator(ackFinal);
1098         trySetResponseMessage(responseBuilder, responseObject);
1099         log.info(UPDATED_MDSAL_INFO_MESSAGE, svcOperation, siid);
1100         log.info(RETURNED_SUCCESS_MESSAGE, svcOperation, siid, responseBuilder.build());
1101
1102         RpcResult<VfModuleTopologyOperationOutput> rpcResult = RpcResultBuilder
1103             .<VfModuleTopologyOperationOutput>status(true)
1104             .withResult(responseBuilder.build())
1105             .build();
1106
1107         // return success
1108         return Futures.immediateFuture(rpcResult);
1109     }
1110
1111     private void trySetResponseMessage(VfModuleTopologyOperationOutputBuilder responseBuilder, ResponseObject error) {
1112         if (!error.getMessage().isEmpty()) {
1113             responseBuilder.setResponseMessage(error.getMessage());
1114         }
1115     }
1116
1117     private void trySaveService(VfModuleTopologyOperationInput input, ServiceBuilder serviceBuilder) {
1118         if (isValidRequest(input) &&
1119             (input.getSdncRequestHeader().getSvcAction().equals(SvcAction.Unassign) ||
1120                 input.getSdncRequestHeader().getSvcAction().equals(SvcAction.Activate))) {
1121             // Only update operational tree on activate or delete
1122
1123             log.info(UPDATING_TREE_INFO_MESSAGE);
1124             saveService(serviceBuilder.build(), false, LogicalDatastoreType.OPERATIONAL);
1125         }
1126     }
1127
1128     private void trySetSvcRequestId(VfModuleTopologyOperationInput input,
1129         VfModuleTopologyOperationOutputBuilder responseBuilder) {
1130         if (input.getSdncRequestHeader() != null) {
1131             responseBuilder.setSvcRequestId(input.getSdncRequestHeader().getSvcRequestId());
1132         }
1133     }
1134
1135     private boolean hasInvalidVfModuleId(VfModuleTopologyOperationInput input) {
1136         return input.getVfModuleInformation() == null || input.getVfModuleInformation().getVfModuleId() == null
1137             || input.getVfModuleInformation().getVfModuleId().length() == 0;
1138     }
1139
1140     private boolean hasInvalidVnfId(VfModuleTopologyOperationInput input) {
1141         return input.getVnfInformation() == null || input.getVnfInformation().getVnfId() == null
1142             || input.getVnfInformation().getVnfId().length() == 0;
1143     }
1144
1145     private boolean hasInvalidServiceId(VfModuleTopologyOperationInput input) {
1146         return input == null || input.getServiceInformation() == null
1147             || input.getServiceInformation().getServiceInstanceId() == null
1148             || input.getServiceInformation().getServiceInstanceId().length() == 0;
1149     }
1150
1151     private boolean isValidRequest(VfModuleTopologyOperationInput input) {
1152         return input.getSdncRequestHeader() != null && input.getSdncRequestHeader().getSvcAction() != null;
1153     }
1154
1155     @Override
1156     public Future<RpcResult<NetworkTopologyOperationOutput>> networkTopologyOperation(
1157         NetworkTopologyOperationInput input) {
1158
1159         final String svcOperation = "network-topology-operation";
1160         ServiceData serviceData;
1161         ServiceStatusBuilder serviceStatusBuilder = new ServiceStatusBuilder();
1162         Properties parms = new Properties();
1163
1164         log.info(CALLED_STR, svcOperation);
1165         // create a new response object
1166         NetworkTopologyOperationOutputBuilder responseBuilder = new NetworkTopologyOperationOutputBuilder();
1167
1168         if (hasInvalidServiceId(input)) {
1169             log.debug(NULL_OR_EMPTY_ERROR_MESSAGE, svcOperation);
1170             return buildRpcResultFuture(responseBuilder, NULL_OR_EMPTY_ERROR_PARAM);
1171         }
1172
1173         String siid = input.getServiceInformation().getServiceInstanceId();
1174
1175         // Get the service-instance service data from MD-SAL
1176         ServiceDataBuilder serviceDataBuilder = new ServiceDataBuilder();
1177         getServiceData(siid, serviceDataBuilder);
1178
1179         this.trySetSvcRequestId(input, responseBuilder);
1180
1181         ServiceData sd = serviceDataBuilder.build();
1182         if (isInvalidServiceData(sd)) {
1183             log.debug(EMPTY_SERVICE_INSTANCE_MESSAGE, svcOperation);
1184             return buildRpcResultFuture(responseBuilder, INVALID_INPUT_ERROR_MESSAGE);
1185         }
1186
1187         log.info(ADDING_INPUT_DATA_LOG, svcOperation, siid, input);
1188         NetworkTopologyOperationInputBuilder inputBuilder = new NetworkTopologyOperationInputBuilder(input);
1189         GenericResourceApiUtil.toProperties(parms, inputBuilder.build());
1190
1191         // Call SLI sync method
1192         // Get SvcLogicService reference
1193
1194         ResponseObject responseObject = new ResponseObject("200", "");
1195         String ackFinal = "Y";
1196         String networkId = ERROR_NETWORK_ID;
1197         String serviceObjectPath = null;
1198         String networkObjectPath = null;
1199         Properties respProps = tryGetProperties(svcOperation, parms, serviceDataBuilder, responseObject);
1200
1201         if (respProps != null) {
1202             responseObject.setStatusCode(respProps.getProperty(ERROR_CODE_PARAM));
1203             responseObject.setMessage(respProps.getProperty(ERROR_MESSAGE_PARAM));
1204             ackFinal = respProps.getProperty(ACK_FINAL_PARAM, "Y");
1205             networkId = respProps.getProperty("networkId");
1206             serviceObjectPath = respProps.getProperty(SERVICE_OBJECT_PATH_PARAM);
1207             networkObjectPath = respProps.getProperty("network-object-path");
1208         }
1209
1210         if (failed(responseObject)) {
1211             responseBuilder.setResponseCode(responseObject.getStatusCode());
1212             responseBuilder.setResponseMessage(responseObject.getMessage());
1213             responseBuilder.setAckFinalIndicator(ackFinal);
1214
1215             log.error(RETURNED_FAILED_MESSAGE, svcOperation, siid, responseBuilder.build());
1216
1217             RpcResult<NetworkTopologyOperationOutput> rpcResult = RpcResultBuilder
1218                 .<NetworkTopologyOperationOutput>status(true)
1219                 .withResult(responseBuilder.build())
1220                 .build();
1221
1222             return Futures.immediateFuture(rpcResult);
1223         }
1224
1225         // Got success from SLI
1226         try {
1227
1228             serviceData = serviceDataBuilder.build();
1229             log.info(UPDATING_MDSAL_INFO_MESSAGE, svcOperation, siid, serviceData);
1230
1231             // service object
1232             ServiceBuilder serviceBuilder = new ServiceBuilder();
1233             serviceBuilder.setServiceData(serviceData);
1234             serviceBuilder.setServiceInstanceId(siid);
1235             serviceBuilder.setServiceStatus(serviceStatusBuilder.build());
1236             saveService(serviceBuilder.build(), false, LogicalDatastoreType.CONFIGURATION);
1237
1238             trySaveService(input, serviceBuilder);
1239
1240             NetworkResponseInformationBuilder networkResponseInformationBuilder = new NetworkResponseInformationBuilder();
1241             networkResponseInformationBuilder.setInstanceId(networkId);
1242             networkResponseInformationBuilder.setObjectPath(networkObjectPath);
1243             responseBuilder.setNetworkResponseInformation(networkResponseInformationBuilder.build());
1244
1245             ServiceResponseInformationBuilder serviceResponseInformationBuilder = new ServiceResponseInformationBuilder();
1246             serviceResponseInformationBuilder.setInstanceId(siid);
1247             serviceResponseInformationBuilder.setObjectPath(serviceObjectPath);
1248             responseBuilder.setServiceResponseInformation(serviceResponseInformationBuilder.build());
1249
1250         } catch (IllegalStateException e) {
1251             log.error(UPDATING_MDSAL_ERROR_MESSAGE, svcOperation, siid, e);
1252             responseBuilder.setResponseCode("500");
1253             responseBuilder.setResponseMessage(e.getMessage());
1254             responseBuilder.setAckFinalIndicator("Y");
1255             log.error(RETURNED_FAILED_MESSAGE, svcOperation, siid, responseBuilder.build());
1256
1257             RpcResult<NetworkTopologyOperationOutput> rpcResult = RpcResultBuilder
1258                 .<NetworkTopologyOperationOutput>status(true)
1259                 .withResult(responseBuilder.build())
1260                 .build();
1261
1262             return Futures.immediateFuture(rpcResult);
1263         }
1264
1265         // Update succeeded
1266         responseBuilder.setResponseCode(responseObject.getStatusCode());
1267         responseBuilder.setAckFinalIndicator(ackFinal);
1268         trySetResponseMessage(responseBuilder, responseObject);
1269         log.info(UPDATED_MDSAL_INFO_MESSAGE, svcOperation, siid);
1270         log.info(RETURNED_SUCCESS_MESSAGE, svcOperation, siid, responseBuilder.build());
1271
1272         RpcResult<NetworkTopologyOperationOutput> rpcResult = RpcResultBuilder
1273             .<NetworkTopologyOperationOutput>status(true)
1274             .withResult(responseBuilder.build())
1275             .build();
1276
1277         return Futures.immediateFuture(rpcResult);
1278     }
1279
1280     private void trySetResponseMessage(NetworkTopologyOperationOutputBuilder responseBuilder, ResponseObject error) {
1281         if (!error.getMessage().isEmpty()) {
1282             responseBuilder.setResponseMessage(error.getMessage());
1283         }
1284     }
1285
1286     private void trySetSvcRequestId(NetworkTopologyOperationInput input,
1287         NetworkTopologyOperationOutputBuilder responseBuilder) {
1288         if (input.getSdncRequestHeader() != null) {
1289             responseBuilder.setSvcRequestId(input.getSdncRequestHeader().getSvcRequestId());
1290         }
1291     }
1292
1293     private void trySaveService(NetworkTopologyOperationInput input, ServiceBuilder serviceBuilder) {
1294         if (isValidRequest(input) &&
1295             (input.getSdncRequestHeader().getSvcAction().equals(SvcAction.Activate) ||
1296                 input.getSdncRequestHeader().getSvcAction().equals(SvcAction.Create))) {
1297             // Only update operational tree on Activate
1298             log.info(UPDATING_TREE_INFO_MESSAGE);
1299             saveService(serviceBuilder.build(), false, LogicalDatastoreType.OPERATIONAL);
1300         }
1301     }
1302
1303     private boolean hasInvalidServiceId(NetworkTopologyOperationInput input) {
1304         return input == null || input.getServiceInformation() == null
1305             || input.getServiceInformation().getServiceInstanceId() == null
1306             || input.getServiceInformation().getServiceInstanceId().length() == 0;
1307     }
1308
1309     private Future<RpcResult<NetworkTopologyOperationOutput>> buildRpcResultFuture(
1310         NetworkTopologyOperationOutputBuilder responseBuilder, String responseMessage) {
1311
1312         responseBuilder.setResponseCode("404");
1313         responseBuilder
1314             .setResponseMessage(responseMessage);
1315         responseBuilder.setAckFinalIndicator("Y");
1316
1317         RpcResult<NetworkTopologyOperationOutput> rpcResult = RpcResultBuilder
1318             .<NetworkTopologyOperationOutput>status(true)
1319             .withResult(responseBuilder.build())
1320             .build();
1321
1322         return Futures.immediateFuture(rpcResult);
1323     }
1324
1325     private boolean isValidRequest(NetworkTopologyOperationInput input) {
1326         return input.getSdncRequestHeader() != null && input.getSdncRequestHeader().getSvcAction() != null;
1327     }
1328
1329     @Override
1330     public Future<RpcResult<ContrailRouteTopologyOperationOutput>> contrailRouteTopologyOperation(
1331         ContrailRouteTopologyOperationInput input) {
1332
1333         final String svcOperation = "contrail-route-topology-operation";
1334         ServiceData serviceData;
1335         ServiceStatusBuilder serviceStatusBuilder = new ServiceStatusBuilder();
1336         Properties properties = new Properties();
1337
1338         log.info(CALLED_STR, svcOperation);
1339         // create a new response object
1340         ContrailRouteTopologyOperationOutputBuilder responseBuilder = new ContrailRouteTopologyOperationOutputBuilder();
1341
1342         if (hasInvalidServiceId(input)) {
1343             log.debug(NULL_OR_EMPTY_ERROR_MESSAGE, svcOperation);
1344             return buildRpcResultFuture(responseBuilder, NULL_OR_EMPTY_ERROR_PARAM);
1345         }
1346
1347         String siid = input.getServiceInformation().getServiceInstanceId();
1348
1349         // Get the service-instance service data from MD-SAL
1350         ServiceDataBuilder serviceDataBuilder = new ServiceDataBuilder();
1351         getServiceData(siid, serviceDataBuilder);
1352
1353         trySetSvcRequestId(input, responseBuilder);
1354
1355         ServiceData sd = serviceDataBuilder.build();
1356         if (isInvalidServiceData(sd)) {
1357             log.debug(EMPTY_SERVICE_INSTANCE_MESSAGE, svcOperation);
1358             return buildRpcResultFuture(responseBuilder, INVALID_INPUT_ERROR_MESSAGE);
1359         }
1360
1361         log.info("Adding INPUT data for " + svcOperation + " [" + siid + "] input: " + input);
1362         ContrailRouteTopologyOperationInputBuilder inputBuilder = new ContrailRouteTopologyOperationInputBuilder(input);
1363         GenericResourceApiUtil.toProperties(properties, inputBuilder.build());
1364
1365         // Call SLI sync method
1366         // Get SvcLogicService reference
1367         ResponseObject error = new ResponseObject("200", "");
1368         String ackFinal = "Y";
1369         String allottedResourceId = ERROR_NETWORK_ID;
1370         String serviceObjectPath = null;
1371         String contrailRouteObjectPath = null;
1372         Properties respProps = tryGetProperties(svcOperation, properties, serviceDataBuilder, error);
1373
1374         if (respProps != null) {
1375             error.setStatusCode(respProps.getProperty(ERROR_CODE_PARAM));
1376             error.setMessage(respProps.getProperty(ERROR_MESSAGE_PARAM));
1377             ackFinal = respProps.getProperty(ACK_FINAL_PARAM, "Y");
1378             allottedResourceId = respProps.getProperty(ALLOTTED_RESOURCE_ID_PARAM);
1379             serviceObjectPath = respProps.getProperty(SERVICE_OBJECT_PATH_PARAM);
1380             contrailRouteObjectPath = respProps.getProperty("contrail-route-object-path");
1381         }
1382
1383         if (failed(error)) {
1384             responseBuilder.setResponseCode(error.getStatusCode());
1385             responseBuilder.setResponseMessage(error.getMessage());
1386             responseBuilder.setAckFinalIndicator(ackFinal);
1387             log.error(RETURNED_FAILED_MESSAGE, svcOperation, siid, responseBuilder.build());
1388
1389             RpcResult<ContrailRouteTopologyOperationOutput> rpcResult = RpcResultBuilder
1390                 .<ContrailRouteTopologyOperationOutput>status(true)
1391                 .withResult(responseBuilder.build())
1392                 .build();
1393
1394             return Futures.immediateFuture(rpcResult);
1395         }
1396
1397         // Got success from SLI
1398         try {
1399             serviceData = serviceDataBuilder.build();
1400             log.info(UPDATING_MDSAL_INFO_MESSAGE, svcOperation, siid, serviceData);
1401
1402             // service object
1403             ServiceBuilder serviceBuilder = new ServiceBuilder();
1404             serviceBuilder.setServiceData(serviceData);
1405             serviceBuilder.setServiceInstanceId(siid);
1406             serviceBuilder.setServiceStatus(serviceStatusBuilder.build());
1407             saveService(serviceBuilder.build(), false, LogicalDatastoreType.CONFIGURATION);
1408
1409             trySaveService(input, serviceBuilder);
1410
1411             ContrailRouteResponseInformationBuilder contrailRouteResponseInformationBuilder = new ContrailRouteResponseInformationBuilder();
1412             contrailRouteResponseInformationBuilder.setInstanceId(allottedResourceId);
1413             contrailRouteResponseInformationBuilder.setObjectPath(contrailRouteObjectPath);
1414             responseBuilder.setContrailRouteResponseInformation(contrailRouteResponseInformationBuilder.build());
1415
1416             ServiceResponseInformationBuilder serviceResponseInformationBuilder = new ServiceResponseInformationBuilder();
1417             serviceResponseInformationBuilder.setInstanceId(siid);
1418             serviceResponseInformationBuilder.setObjectPath(serviceObjectPath);
1419             responseBuilder.setServiceResponseInformation(serviceResponseInformationBuilder.build());
1420
1421         } catch (IllegalStateException e) {
1422             log.error(UPDATING_MDSAL_ERROR_MESSAGE, svcOperation, siid, e);
1423             responseBuilder.setResponseCode("500");
1424             responseBuilder.setResponseMessage(e.getMessage());
1425             responseBuilder.setAckFinalIndicator("Y");
1426             log.error(RETURNED_FAILED_MESSAGE, svcOperation, siid, responseBuilder.build());
1427
1428             RpcResult<ContrailRouteTopologyOperationOutput> rpcResult = RpcResultBuilder
1429                 .<ContrailRouteTopologyOperationOutput>status(true)
1430                 .withResult(responseBuilder.build())
1431                 .build();
1432
1433             return Futures.immediateFuture(rpcResult);
1434         }
1435
1436         // Update succeeded
1437         responseBuilder.setResponseCode(error.getStatusCode());
1438         responseBuilder.setAckFinalIndicator(ackFinal);
1439         trySetResponseMessage(responseBuilder, error);
1440         log.info(UPDATED_MDSAL_INFO_MESSAGE, svcOperation, siid);
1441         log.info(RETURNED_SUCCESS_MESSAGE, svcOperation, siid, responseBuilder.build());
1442
1443         RpcResult<ContrailRouteTopologyOperationOutput> rpcResult = RpcResultBuilder
1444             .<ContrailRouteTopologyOperationOutput>status(true)
1445             .withResult(responseBuilder.build())
1446             .build();
1447
1448         return Futures.immediateFuture(rpcResult);
1449     }
1450
1451     private void trySetResponseMessage(ContrailRouteTopologyOperationOutputBuilder responseBuilder,
1452         ResponseObject error) {
1453         if (!error.getMessage().isEmpty()) {
1454             responseBuilder.setResponseMessage(error.getMessage());
1455         }
1456     }
1457
1458     private void trySaveService(ContrailRouteTopologyOperationInput input, ServiceBuilder serviceBuilder) {
1459         if (isValidRequest(input) &&
1460             (input.getSdncRequestHeader().getSvcAction().equals(SvcAction.Unassign) ||
1461                 input.getSdncRequestHeader().getSvcAction().equals(SvcAction.Activate))) {
1462             // Only update operational tree on activate or delete
1463             log.info(UPDATING_TREE_INFO_MESSAGE);
1464             saveService(serviceBuilder.build(), false, LogicalDatastoreType.OPERATIONAL);
1465         }
1466     }
1467
1468     private void trySetSvcRequestId(ContrailRouteTopologyOperationInput input,
1469         ContrailRouteTopologyOperationOutputBuilder responseBuilder) {
1470         if (input.getSdncRequestHeader() != null) {
1471             responseBuilder.setSvcRequestId(input.getSdncRequestHeader().getSvcRequestId());
1472         }
1473     }
1474
1475     private boolean hasInvalidServiceId(ContrailRouteTopologyOperationInput input) {
1476         return input == null || input.getServiceInformation() == null
1477             || input.getServiceInformation().getServiceInstanceId() == null
1478             || input.getServiceInformation().getServiceInstanceId().length() == 0;
1479     }
1480
1481     private Future<RpcResult<ContrailRouteTopologyOperationOutput>>
1482     buildRpcResultFuture(ContrailRouteTopologyOperationOutputBuilder responseBuilder, String responseMessage) {
1483
1484         responseBuilder.setResponseCode("404");
1485         responseBuilder.setResponseMessage(responseMessage);
1486         responseBuilder.setAckFinalIndicator("Y");
1487
1488         RpcResult<ContrailRouteTopologyOperationOutput> rpcResult = RpcResultBuilder
1489             .<ContrailRouteTopologyOperationOutput>status(true)
1490             .withResult(responseBuilder.build())
1491             .build();
1492
1493         return Futures.immediateFuture(rpcResult);
1494     }
1495
1496     private boolean isValidRequest(ContrailRouteTopologyOperationInput input) {
1497         return input.getSdncRequestHeader() != null && input.getSdncRequestHeader().getSvcAction() != null;
1498     }
1499
1500     @Override
1501     public Future<RpcResult<SecurityZoneTopologyOperationOutput>> securityZoneTopologyOperation(
1502         SecurityZoneTopologyOperationInput input) {
1503
1504         final String svcOperation = "security-zone-topology-operation";
1505         ServiceData serviceData;
1506         ServiceStatusBuilder serviceStatusBuilder = new ServiceStatusBuilder();
1507         Properties parms = new Properties();
1508
1509         log.info(CALLED_STR, svcOperation);
1510         // create a new response object
1511         SecurityZoneTopologyOperationOutputBuilder responseBuilder = new SecurityZoneTopologyOperationOutputBuilder();
1512
1513         if (this.hasInvalidServiceId(input)) {
1514             log.debug(NULL_OR_EMPTY_ERROR_MESSAGE, svcOperation);
1515             return buildRpcResultFuture(responseBuilder, NULL_OR_EMPTY_ERROR_PARAM);
1516         }
1517
1518         String siid = input.getServiceInformation().getServiceInstanceId();
1519
1520         // Get the service-instance service data from MD-SAL
1521         ServiceDataBuilder serviceDataBuilder = new ServiceDataBuilder();
1522         getServiceData(siid, serviceDataBuilder);
1523         trySetSvcRequestId(input, responseBuilder);
1524
1525         ServiceData sd = serviceDataBuilder.build();
1526         if (isInvalidServiceData(sd)) {
1527             log.debug(EMPTY_SERVICE_INSTANCE_MESSAGE, svcOperation);
1528             return buildRpcResultFuture(responseBuilder, INVALID_INPUT_ERROR_MESSAGE);
1529         }
1530
1531         log.info(ADDING_INPUT_DATA_LOG, svcOperation, siid, input);
1532         SecurityZoneTopologyOperationInputBuilder inputBuilder = new SecurityZoneTopologyOperationInputBuilder(input);
1533         GenericResourceApiUtil.toProperties(parms, inputBuilder.build());
1534
1535         // Call SLI sync method
1536         // Get SvcLogicService reference
1537
1538         Properties respProps = null;
1539
1540         ResponseObject responseObject = new ResponseObject("200", "");
1541         String ackFinal = "Y";
1542         String allottedResourceId = ERROR_NETWORK_ID;
1543         String serviceObjectPath = null;
1544         String securityZoneObjectPath = null;
1545
1546         try {
1547             if (svcLogicClient.hasGraph(APP_NAME, svcOperation, null, "sync")) {
1548
1549                 try {
1550                     respProps = svcLogicClient.execute(APP_NAME, svcOperation, null, "sync", serviceDataBuilder, parms);
1551                 } catch (Exception e) {
1552                     log.error(SERVICE_LOGIC_EXECUTION_ERROR_MESSAGE, svcOperation, e);
1553                     responseObject.setMessage(e.getMessage());
1554                     responseObject.setStatusCode("500");
1555                 }
1556             } else {
1557                 responseObject.setMessage(NO_SERVICE_LOGIC_ACTIVE + APP_NAME + ": '" + svcOperation + "'");
1558                 responseObject.setStatusCode("503");
1559             }
1560         } catch (Exception e) {
1561             responseObject.setStatusCode("500");
1562             responseObject.setMessage(e.getMessage());
1563             log.error(SERVICE_LOGIC_SEARCH_ERROR_MESSAGE, e);
1564         }
1565
1566         if (respProps != null) {
1567             responseObject.setStatusCode(respProps.getProperty(ERROR_CODE_PARAM));
1568             responseObject.setMessage(respProps.getProperty(ERROR_MESSAGE_PARAM));
1569             ackFinal = respProps.getProperty(ACK_FINAL_PARAM, "Y");
1570             allottedResourceId = respProps.getProperty(ALLOTTED_RESOURCE_ID_PARAM);
1571             serviceObjectPath = respProps.getProperty(SERVICE_OBJECT_PATH_PARAM);
1572             securityZoneObjectPath = respProps.getProperty("security-zone-object-path");
1573         }
1574
1575         if (failed(responseObject)) {
1576             responseBuilder.setResponseCode(responseObject.getStatusCode());
1577             responseBuilder.setResponseMessage(responseObject.getMessage());
1578             responseBuilder.setAckFinalIndicator(ackFinal);
1579             log.error(RETURNED_FAILED_MESSAGE, svcOperation, siid, responseBuilder.build());
1580
1581             RpcResult<SecurityZoneTopologyOperationOutput> rpcResult = RpcResultBuilder
1582                 .<SecurityZoneTopologyOperationOutput>status(true)
1583                 .withResult(responseBuilder.build())
1584                 .build();
1585
1586             return Futures.immediateFuture(rpcResult);
1587         }
1588
1589         // Got success from SLI
1590         try {
1591
1592             serviceData = serviceDataBuilder.build();
1593             log.info(UPDATING_MDSAL_INFO_MESSAGE, svcOperation, siid, serviceData);
1594
1595             // service object
1596             ServiceBuilder serviceBuilder = new ServiceBuilder();
1597             serviceBuilder.setServiceData(serviceData);
1598             serviceBuilder.setServiceInstanceId(siid);
1599             serviceBuilder.setServiceStatus(serviceStatusBuilder.build());
1600             saveService(serviceBuilder.build(), false, LogicalDatastoreType.CONFIGURATION);
1601
1602             trySaveService(input, serviceBuilder);
1603
1604             SecurityZoneResponseInformationBuilder securityZoneResponseInformationBuilder = new SecurityZoneResponseInformationBuilder();
1605             securityZoneResponseInformationBuilder.setInstanceId(allottedResourceId);
1606             securityZoneResponseInformationBuilder.setObjectPath(securityZoneObjectPath);
1607             responseBuilder.setSecurityZoneResponseInformation(securityZoneResponseInformationBuilder.build());
1608
1609             ServiceResponseInformationBuilder serviceResponseInformationBuilder = new ServiceResponseInformationBuilder();
1610             serviceResponseInformationBuilder.setInstanceId(siid);
1611             serviceResponseInformationBuilder.setObjectPath(serviceObjectPath);
1612             responseBuilder.setServiceResponseInformation(serviceResponseInformationBuilder.build());
1613
1614         } catch (IllegalStateException e) {
1615             log.error(UPDATING_MDSAL_ERROR_MESSAGE, svcOperation, siid, e);
1616             responseBuilder.setResponseCode("500");
1617             responseBuilder.setResponseMessage(e.getMessage());
1618             responseBuilder.setAckFinalIndicator("Y");
1619             log.error(RETURNED_FAILED_MESSAGE, svcOperation, siid, responseBuilder.build());
1620
1621             RpcResult<SecurityZoneTopologyOperationOutput> rpcResult = RpcResultBuilder
1622                 .<SecurityZoneTopologyOperationOutput>status(true)
1623                 .withResult(responseBuilder.build())
1624                 .build();
1625
1626             return Futures.immediateFuture(rpcResult);
1627         }
1628
1629         // Update succeeded
1630         responseBuilder.setResponseCode(responseObject.getStatusCode());
1631         responseBuilder.setAckFinalIndicator(ackFinal);
1632         trySetResponseMessage(responseBuilder, responseObject);
1633         log.info(UPDATED_MDSAL_INFO_MESSAGE, svcOperation, siid);
1634         log.info(RETURNED_SUCCESS_MESSAGE, svcOperation, siid, responseBuilder.build());
1635
1636         RpcResult<SecurityZoneTopologyOperationOutput> rpcResult = RpcResultBuilder
1637             .<SecurityZoneTopologyOperationOutput>status(true)
1638             .withResult(responseBuilder.build())
1639             .build();
1640
1641         return Futures.immediateFuture(rpcResult);
1642     }
1643
1644     private void trySetResponseMessage(SecurityZoneTopologyOperationOutputBuilder responseBuilder,
1645         ResponseObject error) {
1646         if (!error.getMessage().isEmpty()) {
1647             responseBuilder.setResponseMessage(error.getMessage());
1648         }
1649     }
1650
1651     private void trySaveService(SecurityZoneTopologyOperationInput input, ServiceBuilder serviceBuilder) {
1652         if (isValidRequest(input) &&
1653             (input.getSdncRequestHeader().getSvcAction().equals(SvcAction.Unassign) ||
1654                 input.getSdncRequestHeader().getSvcAction().equals(SvcAction.Activate))) {
1655             // Only update operational tree on activate or delete
1656             log.info(UPDATING_TREE_INFO_MESSAGE);
1657             saveService(serviceBuilder.build(), false, LogicalDatastoreType.OPERATIONAL);
1658         }
1659     }
1660
1661     private void trySetSvcRequestId(SecurityZoneTopologyOperationInput input,
1662         SecurityZoneTopologyOperationOutputBuilder responseBuilder) {
1663         if (input.getSdncRequestHeader() != null) {
1664             responseBuilder.setSvcRequestId(input.getSdncRequestHeader().getSvcRequestId());
1665         }
1666     }
1667
1668     private boolean isInvalidServiceData(ServiceData sd) {
1669         return sd == null || sd.getServiceLevelOperStatus() == null;
1670     }
1671
1672     private boolean hasInvalidServiceId(SecurityZoneTopologyOperationInput input) {
1673         return input == null || input.getServiceInformation() == null
1674             || input.getServiceInformation().getServiceInstanceId() == null
1675             || input.getServiceInformation().getServiceInstanceId().length() == 0;
1676     }
1677
1678     private Future<RpcResult<SecurityZoneTopologyOperationOutput>>
1679     buildRpcResultFuture(SecurityZoneTopologyOperationOutputBuilder responseBuilder, String responseMessage) {
1680
1681         responseBuilder.setResponseCode("404");
1682         responseBuilder.setResponseMessage(responseMessage);
1683         responseBuilder.setAckFinalIndicator("Y");
1684
1685         RpcResult<SecurityZoneTopologyOperationOutput> rpcResult = RpcResultBuilder
1686             .<SecurityZoneTopologyOperationOutput>status(true)
1687             .withResult(responseBuilder.build())
1688             .build();
1689
1690         return Futures.immediateFuture(rpcResult);
1691     }
1692
1693     private boolean isValidRequest(SecurityZoneTopologyOperationInput input) {
1694         return input.getSdncRequestHeader() != null && input.getSdncRequestHeader().getSvcAction() != null;
1695     }
1696
1697     @Override
1698     public Future<RpcResult<TunnelxconnTopologyOperationOutput>> tunnelxconnTopologyOperation(
1699         TunnelxconnTopologyOperationInput input) {
1700
1701         final String svcOperation = "tunnelxconn-topology-operation";
1702         Properties parms = new Properties();
1703         log.info(CALLED_STR, svcOperation);
1704
1705         // create a new response object
1706         TunnelxconnTopologyOperationOutputBuilder responseBuilder = new TunnelxconnTopologyOperationOutputBuilder();
1707         if (hasInvalidServiceId(input)) {
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
1713             RpcResult<TunnelxconnTopologyOperationOutput> rpcResult = RpcResultBuilder
1714                 .<TunnelxconnTopologyOperationOutput>status(true)
1715                 .withResult(responseBuilder.build())
1716                 .build();
1717
1718             return Futures.immediateFuture(rpcResult);
1719         }
1720         String siid = input.getServiceInformation().getServiceInstanceId();
1721         log.info(ADDING_INPUT_DATA_LOG, svcOperation, siid, input);
1722         TunnelxconnTopologyOperationInputBuilder inputBuilder = new TunnelxconnTopologyOperationInputBuilder(input);
1723         GenericResourceApiUtil.toProperties(parms, inputBuilder.build());
1724
1725         // Call SLI sync method
1726         // Get SvcLogicService reference
1727         ResponseObject responseObject = new ResponseObject("200", "");
1728         String ackFinal = "Y";
1729         String allottedResourceId = ERROR_NETWORK_ID;
1730         String serviceObjectPath = null;
1731         String tunnelxconnObjectPath = null;
1732         Properties respProps = tryGetProperties(svcOperation, parms, responseObject);
1733
1734         if (respProps != null) {
1735             responseObject.setStatusCode(respProps.getProperty(ERROR_CODE_PARAM));
1736             responseObject.setMessage(respProps.getProperty(ERROR_MESSAGE_PARAM));
1737             ackFinal = respProps.getProperty(ACK_FINAL_PARAM, "Y");
1738             allottedResourceId = respProps.getProperty(ALLOTTED_RESOURCE_ID_PARAM);
1739             serviceObjectPath = respProps.getProperty(SERVICE_OBJECT_PATH_PARAM);
1740             tunnelxconnObjectPath = respProps.getProperty("tunnelxconn-object-path");
1741         }
1742
1743         if (failed(responseObject)) {
1744             responseBuilder.setResponseCode(responseObject.getStatusCode());
1745             responseBuilder.setResponseMessage(responseObject.getMessage());
1746             responseBuilder.setAckFinalIndicator(ackFinal);
1747
1748             log.error(RETURNED_FAILED_MESSAGE, svcOperation, siid, responseBuilder.build());
1749
1750             RpcResult<TunnelxconnTopologyOperationOutput> rpcResult = RpcResultBuilder
1751                 .<TunnelxconnTopologyOperationOutput>status(true)
1752                 .withResult(responseBuilder.build())
1753                 .build();
1754
1755             return Futures.immediateFuture(rpcResult);
1756         }
1757
1758         // Got success from SLI
1759         try {
1760             TunnelxconnResponseInformationBuilder tunnelxconnResponseInformationBuilder = new TunnelxconnResponseInformationBuilder();
1761             tunnelxconnResponseInformationBuilder.setInstanceId(allottedResourceId);
1762             tunnelxconnResponseInformationBuilder.setObjectPath(tunnelxconnObjectPath);
1763             responseBuilder.setTunnelxconnResponseInformation(tunnelxconnResponseInformationBuilder.build());
1764
1765             ServiceResponseInformationBuilder serviceResponseInformationBuilder = new ServiceResponseInformationBuilder();
1766             serviceResponseInformationBuilder.setInstanceId(siid);
1767             serviceResponseInformationBuilder.setObjectPath(serviceObjectPath);
1768             responseBuilder.setServiceResponseInformation(serviceResponseInformationBuilder.build());
1769
1770         } catch (IllegalStateException e) {
1771             log.error(UPDATING_MDSAL_ERROR_MESSAGE, svcOperation, siid, e);
1772             responseBuilder.setResponseCode("500");
1773             responseBuilder.setResponseMessage(e.toString());
1774             responseBuilder.setAckFinalIndicator("Y");
1775             log.error(RETURNED_FAILED_MESSAGE, svcOperation, siid, responseBuilder.build());
1776
1777             RpcResult<TunnelxconnTopologyOperationOutput> rpcResult = RpcResultBuilder
1778                 .<TunnelxconnTopologyOperationOutput>status(true)
1779                 .withResult(responseBuilder.build())
1780                 .build();
1781
1782             return Futures.immediateFuture(rpcResult);
1783         }
1784
1785         // Update succeeded
1786         responseBuilder.setResponseCode(responseObject.getStatusCode());
1787         responseBuilder.setAckFinalIndicator(ackFinal);
1788         trySetResponseMessage(responseBuilder, responseObject);
1789         log.info(UPDATED_MDSAL_INFO_MESSAGE, svcOperation, siid);
1790         log.info(RETURNED_SUCCESS_MESSAGE, svcOperation, siid, responseBuilder.build());
1791
1792         RpcResult<TunnelxconnTopologyOperationOutput> rpcResult = RpcResultBuilder
1793             .<TunnelxconnTopologyOperationOutput>status(true)
1794             .withResult(responseBuilder.build())
1795             .build();
1796
1797         return Futures.immediateFuture(rpcResult);
1798     }
1799
1800     @Override
1801     public Future<RpcResult<ConnectionAttachmentTopologyOperationOutput>> connectionAttachmentTopologyOperation(
1802         ConnectionAttachmentTopologyOperationInput input) {
1803         //TODO after YANG review
1804         return null;
1805     }
1806
1807     private void trySetResponseMessage(TunnelxconnTopologyOperationOutputBuilder responseBuilder,
1808         ResponseObject error) {
1809         if (!error.getMessage().isEmpty()) {
1810             responseBuilder.setResponseMessage(error.getMessage());
1811         }
1812     }
1813
1814     private boolean hasInvalidServiceId(TunnelxconnTopologyOperationInput input) {
1815         return input == null || input.getServiceInformation() == null
1816             || input.getServiceInformation().getServiceInstanceId() == null
1817             || input.getServiceInformation().getServiceInstanceId().length() == 0;
1818     }
1819
1820     private Properties tryGetProperties(String svcOperation, Properties parms, ResponseObject responseObject) {
1821         try {
1822             if (svcLogicClient.hasGraph(APP_NAME, svcOperation, null, "sync")) {
1823
1824                 try {
1825                     return svcLogicClient.execute(APP_NAME, svcOperation, null, "sync", parms);
1826                 } catch (Exception e) {
1827                     log.error(SERVICE_LOGIC_EXECUTION_ERROR_MESSAGE, svcOperation, e);
1828                     responseObject.setMessage(e.getMessage());
1829                     responseObject.setStatusCode("500");
1830                 }
1831             } else {
1832                 responseObject.setMessage(NO_SERVICE_LOGIC_ACTIVE + APP_NAME + ": '" + svcOperation + "'");
1833                 responseObject.setStatusCode("503");
1834             }
1835         } catch (Exception e) {
1836             responseObject.setMessage(e.getMessage());
1837             responseObject.setStatusCode("500");
1838             log.error(SERVICE_LOGIC_SEARCH_ERROR_MESSAGE, e);
1839         }
1840         return null;
1841     }
1842
1843     @Override
1844     public Future<RpcResult<BrgTopologyOperationOutput>> brgTopologyOperation(BrgTopologyOperationInput input) {
1845         final String svcOperation = "brg-topology-operation";
1846         Properties parms = new Properties();
1847
1848         log.info(CALLED_STR, svcOperation);
1849         // create a new response object
1850         BrgTopologyOperationOutputBuilder responseBuilder = new BrgTopologyOperationOutputBuilder();
1851
1852         if (this.hasInvalidServiceId(input)) {
1853
1854             log.debug(NULL_OR_EMPTY_ERROR_MESSAGE, svcOperation);
1855             responseBuilder.setResponseCode("404");
1856             responseBuilder.setResponseMessage(NULL_OR_EMPTY_ERROR_PARAM);
1857             responseBuilder.setAckFinalIndicator("Y");
1858
1859             RpcResult<BrgTopologyOperationOutput> rpcResult = RpcResultBuilder
1860                 .<BrgTopologyOperationOutput>status(true)
1861                 .withResult(responseBuilder.build())
1862                 .build();
1863
1864             return Futures.immediateFuture(rpcResult);
1865         }
1866
1867         String siid = input.getServiceInformation().getServiceInstanceId();
1868
1869         log.info(ADDING_INPUT_DATA_LOG, svcOperation, siid, input);
1870         BrgTopologyOperationInputBuilder inputBuilder = new BrgTopologyOperationInputBuilder(input);
1871         GenericResourceApiUtil.toProperties(parms, inputBuilder.build());
1872
1873         // Call SLI sync method
1874         // Get SvcLogicService reference
1875         ResponseObject error = new ResponseObject("200", "");
1876         String ackFinal = "Y";
1877         String allottedResourceId = ERROR_NETWORK_ID;
1878         String serviceObjectPath = null;
1879         String brgObjectPath = null;
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             allottedResourceId = respProps.getProperty(ALLOTTED_RESOURCE_ID_PARAM);
1887             serviceObjectPath = respProps.getProperty(SERVICE_OBJECT_PATH_PARAM);
1888             brgObjectPath = respProps.getProperty("brg-object-path");
1889         }
1890
1891         if (failed(error)) {
1892             responseBuilder.setResponseCode(error.getStatusCode());
1893             responseBuilder.setResponseMessage(error.getMessage());
1894             responseBuilder.setAckFinalIndicator(ackFinal);
1895
1896             log.error(RETURNED_FAILED_MESSAGE, svcOperation, siid, responseBuilder.build());
1897             RpcResult<BrgTopologyOperationOutput> rpcResult = RpcResultBuilder
1898                 .<BrgTopologyOperationOutput>status(true)
1899                 .withResult(responseBuilder.build())
1900                 .build();
1901
1902             return Futures.immediateFuture(rpcResult);
1903         }
1904
1905         // Got success from SLI
1906         try {
1907
1908             BrgResponseInformationBuilder brgResponseInformationBuilder = new BrgResponseInformationBuilder();
1909             brgResponseInformationBuilder.setInstanceId(allottedResourceId);
1910             brgResponseInformationBuilder.setObjectPath(brgObjectPath);
1911             responseBuilder.setBrgResponseInformation(brgResponseInformationBuilder.build());
1912
1913             ServiceResponseInformationBuilder serviceResponseInformationBuilder = new ServiceResponseInformationBuilder();
1914             serviceResponseInformationBuilder.setInstanceId(siid);
1915             serviceResponseInformationBuilder.setObjectPath(serviceObjectPath);
1916             responseBuilder.setServiceResponseInformation(serviceResponseInformationBuilder.build());
1917
1918         } catch (IllegalStateException e) {
1919             log.error(UPDATING_MDSAL_ERROR_MESSAGE, svcOperation, siid, e);
1920             responseBuilder.setResponseCode("500");
1921             responseBuilder.setResponseMessage(e.toString());
1922             responseBuilder.setAckFinalIndicator("Y");
1923             log.error(RETURNED_FAILED_MESSAGE, svcOperation, siid, responseBuilder.build());
1924
1925             RpcResult<BrgTopologyOperationOutput> rpcResult = RpcResultBuilder
1926                 .<BrgTopologyOperationOutput>status(true)
1927                 .withResult(responseBuilder.build())
1928                 .build();
1929
1930             return Futures.immediateFuture(rpcResult);
1931         }
1932
1933         // Update succeeded
1934         responseBuilder.setResponseCode(error.getStatusCode());
1935         responseBuilder.setAckFinalIndicator(ackFinal);
1936         trySetResponseMessage(responseBuilder, error);
1937         log.info(UPDATED_MDSAL_INFO_MESSAGE, svcOperation, siid);
1938         log.info(RETURNED_SUCCESS_MESSAGE, svcOperation, siid, responseBuilder.build());
1939
1940         RpcResult<BrgTopologyOperationOutput> rpcResult = RpcResultBuilder
1941             .<BrgTopologyOperationOutput>status(true)
1942             .withResult(responseBuilder.build())
1943             .build();
1944
1945         return Futures.immediateFuture(rpcResult);
1946     }
1947
1948     private void trySetResponseMessage(BrgTopologyOperationOutputBuilder responseBuilder, ResponseObject error) {
1949         if (!error.getMessage().isEmpty()) {
1950             responseBuilder.setResponseMessage(error.getMessage());
1951         }
1952     }
1953
1954     private boolean hasInvalidServiceId(BrgTopologyOperationInput input) {
1955         return input == null || input.getServiceInformation() == null
1956             || input.getServiceInformation().getServiceInstanceId() == null
1957             || input.getServiceInformation().getServiceInstanceId().length() == 0;
1958     }
1959
1960     @Override
1961     public Future<RpcResult<PreloadVnfTopologyOperationOutput>> preloadVnfTopologyOperation(
1962         PreloadVnfTopologyOperationInput input) {
1963
1964         final String svcOperation = "preload-vnf-topology-operation";
1965         Properties parms = new Properties();
1966
1967         log.info(CALLED_STR, svcOperation);
1968         // create a new response object
1969         PreloadVnfTopologyOperationOutputBuilder responseBuilder = new PreloadVnfTopologyOperationOutputBuilder();
1970
1971         if (hasInvalidVnfTopology(input)) {
1972
1973             log.debug("exiting {} because of null input", svcOperation);
1974             responseBuilder.setResponseCode("403");
1975             responseBuilder.setResponseMessage("invalid input: input is null");
1976             responseBuilder.setAckFinalIndicator("Y");
1977
1978             RpcResult<PreloadVnfTopologyOperationOutput> rpcResult = RpcResultBuilder
1979                 .<PreloadVnfTopologyOperationOutput>status(true)
1980                 .withResult(responseBuilder.build())
1981                 .build();
1982
1983             return Futures.immediateFuture(rpcResult);
1984         }
1985
1986         // Grab the name and type from the input buffer
1987         String preloadName = input.getVnfTopologyInformation().getVnfTopologyIdentifier().getVnfName();
1988         String preloadType = input.getVnfTopologyInformation().getVnfTopologyIdentifier().getVnfType();
1989
1990         // Make sure we have a preload_name and preload_type
1991         if (invalidPreloadData(preloadName, preloadType)) {
1992             log.debug("exiting {} vnf-name or vnf-type is null or empty", svcOperation);
1993             responseBuilder.setResponseCode("403");
1994             responseBuilder.setResponseMessage("invalid input: vnf-name or vnf-type is null or empty");
1995             responseBuilder.setAckFinalIndicator("Y");
1996
1997             RpcResult<PreloadVnfTopologyOperationOutput> rpcResult = RpcResultBuilder
1998                 .<PreloadVnfTopologyOperationOutput>status(true)
1999                 .withResult(responseBuilder.build())
2000                 .build();
2001
2002             return Futures.immediateFuture(rpcResult);
2003         }
2004
2005         trySetSvcRequestId(input, responseBuilder);
2006
2007         PreloadDataBuilder preloadDataBuilder = new PreloadDataBuilder();
2008         getPreloadData(preloadName, preloadType, preloadDataBuilder);
2009
2010         PreloadDataBuilder operDataBuilder = new PreloadDataBuilder();
2011         getPreloadData(preloadName, preloadType, operDataBuilder, LogicalDatastoreType.OPERATIONAL);
2012
2013         // setup a preload-data object builder
2014         // ACTION preload-vnf-topology-operation
2015         // INPUT:
2016         // USES sdnc-request-header;
2017         // USES request-information;
2018         // uses vnf-topology-information;
2019         // OUTPUT:
2020         // USES vnf-topology-response-body;
2021         //
2022         // container preload-data
2023         // uses vnf-topology-information;
2024         // uses network-topology-information;
2025         // uses oper-status;
2026
2027         log.info("Adding INPUT data for {} [{},{}] input: {}", svcOperation, preloadName, preloadType, input);
2028         PreloadVnfTopologyOperationInputBuilder inputBuilder = new PreloadVnfTopologyOperationInputBuilder(input);
2029         GenericResourceApiUtil.toProperties(parms, inputBuilder.build());
2030         log.info("Adding OPERATIONAL data for {} [{},{}] operational-data: {}", svcOperation, preloadName,
2031             preloadType, operDataBuilder.build());
2032         GenericResourceApiUtil.toProperties(parms, OPERATIONAL_DATA_PARAM, operDataBuilder);
2033
2034         // Call SLI sync method
2035         // Get SvcLogicService reference
2036         ResponseObject responseObject = new ResponseObject("200", "");
2037         Properties respProps = tryGetProperties(svcOperation, parms, responseObject);
2038         String ackFinal = resolveAckFinal(responseObject, respProps);
2039
2040         if (failed(responseObject)) {
2041
2042             responseBuilder.setResponseCode(responseObject.getStatusCode());
2043             responseBuilder.setResponseMessage(responseObject.getMessage());
2044             responseBuilder.setAckFinalIndicator(ackFinal);
2045
2046             VnfPreloadListBuilder preloadVnfListBuilder = new VnfPreloadListBuilder();
2047             preloadVnfListBuilder.setVnfName(preloadName);
2048             preloadVnfListBuilder.setVnfType(preloadType);
2049             preloadVnfListBuilder.setPreloadData(preloadDataBuilder.build());
2050             log.error("Returned FAILED for {} [{},{}] error code: '{}', Reason: '{}'", svcOperation, preloadName,
2051                 preloadType, responseObject.getStatusCode(), responseObject.getMessage());
2052             try {
2053                 savePreloadList(preloadVnfListBuilder.build(), true, LogicalDatastoreType.CONFIGURATION);
2054             } catch (Exception e) {
2055                 log.error(UPDATING_MDSAL_ERROR_MESSAGE_2, svcOperation, preloadName,
2056                     preloadType, e);
2057             }
2058             log.debug("Sending Success rpc result due to external error");
2059
2060             RpcResult<PreloadVnfTopologyOperationOutput> rpcResult = RpcResultBuilder
2061                 .<PreloadVnfTopologyOperationOutput>status(true)
2062                 .withResult(responseBuilder.build())
2063                 .build();
2064
2065             return Futures.immediateFuture(rpcResult);
2066         }
2067
2068         // Got success from SLI
2069         try {
2070             updatePreloadData(svcOperation, preloadName, preloadType, preloadDataBuilder);
2071         } catch (Exception e) {
2072             log.error(UPDATING_MDSAL_ERROR_MESSAGE_2, svcOperation, preloadName, preloadType,
2073                 e);
2074             responseBuilder.setResponseCode("500");
2075             responseBuilder.setResponseMessage(e.getMessage());
2076             responseBuilder.setAckFinalIndicator("Y");
2077             log.error("Returned FAILED for {} [{},{}] {}", svcOperation, preloadName, preloadType,
2078                 responseBuilder.build());
2079
2080             RpcResult<PreloadVnfTopologyOperationOutput> rpcResult = RpcResultBuilder
2081                 .<PreloadVnfTopologyOperationOutput>status(false)
2082                 .withResult(responseBuilder.build())
2083                 .build();
2084
2085             return Futures.immediateFuture(rpcResult);
2086         }
2087
2088         // Update succeeded
2089         responseBuilder.setResponseCode(responseObject.getStatusCode());
2090         responseBuilder.setAckFinalIndicator(ackFinal);
2091         trySetResponseMessage(responseBuilder, responseObject);
2092
2093         log.info("Updated MD-SAL for {} [{},{}]", svcOperation, preloadName, preloadType);
2094         log.info("Returned SUCCESS for {} [{},{}] {}", svcOperation, preloadName, preloadType,
2095             responseBuilder.build());
2096
2097         RpcResult<PreloadVnfTopologyOperationOutput> rpcResult = RpcResultBuilder
2098             .<PreloadVnfTopologyOperationOutput>status(true)
2099             .withResult(responseBuilder.build())
2100             .build();
2101
2102         return Futures.immediateFuture(rpcResult);
2103     }
2104
2105     private String resolveAckFinal(ResponseObject responseObject, Properties respProps) {
2106         if (respProps != null) {
2107             responseObject.setStatusCode(respProps.getProperty(ERROR_CODE_PARAM));
2108             responseObject.setMessage(respProps.getProperty(ERROR_MESSAGE_PARAM));
2109             return respProps.getProperty(ACK_FINAL_PARAM, "Y");
2110         }
2111         return "Y";
2112     }
2113
2114     private void trySetResponseMessage(PreloadVnfTopologyOperationOutputBuilder responseBuilder, ResponseObject error) {
2115         if (!error.getMessage().isEmpty()) {
2116             responseBuilder.setResponseMessage(error.getMessage());
2117         }
2118     }
2119
2120     private void trySetSvcRequestId(PreloadVnfTopologyOperationInput input,
2121         PreloadVnfTopologyOperationOutputBuilder responseBuilder) {
2122         if (input.getSdncRequestHeader() != null) {
2123             responseBuilder.setSvcRequestId(input.getSdncRequestHeader().getSvcRequestId());
2124         }
2125     }
2126
2127     private boolean hasInvalidVnfTopology(PreloadVnfTopologyOperationInput input) {
2128         return input == null || input.getVnfTopologyInformation() == null
2129             || input.getVnfTopologyInformation().getVnfTopologyIdentifier() == null;
2130     }
2131
2132     private void updatePreloadData(String svcOperation, String preloadName, String preloadType,
2133         PreloadDataBuilder preloadDataBuilder) {
2134         PreloadData preloadData;
2135         preloadData = preloadDataBuilder.build();
2136         log.info("Updating MD-SAL for {} [{},{}] preloadData: {}", svcOperation, preloadName, preloadType,
2137             preloadData);
2138         // svc-configuration-list
2139         VnfPreloadListBuilder preloadVnfListBuilder = new VnfPreloadListBuilder();
2140         preloadVnfListBuilder.setVnfName(preloadName);
2141         preloadVnfListBuilder.setVnfType(preloadType);
2142         preloadVnfListBuilder.setPreloadData(preloadData);
2143
2144         // merge flag sets to false to allow it to be overwritten (not appended)
2145         savePreloadList(preloadVnfListBuilder.build(), false, LogicalDatastoreType.CONFIGURATION);
2146         log.info(UPDATING_TREE_INFO_MESSAGE);
2147         savePreloadList(preloadVnfListBuilder.build(), false, LogicalDatastoreType.OPERATIONAL);
2148     }
2149
2150     @Override
2151     public Future<RpcResult<PreloadNetworkTopologyOperationOutput>> preloadNetworkTopologyOperation(
2152         PreloadNetworkTopologyOperationInput input) {
2153
2154         final String svcOperation = "preload-network-topology-operation";
2155         Properties parms = new Properties();
2156
2157         log.info(CALLED_STR, svcOperation);
2158         // create a new response object
2159         PreloadNetworkTopologyOperationOutputBuilder responseBuilder = new PreloadNetworkTopologyOperationOutputBuilder();
2160
2161         if (hasInvalidNetworkTopology(input)) {
2162
2163             log.debug("exiting {} because of null input", svcOperation);
2164             responseBuilder.setResponseCode("403");
2165             responseBuilder.setResponseMessage("input is null");
2166             responseBuilder.setAckFinalIndicator("Y");
2167
2168             RpcResult<PreloadNetworkTopologyOperationOutput> rpcResult = RpcResultBuilder
2169                 .<PreloadNetworkTopologyOperationOutput>status(true)
2170                 .withResult(responseBuilder.build())
2171                 .build();
2172
2173             return Futures.immediateFuture(rpcResult);
2174         }
2175
2176         // Grab the name and type from the input buffer
2177         String preloadName = input.getNetworkTopologyInformation().getNetworkTopologyIdentifier().getNetworkName();
2178         String preloadType = input.getNetworkTopologyInformation().getNetworkTopologyIdentifier().getNetworkType();
2179
2180         // Make sure we have a preload_name and preload_type
2181         if (invalidPreloadData(preloadName, preloadType)) {
2182             log.debug("exiting {} because of invalid preload-name or preload-type", svcOperation);
2183             responseBuilder.setResponseCode("403");
2184             responseBuilder.setResponseMessage("invalid input: network-name or network-type is null or empty");
2185             responseBuilder.setAckFinalIndicator("Y");
2186
2187             RpcResult<PreloadNetworkTopologyOperationOutput> rpcResult = RpcResultBuilder
2188                 .<PreloadNetworkTopologyOperationOutput>status(true)
2189                 .withResult(responseBuilder.build())
2190                 .build();
2191
2192             return Futures.immediateFuture(rpcResult);
2193         }
2194
2195         trySetSvcRequestId(input, responseBuilder);
2196
2197         PreloadDataBuilder preloadDataBuilder = new PreloadDataBuilder();
2198         getPreloadData(preloadName, preloadType, preloadDataBuilder);
2199
2200         PreloadDataBuilder operDataBuilder = new PreloadDataBuilder();
2201         getPreloadData(preloadName, preloadType, operDataBuilder, LogicalDatastoreType.OPERATIONAL);
2202
2203         //
2204         // setup a preload-data object builder
2205         // ACTION preload-network-topology-operation
2206         // INPUT:
2207         // USES sdnc-request-header;
2208         // USES request-information;
2209         // uses network-topology-information;
2210         // OUTPUT:
2211         // USES vnf-topology-response-body;
2212         //
2213         // container preload-data
2214         // uses vnf-topology-information;
2215         // uses network-topology-information;
2216         // uses oper-status;
2217
2218         log.info("Adding INPUT data for {} [{},{}] input: {}", svcOperation, preloadName, preloadType, input);
2219         PreloadNetworkTopologyOperationInputBuilder inputBuilder = new PreloadNetworkTopologyOperationInputBuilder(
2220             input);
2221         GenericResourceApiUtil.toProperties(parms, inputBuilder.build());
2222         log.info("Adding OPERATIONAL data for {} [{},{}] operational-data: {}", svcOperation, preloadName,
2223             preloadType, operDataBuilder.build());
2224         GenericResourceApiUtil.toProperties(parms, OPERATIONAL_DATA_PARAM, operDataBuilder);
2225
2226         // Call SLI sync method
2227         // Get SvcLogicService reference
2228         ResponseObject responseObject = new ResponseObject("200", "");
2229         Properties respProps = tryGetProperties(svcOperation, parms, responseObject);
2230
2231         String ackFinal = resolveAckFinal(responseObject, respProps);
2232
2233         if (failed(responseObject)) {
2234
2235             responseBuilder.setResponseCode(responseObject.getStatusCode());
2236             responseBuilder.setResponseMessage(responseObject.getMessage());
2237             responseBuilder.setAckFinalIndicator(ackFinal);
2238
2239             VnfPreloadListBuilder preloadVnfListBuilder = new VnfPreloadListBuilder();
2240             preloadVnfListBuilder.setVnfName(preloadName);
2241             preloadVnfListBuilder.setVnfType(preloadType);
2242             preloadVnfListBuilder.setPreloadData(preloadDataBuilder.build());
2243             log.error("Returned FAILED for {} [{},{}] error code: '{}', Reason: '{}'", svcOperation, preloadName,
2244                 preloadType, responseObject.getStatusCode(), responseObject.getMessage());
2245             try {
2246                 savePreloadList(preloadVnfListBuilder.build(), true, LogicalDatastoreType.CONFIGURATION);
2247             } catch (Exception e) {
2248                 log.error(UPDATING_MDSAL_ERROR_MESSAGE_2, svcOperation, preloadName,
2249                     preloadType, e);
2250
2251             }
2252             log.debug("Sending Success rpc result due to external error");
2253
2254             RpcResult<PreloadNetworkTopologyOperationOutput> rpcResult = RpcResultBuilder
2255                 .<PreloadNetworkTopologyOperationOutput>status(true)
2256                 .withResult(responseBuilder.build())
2257                 .build();
2258
2259             return Futures.immediateFuture(rpcResult);
2260         }
2261
2262         // Got success from SLI
2263         try {
2264             updatePreloadData(svcOperation, preloadName, preloadType, preloadDataBuilder);
2265         } catch (Exception e) {
2266             log.error(UPDATING_MDSAL_ERROR_MESSAGE_2, svcOperation, preloadName, preloadType, e);
2267             responseBuilder.setResponseCode("500");
2268             responseBuilder.setResponseMessage(e.getMessage());
2269             responseBuilder.setAckFinalIndicator("Y");
2270             log.error("Returned FAILED for {} [{},{}] {}", svcOperation, preloadName, preloadType,
2271                 responseBuilder.build());
2272
2273             RpcResult<PreloadNetworkTopologyOperationOutput> rpcResult = RpcResultBuilder
2274                 .<PreloadNetworkTopologyOperationOutput>status(false)
2275                 .withResult(responseBuilder.build())
2276                 .build();
2277
2278             return Futures.immediateFuture(rpcResult);
2279         }
2280
2281         // Update succeeded
2282         responseBuilder.setResponseCode(responseObject.getStatusCode());
2283         responseBuilder.setAckFinalIndicator(ackFinal);
2284         trySetResponseMessage(responseBuilder, responseObject);
2285
2286         log.info("Updated MD-SAL for {} [{},{}]", svcOperation, preloadName, preloadType);
2287         log.info("Returned SUCCESS for {} [{},{}] {}", svcOperation, preloadName, preloadType,
2288             responseBuilder.build());
2289
2290         RpcResult<PreloadNetworkTopologyOperationOutput> rpcResult = RpcResultBuilder
2291             .<PreloadNetworkTopologyOperationOutput>status(true)
2292             .withResult(responseBuilder.build())
2293             .build();
2294
2295         return Futures.immediateFuture(rpcResult);
2296     }
2297
2298     private void trySetResponseMessage(PreloadNetworkTopologyOperationOutputBuilder responseBuilder,
2299         ResponseObject error) {
2300         if (!error.getMessage().isEmpty()) {
2301             responseBuilder.setResponseMessage(error.getMessage());
2302         }
2303     }
2304
2305     private void trySetSvcRequestId(PreloadNetworkTopologyOperationInput input,
2306         PreloadNetworkTopologyOperationOutputBuilder responseBuilder) {
2307         if (input.getSdncRequestHeader() != null) {
2308             responseBuilder.setSvcRequestId(input.getSdncRequestHeader().getSvcRequestId());
2309         }
2310     }
2311
2312     private boolean invalidPreloadData(String preloadName, String preloadType) {
2313         return preloadName == null || preloadName.length() == 0 || preloadType == null || preloadType.length() == 0;
2314     }
2315
2316     private boolean hasInvalidNetworkTopology(PreloadNetworkTopologyOperationInput input) {
2317         return input == null || input.getNetworkTopologyInformation() == null
2318             || input.getNetworkTopologyInformation().getNetworkTopologyIdentifier() == null;
2319     }
2320
2321 }