2ab1a0583b9ac9b2dba9cb08c843438feeeac90e
[controller.git] / opendaylight / forwardingrulesmanager / src / main / java / org / opendaylight / controller / forwardingrulesmanager / FlowEntry.java
1
2 /*
3  * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
4  *
5  * This program and the accompanying materials are made available under the
6  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
7  * and is available at http://www.eclipse.org/legal/epl-v10.html
8  */
9
10 package org.opendaylight.controller.forwardingrulesmanager;
11
12 import java.io.Serializable;
13 import java.util.Date;
14
15 import org.apache.commons.lang3.builder.EqualsBuilder;
16 import org.apache.commons.lang3.builder.HashCodeBuilder;
17 import org.opendaylight.controller.sal.core.ContainerFlow;
18 import org.opendaylight.controller.sal.core.Node;
19 import org.opendaylight.controller.sal.flowprogrammer.Flow;
20 import org.opendaylight.controller.sal.match.Match;
21
22 /**
23  * Represents a flow applications request Forwarding Rules Manager to install
24  * on a network node. A FlowEntry is constituted of a flow (match + actions),
25  * the target network node, and the flow name. It also includes a group name. 
26  * For instance the flows constituting a policy all share the same group name.
27  */
28 public class FlowEntry implements Cloneable, Serializable {
29     private static final long serialVersionUID = 1L;
30     private String groupName; // group name
31     private String flowName; // flow name (may be null)
32     private Node node; // network node where to install the flow
33     private Flow flow; // match + action
34
35     public FlowEntry(String groupName, String flowName, Flow flow, Node node) {
36         this.groupName = groupName;
37         this.flow = flow;
38         this.node = node;
39         this.flowName = (flowName != null) ? flowName : constructFlowName();
40     }
41
42     public String getGroupName() {
43         return groupName;
44     }
45
46     public void setGroupName(String name) {
47         this.groupName = name;
48     }
49
50     /**
51      * Return the actual Flow contained in this entry
52      *
53      * @return the flow
54      */
55     public Flow getFlow() {
56         return flow;
57     }
58
59     public Node getNode() {
60         return node;
61     }
62
63     public void setNode(Node n) {
64         this.node = n;
65     }
66
67     public String getFlowName() {
68         return flowName;
69     }
70
71     public void setFlowName(String n) {
72         this.flowName = n;
73     }
74
75     @Override
76     public FlowEntry clone() {
77         FlowEntry cloned = null;
78         try {
79             cloned = (FlowEntry) super.clone();
80             cloned.flow = this.flow.clone();
81         } catch (CloneNotSupportedException e) {
82             e.printStackTrace();
83         }
84         return cloned;
85     }
86
87     @Override
88     public int hashCode() {
89         return HashCodeBuilder.reflectionHashCode(this);
90     }
91
92     @Override
93     public boolean equals(Object obj) {
94         return EqualsBuilder.reflectionEquals(this, obj);
95     }
96
97     @Override
98     public String toString() {
99         return "FlowEntry[flowName = " + flowName + ", groupName = "
100                 + groupName + ",node = " + node + ", flow = " + flow + "]";
101     }
102
103     private String constructFlowName() {
104         return this.groupName + "_" + new Date().toString();
105     }
106
107     public boolean equalsByNodeAndName(Node node, String flowName) {
108         return this.node.equals(node) && this.flowName.equals(flowName);
109     }
110
111     /**
112      * Merges the current Flow with the passed Container Flow
113      *
114      * Note: Container Flow merging is not an injective function.
115      * Be m1 and m2 two different matches, and be f() the flow merge
116      * function, such that y1 = f(m1) and y2 = f(m2) are the two merged
117      * matches, we may have: y1 = y2
118      *
119      *
120      * @param containerFlow
121      * @return this merged FlowEntry
122      */
123     public FlowEntry mergeWith(ContainerFlow containerFlow) {
124         Match myMatch = flow.getMatch();
125
126         // Based on this flow direction, rearrange the match
127         Match match = containerFlow.getMatch();
128
129         // Merge
130         myMatch.mergeWithFilter(match);
131
132         // Replace this Flow's match with merged version
133         flow.setMatch(myMatch);
134
135         return this;
136     }
137 }