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