6d5d506d82534504806a7e85b0530723d5be202b
[honeycomb.git] / v3po / v3po2vpp / src / main / java / io / fd / honeycomb / translate / v3po / interfaces / acl / common / PortPair.java
1 /*
2  * Copyright (c) 2016 Cisco and/or its affiliates.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at:
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 package io.fd.honeycomb.translate.v3po.interfaces.acl.common;
18
19 import java.util.ArrayList;
20 import java.util.List;
21 import java.util.Objects;
22 import java.util.function.BiFunction;
23 import javax.annotation.Nullable;
24 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.PortNumber;
25 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.packet.fields.rev160708.acl.transport.header.fields.DestinationPortRange;
26 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.packet.fields.rev160708.acl.transport.header.fields.SourcePortRange;
27
28 /**
29  * Utility that produces cartesian product out of src and dst port ranges (used to translate ranges into
30  * list of classify sessions).
31  */
32 final class PortPair {
33     private final Integer src;
34     private final Integer dst;
35
36     PortPair(@Nullable final Integer src, @Nullable final Integer dst) {
37         this.src = src;
38         this.dst = dst;
39     }
40
41     Integer getSrc() {
42         return src;
43     }
44
45     Integer getDst() {
46         return dst;
47     }
48
49     @Override
50     public String toString() {
51         return "(" + src + "," + dst + ")";
52     }
53
54     @Override
55     public boolean equals(final Object o) {
56         if (this == o) {
57             return true;
58         }
59         if (o == null || getClass() != o.getClass()) {
60             return false;
61         }
62
63         final PortPair that = (PortPair) o;
64         if (!Objects.equals(src, that.src)) {
65             return false;
66         }
67         if (!Objects.equals(dst, that.dst)) {
68             return false;
69         }
70         return true;
71     }
72
73     @Override
74     public int hashCode() {
75         return Objects.hash(src, dst);
76     }
77
78     static List<PortPair> fromRange(final SourcePortRange srcRange,
79                                     final DestinationPortRange dstRange) {
80         final List<PortPair> result = new ArrayList<>();
81         if (srcRange == null && dstRange == null) {
82             result.add(new PortPair(null, null));
83         } else if (srcRange != null && dstRange == null) {
84             processSingleRange(result, srcRange.getLowerPort(), srcRange.getUpperPort(), PortPair::new);
85         } else if (srcRange == null && dstRange != null) {
86             processSingleRange(result, dstRange.getLowerPort(), dstRange.getUpperPort(),
87                 (dst, src) -> new PortPair(src, dst));
88         } else {
89             processDoubleRange(result, srcRange, dstRange);
90         }
91         return result;
92     }
93
94     private static void processSingleRange(final List<PortPair> result,
95                                            final PortNumber lowerPort,
96                                            final PortNumber upperPort,
97                                            final BiFunction<Integer, Integer, PortPair> f) {
98         int low = lowerPort.getValue(); // mandatory
99         int hi = low;
100         if (upperPort != null) {
101             hi = upperPort.getValue();
102         }
103         for (; low <= hi; ++low) {
104             result.add(f.apply(low, null));
105         }
106     }
107
108     private static void processDoubleRange(final List<PortPair> result, final SourcePortRange srcRange,
109                                            final DestinationPortRange dstRange) {
110         int srcL = srcRange.getLowerPort().getValue();
111         int srcH = srcL;
112         if (srcRange.getUpperPort() != null) {
113             srcH = srcRange.getUpperPort().getValue();
114         }
115         int dstL = dstRange.getLowerPort().getValue();
116         int dstH = dstL;
117         if (dstRange.getUpperPort() != null) {
118             dstH = dstRange.getUpperPort().getValue();
119         }
120         for (int i=srcL; i <= srcH; ++i) {
121             for (int j=dstL; j <= dstH; ++j) {
122                 result.add(new PortPair(i, j));
123             }
124         }
125     }
126 }