Bug 6743: added futures to InterfaceManager and VppNodeManager
[groupbasedpolicy.git] / renderers / vpp / src / main / java / org / opendaylight / groupbasedpolicy / renderer / vpp / iface / VppEndpointLocationProvider.java
index 910bcd0496d6d06449544d5a2cc6281a4cac66c9..93f770e8ac97eeefda6546e81fee9c354e88465d 100644 (file)
@@ -8,16 +8,24 @@
 
 package org.opendaylight.groupbasedpolicy.renderer.vpp.iface;
 
-import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
+import static com.google.common.base.Preconditions.checkNotNull;
 
+import javax.annotation.Nonnull;
+import com.google.common.base.Function;
+import com.google.common.util.concurrent.FutureCallback;
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
+import org.opendaylight.controller.md.sal.binding.api.BindingTransactionChain;
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.groupbasedpolicy.renderer.vpp.util.CloseOnFailTransactionChain;
 import org.opendaylight.groupbasedpolicy.renderer.vpp.util.KeyFactory;
+import org.opendaylight.groupbasedpolicy.renderer.vpp.util.VppIidFactory;
 import org.opendaylight.groupbasedpolicy.util.IidFactory;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.has.absolute.location.AbsoluteLocation;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.has.absolute.location.AbsoluteLocationBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.has.absolute.location.absolute.location.location.type.ExternalLocationCase;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.has.absolute.location.absolute.location.location.type.ExternalLocationCaseBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint_location_provider.rev160419.ProviderName;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint_location_provider.rev160419.location.providers.LocationProvider;
@@ -27,27 +35,26 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint_l
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint_location_provider.rev160419.location.providers.location.provider.ProviderAddressEndpointLocationKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.endpoints.AddressEndpointWithLocationKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.config.VppEndpoint;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.google.common.base.Preconditions;
-import com.google.common.util.concurrent.FutureCallback;
-import com.google.common.util.concurrent.Futures;
-
 public class VppEndpointLocationProvider implements AutoCloseable {
 
     private static final Logger LOG = LoggerFactory.getLogger(VppEndpointLocationProvider.class);
     public static final ProviderName VPP_ENDPOINT_LOCATION_PROVIDER =
             new ProviderName("VPP endpoint location provider");
     public static final long PROVIDER_PRIORITY = 10L;
-    private final DataBroker dataProvider;
+    private final BindingTransactionChain txChain;
 
     public VppEndpointLocationProvider(DataBroker dataProvider) {
-        this.dataProvider = Preconditions.checkNotNull(dataProvider);
         LocationProvider locationProvider = new LocationProviderBuilder().setProvider(VPP_ENDPOINT_LOCATION_PROVIDER)
             .setPriority(PROVIDER_PRIORITY)
             .build();
-        WriteTransaction wTx = dataProvider.newWriteOnlyTransaction();
+        txChain = checkNotNull(dataProvider)
+            .createTransactionChain(new CloseOnFailTransactionChain(VppEndpointLocationProvider.class.getSimpleName()));
+        WriteTransaction wTx = txChain.newWriteOnlyTransaction();
         wTx.put(LogicalDatastoreType.CONFIGURATION, IidFactory.locationProviderIid(VPP_ENDPOINT_LOCATION_PROVIDER),
                 locationProvider, true);
 
@@ -55,7 +62,7 @@ public class VppEndpointLocationProvider implements AutoCloseable {
 
             @Override
             public void onSuccess(Void result) {
-                LOG.trace("{} was created", VPP_ENDPOINT_LOCATION_PROVIDER.getValue());
+                LOG.debug("{} was created", VPP_ENDPOINT_LOCATION_PROVIDER.getValue());
             }
 
             @Override
@@ -65,35 +72,26 @@ public class VppEndpointLocationProvider implements AutoCloseable {
         });
     }
 
-    public void createLocationForVppEndpoint(VppEndpoint vppEndpoint) {
-        ProviderAddressEndpointLocation providerAddressEndpointLocation =
+    ListenableFuture<Void> createLocationForVppEndpoint(final VppEndpoint vppEndpoint) {
+        final ProviderAddressEndpointLocation providerAddressEndpointLocation =
                 createProviderAddressEndpointLocation(vppEndpoint);
-        WriteTransaction wTx = dataProvider.newWriteOnlyTransaction();
-        wTx.put(LogicalDatastoreType.CONFIGURATION,
-                IidFactory.providerAddressEndpointLocationIid(VPP_ENDPOINT_LOCATION_PROVIDER,
-                        providerAddressEndpointLocation.getKey()),
+        final WriteTransaction wTx = txChain.newWriteOnlyTransaction();
+        wTx.put(LogicalDatastoreType.CONFIGURATION, IidFactory.providerAddressEndpointLocationIid(
+                VPP_ENDPOINT_LOCATION_PROVIDER, providerAddressEndpointLocation.getKey()),
                 providerAddressEndpointLocation);
-
-        Futures.addCallback(wTx.submit(), new FutureCallback<Void>() {
-
-            @Override
-            public void onSuccess(Void result) {
-                LOG.trace("{} provides location: {}", VPP_ENDPOINT_LOCATION_PROVIDER.getValue(),
-                        providerAddressEndpointLocation);
-            }
-
-            @Override
-            public void onFailure(Throwable t) {
-                LOG.error("{} failed to provide location: {}", VPP_ENDPOINT_LOCATION_PROVIDER.getValue(),
-                        providerAddressEndpointLocation, t);
-            }
+        LOG.debug("Creating location for {}", providerAddressEndpointLocation.getKey());
+        return Futures.transform(wTx.submit(), (Function<Void, Void>) input -> {
+            LOG.debug("{} provided location: {}", VPP_ENDPOINT_LOCATION_PROVIDER.getValue(),
+                    providerAddressEndpointLocation);
+            return null;
         });
     }
 
     public static ProviderAddressEndpointLocation createProviderAddressEndpointLocation(VppEndpoint vppEndpoint) {
+        InstanceIdentifier<Node> vppNodeIid = VppIidFactory.getNetconfNodeIid(vppEndpoint.getVppNodeId());
         String restIfacePath = VppPathMapper.interfaceToRestPath(vppEndpoint.getVppInterfaceName());
         AbsoluteLocation absoluteLocation = new AbsoluteLocationBuilder()
-            .setLocationType(new ExternalLocationCaseBuilder().setExternalNodeMountPoint(vppEndpoint.getVppNodePath())
+            .setLocationType(new ExternalLocationCaseBuilder().setExternalNodeMountPoint(vppNodeIid)
                 .setExternalNodeConnector(restIfacePath)
                 .build())
             .build();
@@ -103,64 +101,52 @@ public class VppEndpointLocationProvider implements AutoCloseable {
             .build();
     }
 
-    public void deleteLocationForVppEndpoint(VppEndpoint vppEndpoint) {
-        ProviderAddressEndpointLocationKey provAddrEpLocKey = createProviderAddressEndpointLocationKey(vppEndpoint);
-        WriteTransaction wTx = dataProvider.newWriteOnlyTransaction();
+    ListenableFuture<Void> deleteLocationForVppEndpoint(final VppEndpoint vppEndpoint) {
+        final ProviderAddressEndpointLocationKey provAddrEpLocKey =
+                createProviderAddressEndpointLocationKey(vppEndpoint);
+        final WriteTransaction wTx = txChain.newWriteOnlyTransaction();
         wTx.delete(LogicalDatastoreType.CONFIGURATION,
                 IidFactory.providerAddressEndpointLocationIid(VPP_ENDPOINT_LOCATION_PROVIDER, provAddrEpLocKey));
-        Futures.addCallback(wTx.submit(), new FutureCallback<Void>() {
-
-            @Override
-            public void onSuccess(Void result) {
-                LOG.trace("{} removes location: {}", VPP_ENDPOINT_LOCATION_PROVIDER.getValue(), provAddrEpLocKey);
-            }
-
-            @Override
-            public void onFailure(Throwable t) {
-                LOG.error("{} failed to remove location: {}", VPP_ENDPOINT_LOCATION_PROVIDER.getValue(),
-                        provAddrEpLocKey, t);
-            }
+        LOG.debug("Deleting location for {}", provAddrEpLocKey);
+        return Futures.transform(wTx.submit(), (Function<Void, Void>) input -> {
+            LOG.debug("{} removed location: {}", VPP_ENDPOINT_LOCATION_PROVIDER.getValue(), provAddrEpLocKey);
+            return null;
         });
     }
 
-    private static ProviderAddressEndpointLocationKey createProviderAddressEndpointLocationKey(VppEndpoint vppEndpoint) {
+    private static ProviderAddressEndpointLocationKey createProviderAddressEndpointLocationKey(
+            VppEndpoint vppEndpoint) {
         return new ProviderAddressEndpointLocationKey(vppEndpoint.getAddress(), vppEndpoint.getAddressType(),
                 vppEndpoint.getContextId(), vppEndpoint.getContextType());
     }
 
-    public void updateExternalNodeLocationForEndpoint(@Nullable String nodePath,
-            @Nonnull AddressEndpointWithLocationKey addrEpWithLocKey) {
+    public ListenableFuture<Void> replaceLocationForEndpoint(@Nonnull ExternalLocationCase location, @Nonnull AddressEndpointWithLocationKey addrEpWithLocKey) {
         ProviderAddressEndpointLocationKey provAddrEpLocKey =
                 KeyFactory.providerAddressEndpointLocationKey(addrEpWithLocKey);
-        AbsoluteLocation absoluteLocation = new AbsoluteLocationBuilder()
-            .setLocationType(new ExternalLocationCaseBuilder().setExternalNode(nodePath).build()).build();
+        AbsoluteLocation absoluteLocation =
+                new AbsoluteLocationBuilder().setLocationType(location).build();
         ProviderAddressEndpointLocation providerAddressEndpointLocation = new ProviderAddressEndpointLocationBuilder()
             .setKey(provAddrEpLocKey).setAbsoluteLocation(absoluteLocation).build();
-        WriteTransaction wTx = dataProvider.newWriteOnlyTransaction();
-        wTx.merge(LogicalDatastoreType.CONFIGURATION,
+        WriteTransaction wTx = txChain.newWriteOnlyTransaction();
+        wTx.put(LogicalDatastoreType.CONFIGURATION,
                 IidFactory.providerAddressEndpointLocationIid(VPP_ENDPOINT_LOCATION_PROVIDER,
                         providerAddressEndpointLocation.getKey()),
                 providerAddressEndpointLocation);
-
-        Futures.addCallback(wTx.submit(), new FutureCallback<Void>() {
+        LOG.debug("Updating location for {}", provAddrEpLocKey);
+        return Futures.transform(wTx.submit(), new Function<Void, Void>() {
 
             @Override
-            public void onSuccess(Void result) {
-                LOG.trace("{} merges location: {}", VPP_ENDPOINT_LOCATION_PROVIDER.getValue(),
+            public Void apply(Void input) {
+                LOG.debug("{} replaced location: {}", VPP_ENDPOINT_LOCATION_PROVIDER.getValue(),
                         providerAddressEndpointLocation);
-            }
-
-            @Override
-            public void onFailure(Throwable t) {
-                LOG.error("{} failed to merge location: {}", VPP_ENDPOINT_LOCATION_PROVIDER.getValue(),
-                        providerAddressEndpointLocation, t);
+                return null;
             }
         });
     }
 
     @Override
     public void close() throws Exception {
-        WriteTransaction wTx = dataProvider.newWriteOnlyTransaction();
+        WriteTransaction wTx = txChain.newWriteOnlyTransaction();
         wTx.delete(LogicalDatastoreType.CONFIGURATION, IidFactory.locationProviderIid(VPP_ENDPOINT_LOCATION_PROVIDER));
         wTx.submit();
     }