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