From ed1db1fa56f6dfc88d1c390ffb8c63b2cdc2f5a8 Mon Sep 17 00:00:00 2001 From: Michal Rehak Date: Mon, 22 Aug 2016 11:26:15 +0200 Subject: [PATCH] BUG-6650: ep-ip/sgt, propose sxp-generator - ep-to-sgt mapper implementation - sxp-ep-mapper wiring - added blueprint migration impact - moved sgt-generator-config model to top-level Change-Id: Id3765448f1e0e7da37701131e307c6f544dd20d2 Signed-off-by: Michal Rehak --- .../impl/IosXeRendererProviderImpl.java | 13 +- .../impl/config/IosXeProviderInstance.java | 8 +- .../impl/manager/PolicyManagerImpl.java | 10 +- .../impl/util/PolicyManagerUtil.java | 5 +- .../blueprint/ios-xe-renderer.xml | 3 + .../impl/manager/PolicyManagerImplTest.java | 30 ++-- .../src/main/config/default-config.xml | 27 --- .../SxpEpProviderProviderInstance.java | 105 ++++++++++++ .../SxpEpProviderProviderModule.java | 6 +- .../api/EPPolicyTemplateDaoFacade.java | 4 +- .../sxp/ep/provider/api/EPToSgtMapper.java | 26 +++ .../ep/provider/impl/EPToSgtMapperImpl.java | 60 +++++++ .../ep/provider/impl/SgtGeneratorImpl.java | 67 ++++++++ .../sxp/ep/provider/impl/SimpleCachedDao.java | 5 + .../impl/SxpEpProviderProviderImpl.java | 37 +++-- .../dao/EPPolicyTemplateDaoFacadeImpl.java | 68 +++++++- ...mpleCachedDaoEPForwardingTemplateImpl.java | 6 + .../impl/dao/SimpleCachedDaoImpl.java | 5 + .../listen/EPPolicyTemplateListenerImpl.java | 11 +- .../ep/provider/impl/util/EPTemplateUtil.java | 14 ++ .../provider/spi/SxpEpProviderProvider.java | 6 + .../org/opendaylight/blueprint/sxp-mapper.xml | 34 ++++ .../src/main/yang/sxp-ep-provider-cfg.yang | 41 ++--- .../SxpEpProviderProviderInstanceTest.java | 155 ++++++++++++++++++ .../provider/impl/EPToSgtMapperImplTest.java | 79 +++++++++ .../provider/impl/SgtGeneratorImplTest.java | 81 +++++++++ .../impl/SxpEpProviderProviderImplTest.java | 43 +++-- .../EPPolicyTemplateDaoFacadeImplTest.java | 36 +++- 28 files changed, 865 insertions(+), 120 deletions(-) create mode 100644 sxp-integration/sxp-ep-provider/src/main/java/org/opendaylight/controller/config/yang/config/groupbasedpolicy/sxp_integration/sxp_ep_provider/SxpEpProviderProviderInstance.java create mode 100644 sxp-integration/sxp-ep-provider/src/main/java/org/opendaylight/groupbasedpolicy/sxp/ep/provider/api/EPToSgtMapper.java create mode 100644 sxp-integration/sxp-ep-provider/src/main/java/org/opendaylight/groupbasedpolicy/sxp/ep/provider/impl/EPToSgtMapperImpl.java create mode 100644 sxp-integration/sxp-ep-provider/src/main/java/org/opendaylight/groupbasedpolicy/sxp/ep/provider/impl/SgtGeneratorImpl.java create mode 100644 sxp-integration/sxp-ep-provider/src/main/resources/org/opendaylight/blueprint/sxp-mapper.xml create mode 100644 sxp-integration/sxp-ep-provider/src/test/java/org/opendaylight/controller/config/yang/config/groupbasedpolicy/sxp_integration/sxp_ep_provider/SxpEpProviderProviderInstanceTest.java create mode 100644 sxp-integration/sxp-ep-provider/src/test/java/org/opendaylight/groupbasedpolicy/sxp/ep/provider/impl/EPToSgtMapperImplTest.java create mode 100644 sxp-integration/sxp-ep-provider/src/test/java/org/opendaylight/groupbasedpolicy/sxp/ep/provider/impl/SgtGeneratorImplTest.java diff --git a/renderers/ios-xe/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ios_xe_provider/impl/IosXeRendererProviderImpl.java b/renderers/ios-xe/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ios_xe_provider/impl/IosXeRendererProviderImpl.java index e6075f335..33badeb05 100644 --- a/renderers/ios-xe/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ios_xe_provider/impl/IosXeRendererProviderImpl.java +++ b/renderers/ios-xe/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ios_xe_provider/impl/IosXeRendererProviderImpl.java @@ -13,6 +13,8 @@ import com.google.common.collect.ImmutableList; import com.google.common.util.concurrent.CheckedFuture; import com.google.common.util.concurrent.FutureCallback; import com.google.common.util.concurrent.Futures; +import java.util.List; +import java.util.Optional; import org.opendaylight.controller.md.sal.binding.api.DataBroker; import org.opendaylight.controller.md.sal.binding.api.WriteTransaction; import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; @@ -31,6 +33,7 @@ import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.sf.ChainAction import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.sf.Classifier; import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.sf.EtherTypeClassifier; import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.sf.IpProtoClassifier; +import org.opendaylight.groupbasedpolicy.sxp.ep.provider.spi.SxpEpProviderProvider; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.RendererName; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.Renderers; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.Renderer; @@ -45,9 +48,6 @@ import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.List; -import java.util.Optional; - /** * Purpose: bootstrap provider implementation of Ios-xe renderer */ @@ -56,12 +56,15 @@ public class IosXeRendererProviderImpl implements IosXeRendererProvider, Binding private static final Logger LOG = LoggerFactory.getLogger(IosXeRendererProviderImpl.class); private final DataBroker dataBroker; + private final SxpEpProviderProvider sxpEpProvider; private RendererConfigurationListenerImpl rendererConfigurationListener; private IosXeCapableNodeListenerImpl iosXeCapableNodeListener; - public IosXeRendererProviderImpl(final DataBroker dataBroker, final BindingAwareBroker broker) { + public IosXeRendererProviderImpl(final DataBroker dataBroker, final BindingAwareBroker broker, + final SxpEpProviderProvider sxpEpProvider) { LOG.debug("ios-xe renderer bootstrap"); this.dataBroker = Preconditions.checkNotNull(dataBroker, "missing dataBroker dependency"); + this.sxpEpProvider = Preconditions.checkNotNull(sxpEpProvider, "missing sxpEpProvider param"); broker.registerProvider(this); } @@ -87,7 +90,7 @@ public class IosXeRendererProviderImpl implements IosXeRendererProvider, Binding iosXeCapableNodeListener = new IosXeCapableNodeListenerImpl(dataBroker, nodeManager); // policy-manager and delegates - final PolicyManager policyManager = new PolicyManagerImpl(dataBroker, nodeManager); + final PolicyManager policyManager = new PolicyManagerImpl(dataBroker, nodeManager, sxpEpProvider.getEPToSgtMapper()); final PolicyManager policyManagerZip = new PolicyManagerZipImpl(policyManager); // renderer-configuration endpoints diff --git a/renderers/ios-xe/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ios_xe_provider/impl/config/IosXeProviderInstance.java b/renderers/ios-xe/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ios_xe_provider/impl/config/IosXeProviderInstance.java index e261ece26..3ef74be95 100644 --- a/renderers/ios-xe/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ios_xe_provider/impl/config/IosXeProviderInstance.java +++ b/renderers/ios-xe/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ios_xe_provider/impl/config/IosXeProviderInstance.java @@ -15,6 +15,7 @@ import org.opendaylight.controller.config.yang.config.groupbasedpolicy.Groupbase import org.opendaylight.controller.md.sal.binding.api.DataBroker; import org.opendaylight.controller.sal.binding.api.BindingAwareBroker; import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.IosXeRendererProviderImpl; +import org.opendaylight.groupbasedpolicy.sxp.ep.provider.spi.SxpEpProviderProvider; import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonService; import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceProvider; import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceRegistration; @@ -31,15 +32,18 @@ public class IosXeProviderInstance implements ClusterSingletonService, AutoClose private final DataBroker dataBroker; private final BindingAwareBroker bindingAwareBroker; private final ClusterSingletonServiceProvider clusterSingletonService; + private final SxpEpProviderProvider sxpEpProvider; private ClusterSingletonServiceRegistration singletonServiceRegistration; private IosXeRendererProviderImpl renderer; public IosXeProviderInstance(final DataBroker dataBroker, final BindingAwareBroker broker, - final ClusterSingletonServiceProvider clusterSingletonService) { + final ClusterSingletonServiceProvider clusterSingletonService, + final SxpEpProviderProvider sxpEpProvider) { this.dataBroker = Preconditions.checkNotNull(dataBroker); this.bindingAwareBroker = Preconditions.checkNotNull(broker); this.clusterSingletonService = Preconditions.checkNotNull(clusterSingletonService); + this.sxpEpProvider = Preconditions.checkNotNull(sxpEpProvider); } public void initialize() { @@ -50,7 +54,7 @@ public class IosXeProviderInstance implements ClusterSingletonService, AutoClose @Override public void instantiateServiceInstance() { LOG.info("Instantiating {}", this.getClass().getSimpleName()); - renderer = new IosXeRendererProviderImpl(dataBroker, bindingAwareBroker); + renderer = new IosXeRendererProviderImpl(dataBroker, bindingAwareBroker, sxpEpProvider); } @Override diff --git a/renderers/ios-xe/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ios_xe_provider/impl/manager/PolicyManagerImpl.java b/renderers/ios-xe/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ios_xe_provider/impl/manager/PolicyManagerImpl.java index 3b5f5a5e2..884e74e46 100644 --- a/renderers/ios-xe/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ios_xe_provider/impl/manager/PolicyManagerImpl.java +++ b/renderers/ios-xe/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ios_xe_provider/impl/manager/PolicyManagerImpl.java @@ -28,6 +28,8 @@ import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFaile import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.api.manager.PolicyManager; import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.util.PolicyManagerUtil; import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.util.StatusUtil; +import org.opendaylight.groupbasedpolicy.sxp.ep.provider.api.EPToSgtMapper; +import org.opendaylight.groupbasedpolicy.sxp.ep.provider.spi.SxpEpProviderProvider; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.RendererName; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.Renderers; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.Renderer; @@ -54,11 +56,13 @@ public class PolicyManagerImpl implements PolicyManager { private static final String BASE_POLICY_MAP_NAME = "service-chains-"; private final DataBroker dataBroker; private final NodeManager nodeManager; + private final EPToSgtMapper epToSgtMapper; public PolicyManagerImpl(final DataBroker dataBroker, - final NodeManager nodeManager) { + final NodeManager nodeManager, final EPToSgtMapper epToSgtMapper) { this.dataBroker = Preconditions.checkNotNull(dataBroker); this.nodeManager = Preconditions.checkNotNull(nodeManager); + this.epToSgtMapper = Preconditions.checkNotNull(epToSgtMapper); } @Override @@ -152,11 +156,11 @@ public class PolicyManagerImpl implements PolicyManager { managementIpAddress, mountpoint); context.setPolicyMapLocation(policyMapLocation); - final Sgt sourceSgt = PolicyManagerUtil.findSgtTag(rendererEndpoint, dataAfter.getEndpoints() + final Sgt sourceSgt = PolicyManagerUtil.findSgtTag(epToSgtMapper, rendererEndpoint, dataAfter.getEndpoints() .getAddressEndpointWithLocation()); // Peer Endpoint for (PeerEndpoint peerEndpoint : rendererEndpoint.getPeerEndpoint()) { - final Sgt destinationSgt = PolicyManagerUtil.findSgtTag(peerEndpoint, dataAfter.getEndpoints() + final Sgt destinationSgt = PolicyManagerUtil.findSgtTag(epToSgtMapper, peerEndpoint, dataAfter.getEndpoints() .getAddressEndpointWithLocation()); if (sourceSgt == null || destinationSgt == null) { final String info = String.format("Endpoint-policy: missing sgt value(sourceSgt=%s, destinationSgt=%s)", diff --git a/renderers/ios-xe/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ios_xe_provider/impl/util/PolicyManagerUtil.java b/renderers/ios-xe/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ios_xe_provider/impl/util/PolicyManagerUtil.java index 2dcaa1b62..e9e9ee276 100644 --- a/renderers/ios-xe/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ios_xe_provider/impl/util/PolicyManagerUtil.java +++ b/renderers/ios-xe/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ios_xe_provider/impl/util/PolicyManagerUtil.java @@ -28,6 +28,7 @@ import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.manager.P import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.manager.PolicyManagerImpl; import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.manager.PolicyManagerImpl.ActionCase; import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.writer.PolicyWriterUtil; +import org.opendaylight.groupbasedpolicy.sxp.ep.provider.api.EPToSgtMapper; import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.rsp.rev140701.rendered.service.paths.RenderedServicePath; import org.opendaylight.yang.gen.v1.urn.ios.rev160308.ClassNameType; import org.opendaylight.yang.gen.v1.urn.ios.rev160308.PolicyActionType; @@ -198,13 +199,15 @@ public class PolicyManagerUtil { } @Nullable - public static Sgt findSgtTag(final AddressEndpointKey endpointKey, + public static Sgt findSgtTag(final EPToSgtMapper sxpEpProvider, final AddressEndpointKey endpointKey, final List endpointsWithLocation) { if (endpointKey == null || endpointsWithLocation == null) { return null; } final AddressEndpointWithLocation endpointWithLocation = RendererPolicyUtil.lookupEndpoint(endpointKey, endpointsWithLocation); + + //TODO: involve sxpEpProvider final AddressEndpointWithLocationAug augmentation = endpointWithLocation.getAugmentation(AddressEndpointWithLocationAug.class); if (augmentation == null) { return null; diff --git a/renderers/ios-xe/src/main/resources/org/opendaylight/blueprint/ios-xe-renderer.xml b/renderers/ios-xe/src/main/resources/org/opendaylight/blueprint/ios-xe-renderer.xml index 9803c23c2..d3177038a 100644 --- a/renderers/ios-xe/src/main/resources/org/opendaylight/blueprint/ios-xe-renderer.xml +++ b/renderers/ios-xe/src/main/resources/org/opendaylight/blueprint/ios-xe-renderer.xml @@ -6,11 +6,14 @@ + + \ No newline at end of file diff --git a/renderers/ios-xe/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ios_xe_provider/impl/manager/PolicyManagerImplTest.java b/renderers/ios-xe/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ios_xe_provider/impl/manager/PolicyManagerImplTest.java index 77d2aec16..f4006a79e 100644 --- a/renderers/ios-xe/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ios_xe_provider/impl/manager/PolicyManagerImplTest.java +++ b/renderers/ios-xe/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ios_xe_provider/impl/manager/PolicyManagerImplTest.java @@ -7,20 +7,8 @@ */ package org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.manager; -import static org.junit.Assert.assertTrue; -import static org.mockito.Matchers.eq; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; -import static org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.HasDirection.Direction.Out; -import static org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.EndpointPolicyParticipation.PROVIDER; -import static org.powermock.api.support.membermodification.MemberMatcher.method; -import static org.powermock.api.support.membermodification.MemberModifier.stub; - import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; -import java.util.Collections; -import java.util.List; -import java.util.Optional; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -29,6 +17,7 @@ import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction; import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.util.PolicyManagerUtil; import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.util.RendererPolicyUtil; import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.util.ServiceChainingUtil; +import org.opendaylight.groupbasedpolicy.sxp.ep.provider.api.EPToSgtMapper; import org.opendaylight.groupbasedpolicy.util.IetfModelCodec; import org.opendaylight.sfc.provider.api.SfcProviderServiceForwarderAPI; import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.common.rev151017.RspName; @@ -97,6 +86,19 @@ import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; import org.powermock.core.classloader.annotations.PrepareForTest; import org.powermock.modules.junit4.PowerMockRunner; +import java.util.Collections; +import java.util.List; +import java.util.Optional; + +import static org.junit.Assert.assertTrue; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; +import static org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.HasDirection.Direction.Out; +import static org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.EndpointPolicyParticipation.PROVIDER; +import static org.powermock.api.support.membermodification.MemberMatcher.method; +import static org.powermock.api.support.membermodification.MemberModifier.stub; + @RunWith(PowerMockRunner.class) @PrepareForTest({RendererPolicyUtil.class, PolicyManagerUtil.class, SfcProviderServiceForwarderAPI.class}) public class PolicyManagerImplTest { @@ -122,13 +124,15 @@ public class PolicyManagerImplTest { private PolicyManagerImpl policyManager; private DataBroker mountpoint; private NodeManager nodeManager; + private EPToSgtMapper epToSgtMapper; @Before public void init() { mountpoint = mock(DataBroker.class); ReadWriteTransaction readWriteTransaction = mock(ReadWriteTransaction.class); nodeManager = mock(NodeManager.class); - policyManager = new PolicyManagerImpl(mountpoint, nodeManager); + epToSgtMapper = mock(EPToSgtMapper.class); + policyManager = new PolicyManagerImpl(mountpoint, nodeManager, epToSgtMapper); when(mountpoint.newReadWriteTransaction()).thenReturn(readWriteTransaction); when(readWriteTransaction.submit()).thenReturn(Futures.immediateCheckedFuture(null)); } diff --git a/sxp-integration/sxp-ep-provider/src/main/config/default-config.xml b/sxp-integration/sxp-ep-provider/src/main/config/default-config.xml index 89a40b918..2e0812d4f 100755 --- a/sxp-integration/sxp-ep-provider/src/main/config/default-config.xml +++ b/sxp-integration/sxp-ep-provider/src/main/config/default-config.xml @@ -16,35 +16,8 @@ sxp-ep-provider:sxp-ep-provider-impl sxp-ep-provider-default-impl - - - binding:binding-async-data-broker - binding-data-broker - - - binding:binding-rpc-registry - binding-rpc-broker - - - - gbp:domain-specific-registry - - domain-specific-registry - - - - - sxp-ep-provider:sxp-ep-provider - - - - sxp-ep-provider-service - /modules/module[type='sxp-ep-provider-impl'][name='sxp-ep-provider-default-impl'] - - - diff --git a/sxp-integration/sxp-ep-provider/src/main/java/org/opendaylight/controller/config/yang/config/groupbasedpolicy/sxp_integration/sxp_ep_provider/SxpEpProviderProviderInstance.java b/sxp-integration/sxp-ep-provider/src/main/java/org/opendaylight/controller/config/yang/config/groupbasedpolicy/sxp_integration/sxp_ep_provider/SxpEpProviderProviderInstance.java new file mode 100644 index 000000000..59f18ec86 --- /dev/null +++ b/sxp-integration/sxp-ep-provider/src/main/java/org/opendaylight/controller/config/yang/config/groupbasedpolicy/sxp_integration/sxp_ep_provider/SxpEpProviderProviderInstance.java @@ -0,0 +1,105 @@ +/* + * 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.controller.config.yang.config.groupbasedpolicy.sxp_integration.sxp_ep_provider; + +import com.google.common.base.Preconditions; +import com.google.common.util.concurrent.Futures; +import com.google.common.util.concurrent.ListenableFuture; +import org.opendaylight.controller.config.yang.config.groupbasedpolicy.GroupbasedpolicyInstance; +import org.opendaylight.controller.md.sal.binding.api.DataBroker; +import org.opendaylight.groupbasedpolicy.api.DomainSpecificRegistry; +import org.opendaylight.groupbasedpolicy.sxp.ep.provider.api.EPPolicyTemplateProviderRegistry; +import org.opendaylight.groupbasedpolicy.sxp.ep.provider.api.EPToSgtMapper; +import org.opendaylight.groupbasedpolicy.sxp.ep.provider.impl.SxpEpProviderProviderImpl; +import org.opendaylight.groupbasedpolicy.sxp.ep.provider.spi.SxpEpProviderProvider; +import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonService; +import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceProvider; +import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceRegistration; +import org.opendaylight.mdsal.singleton.common.api.ServiceGroupIdentifier; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.BaseEndpointService; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.integration.sxp.ep.provider.rev160722.SgtGeneratorConfig; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class SxpEpProviderProviderInstance implements SxpEpProviderProvider, ClusterSingletonService, AutoCloseable { + + private static final Logger LOG = LoggerFactory.getLogger(SxpEpProviderProviderInstance.class); + + private static final ServiceGroupIdentifier IDENTIFIER = + ServiceGroupIdentifier.create(GroupbasedpolicyInstance.GBP_SERVICE_GROUP_IDENTIFIER); + + private final DataBroker dataBroker; + private final BaseEndpointService endpointService; + private final DomainSpecificRegistry registry; + private final ClusterSingletonServiceProvider clusterSingletonService; + private final SgtGeneratorConfig sgtGeneratorConfig; + private ClusterSingletonServiceRegistration singletonServiceRegistration; + private SxpEpProviderProviderImpl sxpEpProviderProvider; + + public SxpEpProviderProviderInstance(DataBroker dataBroker, BaseEndpointService endpointService, + DomainSpecificRegistry registry, + ClusterSingletonServiceProvider clusterSingletonService, + SgtGeneratorConfig sgtGeneratorConfig) { + this.dataBroker = Preconditions.checkNotNull(dataBroker); + this.endpointService = Preconditions.checkNotNull(endpointService); + this.registry = Preconditions.checkNotNull(registry); + this.clusterSingletonService = Preconditions.checkNotNull(clusterSingletonService); + this.sgtGeneratorConfig = Preconditions.checkNotNull(sgtGeneratorConfig); + } + + public void initialize() { + LOG.info("Clustering session initiated for {}", this.getClass().getSimpleName()); + singletonServiceRegistration = clusterSingletonService.registerClusterSingletonService(this); + } + + @Override + public void instantiateServiceInstance() { + LOG.info("Instantiating {}", this.getClass().getSimpleName()); + sxpEpProviderProvider = new SxpEpProviderProviderImpl(dataBroker, endpointService, registry, sgtGeneratorConfig); + } + + @Override + public ListenableFuture closeServiceInstance() { + LOG.info("Instance {} closed", this.getClass().getSimpleName()); + try { + sxpEpProviderProvider.close(); + } catch (Exception e) { + LOG.warn("Exception while closing ... {}", e.getMessage()); + } + return Futures.immediateFuture(null); + } + + @Override + public void close() throws Exception { + LOG.info("Clustering provider closed for {}", this.getClass().getSimpleName()); + if (singletonServiceRegistration != null) { + try { + singletonServiceRegistration.close(); + } catch (Exception e) { + LOG.warn("{} closed unexpectedly. Cause: {}", e.getMessage()); + } + singletonServiceRegistration = null; + } + } + + @Override + public ServiceGroupIdentifier getIdentifier() { + return IDENTIFIER; + } + + @Override + public EPToSgtMapper getEPToSgtMapper() { + return sxpEpProviderProvider.getEPToSgtMapper(); + } + + @Override + public EPPolicyTemplateProviderRegistry getEPPolicyTemplateProviderRegistry() { + return sxpEpProviderProvider.getEPPolicyTemplateProviderRegistry(); + } +} diff --git a/sxp-integration/sxp-ep-provider/src/main/java/org/opendaylight/controller/config/yang/config/groupbasedpolicy/sxp_integration/sxp_ep_provider/SxpEpProviderProviderModule.java b/sxp-integration/sxp-ep-provider/src/main/java/org/opendaylight/controller/config/yang/config/groupbasedpolicy/sxp_integration/sxp_ep_provider/SxpEpProviderProviderModule.java index 56458dbd2..181e007af 100644 --- a/sxp-integration/sxp-ep-provider/src/main/java/org/opendaylight/controller/config/yang/config/groupbasedpolicy/sxp_integration/sxp_ep_provider/SxpEpProviderProviderModule.java +++ b/sxp-integration/sxp-ep-provider/src/main/java/org/opendaylight/controller/config/yang/config/groupbasedpolicy/sxp_integration/sxp_ep_provider/SxpEpProviderProviderModule.java @@ -8,7 +8,8 @@ package org.opendaylight.controller.config.yang.config.groupbasedpolicy.sxp_integration.sxp_ep_provider; -import org.opendaylight.groupbasedpolicy.sxp.ep.provider.impl.SxpEpProviderProviderImpl; + +import org.opendaylight.controller.sal.common.util.NoopAutoCloseable; /** * sxp-ep-provider impl module @@ -29,8 +30,7 @@ public class SxpEpProviderProviderModule extends org.opendaylight.controller.con @Override public java.lang.AutoCloseable createInstance() { - return new SxpEpProviderProviderImpl(getDataBrokerDependency(), getRpcRegistryDependency(), - getDomainSpecificRegistryDependency()); + return NoopAutoCloseable.INSTANCE; } } diff --git a/sxp-integration/sxp-ep-provider/src/main/java/org/opendaylight/groupbasedpolicy/sxp/ep/provider/api/EPPolicyTemplateDaoFacade.java b/sxp-integration/sxp-ep-provider/src/main/java/org/opendaylight/groupbasedpolicy/sxp/ep/provider/api/EPPolicyTemplateDaoFacade.java index 25af1dab6..0737de9a6 100644 --- a/sxp-integration/sxp-ep-provider/src/main/java/org/opendaylight/groupbasedpolicy/sxp/ep/provider/api/EPPolicyTemplateDaoFacade.java +++ b/sxp-integration/sxp-ep-provider/src/main/java/org/opendaylight/groupbasedpolicy/sxp/ep/provider/api/EPPolicyTemplateDaoFacade.java @@ -9,7 +9,7 @@ package org.opendaylight.groupbasedpolicy.sxp.ep.provider.api; import org.opendaylight.groupbasedpolicy.sxp.ep.provider.impl.DSAsyncDao; -import org.opendaylight.groupbasedpolicy.sxp.ep.provider.impl.ReadableByKey; +import org.opendaylight.groupbasedpolicy.sxp.ep.provider.impl.ReadableAsyncByKey; import org.opendaylight.groupbasedpolicy.sxp.ep.provider.impl.dao.EpPolicyTemplateValueKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.integration.sxp.ep.provider.model.rev160302.sxp.ep.mapper.EndpointPolicyTemplateBySgt; import org.opendaylight.yang.gen.v1.urn.opendaylight.sxp.database.rev160308.Sgt; @@ -18,5 +18,5 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.sxp.database.rev160308.Sgt; * Purpose: union of template-dao and template provider consumer */ public interface EPPolicyTemplateDaoFacade extends TemplateProviderDistributionTarget, - DSAsyncDao, ReadableByKey { + DSAsyncDao, ReadableAsyncByKey { } diff --git a/sxp-integration/sxp-ep-provider/src/main/java/org/opendaylight/groupbasedpolicy/sxp/ep/provider/api/EPToSgtMapper.java b/sxp-integration/sxp-ep-provider/src/main/java/org/opendaylight/groupbasedpolicy/sxp/ep/provider/api/EPToSgtMapper.java new file mode 100644 index 000000000..2f4bbf6e3 --- /dev/null +++ b/sxp-integration/sxp-ep-provider/src/main/java/org/opendaylight/groupbasedpolicy/sxp/ep/provider/api/EPToSgtMapper.java @@ -0,0 +1,26 @@ +/* + * 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.sxp.ep.provider.api; + +import com.google.common.util.concurrent.ListenableFuture; +import java.util.Collection; +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.sxp.database.rev160308.Sgt; + +/** + * Purpose: expose endpoint to sgt mapping + */ +public interface EPToSgtMapper { + + /** + * @param endpointWithLocation peer which sgt is being searched for + * @return found sgt + */ + ListenableFuture> findSgtForEP(AddressEndpointWithLocation endpointWithLocation); +} diff --git a/sxp-integration/sxp-ep-provider/src/main/java/org/opendaylight/groupbasedpolicy/sxp/ep/provider/impl/EPToSgtMapperImpl.java b/sxp-integration/sxp-ep-provider/src/main/java/org/opendaylight/groupbasedpolicy/sxp/ep/provider/impl/EPToSgtMapperImpl.java new file mode 100644 index 000000000..3ec8e5ecf --- /dev/null +++ b/sxp-integration/sxp-ep-provider/src/main/java/org/opendaylight/groupbasedpolicy/sxp/ep/provider/impl/EPToSgtMapperImpl.java @@ -0,0 +1,60 @@ +/* + * 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.sxp.ep.provider.impl; + +import com.google.common.base.Function; +import com.google.common.util.concurrent.Futures; +import com.google.common.util.concurrent.ListenableFuture; +import java.util.Collection; +import java.util.HashSet; +import javax.annotation.Nullable; +import org.opendaylight.groupbasedpolicy.sxp.ep.provider.api.EPPolicyTemplateDaoFacade; +import org.opendaylight.groupbasedpolicy.sxp.ep.provider.api.EPToSgtMapper; +import org.opendaylight.groupbasedpolicy.sxp.ep.provider.impl.dao.EpPolicyTemplateValueKey; +import org.opendaylight.groupbasedpolicy.sxp.ep.provider.impl.dao.EpPolicyTemplateValueKeyFactory; +import org.opendaylight.groupbasedpolicy.sxp.ep.provider.impl.util.EPTemplateUtil; +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.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.integration.sxp.ep.provider.model.rev160302.sxp.ep.mapper.EndpointPolicyTemplateBySgt; +import org.opendaylight.yang.gen.v1.urn.opendaylight.sxp.database.rev160308.Sgt; + +/** + * Purpose: mapper implementation based on {@link ReadableAsyncByKey} (e.g.: {@link EPPolicyTemplateDaoFacade}) + */ +public class EPToSgtMapperImpl implements EPToSgtMapper { + + public static final Function, Collection> TRANSFORM_TEMPLATE_TO_SGT = + new Function, Collection>() { + @Nullable + @Override + public Collection apply(@Nullable final Collection input) { + final Collection sgtBag = new HashSet<>(); + for (EndpointPolicyTemplateBySgt template : input) { + sgtBag.add(template.getSgt()); + } + return sgtBag; + } + }; + + private final ReadableAsyncByKey epPolicyTemplateReader; + private final EpPolicyTemplateValueKeyFactory keyFactory; + + public EPToSgtMapperImpl(final ReadableAsyncByKey epPolicyTemplateReader) { + this.epPolicyTemplateReader = epPolicyTemplateReader; + keyFactory = new EpPolicyTemplateValueKeyFactory( + EPTemplateUtil.createEndpointGroupIdOrdering(), EPTemplateUtil.createConditionNameOrdering()); + + } + + @Override + public ListenableFuture> findSgtForEP(final AddressEndpointWithLocation endpointWithLocation) { + final EpPolicyTemplateValueKey rawKey = new EpPolicyTemplateValueKey(endpointWithLocation); + final EpPolicyTemplateValueKey key = keyFactory.sortValueKeyLists(rawKey); + return Futures.transform(epPolicyTemplateReader.readBy(key), TRANSFORM_TEMPLATE_TO_SGT); + } +} diff --git a/sxp-integration/sxp-ep-provider/src/main/java/org/opendaylight/groupbasedpolicy/sxp/ep/provider/impl/SgtGeneratorImpl.java b/sxp-integration/sxp-ep-provider/src/main/java/org/opendaylight/groupbasedpolicy/sxp/ep/provider/impl/SgtGeneratorImpl.java new file mode 100644 index 000000000..1c4ec7812 --- /dev/null +++ b/sxp-integration/sxp-ep-provider/src/main/java/org/opendaylight/groupbasedpolicy/sxp/ep/provider/impl/SgtGeneratorImpl.java @@ -0,0 +1,67 @@ +/* + * 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.sxp.ep.provider.impl; + +import com.google.common.collect.Iterables; +import com.google.common.collect.Ordering; +import com.google.common.collect.Range; +import org.opendaylight.groupbasedpolicy.sxp.ep.provider.impl.util.EPTemplateUtil; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.integration.sxp.ep.provider.model.rev160302.sxp.ep.mapper.EndpointPolicyTemplateBySgt; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.integration.sxp.ep.provider.rev160722.SgtGeneratorConfig; +import org.opendaylight.yang.gen.v1.urn.opendaylight.sxp.database.rev160308.Sgt; + +import java.util.Optional; + +/** + * Purpose: generate {@link Sgt} value on demand + */ +public class SgtGeneratorImpl { + private final Ordering sgtOrdering; + private Optional> sgtRange = Optional.empty(); + + public SgtGeneratorImpl(final SgtGeneratorConfig sgtGenerator) { + if (sgtGenerator != null) { + sgtRange = Optional.of( + Range.closed(sgtGenerator.getSgtLow().getValue(), sgtGenerator.getSgtHigh().getValue())); + } + sgtOrdering = EPTemplateUtil.createSgtOrdering(); + } + + /** + * @param templateCache source of used sgt items + * @return next free sgt + */ + public java.util.Optional generateNextSgt(SimpleCachedDao templateCache) { + return sgtRange.flatMap(range -> + findTopUsedSgt(templateCache.keySet()) + .map(topUsedSgt -> incrementSafely(range, topUsedSgt)) + ); + } + + private Optional findTopUsedSgt(final Iterable sgts) { + return java.util.Optional.ofNullable(sgts) + .filter(sgtBag -> !Iterables.isEmpty(sgtBag)) + .map(sgtOrdering::max); + } + + private Sgt incrementSafely(final Range range, final Sgt topUsedSgt) { + final Sgt applicableSgt; + + final int nextMax = topUsedSgt.getValue() + 1; + if (range.contains(nextMax)) { + applicableSgt = new Sgt(nextMax); + } else if (nextMax < range.lowerEndpoint()) { + applicableSgt = new Sgt(range.lowerEndpoint()); + } else { + applicableSgt = null; + } + + return applicableSgt; + } +} diff --git a/sxp-integration/sxp-ep-provider/src/main/java/org/opendaylight/groupbasedpolicy/sxp/ep/provider/impl/SimpleCachedDao.java b/sxp-integration/sxp-ep-provider/src/main/java/org/opendaylight/groupbasedpolicy/sxp/ep/provider/impl/SimpleCachedDao.java index 913274bd3..21ae5944d 100644 --- a/sxp-integration/sxp-ep-provider/src/main/java/org/opendaylight/groupbasedpolicy/sxp/ep/provider/impl/SimpleCachedDao.java +++ b/sxp-integration/sxp-ep-provider/src/main/java/org/opendaylight/groupbasedpolicy/sxp/ep/provider/impl/SimpleCachedDao.java @@ -47,4 +47,9 @@ public interface SimpleCachedDao extends SimpleDao { * @return unmodifiable iterator through all cached values */ Iterable values(); + + /** + * @return unmodifiable iterator through all cached keys + */ + Iterable keySet(); } diff --git a/sxp-integration/sxp-ep-provider/src/main/java/org/opendaylight/groupbasedpolicy/sxp/ep/provider/impl/SxpEpProviderProviderImpl.java b/sxp-integration/sxp-ep-provider/src/main/java/org/opendaylight/groupbasedpolicy/sxp/ep/provider/impl/SxpEpProviderProviderImpl.java index c20eb00a0..0542cd4c3 100644 --- a/sxp-integration/sxp-ep-provider/src/main/java/org/opendaylight/groupbasedpolicy/sxp/ep/provider/impl/SxpEpProviderProviderImpl.java +++ b/sxp-integration/sxp-ep-provider/src/main/java/org/opendaylight/groupbasedpolicy/sxp/ep/provider/impl/SxpEpProviderProviderImpl.java @@ -9,11 +9,11 @@ package org.opendaylight.groupbasedpolicy.sxp.ep.provider.impl; import org.opendaylight.controller.md.sal.binding.api.DataBroker; -import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry; import org.opendaylight.groupbasedpolicy.api.DomainSpecificRegistry; import org.opendaylight.groupbasedpolicy.api.EndpointAugmentor; import org.opendaylight.groupbasedpolicy.sxp.ep.provider.api.EPPolicyTemplateDaoFacade; import org.opendaylight.groupbasedpolicy.sxp.ep.provider.api.EPPolicyTemplateProviderRegistry; +import org.opendaylight.groupbasedpolicy.sxp.ep.provider.api.EPToSgtMapper; import org.opendaylight.groupbasedpolicy.sxp.ep.provider.impl.dao.EPForwardingTemplateDaoImpl; import org.opendaylight.groupbasedpolicy.sxp.ep.provider.impl.dao.EPPolicyTemplateDaoFacadeImpl; import org.opendaylight.groupbasedpolicy.sxp.ep.provider.impl.dao.EPPolicyTemplateDaoImpl; @@ -30,6 +30,7 @@ import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types. import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.BaseEndpointService; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.integration.sxp.ep.provider.model.rev160302.sxp.ep.mapper.EndpointForwardingTemplateBySubnet; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.integration.sxp.ep.provider.model.rev160302.sxp.ep.mapper.EndpointPolicyTemplateBySgt; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.integration.sxp.ep.provider.rev160722.SgtGeneratorConfig; import org.opendaylight.yang.gen.v1.urn.opendaylight.sxp.database.rev160308.Sgt; import org.opendaylight.yang.gen.v1.urn.opendaylight.sxp.database.rev160308.master.database.fields.MasterDatabaseBinding; import org.slf4j.Logger; @@ -48,41 +49,50 @@ public class SxpEpProviderProviderImpl implements SxpEpProviderProvider { private final DomainSpecificRegistry domainSpecificRegistry; private final EndpointAugmentor sxpEndpointAugmentor; private final EPPolicyTemplateProviderRegistry epPolicyTemplateRegistry; + private final EPToSgtMapper epToSgtMapper; - public SxpEpProviderProviderImpl(final DataBroker dataBroker, final RpcProviderRegistry rpcRegistryDependency, - final DomainSpecificRegistry domainSpecificRegistry) { + public SxpEpProviderProviderImpl(final DataBroker dataBroker, final BaseEndpointService endpointService, + final DomainSpecificRegistry domainSpecificRegistry, final SgtGeneratorConfig sgtGeneratorConfig) { LOG.info("starting SxmMapper .."); this.domainSpecificRegistry = domainSpecificRegistry; - epPolicyTemplateRegistry = new EPPolicyTemplateProviderRegistryImpl(); - - final BaseEndpointService endpointService = rpcRegistryDependency.getRpcService(BaseEndpointService.class); + // low level reactor final SxpMapperReactor sxpMapperReactor = new SxpMapperReactorImpl(endpointService, dataBroker); + // cached dao layer for templates and master-database final SimpleCachedDao epPolicyTemplateCachedDao = new SimpleCachedDaoImpl<>(); final SimpleCachedDao epForwardingTemplateCachedDao = new SimpleCachedDaoEPForwardingTemplateImpl(); final SimpleCachedDao masterDBBindingCachedDao = new SimpleCachedDaoImpl<>(); + // reading dao layer for templates and master-database final EpPolicyTemplateValueKeyFactory epPolicyTemplateKeyFactory = new EpPolicyTemplateValueKeyFactory( EPTemplateUtil.createEndpointGroupIdOrdering(), EPTemplateUtil.createConditionNameOrdering()); final EPPolicyTemplateDaoImpl epPolicyTemplateDao = new EPPolicyTemplateDaoImpl(dataBroker, epPolicyTemplateCachedDao, epPolicyTemplateKeyFactory); - final EPPolicyTemplateDaoFacade epPolicyTemplateDaoFacade = new EPPolicyTemplateDaoFacadeImpl(dataBroker, epPolicyTemplateDao); - epPolicyTemplateRegistry.addDistributionTarget(epPolicyTemplateDaoFacade); - final EPForwardingTemplateDaoImpl epForwardingTemplateDao = new EPForwardingTemplateDaoImpl(dataBroker, epForwardingTemplateCachedDao); - final MasterDatabaseBindingDaoImpl masterDBBindingDao = new MasterDatabaseBindingDaoImpl(dataBroker, masterDBBindingCachedDao); + // facade for ep-policy-template: reading dao + consumer of ise provider + template generator + final SgtGeneratorImpl sgtGeneratorImpl = new SgtGeneratorImpl(sgtGeneratorConfig); + final EPPolicyTemplateDaoFacade epPolicyTemplateDaoFacade = new EPPolicyTemplateDaoFacadeImpl(dataBroker, + epPolicyTemplateDao, epPolicyTemplateCachedDao, sgtGeneratorImpl); + epPolicyTemplateRegistry = new EPPolicyTemplateProviderRegistryImpl(); + epPolicyTemplateRegistry.addDistributionTarget(epPolicyTemplateDaoFacade); + epToSgtMapper = new EPToSgtMapperImpl(epPolicyTemplateDaoFacade); + + // DS-listeners for templates and master-database sxpDatabaseListener = new MasterDatabaseBindingListenerImpl(dataBroker, sxpMapperReactor, masterDBBindingCachedDao, epPolicyTemplateDaoFacade, epForwardingTemplateDao); epPolicyTemplateListener = new EPPolicyTemplateListenerImpl(dataBroker, sxpMapperReactor, epPolicyTemplateCachedDao, masterDBBindingDao, epForwardingTemplateDao); epForwardingTemplateListener = new EPForwardingTemplateListenerImpl(dataBroker, sxpMapperReactor, epForwardingTemplateCachedDao, masterDBBindingDao, epPolicyTemplateDaoFacade); - sxpEndpointAugmentor = new SxpEndpointAugmentorImpl(epPolicyTemplateDaoFacade, epPolicyTemplateKeyFactory); + + // sxp-ep-augmentor -> deprecated, will use ep2sxpMapper service + sxpEndpointAugmentor = new SxpEndpointAugmentorImpl(epPolicyTemplateDao, epPolicyTemplateKeyFactory); domainSpecificRegistry.getEndpointAugmentorRegistry().register(sxpEndpointAugmentor); + LOG.info("started SxmMapper"); } @@ -91,6 +101,11 @@ public class SxpEpProviderProviderImpl implements SxpEpProviderProvider { return epPolicyTemplateRegistry; } + @Override + public EPToSgtMapper getEPToSgtMapper() { + return epToSgtMapper; + } + @Override public void close() throws Exception { sxpDatabaseListener.close(); diff --git a/sxp-integration/sxp-ep-provider/src/main/java/org/opendaylight/groupbasedpolicy/sxp/ep/provider/impl/dao/EPPolicyTemplateDaoFacadeImpl.java b/sxp-integration/sxp-ep-provider/src/main/java/org/opendaylight/groupbasedpolicy/sxp/ep/provider/impl/dao/EPPolicyTemplateDaoFacadeImpl.java index e23064c67..fa3f457c1 100644 --- a/sxp-integration/sxp-ep-provider/src/main/java/org/opendaylight/groupbasedpolicy/sxp/ep/provider/impl/dao/EPPolicyTemplateDaoFacadeImpl.java +++ b/sxp-integration/sxp-ep-provider/src/main/java/org/opendaylight/groupbasedpolicy/sxp/ep/provider/impl/dao/EPPolicyTemplateDaoFacadeImpl.java @@ -14,6 +14,7 @@ import com.google.common.util.concurrent.AsyncFunction; import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; import java.util.Collection; +import java.util.Collections; import javax.annotation.Nonnull; import javax.annotation.Nullable; import org.opendaylight.controller.md.sal.binding.api.DataBroker; @@ -21,6 +22,8 @@ import org.opendaylight.controller.md.sal.binding.api.WriteTransaction; import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; import org.opendaylight.groupbasedpolicy.sxp.ep.provider.api.EPPolicyTemplateDaoFacade; import org.opendaylight.groupbasedpolicy.sxp.ep.provider.api.EPPolicyTemplateProvider; +import org.opendaylight.groupbasedpolicy.sxp.ep.provider.impl.SgtGeneratorImpl; +import org.opendaylight.groupbasedpolicy.sxp.ep.provider.impl.SimpleCachedDao; import org.opendaylight.groupbasedpolicy.util.IidFactory; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.Description; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.EndpointGroupId; @@ -28,7 +31,9 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.EndpointGroup; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.EndpointGroupBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.integration.sxp.ep.provider.model.rev160302.SxpEpMapper; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.integration.sxp.ep.provider.model.rev160302.TemplateGenerated; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.integration.sxp.ep.provider.model.rev160302.sxp.ep.mapper.EndpointPolicyTemplateBySgt; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.integration.sxp.ep.provider.model.rev160302.sxp.ep.mapper.EndpointPolicyTemplateBySgtBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.integration.sxp.ep.provider.model.rev160302.sxp.ep.mapper.EndpointPolicyTemplateBySgtKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.sxp.database.rev160308.Sgt; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; @@ -43,13 +48,19 @@ public class EPPolicyTemplateDaoFacadeImpl implements EPPolicyTemplateDaoFacade private static final Logger LOG = LoggerFactory.getLogger(EPPolicyTemplateDaoFacadeImpl.class); private final EPPolicyTemplateDaoImpl epPolicyTemplateDao; + private final SimpleCachedDao epPolicyTemplateCachedDao; + private final SgtGeneratorImpl sgtGenerator; private final DataBroker dataBroker; private EPPolicyTemplateProvider templateProvider; - public EPPolicyTemplateDaoFacadeImpl(final DataBroker dataBroker, final EPPolicyTemplateDaoImpl epPolicyTemplateDao) { + public EPPolicyTemplateDaoFacadeImpl(final DataBroker dataBroker, final EPPolicyTemplateDaoImpl epPolicyTemplateDao, + final SimpleCachedDao epPolicyTemplateCachedDao, + final SgtGeneratorImpl sgtGenerator) { this.dataBroker = dataBroker; this.epPolicyTemplateDao = epPolicyTemplateDao; + this.epPolicyTemplateCachedDao = epPolicyTemplateCachedDao; + this.sgtGenerator = sgtGenerator; } @Override @@ -106,10 +117,10 @@ public class EPPolicyTemplateDaoFacadeImpl implements EPPolicyTemplateDaoFacade .child(EndpointPolicyTemplateBySgt.class, new EndpointPolicyTemplateBySgtKey(sgtValue)); wTx.put(LogicalDatastoreType.CONFIGURATION, epPolicyTemplatePath, template, true); - return Futures.transform(wTx.submit(), createStoreOutcomeHandler(template)); + return Futures.transform(wTx.submit(), createStoreOutcomeHandlerToOptional(template)); } - private Function> createStoreOutcomeHandler(final EndpointPolicyTemplateBySgt template) { + private Function> createStoreOutcomeHandlerToOptional(final EndpointPolicyTemplateBySgt template) { return new Function>() { @Nullable @Override @@ -119,8 +130,55 @@ public class EPPolicyTemplateDaoFacadeImpl implements EPPolicyTemplateDaoFacade }; } + private Function> createStoreOutcomeHandlerToCollection(final EndpointPolicyTemplateBySgt template) { + return new Function>() { + @Nullable + @Override + public Collection apply(@Nullable final Void aVoid) { + return Collections.singletonList(template); + } + }; + } + @Override - public Collection readBy(@Nonnull final EpPolicyTemplateValueKey specialKey) { - return epPolicyTemplateDao.readBy(specialKey); + public ListenableFuture> readBy(@Nonnull final EpPolicyTemplateValueKey templateLookupKey) { + //TODO: expose to ios-xe renderer, + final Collection templatesFromDao = epPolicyTemplateDao.readBy(templateLookupKey); + final ListenableFuture> result; + if (!templatesFromDao.isEmpty()) { + result = Futures.immediateFuture(templatesFromDao); + } else { + // generate + result = sgtGenerator.generateNextSgt(epPolicyTemplateCachedDao) + // build ep-policy-template + .map(sgt -> buildEpPolicyTemplate(templateLookupKey, sgt)) + // store the template + .map(this::storeTemplate) + .orElse(Futures.immediateFuture(Collections.emptyList())); + } + return result; + } + + private ListenableFuture> storeTemplate(final EndpointPolicyTemplateBySgt template) { + final WriteTransaction wTx = dataBroker.newWriteOnlyTransaction(); + // store ep-policy-template + final Sgt sgt = template.getSgt(); + LOG.trace("storing generated epPolicyTemplate: {}", sgt.getValue()); + final InstanceIdentifier epPolicyTemplatePath = InstanceIdentifier + .create(SxpEpMapper.class) + .child(EndpointPolicyTemplateBySgt.class, new EndpointPolicyTemplateBySgtKey(sgt)); + wTx.put(LogicalDatastoreType.CONFIGURATION, epPolicyTemplatePath, template, true); + + return Futures.transform(wTx.submit(), createStoreOutcomeHandlerToCollection(template)); + } + + private EndpointPolicyTemplateBySgt buildEpPolicyTemplate(final EpPolicyTemplateValueKey templateLookupKey, final Sgt sgt) { + return new EndpointPolicyTemplateBySgtBuilder() + .setOrigin(TemplateGenerated.class) + .setTenant(templateLookupKey.getTenantId()) + .setSgt(sgt) + .setEndpointGroups(templateLookupKey.getEpgId()) + .setConditions(templateLookupKey.getConditionName()) + .build(); } } diff --git a/sxp-integration/sxp-ep-provider/src/main/java/org/opendaylight/groupbasedpolicy/sxp/ep/provider/impl/dao/SimpleCachedDaoEPForwardingTemplateImpl.java b/sxp-integration/sxp-ep-provider/src/main/java/org/opendaylight/groupbasedpolicy/sxp/ep/provider/impl/dao/SimpleCachedDaoEPForwardingTemplateImpl.java index 5ae7af372..d08f83b75 100644 --- a/sxp-integration/sxp-ep-provider/src/main/java/org/opendaylight/groupbasedpolicy/sxp/ep/provider/impl/dao/SimpleCachedDaoEPForwardingTemplateImpl.java +++ b/sxp-integration/sxp-ep-provider/src/main/java/org/opendaylight/groupbasedpolicy/sxp/ep/provider/impl/dao/SimpleCachedDaoEPForwardingTemplateImpl.java @@ -125,4 +125,10 @@ public class SimpleCachedDaoEPForwardingTemplateImpl implements SimpleCachedDao< public Iterable values() { return Iterables.unmodifiableIterable(Iterables.concat(plainCache.values(), subnetCache.values())); } + + @Override + public Iterable keySet() { + // bypassing subnets + return Iterables.unmodifiableIterable(plainCache.keySet()); + } } diff --git a/sxp-integration/sxp-ep-provider/src/main/java/org/opendaylight/groupbasedpolicy/sxp/ep/provider/impl/dao/SimpleCachedDaoImpl.java b/sxp-integration/sxp-ep-provider/src/main/java/org/opendaylight/groupbasedpolicy/sxp/ep/provider/impl/dao/SimpleCachedDaoImpl.java index a6c162971..c5786b042 100644 --- a/sxp-integration/sxp-ep-provider/src/main/java/org/opendaylight/groupbasedpolicy/sxp/ep/provider/impl/dao/SimpleCachedDaoImpl.java +++ b/sxp-integration/sxp-ep-provider/src/main/java/org/opendaylight/groupbasedpolicy/sxp/ep/provider/impl/dao/SimpleCachedDaoImpl.java @@ -58,4 +58,9 @@ public class SimpleCachedDaoImpl implements SimpleCache public Iterable values() { return Iterables.unmodifiableIterable(cache.values()); } + + @Override + public Iterable keySet() { + return Iterables.unmodifiableIterable(cache.keySet()); + } } diff --git a/sxp-integration/sxp-ep-provider/src/main/java/org/opendaylight/groupbasedpolicy/sxp/ep/provider/impl/listen/EPPolicyTemplateListenerImpl.java b/sxp-integration/sxp-ep-provider/src/main/java/org/opendaylight/groupbasedpolicy/sxp/ep/provider/impl/listen/EPPolicyTemplateListenerImpl.java index 9fa8be05c..4b70c55b6 100644 --- a/sxp-integration/sxp-ep-provider/src/main/java/org/opendaylight/groupbasedpolicy/sxp/ep/provider/impl/listen/EPPolicyTemplateListenerImpl.java +++ b/sxp-integration/sxp-ep-provider/src/main/java/org/opendaylight/groupbasedpolicy/sxp/ep/provider/impl/listen/EPPolicyTemplateListenerImpl.java @@ -32,6 +32,7 @@ import org.opendaylight.groupbasedpolicy.sxp.ep.provider.impl.util.EPTemplateUti import org.opendaylight.groupbasedpolicy.sxp.ep.provider.impl.util.L3EPServiceUtil; import org.opendaylight.groupbasedpolicy.sxp.ep.provider.impl.util.SxpListenerUtil; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefix; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.integration.sxp.ep.provider.model.rev160302.TemplateGenerated; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.integration.sxp.ep.provider.model.rev160302.sxp.ep.mapper.EndpointForwardingTemplateBySubnet; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.integration.sxp.ep.provider.model.rev160302.sxp.ep.mapper.EndpointPolicyTemplateBySgt; import org.opendaylight.yang.gen.v1.urn.opendaylight.sxp.database.rev160308.Sgt; @@ -89,7 +90,13 @@ public class EPPolicyTemplateListenerImpl implements EPTemplateListener, List>> diff --git a/sxp-integration/sxp-ep-provider/src/main/java/org/opendaylight/groupbasedpolicy/sxp/ep/provider/impl/util/EPTemplateUtil.java b/sxp-integration/sxp-ep-provider/src/main/java/org/opendaylight/groupbasedpolicy/sxp/ep/provider/impl/util/EPTemplateUtil.java index c3b89e16d..300ef8d36 100644 --- a/sxp-integration/sxp-ep-provider/src/main/java/org/opendaylight/groupbasedpolicy/sxp/ep/provider/impl/util/EPTemplateUtil.java +++ b/sxp-integration/sxp-ep-provider/src/main/java/org/opendaylight/groupbasedpolicy/sxp/ep/provider/impl/util/EPTemplateUtil.java @@ -25,6 +25,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.EndpointGroupId; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.integration.sxp.ep.provider.model.rev160302.sxp.ep.mapper.EndpointForwardingTemplateBySubnet; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.integration.sxp.ep.provider.model.rev160302.sxp.ep.mapper.EndpointPolicyTemplateBySgt; +import org.opendaylight.yang.gen.v1.urn.opendaylight.sxp.database.rev160308.Sgt; /** * Purpose: util methods for {@link EndpointForwardingTemplateBySubnet} and {@link EndpointPolicyTemplateBySgt} @@ -128,6 +129,19 @@ public final class EPTemplateUtil { }); } + public static Ordering createSgtOrdering() { + return Ordering.natural().onResultOf(new Function() { + @Nullable + @Override + public Comparable apply(@Nullable final Sgt input) { + if (input == null) { + return EMPTY_COMPARABLE; + } + return MoreObjects.firstNonNull(input.getValue(), EMPTY_COMPARABLE); + } + }); + } + public static class OptionalMutablePair extends MutablePair, Optional> { public OptionalMutablePair() { super(Optional.absent(), Optional.absent()); diff --git a/sxp-integration/sxp-ep-provider/src/main/java/org/opendaylight/groupbasedpolicy/sxp/ep/provider/spi/SxpEpProviderProvider.java b/sxp-integration/sxp-ep-provider/src/main/java/org/opendaylight/groupbasedpolicy/sxp/ep/provider/spi/SxpEpProviderProvider.java index 3f9042afa..654457d79 100644 --- a/sxp-integration/sxp-ep-provider/src/main/java/org/opendaylight/groupbasedpolicy/sxp/ep/provider/spi/SxpEpProviderProvider.java +++ b/sxp-integration/sxp-ep-provider/src/main/java/org/opendaylight/groupbasedpolicy/sxp/ep/provider/spi/SxpEpProviderProvider.java @@ -10,6 +10,7 @@ package org.opendaylight.groupbasedpolicy.sxp.ep.provider.spi; import org.opendaylight.groupbasedpolicy.sxp.ep.provider.api.EPPolicyTemplateProvider; import org.opendaylight.groupbasedpolicy.sxp.ep.provider.api.EPPolicyTemplateProviderRegistry; +import org.opendaylight.groupbasedpolicy.sxp.ep.provider.api.EPToSgtMapper; /** * Purpose: spi for sxp-ep-provider @@ -20,4 +21,9 @@ public interface SxpEpProviderProvider extends AutoCloseable { * @return registry point for {@link EPPolicyTemplateProvider} */ EPPolicyTemplateProviderRegistry getEPPolicyTemplateProviderRegistry(); + + /** + * @return endpoint-to-sgt mapper + */ + EPToSgtMapper getEPToSgtMapper(); } diff --git a/sxp-integration/sxp-ep-provider/src/main/resources/org/opendaylight/blueprint/sxp-mapper.xml b/sxp-integration/sxp-ep-provider/src/main/resources/org/opendaylight/blueprint/sxp-mapper.xml new file mode 100644 index 000000000..118741a85 --- /dev/null +++ b/sxp-integration/sxp-ep-provider/src/main/resources/org/opendaylight/blueprint/sxp-mapper.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + 100 + 200 + + ]]> + + + + + + + + + + + + \ No newline at end of file diff --git a/sxp-integration/sxp-ep-provider/src/main/yang/sxp-ep-provider-cfg.yang b/sxp-integration/sxp-ep-provider/src/main/yang/sxp-ep-provider-cfg.yang index 84bca8605..89a6155f8 100644 --- a/sxp-integration/sxp-ep-provider/src/main/yang/sxp-ep-provider-cfg.yang +++ b/sxp-integration/sxp-ep-provider/src/main/yang/sxp-ep-provider-cfg.yang @@ -14,6 +14,7 @@ module sxp-ep-provider-cfg { import config { prefix config; revision-date 2013-04-05; } import opendaylight-md-sal-binding { prefix mdsal; revision-date 2013-10-28; } import groupbasedpolicy-cfg {prefix gbpcfg; revision-date 2015-11-06; } + import sxp-database { prefix sxp-database; revision-date 2016-03-08; } description "This module contains the base YANG definitions for @@ -45,34 +46,20 @@ module sxp-ep-provider-cfg { augment "/config:modules/config:module/config:configuration" { case sxp-ep-provider-impl { when "/config:modules/config:module/config:type = 'sxp-ep-provider-impl'"; + } + } - //wires in the data-broker service - container data-broker { - uses config:service-ref { - refine type { - mandatory true; - config:required-identity mdsal:binding-async-data-broker; - } - } - } - //RPC Registry - container rpc-registry { - uses config:service-ref { - refine type { - mandatory true; - config:required-identity mdsal:binding-rpc-registry; - } - } - } - //Domain specific registry - container domain-specific-registry { - uses config:service-ref { - refine type { - mandatory true; - config:required-identity gbpcfg:domain-specific-registry; - } - } - } + container sgt-generator-config { + description "sgt-generator configuration"; + leaf sgt-low { + type sxp-database:sgt; + mandatory true; + description "minimal SGT value to be used by sgt-generator"; + } + leaf sgt-high { + type sxp-database:sgt; + mandatory true; + description "maximal SGT value to be used by sgt-generator"; } } } diff --git a/sxp-integration/sxp-ep-provider/src/test/java/org/opendaylight/controller/config/yang/config/groupbasedpolicy/sxp_integration/sxp_ep_provider/SxpEpProviderProviderInstanceTest.java b/sxp-integration/sxp-ep-provider/src/test/java/org/opendaylight/controller/config/yang/config/groupbasedpolicy/sxp_integration/sxp_ep_provider/SxpEpProviderProviderInstanceTest.java new file mode 100644 index 000000000..9824b4e07 --- /dev/null +++ b/sxp-integration/sxp-ep-provider/src/test/java/org/opendaylight/controller/config/yang/config/groupbasedpolicy/sxp_integration/sxp_ep_provider/SxpEpProviderProviderInstanceTest.java @@ -0,0 +1,155 @@ +/* + * 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.controller.config.yang.config.groupbasedpolicy.sxp_integration.sxp_ep_provider; + +import static org.powermock.api.mockito.PowerMockito.verifyNew; +import static org.powermock.api.mockito.PowerMockito.whenNew; + +import com.google.common.util.concurrent.ListenableFuture; +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Matchers; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.opendaylight.controller.md.sal.binding.api.DataBroker; +import org.opendaylight.controller.sal.binding.api.BindingAwareBroker; +import org.opendaylight.groupbasedpolicy.api.DomainSpecificRegistry; +import org.opendaylight.groupbasedpolicy.sxp.ep.provider.api.EPPolicyTemplateProviderRegistry; +import org.opendaylight.groupbasedpolicy.sxp.ep.provider.api.EPToSgtMapper; +import org.opendaylight.groupbasedpolicy.sxp.ep.provider.impl.SxpEpProviderProviderImpl; +import org.opendaylight.groupbasedpolicy.sxp.ep.provider.spi.SxpEpProviderProvider; +import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonService; +import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceProvider; +import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceRegistration; +import org.opendaylight.mdsal.singleton.common.api.ServiceGroupIdentifier; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.BaseEndpointService; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.integration.sxp.ep.provider.rev160722.SgtGeneratorConfig; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +/** + * Test for {@link SxpEpProviderProviderInstance}. + */ +@RunWith(PowerMockRunner.class) +@PrepareForTest({SxpEpProviderProviderInstance.class}) +public class SxpEpProviderProviderInstanceTest { + + @Mock + private DataBroker dataBroker; + @Mock + private BindingAwareBroker bindingAwareBroker; + @Mock + private ClusterSingletonServiceProvider clusterSingletonService; + @Mock + private BaseEndpointService endpointService; + @Mock + private DomainSpecificRegistry domainSpecificRegistry; + @Mock + private SgtGeneratorConfig sgtGeneratorConfig; + @Mock + private SxpEpProviderProvider sxpEpProvider; + @Mock + private ClusterSingletonServiceRegistration clusterSingletonRegistration; + @Mock + private SxpEpProviderProviderImpl sxpEpProviderProvider; + @Mock + private EPToSgtMapper epToSgtMapper; + @Mock + private EPPolicyTemplateProviderRegistry epPolicyTemplateProviderRegistry; + + private SxpEpProviderProviderInstance instance; + + @Before + public void setUp() throws Exception { + Mockito.when(clusterSingletonService.registerClusterSingletonService(Matchers.any())) + .thenReturn(clusterSingletonRegistration); + Mockito.when(sxpEpProviderProvider.getEPToSgtMapper()).thenReturn(epToSgtMapper); + Mockito.when(sxpEpProviderProvider.getEPPolicyTemplateProviderRegistry()).thenReturn(epPolicyTemplateProviderRegistry); + + whenNew(SxpEpProviderProviderImpl.class) + .withArguments(dataBroker, endpointService, domainSpecificRegistry, sgtGeneratorConfig) + .thenReturn(sxpEpProviderProvider); + + instance = new SxpEpProviderProviderInstance(dataBroker, endpointService, domainSpecificRegistry, + clusterSingletonService, sgtGeneratorConfig); + } + + @After + public void tearDown() throws Exception { + Mockito.verifyNoMoreInteractions(dataBroker, bindingAwareBroker, clusterSingletonService, sxpEpProvider, + clusterSingletonRegistration, sgtGeneratorConfig, endpointService, domainSpecificRegistry); + } + + @Test + public void testInitialize() throws Exception { + instance.initialize(); + Mockito.verify(clusterSingletonService).registerClusterSingletonService(instance); + } + + @Test + public void testInstantiateServiceInstance() throws Exception { + instance.instantiateServiceInstance(); + + verifyNew(SxpEpProviderProviderImpl.class).withArguments(dataBroker, endpointService, domainSpecificRegistry, + sgtGeneratorConfig); + } + + @Test + public void testCloseServiceInstance() throws Exception { + instance.instantiateServiceInstance(); + final ListenableFuture future = instance.closeServiceInstance(); + + Mockito.verify(sxpEpProviderProvider).close(); + Assert.assertTrue(future.isDone()); + Assert.assertNull(future.get()); + } + + @Test + public void testCloseServiceInstance_null() throws Exception { + final ListenableFuture future = instance.closeServiceInstance(); + + Assert.assertTrue(future.isDone()); + Assert.assertNull(future.get()); + } + + @Test + public void testClose() throws Exception { + instance.initialize(); + Mockito.verify(clusterSingletonService).registerClusterSingletonService(instance); + + instance.close(); + Mockito.verify(clusterSingletonRegistration).close(); + } + + @Test + public void testClose_null() throws Exception { + instance.close(); + } + + @Test + public void testGetIdentifier() throws Exception { + final ServiceGroupIdentifier identifier = instance.getIdentifier(); + Assert.assertEquals("gbp-service-group-identifier", identifier.getValue()); + } + + @Test + public void testGetEPToSgtMapper() throws Exception { + instance.instantiateServiceInstance(); + Assert.assertEquals(epToSgtMapper, instance.getEPToSgtMapper()); + } + + @Test + public void testGetEPPolicyTemplateProviderRegistry() throws Exception { + instance.instantiateServiceInstance(); + Assert.assertEquals(epPolicyTemplateProviderRegistry, instance.getEPPolicyTemplateProviderRegistry()); + } +} \ No newline at end of file diff --git a/sxp-integration/sxp-ep-provider/src/test/java/org/opendaylight/groupbasedpolicy/sxp/ep/provider/impl/EPToSgtMapperImplTest.java b/sxp-integration/sxp-ep-provider/src/test/java/org/opendaylight/groupbasedpolicy/sxp/ep/provider/impl/EPToSgtMapperImplTest.java new file mode 100644 index 000000000..bf67d7216 --- /dev/null +++ b/sxp-integration/sxp-ep-provider/src/test/java/org/opendaylight/groupbasedpolicy/sxp/ep/provider/impl/EPToSgtMapperImplTest.java @@ -0,0 +1,79 @@ +/* + * 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.sxp.ep.provider.impl; + +import com.google.common.collect.Iterables; +import com.google.common.util.concurrent.Futures; +import com.google.common.util.concurrent.ListenableFuture; +import java.util.Collection; +import java.util.Collections; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Matchers; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.runners.MockitoJUnitRunner; +import org.opendaylight.groupbasedpolicy.sxp.ep.provider.impl.dao.EpPolicyTemplateValueKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.EndpointGroupId; +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.renderer.policy.configuration.endpoints.AddressEndpointWithLocation; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.endpoints.AddressEndpointWithLocationBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.integration.sxp.ep.provider.model.rev160302.TemplateGenerated; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.integration.sxp.ep.provider.model.rev160302.sxp.ep.mapper.EndpointPolicyTemplateBySgt; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.integration.sxp.ep.provider.model.rev160302.sxp.ep.mapper.EndpointPolicyTemplateBySgtBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.sxp.database.rev160308.Sgt; + +/** + * Test for {@link EPToSgtMapperImpl}. + */ +@RunWith(MockitoJUnitRunner.class) +public class EPToSgtMapperImplTest { + + private static final EndpointGroupId EPG_ID = new EndpointGroupId("epg-42"); + private static final TenantId TENANT_ID = new TenantId("tenant-01"); + private static final Sgt SGT = new Sgt(42); + + @Mock + private ReadableAsyncByKey templateReader; + + private EPToSgtMapperImpl mapper; + + @Before + public void setUp() throws Exception { + mapper = new EPToSgtMapperImpl(templateReader); + } + + @Test + public void testFindSgtForEP() throws Exception { + final AddressEndpointWithLocation epWithLocation = new AddressEndpointWithLocationBuilder() + .setEndpointGroup(Collections.singletonList(EPG_ID)) + .setTenant(TENANT_ID) + .setCondition(Collections.emptyList()) + .build(); + + final EndpointPolicyTemplateBySgt epPolicyTemplate = new EndpointPolicyTemplateBySgtBuilder() + .setConditions(epWithLocation.getCondition()) + .setTenant(epWithLocation.getTenant()) + .setEndpointGroups(epWithLocation.getEndpointGroup()) + .setSgt(SGT) + .setOrigin(TemplateGenerated.class) + .build(); + + Mockito.when(templateReader.readBy(Matchers.any())) + .thenReturn(Futures.immediateFuture(Collections.singletonList(epPolicyTemplate))); + + final ListenableFuture> sgtForEP = mapper.findSgtForEP(epWithLocation); + Assert.assertTrue(sgtForEP.isDone()); + final Collection sgts = sgtForEP.get(); + Assert.assertEquals(1, sgts.size()); + Assert.assertEquals(SGT, Iterables.getFirst(sgts, null)); + } +} \ No newline at end of file diff --git a/sxp-integration/sxp-ep-provider/src/test/java/org/opendaylight/groupbasedpolicy/sxp/ep/provider/impl/SgtGeneratorImplTest.java b/sxp-integration/sxp-ep-provider/src/test/java/org/opendaylight/groupbasedpolicy/sxp/ep/provider/impl/SgtGeneratorImplTest.java new file mode 100644 index 000000000..2d5b46ca8 --- /dev/null +++ b/sxp-integration/sxp-ep-provider/src/test/java/org/opendaylight/groupbasedpolicy/sxp/ep/provider/impl/SgtGeneratorImplTest.java @@ -0,0 +1,81 @@ +/* + * 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.sxp.ep.provider.impl; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.runners.MockitoJUnitRunner; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.integration.sxp.ep.provider.model.rev160302.sxp.ep.mapper.EndpointPolicyTemplateBySgt; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.integration.sxp.ep.provider.rev160722.SgtGeneratorConfig; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.integration.sxp.ep.provider.rev160722.SgtGeneratorConfigBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.sxp.database.rev160308.Sgt; + +import java.util.HashSet; +import java.util.Optional; +import java.util.Set; + +/** + * Test for {@link SgtGeneratorImpl}. + */ +@RunWith(MockitoJUnitRunner.class) +public class SgtGeneratorImplTest { + + @Mock + private SimpleCachedDao templateDao; + + private SgtGeneratorImpl generator; + private Set sgts; + + @Before + public void setUp() throws Exception { + final SgtGeneratorConfig config = new SgtGeneratorConfigBuilder() + .setSgtLow(new Sgt(10)) + .setSgtHigh(new Sgt(20)) + .build(); + + sgts = new HashSet<>(); + Mockito.when(templateDao.keySet()).thenReturn(sgts); + generator = new SgtGeneratorImpl(config); + } + + @Test + public void testGenerateNextSgt_noData() throws Exception { + final Optional sgt = generator.generateNextSgt(templateDao); + Assert.assertFalse(sgt.isPresent()); + } + + @Test + public void testGenerateNextSgt_topIsAboveLimit() throws Exception { + sgts.add(new Sgt(20)); + final Optional sgt = generator.generateNextSgt(templateDao); + Assert.assertFalse(sgt.isPresent()); + } + + @Test + public void testGenerateNextSgt_topIsBelowLimit() throws Exception { + sgts.add(new Sgt(9)); + final Optional sgt = generator.generateNextSgt(templateDao); + + Assert.assertTrue(sgt.isPresent()); + Assert.assertEquals(10, sgt.get().getValue().intValue()); + } + + @Test + public void testGenerateNextSgt_withinLimits() throws Exception { + sgts.add(new Sgt(10)); + final Optional sgt = generator.generateNextSgt(templateDao); + + Assert.assertTrue(sgt.isPresent()); + Assert.assertEquals(11, sgt.get().getValue().intValue()); + } +} \ No newline at end of file diff --git a/sxp-integration/sxp-ep-provider/src/test/java/org/opendaylight/groupbasedpolicy/sxp/ep/provider/impl/SxpEpProviderProviderImplTest.java b/sxp-integration/sxp-ep-provider/src/test/java/org/opendaylight/groupbasedpolicy/sxp/ep/provider/impl/SxpEpProviderProviderImplTest.java index ed7895c57..8039fcf9d 100644 --- a/sxp-integration/sxp-ep-provider/src/test/java/org/opendaylight/groupbasedpolicy/sxp/ep/provider/impl/SxpEpProviderProviderImplTest.java +++ b/sxp-integration/sxp-ep-provider/src/test/java/org/opendaylight/groupbasedpolicy/sxp/ep/provider/impl/SxpEpProviderProviderImplTest.java @@ -8,11 +8,6 @@ package org.opendaylight.groupbasedpolicy.sxp.ep.provider.impl; -import static org.powermock.api.mockito.PowerMockito.verifyNew; -import static org.powermock.api.mockito.PowerMockito.whenNew; -import static org.powermock.api.support.membermodification.MemberMatcher.method; -import static org.powermock.api.support.membermodification.MemberModifier.stub; - import com.google.common.collect.Ordering; import org.junit.Assert; import org.junit.Before; @@ -21,7 +16,6 @@ import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.Mockito; import org.opendaylight.controller.md.sal.binding.api.DataBroker; -import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry; import org.opendaylight.groupbasedpolicy.api.DomainSpecificRegistry; import org.opendaylight.groupbasedpolicy.api.EndpointAugmentorRegistry; import org.opendaylight.groupbasedpolicy.sxp.ep.provider.impl.dao.EPForwardingTemplateDaoImpl; @@ -40,11 +34,17 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpo import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ConditionName; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.EndpointGroupId; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.integration.sxp.ep.provider.model.rev160302.sxp.ep.mapper.EndpointPolicyTemplateBySgt; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.integration.sxp.ep.provider.rev160722.SgtGeneratorConfig; import org.opendaylight.yang.gen.v1.urn.opendaylight.sxp.database.rev160308.Sgt; import org.opendaylight.yang.gen.v1.urn.opendaylight.sxp.database.rev160308.master.database.fields.MasterDatabaseBinding; import org.powermock.core.classloader.annotations.PrepareForTest; import org.powermock.modules.junit4.PowerMockRunner; +import static org.powermock.api.mockito.PowerMockito.verifyNew; +import static org.powermock.api.mockito.PowerMockito.whenNew; +import static org.powermock.api.support.membermodification.MemberMatcher.method; +import static org.powermock.api.support.membermodification.MemberModifier.stub; + /** * Test for {@link SxpEpProviderProviderImpl}. */ @@ -55,15 +55,13 @@ public class SxpEpProviderProviderImplTest { @Mock private DataBroker dataBroker; @Mock - private RpcProviderRegistry rpcRegistry; - @Mock private DomainSpecificRegistry domainSpecificRegistry; @Mock private EPPolicyTemplateProviderRegistryImpl templateProviderRegistry; @Mock private SxpMapperReactorImpl sxpMapperReactor; @Mock - private BaseEndpointService endPointService; + private BaseEndpointService endpointService; @Mock private SimpleCachedDaoImpl epPolicyTemplateCachedDao; @Mock @@ -94,16 +92,21 @@ public class SxpEpProviderProviderImplTest { private EndpointAugmentorRegistry epAugmentorRegistry; @Mock private EPPolicyTemplateDaoFacadeImpl epPolicyTemplateDaoFacade; + @Mock + private SgtGeneratorConfig sgtGeneratorConfig; + @Mock + private SgtGeneratorImpl sgtGenerator; + @Mock + private EPToSgtMapperImpl epToSgtMapper; private SxpEpProviderProviderImpl provider; @Before public void setUp() throws Exception { - Mockito.when(rpcRegistry.getRpcService(BaseEndpointService.class)).thenReturn(endPointService); Mockito.when(domainSpecificRegistry.getEndpointAugmentorRegistry()).thenReturn(epAugmentorRegistry); whenNew(EPPolicyTemplateProviderRegistryImpl.class).withNoArguments().thenReturn(templateProviderRegistry); - whenNew(SxpMapperReactorImpl.class).withArguments(endPointService, dataBroker).thenReturn(sxpMapperReactor); + whenNew(SxpMapperReactorImpl.class).withArguments(endpointService, dataBroker).thenReturn(sxpMapperReactor); whenNew(SimpleCachedDaoImpl.class).withNoArguments().thenReturn(epPolicyTemplateCachedDao, masterDBBindingCachedDao); whenNew(SimpleCachedDaoEPForwardingTemplateImpl.class).withNoArguments().thenReturn(epFwTemplateCachedDao); stub(method(EPTemplateUtil.class, "createEndpointGroupIdOrdering")).toReturn(groupOrdering); @@ -112,8 +115,11 @@ public class SxpEpProviderProviderImplTest { .thenReturn(epPolicyTemplateKeyFactory); whenNew(EPPolicyTemplateDaoImpl.class).withArguments(dataBroker, epPolicyTemplateCachedDao, epPolicyTemplateKeyFactory) .thenReturn(epPolicyTemplateDao); - whenNew(EPPolicyTemplateDaoFacadeImpl.class).withArguments(dataBroker, epPolicyTemplateDao) + whenNew(SgtGeneratorImpl.class).withArguments(sgtGeneratorConfig).thenReturn(sgtGenerator); + whenNew(EPPolicyTemplateDaoFacadeImpl.class).withArguments(dataBroker, epPolicyTemplateDao, epPolicyTemplateCachedDao, sgtGenerator) .thenReturn(epPolicyTemplateDaoFacade); + whenNew(EPToSgtMapperImpl.class).withArguments(epPolicyTemplateDaoFacade).thenReturn(epToSgtMapper); + whenNew(EPForwardingTemplateDaoImpl.class).withArguments(dataBroker, epFwTemplateCachedDao) .thenReturn(epForwardingTemplateDao); whenNew(MasterDatabaseBindingDaoImpl.class).withArguments(dataBroker, masterDBBindingCachedDao) @@ -124,24 +130,25 @@ public class SxpEpProviderProviderImplTest { masterDBBindingDao, epForwardingTemplateDao).thenReturn(epPolicyTemplateListener); whenNew(EPForwardingTemplateListenerImpl.class).withArguments(dataBroker, sxpMapperReactor, epFwTemplateCachedDao, masterDBBindingDao, epPolicyTemplateDaoFacade).thenReturn(epForwardingTemplateListener); - whenNew(SxpEndpointAugmentorImpl.class).withArguments(epPolicyTemplateDaoFacade,epPolicyTemplateKeyFactory) + whenNew(SxpEndpointAugmentorImpl.class).withArguments(epPolicyTemplateDao, epPolicyTemplateKeyFactory) .thenReturn(sxpEPAugmentor); - provider = new SxpEpProviderProviderImpl(dataBroker, rpcRegistry, domainSpecificRegistry); + provider = new SxpEpProviderProviderImpl(dataBroker, endpointService, domainSpecificRegistry, sgtGeneratorConfig); - Mockito.verify(rpcRegistry).getRpcService(BaseEndpointService.class); Mockito.verify(templateProviderRegistry).addDistributionTarget(epPolicyTemplateDaoFacade); Mockito.verify(epAugmentorRegistry).register(sxpEPAugmentor); // check if all expected object got constructed and wired verifyNew(EPPolicyTemplateProviderRegistryImpl.class).withNoArguments(); - verifyNew(SxpMapperReactorImpl.class).withArguments(endPointService, dataBroker); + verifyNew(SxpMapperReactorImpl.class).withArguments(endpointService, dataBroker); verifyNew(SimpleCachedDaoImpl.class, Mockito.times(2)).withNoArguments(); verifyNew(SimpleCachedDaoEPForwardingTemplateImpl.class).withNoArguments(); verifyNew(EpPolicyTemplateValueKeyFactory.class).withArguments(groupOrdering, conditionOrdering); verifyNew(EPPolicyTemplateDaoImpl.class).withArguments(dataBroker, epPolicyTemplateCachedDao, epPolicyTemplateKeyFactory); - verifyNew(EPPolicyTemplateDaoFacadeImpl.class).withArguments(dataBroker, epPolicyTemplateDao); + verifyNew(SgtGeneratorImpl.class).withArguments(sgtGeneratorConfig); + verifyNew(EPPolicyTemplateDaoFacadeImpl.class).withArguments(dataBroker, epPolicyTemplateDao, epPolicyTemplateCachedDao, sgtGenerator); + verifyNew(EPToSgtMapperImpl.class).withArguments(epPolicyTemplateDaoFacade); verifyNew(EPForwardingTemplateDaoImpl.class).withArguments(dataBroker, epFwTemplateCachedDao); verifyNew(MasterDatabaseBindingDaoImpl.class).withArguments(dataBroker, masterDBBindingCachedDao); verifyNew(MasterDatabaseBindingListenerImpl.class).withArguments(dataBroker, sxpMapperReactor, masterDBBindingCachedDao, @@ -150,7 +157,7 @@ public class SxpEpProviderProviderImplTest { masterDBBindingDao, epForwardingTemplateDao); verifyNew(EPForwardingTemplateListenerImpl.class).withArguments(dataBroker, sxpMapperReactor, epFwTemplateCachedDao, masterDBBindingDao, epPolicyTemplateDaoFacade); - verifyNew(SxpEndpointAugmentorImpl.class).withArguments(epPolicyTemplateDaoFacade,epPolicyTemplateKeyFactory); + verifyNew(SxpEndpointAugmentorImpl.class).withArguments(epPolicyTemplateDao, epPolicyTemplateKeyFactory); } @Test diff --git a/sxp-integration/sxp-ep-provider/src/test/java/org/opendaylight/groupbasedpolicy/sxp/ep/provider/impl/dao/EPPolicyTemplateDaoFacadeImplTest.java b/sxp-integration/sxp-ep-provider/src/test/java/org/opendaylight/groupbasedpolicy/sxp/ep/provider/impl/dao/EPPolicyTemplateDaoFacadeImplTest.java index 57727c776..532da14dd 100644 --- a/sxp-integration/sxp-ep-provider/src/test/java/org/opendaylight/groupbasedpolicy/sxp/ep/provider/impl/dao/EPPolicyTemplateDaoFacadeImplTest.java +++ b/sxp-integration/sxp-ep-provider/src/test/java/org/opendaylight/groupbasedpolicy/sxp/ep/provider/impl/dao/EPPolicyTemplateDaoFacadeImplTest.java @@ -9,8 +9,10 @@ package org.opendaylight.groupbasedpolicy.sxp.ep.provider.impl.dao; import com.google.common.base.Optional; +import com.google.common.collect.Iterables; import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; +import java.util.Collection; import java.util.Collections; import java.util.concurrent.ExecutionException; import org.hamcrest.BaseMatcher; @@ -28,6 +30,8 @@ import org.opendaylight.controller.md.sal.binding.api.DataBroker; import org.opendaylight.controller.md.sal.binding.api.WriteTransaction; import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException; import org.opendaylight.groupbasedpolicy.sxp.ep.provider.api.EPPolicyTemplateProvider; +import org.opendaylight.groupbasedpolicy.sxp.ep.provider.impl.SgtGeneratorImpl; +import org.opendaylight.groupbasedpolicy.sxp.ep.provider.impl.SimpleCachedDao; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.EndpointGroupId; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.TenantId; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.integration.sxp.ep.provider.model.rev160302.TemplateGenerated; @@ -52,15 +56,20 @@ public class EPPolicyTemplateDaoFacadeImplTest { @Mock private EPPolicyTemplateDaoImpl delegateDao; @Mock + private SimpleCachedDao delegateCachedDao; + @Mock private DataBroker dataBroker; @Mock private EPPolicyTemplateProvider provider; @Mock + private SgtGeneratorImpl sgtGeneratorImpl; + @Mock private WriteTransaction wTx; private EndpointPolicyTemplateBySgtBuilder templateBld; private EPPolicyTemplateDaoFacadeImpl facade; + private EndpointPolicyTemplateBySgt first; @Before public void setUp() throws Exception { @@ -71,7 +80,7 @@ public class EPPolicyTemplateDaoFacadeImplTest { .setSgt(SGT) .setEndpointGroups(Collections.singletonList(EPG_ID)); - facade = new EPPolicyTemplateDaoFacadeImpl(dataBroker, delegateDao); + facade = new EPPolicyTemplateDaoFacadeImpl(dataBroker, delegateDao, delegateCachedDao, sgtGeneratorImpl); } @Test @@ -154,4 +163,29 @@ public class EPPolicyTemplateDaoFacadeImplTest { }); actual.get(); } + + @Test + public void testReadBy() throws Exception { + Mockito.when(sgtGeneratorImpl.generateNextSgt(delegateCachedDao)) + .thenReturn(java.util.Optional.empty()) + .thenReturn(java.util.Optional.of(new Sgt(42))); + + final EpPolicyTemplateValueKey lookupKey = new EpPolicyTemplateValueKey(TENANT_ID, + Collections.singletonList(EPG_ID), Collections.emptyList()); + + final ListenableFuture> templateFail = facade.readBy(lookupKey); + Assert.assertTrue(templateFail.isDone()); + Assert.assertTrue(templateFail.get().isEmpty()); + + final ListenableFuture> templateSuccess = facade.readBy(lookupKey); + Assert.assertTrue(templateSuccess.isDone()); + final Collection templateBag = templateSuccess.get(); + Assert.assertFalse(templateBag.isEmpty()); + first = Iterables.getFirst(templateBag, null); + Assert.assertNotNull(templateBag); + Assert.assertEquals(TemplateGenerated.class, first.getOrigin()); + Assert.assertEquals(Collections.singletonList(EPG_ID), Iterables.getFirst(templateBag, null).getEndpointGroups()); + Assert.assertTrue(Iterables.getFirst(templateBag, null).getConditions().isEmpty()); + Assert.assertEquals(42, Iterables.getFirst(templateBag, null).getSgt().getValue().intValue()); + } } \ No newline at end of file -- 2.36.6