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
8 package org.opendaylight.openflowplugin.applications.frm.impl;
10 import static org.opendaylight.openflowplugin.applications.frm.util.FrmUtil.getNodeIdValueFromNodeIdentifier;
11 import static org.opendaylight.openflowplugin.applications.frm.util.FrmUtil.isGroupExistsOnDevice;
13 import com.google.common.base.Preconditions;
14 import com.google.common.util.concurrent.FutureCallback;
15 import com.google.common.util.concurrent.Futures;
16 import com.google.common.util.concurrent.ListenableFuture;
17 import com.google.common.util.concurrent.MoreExecutors;
18 import java.util.ArrayList;
19 import java.util.List;
20 import org.opendaylight.infrautils.utils.concurrent.LoggingFutures;
21 import org.opendaylight.openflowplugin.applications.frm.BundleMessagesCommiter;
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.NodeRef;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.onf.bundle.service.rev170124.AddBundleMessagesInput;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.onf.bundle.service.rev170124.AddBundleMessagesInputBuilder;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.onf.bundle.service.rev170124.AddBundleMessagesOutput;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.onf.bundle.service.rev170124.add.bundle.messages.input.MessagesBuilder;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.onf.bundle.service.rev170124.add.bundle.messages.input.messages.Message;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.onf.bundle.service.rev170124.add.bundle.messages.input.messages.MessageBuilder;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.onf.bundle.service.rev170124.bundle.inner.message.grouping.BundleInnerMessage;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.onf.bundle.service.rev170124.bundle.inner.message.grouping.bundle.inner.message.BundleAddGroupCaseBuilder;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.onf.bundle.service.rev170124.bundle.inner.message.grouping.bundle.inner.message.BundleRemoveGroupCaseBuilder;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.onf.bundle.service.rev170124.bundle.inner.message.grouping.bundle.inner.message.BundleUpdateGroupCaseBuilder;
38 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;
39 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;
40 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;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.onf.rev170124.BundleFlags;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.onf.rev170124.BundleId;
43 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
44 import org.opendaylight.yangtools.yang.common.RpcResult;
45 import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
46 import org.opendaylight.yangtools.yang.common.Uint32;
47 import org.slf4j.Logger;
48 import org.slf4j.LoggerFactory;
50 public class BundleGroupForwarder implements BundleMessagesCommiter<Group> {
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!");
65 public void remove(final InstanceIdentifier<Group> identifier, final Group group,
66 final InstanceIdentifier<FlowCapableNode> nodeIdent, final BundleId bundleId) {
67 final String nodeId = getNodeIdValueFromNodeIdentifier(nodeIdent);
68 nodeConfigurator.enqueueJob(nodeId, () -> {
69 final List<Message> messages = new ArrayList<>(1);
70 BundleInnerMessage bundleInnerMessage = new BundleRemoveGroupCaseBuilder()
71 .setRemoveGroupCaseData(new RemoveGroupCaseDataBuilder(group).build())
73 Message message = new MessageBuilder()
74 .setNode(new NodeRef(nodeIdent.firstIdentifierOf(Node.class)))
75 .setBundleInnerMessage(bundleInnerMessage)
77 messages.add(message);
78 AddBundleMessagesInput addBundleMessagesInput = new AddBundleMessagesInputBuilder()
79 .setNode(new NodeRef(nodeIdent.firstIdentifierOf(Node.class)))
80 .setBundleId(bundleId)
81 .setFlags(BUNDLE_FLAGS)
82 .setMessages(new MessagesBuilder().setMessage(messages).build())
84 LOG.trace("Pushing group remove message {} to bundle {} for device {}", addBundleMessagesInput,
85 bundleId.getValue(), nodeId);
86 final ListenableFuture<RpcResult<AddBundleMessagesOutput>> resultFuture = forwardingRulesManager
87 .getSalBundleService().addBundleMessages(addBundleMessagesInput);
88 Futures.addCallback(resultFuture,
89 new BundleRemoveGroupCallBack(group.getGroupId().getValue(), nodeId),
90 MoreExecutors.directExecutor());
91 LoggingFutures.addErrorLogging(resultFuture, LOG, "removeBundleGroup");
98 public void update(final InstanceIdentifier<Group> identifier,
99 final Group originalGroup,
100 final Group updatedGroup,
101 final InstanceIdentifier<FlowCapableNode> nodeIdent,
102 final BundleId bundleId) {
103 final String nodeId = getNodeIdValueFromNodeIdentifier(nodeIdent);
104 nodeConfigurator.enqueueJob(nodeId, () -> {
105 final List<Message> messages = new ArrayList<>(1);
106 BundleInnerMessage bundleInnerMessage = new BundleUpdateGroupCaseBuilder()
107 .setUpdateGroupCaseData(new UpdateGroupCaseDataBuilder(updatedGroup).build())
109 Message message = new MessageBuilder()
110 .setNode(new NodeRef(nodeIdent.firstIdentifierOf(Node.class)))
111 .setBundleInnerMessage(bundleInnerMessage)
113 messages.add(message);
114 AddBundleMessagesInput addBundleMessagesInput = new AddBundleMessagesInputBuilder()
115 .setNode(new NodeRef(nodeIdent.firstIdentifierOf(Node.class)))
116 .setBundleId(bundleId)
117 .setFlags(BUNDLE_FLAGS)
118 .setMessages(new MessagesBuilder().setMessage(messages).build())
120 LOG.trace("Pushing group update message {} to bundle {} for device {}", addBundleMessagesInput,
121 bundleId.getValue(), nodeId);
122 final ListenableFuture<RpcResult<AddBundleMessagesOutput>> resultFuture = forwardingRulesManager
123 .getSalBundleService()
124 .addBundleMessages(addBundleMessagesInput);
125 Futures.addCallback(resultFuture,
126 new BundleUpdateGroupCallBack(originalGroup.getGroupId().getValue(), nodeId),
127 MoreExecutors.directExecutor());
128 LoggingFutures.addErrorLogging(resultFuture, LOG, "updateBundleGroup");
134 public ListenableFuture<RpcResult<AddBundleMessagesOutput>> add(final InstanceIdentifier<Group> identifier,
136 final InstanceIdentifier<FlowCapableNode> nodeIdent,
137 final BundleId bundleId) {
138 final String nodeId = getNodeIdValueFromNodeIdentifier(nodeIdent);
139 final Uint32 groupId = group.getGroupId().getValue();
140 return nodeConfigurator.enqueueJob(nodeId, () -> {
141 if (isGroupExistsOnDevice(nodeIdent, groupId, forwardingRulesManager)) {
142 LOG.debug("Group {} already exists in the device. Ignoring the add DTCN", groupId);
143 return Futures.immediateFuture(RpcResultBuilder.<AddBundleMessagesOutput>success().build());
145 final List<Message> messages = new ArrayList<>(1);
146 BundleInnerMessage bundleInnerMessage = new BundleAddGroupCaseBuilder()
147 .setAddGroupCaseData(new AddGroupCaseDataBuilder(group).build())
149 Message message = new MessageBuilder()
150 .setNode(new NodeRef(nodeIdent.firstIdentifierOf(Node.class)))
151 .setBundleInnerMessage(bundleInnerMessage)
153 messages.add(message);
154 AddBundleMessagesInput addBundleMessagesInput = new AddBundleMessagesInputBuilder()
155 .setNode(new NodeRef(nodeIdent.firstIdentifierOf(Node.class)))
156 .setBundleId(bundleId)
157 .setFlags(BUNDLE_FLAGS)
158 .setMessages(new MessagesBuilder()
159 .setMessage(messages).build())
161 LOG.trace("Pushing group add message {} to bundle {} for device {}", addBundleMessagesInput,
162 bundleId.getValue(), nodeId);
163 ListenableFuture<RpcResult<AddBundleMessagesOutput>> resultFuture = forwardingRulesManager
164 .getSalBundleService()
165 .addBundleMessages(addBundleMessagesInput);
166 Futures.addCallback(resultFuture,
167 new BundleAddGroupCallBack(groupId, nodeId),
168 MoreExecutors.directExecutor());
173 private final class BundleAddGroupCallBack implements FutureCallback<RpcResult<AddBundleMessagesOutput>> {
174 private final Uint32 groupId;
175 private final String nodeId;
177 private BundleAddGroupCallBack(final Uint32 groupId, final String nodeId) {
178 this.groupId = groupId;
179 this.nodeId = nodeId;
183 public void onSuccess(RpcResult<AddBundleMessagesOutput> result) {
184 if (result.isSuccessful()) {
185 forwardingRulesManager.getDevicesGroupRegistry().storeGroup(nodeId, groupId);
186 LOG.debug("Group add with id {} finished without error for node {}", groupId, nodeId);
188 LOG.error("Group add with id {} failed for node {} with error: {}", groupId, nodeId,
189 result.getErrors().toString());
194 public void onFailure(Throwable throwable) {
195 LOG.error("Service call for adding group {} failed for node {} with error ", groupId, nodeId, throwable);
199 private final class BundleUpdateGroupCallBack implements FutureCallback<RpcResult<AddBundleMessagesOutput>> {
200 private final Uint32 groupId;
201 private final String nodeId;
203 private BundleUpdateGroupCallBack(final Uint32 groupId, final String nodeId) {
204 this.groupId = groupId;
205 this.nodeId = nodeId;
209 public void onSuccess(RpcResult<AddBundleMessagesOutput> result) {
210 if (result.isSuccessful()) {
211 forwardingRulesManager.getDevicesGroupRegistry().storeGroup(nodeId, groupId);
212 LOG.debug("Group update with id {} finished without error for node {}", groupId, nodeId);
214 LOG.error("Group update with id {} failed for node {} with error: {}", groupId, nodeId,
215 result.getErrors().toString());
220 public void onFailure(Throwable throwable) {
221 LOG.error("Service call for updating group {} failed for node {}", groupId, nodeId, throwable);
225 private final class BundleRemoveGroupCallBack implements FutureCallback<RpcResult<AddBundleMessagesOutput>> {
226 private final Uint32 groupId;
227 private final String nodeId;
229 private BundleRemoveGroupCallBack(final Uint32 groupId, final String nodeId) {
230 this.groupId = groupId;
231 this.nodeId = nodeId;
235 public void onSuccess(RpcResult<AddBundleMessagesOutput> result) {
236 if (result.isSuccessful()) {
237 LOG.debug("Group remove with id {} finished without error for node {}", groupId, nodeId);
238 forwardingRulesManager.getDevicesGroupRegistry().removeGroup(nodeId, groupId);
240 LOG.error("Group remove with id {} failed for node {} with error {}", groupId, nodeId,
241 result.getErrors().toString());
246 public void onFailure(Throwable throwable) {
247 LOG.error("Service call for removing group {} failed for node {} with error", groupId, nodeId, throwable);