Add INFO.yaml for GBP
[groupbasedpolicy.git] / groupbasedpolicy / src / main / java / org / opendaylight / groupbasedpolicy / renderer / RendererConfigurationBuilder.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;
10
11 import com.google.common.base.Function;
12 import com.google.common.base.Optional;
13 import com.google.common.base.Preconditions;
14 import com.google.common.collect.FluentIterable;
15 import com.google.common.collect.HashBasedTable;
16 import com.google.common.collect.ImmutableSet;
17 import com.google.common.collect.ImmutableTable;
18 import com.google.common.collect.Table;
19
20 import java.util.ArrayList;
21 import java.util.Collections;
22 import java.util.HashMap;
23 import java.util.HashSet;
24 import java.util.List;
25 import java.util.Map;
26 import java.util.Map.Entry;
27 import java.util.Set;
28
29 import javax.annotation.Nonnull;
30 import javax.annotation.Nullable;
31
32 import org.opendaylight.groupbasedpolicy.api.EndpointAugmentor;
33 import org.opendaylight.groupbasedpolicy.api.NetworkDomainAugmentor;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.NatAddress;
35 import org.opendaylight.groupbasedpolicy.renderer.util.AddressEndpointUtils;
36 import org.opendaylight.groupbasedpolicy.renderer.util.ContainmentEndpointUtils;
37 import org.opendaylight.groupbasedpolicy.renderer.util.EndpointLocationUtils;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoint.locations.AddressEndpointLocation;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoint.locations.ContainmentEndpointLocation;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoints.address.endpoints.AddressEndpoint;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoints.address.endpoints.AddressEndpointKey;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoints.containment.endpoints.ContainmentEndpoint;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoints.containment.endpoints.ContainmentEndpointKey;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.rev160427.Forwarding;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.rev160427.forwarding.ForwardingByTenant;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.rev160427.forwarding.forwarding.by.tenant.ForwardingContext;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.rev160427.forwarding.forwarding.by.tenant.NetworkDomain;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.EndpointPolicyParticipation;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.NatAddressRenderer;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.NatAddressRendererBuilder;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.RendererName;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.has.rule.group.with.renderer.endpoint.participation.RuleGroupWithRendererEndpointParticipation;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.has.rule.group.with.renderer.endpoint.participation.RuleGroupWithRendererEndpointParticipationBuilder;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.Endpoints;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.EndpointsBuilder;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.RendererEndpoints;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.RendererEndpointsBuilder;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.RendererForwarding;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.RendererForwardingBuilder;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.RuleGroups;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.RuleGroupsBuilder;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.endpoints.AddressEndpointWithLocation;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.endpoints.AddressEndpointWithLocationBuilder;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.endpoints.ContainmentEndpointWithLocation;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.endpoints.ContainmentEndpointWithLocationBuilder;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.RendererEndpoint;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.RendererEndpointBuilder;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.RendererEndpointKey;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.renderer.endpoint.PeerEndpoint;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.renderer.endpoint.PeerEndpointBuilder;
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.renderer.endpoint.PeerEndpointKey;
72 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.renderer.endpoint.PeerExternalContainmentEndpoint;
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.renderer.endpoint.PeerExternalContainmentEndpointBuilder;
74 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.renderer.endpoint.PeerExternalContainmentEndpointKey;
75 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.renderer.endpoint.PeerExternalEndpoint;
76 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.renderer.endpoint.PeerExternalEndpointBuilder;
77 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.renderer.endpoint.PeerExternalEndpointKey;
78 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.forwarding.RendererForwardingByTenant;
79 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.forwarding.RendererForwardingByTenantBuilder;
80 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.forwarding.renderer.forwarding.by.tenant.RendererForwardingContext;
81 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.forwarding.renderer.forwarding.by.tenant.RendererForwardingContextBuilder;
82 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.forwarding.renderer.forwarding.by.tenant.RendererNetworkDomain;
83 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.forwarding.renderer.forwarding.by.tenant.RendererNetworkDomainBuilder;
84 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.rule.groups.RuleGroup;
85 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.rule.groups.RuleGroupBuilder;
86 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.resolved.policy.rev150828.resolved.policies.resolved.policy.policy.rule.group.with.endpoint.constraints.PolicyRuleGroup;
87 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.resolved.policy.rev150828.resolved.policies.resolved.policy.policy.rule.group.with.endpoint.constraints.PolicyRuleGroupKey;
88 import org.opendaylight.yangtools.yang.binding.Augmentation;
89 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
90 import org.slf4j.Logger;
91 import org.slf4j.LoggerFactory;
92
93 public class RendererConfigurationBuilder {
94
95     private static final Logger LOG = LoggerFactory.getLogger(RendererConfigurationBuilder.class);
96
97     private final Table<RendererEndpointKey, PeerEndpointKey, Set<RuleGroupWithRendererEndpointParticipation>> policiesByEpAndPeerEp =
98             HashBasedTable.create();
99     private final Table<RendererEndpointKey, PeerExternalEndpointKey, Set<RuleGroupWithRendererEndpointParticipation>> policiesByEpAndPeerExtEp =
100             HashBasedTable.create();
101     private final Table<RendererEndpointKey, PeerExternalContainmentEndpointKey, Set<RuleGroupWithRendererEndpointParticipation>> policiesByEpAndPeerExtCtxEp =
102             HashBasedTable.create();
103     private final Set<AddressEndpointKey> adrEpKeys = new HashSet<>();
104     private final Set<ContainmentEndpointKey> contEpKeys = new HashSet<>();
105     private final Set<PolicyRuleGroupKey> policyRuleGrpKeys = new HashSet<>();
106
107     public void add(RendererEndpointKey rendererEpKey, PeerEndpointKey peerEpKey, PolicyRuleGroupKey ruleGrpKey,
108             EndpointPolicyParticipation rendererEpParticipation) {
109         Set<RuleGroupWithRendererEndpointParticipation> ruleGrpWithRendererEpParticipation =
110                 policiesByEpAndPeerEp.get(rendererEpKey, peerEpKey);
111         if (ruleGrpWithRendererEpParticipation == null) {
112             ruleGrpWithRendererEpParticipation = new HashSet<>();
113             policiesByEpAndPeerEp.put(rendererEpKey, peerEpKey, ruleGrpWithRendererEpParticipation);
114             adrEpKeys.add(AddressEndpointUtils.fromRendererEpKey(rendererEpKey));
115             adrEpKeys.add(AddressEndpointUtils.fromPeerEpKey(peerEpKey));
116         }
117         policyRuleGrpKeys.add(ruleGrpKey);
118         ruleGrpWithRendererEpParticipation
119             .add(toRuleGroupWithRendererEndpointParticipation(ruleGrpKey, rendererEpParticipation));
120     }
121
122     public void add(RendererEndpointKey rendererEpKey, PeerExternalEndpointKey peerExtEpKey,
123             PolicyRuleGroupKey ruleGrpKey, EndpointPolicyParticipation rendererEpParticipation) {
124         Set<RuleGroupWithRendererEndpointParticipation> ruleGrpWithRendererEpParticipation =
125                 policiesByEpAndPeerExtEp.get(rendererEpKey, peerExtEpKey);
126         if (ruleGrpWithRendererEpParticipation == null) {
127             ruleGrpWithRendererEpParticipation = new HashSet<>();
128             policiesByEpAndPeerExtEp.put(rendererEpKey, peerExtEpKey, ruleGrpWithRendererEpParticipation);
129             adrEpKeys.add(AddressEndpointUtils.fromRendererEpKey(rendererEpKey));
130             adrEpKeys.add(AddressEndpointUtils.fromPeerExtEpKey(peerExtEpKey));
131         }
132         policyRuleGrpKeys.add(ruleGrpKey);
133         ruleGrpWithRendererEpParticipation
134             .add(toRuleGroupWithRendererEndpointParticipation(ruleGrpKey, rendererEpParticipation));
135     }
136
137     public void add(RendererEndpointKey rendererEpKey, PeerExternalContainmentEndpointKey peerExtContainmentEpKey,
138             PolicyRuleGroupKey ruleGrpKey, EndpointPolicyParticipation rendererEpParticipation) {
139         Set<RuleGroupWithRendererEndpointParticipation> ruleGrpWithRendererEpParticipation =
140                 policiesByEpAndPeerExtCtxEp.get(rendererEpKey, peerExtContainmentEpKey);
141         if (ruleGrpWithRendererEpParticipation == null) {
142             ruleGrpWithRendererEpParticipation = new HashSet<>();
143             policiesByEpAndPeerExtCtxEp.put(rendererEpKey, peerExtContainmentEpKey, ruleGrpWithRendererEpParticipation);
144             adrEpKeys.add(AddressEndpointUtils.fromRendererEpKey(rendererEpKey));
145             contEpKeys.add(ContainmentEndpointUtils.fromPeerExtContEpKey(peerExtContainmentEpKey));
146         }
147         policyRuleGrpKeys.add(ruleGrpKey);
148         ruleGrpWithRendererEpParticipation
149             .add(toRuleGroupWithRendererEndpointParticipation(ruleGrpKey, rendererEpParticipation));
150     }
151
152     public static RuleGroupWithRendererEndpointParticipation toRuleGroupWithRendererEndpointParticipation(
153             PolicyRuleGroupKey ruleGrpKey, EndpointPolicyParticipation rendererEpParticipation) {
154         return new RuleGroupWithRendererEndpointParticipationBuilder().setTenantId(ruleGrpKey.getTenantId())
155             .setContractId(ruleGrpKey.getContractId())
156             .setSubjectName(ruleGrpKey.getSubjectName())
157             .setRendererEndpointParticipation(rendererEpParticipation)
158             .build();
159     }
160
161     public ImmutableTable<RendererEndpointKey, PeerEndpointKey, Set<RuleGroupWithRendererEndpointParticipation>> getPoliciesByEpAndPeerEp() {
162         return ImmutableTable.copyOf(policiesByEpAndPeerEp);
163     }
164
165     public ImmutableTable<RendererEndpointKey, PeerExternalEndpointKey, Set<RuleGroupWithRendererEndpointParticipation>> getPoliciesByEpAndPeerExtEp() {
166         return ImmutableTable.copyOf(policiesByEpAndPeerExtEp);
167     }
168
169     public ImmutableTable<RendererEndpointKey, PeerExternalContainmentEndpointKey, Set<RuleGroupWithRendererEndpointParticipation>> getPoliciesByEpAndPeerExtConEp() {
170         return ImmutableTable.copyOf(policiesByEpAndPeerExtCtxEp);
171     }
172
173     public ImmutableSet<AddressEndpointKey> getAddressEndpointKeys() {
174         return ImmutableSet.copyOf(adrEpKeys);
175     }
176
177     public ImmutableSet<ContainmentEndpointKey> getContainmentEndpointKeys() {
178         return ImmutableSet.copyOf(contEpKeys);
179     }
180
181     public ImmutableSet<PolicyRuleGroupKey> getPolicyRuleGroupKeys() {
182         return ImmutableSet.copyOf(policyRuleGrpKeys);
183     }
184
185     public @Nonnull RendererEndpoints buildRendererEndpoints() {
186         Map<RendererEndpointKey, RendererEndpointBuilder> rendererEpBuilderByKey = new HashMap<>();
187         for (RendererEndpointKey rendererEpKey : policiesByEpAndPeerEp.rowKeySet()) {
188             RendererEndpointBuilder rendererEpBuilder =
189                     resolveRendererEndpointBuilder(rendererEpKey, rendererEpBuilderByKey);
190             List<PeerEndpoint> peerEps =
191                     toListPeerEndpoint(policiesByEpAndPeerEp.row(rendererEpKey));
192             rendererEpBuilder.setPeerEndpoint(peerEps);
193             rendererEpBuilderByKey.put(rendererEpKey, rendererEpBuilder);
194         }
195         for (RendererEndpointKey rendererEpKey : policiesByEpAndPeerExtEp.rowKeySet()) {
196             RendererEndpointBuilder rendererEpBuilder =
197                     resolveRendererEndpointBuilder(rendererEpKey, rendererEpBuilderByKey);
198             List<PeerExternalEndpoint> peerExtEps =
199                     toListPeerExternalEndpoint(policiesByEpAndPeerExtEp.row(rendererEpKey));
200             rendererEpBuilder.setPeerExternalEndpoint(peerExtEps);
201             rendererEpBuilderByKey.put(rendererEpKey, rendererEpBuilder);
202         }
203         for (RendererEndpointKey rendererEpKey : policiesByEpAndPeerExtCtxEp.rowKeySet()) {
204             RendererEndpointBuilder rendererEpBuilder =
205                     resolveRendererEndpointBuilder(rendererEpKey, rendererEpBuilderByKey);
206             List<PeerExternalContainmentEndpoint> peerExtContEps =
207                     toListPeerExternalContainmentEndpoint(policiesByEpAndPeerExtCtxEp.row(rendererEpKey));
208             rendererEpBuilder.setPeerExternalContainmentEndpoint(peerExtContEps);
209             rendererEpBuilderByKey.put(rendererEpKey, rendererEpBuilder);
210         }
211         List<RendererEndpoint> rendererEps = new ArrayList<>();
212         for (RendererEndpointBuilder builder : rendererEpBuilderByKey.values()) {
213             rendererEps.add(builder.build());
214         }
215         return new RendererEndpointsBuilder().setRendererEndpoint(rendererEps).build();
216     }
217
218     private static RendererEndpointBuilder resolveRendererEndpointBuilder(RendererEndpointKey rendererEpKey,
219             Map<RendererEndpointKey, RendererEndpointBuilder> rendererEpBuilderByKey) {
220         RendererEndpointBuilder rendererEpBuilder = rendererEpBuilderByKey.get(rendererEpKey);
221         if (rendererEpBuilder == null) {
222             rendererEpBuilder = new RendererEndpointBuilder();
223             rendererEpBuilder.setKey(rendererEpKey);
224         }
225         return rendererEpBuilder;
226     }
227
228     private static List<PeerEndpoint> toListPeerEndpoint(
229             Map<PeerEndpointKey, Set<RuleGroupWithRendererEndpointParticipation>> policiesByPeerEp) {
230         List<PeerEndpoint> peerEps = new ArrayList<>();
231         for (Entry<PeerEndpointKey, Set<RuleGroupWithRendererEndpointParticipation>> entry : policiesByPeerEp
232             .entrySet()) {
233             PeerEndpointKey peerEpKey = entry.getKey();
234             PeerEndpointKey peerEndpointKey = new PeerEndpointKey(peerEpKey.getAddress(),
235                     peerEpKey.getAddressType(), peerEpKey.getContextId(), peerEpKey.getContextType());
236             PeerEndpoint peerEndpoint =
237                     new PeerEndpointBuilder().setKey(peerEndpointKey)
238                         .setRuleGroupWithRendererEndpointParticipation(new ArrayList<>(entry.getValue()))
239                         .build();
240             peerEps.add(peerEndpoint);
241         }
242         return peerEps;
243     }
244
245     private static List<PeerExternalEndpoint> toListPeerExternalEndpoint(
246             Map<PeerExternalEndpointKey, Set<RuleGroupWithRendererEndpointParticipation>> policiesByPeerExtEp) {
247         List<PeerExternalEndpoint> peerExtEps = new ArrayList<>();
248         for (Entry<PeerExternalEndpointKey, Set<RuleGroupWithRendererEndpointParticipation>> entry : policiesByPeerExtEp
249             .entrySet()) {
250             PeerExternalEndpointKey peerEpKey = entry.getKey();
251             PeerExternalEndpointKey peerExternalEpKey =
252                     new PeerExternalEndpointKey(peerEpKey.getAddress(), peerEpKey.getAddressType(),
253                             peerEpKey.getContextId(), peerEpKey.getContextType());
254             PeerExternalEndpoint peerExternalEp =
255                     new PeerExternalEndpointBuilder().setKey(peerExternalEpKey)
256                         .setRuleGroupWithRendererEndpointParticipation(new ArrayList<>(entry.getValue()))
257                         .build();
258             peerExtEps.add(peerExternalEp);
259         }
260         return peerExtEps;
261     }
262
263     private static List<PeerExternalContainmentEndpoint> toListPeerExternalContainmentEndpoint(
264             Map<PeerExternalContainmentEndpointKey, Set<RuleGroupWithRendererEndpointParticipation>> policiesByPeerExtContEp) {
265         List<PeerExternalContainmentEndpoint> peerExtContEps = new ArrayList<>();
266         for (Entry<PeerExternalContainmentEndpointKey, Set<RuleGroupWithRendererEndpointParticipation>> entry : policiesByPeerExtContEp
267             .entrySet()) {
268             PeerExternalContainmentEndpointKey peerEpKey = entry.getKey();
269             PeerExternalContainmentEndpointKey peerExternalContEpKey =
270                     new PeerExternalContainmentEndpointKey(peerEpKey.getContextId(),
271                             peerEpKey.getContextType());
272             PeerExternalContainmentEndpoint peerExternalContEp =
273                     new PeerExternalContainmentEndpointBuilder().setKey(peerExternalContEpKey)
274                         .setRuleGroupWithRendererEndpointParticipation(new ArrayList<>(entry.getValue()))
275                         .build();
276             peerExtContEps.add(peerExternalContEp);
277         }
278         return peerExtContEps;
279     }
280
281     public Endpoints buildEndpoints(EndpointInfo epInfo, EndpointLocationInfo epLocInfo,
282                                     Map<InstanceIdentifier<?>, RendererName> rendererByNode, Set<EndpointAugmentor> augmentors) {
283         List<AddressEndpointWithLocation> epsWithLoc =
284                 resolveEpsWithLoc(getAddressEndpointKeys(), epInfo, epLocInfo, rendererByNode, augmentors);
285         List<ContainmentEndpointWithLocation> contEpsWithLoc =
286                 resolveContEpsWithLoc(getContainmentEndpointKeys(), epInfo, epLocInfo, augmentors);
287         return new EndpointsBuilder().setAddressEndpointWithLocation(epsWithLoc)
288             .setContainmentEndpointWithLocation(contEpsWithLoc)
289             .build();
290     }
291
292     private static List<AddressEndpointWithLocation> resolveEpsWithLoc(Set<AddressEndpointKey> epKeys,
293             EndpointInfo epInfo, EndpointLocationInfo epLocInfo,
294             Map<InstanceIdentifier<?>, RendererName> rendererByNode, Set<EndpointAugmentor> augmentors) {
295         List<AddressEndpointWithLocation> result = new ArrayList<>();
296         for (AddressEndpointKey epKey : epKeys) {
297             Optional<AddressEndpoint> potentialEp = epInfo.getEndpoint(epKey);
298             Preconditions.checkArgument(potentialEp.isPresent());
299             Optional<AddressEndpointLocation> potentionalEpLoc = epLocInfo.getAdressEndpointLocation(epKey);
300             Preconditions.checkArgument(potentionalEpLoc.isPresent());
301             Optional<RendererName> rendererName = resolveRendererName(potentionalEpLoc.get(), rendererByNode);
302             if (!rendererName.isPresent()) {
303                 LOG.debug("Endpoint {} has no location, skipped", epKey);
304                 continue;
305             }
306             result.add(createEpWithLoc(potentialEp.get(), potentionalEpLoc.get(), rendererName.get(), augmentors));
307         }
308         return result;
309     }
310
311     /**
312      * Renderer name can be resolved from absolute node location or any of relative node locations.
313      */
314     private static Optional<RendererName> resolveRendererName(AddressEndpointLocation epLoc,
315             Map<InstanceIdentifier<?>, RendererName> rendererByNode) {
316         Optional<InstanceIdentifier<?>> potentialAbsNodeLoc = EndpointLocationUtils.resolveAbsoluteNodeLocation(epLoc);
317         if (potentialAbsNodeLoc.isPresent()) {
318             if (rendererByNode.get(potentialAbsNodeLoc.get()) != null) {
319                 return Optional.of(rendererByNode.get(potentialAbsNodeLoc.get()));
320             } else {
321                 return Optional.absent();
322             }
323         }
324         Optional<List<InstanceIdentifier<?>>> potentianRelativeLocation =
325                 EndpointLocationUtils.resolveRelativeExternalNodeMountPointLocation(epLoc);
326         if (potentianRelativeLocation.isPresent()) {
327             return Optional.of(rendererByNode.get(potentianRelativeLocation.get().stream().findAny().get()));
328         }
329         return Optional.absent();
330     }
331
332     private static AddressEndpointWithLocation createEpWithLoc(AddressEndpoint ep, AddressEndpointLocation epLoc,
333             RendererName rendererName, Set<EndpointAugmentor> augmentors) {
334         AddressEndpointWithLocationBuilder addrEpWithLoc = new AddressEndpointWithLocationBuilder()
335             .setAddress(ep.getAddress())
336             .setAddressType(ep.getAddressType())
337             .setContextId(ep.getContextId())
338             .setContextType(ep.getContextType())
339             .setTenant(ep.getTenant())
340             .setChildEndpoint(ep.getChildEndpoint())
341             .setParentEndpointChoice(ep.getParentEndpointChoice())
342             .setEndpointGroup(ep.getEndpointGroup())
343             .setCondition(ep.getCondition())
344             .setNetworkContainment(ep.getNetworkContainment())
345             .setTimestamp(ep.getTimestamp())
346             .setAbsoluteLocation(epLoc.getAbsoluteLocation())
347             .setRelativeLocations(epLoc.getRelativeLocations())
348             .setRendererName(rendererName);
349         for (EndpointAugmentor augmentor : augmentors) {
350             Entry<Class<? extends Augmentation<AddressEndpointWithLocation>>, Augmentation<AddressEndpointWithLocation>> addrEpWithLocAug =
351                     augmentor.buildAddressEndpointWithLocationAugmentation(ep);
352             if (addrEpWithLocAug != null) {
353                 addrEpWithLoc.addAugmentation(addrEpWithLocAug.getKey(), addrEpWithLocAug.getValue());
354             }
355         }
356         if (ep.getAugmentation(NatAddress.class) != null) {
357             NatAddress natAddr = ep.getAugmentation(NatAddress.class);
358             addrEpWithLoc.addAugmentation(NatAddressRenderer.class,
359                 new NatAddressRendererBuilder().setNatAddress(natAddr.getNatAddress()).build());
360         }
361         return addrEpWithLoc.build();
362     }
363
364     private static List<ContainmentEndpointWithLocation> resolveContEpsWithLoc(Set<ContainmentEndpointKey> contEpKeys,
365             EndpointInfo epInfo, EndpointLocationInfo epLocInfo, Set<EndpointAugmentor> augmentors) {
366         List<ContainmentEndpointWithLocation> result = new ArrayList<>();
367         for (ContainmentEndpointKey contEpKey : contEpKeys) {
368             Optional<ContainmentEndpoint> potentialContEp = epInfo.getContainmentEndpoint(contEpKey);
369             Preconditions.checkArgument(potentialContEp.isPresent());
370             Optional<ContainmentEndpointLocation> potentialContEpLoc =
371                     epLocInfo.getContainmentEndpointLocation(contEpKey);
372             Preconditions.checkArgument(potentialContEpLoc.isPresent());
373             result.add(createContEpWithLoc(potentialContEp.get(), potentialContEpLoc.get(), augmentors));
374         }
375         return result;
376     }
377
378     private static ContainmentEndpointWithLocation createContEpWithLoc(ContainmentEndpoint contEp,
379             ContainmentEndpointLocation contEpLoc, Set<EndpointAugmentor> augmentors) {
380         ContainmentEndpointWithLocationBuilder contEpWithLoc = new ContainmentEndpointWithLocationBuilder()
381             .setContextId(contEp.getContextId())
382             .setContextType(contEp.getContextType())
383             .setTenant(contEp.getTenant())
384             .setChildEndpoint(contEp.getChildEndpoint())
385             .setEndpointGroup(contEp.getEndpointGroup())
386             .setCondition(contEp.getCondition())
387             .setNetworkContainment(contEp.getNetworkContainment())
388             .setTimestamp(contEp.getTimestamp())
389             .setRelativeLocations(contEpLoc.getRelativeLocations());
390         for (EndpointAugmentor augmentor : augmentors) {
391             Entry<Class<? extends Augmentation<ContainmentEndpointWithLocation>>, Augmentation<ContainmentEndpointWithLocation>> contEpWithLocAug =
392                     augmentor.buildContainmentEndpointWithLocationAugmentation(contEp);
393             if (contEpWithLocAug != null) {
394                 contEpWithLoc.addAugmentation(contEpWithLocAug.getKey(), contEpWithLocAug.getValue());
395             }
396         }
397         return contEpWithLoc.build();
398     }
399
400     public RuleGroups buildRuleGroups(ResolvedPolicyInfo policyInfo) {
401         List<RuleGroup> ruleGroups = resolveRuleGroups(getPolicyRuleGroupKeys(), policyInfo);
402         return new RuleGroupsBuilder().setRuleGroup(ruleGroups).build();
403     }
404
405     private List<RuleGroup> resolveRuleGroups(Set<PolicyRuleGroupKey> policyRuleGrpKeys,
406             ResolvedPolicyInfo policyInfo) {
407         List<RuleGroup> result = new ArrayList<>();
408         for (PolicyRuleGroupKey policyRuleGrpKey : policyRuleGrpKeys) {
409             Optional<PolicyRuleGroup> potentialPolicyRuleGrp = policyInfo.getPolicyRuleGroup(policyRuleGrpKey);
410             Preconditions.checkArgument(potentialPolicyRuleGrp.isPresent());
411             result.add(createRuleGroup(potentialPolicyRuleGrp.get()));
412         }
413         return result;
414     }
415
416     private RuleGroup createRuleGroup(PolicyRuleGroup policyRuleGrp) {
417         return new RuleGroupBuilder().setTenantId(policyRuleGrp.getTenantId())
418             .setContractId(policyRuleGrp.getContractId())
419             .setSubjectName(policyRuleGrp.getSubjectName())
420             .setResolvedRule(policyRuleGrp.getResolvedRule())
421             .setOrder(policyRuleGrp.getOrder())
422             .build();
423     }
424
425     // TODO this copies entire Forwarding to RendererForwarding - it could copy only forwarding used
426     // in EPs (renderer EPs + peers)
427     public RendererForwarding buildRendererForwarding(Forwarding forwarding, Set<NetworkDomainAugmentor> augmentors) {
428         List<RendererForwardingByTenant> forwardingContextByTenant =
429                 resolveForwardingContextByTenant(forwarding.getForwardingByTenant(), augmentors);
430         return new RendererForwardingBuilder().setRendererForwardingByTenant(forwardingContextByTenant).build();
431     }
432
433     private static List<RendererForwardingByTenant> resolveForwardingContextByTenant(
434             List<ForwardingByTenant> forwardingByTenant, Set<NetworkDomainAugmentor> augmentors) {
435         List<RendererForwardingByTenant> result = new ArrayList<>();
436         for (ForwardingByTenant fwdByTenant : forwardingByTenant) {
437             result.add(resolveRendererForwardingByTenant(fwdByTenant, augmentors));
438         }
439         return result;
440     }
441
442     private static RendererForwardingByTenant resolveRendererForwardingByTenant(ForwardingByTenant fwdByTenant,
443             Set<NetworkDomainAugmentor> augmentors) {
444         List<RendererForwardingContext> rendererForwardingContexts =
445                 resolveRendererForwardingContexts(fwdByTenant.getForwardingContext());
446         List<RendererNetworkDomain> rendererNetworkDomains =
447                 resolveRendererNetworkDomains(fwdByTenant.getNetworkDomain(), augmentors);
448         return new RendererForwardingByTenantBuilder().setTenantId(fwdByTenant.getTenantId())
449             .setRendererForwardingContext(rendererForwardingContexts)
450             .setRendererNetworkDomain(rendererNetworkDomains)
451             .build();
452     }
453
454     private static List<RendererForwardingContext> resolveRendererForwardingContexts(
455             @Nullable List<ForwardingContext> fwdCtx) {
456         if (fwdCtx == null) {
457             return Collections.emptyList();
458         }
459         return FluentIterable.from(fwdCtx).transform(new Function<ForwardingContext, RendererForwardingContext>() {
460
461             @Override
462             public RendererForwardingContext apply(ForwardingContext input) {
463                 return new RendererForwardingContextBuilder().setContextId(input.getContextId())
464                     .setContextType(input.getContextType())
465                     .setName(input.getName())
466                     .setParent(input.getParent())
467                     .build();
468             }
469         }).toList();
470     }
471
472     private static List<RendererNetworkDomain> resolveRendererNetworkDomains(@Nullable List<NetworkDomain> netDomains,
473             Set<NetworkDomainAugmentor> augmentors) {
474         if (netDomains == null) {
475             return Collections.emptyList();
476         }
477         return FluentIterable.from(netDomains).transform(new Function<NetworkDomain, RendererNetworkDomain>() {
478
479             @Override
480             public RendererNetworkDomain apply(NetworkDomain input) {
481                 RendererNetworkDomainBuilder rendererNetworkDomainBuilder =
482                         new RendererNetworkDomainBuilder().setNetworkDomainId(input.getNetworkDomainId())
483                             .setNetworkDomainType(input.getNetworkDomainType())
484                             .setName(input.getName())
485                             .setParent(input.getParent());
486                 for (NetworkDomainAugmentor augmentor : augmentors) {
487                     Entry<Class<? extends Augmentation<RendererNetworkDomain>>, Augmentation<RendererNetworkDomain>> networkDomainAugmentation =
488                             augmentor.buildRendererNetworkDomainAugmentation(input);
489                     if (networkDomainAugmentation != null) {
490                         rendererNetworkDomainBuilder.addAugmentation(networkDomainAugmentation.getKey(),
491                                 networkDomainAugmentation.getValue());
492                     }
493                 }
494                 return rendererNetworkDomainBuilder.build();
495             }
496         }).toList();
497     }
498
499 }