Policy exclusions & parallel netconf transactions
[groupbasedpolicy.git] / renderers / vpp / src / main / java / org / opendaylight / groupbasedpolicy / renderer / vpp / policy / PolicyContext.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
9 package org.opendaylight.groupbasedpolicy.renderer.vpp.policy;
10
11 import java.util.Collections;
12 import java.util.List;
13 import java.util.Map;
14 import java.util.Objects;
15 import java.util.Optional;
16 import java.util.TreeSet;
17 import java.util.function.Supplier;
18 import java.util.stream.Collectors;
19
20 import javax.annotation.Nonnull;
21
22 import org.opendaylight.groupbasedpolicy.renderer.vpp.util.KeyFactory;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoints.address.endpoints.AddressEndpointKey;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.TenantId;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.RendererPolicy;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.Configuration;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.endpoints.AddressEndpointWithLocation;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.RendererEndpoint;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.RendererEndpointKey;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.renderer.endpoint.PeerEndpointKey;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.forwarding.renderer.forwarding.by.tenant.RendererForwardingContext;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.forwarding.renderer.forwarding.by.tenant.RendererForwardingContextKey;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.forwarding.renderer.forwarding.by.tenant.RendererNetworkDomain;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.forwarding.renderer.forwarding.by.tenant.RendererNetworkDomainKey;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.rule.groups.RuleGroup;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.rule.groups.RuleGroupKey;
37
38 import com.google.common.base.Preconditions;
39 import com.google.common.collect.HashMultimap;
40 import com.google.common.collect.ImmutableMap;
41 import com.google.common.collect.ImmutableSetMultimap;
42 import com.google.common.collect.ImmutableSortedSet;
43 import com.google.common.collect.ImmutableTable;
44 import com.google.common.collect.ImmutableTable.Builder;
45 import com.google.common.collect.Maps;
46 import com.google.common.collect.SetMultimap;
47
48 public class PolicyContext {
49
50     private final RendererPolicy policy;
51     private final ImmutableTable<RendererEndpointKey, PeerEndpointKey, ImmutableSortedSet<RendererResolvedPolicy>> policyTable;
52     private final ImmutableMap<RuleGroupKey, ResolvedRuleGroup> ruleGroupByKey;
53     private final ImmutableMap<AddressEndpointKey, AddressEndpointWithLocation> addrEpByKey;
54     private final ImmutableTable<TenantId, RendererForwardingContextKey, RendererForwardingContext> forwardingCtxTable;
55     private final ImmutableTable<TenantId, RendererNetworkDomainKey, RendererNetworkDomain> networkDomainTable;
56     private final ImmutableSetMultimap<RuleGroupKey, RendererEndpointKey> endpointsByRuleGroups;
57
58     public PolicyContext(@Nonnull RendererPolicy policy) {
59         this.policy = Preconditions.checkNotNull(policy);
60         Optional<Configuration> optConfig = resolveValidConfig(policy);
61         if (optConfig.isPresent()) {
62             Configuration config = optConfig.get();
63             this.ruleGroupByKey = resolveRuleGroups(config);
64             List<RendererEndpoint> rendererEps = resolveRendererEndpoints(config);
65             SetMultimap<RuleGroupKey, RendererEndpointKey> epsByRules = HashMultimap.create();
66             this.policyTable = resolvePolicy(rendererEps, ruleGroupByKey, epsByRules);
67             this.endpointsByRuleGroups = ImmutableSetMultimap.<RuleGroupKey, RendererEndpointKey>copyOf(epsByRules);
68             addrEpByKey = resolveAddrEpWithLoc(config);
69             this.forwardingCtxTable = resolveForwardingCtxTable(config);
70             this.networkDomainTable = resolveNetworkDomainTable(config);
71         } else {
72             this.ruleGroupByKey = ImmutableMap.of();
73             this.policyTable = ImmutableTable.of();
74             this.addrEpByKey = ImmutableMap.of();
75             this.forwardingCtxTable = ImmutableTable.of();
76             this.networkDomainTable = ImmutableTable.of();
77             this.endpointsByRuleGroups = ImmutableSetMultimap.<RuleGroupKey, RendererEndpointKey>of();
78         }
79     }
80
81     private static List<RendererEndpoint> resolveRendererEndpoints(Configuration config) {
82         if (config.getRendererEndpoints() == null) {
83             return Collections.emptyList();
84         }
85         List<RendererEndpoint> rendererEndpoints = config.getRendererEndpoints().getRendererEndpoint();
86         if (rendererEndpoints == null) {
87             return Collections.emptyList();
88         }
89         return rendererEndpoints;
90     }
91
92     private static ImmutableTable<RendererEndpointKey, PeerEndpointKey, ImmutableSortedSet<RendererResolvedPolicy>> resolvePolicy(
93             List<RendererEndpoint> rendererEps, Map<RuleGroupKey, ResolvedRuleGroup> ruleGroupInfoByRuleGroupKey, SetMultimap<RuleGroupKey, RendererEndpointKey> epsByRules) {
94         Builder<RendererEndpointKey, PeerEndpointKey, ImmutableSortedSet<RendererResolvedPolicy>> resultBuilder =
95                 new Builder<>();
96         Supplier<TreeSet<RendererResolvedPolicy>> rendererPolicySupplier = () -> new TreeSet<>();
97         rendererEps.stream().forEach(rEp -> {
98             rEp.getPeerEndpoint()
99                 .stream()
100                 .filter(Objects::nonNull)
101                 .filter(peer -> peer.getRuleGroupWithRendererEndpointParticipation() != null)
102                 .forEach(peer -> {
103                 ImmutableSortedSet<RendererResolvedPolicy> rPolicy =
104                         peer.getRuleGroupWithRendererEndpointParticipation()
105                             .stream()
106                             .map(ruleGroup -> new RendererResolvedPolicy(ruleGroup.getRendererEndpointParticipation(),
107                                     ruleGroupInfoByRuleGroupKey.get(KeyFactory.ruleGroupKey(ruleGroup.getKey()))))
108                             .collect(Collectors.collectingAndThen(Collectors.toCollection(rendererPolicySupplier),
109                                     ImmutableSortedSet::copyOfSorted));
110                 peer.getRuleGroupWithRendererEndpointParticipation()
111                     .forEach(ruleGroup -> epsByRules.put(KeyFactory.ruleGroupKey(ruleGroup.getKey()), rEp.getKey()));
112                 resultBuilder.put(rEp.getKey(), KeyFactory.peerEndpointKey(peer.getKey()),
113                         ImmutableSortedSet.copyOfSorted(rPolicy));
114             });
115         });
116         return resultBuilder.build();
117     }
118
119     private static ImmutableMap<RuleGroupKey, ResolvedRuleGroup> resolveRuleGroups(Configuration config) {
120         return config.getRuleGroups().getRuleGroup().stream().collect(Collectors
121             .collectingAndThen(Collectors.toMap(RuleGroup::getKey, ResolvedRuleGroup::new), ImmutableMap::copyOf));
122     }
123
124     private static ImmutableTable<TenantId, RendererForwardingContextKey, RendererForwardingContext> resolveForwardingCtxTable(
125             Configuration config) {
126         Builder<TenantId, RendererForwardingContextKey, RendererForwardingContext> resultBuilder = new Builder<>();
127         Optional.ofNullable(config.getRendererForwarding()).map(x -> x.getRendererForwardingByTenant()).ifPresent(x -> {
128             x.forEach(fwdByTenant -> {
129                 Optional.ofNullable(fwdByTenant.getRendererForwardingContext()).ifPresent(fwdCtxs -> {
130                     fwdCtxs.forEach(fwdCtx -> {
131                         resultBuilder.put(fwdByTenant.getTenantId(), fwdCtx.getKey(), fwdCtx);
132                     });
133                 });
134             });
135         });
136         return resultBuilder.build();
137     }
138
139     private static ImmutableTable<TenantId, RendererNetworkDomainKey, RendererNetworkDomain> resolveNetworkDomainTable(
140             Configuration config) {
141         Builder<TenantId, RendererNetworkDomainKey, RendererNetworkDomain> resultBuilder = new Builder<>();
142         Optional.ofNullable(config.getRendererForwarding()).map(x -> x.getRendererForwardingByTenant()).ifPresent(x -> {
143             x.forEach(fwdByTenant -> {
144                 Optional.ofNullable(fwdByTenant.getRendererNetworkDomain()).ifPresent(netDomains -> {
145                     netDomains.forEach(netDomain -> {
146                         resultBuilder.put(fwdByTenant.getTenantId(), netDomain.getKey(), netDomain);
147                     });
148                 });
149             });
150         });
151         return resultBuilder.build();
152     }
153
154     private static ImmutableMap<AddressEndpointKey, AddressEndpointWithLocation> resolveAddrEpWithLoc(
155             Configuration config) {
156         return Maps.uniqueIndex(config.getEndpoints().getAddressEndpointWithLocation(),
157                 new com.google.common.base.Function<AddressEndpointWithLocation, AddressEndpointKey>() {
158
159                     @Override
160                     public AddressEndpointKey apply(AddressEndpointWithLocation input) {
161                         return new AddressEndpointKey(input.getAddress(), input.getAddressType(), input.getContextId(),
162                                 input.getContextType());
163                     }
164                 });
165     }
166
167     private static Optional<Configuration> resolveValidConfig(RendererPolicy policy) {
168         Configuration config = policy.getConfiguration();
169         if (config == null) {
170             return Optional.empty();
171         }
172         if (config.getRendererEndpoints() == null) {
173             return Optional.empty();
174         }
175         return Optional.of(config);
176     }
177
178     public @Nonnull RendererPolicy getPolicy() {
179         return policy;
180     }
181
182     public @Nonnull ImmutableTable<RendererEndpointKey, PeerEndpointKey, ImmutableSortedSet<RendererResolvedPolicy>> getPolicyTable() {
183         return policyTable;
184     }
185
186     public @Nonnull ImmutableMap<RuleGroupKey, ResolvedRuleGroup> getRuleGroupByKey() {
187         return ruleGroupByKey;
188     }
189
190     public @Nonnull ImmutableMap<AddressEndpointKey, AddressEndpointWithLocation> getAddrEpByKey() {
191         return addrEpByKey;
192     }
193
194     public @Nonnull ImmutableTable<TenantId, RendererForwardingContextKey, RendererForwardingContext> getForwardingCtxTable() {
195         return forwardingCtxTable;
196     }
197
198     public @Nonnull ImmutableTable<TenantId, RendererNetworkDomainKey, RendererNetworkDomain> getNetworkDomainTable() {
199         return networkDomainTable;
200     }
201
202     public @Nonnull ImmutableSetMultimap<RuleGroupKey, RendererEndpointKey> getEndpointsByRuleGroups() {
203         return endpointsByRuleGroups;
204     }
205
206     @Override
207     public String toString() {
208         return "PolicyContext [policyTable=" + policyTable + ", ruleGroupByKey=" + ruleGroupByKey + ", addrEpByKey="
209                 + addrEpByKey + ", forwardingCtxTable=" + forwardingCtxTable + ", networkDomainTable="
210                 + networkDomainTable + "]";
211     }
212
213 }