Merge "Remove unneeded boxing"
[openflowplugin.git] / applications / forwardingrules-manager / src / main / java / org / opendaylight / openflowplugin / applications / frm / impl / BundleGroupForwarder.java
1 /*
2  * Copyright (c) 2018 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
3  *
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
7  */
8 package org.opendaylight.openflowplugin.applications.frm.impl;
9
10 import static org.opendaylight.openflowplugin.applications.frm.util.FrmUtil.getNodeIdValueFromNodeIdentifier;
11 import static org.opendaylight.openflowplugin.applications.frm.util.FrmUtil.isGroupExistsOnDevice;
12
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;
49
50 public class BundleGroupForwarder implements BundleMessagesCommiter<Group> {
51
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;
56
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!");
62     }
63
64     @Override
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())
72                     .build();
73             Message message = new MessageBuilder()
74                     .setNode(new NodeRef(nodeIdent.firstIdentifierOf(Node.class)))
75                     .setBundleInnerMessage(bundleInnerMessage)
76                     .build();
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())
83                     .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");
92             return resultFuture;
93         });
94
95     }
96
97     @Override
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())
108                     .build();
109             Message message = new MessageBuilder()
110                     .setNode(new NodeRef(nodeIdent.firstIdentifierOf(Node.class)))
111                     .setBundleInnerMessage(bundleInnerMessage)
112                     .build();
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())
119                     .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");
129             return resultFuture;
130         });
131     }
132
133     @Override
134     public ListenableFuture<RpcResult<AddBundleMessagesOutput>> add(final InstanceIdentifier<Group> identifier,
135                                                                     final Group group,
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());
144             }
145             final List<Message> messages = new ArrayList<>(1);
146             BundleInnerMessage bundleInnerMessage = new BundleAddGroupCaseBuilder()
147                     .setAddGroupCaseData(new AddGroupCaseDataBuilder(group).build())
148                     .build();
149             Message message = new MessageBuilder()
150                     .setNode(new NodeRef(nodeIdent.firstIdentifierOf(Node.class)))
151                     .setBundleInnerMessage(bundleInnerMessage)
152                     .build();
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())
160                     .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());
169             return resultFuture;
170         });
171     }
172
173     private final class BundleAddGroupCallBack implements FutureCallback<RpcResult<AddBundleMessagesOutput>> {
174         private final Uint32 groupId;
175         private final String nodeId;
176
177         private BundleAddGroupCallBack(final Uint32 groupId, final String nodeId) {
178             this.groupId = groupId;
179             this.nodeId = nodeId;
180         }
181
182         @Override
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);
187             } else {
188                 LOG.error("Group add with id {} failed for node {} with error: {}", groupId, nodeId,
189                         result.getErrors().toString());
190             }
191         }
192
193         @Override
194         public void onFailure(Throwable throwable) {
195             LOG.error("Service call for adding group {} failed for node {} with error ", groupId, nodeId, throwable);
196         }
197     }
198
199     private final class BundleUpdateGroupCallBack implements FutureCallback<RpcResult<AddBundleMessagesOutput>> {
200         private final Uint32 groupId;
201         private final String nodeId;
202
203         private BundleUpdateGroupCallBack(final Uint32 groupId, final String nodeId) {
204             this.groupId = groupId;
205             this.nodeId = nodeId;
206         }
207
208         @Override
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);
213             } else {
214                 LOG.error("Group update with id {} failed for node {} with error: {}", groupId, nodeId,
215                         result.getErrors().toString());
216             }
217         }
218
219         @Override
220         public void onFailure(Throwable throwable) {
221             LOG.error("Service call for updating group {} failed for node {}", groupId, nodeId, throwable);
222         }
223     }
224
225     private final class BundleRemoveGroupCallBack implements FutureCallback<RpcResult<AddBundleMessagesOutput>> {
226         private final Uint32 groupId;
227         private final String nodeId;
228
229         private BundleRemoveGroupCallBack(final Uint32 groupId, final String nodeId) {
230             this.groupId = groupId;
231             this.nodeId = nodeId;
232         }
233
234         @Override
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);
239             } else {
240                 LOG.error("Group remove with id {} failed for node {} with error {}", groupId, nodeId,
241                         result.getErrors().toString());
242             }
243         }
244
245         @Override
246         public void onFailure(Throwable throwable) {
247             LOG.error("Service call for removing group {} failed for node {} with error", groupId, nodeId, throwable);
248         }
249     }
250 }