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