Merge "Cleanup MeterMessageSerializer"
[openflowplugin.git] / samples / sample-bundles / src / main / java / org / opendaylight / openflowplugin / samples / sample / bundles / SampleFlowCapableNodeListener.java
1 /*
2  * Copyright (c) 2017 Pantheon Technologies s.r.o. 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.samples.sample.bundles;
9
10 import java.util.ArrayList;
11 import java.util.Collection;
12 import java.util.List;
13 import java.util.concurrent.CompletableFuture;
14 import java.util.concurrent.ExecutionException;
15 import java.util.concurrent.ExecutorService;
16 import java.util.concurrent.Executors;
17 import java.util.concurrent.Future;
18 import org.opendaylight.mdsal.binding.api.ClusteredDataTreeChangeListener;
19 import org.opendaylight.mdsal.binding.api.DataBroker;
20 import org.opendaylight.mdsal.binding.api.DataObjectModification.ModificationType;
21 import org.opendaylight.mdsal.binding.api.DataTreeIdentifier;
22 import org.opendaylight.mdsal.binding.api.DataTreeModification;
23 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
24 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Prefix;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.GroupActionCaseBuilder;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.PopVlanActionCaseBuilder;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetFieldCaseBuilder;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.group.action._case.GroupActionBuilder;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.pop.vlan.action._case.PopVlanActionBuilder;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.set.field._case.SetFieldBuilder;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.ActionBuilder;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.ActionKey;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowBuilder;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.FlowCookie;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.InstructionsBuilder;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.ApplyActionsCaseBuilder;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.apply.actions._case.ApplyActionsBuilder;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.InstructionBuilder;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.InstructionKey;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.BucketId;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.Group;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupId;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupTypes;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.BucketsBuilder;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.buckets.BucketBuilder;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.GroupBuilder;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.EtherType;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.ethernet.match.fields.EthernetTypeBuilder;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.EthernetMatchBuilder;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv4MatchBuilder;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.onf.bundle.service.rev170124.AddBundleMessagesInput;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.onf.bundle.service.rev170124.AddBundleMessagesInputBuilder;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.onf.bundle.service.rev170124.AddBundleMessagesOutput;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.onf.bundle.service.rev170124.ControlBundleInput;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.onf.bundle.service.rev170124.ControlBundleInputBuilder;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.onf.bundle.service.rev170124.ControlBundleOutput;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.onf.bundle.service.rev170124.SalBundleService;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.onf.bundle.service.rev170124.add.bundle.messages.input.Messages;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.onf.bundle.service.rev170124.add.bundle.messages.input.MessagesBuilder;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.onf.bundle.service.rev170124.add.bundle.messages.input.messages.Message;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.onf.bundle.service.rev170124.add.bundle.messages.input.messages.MessageBuilder;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.onf.bundle.service.rev170124.bundle.inner.message.grouping.bundle.inner.message.BundleAddFlowCaseBuilder;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.onf.bundle.service.rev170124.bundle.inner.message.grouping.bundle.inner.message.BundleAddGroupCaseBuilder;
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.onf.bundle.service.rev170124.bundle.inner.message.grouping.bundle.inner.message.bundle.add.flow._case.AddFlowCaseDataBuilder;
72 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;
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.onf.rev170124.BundleControlType;
74 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.onf.rev170124.BundleFlags;
75 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.onf.rev170124.BundleId;
76 import org.opendaylight.yangtools.concepts.ListenerRegistration;
77 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
78 import org.opendaylight.yangtools.yang.binding.util.BindingMap;
79 import org.opendaylight.yangtools.yang.common.RpcResult;
80 import org.opendaylight.yangtools.yang.common.Uint16;
81 import org.opendaylight.yangtools.yang.common.Uint32;
82 import org.opendaylight.yangtools.yang.common.Uint64;
83 import org.opendaylight.yangtools.yang.common.Uint8;
84 import org.slf4j.Logger;
85 import org.slf4j.LoggerFactory;
86
87 /**
88  * Sample DataTreeChangeListener.
89  */
90 public class SampleFlowCapableNodeListener implements ClusteredDataTreeChangeListener<FlowCapableNode>, AutoCloseable {
91
92     private static final Logger LOG = LoggerFactory.getLogger(SampleFlowCapableNodeListener.class);
93
94     private static final BundleId BUNDLE_ID = new BundleId(Uint32.ONE);
95     private static final BundleFlags BUNDLE_FLAGS = new BundleFlags(true, true);
96     private static final ExecutorService EXECUTOR = Executors.newSingleThreadExecutor();
97
98     private final DataBroker dataBroker;
99     private final SalBundleService bundleService;
100     private ListenerRegistration<?> listenerReg;
101
102     public SampleFlowCapableNodeListener(final DataBroker dataBroker, final SalBundleService bundleService) {
103         this.dataBroker = dataBroker;
104         this.bundleService = bundleService;
105     }
106
107     @Override
108     public void close() {
109         LOG.debug("close() passing");
110         if (listenerReg != null) {
111             listenerReg.close();
112         }
113     }
114
115     public void init() {
116         LOG.debug("inSessionInitialized() passing");
117
118         final InstanceIdentifier<FlowCapableNode> path = InstanceIdentifier.create(Nodes.class).child(Node.class)
119                 .augmentation(FlowCapableNode.class);
120         final DataTreeIdentifier<FlowCapableNode> identifier =
121                 DataTreeIdentifier.create(LogicalDatastoreType.OPERATIONAL, path);
122
123         listenerReg = dataBroker.registerDataTreeChangeListener(identifier, SampleFlowCapableNodeListener.this);
124     }
125
126     @Override
127     public void onDataTreeChanged(final Collection<DataTreeModification<FlowCapableNode>> modifications) {
128         for (DataTreeModification<FlowCapableNode> modification : modifications) {
129             if (modification.getRootNode().getModificationType() == ModificationType.WRITE) {
130                 LOG.info("Node connected:  {}",
131                         modification.getRootPath().getRootIdentifier().firstIdentifierOf(Node.class));
132
133                 final NodeRef nodeRef =
134                         new NodeRef(modification.getRootPath().getRootIdentifier().firstIdentifierOf(Node.class));
135
136                 final ControlBundleInput openBundleInput = new ControlBundleInputBuilder()
137                         .setNode(nodeRef)
138                         .setBundleId(BUNDLE_ID)
139                         .setFlags(BUNDLE_FLAGS)
140                         .setType(BundleControlType.ONFBCTOPENREQUEST)
141                         .build();
142
143                 final ControlBundleInput commitBundleInput = new ControlBundleInputBuilder()
144                         .setNode(nodeRef)
145                         .setBundleId(BUNDLE_ID)
146                         .setFlags(BUNDLE_FLAGS)
147                         .setType(BundleControlType.ONFBCTCOMMITREQUEST)
148                         .build();
149
150                 final List<Message> innerMessages = createMessages(nodeRef);
151                 final Messages messages = new MessagesBuilder().setMessage(innerMessages).build();
152                 final AddBundleMessagesInput addBundleMessagesInput = new AddBundleMessagesInputBuilder()
153                         .setNode(nodeRef)
154                         .setBundleId(BUNDLE_ID)
155                         .setFlags(BUNDLE_FLAGS)
156                         .setMessages(messages)
157                         .build();
158
159                 makeCompletableFuture(bundleService.controlBundle(openBundleInput))
160                     .thenComposeAsync(voidRpcResult -> {
161                         LOG.debug("Open successful: {}, msg: {}", voidRpcResult.isSuccessful(),
162                                 voidRpcResult.getErrors());
163
164                         final CompletableFuture<RpcResult<AddBundleMessagesOutput>> addFuture =
165                                 makeCompletableFuture(bundleService.addBundleMessages(addBundleMessagesInput));
166
167                         return addFuture;
168                     }).thenComposeAsync(voidRpcResult -> {
169                         LOG.debug("AddBundleMessages successful: {}, msg: {}", voidRpcResult.isSuccessful(),
170                                 voidRpcResult.getErrors());
171
172                         final CompletableFuture<RpcResult<ControlBundleOutput>> controlCommitFuture =
173                                 makeCompletableFuture(bundleService.controlBundle(commitBundleInput));
174
175                         return controlCommitFuture;
176                     }).thenAccept(voidRpcResult -> LOG.debug("Commit successful: {}, msg: {}",
177                         voidRpcResult.isSuccessful(), voidRpcResult.getErrors()));
178             }
179         }
180     }
181
182     private static <T> CompletableFuture<T> makeCompletableFuture(final Future<T> future) {
183         return CompletableFuture.supplyAsync(() -> {
184             try {
185                 return future.get();
186             } catch (InterruptedException | ExecutionException e) {
187                 throw new RuntimeException(e);
188             }
189         }, EXECUTOR);
190     }
191
192     private static List<Message> createMessages(final NodeRef nodeRef) {
193         List<Message> messages  = new ArrayList<>();
194
195
196         messages.add(new MessageBuilder()
197             .setNode(nodeRef)
198             .setBundleInnerMessage(new BundleAddGroupCaseBuilder()
199                 .setAddGroupCaseData(new AddGroupCaseDataBuilder(createGroup(Uint32.ONE)).build()).build())
200             .build());
201
202         messages.add(new MessageBuilder()
203             .setNode(nodeRef)
204             .setBundleInnerMessage(new BundleAddFlowCaseBuilder()
205                 .setAddFlowCaseData(new AddFlowCaseDataBuilder(createFlow("42", Uint32.ONE, Uint16.ONE, Uint8.ONE))
206                     .build())
207                 .build())
208             .build());
209
210         messages.add(new MessageBuilder()
211             .setNode(nodeRef)
212             .setBundleInnerMessage(new BundleAddFlowCaseBuilder()
213                 .setAddFlowCaseData(new AddFlowCaseDataBuilder(createFlow("43", Uint32.ONE, Uint16.TWO, Uint8.TWO))
214                     .build())
215                 .build())
216             .build());
217
218         LOG.debug("createMessages() passing {}", messages);
219
220         return messages;
221     }
222
223     private static Flow createFlow(final String flowId, final Uint32 groupId, final Uint16 priority,
224             final Uint8 tableId) {
225         return new FlowBuilder()
226             .setId(new FlowId(flowId))
227             .setTableId(tableId)
228             .setMatch(new MatchBuilder()
229                 .setEthernetMatch(new EthernetMatchBuilder()
230                     .setEthernetType(new EthernetTypeBuilder()
231                         .setType(new EtherType(Uint32.valueOf(2048)))
232                         .build())
233                     .build())
234                 .build())
235             .setInstructions(createGroupInstructions(groupId).build())
236             .setPriority(priority)
237             .setCookie(new FlowCookie(Uint64.valueOf(flowId + "" + priority)))
238             .setHardTimeout(Uint16.ZERO)
239             .setIdleTimeout(Uint16.ZERO)
240             .setStrict(false)
241             .setContainerName(null)
242             .setFlowName("FlowWithGroupInstruction")
243             .build();
244     }
245
246     private static Group createGroup(final Uint32 groupId) {
247         return new GroupBuilder()
248             .setGroupId(new GroupId(groupId))
249             .setBarrier(false)
250             .setGroupName("Foo")
251             .setContainerName(null)
252             .setGroupType(GroupTypes.GroupAll)
253             .setBuckets(createBuckets().build())
254             .build();
255     }
256
257     private static BucketsBuilder createBuckets() {
258         return new BucketsBuilder()
259             .setBucket(BindingMap.ordered(new BucketBuilder()
260                 .setBucketId(new BucketId(Uint32.valueOf(12)))
261                 .setAction(BindingMap.of(new ActionBuilder()
262                     .setOrder(0)
263                     .setAction(new PopVlanActionCaseBuilder()
264                         .setPopVlanAction(new PopVlanActionBuilder().build())
265                         .build())
266                     .build()))
267                 .build(), new BucketBuilder()
268                 .setBucketId(new BucketId(Uint32.valueOf(13)))
269                 .setAction(BindingMap.of(new ActionBuilder()
270                     .setAction(new SetFieldCaseBuilder()
271                         .setSetField(new SetFieldBuilder()
272                             .setLayer3Match(new Ipv4MatchBuilder().setIpv4Source(new Ipv4Prefix("10.0.1.0/32")).build())
273                             .build())
274                         .build())
275                     .setOrder(0)
276                     .build(), new ActionBuilder()
277                     .setOrder(0)
278                     .setAction(new SetFieldCaseBuilder()
279                         .setSetField(new SetFieldBuilder()
280                             .setLayer3Match(new Ipv4MatchBuilder()
281                                 .setIpv4Destination(new Ipv4Prefix("10.0.10.0/32"))
282                                 .build())
283                             .build())
284                         .build())
285                     .build()))
286                 .build()));
287     }
288
289     private static InstructionsBuilder createGroupInstructions(final Uint32 groupId) {
290         return new InstructionsBuilder()
291             .setInstruction(BindingMap.of(new InstructionBuilder()
292                 .setInstruction(new ApplyActionsCaseBuilder()
293                     .setApplyActions(new ApplyActionsBuilder()
294                         .setAction(BindingMap.of(new ActionBuilder()
295                             .setAction(new GroupActionCaseBuilder()
296                                 .setGroupAction(new GroupActionBuilder().setGroupId(groupId).build())
297                                 .build())
298                             .setOrder(1)
299                             .withKey(new ActionKey(0))
300                             .build()))
301                         .build())
302                     .build())
303                 .withKey(new InstructionKey(0))
304                 .build()));
305     }
306 }