BUG-6858: adapt to ise api, change lookup from ise
[groupbasedpolicy.git] / sxp-integration / sxp-ise-adapter / src / main / java / org / opendaylight / groupbasedpolicy / sxp_ise_adapter / impl / EPPolicyTemplateProviderIseImpl.java
index 1f8c5be4167a6007f6c24f388019f364bf981f4f..bcea610d4dcd66b7ebacf2c34a8cf789de59e559 100644 (file)
@@ -8,28 +8,23 @@
 
 package org.opendaylight.groupbasedpolicy.sxp_ise_adapter.impl;
 
+import com.google.common.base.Function;
 import com.google.common.collect.Range;
-import com.sun.jersey.api.client.Client;
-import com.sun.jersey.api.client.WebResource;
+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.Optional;
 import javax.annotation.Nonnull;
 import javax.annotation.Nullable;
-import javax.xml.xpath.XPath;
-import javax.xml.xpath.XPathConstants;
-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.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.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.ise.source.config.ConnectionConfig;
 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;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-import org.w3c.dom.Node;
 
 /**
  * Purpose: query ise in order to get name of sgt for given tenant and build {@link EndpointPolicyTemplateBySgt}
@@ -38,13 +33,26 @@ public class EPPolicyTemplateProviderIseImpl implements EPPolicyTemplateProvider
 
     private static final Logger LOG = LoggerFactory.getLogger(EPPolicyTemplateProviderIseImpl.class);
 
-    private Optional<IseSourceConfig> iseSourceConfig = Optional.empty();
+    private Optional<IseContext> iseContext = Optional.empty();
+    private GbpIseSgtHarvester iseSgtHarvester;
 
     @Override
-    public Optional<EndpointPolicyTemplateBySgt> provideTemplate(@Nonnull final Sgt sgt) {
+    public ListenableFuture<Optional<EndpointPolicyTemplateBySgt>> provideTemplate(@Nonnull final Sgt sgt) {
         return findIseSourceConfigBySgt(sgt)
-                .flatMap(iseSourceConfig -> queryIseOnSgt(iseSourceConfig.getConnectionConfig(), sgt)
-                        .map(sgtName -> buildTemplate(sgt, iseSourceConfig.getTenant(), sgtName)));
+                .map(iseContext -> queryIseAndBuildTemplate(iseContext, sgt))
+                .orElse(Futures.immediateFuture(Optional.empty()));
+    }
+
+    private ListenableFuture<Optional<EndpointPolicyTemplateBySgt>> queryIseAndBuildTemplate(final IseContext iseContext, final Sgt sgt) {
+        final ListenableFuture<Optional<String>> sgtNameFu = queryIseOnSgt(iseContext, sgt);
+        return Futures.transform(sgtNameFu, new Function<Optional<String>, Optional<EndpointPolicyTemplateBySgt>>() {
+            @Nullable
+            @Override
+            public Optional<EndpointPolicyTemplateBySgt> apply(@Nullable final Optional<String> input) {
+                return Optional.ofNullable(input)
+                        .flatMap(i -> i.map(sgtName -> buildTemplate(sgt, iseContext.getIseSourceConfig().getTenant(), sgtName)));
+            }
+        });
     }
 
     private EndpointPolicyTemplateBySgt buildTemplate(final @Nonnull Sgt sgt, final @Nonnull TenantId tenantId,
@@ -58,39 +66,38 @@ public class EPPolicyTemplateProviderIseImpl implements EPPolicyTemplateProvider
                 .build();
     }
 
-    private Optional<String> queryIseOnSgt(final ConnectionConfig connectionConfig, final Sgt sgt) {
-        String sgtName = null;
-        try {
-            final Client iseClient = RestClientFactory.createIseClient(connectionConfig);
-            final WebResource baseWebResource = iseClient.resource(connectionConfig.getIseRestUrl().getValue());
-
-            final String pathToSgtDetail = String.format("%s/%d", RestClientFactory.PATH_ERS_CONFIG_SGT, sgt.getValue());
-            final WebResource.Builder requestBuilder = RestClientFactory.createRequestBuilder(baseWebResource,
-                    connectionConfig.getHeader(), pathToSgtDetail);
-            final String rawSgtDetail = IseReplyUtil.deliverResponse(requestBuilder);
+    private ListenableFuture<Optional<String>> queryIseOnSgt(final IseContext iseContext, @Nonnull final Sgt sgt) {
+        final ListenableFuture<Collection<SgtInfo>> sgtUpdateFu = iseSgtHarvester.update(iseContext);
+        return Futures.transform(sgtUpdateFu, new Function<Collection<SgtInfo>, Optional<String>>() {
+            @Nullable
+            @Override
+            public Optional<String> apply(@Nullable final Collection<SgtInfo> input) {
+                // pick first sgtInfo which equals to given sgt
+                return Optional.ofNullable(input)
+                        .flatMap(safeInput -> safeInput.stream()
+                                .filter(sgtInfo -> sgt.equals(sgtInfo.getSgt())).findFirst()
+                                .map(SgtInfo::getName));
+            }
+        });
+    }
 
-            final XPath xpath = IseReplyUtil.setupXpath();
-            final Node sgtNameNode = (Node) xpath.evaluate(
-                    IseReplyUtil.EXPRESSION_SGT_NAME_ATTR, IseReplyUtil.createInputSource(rawSgtDetail),
-                    XPathConstants.NODE);
-            sgtName = sgtNameNode.getNodeValue();
-            LOG.debug("obtained sgt/name: {}/{}", sgt.getValue(), sgtName);
-        } catch (Exception e) {
-            LOG.debug("failed to read sgt detail on ISE", e);
-        }
-        return Optional.ofNullable(sgtName);
+    private Optional<IseContext> findIseSourceConfigBySgt(final Sgt sgt) {
+        // expected relation (ise : tenant) == (1:1)
+        return iseContext
+                .filter(context ->
+                        Range.closed(context.getIseSourceConfig().getSgtRangeMin().getValue(),
+                                context.getIseSourceConfig().getSgtRangeMax().getValue())
+                                .contains(sgt.getValue())
+                );
     }
 
-    private Optional<IseSourceConfig> findIseSourceConfigBySgt(final Sgt sgt) {
-        //TODO: cover multiple sources / tenants .. lookup (option: multiple servers per tenant?)
-        return iseSourceConfig
-                .filter(config ->
-                        Range.closed(config.getSgtRangeMin().getValue(), config.getSgtRangeMax().getValue())
-                                .contains(sgt.getValue()));
+    @Override
+    public void assignIseContext(final @Nullable IseContext iseContext) {
+        this.iseContext = Optional.ofNullable(iseContext);
     }
 
     @Override
-    public void assignIseSourceConfig(final @Nullable IseSourceConfig iseSourceConfig) {
-        this.iseSourceConfig = Optional.ofNullable(iseSourceConfig);
+    public void setIseSgtHarvester(final GbpIseSgtHarvester iseSgtHarvester) {
+        this.iseSgtHarvester = iseSgtHarvester;
     }
 }