X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=applications%2Fforwardingrules-manager%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fopenflowplugin%2Fapplications%2Ffrm%2Fimpl%2FGroupForwarder.java;h=cbb28503d73d05ab35aa7b02ff5a7a17307242ec;hb=05f8db12159673d0e0a95642fe86e62c14b7dc7b;hp=5f9398c1efd5f926560932b160222e166be5bb04;hpb=c5e10abbd2a2d9c806555f11f1d58f0cb10aa0a9;p=openflowplugin.git diff --git a/applications/forwardingrules-manager/src/main/java/org/opendaylight/openflowplugin/applications/frm/impl/GroupForwarder.java b/applications/forwardingrules-manager/src/main/java/org/opendaylight/openflowplugin/applications/frm/impl/GroupForwarder.java index 5f9398c1ef..cbb28503d7 100644 --- a/applications/forwardingrules-manager/src/main/java/org/opendaylight/openflowplugin/applications/frm/impl/GroupForwarder.java +++ b/applications/forwardingrules-manager/src/main/java/org/opendaylight/openflowplugin/applications/frm/impl/GroupForwarder.java @@ -1,4 +1,4 @@ -/** +/* * Copyright (c) 2014, 2017 Cisco Systems, Inc. and others. All rights reserved. * * This program and the accompanying materials are made available under the @@ -7,26 +7,32 @@ */ package org.opendaylight.openflowplugin.applications.frm.impl; -import com.google.common.base.Preconditions; -import com.google.common.util.concurrent.CheckedFuture; +import static org.opendaylight.openflowplugin.applications.frm.util.FrmUtil.getActiveBundle; +import static org.opendaylight.openflowplugin.applications.frm.util.FrmUtil.getNodeIdValueFromNodeIdentifier; + +import com.google.common.util.concurrent.FluentFuture; import com.google.common.util.concurrent.FutureCallback; import com.google.common.util.concurrent.Futures; +import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.MoreExecutors; import java.util.concurrent.Future; -import org.opendaylight.controller.md.sal.binding.api.DataBroker; -import org.opendaylight.controller.md.sal.binding.api.DataTreeIdentifier; -import org.opendaylight.controller.md.sal.binding.api.WriteTransaction; -import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; -import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException; +import org.opendaylight.infrautils.utils.concurrent.LoggingFutures; +import org.opendaylight.mdsal.binding.api.DataBroker; +import org.opendaylight.mdsal.binding.api.DataTreeIdentifier; +import org.opendaylight.mdsal.binding.api.WriteTransaction; +import org.opendaylight.mdsal.common.api.LogicalDatastoreType; import org.opendaylight.openflowplugin.applications.frm.ForwardingRulesManager; -import org.opendaylight.openflowplugin.common.wait.SimpleTaskRetryLooper; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Uri; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode; +import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.AddGroupInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.AddGroupInputBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.AddGroupOutput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.RemoveGroupInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.RemoveGroupInputBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.RemoveGroupOutput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.UpdateGroupInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.UpdateGroupInputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.UpdateGroupOutput; import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.group.update.OriginalGroupBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.group.update.UpdatedGroupBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupId; @@ -38,37 +44,38 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef; import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes; import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.onf.rev170124.BundleId; import org.opendaylight.yangtools.concepts.ListenerRegistration; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; import org.opendaylight.yangtools.yang.common.RpcResult; +import org.opendaylight.yangtools.yang.common.Uint32; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * GroupForwarder It implements - * {@link org.opendaylight.controller.md.sal.binding.api.DataTreeChangeListener} + * {@link org.opendaylight.mdsal.binding.api.DataTreeChangeListener} * for WildCardedPath to {@link Group} and ForwardingRulesCommiter interface for * methods: add, update and remove {@link Group} processing for - * {@link org.opendaylight.controller.md.sal.binding.api.DataTreeModification}. + * {@link org.opendaylight.mdsal.binding.api.DataTreeModification}. */ public class GroupForwarder extends AbstractListeningCommiter { private static final Logger LOG = LoggerFactory.getLogger(GroupForwarder.class); - private final DataBroker dataBroker; private ListenerRegistration listenerRegistration; - @SuppressWarnings("IllegalCatch") public GroupForwarder(final ForwardingRulesManager manager, final DataBroker db) { - super(manager); - dataBroker = Preconditions.checkNotNull(db, "DataBroker can not be null!"); - final DataTreeIdentifier treeId = new DataTreeIdentifier<>(LogicalDatastoreType.CONFIGURATION, + super(manager, db); + } + + @SuppressWarnings("IllegalCatch") + @Override + public void registerListener() { + final DataTreeIdentifier treeId = DataTreeIdentifier.create(LogicalDatastoreType.CONFIGURATION, getWildCardPath()); try { - SimpleTaskRetryLooper looper = new SimpleTaskRetryLooper(ForwardingRulesManagerImpl.STARTUP_LOOP_TICK, - ForwardingRulesManagerImpl.STARTUP_LOOP_MAX_RETRIES); - listenerRegistration = looper - .loopUntilNoException(() -> db.registerDataTreeChangeListener(treeId, GroupForwarder.this)); + listenerRegistration = dataBroker.registerDataTreeChangeListener(treeId, GroupForwarder.this); } catch (final Exception e) { LOG.warn("FRM Group DataTreeChange listener registration fail!"); LOG.debug("FRM Group DataTreeChange listener registration fail ..", e); @@ -76,6 +83,11 @@ public class GroupForwarder extends AbstractListeningCommiter { } } + @Override + public void deregisterListener() { + close(); + } + @Override public void close() { if (listenerRegistration != null) { @@ -86,21 +98,38 @@ public class GroupForwarder extends AbstractListeningCommiter { @Override protected InstanceIdentifier getWildCardPath() { - return InstanceIdentifier.create(Nodes.class).child(Node.class).augmentation(FlowCapableNode.class) + return InstanceIdentifier.create(Nodes.class) + .child(Node.class) + .augmentation(FlowCapableNode.class) .child(Group.class); } @Override public void remove(final InstanceIdentifier identifier, final Group removeDataObj, final InstanceIdentifier nodeIdent) { + BundleId bundleId = getActiveBundle(nodeIdent, provider); + if (bundleId != null) { + provider.getBundleGroupListener().remove(identifier, removeDataObj, nodeIdent, bundleId); + } else { + final String nodeId = getNodeIdValueFromNodeIdentifier(nodeIdent); + nodeConfigurator.enqueueJob(nodeId, () -> { + final Group group = removeDataObj; + final RemoveGroupInput removeGroup = new RemoveGroupInputBuilder(group) + .setNode(new NodeRef(nodeIdent.firstIdentifierOf(Node.class))) + .setGroupRef(new GroupRef(identifier)) + .setTransactionUri(new Uri(provider.getNewTransactionId())) + .build(); - final Group group = removeDataObj; - final RemoveGroupInputBuilder builder = new RemoveGroupInputBuilder(group); - - builder.setNode(new NodeRef(nodeIdent.firstIdentifierOf(Node.class))); - builder.setGroupRef(new GroupRef(identifier)); - builder.setTransactionUri(new Uri(provider.getNewTransactionId())); - this.provider.getSalGroupService().removeGroup(builder.build()); + final ListenableFuture> resultFuture = + this.provider.getSalGroupService() + .removeGroup(removeGroup); + Futures.addCallback(resultFuture, + new RemoveGroupCallBack(removeDataObj.getGroupId().getValue(), nodeId), + MoreExecutors.directExecutor()); + LoggingFutures.addErrorLogging(resultFuture, LOG, "removeGroup"); + return resultFuture; + }); + } } // TODO: Pull this into ForwardingRulesCommiter and override it here @@ -120,37 +149,62 @@ public class GroupForwarder extends AbstractListeningCommiter { @Override public void update(final InstanceIdentifier identifier, final Group original, final Group update, final InstanceIdentifier nodeIdent) { - - final Group originalGroup = original; - final Group updatedGroup = update; - final UpdateGroupInputBuilder builder = new UpdateGroupInputBuilder(); - - builder.setNode(new NodeRef(nodeIdent.firstIdentifierOf(Node.class))); - builder.setGroupRef(new GroupRef(identifier)); - builder.setTransactionUri(new Uri(provider.getNewTransactionId())); - builder.setUpdatedGroup(new UpdatedGroupBuilder(updatedGroup).build()); - builder.setOriginalGroup(new OriginalGroupBuilder(originalGroup).build()); - - this.provider.getSalGroupService().updateGroup(builder.build()); + BundleId bundleId = getActiveBundle(nodeIdent, provider); + if (bundleId != null) { + provider.getBundleGroupListener().update(identifier, original, update, nodeIdent, bundleId); + } else { + final String nodeId = getNodeIdValueFromNodeIdentifier(nodeIdent); + nodeConfigurator.enqueueJob(nodeId, () -> { + final Group originalGroup = original; + final Group updatedGroup = update; + final UpdateGroupInputBuilder builder = new UpdateGroupInputBuilder(); + builder.setNode(new NodeRef(nodeIdent.firstIdentifierOf(Node.class))); + builder.setGroupRef(new GroupRef(identifier)); + builder.setTransactionUri(new Uri(provider.getNewTransactionId())); + builder.setUpdatedGroup(new UpdatedGroupBuilder(updatedGroup).build()); + builder.setOriginalGroup(new OriginalGroupBuilder(originalGroup).build()); + UpdateGroupInput updateGroupInput = builder.build(); + final ListenableFuture> resultFuture = this.provider.getSalGroupService() + .updateGroup(updateGroupInput); + LoggingFutures.addErrorLogging(resultFuture, LOG, "updateGroup"); + Futures.addCallback(resultFuture, + new UpdateGroupCallBack(updateGroupInput.getOriginalGroup().getGroupId().getValue(), nodeId), + MoreExecutors.directExecutor()); + return resultFuture; + }); + } } @Override - public Future> add(final InstanceIdentifier identifier, final Group addDataObj, + public Future> add(final InstanceIdentifier identifier, final Group addDataObj, final InstanceIdentifier nodeIdent) { - - final Group group = addDataObj; - final AddGroupInputBuilder builder = new AddGroupInputBuilder(group); - - builder.setNode(new NodeRef(nodeIdent.firstIdentifierOf(Node.class))); - builder.setGroupRef(new GroupRef(identifier)); - builder.setTransactionUri(new Uri(provider.getNewTransactionId())); - return this.provider.getSalGroupService().addGroup(builder.build()); + BundleId bundleId = getActiveBundle(nodeIdent, provider); + if (bundleId != null) { + return provider.getBundleGroupListener().add(identifier, addDataObj, nodeIdent, bundleId); + } else { + final String nodeId = getNodeIdValueFromNodeIdentifier(nodeIdent); + return nodeConfigurator + .enqueueJob(nodeId, () -> { + final Group group = addDataObj; + final AddGroupInputBuilder builder = new AddGroupInputBuilder(group); + builder.setNode(new NodeRef(nodeIdent.firstIdentifierOf(Node.class))); + builder.setGroupRef(new GroupRef(identifier)); + builder.setTransactionUri(new Uri(provider.getNewTransactionId())); + AddGroupInput addGroupInput = builder.build(); + final ListenableFuture> resultFuture; + resultFuture = this.provider.getSalGroupService().addGroup(addGroupInput); + Futures.addCallback(resultFuture, + new AddGroupCallBack(addGroupInput.getGroupId().getValue(), nodeId), + MoreExecutors.directExecutor()); + return resultFuture; + }); + } } @Override public void createStaleMarkEntity(InstanceIdentifier identifier, Group del, InstanceIdentifier nodeIdent) { - LOG.debug("Creating Stale-Mark entry for the switch {} for Group {} ", nodeIdent.toString(), del.toString()); + LOG.debug("Creating Stale-Mark entry for the switch {} for Group {} ", nodeIdent, del); StaleGroup staleGroup = makeStaleGroup(identifier, del, nodeIdent); persistStaleGroup(staleGroup, nodeIdent); @@ -165,22 +219,22 @@ public class GroupForwarder extends AbstractListeningCommiter { private void persistStaleGroup(StaleGroup staleGroup, InstanceIdentifier nodeIdent) { WriteTransaction writeTransaction = dataBroker.newWriteOnlyTransaction(); writeTransaction.put(LogicalDatastoreType.CONFIGURATION, getStaleGroupInstanceIdentifier(staleGroup, nodeIdent), - staleGroup, false); + staleGroup); - CheckedFuture submitFuture = writeTransaction.submit(); + FluentFuture submitFuture = writeTransaction.commit(); handleStaleGroupResultFuture(submitFuture); } - private void handleStaleGroupResultFuture(CheckedFuture submitFuture) { - Futures.addCallback(submitFuture, new FutureCallback() { + private void handleStaleGroupResultFuture(FluentFuture submitFuture) { + submitFuture.addCallback(new FutureCallback() { @Override - public void onSuccess(Void result) { + public void onSuccess(Object result) { LOG.debug("Stale Group creation success"); } @Override public void onFailure(Throwable throwable) { - LOG.error("Stale Group creation failed {}", throwable); + LOG.error("Stale Group creation failed", throwable); } }, MoreExecutors.directExecutor()); @@ -192,4 +246,82 @@ public class GroupForwarder extends AbstractListeningCommiter { return nodeIdent.child(StaleGroup.class, new StaleGroupKey(new GroupId(staleGroup.getGroupId()))); } + private final class AddGroupCallBack implements FutureCallback> { + private final Uint32 groupId; + private final String nodeId; + + private AddGroupCallBack(final Uint32 groupId, final String nodeId) { + this.groupId = groupId; + this.nodeId = nodeId; + } + + @Override + public void onSuccess(RpcResult result) { + if (result.isSuccessful()) { + provider.getDevicesGroupRegistry().storeGroup(nodeId, groupId); + LOG.debug("Group add with id {} finished without error for node {}", groupId, nodeId); + } else { + LOG.debug("Group add with id {} failed for node {} with error {}", groupId, nodeId, + result.getErrors()); + } + } + + @Override + public void onFailure(Throwable throwable) { + LOG.error("Service call for adding group {} failed for node with error {}", groupId, nodeId, throwable); + } + } + + private final class UpdateGroupCallBack implements FutureCallback> { + private final Uint32 groupId; + private final String nodeId; + + private UpdateGroupCallBack(final Uint32 groupId, final String nodeId) { + this.groupId = groupId; + this.nodeId = nodeId; + } + + @Override + public void onSuccess(RpcResult result) { + if (result.isSuccessful()) { + provider.getDevicesGroupRegistry().storeGroup(nodeId, groupId); + LOG.debug("Group update with id {} finished without error for node {}", groupId, nodeId); + } else { + LOG.debug("Group update with id {} failed for node {} with error {}", groupId, nodeId, + result.getErrors().toString()); + } + } + + @Override + public void onFailure(Throwable throwable) { + LOG.error("Service call for updating group {} failed for node {} with", groupId, nodeId, + throwable); + } + } + + private final class RemoveGroupCallBack implements FutureCallback> { + private final Uint32 groupId; + private final String nodeId; + + private RemoveGroupCallBack(final Uint32 groupId, final String nodeId) { + this.groupId = groupId; + this.nodeId = nodeId; + } + + @Override + public void onSuccess(RpcResult result) { + if (result.isSuccessful()) { + LOG.debug("Group remove with id {} finished without error for node {}", groupId, nodeId); + provider.getDevicesGroupRegistry().removeGroup(nodeId, groupId); + } else { + LOG.debug("Group remove with id {} failed for node {} with error {}", groupId, nodeId, + result.getErrors().toString()); + } + } + + @Override + public void onFailure(Throwable throwable) { + LOG.error("Service call for removing group {} failed for node with error {}", groupId, nodeId, throwable); + } + } }