fixes for several logical bugs
[groupbasedpolicy.git] / groupbasedpolicy / src / main / java / org / opendaylight / groupbasedpolicy / renderer / RendererManager.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 static com.google.common.base.Preconditions.checkNotNull;
12
13 import java.util.ArrayList;
14 import java.util.Collections;
15 import java.util.HashMap;
16 import java.util.HashSet;
17 import java.util.List;
18 import java.util.Map;
19 import java.util.Set;
20
21 import javax.annotation.Nullable;
22
23 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
24 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
25 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
26 import org.opendaylight.groupbasedpolicy.dto.ConsEpgKey;
27 import org.opendaylight.groupbasedpolicy.dto.EpgKeyDto;
28 import org.opendaylight.groupbasedpolicy.dto.ProvEpgKey;
29 import org.opendaylight.groupbasedpolicy.forwarding.NetworkDomainAugmentorRegistryImpl;
30 import org.opendaylight.groupbasedpolicy.renderer.listener.EndpointLocationsListener;
31 import org.opendaylight.groupbasedpolicy.renderer.listener.EndpointsListener;
32 import org.opendaylight.groupbasedpolicy.renderer.listener.ForwardingListener;
33 import org.opendaylight.groupbasedpolicy.renderer.listener.RenderersListener;
34 import org.opendaylight.groupbasedpolicy.renderer.listener.ResolvedPoliciesListener;
35 import org.opendaylight.groupbasedpolicy.util.DataStoreHelper;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.EndpointLocations;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.Endpoints;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoints.address.endpoints.AddressEndpoint;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoints.address.endpoints.AddressEndpointKey;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoints.containment.endpoints.ContainmentEndpointKey;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.EndpointGroupId;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.TenantId;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.rev160427.Forwarding;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.EndpointPolicyParticipation;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.RendererName;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.Renderers;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.RenderersBuilder;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.has.peer.endpoints.PeerEndpointKey;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.has.peer.external.containment.endpoints.PeerExternalContainmentEndpointKey;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.has.peer.external.endpoints.PeerExternalEndpointKey;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.Renderer;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.RendererBuilder;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.RendererPolicy;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.RendererPolicyBuilder;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.Configuration;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.ConfigurationBuilder;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.Status;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.RendererEndpoints;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.RendererForwarding;
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.renderer.endpoints.RendererEndpointKey;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.resolved.policy.rev150828.ResolvedPolicies;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.resolved.policy.rev150828.resolved.policies.ResolvedPolicy;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.resolved.policy.rev150828.resolved.policies.ResolvedPolicy.ExternalImplicitGroup;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.resolved.policy.rev150828.resolved.policies.resolved.policy.PolicyRuleGroupWithEndpointConstraints;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.resolved.policy.rev150828.resolved.policies.resolved.policy.policy.rule.group.with.endpoint.constraints.PolicyRuleGroup;
67 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
68 import org.slf4j.Logger;
69 import org.slf4j.LoggerFactory;
70
71 import com.google.common.annotations.VisibleForTesting;
72 import com.google.common.base.Function;
73 import com.google.common.base.Optional;
74 import com.google.common.collect.FluentIterable;
75 import com.google.common.collect.ImmutableCollection;
76 import com.google.common.collect.ImmutableMap;
77 import com.google.common.collect.ImmutableMultimap;
78 import com.google.common.collect.ImmutableSet;
79
80 public class RendererManager implements AutoCloseable {
81
82     private static final Logger LOG = LoggerFactory.getLogger(RendererManager.class);
83
84     private static long version = 0;
85
86     private final DataBroker dataProvider;
87     private final NetworkDomainAugmentorRegistryImpl netDomainAugmentorRegistry;
88     private final Set<RendererName> processingRenderers = new HashSet<>();
89     private Map<InstanceIdentifier<?>, RendererName> rendererByNode = new HashMap<>();
90     private ResolvedPolicyInfo policyInfo;
91     private EndpointInfo epInfo;
92     private EndpointLocationInfo epLocInfo;
93     private Forwarding forwarding;
94     private boolean changesWaitingToProcess = false;
95     private boolean currentVersionHasConfig = false;
96
97     private final EndpointsListener endpointsListener;
98     private final EndpointLocationsListener endpointLocationsListener;
99     private final ResolvedPoliciesListener resolvedPoliciesListener;
100     private final ForwardingListener forwardingListener;
101     private final RenderersListener renderersListener;
102
103     public RendererManager(DataBroker dataProvider, NetworkDomainAugmentorRegistryImpl netDomainAugmentorRegistry) {
104         this.dataProvider = checkNotNull(dataProvider);
105         this.netDomainAugmentorRegistry = checkNotNull(netDomainAugmentorRegistry);
106         endpointsListener = new EndpointsListener(this, dataProvider);
107         endpointLocationsListener = new EndpointLocationsListener(this, dataProvider);
108         resolvedPoliciesListener = new ResolvedPoliciesListener(this, dataProvider);
109         forwardingListener = new ForwardingListener(this, dataProvider);
110         renderersListener = new RenderersListener(this, dataProvider);
111     }
112
113     public synchronized void endpointsUpdated(final Endpoints endpoints) {
114         epInfo = new EndpointInfo(endpoints);
115         changesWaitingToProcess = true;
116         processState();
117     }
118
119     public synchronized void endpointLocationsUpdated(final EndpointLocations epLocations) {
120         epLocInfo = new EndpointLocationInfo(epLocations);
121         changesWaitingToProcess = true;
122         processState();
123     }
124
125     public synchronized void resolvedPoliciesUpdated(final ResolvedPolicies resolvedPolicies) {
126         policyInfo = new ResolvedPolicyInfo(resolvedPolicies);
127         changesWaitingToProcess = true;
128         processState();
129     }
130
131     public synchronized void forwardingUpdated(final Forwarding forwarding) {
132         this.forwarding = forwarding;
133         changesWaitingToProcess = true;
134         processState();
135     }
136
137     public synchronized void renderersUpdated(final Renderers renderersCont) {
138         ImmutableMultimap<InstanceIdentifier<?>, RendererName> renderersByNode =
139                 RendererUtils.resolveRenderersByNodes(renderersCont.getRenderer());
140         rendererByNode = new HashMap<>();
141         for (InstanceIdentifier<?> nodePath : renderersByNode.keySet()) {
142             ImmutableCollection<RendererName> renderers = renderersByNode.get(nodePath);
143             // only first renderer is used
144             rendererByNode.put(nodePath, renderers.asList().get(0));
145         }
146         if (processingRenderers.isEmpty()) {
147             changesWaitingToProcess = true;
148         } else {
149             LOG.debug("Waiting for renderers. Version {} needs to be processed by renderers: {}", version,
150                     processingRenderers);
151             ImmutableMap<RendererName, Renderer> rendererByName =
152                     RendererUtils.resolveRendererByName(renderersCont.getRenderer());
153             for (RendererName configuredRenderer : processingRenderers) {
154                 Renderer renderer = rendererByName.get(configuredRenderer);
155                 RendererPolicy rendererPolicy = renderer.getRendererPolicy();
156                 if (rendererPolicy != null && rendererPolicy.getVersion() != null
157                         && renderer.getRendererPolicy().getVersion().equals(version)) {
158                     processingRenderers.remove(configuredRenderer);
159                     Status status = rendererPolicy.getStatus();
160                     if (status != null && status.getUnconfiguredRule() != null) {
161                         LOG.warn("Renderer {} did not configure policy with version {} successfully. \n{}",
162                                 configuredRenderer.getValue(), version, status);
163                     } else {
164                         LOG.debug("Renderer {} configured policy with version {} successfully.",
165                                 configuredRenderer.getValue(), version);
166                     }
167                 }
168             }
169         }
170         processState();
171     }
172
173     private void processState() {
174         if (!processingRenderers.isEmpty()) {
175             LOG.debug("Waiting for renderers. Version {} needs to be processed by renderers: {}", version,
176                     processingRenderers);
177             return;
178         }
179         if (rendererByNode.values().isEmpty()) {
180             return;
181         }
182         if (!changesWaitingToProcess) {
183             return;
184         }
185         Map<RendererName, RendererConfigurationBuilder> rendererConfigBuilderByRendererName = createRendererConfigBuilders();
186         Set<RendererName> rendererNames = new HashSet<>(rendererByNode.values());
187         boolean newVersionHasConfig = false;
188         Map<RendererName, Optional<Configuration>> configsByRendererName = new HashMap<>();
189         for (RendererName rendererName : rendererNames) {
190             RendererConfigurationBuilder rendererPolicyBuilder = rendererConfigBuilderByRendererName.get(rendererName);
191             Optional<Configuration> potentialConfig = createConfiguration(rendererPolicyBuilder);
192             if (potentialConfig.isPresent()) {
193                 newVersionHasConfig = true;
194             }
195             configsByRendererName.put(rendererName, potentialConfig);
196         }
197         if (newVersionHasConfig || currentVersionHasConfig) {
198             version++;
199             if (!writeRenderersConfigs(configsByRendererName)) {
200                 LOG.warn("Version {} was not dispatched successfully. Previous version is valid until next update.",
201                         version);
202                 for (RendererName rendererName : rendererConfigBuilderByRendererName.keySet()) {
203                     processingRenderers.remove(rendererName);
204                 }
205                 version--;
206                 changesWaitingToProcess = true;
207                 return;
208             } else {
209                 currentVersionHasConfig = newVersionHasConfig;
210             }
211         }
212         changesWaitingToProcess = false;
213     }
214
215     private boolean writeRenderersConfigs(Map<RendererName, Optional<Configuration>> configsByRendererName) {
216         List<Renderer> renderers = new ArrayList<>();
217         for (RendererName rendererName : configsByRendererName.keySet()) {
218             RendererPolicy rendererPolicy = null;
219             if (configsByRendererName.get(rendererName).isPresent()) {
220                 rendererPolicy = new RendererPolicyBuilder().setVersion(version)
221                     .setConfiguration(configsByRendererName.get(rendererName).get())
222                     .build();
223
224             } else {
225                 rendererPolicy = new RendererPolicyBuilder().setVersion(version).build();
226             }
227             renderers.add(new RendererBuilder().setName(rendererName).setRendererPolicy(rendererPolicy).build());
228             processingRenderers.add(rendererName);
229             LOG.debug("Created configuration for renderer {} with version {}", rendererName.getValue(), version);
230         }
231         WriteTransaction wTx = dataProvider.newWriteOnlyTransaction();
232         wTx.put(LogicalDatastoreType.CONFIGURATION, InstanceIdentifier.create(Renderers.class),
233                 new RenderersBuilder().setRenderer(renderers).build());
234         return DataStoreHelper.submitToDs(wTx);
235     }
236
237     /**
238      * Entry is added to the result map only if:<br>
239      * 1. There is at least one Address EP with absolute location
240      * 2. There is a renderer responsible for that EP
241      *
242      * @return
243      */
244     private Map<RendererName, RendererConfigurationBuilder> createRendererConfigBuilders() {
245         if (!isStateValid()) {
246             return Collections.emptyMap();
247         }
248         Map<RendererName, RendererConfigurationBuilder> rendererConfigBuilderByRendererName = new HashMap<>();
249         for (InstanceIdentifier<?> absEpLocation : epLocInfo.getAllAbsoluteNodeLocations()) {
250             RendererName rendererName = rendererByNode.get(absEpLocation);
251             if (rendererName == null) {
252                 LOG.trace("Renderer does not exist for EP with location: {}", absEpLocation);
253                 continue;
254             }
255             RendererConfigurationBuilder rendererConfigBuilder = rendererConfigBuilderByRendererName.get(rendererName);
256             if (rendererConfigBuilder == null) {
257                 rendererConfigBuilder = new RendererConfigurationBuilder();
258                 rendererConfigBuilderByRendererName.put(rendererName, rendererConfigBuilder);
259             }
260             for (AddressEndpointKey rendererAdrEpKey : epLocInfo.getAddressEpsWithAbsoluteNodeLocation(absEpLocation)) {
261                 Optional<AddressEndpoint> potentialAddressEp = epInfo.getEndpoint(rendererAdrEpKey);
262                 if (!potentialAddressEp.isPresent()) {
263                     LOG.trace("Endpoint does not exist but has location: {}", rendererAdrEpKey);
264                     continue;
265                 }
266                 AddressEndpoint rendererAdrEp = potentialAddressEp.get();
267                 resolveRendererConfigForEndpoint(rendererAdrEp, rendererConfigBuilder);
268             }
269         }
270         return rendererConfigBuilderByRendererName;
271     }
272
273     private boolean isStateValid() {
274         if (rendererByNode.isEmpty() || policyInfo == null || epInfo == null || epLocInfo == null
275                 || forwarding == null) {
276             return false;
277         }
278         return true;
279     }
280
281     private Optional<Configuration> createConfiguration(@Nullable RendererConfigurationBuilder rendererPolicyBuilder) {
282         if (rendererPolicyBuilder == null) {
283             return Optional.absent();
284         }
285         ConfigurationBuilder configBuilder = new ConfigurationBuilder();
286         RendererEndpoints rendererEndpoints = rendererPolicyBuilder.buildRendererEndpoints();
287         if (isRendererEndpointsEmpty(rendererEndpoints)) {
288             return Optional.absent();
289         }
290         configBuilder.setRendererEndpoints(rendererEndpoints);
291
292         org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.Endpoints endpoints =
293                 rendererPolicyBuilder.buildEndoints(epInfo, epLocInfo, rendererByNode);
294         configBuilder.setEndpoints(endpoints);
295
296         RuleGroups ruleGroups = rendererPolicyBuilder.buildRuluGroups(policyInfo);
297         configBuilder.setRuleGroups(ruleGroups);
298
299         RendererForwarding rendererForwarding = rendererPolicyBuilder.buildRendererForwarding(forwarding,
300                 netDomainAugmentorRegistry.getEndpointAugmentors());
301         configBuilder.setRendererForwarding(rendererForwarding);
302
303         return Optional.of(configBuilder.build());
304     }
305
306     private boolean isRendererEndpointsEmpty(RendererEndpoints rendererEndpoints) {
307         if (rendererEndpoints == null || rendererEndpoints.getRendererEndpoint() == null
308                 || rendererEndpoints.getRendererEndpoint().isEmpty()) {
309             return true;
310         }
311         return false;
312     }
313
314     @VisibleForTesting
315     void resolveRendererConfigForEndpoint(AddressEndpoint rendererAdrEp,
316             RendererConfigurationBuilder rendererPolicyBuilder) {
317         Set<EpgKeyDto> rendererEpgs = toEpgKeys(rendererAdrEp.getEndpointGroup(), rendererAdrEp.getTenant());
318         RendererEndpointKey rendererEpKey = AddressEndpointUtils.toRendererEpKey(rendererAdrEp.getKey());
319         for (EpgKeyDto rendererEpg : rendererEpgs) {
320             ImmutableSet<ConsEpgKey> consPeerEpgs = policyInfo.findConsumerPeers(rendererEpg);
321             for (ConsEpgKey consPeerEpg : consPeerEpgs) {
322                 Optional<ResolvedPolicy> potentialPolicy = policyInfo.findPolicy(consPeerEpg, rendererEpg);
323                 ResolvedPolicy policy = potentialPolicy.get();
324                 ImmutableSet<AddressEndpointKey> consPeerAdrEps = epInfo.findAddressEpsWithEpg(consPeerEpg);
325                 resolveRendererPolicyBetweenEpAndPeers(rendererEpKey, consPeerAdrEps, policy,
326                         EndpointPolicyParticipation.PROVIDER, rendererPolicyBuilder);
327                 ImmutableSet<ContainmentEndpointKey> consPeerContEps = epInfo.findContainmentEpsWithEpg(consPeerEpg);
328                 resolveRendererPolicyBetweenEpAndContPeers(rendererEpKey, consPeerContEps, policy,
329                         EndpointPolicyParticipation.PROVIDER, rendererPolicyBuilder);
330             }
331             ImmutableSet<ProvEpgKey> provPeerEpgs = policyInfo.findProviderPeers(rendererEpg);
332             for (ProvEpgKey provPeerEpg : provPeerEpgs) {
333                 Optional<ResolvedPolicy> potentialPolicy = policyInfo.findPolicy(rendererEpg, provPeerEpg);
334                 ResolvedPolicy policy = potentialPolicy.get();
335                 ImmutableSet<AddressEndpointKey> provPeerAdrEps = epInfo.findAddressEpsWithEpg(provPeerEpg);
336                 resolveRendererPolicyBetweenEpAndPeers(rendererEpKey, provPeerAdrEps, policy,
337                         EndpointPolicyParticipation.CONSUMER, rendererPolicyBuilder);
338                 ImmutableSet<ContainmentEndpointKey> provPeerContEps = epInfo.findContainmentEpsWithEpg(provPeerEpg);
339                 resolveRendererPolicyBetweenEpAndContPeers(rendererEpKey, provPeerContEps, policy,
340                         EndpointPolicyParticipation.CONSUMER, rendererPolicyBuilder);
341             }
342         }
343     }
344
345     private void resolveRendererPolicyBetweenEpAndContPeers(RendererEndpointKey rendererEpKey,
346             Set<ContainmentEndpointKey> peerContEps, ResolvedPolicy policy,
347             EndpointPolicyParticipation rendererEpParticipation, RendererConfigurationBuilder rendererPolicyBuilder) {
348         if (isRendererEpInEig(policy, rendererEpParticipation)) {
349             LOG.info("Renderer EP cannot be in EIG therefore it is ignored: {}. \nPolicy: {}", rendererEpKey);
350             LOG.debug("Renderer EP participation: {}, Policy: {}", rendererEpParticipation, policy);
351             return;
352         }
353         for (ContainmentEndpointKey peerContEpKey : peerContEps) {
354             ExternalImplicitGroup eig = policy.getExternalImplicitGroup();
355             if (eig != null) { // peers are in EIG
356                 if (!epLocInfo.hasRelativeLocation(peerContEpKey)) {
357                     LOG.debug("EIG Containment Peer does not have relative location therefore it is ignored: {}",
358                             peerContEpKey);
359                     continue;
360                 }
361                 PeerExternalContainmentEndpointKey peerExtContEpKey =
362                         ContainmentEndpointUtils.toPeerExtContEpKey(peerContEpKey);
363                 for (PolicyRuleGroupWithEndpointConstraints ruleGrpsWithEpConstraints : policy
364                     .getPolicyRuleGroupWithEndpointConstraints()) {
365                     // TODO filter based on endpoint constraints
366                     for (PolicyRuleGroup ruleGrp : ruleGrpsWithEpConstraints.getPolicyRuleGroup()) {
367                         rendererPolicyBuilder.add(rendererEpKey, peerExtContEpKey, ruleGrp.getKey(),
368                                 rendererEpParticipation);
369                     }
370                 }
371             } else {
372                 LOG.info("Peer Containment EP cannot be in other EPG than EIG therefore it is ignored: {}",
373                         peerContEpKey);
374             }
375         }
376     }
377
378     private void resolveRendererPolicyBetweenEpAndPeers(RendererEndpointKey rendererEpKey,
379             Set<AddressEndpointKey> peerAdrEps, ResolvedPolicy policy,
380             EndpointPolicyParticipation rendererEpParticipation, RendererConfigurationBuilder rendererPolicyBuilder) {
381         if (isRendererEpInEig(policy, rendererEpParticipation)) {
382             LOG.info("Renderer EP cannot be in EIG therefore it is ignored: {}. \nPolicy: {}", rendererEpKey);
383             LOG.debug("Renderer EP participation: {}, Policy: {}", rendererEpParticipation, policy);
384             return;
385         }
386         for (AddressEndpointKey peerAdrEpKey : peerAdrEps) {
387             if (isSameKeys(rendererEpKey, peerAdrEpKey)) {
388                 continue;
389             }
390             ExternalImplicitGroup eig = policy.getExternalImplicitGroup();
391             if (eig != null) {
392                 if (!epLocInfo.hasRelativeLocation(peerAdrEpKey)) {
393                     LOG.debug("EIG Peer does not have relative location therefore it is ignored: {}", peerAdrEpKey);
394                     continue;
395                 }
396                 PeerExternalEndpointKey peerExtEpKey = AddressEndpointUtils.toPeerExtEpKey(peerAdrEpKey);
397                 for (PolicyRuleGroupWithEndpointConstraints ruleGrpsWithEpConstraints : policy
398                     .getPolicyRuleGroupWithEndpointConstraints()) {
399                     // TODO filter based on endpoint constraints
400                     for (PolicyRuleGroup ruleGrp : ruleGrpsWithEpConstraints.getPolicyRuleGroup()) {
401                         rendererPolicyBuilder.add(rendererEpKey, peerExtEpKey, ruleGrp.getKey(),
402                                 rendererEpParticipation);
403                     }
404                 }
405             } else {
406                 if (!epLocInfo.hasRealLocation(peerAdrEpKey)) {
407                     LOG.debug("Peer does not have real location therefore it is ignored: {}", peerAdrEpKey);
408                     continue;
409                 }
410                 PeerEndpointKey peerEpKey = AddressEndpointUtils.toPeerEpKey(peerAdrEpKey);
411                 for (PolicyRuleGroupWithEndpointConstraints ruleGrpsWithEpConstraints : policy
412                     .getPolicyRuleGroupWithEndpointConstraints()) {
413                     // TODO filter based on endpoint constraints
414                     for (PolicyRuleGroup ruleGrp : ruleGrpsWithEpConstraints.getPolicyRuleGroup()) {
415                         rendererPolicyBuilder.add(rendererEpKey, peerEpKey, ruleGrp.getKey(), rendererEpParticipation);
416                     }
417                 }
418             }
419         }
420     }
421
422     private boolean isRendererEpInEig(ResolvedPolicy policy, EndpointPolicyParticipation rendererEpParticipation) {
423         ExternalImplicitGroup eig = policy.getExternalImplicitGroup();
424         if (rendererEpParticipation == EndpointPolicyParticipation.PROVIDER
425                 && ExternalImplicitGroup.ProviderEpg == eig) {
426             return true;
427         } else if (rendererEpParticipation == EndpointPolicyParticipation.CONSUMER
428                 && ExternalImplicitGroup.ConsumerEpg == eig) {
429             return true;
430         }
431         return false;
432     }
433
434     private boolean isSameKeys(RendererEndpointKey rendererEpKey, AddressEndpointKey peerAdrEpKey) {
435         if (rendererEpKey.getAddress().equals(peerAdrEpKey.getAddress())
436                 && rendererEpKey.getAddressType().equals(peerAdrEpKey.getAddressType())
437                 && rendererEpKey.getContextId().equals(peerAdrEpKey.getContextId())
438                 && rendererEpKey.getContextType().equals(peerAdrEpKey.getContextType())) {
439             return true;
440         }
441         return false;
442     }
443
444     private Set<EpgKeyDto> toEpgKeys(List<EndpointGroupId> epgIds, TenantId tenantId) {
445         return FluentIterable.from(epgIds).transform(new Function<EndpointGroupId, EpgKeyDto>() {
446
447             @Override
448             public EpgKeyDto apply(EndpointGroupId input) {
449                 return new EpgKeyDto(input, tenantId);
450             }
451         }).toSet();
452     }
453
454     @VisibleForTesting
455     Set<RendererName> getProcessingRenderers() {
456         return processingRenderers;
457     }
458
459     @VisibleForTesting
460     static void resetVersion() {
461         version = 0;
462     }
463
464     @Override
465     public void close() throws Exception {
466         endpointsListener.close();
467         endpointLocationsListener.close();
468         resolvedPoliciesListener.close();
469         forwardingListener.close();
470         renderersListener.close();
471     }
472
473 }