Separating renderers into features.
[groupbasedpolicy.git] / renderers / ofoverlay / src / test / java / org / opendaylight / groupbasedpolicy / renderer / ofoverlay / flow / PolicyEnforcerTest.java
1 /*
2  * Copyright (c) 2014 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.groupbasedpolicy.renderer.ofoverlay.flow;
10
11 import java.util.Collections;
12 import java.util.HashMap;
13 import java.util.List;
14 import java.util.Objects;
15
16 import org.junit.Before;
17 import org.junit.Test;
18 import org.mockito.ArgumentCaptor;
19 import org.mockito.Matchers;
20 import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
21 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
22 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowTable.FlowCtx;
23 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.RegMatch;
24 import org.opendaylight.groupbasedpolicy.resolver.ConditionGroup;
25 import org.opendaylight.groupbasedpolicy.resolver.EgKey;
26 import org.opendaylight.groupbasedpolicy.resolver.PolicyInfo;
27 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
28 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address;
29 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ClauseName;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ConditionMatcherName;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ConditionName;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.SubjectName;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.Endpoint;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.ofoverlay.rev140528.OfOverlayNodeConfigBuilder;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.HasDirection.Direction;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.Matcher.MatchType;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.condition.matchers.ConditionMatcherBuilder;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.conditions.Condition;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.conditions.ConditionBuilder;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.TenantBuilder;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.ContractBuilder;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.contract.ClauseBuilder;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.contract.clause.ConsumerMatchersBuilder;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.contract.clause.ProviderMatchersBuilder;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._4.match.TcpMatch;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg0;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg1;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg2;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg3;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg7;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.GeneralAugMatchNodesNodeTableFlow;
56 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
57 import org.slf4j.Logger;
58 import org.slf4j.LoggerFactory;
59
60 import com.google.common.collect.ImmutableList;
61
62 import static org.junit.Assert.*;
63
64 import static org.mockito.Matchers.*;
65
66 import static org.mockito.Mockito.*;
67
68 import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.*;
69
70 public class PolicyEnforcerTest extends FlowTableTest {
71     protected static final Logger LOG = 
72             LoggerFactory.getLogger(PolicyEnforcerTest.class);
73
74     @Before
75     public void setup() throws Exception {
76         initCtx();
77         table = new PolicyEnforcer(ctx);
78         super.setup();
79         
80         switchManager.addSwitch(nodeId, tunnelId, 
81                                 Collections.<NodeConnectorId>emptySet(),
82                                 new OfOverlayNodeConfigBuilder()
83                                     .setTunnelIp(new IpAddress(new Ipv4Address("1.2.3.4")))
84                                     .build());
85     }
86
87     @Test
88     public void testNoEps() throws Exception {
89         ReadWriteTransaction t = dosync(null);
90         verify(t, times(2)).put(any(LogicalDatastoreType.class), 
91                                 Matchers.<InstanceIdentifier<Flow>>any(), 
92                                 any(Flow.class), anyBoolean());
93     }
94     
95     @Test
96     public void testSameEg() throws Exception {
97         Endpoint ep1 = localEP().build();
98         endpointManager.addEndpoint(ep1);
99         Endpoint ep2 = localEP()
100             .setMacAddress(new MacAddress("00:00:00:00:00:02"))
101             .build();
102         endpointManager.addEndpoint(ep2);
103         policyResolver.addTenant(baseTenant().build());
104         
105         ReadWriteTransaction t = dosync(null);
106         ArgumentCaptor<Flow> ac = ArgumentCaptor.forClass(Flow.class);
107         verify(t, atLeastOnce()).put(eq(LogicalDatastoreType.CONFIGURATION), 
108                                      Matchers.<InstanceIdentifier<Flow>>any(),
109                                      ac.capture(), anyBoolean());
110         int count = 0;
111         HashMap<String, FlowCtx> flowMap = new HashMap<>();
112         for (Flow f : ac.getAllValues()) {
113             flowMap.put(f.getId().getValue(), new FlowCtx(f));
114             if (f.getId().getValue().indexOf("intraallow") == 0)
115                 count += 1;
116         }
117         assertEquals(1, count);
118
119         t = dosync(flowMap);
120         verify(t, never()).put(any(LogicalDatastoreType.class), 
121                                Matchers.<InstanceIdentifier<Flow>>any(), 
122                                any(Flow.class), anyBoolean());
123     }
124
125     @Test
126     public void testDifferentEg() throws Exception {
127         doTestDifferentEg(null);
128         doTestDifferentEg(Direction.Bidirectional);
129         doTestDifferentEg(Direction.In);
130         doTestDifferentEg(Direction.Out);
131     }
132     
133     public void doTestDifferentEg(Direction direction) throws Exception {
134         Endpoint ep1 = localEP().build();
135         endpointManager.addEndpoint(ep1);
136         Endpoint ep2 = localEP()
137             .setMacAddress(new MacAddress("00:00:00:00:00:02"))
138             .setEndpointGroup(eg2)
139             .build();
140         endpointManager.addEndpoint(ep2);
141         policyResolver.addTenant(baseTenant(direction).build());
142         
143         ReadWriteTransaction t = dosync(null);
144         ArgumentCaptor<Flow> ac = ArgumentCaptor.forClass(Flow.class);
145         verify(t, atLeastOnce()).put(eq(LogicalDatastoreType.CONFIGURATION), 
146                                      Matchers.<InstanceIdentifier<Flow>>any(),
147                                      ac.capture(), anyBoolean());
148         int count = 0;
149         HashMap<String, FlowCtx> flowMap = new HashMap<>();
150         for (Flow f : ac.getAllValues()) {
151             flowMap.put(f.getId().getValue(), new FlowCtx(f));
152             if (f.getId().getValue().indexOf("intraallow") == 0) {
153                 count += 1;
154             } else if (f.getMatch() != null &&
155                        Objects.equals(tunnelId, f.getMatch().getInPort())) {
156                 assertEquals(instructions(applyActionIns(nxOutputRegAction(NxmNxReg7.class))),
157                              f.getInstructions());
158                 count += 1;
159             } else if (f.getMatch() != null &&
160                        f.getMatch().getEthernetMatch() != null &&
161                        Objects.equals(FlowUtils.IPv4,
162                                       f.getMatch().getEthernetMatch()
163                                           .getEthernetType().getType().getValue()) &&
164                        f.getMatch().getIpMatch() != null &&
165                        Objects.equals(Short.valueOf((short)6),
166                                       f.getMatch().getIpMatch().getIpProtocol()) &&
167                        Objects.equals(Integer.valueOf(80),
168                                       ((TcpMatch)f.getMatch().getLayer4Match())
169                                           .getTcpDestinationPort().getValue())) {
170                 count += 1;
171             } else if (f.getMatch() != null &&
172                        f.getMatch().getEthernetMatch() != null &&
173                        Objects.equals(FlowUtils.IPv6,
174                                       f.getMatch().getEthernetMatch()
175                                           .getEthernetType().getType().getValue()) &&
176                        f.getMatch().getIpMatch() != null &&
177                        Objects.equals(Short.valueOf((short)6),
178                                       f.getMatch().getIpMatch().getIpProtocol()) &&
179                        Objects.equals(Integer.valueOf(80),
180                                       ((TcpMatch)f.getMatch().getLayer4Match())
181                                           .getTcpDestinationPort().getValue())) {
182                 count += 1;
183             } 
184         }
185         if (direction == null || direction.equals(Direction.Bidirectional))
186             assertEquals(7, count);
187         else
188             assertEquals(5, count);
189
190         t = dosync(flowMap);
191         verify(t, never()).put(any(LogicalDatastoreType.class), 
192                                Matchers.<InstanceIdentifier<Flow>>any(), 
193                                any(Flow.class), anyBoolean());
194     }
195
196     @Test
197     public void testConditions() throws Exception {
198         Condition cond1 = new ConditionBuilder()
199             .setName(new ConditionName("cond1"))
200             .build();
201         Condition cond2 = new ConditionBuilder()
202             .setName(new ConditionName("cond2"))
203             .build();
204
205         Endpoint ep1 = localEP()
206             .setCondition(ImmutableList.of(cond1.getName()))
207             .build();
208         endpointManager.addEndpoint(ep1);
209         Endpoint ep2 = localEP()
210             .setMacAddress(new MacAddress("00:00:00:00:00:02"))
211             .setCondition(ImmutableList.of(cond1.getName(), cond2.getName()))
212             .setEndpointGroup(eg2)
213             .build();
214         endpointManager.addEndpoint(ep2);        
215         
216         TenantBuilder tb = baseTenant()
217             .setContract(ImmutableList.of(new ContractBuilder()
218                 .setId(cid)
219                 .setSubject(ImmutableList.of(baseSubject(Direction.Out).build()))
220                 .setClause(ImmutableList.of(new ClauseBuilder()
221                     .setName(new ClauseName("test"))
222                     .setSubjectRefs(ImmutableList.of(new SubjectName("s1")))
223                     .setConsumerMatchers(new ConsumerMatchersBuilder()
224                         .setConditionMatcher(ImmutableList.of(new ConditionMatcherBuilder()
225                             .setName(new ConditionMatcherName("m1"))
226                             .setCondition(ImmutableList.of(cond1, cond2))
227                             .setMatchType(MatchType.Any)
228                             .build()))
229                         .build())
230                     .setProviderMatchers(new ProviderMatchersBuilder()
231                         .setConditionMatcher(ImmutableList.of(new ConditionMatcherBuilder()
232                             .setName(new ConditionMatcherName("m2"))
233                             .setCondition(ImmutableList.of(cond1, cond2))
234                             .setMatchType(MatchType.All)
235                             .build()))
236                         .build())
237                     .build()))
238                 .build()));
239         policyResolver.addTenant(tb.build());
240
241         PolicyInfo policy = policyResolver.getCurrentPolicy();
242         List<ConditionName> ep1c = endpointManager.getCondsForEndpoint(ep1);
243         ConditionGroup cg1 = 
244                 policy.getEgCondGroup(new EgKey(tb.getId(), 
245                                                 ep1.getEndpointGroup()),
246                                       ep1c);
247         List<ConditionName> ep2c = endpointManager.getCondsForEndpoint(ep2);
248         ConditionGroup cg2 = 
249                 policy.getEgCondGroup(new EgKey(tb.getId(), 
250                                                 ep2.getEndpointGroup()),
251                                       ep2c);
252         int cg1Id = policyManager.getCondGroupOrdinal(cg1);
253         int cg2Id = policyManager.getCondGroupOrdinal(cg2);
254         int eg1Id = policyManager.getContextOrdinal(ep1.getTenant(),
255                                                     ep1.getEndpointGroup());
256         int eg2Id = policyManager.getContextOrdinal(ep1.getTenant(),
257                                                     ep2.getEndpointGroup());
258
259         assertNotEquals(cg1Id, cg2Id);
260
261         MatchBuilder mb = new MatchBuilder();
262         FlowUtils.addNxRegMatch(mb, 
263                                 RegMatch.of(NxmNxReg0.class, Long.valueOf(eg1Id)),
264                                 RegMatch.of(NxmNxReg1.class, Long.valueOf(cg1Id)),
265                                 RegMatch.of(NxmNxReg2.class, Long.valueOf(eg2Id)),
266                                 RegMatch.of(NxmNxReg3.class, Long.valueOf(cg2Id)));
267         GeneralAugMatchNodesNodeTableFlow m1 =
268                 mb.getAugmentation(GeneralAugMatchNodesNodeTableFlow.class);
269         FlowUtils.addNxRegMatch(mb, 
270                                 RegMatch.of(NxmNxReg0.class, Long.valueOf(eg2Id)),
271                                 RegMatch.of(NxmNxReg1.class, Long.valueOf(cg2Id)),
272                                 RegMatch.of(NxmNxReg2.class, Long.valueOf(eg1Id)),
273                                 RegMatch.of(NxmNxReg3.class, Long.valueOf(cg1Id)));
274         GeneralAugMatchNodesNodeTableFlow m2 =
275                 mb.getAugmentation(GeneralAugMatchNodesNodeTableFlow.class);
276
277         ReadWriteTransaction t = dosync(null);
278         ArgumentCaptor<Flow> ac = ArgumentCaptor.forClass(Flow.class);
279         verify(t, atLeastOnce()).put(eq(LogicalDatastoreType.CONFIGURATION), 
280                                      Matchers.<InstanceIdentifier<Flow>>any(),
281                                      ac.capture(), anyBoolean());
282         int count = 0;
283         HashMap<String, FlowCtx> flowMap = new HashMap<>();
284         for (Flow f : ac.getAllValues()) {
285             flowMap.put(f.getId().getValue(), new FlowCtx(f));
286             if (f.getMatch() != null &&
287                 f.getMatch().getEthernetMatch() != null) {
288                 GeneralAugMatchNodesNodeTableFlow fm =
289                         f.getMatch().getAugmentation(GeneralAugMatchNodesNodeTableFlow.class);
290                 assertTrue(Objects.equals(fm, m1) ||
291                            Objects.equals(fm, m2));
292                 count += 1;
293             }
294         }
295         assertEquals(2, count);
296
297         t = dosync(flowMap);
298         verify(t, never()).put(any(LogicalDatastoreType.class), 
299                                Matchers.<InstanceIdentifier<Flow>>any(), 
300                                any(Flow.class), anyBoolean());
301     }
302 }