Merge "Revert "Revert "BUG-1425: Integrated new Binding to Normalized Node codec...
[controller.git] / opendaylight / md-sal / forwardingrules-manager / src / main / java / org / opendaylight / controller / frm / flow / FlowChangeListener.java
1 /**
2  * Copyright (c) 2014 Cisco Systems, Inc. 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.controller.frm.flow;
9
10 import java.math.BigInteger;
11
12 import org.opendaylight.controller.frm.AbstractChangeListener;
13 import org.opendaylight.controller.frm.FlowCookieProducer;
14 import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
15 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri;
16 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.Table;
17 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
18 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.AddFlowInputBuilder;
19 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.FlowTableRef;
20 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.RemoveFlowInputBuilder;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.UpdateFlowInputBuilder;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.flow.update.OriginalFlowBuilder;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.flow.update.UpdatedFlowBuilder;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.FlowCookie;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.FlowRef;
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.yangtools.yang.binding.DataObject;
29 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
30 import org.slf4j.Logger;
31 import org.slf4j.LoggerFactory;
32
33 import com.google.common.base.Preconditions;
34
35 /**
36  * Flow Change Listener
37  *  add, update and remove {@link Flow} processing from {@link org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent}.
38  *
39  * @author <a href="mailto:vdemcak@cisco.com">Vaclav Demcak</a>
40  *
41  */
42 public class FlowChangeListener extends AbstractChangeListener {
43
44     private static final Logger LOG = LoggerFactory.getLogger(FlowChangeListener.class);
45
46     private final FlowProvider provider;
47
48     public FlowChangeListener (final FlowProvider provider) {
49         this.provider = Preconditions.checkNotNull(provider, "FlowProvider can not be null !");
50     }
51
52     @Override
53     protected void remove(final InstanceIdentifier<? extends DataObject> identifier,
54                           final DataObject removeDataObj) {
55
56         final Flow flow = ((Flow) removeDataObj);
57         final InstanceIdentifier<Table> tableIdent = identifier.firstIdentifierOf(Table.class);
58         final InstanceIdentifier<Node> nodeIdent = identifier.firstIdentifierOf(Node.class);
59         final RemoveFlowInputBuilder builder = new RemoveFlowInputBuilder(flow);
60
61         // use empty cookie mask in order to delete flow even with generated cookie
62         builder.setCookieMask(new FlowCookie(BigInteger.ZERO));
63
64         builder.setFlowRef(new FlowRef(identifier));
65         builder.setNode(new NodeRef(nodeIdent));
66         builder.setFlowTable(new FlowTableRef(tableIdent));
67
68         Uri uri = new Uri(this.getTransactionId());
69         builder.setTransactionUri(uri);
70         this.provider.getSalFlowService().removeFlow(builder.build());
71         LOG.debug("Transaction {} - Removed Flow has removed flow: {}", new Object[]{uri, removeDataObj});
72     }
73
74     @Override
75     protected void update(final InstanceIdentifier<? extends DataObject> identifier,
76                           final DataObject original, final DataObject update) {
77
78         final Flow originalFlow = ((Flow) original);
79         final Flow updatedFlow = ((Flow) update);
80         final InstanceIdentifier<Node> nodeIdent = identifier.firstIdentifierOf(Node.class);
81         final UpdateFlowInputBuilder builder = new UpdateFlowInputBuilder();
82
83         builder.setNode(new NodeRef(nodeIdent));
84         builder.setFlowRef(new FlowRef(identifier));
85
86         Uri uri = new Uri(this.getTransactionId());
87         builder.setTransactionUri(uri);
88
89         builder.setUpdatedFlow((new UpdatedFlowBuilder(updatedFlow)).build());
90         builder.setOriginalFlow((new OriginalFlowBuilder(originalFlow)).build());
91
92         this.provider.getSalFlowService().updateFlow(builder.build());
93         LOG.debug("Transaction {} - Update Flow has updated flow {} with {}", new Object[]{uri, original, update});
94     }
95
96     @Override
97     protected void add(final InstanceIdentifier<? extends DataObject> identifier,
98                        final DataObject addDataObj) {
99
100         final Flow flow = ((Flow) addDataObj);
101         final InstanceIdentifier<Table> tableIdent = identifier.firstIdentifierOf(Table.class);
102         final NodeRef nodeRef = new NodeRef(identifier.firstIdentifierOf(Node.class));
103         final FlowCookie flowCookie = new FlowCookie(FlowCookieProducer.INSTANCE.getNewCookie(tableIdent));
104         final AddFlowInputBuilder builder = new AddFlowInputBuilder(flow);
105
106         builder.setNode(nodeRef);
107         builder.setFlowRef(new FlowRef(identifier));
108         builder.setFlowTable(new FlowTableRef(tableIdent));
109         builder.setCookie( flowCookie );
110
111         Uri uri = new Uri(this.getTransactionId());
112         builder.setTransactionUri(uri);
113         this.provider.getSalFlowService().addFlow(builder.build());
114         LOG.debug("Transaction {} - Add Flow has added flow: {}", new Object[]{uri, addDataObj});
115     }
116
117     @Override
118     protected boolean preconditionForChange(final InstanceIdentifier<? extends DataObject> identifier,
119             final DataObject dataObj, final DataObject update) {
120
121         final ReadOnlyTransaction trans = this.provider.getDataService().newReadOnlyTransaction();
122         return update != null
123                 ? (dataObj instanceof Flow && update instanceof Flow && isNodeAvailable(identifier, trans))
124                 : (dataObj instanceof Flow && isNodeAvailable(identifier, trans));
125     }
126 }