From 27a291d46621e5763e9e38986cc2ac858e4e1fb1 Mon Sep 17 00:00:00 2001 From: Michal Rehak Date: Mon, 3 Oct 2016 15:15:13 +0200 Subject: [PATCH] BUG-6858: adapt to ise api, wire harvestAll to template-provider - template-provider reaches out for ise-harverster when template not available - involve template-provider in ios-xe renderer (async blacking call) Change-Id: I4f6077bbeccbaabe2e9dd7025972ef906e79dbe8 Signed-off-by: Michal Rehak --- .../impl/manager/PolicyManagerImpl.java | 10 ++- .../impl/util/PolicyManagerUtil.java | 21 ++++--- .../impl/SxpEpProviderProviderImpl.java | 7 --- .../impl/SxpEpProviderProviderImplTest.java | 15 ++--- .../impl/EPPolicyTemplateProviderIseImpl.java | 2 +- .../impl/GbpIseConfigListenerImpl.java | 1 - .../impl/GbpIseSgtHarvester.java | 6 -- .../impl/GbpIseSgtHarvesterImpl.java | 60 ++++++++++-------- .../sxp_ise_adapter/impl/SgtInfo.java | 7 +++ .../impl/util/IseReplyUtil.java | 62 +++++++++++++++++-- .../EPPolicyTemplateProviderIseImplTest.java | 9 +-- .../impl/GbpIseSgtHarvesterImplTest.java | 25 ++------ .../impl/IseResourceTestHelper.java | 33 ++++++++++ .../impl/util/IseReplyUtilTest.java | 59 ++++++++++++++++++ ...rawIse-allSgts.xml => rawIse-allSgts1.xml} | 0 .../sxp_ise_adapter/impl/rawIse-allSgts2.xml | 22 +++++++ 16 files changed, 248 insertions(+), 91 deletions(-) create mode 100644 sxp-integration/sxp-ise-adapter/src/test/java/org/opendaylight/groupbasedpolicy/sxp_ise_adapter/impl/IseResourceTestHelper.java create mode 100644 sxp-integration/sxp-ise-adapter/src/test/java/org/opendaylight/groupbasedpolicy/sxp_ise_adapter/impl/util/IseReplyUtilTest.java rename sxp-integration/sxp-ise-adapter/src/test/resources/org/opendaylight/groupbasedpolicy/sxp_ise_adapter/impl/{rawIse-allSgts.xml => rawIse-allSgts1.xml} (100%) create mode 100644 sxp-integration/sxp-ise-adapter/src/test/resources/org/opendaylight/groupbasedpolicy/sxp_ise_adapter/impl/rawIse-allSgts2.xml 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 884e74e46..c27361312 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 @@ -11,6 +11,7 @@ package org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.manager; import static org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.manager.PolicyManagerImpl.DsAction.Create; import static org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.manager.PolicyManagerImpl.DsAction.Delete; +import java.util.concurrent.TimeUnit; import javax.annotation.Nonnull; import javax.annotation.Nullable; import java.util.List; @@ -29,7 +30,6 @@ import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.api.manager.Po 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; @@ -156,12 +156,16 @@ public class PolicyManagerImpl implements PolicyManager { managementIpAddress, mountpoint); context.setPolicyMapLocation(policyMapLocation); + // TODO: pull timeout for async ops from config + final long TIMEOUT = 10; + final TimeUnit UNIT = TimeUnit.SECONDS; + final Sgt sourceSgt = PolicyManagerUtil.findSgtTag(epToSgtMapper, rendererEndpoint, dataAfter.getEndpoints() - .getAddressEndpointWithLocation()); + .getAddressEndpointWithLocation(), TIMEOUT, UNIT); // Peer Endpoint for (PeerEndpoint peerEndpoint : rendererEndpoint.getPeerEndpoint()) { final Sgt destinationSgt = PolicyManagerUtil.findSgtTag(epToSgtMapper, peerEndpoint, dataAfter.getEndpoints() - .getAddressEndpointWithLocation()); + .getAddressEndpointWithLocation(), TIMEOUT, UNIT); if (sourceSgt == null || destinationSgt == null) { final String info = String.format("Endpoint-policy: missing sgt value(sourceSgt=%s, destinationSgt=%s)", sourceSgt, destinationSgt); 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 e9e9ee276..e81924d2c 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 @@ -11,8 +11,11 @@ package org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.util; import static org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.manager.PolicyManagerImpl.ActionCase.CHAIN; import com.google.common.base.Preconditions; +import com.google.common.collect.Iterables; import com.google.common.util.concurrent.Futures; +import com.google.common.util.concurrent.ListenableFuture; import java.util.ArrayList; +import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; @@ -20,6 +23,7 @@ import java.util.List; import java.util.Map; import java.util.Optional; import java.util.Set; +import java.util.concurrent.TimeUnit; import javax.annotation.Nonnull; import javax.annotation.Nullable; import org.opendaylight.controller.md.sal.binding.api.DataBroker; @@ -82,7 +86,6 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.r import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.resolved.policy.rev150828.has.actions.Action; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.resolved.policy.rev150828.has.classifiers.Classifier; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.resolved.policy.rev150828.has.resolved.rules.ResolvedRule; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.integration.sxp.ep.provider.model.rev160302.AddressEndpointWithLocationAug; import org.opendaylight.yang.gen.v1.urn.opendaylight.sxp.database.rev160308.Sgt; import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; @@ -200,20 +203,24 @@ public class PolicyManagerUtil { @Nullable public static Sgt findSgtTag(final EPToSgtMapper sxpEpProvider, final AddressEndpointKey endpointKey, - final List endpointsWithLocation) { + final List endpointsWithLocation, final long timeout, final TimeUnit unit) { 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; + final ListenableFuture> sgtForEPFu = sxpEpProvider.findSgtForEP(endpointWithLocation); + + Sgt sgt = null; + try { + sgt = Iterables.getFirst(sgtForEPFu.get(timeout, unit), null); + LOG.trace("For ep[{}] found sgt: {}", endpointKey, sgt); + } catch (Exception e) { + LOG.debug("failed to obtain sgt for given endpoint: ", e.getMessage()); } - return augmentation.getSgt(); + return sgt; } /** 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 0542cd4c3..37e754ada 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 @@ -10,7 +10,6 @@ package org.opendaylight.groupbasedpolicy.sxp.ep.provider.impl; import org.opendaylight.controller.md.sal.binding.api.DataBroker; 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; @@ -47,7 +46,6 @@ public class SxpEpProviderProviderImpl implements SxpEpProviderProvider { private final EPTemplateListener epPolicyTemplateListener; private final EPTemplateListener epForwardingTemplateListener; private final DomainSpecificRegistry domainSpecificRegistry; - private final EndpointAugmentor sxpEndpointAugmentor; private final EPPolicyTemplateProviderRegistry epPolicyTemplateRegistry; private final EPToSgtMapper epToSgtMapper; @@ -89,10 +87,6 @@ public class SxpEpProviderProviderImpl implements SxpEpProviderProvider { epForwardingTemplateListener = new EPForwardingTemplateListenerImpl(dataBroker, sxpMapperReactor, epForwardingTemplateCachedDao, masterDBBindingDao, epPolicyTemplateDaoFacade); - // sxp-ep-augmentor -> deprecated, will use ep2sxpMapper service - sxpEndpointAugmentor = new SxpEndpointAugmentorImpl(epPolicyTemplateDao, epPolicyTemplateKeyFactory); - domainSpecificRegistry.getEndpointAugmentorRegistry().register(sxpEndpointAugmentor); - LOG.info("started SxmMapper"); } @@ -112,6 +106,5 @@ public class SxpEpProviderProviderImpl implements SxpEpProviderProvider { epPolicyTemplateListener.close(); epForwardingTemplateListener.close(); epPolicyTemplateRegistry.close(); - domainSpecificRegistry.getEndpointAugmentorRegistry().unregister(sxpEndpointAugmentor); } } 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 8039fcf9d..6d5c1123c 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,6 +8,11 @@ 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; @@ -40,11 +45,6 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.sxp.database.rev160308.mast 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}. */ @@ -103,8 +103,6 @@ public class SxpEpProviderProviderImplTest { @Before public void setUp() throws Exception { - Mockito.when(domainSpecificRegistry.getEndpointAugmentorRegistry()).thenReturn(epAugmentorRegistry); - whenNew(EPPolicyTemplateProviderRegistryImpl.class).withNoArguments().thenReturn(templateProviderRegistry); whenNew(SxpMapperReactorImpl.class).withArguments(endpointService, dataBroker).thenReturn(sxpMapperReactor); whenNew(SimpleCachedDaoImpl.class).withNoArguments().thenReturn(epPolicyTemplateCachedDao, masterDBBindingCachedDao); @@ -137,7 +135,6 @@ public class SxpEpProviderProviderImplTest { provider = new SxpEpProviderProviderImpl(dataBroker, endpointService, domainSpecificRegistry, sgtGeneratorConfig); Mockito.verify(templateProviderRegistry).addDistributionTarget(epPolicyTemplateDaoFacade); - Mockito.verify(epAugmentorRegistry).register(sxpEPAugmentor); // check if all expected object got constructed and wired verifyNew(EPPolicyTemplateProviderRegistryImpl.class).withNoArguments(); @@ -157,7 +154,6 @@ public class SxpEpProviderProviderImplTest { masterDBBindingDao, epForwardingTemplateDao); verifyNew(EPForwardingTemplateListenerImpl.class).withArguments(dataBroker, sxpMapperReactor, epFwTemplateCachedDao, masterDBBindingDao, epPolicyTemplateDaoFacade); - verifyNew(SxpEndpointAugmentorImpl.class).withArguments(epPolicyTemplateDao, epPolicyTemplateKeyFactory); } @Test @@ -172,6 +168,5 @@ public class SxpEpProviderProviderImplTest { Mockito.verify(epPolicyTemplateListener).close(); Mockito.verify(epForwardingTemplateListener).close(); Mockito.verify(templateProviderRegistry).close(); - Mockito.verify(epAugmentorRegistry).unregister(sxpEPAugmentor); } } \ No newline at end of file diff --git a/sxp-integration/sxp-ise-adapter/src/main/java/org/opendaylight/groupbasedpolicy/sxp_ise_adapter/impl/EPPolicyTemplateProviderIseImpl.java b/sxp-integration/sxp-ise-adapter/src/main/java/org/opendaylight/groupbasedpolicy/sxp_ise_adapter/impl/EPPolicyTemplateProviderIseImpl.java index bcea610d4..7497bc000 100644 --- a/sxp-integration/sxp-ise-adapter/src/main/java/org/opendaylight/groupbasedpolicy/sxp_ise_adapter/impl/EPPolicyTemplateProviderIseImpl.java +++ b/sxp-integration/sxp-ise-adapter/src/main/java/org/opendaylight/groupbasedpolicy/sxp_ise_adapter/impl/EPPolicyTemplateProviderIseImpl.java @@ -67,7 +67,7 @@ public class EPPolicyTemplateProviderIseImpl implements EPPolicyTemplateProvider } private ListenableFuture> queryIseOnSgt(final IseContext iseContext, @Nonnull final Sgt sgt) { - final ListenableFuture> sgtUpdateFu = iseSgtHarvester.update(iseContext); + final ListenableFuture> sgtUpdateFu = iseSgtHarvester.harvestAll(iseContext); return Futures.transform(sgtUpdateFu, new Function, Optional>() { @Nullable @Override diff --git a/sxp-integration/sxp-ise-adapter/src/main/java/org/opendaylight/groupbasedpolicy/sxp_ise_adapter/impl/GbpIseConfigListenerImpl.java b/sxp-integration/sxp-ise-adapter/src/main/java/org/opendaylight/groupbasedpolicy/sxp_ise_adapter/impl/GbpIseConfigListenerImpl.java index 031f9bfd6..92e84100b 100644 --- a/sxp-integration/sxp-ise-adapter/src/main/java/org/opendaylight/groupbasedpolicy/sxp_ise_adapter/impl/GbpIseConfigListenerImpl.java +++ b/sxp-integration/sxp-ise-adapter/src/main/java/org/opendaylight/groupbasedpolicy/sxp_ise_adapter/impl/GbpIseConfigListenerImpl.java @@ -73,7 +73,6 @@ public class GbpIseConfigListenerImpl implements GbpIseConfigListener { public void onDataTreeChanged(@Nonnull final Collection> collection) { for (DataTreeModification modification : collection) { final IseSourceConfig iseSourceConfig = modification.getRootNode().getDataAfter(); - //TODO: separate template provider from harvesting final IseContext iseContext = new IseContext(iseSourceConfig); templateProviderFacade.assignIseContext(iseContext); if (iseSourceConfig != null) { diff --git a/sxp-integration/sxp-ise-adapter/src/main/java/org/opendaylight/groupbasedpolicy/sxp_ise_adapter/impl/GbpIseSgtHarvester.java b/sxp-integration/sxp-ise-adapter/src/main/java/org/opendaylight/groupbasedpolicy/sxp_ise_adapter/impl/GbpIseSgtHarvester.java index 9cecd622e..617da2b5a 100644 --- a/sxp-integration/sxp-ise-adapter/src/main/java/org/opendaylight/groupbasedpolicy/sxp_ise_adapter/impl/GbpIseSgtHarvester.java +++ b/sxp-integration/sxp-ise-adapter/src/main/java/org/opendaylight/groupbasedpolicy/sxp_ise_adapter/impl/GbpIseSgtHarvester.java @@ -22,10 +22,4 @@ public interface GbpIseSgtHarvester { * @return retrieved and stored sgts */ ListenableFuture> harvestAll(@Nonnull IseContext iseContext); - - /** - * @param iseContext user given ise info - * @return retrieved and stored sgts - */ - ListenableFuture> update(@Nonnull IseContext iseContext); } diff --git a/sxp-integration/sxp-ise-adapter/src/main/java/org/opendaylight/groupbasedpolicy/sxp_ise_adapter/impl/GbpIseSgtHarvesterImpl.java b/sxp-integration/sxp-ise-adapter/src/main/java/org/opendaylight/groupbasedpolicy/sxp_ise_adapter/impl/GbpIseSgtHarvesterImpl.java index 74dee9026..ef93ebab9 100644 --- a/sxp-integration/sxp-ise-adapter/src/main/java/org/opendaylight/groupbasedpolicy/sxp_ise_adapter/impl/GbpIseSgtHarvesterImpl.java +++ b/sxp-integration/sxp-ise-adapter/src/main/java/org/opendaylight/groupbasedpolicy/sxp_ise_adapter/impl/GbpIseSgtHarvesterImpl.java @@ -16,9 +16,11 @@ import com.google.common.util.concurrent.ThreadFactoryBuilder; import com.sun.jersey.api.client.Client; import com.sun.jersey.api.client.WebResource; import java.net.URI; +import java.security.GeneralSecurityException; import java.util.ArrayList; import java.util.Collection; import java.util.List; +import java.util.Map; import java.util.Objects; import java.util.concurrent.Callable; import java.util.concurrent.ExecutorService; @@ -29,7 +31,6 @@ import java.util.stream.Collectors; import javax.annotation.Nonnull; import javax.annotation.Nullable; import javax.xml.xpath.XPath; -import javax.xml.xpath.XPathConstants; import javax.xml.xpath.XPathExpressionException; import org.opendaylight.groupbasedpolicy.sxp_ise_adapter.impl.util.IseReplyUtil; import org.opendaylight.groupbasedpolicy.sxp_ise_adapter.impl.util.RestClientFactory; @@ -61,18 +62,17 @@ public class GbpIseSgtHarvesterImpl implements GbpIseSgtHarvester { @Override public ListenableFuture> harvestAll(@Nonnull final IseContext iseContext) { - final IseSourceConfig iseSourceConfig = iseContext.getIseSourceConfig(); - final ConnectionConfig connectionConfig = iseSourceConfig.getConnectionConfig(); ListenableFuture> result; try { - final Client iseClient = RestClientFactory.createIseClient(connectionConfig); - final WebResource baseWebResource = iseClient.resource(connectionConfig.getIseRestUrl().getValue()); + final IseSourceConfig iseSourceConfig = iseContext.getIseSourceConfig(); + final ConnectionConfig connectionConfig = iseSourceConfig.getConnectionConfig(); + final WebResource baseWebResource = createWebResource(connectionConfig); final WebResource.Builder requestBuilder = RestClientFactory.createRequestBuilder(baseWebResource, connectionConfig.getHeader(), RestClientFactory.PATH_ERS_CONFIG_SGT); final String rawSgtSummary = IseReplyUtil.deliverResponse(requestBuilder); - final List sgtInfos = harvestDetails(rawSgtSummary, baseWebResource, connectionConfig.getHeader()); + final List sgtInfos = harvestDetails(rawSgtSummary, baseWebResource, connectionConfig, iseContext.getUuidToSgtMap()); ListenableFuture processingResult = Futures.immediateCheckedFuture(null); for (SgtInfoProcessor processor : sgtInfoProcessors) { @@ -88,6 +88,11 @@ public class GbpIseSgtHarvesterImpl implements GbpIseSgtHarvester { @Nullable @Override public Collection apply(@Nullable final Void input) { + // update uuid map + for (SgtInfo sgtInfo : sgtInfos) { + iseContext.getUuidToSgtMap().put(sgtInfo.getUuid(), sgtInfo.getSgt().getValue()); + } + //TODO: store harvest stats to DS/operational // always success, otherwise there will be TransactionCommitFailedException thrown return sgtInfos; } @@ -100,7 +105,13 @@ public class GbpIseSgtHarvesterImpl implements GbpIseSgtHarvester { return result; } - private List harvestDetails(final String rawSgtSummary, final WebResource baseWebResource, final List
headers) { + private WebResource createWebResource(final ConnectionConfig connectionConfig) throws GeneralSecurityException { + final Client iseClient = RestClientFactory.createIseClient(connectionConfig); + return iseClient.resource(connectionConfig.getIseRestUrl().getValue()); + } + + private List harvestDetails(final String rawSgtSummary, final WebResource baseWebResource, + final ConnectionConfig connectionConfig, final Map uuidToSgtMap) { LOG.trace("rawSgtSummary: {}", rawSgtSummary); final List> sgtInfoFutureBag = new ArrayList<>(); @@ -111,22 +122,24 @@ public class GbpIseSgtHarvesterImpl implements GbpIseSgtHarvester { // parse sgtSummary final XPath xpath = IseReplyUtil.setupXpath(); - InputSource inputSource = IseReplyUtil.createInputSource(rawSgtSummary); + final InputSource inputSource = IseReplyUtil.createInputSource(rawSgtSummary); try { - final NodeList sgtLinkNodes = (NodeList) xpath.evaluate(IseReplyUtil.EXPRESSION_SGT_ALL_LINK_HREFS, inputSource, - XPathConstants.NODESET); - for (int i = 0; i < sgtLinkNodes.getLength(); i++) { - final String sgtLinkHrefValue = sgtLinkNodes.item(i).getNodeValue(); - LOG.debug("found sgt resource [{}]: {}", i, sgtLinkHrefValue); + final NodeList sgtResources = IseReplyUtil.findAllSgtResourceNodes(xpath, inputSource); + final Collection sgtLinkNodes = IseReplyUtil.filterNewResourcesByID(uuidToSgtMap, xpath, sgtResources); + + int counter = 0; + for (Node sgtLinkNode : sgtLinkNodes) { + final String sgtLinkHrefValue = sgtLinkNode.getNodeValue(); + LOG.debug("found sgt resource: {}", sgtLinkHrefValue); // submit all query tasks to pool - final int idx = i; + final int idx = counter++; sgtInfoFutureBag.add(pool.submit(new Callable() { @Override public SgtInfo call() { SgtInfo sgtInfo = null; try { - sgtInfo = querySgtDetail(baseWebResource, headers, xpath, idx, sgtLinkHrefValue); + sgtInfo = querySgtDetail(baseWebResource, connectionConfig.getHeader(), xpath, idx, sgtLinkHrefValue); } catch (XPathExpressionException e) { LOG.info("failed to parse sgt response for {}: {}", sgtLinkHrefValue, e.getMessage()); } @@ -169,17 +182,17 @@ public class GbpIseSgtHarvesterImpl implements GbpIseSgtHarvester { final int idx, final String sgtLinkHrefValue) throws XPathExpressionException { // query all sgt entries (serial-vise) final URI hrefToSgtDetailUri = URI.create(sgtLinkHrefValue); - final WebResource.Builder requestBuilder = RestClientFactory.createRequestBuilder(baseWebResource, headers, hrefToSgtDetailUri.getPath()); + final WebResource.Builder requestBuilder = RestClientFactory.createRequestBuilder(baseWebResource, headers, + hrefToSgtDetailUri.getPath()); // time consuming operation - wait for rest response final String rawSgtDetail = IseReplyUtil.deliverResponse(requestBuilder); LOG.trace("rawSgtDetail: {}", rawSgtDetail); // process response xml - final Node sgtNode = (Node) xpath.evaluate(IseReplyUtil.EXPRESSION_SGT_DETAIL, IseReplyUtil.createInputSource(rawSgtDetail), - XPathConstants.NODE); - final Node sgtName = (Node) xpath.evaluate(IseReplyUtil.EXPRESSION_SGT_NAME_ATTR, sgtNode, XPathConstants.NODE); - final Node sgtUuid = (Node) xpath.evaluate(IseReplyUtil.EXPRESSION_SGT_UUID_ATTR, sgtNode, XPathConstants.NODE); - final Node sgtValue = (Node) xpath.evaluate(IseReplyUtil.EXPRESSION_SGT_VALUE, sgtNode, XPathConstants.NODE); + final Node sgtNode = IseReplyUtil.findSgtDetailNode(xpath, rawSgtDetail); + final Node sgtName = IseReplyUtil.gainSgtName(xpath, sgtNode); + final Node sgtUuid = IseReplyUtil.gainSgtUuid(xpath, sgtNode); + final Node sgtValue = IseReplyUtil.gainSgtValue(xpath, sgtNode); LOG.debug("sgt value [{}]: {} -> {}", idx, sgtValue, sgtName); // store replies into list of SgtInfo @@ -187,9 +200,4 @@ public class GbpIseSgtHarvesterImpl implements GbpIseSgtHarvester { return new SgtInfo(sgt, sgtName.getNodeValue(), sgtUuid.getNodeValue()); } - @Override - public ListenableFuture> update(@Nonnull final IseContext iseContext) { - //TODO: stub - return null; - } } diff --git a/sxp-integration/sxp-ise-adapter/src/main/java/org/opendaylight/groupbasedpolicy/sxp_ise_adapter/impl/SgtInfo.java b/sxp-integration/sxp-ise-adapter/src/main/java/org/opendaylight/groupbasedpolicy/sxp_ise_adapter/impl/SgtInfo.java index 173a59340..8cb4921b9 100644 --- a/sxp-integration/sxp-ise-adapter/src/main/java/org/opendaylight/groupbasedpolicy/sxp_ise_adapter/impl/SgtInfo.java +++ b/sxp-integration/sxp-ise-adapter/src/main/java/org/opendaylight/groupbasedpolicy/sxp_ise_adapter/impl/SgtInfo.java @@ -45,4 +45,11 @@ public class SgtInfo { public String getName() { return name; } + + /** + * @return uuid of sgt + */ + public String getUuid() { + return uuid; + } } diff --git a/sxp-integration/sxp-ise-adapter/src/main/java/org/opendaylight/groupbasedpolicy/sxp_ise_adapter/impl/util/IseReplyUtil.java b/sxp-integration/sxp-ise-adapter/src/main/java/org/opendaylight/groupbasedpolicy/sxp_ise_adapter/impl/util/IseReplyUtil.java index 3861765f2..930082bd0 100644 --- a/sxp-integration/sxp-ise-adapter/src/main/java/org/opendaylight/groupbasedpolicy/sxp_ise_adapter/impl/util/IseReplyUtil.java +++ b/sxp-integration/sxp-ise-adapter/src/main/java/org/opendaylight/groupbasedpolicy/sxp_ise_adapter/impl/util/IseReplyUtil.java @@ -11,11 +11,18 @@ package org.opendaylight.groupbasedpolicy.sxp_ise_adapter.impl.util; import com.sun.jersey.api.client.ClientResponse; import com.sun.jersey.api.client.WebResource; import java.io.StringReader; +import java.util.ArrayList; +import java.util.Collection; import java.util.Iterator; +import java.util.Map; import javax.xml.XMLConstants; import javax.xml.namespace.NamespaceContext; import javax.xml.xpath.XPath; +import javax.xml.xpath.XPathConstants; +import javax.xml.xpath.XPathExpressionException; import javax.xml.xpath.XPathFactory; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; import org.xml.sax.InputSource; /** @@ -23,11 +30,12 @@ import org.xml.sax.InputSource; */ public class IseReplyUtil { - public static final String EXPRESSION_SGT_ALL_LINK_HREFS = "/ns3:searchResult/ns3:resources/ns5:resource/link/@href"; - public static final String EXPRESSION_SGT_DETAIL = "./ns4:sgt"; - public static final String EXPRESSION_SGT_NAME_ATTR = "./@name"; - public static final String EXPRESSION_SGT_UUID_ATTR = "./@id"; - public static final String EXPRESSION_SGT_VALUE = "./value/text()"; + private static final String EXPRESSION_SGT_ALL_RESOURCES = "/ns3:searchResult/ns3:resources/ns5:resource"; + private static final String EXPRESSION_SGT_DETAIL_LINK = "./link/@href"; + private static final String EXPRESSION_SGT_DETAIL = "./ns4:sgt"; + private static final String EXPRESSION_SGT_NAME_ATTR = "./@name"; + private static final String EXPRESSION_SGT_UUID_ATTR = "./@id"; + private static final String EXPRESSION_SGT_VALUE = "./value/text()"; private IseReplyUtil() { throw new IllegalAccessError("util class - no instances supported"); @@ -80,4 +88,48 @@ public class IseReplyUtil { public static InputSource createInputSource(final String rawSgtDetail) { return new InputSource(new StringReader(rawSgtDetail)); } + + /** + * @param uuidToSgtMap map of existing sgts (by uuid) + * @param xpath xpath instance + * @param sgtResources input node list + * @return new/unknown sgts to explore + * @throws XPathExpressionException in case xpath processing fails + */ + public static Collection filterNewResourcesByID(final Map uuidToSgtMap, final XPath xpath, + final NodeList sgtResources) + throws XPathExpressionException { + final Collection nodesToExplore = new ArrayList<>(); + for (int i = 0; i < sgtResources.getLength(); i++) { + final String uuid = ((Node) xpath.evaluate(EXPRESSION_SGT_UUID_ATTR, sgtResources.item(i), XPathConstants.NODE)).getNodeValue(); + if (!uuidToSgtMap.containsKey(uuid)) { + nodesToExplore.add( + (Node) xpath.evaluate(EXPRESSION_SGT_DETAIL_LINK, sgtResources.item(i), XPathConstants.NODE) + ); + } + } + return nodesToExplore; + } + + public static NodeList findAllSgtResourceNodes(final XPath xpath, final InputSource inputSource) throws XPathExpressionException { + return (NodeList) xpath.evaluate(EXPRESSION_SGT_ALL_RESOURCES, inputSource, + XPathConstants.NODESET); + } + + public static Node gainSgtValue(final XPath xpath, final Node sgtNode) throws XPathExpressionException { + return (Node) xpath.evaluate(EXPRESSION_SGT_VALUE, sgtNode, XPathConstants.NODE); + } + + public static Node gainSgtUuid(final XPath xpath, final Node sgtNode) throws XPathExpressionException { + return (Node) xpath.evaluate(EXPRESSION_SGT_UUID_ATTR, sgtNode, XPathConstants.NODE); + } + + public static Node gainSgtName(final XPath xpath, final Node sgtNode) throws XPathExpressionException { + return (Node) xpath.evaluate(EXPRESSION_SGT_NAME_ATTR, sgtNode, XPathConstants.NODE); + } + + public static Node findSgtDetailNode(final XPath xpath, final String rawSgtDetail) throws XPathExpressionException { + return (Node) xpath.evaluate(EXPRESSION_SGT_DETAIL, createInputSource(rawSgtDetail), + XPathConstants.NODE); + } } diff --git a/sxp-integration/sxp-ise-adapter/src/test/java/org/opendaylight/groupbasedpolicy/sxp_ise_adapter/impl/EPPolicyTemplateProviderIseImplTest.java b/sxp-integration/sxp-ise-adapter/src/test/java/org/opendaylight/groupbasedpolicy/sxp_ise_adapter/impl/EPPolicyTemplateProviderIseImplTest.java index 126ee61eb..b934a43af 100644 --- a/sxp-integration/sxp-ise-adapter/src/test/java/org/opendaylight/groupbasedpolicy/sxp_ise_adapter/impl/EPPolicyTemplateProviderIseImplTest.java +++ b/sxp-integration/sxp-ise-adapter/src/test/java/org/opendaylight/groupbasedpolicy/sxp_ise_adapter/impl/EPPolicyTemplateProviderIseImplTest.java @@ -31,13 +31,13 @@ import org.opendaylight.groupbasedpolicy.sxp_ise_adapter.impl.util.IseReplyUtil; import org.opendaylight.groupbasedpolicy.sxp_ise_adapter.impl.util.RestClientFactory; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Uri; 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; +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.ise.adapter.model.rev160630.gbp.sxp.ise.adapter.IseSourceConfig; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.integration.sxp.ise.adapter.model.rev160630.gbp.sxp.ise.adapter.IseSourceConfigBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.integration.sxp.ise.adapter.model.rev160630.gbp.sxp.ise.adapter.ise.source.config.ConnectionConfig; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.integration.sxp.ise.adapter.model.rev160630.gbp.sxp.ise.adapter.ise.source.config.ConnectionConfigBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.integration.sxp.ise.adapter.model.rev160630.gbp.sxp.ise.adapter.ise.source.config.connection.config.HeaderBuilder; -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.sxp.database.rev160308.Sgt; import org.powermock.core.classloader.annotations.PrepareForTest; import org.powermock.modules.junit4.PowerMockRunner; @@ -112,12 +112,13 @@ public class EPPolicyTemplateProviderIseImplTest { final String epgName = SGT_INFO.getName(); final Node sgtNameNode = Mockito.mock(Node.class); Mockito.when(sgtNameNode.getNodeValue()).thenReturn(epgName); - Mockito.when(xpathWalker.evaluate(Matchers.same(IseReplyUtil.EXPRESSION_SGT_NAME_ATTR), + // matching value of IseReplyUtil.EXPRESSION_SGT_NAME_ATTR + Mockito.when(xpathWalker.evaluate(Matchers.same("./@name"), Matchers.any(), Matchers.same(XPathConstants.NODE))) .thenReturn(sgtNameNode); Mockito.when(iseContext.getIseSourceConfig()).thenReturn(sourceConfig); - Mockito.when(iseSgtHarvester.update(iseContext)) + Mockito.when(iseSgtHarvester.harvestAll(iseContext)) .thenReturn(Futures.immediateFuture(Collections.singletonList(SGT_INFO))); templateProvider.assignIseContext(iseContext); diff --git a/sxp-integration/sxp-ise-adapter/src/test/java/org/opendaylight/groupbasedpolicy/sxp_ise_adapter/impl/GbpIseSgtHarvesterImplTest.java b/sxp-integration/sxp-ise-adapter/src/test/java/org/opendaylight/groupbasedpolicy/sxp_ise_adapter/impl/GbpIseSgtHarvesterImplTest.java index 8c3c365a5..b63763864 100644 --- a/sxp-integration/sxp-ise-adapter/src/test/java/org/opendaylight/groupbasedpolicy/sxp_ise_adapter/impl/GbpIseSgtHarvesterImplTest.java +++ b/sxp-integration/sxp-ise-adapter/src/test/java/org/opendaylight/groupbasedpolicy/sxp_ise_adapter/impl/GbpIseSgtHarvesterImplTest.java @@ -16,10 +16,7 @@ import com.google.common.util.concurrent.ListenableFuture; import com.sun.jersey.api.client.Client; import com.sun.jersey.api.client.ClientResponse; import com.sun.jersey.api.client.WebResource; -import java.io.BufferedReader; import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; import java.util.Collection; import java.util.Collections; import java.util.List; @@ -75,22 +72,8 @@ public class GbpIseSgtHarvesterImplTest { private GbpIseSgtHarvesterImpl harvester; public GbpIseSgtHarvesterImplTest() throws IOException { - iseReplyAllSgts = readLocalResource("./rawIse-allSgts.xml"); - iseReplySgtDetail = readLocalResource("./rawIse-sgtDetail.xml"); - } - - private static String readLocalResource(final String resourcePath) throws IOException { - final StringBuilder collector = new StringBuilder(); - try ( - final InputStream iseReplySource = GbpIseSgtHarvesterImplTest.class.getResourceAsStream(resourcePath); - final BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(iseReplySource)) - ) { - String line; - while ((line = bufferedReader.readLine()) != null) { - collector.append(line); - } - } - return collector.toString(); + iseReplyAllSgts = IseResourceTestHelper.readLocalResource("./rawIse-allSgts1.xml"); + iseReplySgtDetail = IseResourceTestHelper.readLocalResource("./rawIse-sgtDetail.xml"); } @Before @@ -125,6 +108,7 @@ public class GbpIseSgtHarvesterImplTest { Futures.immediateCheckedFuture(null)); final ListenableFuture> harvestResult = harvester.harvestAll(iseContext); + final Collection addedSgts = harvestResult.get(2, TimeUnit.SECONDS); final InOrder inOrder = Mockito.inOrder(client, webResource, builder); inOrder.verify(client).resource(ISE_REST_URL.getValue()); @@ -140,7 +124,6 @@ public class GbpIseSgtHarvesterImplTest { inOrder.verify(builder).get(ClientResponse.class); inOrder.verifyNoMoreInteractions(); - final Collection count = harvestResult.get(2, TimeUnit.SECONDS); - Assert.assertEquals(1, count.size()); + Assert.assertEquals(1, addedSgts.size()); } } \ No newline at end of file diff --git a/sxp-integration/sxp-ise-adapter/src/test/java/org/opendaylight/groupbasedpolicy/sxp_ise_adapter/impl/IseResourceTestHelper.java b/sxp-integration/sxp-ise-adapter/src/test/java/org/opendaylight/groupbasedpolicy/sxp_ise_adapter/impl/IseResourceTestHelper.java new file mode 100644 index 000000000..505f75049 --- /dev/null +++ b/sxp-integration/sxp-ise-adapter/src/test/java/org/opendaylight/groupbasedpolicy/sxp_ise_adapter/impl/IseResourceTestHelper.java @@ -0,0 +1,33 @@ +/* + * 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_ise_adapter.impl; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; + +/** + * Purpose: read content of given test file + */ +public class IseResourceTestHelper { + public static String readLocalResource(final String resourcePath) throws IOException { + final StringBuilder collector = new StringBuilder(); + try ( + final InputStream iseReplySource = IseResourceTestHelper.class.getResourceAsStream(resourcePath); + final BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(iseReplySource)) + ) { + String line; + while ((line = bufferedReader.readLine()) != null) { + collector.append(line); + } + } + return collector.toString(); + } +} diff --git a/sxp-integration/sxp-ise-adapter/src/test/java/org/opendaylight/groupbasedpolicy/sxp_ise_adapter/impl/util/IseReplyUtilTest.java b/sxp-integration/sxp-ise-adapter/src/test/java/org/opendaylight/groupbasedpolicy/sxp_ise_adapter/impl/util/IseReplyUtilTest.java new file mode 100644 index 000000000..9e3af6541 --- /dev/null +++ b/sxp-integration/sxp-ise-adapter/src/test/java/org/opendaylight/groupbasedpolicy/sxp_ise_adapter/impl/util/IseReplyUtilTest.java @@ -0,0 +1,59 @@ +/* + * 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_ise_adapter.impl.util; + +import static org.opendaylight.groupbasedpolicy.sxp_ise_adapter.impl.IseResourceTestHelper.readLocalResource; + +import com.google.common.collect.Iterables; +import java.io.IOException; +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; +import javax.xml.xpath.XPath; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.runners.MockitoJUnitRunner; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.xml.sax.InputSource; + +/** + * Test for {@link IseReplyUtil}. + */ +@RunWith(MockitoJUnitRunner.class) +public class IseReplyUtilTest { + + private final String iseReplyAllSgts; + private XPath xpath; + + public IseReplyUtilTest() throws IOException { + iseReplyAllSgts = readLocalResource("./rawIse-allSgts2.xml"); + } + + @Before + public void setUp() throws Exception { + xpath = IseReplyUtil.setupXpath(); + } + + @Test + public void filterNewResourcesByID() throws Exception { + final Map uuidMap = new HashMap<>(); + uuidMap.put("abc123", 42); + + final InputSource inputSource = IseReplyUtil.createInputSource(iseReplyAllSgts); + final NodeList allSgtResourceNodes = IseReplyUtil.findAllSgtResourceNodes(xpath, inputSource); + + final Collection filteredNodes = IseReplyUtil.filterNewResourcesByID(uuidMap, xpath, allSgtResourceNodes); + + Assert.assertEquals(1, filteredNodes.size()); + Assert.assertEquals("https://example.org:9060/ers/config/sgt/abc124", Iterables.getFirst(filteredNodes, null).getNodeValue()); + } +} \ No newline at end of file diff --git a/sxp-integration/sxp-ise-adapter/src/test/resources/org/opendaylight/groupbasedpolicy/sxp_ise_adapter/impl/rawIse-allSgts.xml b/sxp-integration/sxp-ise-adapter/src/test/resources/org/opendaylight/groupbasedpolicy/sxp_ise_adapter/impl/rawIse-allSgts1.xml similarity index 100% rename from sxp-integration/sxp-ise-adapter/src/test/resources/org/opendaylight/groupbasedpolicy/sxp_ise_adapter/impl/rawIse-allSgts.xml rename to sxp-integration/sxp-ise-adapter/src/test/resources/org/opendaylight/groupbasedpolicy/sxp_ise_adapter/impl/rawIse-allSgts1.xml diff --git a/sxp-integration/sxp-ise-adapter/src/test/resources/org/opendaylight/groupbasedpolicy/sxp_ise_adapter/impl/rawIse-allSgts2.xml b/sxp-integration/sxp-ise-adapter/src/test/resources/org/opendaylight/groupbasedpolicy/sxp_ise_adapter/impl/rawIse-allSgts2.xml new file mode 100644 index 000000000..57475e31f --- /dev/null +++ b/sxp-integration/sxp-ise-adapter/src/test/resources/org/opendaylight/groupbasedpolicy/sxp_ise_adapter/impl/rawIse-allSgts2.xml @@ -0,0 +1,22 @@ + + + + + -- 2.36.6