0cc4294c5d4fa5c2a719abf94bf1adcb3ab93f4f
[netvirt.git] / sfc / classifier / impl / src / main / java / org / opendaylight / netvirt / sfc / classifier / service / domain / ClassifierEntry.java
1 /*
2  * Copyright (c) 2017 Ericsson 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.netvirt.sfc.classifier.service.domain;
10
11 import com.google.common.base.MoreObjects;
12 import java.util.Objects;
13 import javax.annotation.Nullable;
14 import org.opendaylight.netvirt.sfc.classifier.service.domain.api.ClassifierEntryRenderer;
15 import org.opendaylight.netvirt.sfc.classifier.service.domain.api.ClassifierRenderableEntry;
16 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160218.access.lists.acl.access.list.entries.ace.Matches;
17 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey;
18 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
19
20 /**
21  * A generic {@link ClassifierRenderableEntry} implementation that supports all
22  * the different render types.
23  */
24 public final class ClassifierEntry implements ClassifierRenderableEntry {
25
26     private enum EntryType {
27         NODE_ENTRY_TYPE,
28         INGRESS_INTERFACE_ENTRY_TYPE,
29         PATH_ENTRY_TYPE,
30         MATCH_ENTRY_TYPE,
31         EGRESS_INTERFACE_ENTRY_TYPE
32     }
33
34     private final EntryType entryType;
35     // TODO skitt Rework using a class hierarchy so we can enforce null constraints
36     private final @Nullable NodeId node;
37     private final @Nullable InterfaceKey interfaceKey;
38     private final @Nullable String connector;
39     private final @Nullable Matches matches;
40     private final @Nullable Long nsp;
41     private final @Nullable Short nsi;
42     private final @Nullable Short nsl;
43     private final @Nullable String destinationIp;
44     private final @Nullable String firstHopIp;
45
46     private ClassifierEntry(EntryType entryType, @Nullable NodeId node, @Nullable InterfaceKey interfaceKey,
47                             @Nullable String connector, @Nullable Matches matches, @Nullable Long nsp,
48                             @Nullable Short nsi, @Nullable Short nsl, @Nullable String destinationIp,
49                             @Nullable String firstHopIp) {
50         this.entryType = entryType;
51         this.node = node;
52         this.interfaceKey = interfaceKey;
53         this.connector = connector;
54         this.matches = matches;
55         this.nsp = nsp;
56         this.nsi = nsi;
57         this.nsl = nsl;
58         this.destinationIp = destinationIp;
59         this.firstHopIp = firstHopIp;
60     }
61
62     @Override
63     public int hashCode() {
64         return Objects.hash(
65                 entryType,
66                 node,
67                 interfaceKey,
68                 connector,
69                 matches,
70                 nsp,
71                 nsi,
72                 nsl,
73                 destinationIp,
74                 firstHopIp);
75     }
76
77     @Override
78     public boolean equals(Object obj) {
79         if (this == obj) {
80             return true;
81         }
82         if (obj == null) {
83             return false;
84         }
85         if (!ClassifierEntry.class.equals(obj.getClass())) {
86             return false;
87         }
88         ClassifierEntry other = (ClassifierEntry) obj;
89         return Objects.equals(entryType, other.entryType)
90                 && Objects.equals(node, other.node)
91                 && Objects.equals(interfaceKey, other.interfaceKey)
92                 && Objects.equals(connector, other.connector)
93                 && Objects.equals(matches, other.matches)
94                 && Objects.equals(nsp, other.nsp)
95                 && Objects.equals(nsi, other.nsi)
96                 && Objects.equals(destinationIp, other.destinationIp)
97                 && Objects.equals(nsl, other.nsl)
98                 && Objects.equals(firstHopIp, other.firstHopIp);
99     }
100
101     @Override
102     public String toString() {
103         return MoreObjects.toStringHelper(this)
104                 .add("entryType", entryType)
105                 .add("node", node)
106                 .add("interfaceKey", interfaceKey)
107                 .add("connector", connector)
108                 .add("matches", matches)
109                 .add("nsp", nsp)
110                 .add("nsi", nsi)
111                 .add("nsl", nsl)
112                 .add("destinationIp", destinationIp)
113                 .add("firstHopIp", firstHopIp)
114                 .toString();
115     }
116
117     @Override
118     public void render(ClassifierEntryRenderer classifierEntryRenderer) {
119         switch (entryType) {
120             case NODE_ENTRY_TYPE:
121                 classifierEntryRenderer.renderNode(node);
122                 break;
123             case INGRESS_INTERFACE_ENTRY_TYPE:
124                 classifierEntryRenderer.renderIngress(interfaceKey);
125                 break;
126             case PATH_ENTRY_TYPE:
127                 classifierEntryRenderer.renderPath(node, nsp, nsi, nsl, firstHopIp);
128                 break;
129             case MATCH_ENTRY_TYPE:
130                 classifierEntryRenderer.renderMatch(node, connector, matches, nsp, nsi);
131                 break;
132             case EGRESS_INTERFACE_ENTRY_TYPE:
133                 classifierEntryRenderer.renderEgress(interfaceKey, destinationIp);
134                 break;
135             default:
136         }
137     }
138
139     @Override
140     public void suppress(ClassifierEntryRenderer classifierEntryRenderer) {
141         switch (entryType) {
142             case NODE_ENTRY_TYPE:
143                 classifierEntryRenderer.suppressNode(node);
144                 break;
145             case INGRESS_INTERFACE_ENTRY_TYPE:
146                 classifierEntryRenderer.suppressIngress(interfaceKey);
147                 break;
148             case PATH_ENTRY_TYPE:
149                 classifierEntryRenderer.suppressPath(node, nsp, nsi, nsl, firstHopIp);
150                 break;
151             case MATCH_ENTRY_TYPE:
152                 classifierEntryRenderer.suppressMatch(node, connector, matches, nsp, nsi);
153                 break;
154             case EGRESS_INTERFACE_ENTRY_TYPE:
155                 classifierEntryRenderer.suppressEgress(interfaceKey, destinationIp);
156                 break;
157             default:
158         }
159     }
160
161     /**
162      * Build a {@code ClassifierEntry} supporting an ingress render type.
163      *
164      * @param interfaceKey the ingress interface.
165      * @return the {@code ClassifierEntry}.
166      */
167     public static ClassifierEntry buildIngressEntry(InterfaceKey interfaceKey) {
168         return new ClassifierEntry(
169                 EntryType.INGRESS_INTERFACE_ENTRY_TYPE,
170                 null,
171                 interfaceKey,
172                 null,
173                 null,
174                 null,
175                 null,
176                 null,
177                 null,
178                 null);
179     }
180
181     /**
182      * Build a {@code ClassifierEntry} supporting an node render type.
183      *
184      * @param node the classifier node identifier.
185      * @return the {@code ClassifierEntry}.
186      */
187     public static ClassifierEntry buildNodeEntry(NodeId node) {
188         return new ClassifierEntry(
189                 EntryType.NODE_ENTRY_TYPE,
190                 node,
191                 null,
192                 null,
193                 null,
194                 null,
195                 null,
196                 null,
197                 null,
198                 null);
199     }
200
201     /**
202      * Build a {@code ClassifierEntry} supporting a path render type.
203      *
204      * @param node the classifier node identifier.
205      * @param nsp the path identifier.
206      * @param nsi the path starting index.
207      * @param nsl the path length.
208      * @param firstHopIp the first SFF ip address. Null if the SFF is nodeId.
209      * @return the {@code ClassifierEntry}.
210      */
211     public static ClassifierEntry buildPathEntry(NodeId node, Long nsp, short nsi, short nsl,
212                                                  @Nullable String firstHopIp) {
213         return new ClassifierEntry(
214                 EntryType.PATH_ENTRY_TYPE,
215                 node,
216                 null,
217                 null,
218                 null,
219                 nsp,
220                 nsi,
221                 nsl,
222                 null,
223                 firstHopIp);
224     }
225
226     /**
227      * Build a {@code ClassifierEntry} supporting an match render type.
228      *
229      * @param node the classifier node identifier.
230      * @param connector the node connector for the ingress interface.
231      * @param matches the ACL matches.
232      * @param nsp the path identifier.
233      * @param nsi the initial path index.
234      * @return the {@code ClassifierEntry}.
235      */
236     public static ClassifierEntry buildMatchEntry(NodeId node, String connector, Matches matches, Long nsp, Short nsi) {
237         return new ClassifierEntry(
238                 EntryType.MATCH_ENTRY_TYPE,
239                 node,
240                 null,
241                 connector,
242                 matches,
243                 nsp,
244                 nsi,
245                 null,
246                 null,
247                 null);
248     }
249
250     /**
251      * Build a {@code ClassifierEntry} supporting a remote egress render type.
252      *
253      * @param interfaceKey the egress interface key.
254      * @param destinationIp the destination IP address associated to the
255      *                      interface. If the interface is a local interface,
256      *                      this should be a node local IP address, otherwise
257      *                      the remote IP address.
258      * @return the {@code ClassifierEntry}.
259      */
260     public static ClassifierEntry buildEgressEntry(InterfaceKey interfaceKey, String destinationIp) {
261         return new ClassifierEntry(
262                 EntryType.EGRESS_INTERFACE_ENTRY_TYPE,
263                 null,
264                 interfaceKey,
265                 null,
266                 null,
267                 null,
268                 null,
269                 null,
270                 destinationIp,
271                 null);
272     }
273 }