/* * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v1.0 which accompanies this distribution, * and is available at http://www.eclipse.org/legal/epl-v10.html */ package org.opendaylight.groupbasedpolicy.renderer.vpp.policy; import java.util.Collections; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Optional; import java.util.TreeSet; import java.util.function.Supplier; import java.util.stream.Collectors; import javax.annotation.Nonnull; import org.opendaylight.groupbasedpolicy.renderer.vpp.util.KeyFactory; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoints.address.endpoints.AddressEndpointKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.TenantId; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.RendererPolicy; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.Configuration; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.endpoints.AddressEndpointWithLocation; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.RendererEndpoint; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.RendererEndpointKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.renderer.endpoint.PeerEndpointKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.forwarding.renderer.forwarding.by.tenant.RendererForwardingContext; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.forwarding.renderer.forwarding.by.tenant.RendererForwardingContextKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.forwarding.renderer.forwarding.by.tenant.RendererNetworkDomain; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.forwarding.renderer.forwarding.by.tenant.RendererNetworkDomainKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.rule.groups.RuleGroup; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.rule.groups.RuleGroupKey; import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSortedSet; import com.google.common.collect.ImmutableTable; import com.google.common.collect.ImmutableTable.Builder; import com.google.common.collect.Maps; public class PolicyContext { private final RendererPolicy policy; private final ImmutableTable<RendererEndpointKey, PeerEndpointKey, ImmutableSortedSet<RendererResolvedPolicy>> policyTable; private final ImmutableMap<RuleGroupKey, ResolvedRuleGroup> ruleGroupByKey; private final ImmutableMap<AddressEndpointKey, AddressEndpointWithLocation> addrEpByKey; private final ImmutableTable<TenantId, RendererForwardingContextKey, RendererForwardingContext> forwardingCtxTable; private final ImmutableTable<TenantId, RendererNetworkDomainKey, RendererNetworkDomain> networkDomainTable; public PolicyContext(@Nonnull RendererPolicy policy) { this.policy = Preconditions.checkNotNull(policy); Optional<Configuration> optConfig = resolveValidConfig(policy); if (optConfig.isPresent()) { Configuration config = optConfig.get(); this.ruleGroupByKey = resolveRuleGroups(config); List<RendererEndpoint> rendererEps = resolveRendererEndpoints(config); this.policyTable = resolvePolicy(rendererEps, ruleGroupByKey); addrEpByKey = resolveAddrEpWithLoc(config); this.forwardingCtxTable = resolveForwardingCtxTable(config); this.networkDomainTable = resolveNetworkDomainTable(config); } else { this.ruleGroupByKey = ImmutableMap.of(); this.policyTable = ImmutableTable.of(); this.addrEpByKey = ImmutableMap.of(); this.forwardingCtxTable = ImmutableTable.of(); this.networkDomainTable = ImmutableTable.of(); } } private static List<RendererEndpoint> resolveRendererEndpoints(Configuration config) { if (config.getRendererEndpoints() == null) { return Collections.emptyList(); } List<RendererEndpoint> rendererEndpoints = config.getRendererEndpoints().getRendererEndpoint(); if (rendererEndpoints == null) { return Collections.emptyList(); } return rendererEndpoints; } private static ImmutableTable<RendererEndpointKey, PeerEndpointKey, ImmutableSortedSet<RendererResolvedPolicy>> resolvePolicy( List<RendererEndpoint> rendererEps, Map<RuleGroupKey, ResolvedRuleGroup> ruleGroupInfoByRuleGroupKey) { Builder<RendererEndpointKey, PeerEndpointKey, ImmutableSortedSet<RendererResolvedPolicy>> resultBuilder = new Builder<>(); Supplier<TreeSet<RendererResolvedPolicy>> rendererPolicySupplier = () -> new TreeSet<>(); rendererEps.stream().forEach(rEp -> { rEp.getPeerEndpoint().stream().filter(Objects::nonNull).forEach(peer -> { ImmutableSortedSet<RendererResolvedPolicy> rPolicy = peer.getRuleGroupWithRendererEndpointParticipation() .stream() .map(ruleGroup -> new RendererResolvedPolicy(ruleGroup.getRendererEndpointParticipation(), ruleGroupInfoByRuleGroupKey.get(KeyFactory.ruleGroupKey(ruleGroup.getKey())))) .collect(Collectors.collectingAndThen(Collectors.toCollection(rendererPolicySupplier), ImmutableSortedSet::copyOfSorted)); resultBuilder.put(rEp.getKey(), KeyFactory.peerEndpointKey(peer.getKey()), ImmutableSortedSet.copyOfSorted(rPolicy)); }); }); return resultBuilder.build(); } private static ImmutableMap<RuleGroupKey, ResolvedRuleGroup> resolveRuleGroups(Configuration config) { return config.getRuleGroups().getRuleGroup().stream().collect(Collectors .collectingAndThen(Collectors.toMap(RuleGroup::getKey, ResolvedRuleGroup::new), ImmutableMap::copyOf)); } private static ImmutableTable<TenantId, RendererForwardingContextKey, RendererForwardingContext> resolveForwardingCtxTable( Configuration config) { Builder<TenantId, RendererForwardingContextKey, RendererForwardingContext> resultBuilder = new Builder<>(); Optional.ofNullable(config.getRendererForwarding()).map(x -> x.getRendererForwardingByTenant()).ifPresent(x -> { x.forEach(fwdByTenant -> { Optional.ofNullable(fwdByTenant.getRendererForwardingContext()).ifPresent(fwdCtxs -> { fwdCtxs.forEach(fwdCtx -> { resultBuilder.put(fwdByTenant.getTenantId(), fwdCtx.getKey(), fwdCtx); }); }); }); }); return resultBuilder.build(); } private static ImmutableTable<TenantId, RendererNetworkDomainKey, RendererNetworkDomain> resolveNetworkDomainTable( Configuration config) { Builder<TenantId, RendererNetworkDomainKey, RendererNetworkDomain> resultBuilder = new Builder<>(); Optional.ofNullable(config.getRendererForwarding()).map(x -> x.getRendererForwardingByTenant()).ifPresent(x -> { x.forEach(fwdByTenant -> { Optional.ofNullable(fwdByTenant.getRendererNetworkDomain()).ifPresent(netDomains -> { netDomains.forEach(netDomain -> { resultBuilder.put(fwdByTenant.getTenantId(), netDomain.getKey(), netDomain); }); }); }); }); return resultBuilder.build(); } private static ImmutableMap<AddressEndpointKey, AddressEndpointWithLocation> resolveAddrEpWithLoc( Configuration config) { return Maps.uniqueIndex(config.getEndpoints().getAddressEndpointWithLocation(), new com.google.common.base.Function<AddressEndpointWithLocation, AddressEndpointKey>() { @Override public AddressEndpointKey apply(AddressEndpointWithLocation input) { return new AddressEndpointKey(input.getAddress(), input.getAddressType(), input.getContextId(), input.getContextType()); } }); } private static Optional<Configuration> resolveValidConfig(RendererPolicy policy) { Configuration config = policy.getConfiguration(); if (config == null) { return Optional.empty(); } if (config.getRendererEndpoints() == null) { return Optional.empty(); } return Optional.of(config); } public @Nonnull RendererPolicy getPolicy() { return policy; } public @Nonnull ImmutableTable<RendererEndpointKey, PeerEndpointKey, ImmutableSortedSet<RendererResolvedPolicy>> getPolicyTable() { return policyTable; } public @Nonnull ImmutableMap<RuleGroupKey, ResolvedRuleGroup> getRuleGroupByKey() { return ruleGroupByKey; } public @Nonnull ImmutableMap<AddressEndpointKey, AddressEndpointWithLocation> getAddrEpByKey() { return addrEpByKey; } public @Nonnull ImmutableTable<TenantId, RendererForwardingContextKey, RendererForwardingContext> getForwardingCtxTable() { return forwardingCtxTable; } public @Nonnull ImmutableTable<TenantId, RendererNetworkDomainKey, RendererNetworkDomain> getNetworkDomainTable() { return networkDomainTable; } @Override public String toString() { return "PolicyContext [policyTable=" + policyTable + ", ruleGroupByKey=" + ruleGroupByKey + ", addrEpByKey=" + addrEpByKey + ", forwardingCtxTable=" + forwardingCtxTable + ", networkDomainTable=" + networkDomainTable + "]"; } }