2 * Copyright (c) 2018 Ericsson India Global Services Pvt Ltd. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
9 package org.opendaylight.openflowplugin.applications.frm.impl;
11 import static org.opendaylight.openflowplugin.applications.frm.util.FrmUtil.getNodeIdFromNodeIdentifier;
12 import static org.opendaylight.openflowplugin.applications.frm.util.FrmUtil.isGroupExistsOnDevice;
14 import com.google.common.base.Preconditions;
15 import com.google.common.util.concurrent.FutureCallback;
16 import com.google.common.util.concurrent.Futures;
17 import com.google.common.util.concurrent.ListenableFuture;
18 import com.google.common.util.concurrent.MoreExecutors;
19 import java.util.ArrayList;
20 import java.util.List;
21 import org.opendaylight.infrautils.utils.concurrent.LoggingFutures;
22 import org.opendaylight.openflowplugin.applications.frm.ForwardingRulesManager;
23 import org.opendaylight.openflowplugin.applications.frm.NodeConfigurator;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.Group;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.onf.bundle.service.rev170124.AddBundleMessagesInput;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.onf.bundle.service.rev170124.AddBundleMessagesInputBuilder;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.onf.bundle.service.rev170124.AddBundleMessagesOutput;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.onf.bundle.service.rev170124.add.bundle.messages.input.MessagesBuilder;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.onf.bundle.service.rev170124.add.bundle.messages.input.messages.Message;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.onf.bundle.service.rev170124.add.bundle.messages.input.messages.MessageBuilder;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.onf.bundle.service.rev170124.bundle.inner.message.grouping.BundleInnerMessage;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.onf.bundle.service.rev170124.bundle.inner.message.grouping.bundle.inner.message.BundleAddGroupCaseBuilder;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.onf.bundle.service.rev170124.bundle.inner.message.grouping.bundle.inner.message.BundleRemoveGroupCaseBuilder;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.onf.bundle.service.rev170124.bundle.inner.message.grouping.bundle.inner.message.BundleUpdateGroupCaseBuilder;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.onf.bundle.service.rev170124.bundle.inner.message.grouping.bundle.inner.message.bundle.add.group._case.AddGroupCaseDataBuilder;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.onf.bundle.service.rev170124.bundle.inner.message.grouping.bundle.inner.message.bundle.remove.group._case.RemoveGroupCaseDataBuilder;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.onf.bundle.service.rev170124.bundle.inner.message.grouping.bundle.inner.message.bundle.update.group._case.UpdateGroupCaseDataBuilder;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.onf.rev170124.BundleFlags;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.onf.rev170124.BundleId;
44 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
45 import org.opendaylight.yangtools.yang.common.RpcResult;
46 import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
47 import org.slf4j.Logger;
48 import org.slf4j.LoggerFactory;
50 public class BundleGroupForwarder {
52 private static final Logger LOG = LoggerFactory.getLogger(BundleGroupForwarder.class);
53 private static final BundleFlags BUNDLE_FLAGS = new BundleFlags(true, true);
54 private final ForwardingRulesManager forwardingRulesManager;
55 private final NodeConfigurator nodeConfigurator;
57 public BundleGroupForwarder(final ForwardingRulesManager forwardingRulesManager) {
58 this.forwardingRulesManager = Preconditions.checkNotNull(forwardingRulesManager,
59 "ForwardingRulesManager can not be null!");
60 this.nodeConfigurator = Preconditions.checkNotNull(forwardingRulesManager.getNodeConfigurator(),
61 "NodeConfigurator can not be null!");
64 public void remove(final InstanceIdentifier<Group> identifier, final Group group,
65 final InstanceIdentifier<FlowCapableNode> nodeIdent, final BundleId bundleId) {
66 final NodeId nodeId = getNodeIdFromNodeIdentifier(nodeIdent);
67 nodeConfigurator.enqueueJob(nodeId.getValue(), () -> {
68 final List<Message> messages = new ArrayList<>(1);
69 BundleInnerMessage bundleInnerMessage = new BundleRemoveGroupCaseBuilder()
70 .setRemoveGroupCaseData(new RemoveGroupCaseDataBuilder(group).build()).build();
71 Message message = new MessageBuilder().setNode(new NodeRef(nodeIdent.firstIdentifierOf(Node.class)))
72 .setBundleInnerMessage(bundleInnerMessage).build();
73 messages.add(message);
74 AddBundleMessagesInput addBundleMessagesInput = new AddBundleMessagesInputBuilder()
75 .setNode(new NodeRef(nodeIdent.firstIdentifierOf(Node.class))).setBundleId(bundleId)
76 .setFlags(BUNDLE_FLAGS).setMessages(new MessagesBuilder().setMessage(messages).build()).build();
77 LOG.trace("Pushing group remove message {} to bundle {} for device {}", addBundleMessagesInput,
78 bundleId.getValue(), nodeId.getValue());
79 final ListenableFuture<RpcResult<AddBundleMessagesOutput>> resultFuture = forwardingRulesManager
80 .getSalBundleService().addBundleMessages(addBundleMessagesInput);
81 Futures.addCallback(resultFuture, new BundleRemoveGroupCallBack(group.getGroupId().getValue(), nodeId),
82 MoreExecutors.directExecutor());
83 LoggingFutures.addErrorLogging(resultFuture, LOG, "removeBundleGroup");
89 public void update(final InstanceIdentifier<Group> identifier, final Group originalGroup, final Group updatedGroup,
90 final InstanceIdentifier<FlowCapableNode> nodeIdent, final BundleId bundleId) {
91 final NodeId nodeId = getNodeIdFromNodeIdentifier(nodeIdent);
92 nodeConfigurator.enqueueJob(nodeId.getValue(), () -> {
93 final List<Message> messages = new ArrayList<>(1);
94 BundleInnerMessage bundleInnerMessage = new BundleUpdateGroupCaseBuilder()
95 .setUpdateGroupCaseData(new UpdateGroupCaseDataBuilder(updatedGroup).build()).build();
96 Message message = new MessageBuilder().setNode(new NodeRef(nodeIdent.firstIdentifierOf(Node.class)))
97 .setBundleInnerMessage(bundleInnerMessage).build();
98 messages.add(message);
99 AddBundleMessagesInput addBundleMessagesInput = new AddBundleMessagesInputBuilder()
100 .setNode(new NodeRef(nodeIdent.firstIdentifierOf(Node.class))).setBundleId(bundleId)
101 .setFlags(BUNDLE_FLAGS).setMessages(new MessagesBuilder().setMessage(messages).build()).build();
102 LOG.trace("Pushing group update message {} to bundle {} for device {}", addBundleMessagesInput,
103 bundleId.getValue(), nodeId.getValue());
104 final ListenableFuture<RpcResult<AddBundleMessagesOutput>> resultFuture = forwardingRulesManager
105 .getSalBundleService().addBundleMessages(addBundleMessagesInput);
106 Futures.addCallback(resultFuture, new BundleUpdateGroupCallBack(originalGroup.getGroupId().getValue(),
107 nodeId), MoreExecutors.directExecutor());
108 LoggingFutures.addErrorLogging(resultFuture, LOG, "updateBundleGroup");
113 public ListenableFuture<? extends RpcResult<?>> add(final InstanceIdentifier<Group> identifier, final Group group,
114 final InstanceIdentifier<FlowCapableNode> nodeIdent, final BundleId bundleId) {
115 final NodeId nodeId = getNodeIdFromNodeIdentifier(nodeIdent);
116 final Long groupId = group.getGroupId().getValue();
117 return nodeConfigurator.enqueueJob(nodeId.getValue(), () -> {
118 if (isGroupExistsOnDevice(nodeIdent, groupId, forwardingRulesManager)) {
119 LOG.debug("Group {} already exists in the device. Ignoring the add DTCN", groupId);
120 return Futures.immediateFuture(RpcResultBuilder.<AddBundleMessagesOutput>success().build());
122 final List<Message> messages = new ArrayList<>(1);
123 BundleInnerMessage bundleInnerMessage = new BundleAddGroupCaseBuilder()
124 .setAddGroupCaseData(new AddGroupCaseDataBuilder(group).build()).build();
125 Message message = new MessageBuilder().setNode(new NodeRef(nodeIdent.firstIdentifierOf(Node.class)))
126 .setBundleInnerMessage(bundleInnerMessage).build();
127 messages.add(message);
128 AddBundleMessagesInput addBundleMessagesInput = new AddBundleMessagesInputBuilder()
129 .setNode(new NodeRef(nodeIdent.firstIdentifierOf(Node.class))).setBundleId(bundleId)
130 .setFlags(BUNDLE_FLAGS).setMessages(new MessagesBuilder().setMessage(messages).build()).build();
131 LOG.trace("Pushing group add message {} to bundle {} for device {}", addBundleMessagesInput,
132 bundleId.getValue(), nodeId.getValue());
133 ListenableFuture<RpcResult<AddBundleMessagesOutput>> resultFuture = forwardingRulesManager
134 .getSalBundleService().addBundleMessages(addBundleMessagesInput);
135 Futures.addCallback(resultFuture, new BundleAddGroupCallBack(groupId, nodeId),
136 MoreExecutors.directExecutor());
141 private final class BundleAddGroupCallBack implements FutureCallback<RpcResult<AddBundleMessagesOutput>> {
142 private final Long groupId;
143 private final NodeId nodeId;
145 private BundleAddGroupCallBack(final Long groupId, final NodeId nodeId) {
146 this.groupId = groupId;
147 this.nodeId = nodeId;
151 public void onSuccess(RpcResult<AddBundleMessagesOutput> result) {
152 if (result.isSuccessful()) {
153 forwardingRulesManager.getDevicesGroupRegistry().storeGroup(nodeId, groupId);
154 LOG.debug("Group add with id {} finished without error for node {}", groupId, nodeId);
156 LOG.debug("Group add with id {} failed for node {} with error {}", groupId, nodeId,
157 result.getErrors().toString());
162 public void onFailure(Throwable throwable) {
163 LOG.error("Service call for adding group {} failed for node with error {}", groupId, nodeId, throwable);
167 private final class BundleUpdateGroupCallBack implements FutureCallback<RpcResult<AddBundleMessagesOutput>> {
168 private final Long groupId;
169 private final NodeId nodeId;
171 private BundleUpdateGroupCallBack(final Long groupId, final NodeId nodeId) {
172 this.groupId = groupId;
173 this.nodeId = nodeId;
177 public void onSuccess(RpcResult<AddBundleMessagesOutput> result) {
178 if (result.isSuccessful()) {
179 forwardingRulesManager.getDevicesGroupRegistry().storeGroup(nodeId, groupId);
180 LOG.debug("Group update with id {} finished without error for node {}", groupId, nodeId);
182 LOG.debug("Group update with id {} failed for node {} with error {}", groupId, nodeId,
183 result.getErrors().toString());
188 public void onFailure(Throwable throwable) {
189 LOG.error("Service call for updating group {} failed for node {}", groupId, nodeId, throwable);
193 private final class BundleRemoveGroupCallBack implements FutureCallback<RpcResult<AddBundleMessagesOutput>> {
194 private final Long groupId;
195 private final NodeId nodeId;
197 private BundleRemoveGroupCallBack(final Long groupId, final NodeId nodeId) {
198 this.groupId = groupId;
199 this.nodeId = nodeId;
203 public void onSuccess(RpcResult<AddBundleMessagesOutput> result) {
204 if (result.isSuccessful()) {
205 LOG.debug("Group remove with id {} finished without error for node {}", groupId, nodeId);
206 forwardingRulesManager.getDevicesGroupRegistry().removeGroup(nodeId, groupId);
208 LOG.debug("Group remove with id {} failed for node {} with error {}", groupId, nodeId,
209 result.getErrors().toString());
214 public void onFailure(Throwable throwable) {
215 LOG.error("Service call for removing group {} failed for node with error {}", groupId, nodeId, throwable);