aaf34a6a3f1fc857fa6d1df72c6e149e6e21e361
[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 import org.slf4j.Logger;
22 import org.slf4j.LoggerFactory;
23
24 /**
25  * Represents a flow applications request Forwarding Rules Manager to install
26  * on a network node. A FlowEntry is constituted of a flow (match + actions),
27  * the target network node, and the flow name. It also includes a group name. 
28  * For instance the flows constituting a policy all share the same group name.
29  */
30 public class FlowEntry implements Cloneable, Serializable {
31     protected static final Logger logger = LoggerFactory
32     .getLogger(FlowEntry.class);
33     private static final long serialVersionUID = 1L;
34     private static final Logger log = LoggerFactory.getLogger(FlowEntry.class);
35     private String groupName; // group name
36     private String flowName; // flow name (may be null)
37     private Node node; // network node where to install the flow
38     private Flow flow; // match + action
39
40     public FlowEntry(String groupName, String flowName, Flow flow, Node node) {
41         this.groupName = groupName;
42         this.flow = flow;
43         this.node = node;
44         this.flowName = (flowName != null) ? flowName : constructFlowName();
45     }
46
47     public String getGroupName() {
48         return groupName;
49     }
50
51     public void setGroupName(String name) {
52         this.groupName = name;
53     }
54
55     /**
56      * Return the actual Flow contained in this entry
57      *
58      * @return the flow
59      */
60     public Flow getFlow() {
61         return flow;
62     }
63
64     public Node getNode() {
65         return node;
66     }
67
68     public void setNode(Node n) {
69         this.node = n;
70     }
71
72     public String getFlowName() {
73         return flowName;
74     }
75
76     public void setFlowName(String n) {
77         this.flowName = n;
78     }
79
80     @Override
81     public FlowEntry clone() {
82         FlowEntry cloned = null;
83         try {
84             cloned = (FlowEntry) super.clone();
85             cloned.flow = this.flow.clone();
86         } catch (CloneNotSupportedException e) {
87            log.warn("exception in clone", e);
88         }
89         return cloned;
90     }
91
92     @Override
93     public int hashCode() {
94         return HashCodeBuilder.reflectionHashCode(this);
95     }
96
97     @Override
98     public boolean equals(Object obj) {
99         return EqualsBuilder.reflectionEquals(this, obj);
100     }
101
102     @Override
103     public String toString() {
104         return "FlowEntry[flowName = " + flowName + ", groupName = "
105                 + groupName + ",node = " + node + ", flow = " + flow + "]";
106     }
107
108     private String constructFlowName() {
109         return this.groupName + "_" + new Date().toString();
110     }
111
112     public boolean equalsByNodeAndName(Node node, String flowName) {
113         return this.node.equals(node) && this.flowName.equals(flowName);
114     }
115
116     /**
117      * Merges the current Flow with the passed Container Flow
118      *
119      * Note: Container Flow merging is not an injective function.
120      * Be m1 and m2 two different matches, and be f() the flow merge
121      * function, such that y1 = f(m1) and y2 = f(m2) are the two merged
122      * matches, we may have: y1 = y2
123      *
124      *
125      * @param containerFlow
126      * @return this merged FlowEntry
127      */
128     public FlowEntry mergeWith(ContainerFlow containerFlow) {
129         Match myMatch = flow.getMatch();
130
131         // Based on this flow direction, rearrange the match
132         Match match = containerFlow.getMatch();
133
134         // Merge
135         myMatch.mergeWithFilter(match);
136
137         // Replace this Flow's match with merged version
138         flow.setMatch(myMatch);
139
140         return this;
141     }
142 }