Bug 4988: OF statistics & REST client
[groupbasedpolicy.git] / renderers / ofoverlay / src / main / java / org / opendaylight / groupbasedpolicy / renderer / ofoverlay / statistics / flowcache / FlowCacheFactory.java
1 /*
2  * Copyright (c) 2016 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.groupbasedpolicy.renderer.ofoverlay.statistics.flowcache;
9
10 import java.util.List;
11
12 import org.opendaylight.groupbasedpolicy.api.sf.EtherTypeClassifierDefinition;
13 import org.opendaylight.groupbasedpolicy.api.sf.IpProtoClassifierDefinition;
14 import org.opendaylight.groupbasedpolicy.api.sf.L4ClassifierDefinition;
15 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils;
16 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.statistics.flowcache.FlowCache.FlowCacheBuilder;
17 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.statistics.flowcache.FlowCacheDefinition.FlowCacheDefinitionBuilder;
18 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.statistics.util.FlowCacheCons;
19 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.statistics.util.IidSflowNameUtil;
20 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.instance.ParameterValue;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.resolved.policy.rev150828.has.classifiers.Classifier;
22 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
23 import org.slf4j.Logger;
24 import org.slf4j.LoggerFactory;
25
26 public class FlowCacheFactory {
27
28     private static final Logger LOG = LoggerFactory.getLogger(FlowCacheFactory.class);
29
30     public static FlowCache createFlowCache(InstanceIdentifier<Classifier> classifierIid, Classifier classifier,
31             FlowCacheCons.Value value) {
32         FlowCacheDefinition flowCacheDefinition = creteFlowCacheDefinition(classifier, value);
33         if (flowCacheDefinition == null) {
34             LOG.info("Cannot create flow cache for statistics of classifier {}\n{}", classifierIid, classifier);
35             return null;
36         }
37         return new FlowCacheBuilder().setDefinition(flowCacheDefinition)
38             .setName(IidSflowNameUtil.createFlowCacheName(classifierIid, value))
39             .setDirection(classifier.getDirection())
40             .build();
41     }
42
43     public static FlowCacheDefinition creteFlowCacheDefinition(Classifier classifier, FlowCacheCons.Value value) {
44         FlowCacheDefinitionBuilder fcdBuilder = new FlowCacheDefinitionBuilder();
45         if (L4ClassifierDefinition.ID.equals(classifier.getClassifierDefinitionId())) {
46             addEthTypeInfoToFlowCache(classifier, fcdBuilder);
47             if (!addIpProtoInfoToFlowCache(classifier, fcdBuilder)) {
48                 return null;
49             }
50             if (!addL4InfoToFlowCache(classifier, fcdBuilder)) {
51                 return null;
52             }
53         } else if (IpProtoClassifierDefinition.ID.equals(classifier.getClassifierDefinitionId())) {
54             addEthTypeInfoToFlowCache(classifier, fcdBuilder);
55             if (!addIpProtoInfoToFlowCache(classifier, fcdBuilder)) {
56                 return null;
57             }
58         } else if (EtherTypeClassifierDefinition.ID.equals(classifier.getClassifierDefinitionId())) {
59             addEthTypeInfoToFlowCache(classifier, fcdBuilder);
60         } else {
61             LOG.warn("Sflow stats will not be pulled because of unknown classifier: {}", classifier);
62             return null;
63         }
64         fcdBuilder.getKeysBuilder().addValue(FlowCacheCons.Key.IP_SOURCE.get()).addValue(FlowCacheCons.Key.IP_DESTINATION.get());
65         fcdBuilder.setValue(value.get());
66         return fcdBuilder.build();
67     }
68
69     private static void addEthTypeInfoToFlowCache(Classifier classifier, FlowCacheDefinitionBuilder fcdBuilder) {
70         List<ParameterValue> parametersAndValues = classifier.getParameterValue();
71         ParameterValue ethTypeParam = getParamVal(parametersAndValues, EtherTypeClassifierDefinition.ETHERTYPE_PARAM);
72         if (ethTypeParam != null) {
73             fcdBuilder.getKeysBuilder().addValue(FlowCacheCons.Key.ETH_PROTOCOL.get());
74             fcdBuilder.getFilterBuilder()
75                 .addValue(FlowCacheCons.Key.ETH_PROTOCOL.get() + FlowCacheCons.EQ + ethTypeParam.getIntValue());
76         } else {
77             fcdBuilder.getKeysBuilder().addValue(FlowCacheCons.Key.ETH_PROTOCOL.get());
78             fcdBuilder.getFilterBuilder()
79                 .addValue(FlowCacheCons.Key.ETH_PROTOCOL.get() + FlowCacheCons.EQ + FlowUtils.IPv4 + FlowCacheCons.OR
80                         + FlowCacheCons.Key.ETH_PROTOCOL.get() + FlowCacheCons.EQ + FlowUtils.IPv6);
81         }
82     }
83
84     private static boolean addIpProtoInfoToFlowCache(Classifier classifier, FlowCacheDefinitionBuilder fcdBuilder) {
85         List<ParameterValue> parametersAndValues = classifier.getParameterValue();
86         ParameterValue ipProtoParam = getParamVal(parametersAndValues, IpProtoClassifierDefinition.PROTO_PARAM);
87         if (ipProtoParam != null) {
88             fcdBuilder.getKeysBuilder().addValue(FlowCacheCons.Key.IP_PROTOCOL.get());
89             fcdBuilder.getFilterBuilder()
90                 .addValue(FlowCacheCons.Key.IP_PROTOCOL.get() + FlowCacheCons.EQ + ipProtoParam.getIntValue());
91             return true;
92         } else {
93             LOG.trace("Cannot add ip-proto information to flow cache for Sflow-RT.");
94             return false;
95         }
96     }
97
98     private static boolean addL4InfoToFlowCache(Classifier classifier, FlowCacheDefinitionBuilder fcdBuilder) {
99         List<ParameterValue> parametersAndValues = classifier.getParameterValue();
100         ParameterValue ipProtoParam = getParamVal(parametersAndValues, IpProtoClassifierDefinition.PROTO_PARAM);
101         ParameterValue dstPortParam = getParamVal(parametersAndValues, L4ClassifierDefinition.DST_PORT_PARAM);
102         ParameterValue srcPortParam = getParamVal(parametersAndValues, L4ClassifierDefinition.SRC_PORT_PARAM);
103         if (ipProtoParam == null || (dstPortParam == null && srcPortParam == null)) {
104             LOG.trace(
105                     "Cannot add L4 information to flow cache for Sflow-RT."
106                             + "\nipProtoParam:{} dstPortParam:{} srcPortParam:{}",
107                     ipProtoParam, dstPortParam, srcPortParam);
108             return false;
109         }
110         if (dstPortParam != null) {
111             if (!addTcpUdpPortKeys(ipProtoParam.getIntValue(), dstPortParam.getIntValue(), true, fcdBuilder)) {
112                 return false;
113             }
114         }
115         if (srcPortParam != null) {
116             if (!addTcpUdpPortKeys(ipProtoParam.getIntValue(), srcPortParam.getIntValue(), false, fcdBuilder)) {
117                 return false;
118             }
119         }
120         return true;
121     }
122
123     private static ParameterValue getParamVal(List<ParameterValue> parametersAndValues, String paramName) {
124         for (ParameterValue paramVal : parametersAndValues) {
125             if (paramName.equals(paramVal.getName().getValue())) {
126                 return paramVal;
127             }
128         }
129         return null;
130     }
131
132     private static boolean addTcpUdpPortKeys(Long ipProto, Long port, boolean isDstPort,
133             FlowCacheDefinitionBuilder fcdBuilder) {
134         if (isDstPort) {
135             if (ipProto == IpProtoClassifierDefinition.TCP_VALUE) {
136                 fcdBuilder.getKeysBuilder().addValue(FlowCacheCons.Key.TCP_DST_PORT.get());
137                 fcdBuilder.getFilterBuilder().addValue(FlowCacheCons.Key.TCP_DST_PORT.get() + FlowCacheCons.EQ + port);
138             } else if (ipProto == IpProtoClassifierDefinition.UDP_VALUE) {
139                 fcdBuilder.getKeysBuilder().addValue(FlowCacheCons.Key.UDP_DST_PORT.get());
140                 fcdBuilder.getFilterBuilder().addValue(FlowCacheCons.Key.UDP_DST_PORT.get() + FlowCacheCons.EQ + port);
141             } else {
142                 LOG.info("Statistics cannot be collected for ip-proto {} and port {}", ipProto, port);
143                 return false;
144             }
145         } else {
146             if (ipProto == IpProtoClassifierDefinition.TCP_VALUE) {
147                 fcdBuilder.getKeysBuilder().addValue(FlowCacheCons.Key.TCP_SRC_PORT.get());
148                 fcdBuilder.getFilterBuilder().addValue(FlowCacheCons.Key.TCP_SRC_PORT.get() + FlowCacheCons.EQ + port);
149             } else if (ipProto == IpProtoClassifierDefinition.UDP_VALUE) {
150                 fcdBuilder.getKeysBuilder().addValue(FlowCacheCons.Key.UDP_SRC_PORT.get());
151                 fcdBuilder.getFilterBuilder().addValue(FlowCacheCons.Key.UDP_SRC_PORT.get() + FlowCacheCons.EQ + port);
152             } else {
153                 LOG.info("Statistics cannot be collected for ip-proto {} and port {}", ipProto, port);
154                 return false;
155             }
156         }
157         return true;
158     }
159 }