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