gbp-ise-adapter proposal 58/41158/12
authorMichal Rehak <mirehak@cisco.com>
Thu, 30 Jun 2016 16:59:17 +0000 (18:59 +0200)
committermichal rehak <mirehak@cisco.com>
Tue, 12 Jul 2016 12:15:13 +0000 (12:15 +0000)
    - initial structure
      - config
      - models
      - api+impl partial stubs
    - generating epgs
    - generating ep-policy-templates
    - storing outcome status
    - added unit tests
    - fixed javadoc/copyright issues
    - squashed interfaces from api to impl

Change-Id: I2bd09e56c5afb26616b0febb5bd74c86eb4bd447
Signed-off-by: Michal Rehak <mirehak@cisco.com>
29 files changed:
artifacts/pom.xml
features/pom.xml
features/src/main/features/features.xml
groupbasedpolicy-ise-adapter/pom.xml [new file with mode: 0755]
groupbasedpolicy-ise-adapter/src/main/config/default-config.xml [new file with mode: 0755]
groupbasedpolicy-ise-adapter/src/main/java/org/opendaylight/controller/config/yang/config/groupbasedpolicy/gbp_ise_adapter/GpbIseAdapterProviderModule.java [new file with mode: 0644]
groupbasedpolicy-ise-adapter/src/main/java/org/opendaylight/controller/config/yang/config/groupbasedpolicy/gbp_ise_adapter/GpbIseAdapterProviderModuleFactory.java [new file with mode: 0644]
groupbasedpolicy-ise-adapter/src/main/java/org/opendaylight/groupbasedpolicy/gbp_ise_adapter/impl/GbpIseAdapterProvider.java [new file with mode: 0644]
groupbasedpolicy-ise-adapter/src/main/java/org/opendaylight/groupbasedpolicy/gbp_ise_adapter/impl/GbpIseConfigListener.java [new file with mode: 0644]
groupbasedpolicy-ise-adapter/src/main/java/org/opendaylight/groupbasedpolicy/gbp_ise_adapter/impl/GbpIseConfigListenerImpl.java [new file with mode: 0644]
groupbasedpolicy-ise-adapter/src/main/java/org/opendaylight/groupbasedpolicy/gbp_ise_adapter/impl/GbpIseSgtHarvester.java [new file with mode: 0644]
groupbasedpolicy-ise-adapter/src/main/java/org/opendaylight/groupbasedpolicy/gbp_ise_adapter/impl/GbpIseSgtHarvesterImpl.java [new file with mode: 0644]
groupbasedpolicy-ise-adapter/src/main/java/org/opendaylight/groupbasedpolicy/gbp_ise_adapter/impl/SgtInfo.java [new file with mode: 0644]
groupbasedpolicy-ise-adapter/src/main/java/org/opendaylight/groupbasedpolicy/gbp_ise_adapter/impl/SgtInfoProcessor.java [new file with mode: 0644]
groupbasedpolicy-ise-adapter/src/main/java/org/opendaylight/groupbasedpolicy/gbp_ise_adapter/impl/SgtToEPTemplateGeneratorImpl.java [new file with mode: 0644]
groupbasedpolicy-ise-adapter/src/main/java/org/opendaylight/groupbasedpolicy/gbp_ise_adapter/impl/SgtToEpgGeneratorImpl.java [new file with mode: 0644]
groupbasedpolicy-ise-adapter/src/main/java/org/opendaylight/groupbasedpolicy/gbp_ise_adapter/impl/util/RestClientFactory.java [new file with mode: 0644]
groupbasedpolicy-ise-adapter/src/main/yang/gbp-ise-adapter-cfg.yang [new file with mode: 0644]
groupbasedpolicy-ise-adapter/src/main/yang/gbp-ise-adapter-model.yang [new file with mode: 0644]
groupbasedpolicy-ise-adapter/src/test/java/org/opendaylight/groupbasedpolicy/gbp_ise_adapter/impl/GbpIseAdapterProviderTest.java [new file with mode: 0644]
groupbasedpolicy-ise-adapter/src/test/java/org/opendaylight/groupbasedpolicy/gbp_ise_adapter/impl/GbpIseConfigListenerImplTest.java [new file with mode: 0644]
groupbasedpolicy-ise-adapter/src/test/java/org/opendaylight/groupbasedpolicy/gbp_ise_adapter/impl/GbpIseSgtHarvesterImplTest.java [new file with mode: 0644]
groupbasedpolicy-ise-adapter/src/test/java/org/opendaylight/groupbasedpolicy/gbp_ise_adapter/impl/SgtToEPTemplateGeneratorImplTest.java [new file with mode: 0644]
groupbasedpolicy-ise-adapter/src/test/java/org/opendaylight/groupbasedpolicy/gbp_ise_adapter/impl/SgtToEpgGeneratorImplTest.java [new file with mode: 0644]
groupbasedpolicy-ise-adapter/src/test/java/org/opendaylight/groupbasedpolicy/gbp_ise_adapter/impl/util/RestClientFactoryTest.java [new file with mode: 0644]
groupbasedpolicy-ise-adapter/src/test/resources/log4j.xml [new file with mode: 0644]
groupbasedpolicy-ise-adapter/src/test/resources/org/opendaylight/groupbasedpolicy/gbp_ise_adapter/impl/rawIse-allSgts.xml [new file with mode: 0644]
groupbasedpolicy-ise-adapter/src/test/resources/org/opendaylight/groupbasedpolicy/gbp_ise_adapter/impl/rawIse-sgtDetail.xml [new file with mode: 0644]
pom.xml

index e6d732605682328b74caf012dd78a94f58a3e422..df5c6732d411946d42d57cd413405e09da4665e5 100755 (executable)
         <artifactId>sxp-mapper</artifactId>
         <version>${project.version}</version>
       </dependency>
+      <dependency>
+        <groupId>${project.groupId}</groupId>
+        <artifactId>groupbasedpolicy-ise-adapter</artifactId>
+        <version>${project.version}</version>
+      </dependency>
 
       <!-- GBP configuration -->
       <dependency>
         <type>xml</type>
         <classifier>config</classifier>
       </dependency>
+      <dependency>
+        <groupId>${project.groupId}</groupId>
+        <artifactId>groupbasedpolicy-ise-adapter</artifactId>
+        <version>${project.version}</version>
+        <type>xml</type>
+        <classifier>config</classifier>
+      </dependency>
 
 
       <!-- GBP features -->
index 41364081fe28654a516801adf50aa6c63bc7849b..02e33de353caf1c06d4458313bd86c8961e9f61c 100755 (executable)
       <groupId>org.opendaylight.groupbasedpolicy</groupId>
       <artifactId>ios-xe-renderer</artifactId>
     </dependency>
+    <dependency>
+      <groupId>org.opendaylight.groupbasedpolicy</groupId>
+      <artifactId>groupbasedpolicy-ise-adapter</artifactId>
+    </dependency>
 
     <!-- GBP configuration -->
     <dependency>
       <type>xml</type>
       <classifier>config</classifier>
     </dependency>
+    <dependency>
+      <groupId>org.opendaylight.groupbasedpolicy</groupId>
+      <artifactId>groupbasedpolicy-ise-adapter</artifactId>
+      <type>xml</type>
+      <classifier>config</classifier>
+    </dependency>
   </dependencies>
 </project>
index cea8f8dbc889a48d6da1cdbabd8e288742542819..0d87284cdac5c1c055e79385c75f71469830fdfc 100755 (executable)
         <configfile finalname="${config.configfile.directory}/15-l2-l3-domain-extension.xml">mvn:org.opendaylight.groupbasedpolicy/l2-l3-domain-extension/{{VERSION}}/xml/config</configfile>
         <configfile finalname="${config.configfile.directory}/15-groupbasedpolicy-ios-xe-renderer.xml">mvn:org.opendaylight.groupbasedpolicy/ios-xe-renderer/{{VERSION}}/xml/config</configfile>
     </feature>
+
+    <!--
+       GBP-ISE ADAPTER
+   -->
+    <feature name='odl-groupbasedpolicy-ise-adapter' version='${project.version}' description='OpenDaylight :: groupbasedpolicy :: gbp-ise adapter'>
+        <feature version="${project.version}">odl-groupbasedpolicy-sxp-mapper</feature>
+        <feature version="${sxp.version}">odl-sxp-core</feature>
+        <bundle>mvn:commons-net/commons-net/{{VERSION}}</bundle>
+        <bundle>mvn:com.sun.jersey/jersey-client/{{VERSION}}</bundle>
+        <bundle>mvn:com.sun.jersey/jersey-core/{{VERSION}}</bundle>
+        <bundle>mvn:org.opendaylight.groupbasedpolicy/groupbasedpolicy-ise-adapter/{{VERSION}}</bundle>
+        <configfile finalname="${config.configfile.directory}/16-groupbasedpolicy-ise-adapter.xml">mvn:org.opendaylight.groupbasedpolicy/groupbasedpolicy-ise-adapter/{{VERSION}}/xml/config</configfile>
+    </feature>
 </features>
diff --git a/groupbasedpolicy-ise-adapter/pom.xml b/groupbasedpolicy-ise-adapter/pom.xml
new file mode 100755 (executable)
index 0000000..4300f46
--- /dev/null
@@ -0,0 +1,117 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 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 -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.opendaylight.controller</groupId>
+        <artifactId>config-parent</artifactId>
+        <version>0.5.0-SNAPSHOT</version>
+        <relativePath/>
+    </parent>
+
+    <groupId>org.opendaylight.groupbasedpolicy</groupId>
+    <artifactId>groupbasedpolicy-ise-adapter</artifactId>
+    <version>0.4.0-SNAPSHOT</version>
+    <packaging>bundle</packaging>
+    <name>groupbasedpolicy-ise-adapter</name>
+
+    <properties>
+        <sxp.version>1.3.0-SNAPSHOT</sxp.version>
+    </properties>
+
+    <dependencyManagement>
+        <dependencies>
+            <dependency>
+                <groupId>org.opendaylight.groupbasedpolicy</groupId>
+                <artifactId>groupbasedpolicy-artifacts</artifactId>
+                <version>${project.version}</version>
+                <scope>import</scope>
+                <type>pom</type>
+            </dependency>
+             <dependency>
+                <groupId>org.opendaylight.sxp</groupId>
+                <artifactId>sxp-api</artifactId>
+                <version>${sxp.version}</version>
+            </dependency>
+        </dependencies>
+    </dependencyManagement>
+
+    <dependencies>
+        <!-- model dependencies -->
+        <dependency>
+            <groupId>org.opendaylight.groupbasedpolicy</groupId>
+            <artifactId>sxp-mapper</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.sxp</groupId>
+            <artifactId>sxp-api</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.opendaylight.mdsal.model</groupId>
+            <artifactId>ietf-inet-types</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.mdsal.model</groupId>
+            <artifactId>ietf-yang-types</artifactId>
+        </dependency>
+
+        <!-- util -->
+        <dependency>
+            <groupId>commons-net</groupId>
+            <artifactId>commons-net</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.sun.jersey</groupId>
+            <artifactId>jersey-client</artifactId>
+        </dependency>
+
+        <!-- testing dependencies -->
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.mockito</groupId>
+            <artifactId>mockito-all</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-log4j12</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.powermock</groupId>
+            <artifactId>powermock-module-junit4</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.powermock</groupId>
+            <artifactId>powermock-api-mockito</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>sal-binding-broker-impl</artifactId>
+            <type>test-jar</type>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+
+    <!-- project build -->
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.felix</groupId>
+                <artifactId>maven-bundle-plugin</artifactId>
+                <extensions>true</extensions>
+            </plugin>
+        </plugins>
+    </build>
+</project>
diff --git a/groupbasedpolicy-ise-adapter/src/main/config/default-config.xml b/groupbasedpolicy-ise-adapter/src/main/config/default-config.xml
new file mode 100755 (executable)
index 0000000..2f71a2c
--- /dev/null
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ 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
+  -->
+
+<!-- vi: set et smarttab sw=4 tabstop=4: -->
+
+<snapshot>
+    <configuration>
+        <data xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
+            <modules xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
+                <module>
+                    <type xmlns:gbp-ise-adapter="urn:opendaylight:params:xml:ns:yang:controller:config:groupbasedpolicy:gbp-ise-adapter">
+                        gbp-ise-adapter:gbp-ise-adapter-impl
+                    </type>
+                    <name>gbp-ise-adapter</name>
+
+                    <data-broker>
+                        <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-async-data-broker</type>
+                        <name>binding-data-broker</name>
+                    </data-broker>
+                    <broker>
+                        <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-broker-osgi-registry</type>
+                        <name>binding-osgi-broker</name>
+                    </broker>
+                </module>
+            </modules>
+        </data>
+    </configuration>
+
+    <required-capabilities>
+        <capability>urn:opendaylight:params:xml:ns:yang:controller:config:groupbasedpolicy:gbp-ise-adapter?module=gbp-ise-adapter-cfg&amp;revision=2016-06-30</capability>
+        <capability>urn:opendaylight:params:xml:ns:yang:controller:config:groupbasedpolicy:gbp-ise-adapter:model?module=gbp-ise-adapter-model&amp;revision=2016-06-30</capability>
+    </required-capabilities>
+
+</snapshot>
diff --git a/groupbasedpolicy-ise-adapter/src/main/java/org/opendaylight/controller/config/yang/config/groupbasedpolicy/gbp_ise_adapter/GpbIseAdapterProviderModule.java b/groupbasedpolicy-ise-adapter/src/main/java/org/opendaylight/controller/config/yang/config/groupbasedpolicy/gbp_ise_adapter/GpbIseAdapterProviderModule.java
new file mode 100644 (file)
index 0000000..415f9e9
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * 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.gbp_ise_adapter;
+
+import org.opendaylight.groupbasedpolicy.gbp_ise_adapter.impl.GbpIseAdapterProvider;
+
+/**
+* gbp-ise-adapter impl module
+*/
+public class GpbIseAdapterProviderModule extends org.opendaylight.controller.config.yang.config.groupbasedpolicy.gbp_ise_adapter.AbstractGpbIseAdapterProviderModule {
+    public GpbIseAdapterProviderModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
+        super(identifier, dependencyResolver);
+    }
+
+    public GpbIseAdapterProviderModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver, org.opendaylight.controller.config.yang.config.groupbasedpolicy.gbp_ise_adapter.GpbIseAdapterProviderModule oldModule, java.lang.AutoCloseable oldInstance) {
+        super(identifier, dependencyResolver, oldModule, oldInstance);
+    }
+
+    @Override
+    public void customValidation() {
+        // add custom validation form module attributes here.
+    }
+
+    @Override
+    public java.lang.AutoCloseable createInstance() {
+        return new GbpIseAdapterProvider(getDataBrokerDependency(), getBrokerDependency());
+    }
+
+}
diff --git a/groupbasedpolicy-ise-adapter/src/main/java/org/opendaylight/controller/config/yang/config/groupbasedpolicy/gbp_ise_adapter/GpbIseAdapterProviderModuleFactory.java b/groupbasedpolicy-ise-adapter/src/main/java/org/opendaylight/controller/config/yang/config/groupbasedpolicy/gbp_ise_adapter/GpbIseAdapterProviderModuleFactory.java
new file mode 100644 (file)
index 0000000..4c15447
--- /dev/null
@@ -0,0 +1,21 @@
+/*
+ * 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
+ */
+
+/*
+* Generated file
+*
+* Generated from: yang module name: gbp-ise-adapter-cfg yang module local name: gbp-ise-adapter-impl
+* Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
+* Generated at: Thu Jun 30 17:44:55 CEST 2016
+*
+* Do not modify this file unless it is present under src/main directory
+*/
+package org.opendaylight.controller.config.yang.config.groupbasedpolicy.gbp_ise_adapter;
+public class GpbIseAdapterProviderModuleFactory extends org.opendaylight.controller.config.yang.config.groupbasedpolicy.gbp_ise_adapter.AbstractGpbIseAdapterProviderModuleFactory {
+
+}
diff --git a/groupbasedpolicy-ise-adapter/src/main/java/org/opendaylight/groupbasedpolicy/gbp_ise_adapter/impl/GbpIseAdapterProvider.java b/groupbasedpolicy-ise-adapter/src/main/java/org/opendaylight/groupbasedpolicy/gbp_ise_adapter/impl/GbpIseAdapterProvider.java
new file mode 100644 (file)
index 0000000..b295097
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+ * 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.gbp_ise_adapter.impl;
+
+import com.google.common.base.Preconditions;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.DataTreeChangeListener;
+import org.opendaylight.controller.md.sal.binding.api.DataTreeIdentifier;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.sal.binding.api.BindingAwareBroker;
+import org.opendaylight.controller.sal.binding.api.BindingAwareProvider;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.gbp.ise.adapter.model.rev160630.GbpIseAdapter;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.gbp.ise.adapter.model.rev160630.gbp.ise.adapter.IseHarvestConfig;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Purpose: main provider of gbp-ise adapter (for reading sgts and generating EndpointPolicyTemplates)
+ */
+public class GbpIseAdapterProvider implements AutoCloseable, BindingAwareProvider {
+
+    private static final Logger LOG = LoggerFactory.getLogger(GbpIseAdapterProvider.class);
+
+    private final DataBroker dataBroker;
+    private ListenerRegistration<DataTreeChangeListener<IseHarvestConfig>> registration;
+
+    public GbpIseAdapterProvider(final DataBroker dataBroker, final BindingAwareBroker brokerDependency) {
+        this.dataBroker = Preconditions.checkNotNull(dataBroker, "provided dataBroker must not be null");
+        brokerDependency.registerProvider(this);
+    }
+
+    @Override
+    public void close() throws Exception {
+        if (registration != null) {
+            LOG.info("closing GbpIseAdapterProvider");
+            registration.close();
+            registration = null;
+        }
+    }
+
+    @Override
+    public void onSessionInitiated(final BindingAwareBroker.ProviderContext providerContext) {
+        LOG.info("Starting GbpIseAdapterProvider ..");
+
+        // setup harvesting and processing pipeline
+        final SgtInfoProcessor epgGenerator = new SgtToEpgGeneratorImpl(dataBroker);
+        final SgtInfoProcessor templateGenerator = new SgtToEPTemplateGeneratorImpl(dataBroker);
+        final GbpIseSgtHarvester gbpIseSgtHarvester = new GbpIseSgtHarvesterImpl(epgGenerator, templateGenerator);
+        final GbpIseConfigListenerImpl gbpIseConfigListener = new GbpIseConfigListenerImpl(dataBroker, gbpIseSgtHarvester);
+
+        // build data-tree path
+        final DataTreeIdentifier<IseHarvestConfig> dataTreePath = new DataTreeIdentifier<>(
+                LogicalDatastoreType.CONFIGURATION,
+                InstanceIdentifier.create(GbpIseAdapter.class).child(IseHarvestConfig.class));
+
+        // register config listener
+        registration = dataBroker.registerDataTreeChangeListener(dataTreePath,
+                gbpIseConfigListener);
+
+        LOG.info("Started");
+    }
+}
diff --git a/groupbasedpolicy-ise-adapter/src/main/java/org/opendaylight/groupbasedpolicy/gbp_ise_adapter/impl/GbpIseConfigListener.java b/groupbasedpolicy-ise-adapter/src/main/java/org/opendaylight/groupbasedpolicy/gbp_ise_adapter/impl/GbpIseConfigListener.java
new file mode 100644 (file)
index 0000000..399ca5f
--- /dev/null
@@ -0,0 +1,19 @@
+/*
+ * 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.gbp_ise_adapter.impl;
+
+import org.opendaylight.controller.md.sal.binding.api.DataTreeChangeListener;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.gbp.ise.adapter.model.rev160630.gbp.ise.adapter.IseHarvestConfig;
+
+/**
+ * Purpose: dtcl for {@link IseHarvestConfig}
+ */
+public interface GbpIseConfigListener extends DataTreeChangeListener<IseHarvestConfig>, AutoCloseable {
+    // nobody
+}
diff --git a/groupbasedpolicy-ise-adapter/src/main/java/org/opendaylight/groupbasedpolicy/gbp_ise_adapter/impl/GbpIseConfigListenerImpl.java b/groupbasedpolicy-ise-adapter/src/main/java/org/opendaylight/groupbasedpolicy/gbp_ise_adapter/impl/GbpIseConfigListenerImpl.java
new file mode 100644 (file)
index 0000000..e613ca9
--- /dev/null
@@ -0,0 +1,128 @@
+/*
+ * 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.gbp_ise_adapter.impl;
+
+import com.google.common.util.concurrent.CheckedFuture;
+import com.google.common.util.concurrent.FutureCallback;
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
+import com.google.common.util.concurrent.ThreadFactoryBuilder;
+import java.text.SimpleDateFormat;
+import java.util.Collection;
+import java.util.Date;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.DateAndTime;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.gbp.ise.adapter.model.rev160630.GbpIseAdapter;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.gbp.ise.adapter.model.rev160630.gbp.ise.adapter.IseHarvestConfig;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.gbp.ise.adapter.model.rev160630.gbp.ise.adapter.IseHarvestStatus;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.gbp.ise.adapter.model.rev160630.gbp.ise.adapter.IseHarvestStatusBuilder;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Purpose: listen for harvest configuration and trigger harvesting
+ */
+public class GbpIseConfigListenerImpl implements GbpIseConfigListener {
+
+    private static final Logger LOG = LoggerFactory.getLogger(GbpIseConfigListenerImpl.class);
+
+    private static final String DATE_AND_TIME_FORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSSXXX";
+
+    private final DataBroker dataBroker;
+    private final GbpIseSgtHarvester gbpIseSgtHarvester;
+    private final ThreadPoolExecutor pool;
+
+    public GbpIseConfigListenerImpl(@Nonnull final DataBroker dataBroker, @Nonnull final GbpIseSgtHarvester gbpIseSgtHarvester) {
+        this.dataBroker = dataBroker;
+        this.gbpIseSgtHarvester = gbpIseSgtHarvester;
+        pool = new ThreadPoolExecutor(1, 1, 0, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>(10),
+                new ThreadFactoryBuilder().setNameFormat("ise-sgt-harverster-%d").build()) {
+            @Override
+            protected void afterExecute(final Runnable r, final Throwable t) {
+                super.afterExecute(r, t);
+                if (t != null) {
+                    LOG.warn("ise harvest task failed", t);
+                }
+            }
+        };
+    }
+
+    @Override
+    public void onDataTreeChanged(@Nonnull final Collection<DataTreeModification<IseHarvestConfig>> collection) {
+        for (DataTreeModification<IseHarvestConfig> modification : collection) {
+            final IseHarvestConfig iseHarvestConfig = modification.getRootNode().getDataAfter();
+            if (iseHarvestConfig != null) {
+                pool.submit(() -> {
+                    final ListenableFuture<Integer> harvestResult = gbpIseSgtHarvester.harvest(iseHarvestConfig);
+                    Futures.addCallback(harvestResult, new FutureCallback<Integer>() {
+                        @Override
+                        public void onSuccess(@Nullable final Integer result) {
+                            LOG.debug("ise harvest finished, outcome: {}", result);
+                            storeOutcome(true, result.intValue(), null);
+                        }
+
+                        @Override
+                        public void onFailure(final Throwable t) {
+                            LOG.debug("ise harvest failed", t);
+                            storeOutcome(false, 0, t.getMessage());
+                        }
+                    });
+
+                    try {
+                        harvestResult.get(30, TimeUnit.SECONDS);
+                    } catch (InterruptedException | ExecutionException | TimeoutException e) {
+                        LOG.debug("failed to finish ise-sgt-harvest task properly on time", e);
+                    }
+                });
+            }
+        }
+    }
+
+    private CheckedFuture<Void, TransactionCommitFailedException> storeOutcome(final boolean succeeded, final int counter, final String reason) {
+        final WriteTransaction wTx = dataBroker.newWriteOnlyTransaction();
+        final InstanceIdentifier<IseHarvestStatus> harvestStatusPath = InstanceIdentifier.create(GbpIseAdapter.class)
+                .child(IseHarvestStatus.class);
+        final IseHarvestStatus harvestStatus = new IseHarvestStatusBuilder()
+                .setReason(reason)
+                .setSuccess(succeeded)
+                .setTemplatesWritten(counter)
+                .setTimestamp(createDateTime(new Date()))
+                .build();
+        wTx.put(LogicalDatastoreType.OPERATIONAL, harvestStatusPath, harvestStatus, true);
+        return wTx.submit();
+    }
+
+    private static DateAndTime createDateTime(Date when) {
+        final SimpleDateFormat simpleDateFormat = new SimpleDateFormat(DATE_AND_TIME_FORMAT);
+        return new DateAndTime(simpleDateFormat.format(when));
+    }
+
+    @Override
+    public void close() throws Exception {
+        if (!pool.isTerminated()) {
+            pool.shutdown();
+            final boolean terminated = pool.awaitTermination(10, TimeUnit.SECONDS);
+            if (! terminated) {
+                pool.shutdownNow();
+            }
+        }
+    }
+}
diff --git a/groupbasedpolicy-ise-adapter/src/main/java/org/opendaylight/groupbasedpolicy/gbp_ise_adapter/impl/GbpIseSgtHarvester.java b/groupbasedpolicy-ise-adapter/src/main/java/org/opendaylight/groupbasedpolicy/gbp_ise_adapter/impl/GbpIseSgtHarvester.java
new file mode 100644 (file)
index 0000000..d551e7a
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+ * 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.gbp_ise_adapter.impl;
+
+import com.google.common.util.concurrent.ListenableFuture;
+import javax.annotation.Nonnull;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.gbp.ise.adapter.model.rev160630.gbp.ise.adapter.IseHarvestConfig;
+
+/**
+ * Purpose: read sgts and naming from ISE via rest-API and have apropriate templates generated and stored
+ */
+public interface GbpIseSgtHarvester {
+
+    /**
+     * @param configuration user given
+     * @return amount of successfully written items
+     */
+    ListenableFuture<Integer> harvest(@Nonnull IseHarvestConfig configuration);
+}
diff --git a/groupbasedpolicy-ise-adapter/src/main/java/org/opendaylight/groupbasedpolicy/gbp_ise_adapter/impl/GbpIseSgtHarvesterImpl.java b/groupbasedpolicy-ise-adapter/src/main/java/org/opendaylight/groupbasedpolicy/gbp_ise_adapter/impl/GbpIseSgtHarvesterImpl.java
new file mode 100644 (file)
index 0000000..bff6d7e
--- /dev/null
@@ -0,0 +1,194 @@
+/*
+ * 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.gbp_ise_adapter.impl;
+
+import com.google.common.base.Function;
+import com.google.common.util.concurrent.AsyncFunction;
+import com.google.common.util.concurrent.Futures;
+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.StringReader;
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+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.opendaylight.groupbasedpolicy.gbp_ise_adapter.impl.util.RestClientFactory;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.gbp.ise.adapter.model.rev160630.gbp.ise.adapter.IseHarvestConfig;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.gbp.ise.adapter.model.rev160630.gbp.ise.adapter.ise.harvest.config.ConnectionConfig;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.gbp.ise.adapter.model.rev160630.gbp.ise.adapter.ise.harvest.config.connection.config.Header;
+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;
+import org.w3c.dom.NodeList;
+import org.xml.sax.InputSource;
+
+/**
+ * Purpose: harvest sgt + names available via ise-rest-api
+ */
+public class GbpIseSgtHarvesterImpl implements GbpIseSgtHarvester {
+
+    private static final Logger LOG = LoggerFactory.getLogger(GbpIseSgtHarvesterImpl.class);
+
+    public static final String PATH_ERS_CONFIG_SGT = "/ers/config/sgt";
+    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_VALUE = "./value/text()";
+
+    private final SgtInfoProcessor[] sgtInfoProcessors;
+
+    /**
+     * @param sgtInfoProcessors generator delegate
+     */
+    public GbpIseSgtHarvesterImpl(final SgtInfoProcessor... sgtInfoProcessors) {
+        this.sgtInfoProcessors = sgtInfoProcessors;
+    }
+
+    @Override
+    public ListenableFuture<Integer> harvest(@Nonnull final IseHarvestConfig configuration) {
+        final ConnectionConfig connectionConfig = configuration.getConnectionConfig();
+        ListenableFuture<Integer> result;
+        try {
+            final Client iseClient = RestClientFactory.createIseClient(connectionConfig);
+            final WebResource baseWebResource = iseClient.resource(connectionConfig.getIseRestUrl().getValue());
+
+            final WebResource.Builder requestBuilder = createRequestBuilder(baseWebResource,
+                    connectionConfig.getHeader(), PATH_ERS_CONFIG_SGT);
+            final String rawSgtSummary = deliverResponse(requestBuilder);
+
+            final List<SgtInfo> sgtInfos = harvestDetails(rawSgtSummary, baseWebResource, connectionConfig.getHeader());
+
+            ListenableFuture<Void> processingResult = Futures.immediateCheckedFuture(null);
+            for (SgtInfoProcessor processor : sgtInfoProcessors) {
+                processingResult = Futures.transform(processingResult, new AsyncFunction<Void, Void>() {
+                    @Override
+                    public ListenableFuture<Void> apply(final Void input) throws Exception {
+                        LOG.debug("entering stg-info processor {}", processor.getClass().getSimpleName());
+                        return processor.processSgtInfo(configuration.getTenant(), sgtInfos);
+                    }
+                });
+            }
+            result = Futures.transform(processingResult, new Function<Void, Integer>() {
+                @Nullable
+                @Override
+                public Integer apply(@Nullable final Void input) {
+                    // always success, otherwise there will be TransactionCommitFailedException thrown
+                    return sgtInfos.size();
+                }
+            });
+        } catch (Exception e) {
+            LOG.debug("failed to harvest ise", e);
+            result = Futures.immediateFailedFuture(e);
+        }
+
+        return result;
+    }
+
+    private static String deliverResponse(final WebResource.Builder requestBuilder) {
+        return requestBuilder.get(ClientResponse.class).getEntity(String.class);
+    }
+
+    private static WebResource.Builder createRequestBuilder(final WebResource resource, final List<Header> headers,
+                                                            final String path) {
+        final WebResource webResource = resource.path(path);
+        final WebResource.Builder requestBuilder = webResource.getRequestBuilder();
+        headers.stream().forEach(
+                (header) -> requestBuilder.header(header.getName(), header.getValue()));
+        return requestBuilder;
+    }
+
+    private List<SgtInfo> harvestDetails(final String rawSgtSummary, final WebResource baseWebResource, final List<Header> headers) {
+        LOG.trace("rawSgtSummary: {}", rawSgtSummary);
+        final List<SgtInfo> sgtInfos = new ArrayList<>();
+
+        // parse sgtSummary
+        final XPath xpath = setupXpath();
+
+        InputSource inputSource = new InputSource(new StringReader(rawSgtSummary));
+        try {
+            final NodeList sgtLinkNodes = (NodeList) xpath.evaluate(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);
+
+                // query all sgt entries (serial-vise)
+                final URI hrefToSgtDetailUri = URI.create(sgtLinkHrefValue);
+                final WebResource.Builder requestBuilder = createRequestBuilder(baseWebResource, headers, hrefToSgtDetailUri.getPath());
+                final String rawSgtDetail = deliverResponse(requestBuilder);
+                LOG.trace("rawSgtDetail: {}", rawSgtDetail);
+
+                final Node sgtNode = (Node) xpath.evaluate(EXPRESSION_SGT_DETAIL,  new InputSource(new StringReader(rawSgtDetail)),
+                        XPathConstants.NODE);
+                final Node sgtName = (Node) xpath.evaluate(EXPRESSION_SGT_NAME_ATTR,  sgtNode, XPathConstants.NODE);
+                final Node sgtValue = (Node) xpath.evaluate(EXPRESSION_SGT_VALUE,  sgtNode, XPathConstants.NODE);
+                LOG.debug("sgt value [{}]: {} -> {}", i, sgtValue, sgtName);
+
+                // store replies into list of SgtInfo
+                final Sgt sgt = new Sgt(Integer.parseInt(sgtValue.getNodeValue(), 10));
+                final SgtInfo sgtInfo = new SgtInfo(sgt, sgtName.getNodeValue());
+                sgtInfos.add(sgtInfo);
+            }
+        } catch (XPathExpressionException e) {
+            LOG.warn("failed to parse all-sgt response", e);
+        }
+
+        return sgtInfos;
+    }
+
+    /**
+     * @return initiated xpath with ise namespace context injected
+     */
+    private static XPath setupXpath() {
+        final NamespaceContext nsContext = new NamespaceContext() {
+            public String getNamespaceURI(String prefix) {
+                final String outcome;
+                if (prefix == null) {
+                    throw new NullPointerException("Null prefix");
+                }
+
+                if ("ns5".equals(prefix)) {
+                    outcome = "ers.ise.cisco.com";
+                } else if ("ns3".equals(prefix)) {
+                    outcome = "v2.ers.ise.cisco.com";
+                } else if ("ns4".equals(prefix)) {
+                    outcome = "trustsec.ers.ise.cisco.com";
+                } else {
+                    outcome = XMLConstants.NULL_NS_URI;
+                }
+                return outcome;
+            }
+
+            // This method isn't necessary for XPath processing.
+            public String getPrefix(String uri) {
+                throw new UnsupportedOperationException();
+            }
+
+            // This method isn't necessary for XPath processing either.
+            public Iterator getPrefixes(String uri) {
+                throw new UnsupportedOperationException();
+            }
+        };
+
+        XPath xpath = XPathFactory.newInstance().newXPath();
+        xpath.setNamespaceContext(nsContext);
+        return xpath;
+    }
+}
diff --git a/groupbasedpolicy-ise-adapter/src/main/java/org/opendaylight/groupbasedpolicy/gbp_ise_adapter/impl/SgtInfo.java b/groupbasedpolicy-ise-adapter/src/main/java/org/opendaylight/groupbasedpolicy/gbp_ise_adapter/impl/SgtInfo.java
new file mode 100644 (file)
index 0000000..015e282
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * 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.gbp_ise_adapter.impl;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.sxp.database.rev160308.Sgt;
+
+/**
+ * Purpose: simple holder for {@link Sgt} and name
+ */
+public class SgtInfo {
+
+    private final Sgt sgt;
+    private final String name;
+
+    /**
+     * @param sgt  value to hold
+     * @param name value to hold
+     */
+    public SgtInfo(@Nonnull final Sgt sgt, @Nullable final String name) {
+        this.sgt = sgt;
+        this.name = name;
+    }
+
+    /**
+     * @return sgt
+     */
+    public Sgt getSgt() {
+        return sgt;
+    }
+
+    /**
+     * @return name associated to sgt
+     */
+    public String getName() {
+        return name;
+    }
+}
diff --git a/groupbasedpolicy-ise-adapter/src/main/java/org/opendaylight/groupbasedpolicy/gbp_ise_adapter/impl/SgtInfoProcessor.java b/groupbasedpolicy-ise-adapter/src/main/java/org/opendaylight/groupbasedpolicy/gbp_ise_adapter/impl/SgtInfoProcessor.java
new file mode 100644 (file)
index 0000000..e281515
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ * 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.gbp_ise_adapter.impl;
+
+import com.google.common.util.concurrent.CheckedFuture;
+import java.util.List;
+import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.TenantId;
+
+/**
+ * Purpose: process given sgt+name
+ */
+public interface SgtInfoProcessor {
+
+    /**
+     * @param tenant   shared by all processed epgs
+     * @param sgtInfos list of sgts to process
+     * @return outcome of dataStore write operation
+     */
+    CheckedFuture<Void, TransactionCommitFailedException> processSgtInfo(final TenantId tenant, List<SgtInfo> sgtInfos);
+}
diff --git a/groupbasedpolicy-ise-adapter/src/main/java/org/opendaylight/groupbasedpolicy/gbp_ise_adapter/impl/SgtToEPTemplateGeneratorImpl.java b/groupbasedpolicy-ise-adapter/src/main/java/org/opendaylight/groupbasedpolicy/gbp_ise_adapter/impl/SgtToEPTemplateGeneratorImpl.java
new file mode 100644 (file)
index 0000000..c5521e3
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * 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.gbp_ise_adapter.impl;
+
+import com.google.common.util.concurrent.CheckedFuture;
+import java.util.Collections;
+import java.util.List;
+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;
+import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
+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.mapper.model.rev160302.SxpMapper;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.mapper.model.rev160302.sxp.mapper.EndpointPolicyTemplateBySgt;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.mapper.model.rev160302.sxp.mapper.EndpointPolicyTemplateBySgtBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.mapper.model.rev160302.sxp.mapper.EndpointPolicyTemplateBySgtKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.sxp.database.rev160308.Sgt;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Purpose: process given sgt+name - create {@link EndpointPolicyTemplateBySgt} and write it to sxp-mapper templates
+ */
+public class SgtToEPTemplateGeneratorImpl implements SgtInfoProcessor {
+
+    private static final Logger LOG = LoggerFactory.getLogger(SgtToEPTemplateGeneratorImpl.class);
+
+    private final DataBroker dataBroker;
+
+    public SgtToEPTemplateGeneratorImpl(final DataBroker dataBroker) {
+        this.dataBroker = dataBroker;
+    }
+
+    @Override
+    public CheckedFuture<Void, TransactionCommitFailedException> processSgtInfo(final TenantId tenantId, final List<SgtInfo> sgtInfos) {
+        final WriteTransaction wTx = dataBroker.newWriteOnlyTransaction();
+
+        // write endpoint-policy-templates
+        boolean createParent = true;
+        for (SgtInfo sgtInfo : sgtInfos) {
+            final Sgt sgt = sgtInfo.getSgt();
+            final String sgtName = sgtInfo.getName();
+            LOG.trace("processing sgtInfo: {} - {}", sgt.getValue(), sgtName);
+
+            final EndpointGroupId epgId = new EndpointGroupId(sgtInfo.getName());
+
+            final InstanceIdentifier<EndpointPolicyTemplateBySgt> epPolicyTemplatePath = InstanceIdentifier
+                    .create(SxpMapper.class)
+                    .child(EndpointPolicyTemplateBySgt.class, new EndpointPolicyTemplateBySgtKey(sgt));
+
+            final EndpointPolicyTemplateBySgt epPolicyTemplate = new EndpointPolicyTemplateBySgtBuilder()
+                    .setSgt(sgt)
+                    .setEndpointGroups(Collections.singletonList(epgId))
+                    .setTenant(tenantId)
+                    .build();
+            wTx.put(LogicalDatastoreType.CONFIGURATION, epPolicyTemplatePath, epPolicyTemplate, createParent);
+            createParent = false;
+        }
+        return wTx.submit();
+    }
+}
diff --git a/groupbasedpolicy-ise-adapter/src/main/java/org/opendaylight/groupbasedpolicy/gbp_ise_adapter/impl/SgtToEpgGeneratorImpl.java b/groupbasedpolicy-ise-adapter/src/main/java/org/opendaylight/groupbasedpolicy/gbp_ise_adapter/impl/SgtToEpgGeneratorImpl.java
new file mode 100644 (file)
index 0000000..3628137
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * 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.gbp_ise_adapter.impl;
+
+import com.google.common.util.concurrent.CheckedFuture;
+import java.util.List;
+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;
+import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
+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;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.Name;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.TenantId;
+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.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Purpose: process given sgt+name - create {@link EndpointGroup} and write it to tenants/tenant/policy/endpoint-group
+ */
+public class SgtToEpgGeneratorImpl implements SgtInfoProcessor {
+
+    private static final Logger LOG = LoggerFactory.getLogger(SgtToEpgGeneratorImpl.class);
+
+    private final DataBroker dataBroker;
+
+    public SgtToEpgGeneratorImpl(final DataBroker dataBroker) {
+        this.dataBroker = dataBroker;
+    }
+
+    @Override
+    public CheckedFuture<Void, TransactionCommitFailedException> processSgtInfo(final TenantId tenantId, final List<SgtInfo> sgtInfos) {
+        final WriteTransaction wTx = dataBroker.newWriteOnlyTransaction();
+
+        // create and write endpointgroups
+        boolean createParent = true;
+        for (SgtInfo sgtInfo : sgtInfos) {
+            final Integer sgtValue = sgtInfo.getSgt().getValue();
+            final String sgtName = sgtInfo.getName();
+            LOG.trace("processing sgtInfo: {} - {}", sgtValue, sgtName);
+
+            final EndpointGroupId epgId = new EndpointGroupId(sgtName);
+            final InstanceIdentifier<EndpointGroup> epgPath = IidFactory.endpointGroupIid(tenantId, epgId);
+            final EndpointGroup epg = new EndpointGroupBuilder()
+                    .setId(epgId)
+                    .setDescription(new Description("imported from ISE for sgt=" + sgtValue))
+                    .setName(new Name(sgtName.replaceAll(" ", "_") + "--" + sgtValue))
+                    .build();
+            wTx.put(LogicalDatastoreType.CONFIGURATION, epgPath, epg, createParent);
+            createParent = false;
+        }
+        return wTx.submit();
+    }
+}
diff --git a/groupbasedpolicy-ise-adapter/src/main/java/org/opendaylight/groupbasedpolicy/gbp_ise_adapter/impl/util/RestClientFactory.java b/groupbasedpolicy-ise-adapter/src/main/java/org/opendaylight/groupbasedpolicy/gbp_ise_adapter/impl/util/RestClientFactory.java
new file mode 100644 (file)
index 0000000..26cc304
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * 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.gbp_ise_adapter.impl.util;
+
+import com.sun.jersey.api.client.Client;
+import com.sun.jersey.api.client.config.ClientConfig;
+import com.sun.jersey.api.client.config.DefaultClientConfig;
+import com.sun.jersey.client.urlconnection.HTTPSProperties;
+import java.security.GeneralSecurityException;
+import java.security.KeyManagementException;
+import java.security.NoSuchAlgorithmException;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.TrustManager;
+import org.apache.commons.net.util.TrustManagerUtils;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.gbp.ise.adapter.model.rev160630.gbp.ise.adapter.ise.harvest.config.ConnectionConfig;
+
+/**
+ * Purpose: setup ise-ready jersey {@link Client}
+ */
+public class RestClientFactory {
+
+    private RestClientFactory() {
+        throw new IllegalAccessError("factory class - no instances supported");
+    }
+
+    /**
+     * @param connectionConfig config provided
+     * @return initiated jersey client - ready to talk to ise
+     *
+     * @throws GeneralSecurityException in case when insecure certificate hack fails
+     */
+    public static Client createIseClient(final ConnectionConfig connectionConfig) throws GeneralSecurityException {
+        final DefaultClientConfig clientConfig = new DefaultClientConfig();
+        clientConfig.getProperties()
+                .put(ClientConfig.PROPERTY_CONNECT_TIMEOUT, connectionConfig.getConnectionTimeout());
+        clientConfig.getProperties()
+                .put(ClientConfig.PROPERTY_READ_TIMEOUT, connectionConfig.getReadTimeout());
+
+        hackInsecureCertificate(clientConfig);
+        return Client.create(clientConfig);
+    }
+
+    private static void hackInsecureCertificate(final ClientConfig clientConfigArg)
+            throws NoSuchAlgorithmException, KeyManagementException {
+        final TrustManager[] trustAllCerts = new TrustManager[]{TrustManagerUtils.getAcceptAllTrustManager()};
+
+        SSLContext sslContext = SSLContext.getInstance("SSL");
+        sslContext.init(null, trustAllCerts, null);
+
+        clientConfigArg.getProperties().put(HTTPSProperties.PROPERTY_HTTPS_PROPERTIES, new HTTPSProperties(
+                (s, sslSession) -> true,
+                sslContext
+        ));
+    }
+}
diff --git a/groupbasedpolicy-ise-adapter/src/main/yang/gbp-ise-adapter-cfg.yang b/groupbasedpolicy-ise-adapter/src/main/yang/gbp-ise-adapter-cfg.yang
new file mode 100644 (file)
index 0000000..90548b0
--- /dev/null
@@ -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
+ */
+
+module gbp-ise-adapter-cfg {
+    yang-version 1;
+    namespace "urn:opendaylight:params:xml:ns:yang:controller:config:groupbasedpolicy:gbp-ise-adapter";
+    prefix "gpb-ise-adapter-cfg";
+
+    import config { prefix config; revision-date 2013-04-05; }
+    import opendaylight-md-sal-binding { prefix mdsal; revision-date 2013-10-28; }
+
+    description
+        "This module contains the base YANG definitions for
+          gbp-ise-adapter impl configuration.";
+
+    revision "2016-06-30" {
+        description
+            "Initial revision.";
+    }
+
+    identity gbp-ise-adapter-impl {
+        description
+            "gbp-ise-adapter impl module";
+
+        base "config:module-type";
+        config:java-name-prefix GpbIseAdapterProvider;
+    }
+
+    // Augments the 'configuration' choice node under modules/module.
+    augment "/config:modules/config:module/config:configuration" {
+        case gbp-ise-adapter-impl {
+            when "/config:modules/config:module/config:type = 'gbp-ise-adapter-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;
+                    }
+                }
+            }
+
+            container broker {
+                uses config:service-ref {
+                    refine type {
+                        mandatory true;
+                        config:required-identity mdsal:binding-broker-osgi-registry;
+                    }
+                }
+            }
+
+        }
+    }
+}
diff --git a/groupbasedpolicy-ise-adapter/src/main/yang/gbp-ise-adapter-model.yang b/groupbasedpolicy-ise-adapter/src/main/yang/gbp-ise-adapter-model.yang
new file mode 100644 (file)
index 0000000..bc59cc5
--- /dev/null
@@ -0,0 +1,101 @@
+/*
+ * 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
+ */
+
+module gbp-ise-adapter-model {
+    yang-version 1;
+    namespace "urn:opendaylight:params:xml:ns:yang:controller:config:groupbasedpolicy:gbp-ise-adapter:model";
+    prefix "gbp-ise-adapter-model";
+
+    import gbp-common { prefix gbp-common; revision-date 2014-04-21; }
+    import ietf-inet-types { prefix inet; revision-date 2010-09-24; }
+    import ietf-yang-types {prefix yang; revision-date "2010-09-24";}
+
+    description
+        "This module contains the YANG definitions for
+          gbp-ise-adapter implementation.";
+
+    revision "2016-06-30" {
+        description
+            "Initial revision.";
+    }
+
+    container gbp-ise-adapter {
+        description "root point for ise connection info and sgt harvest status";
+
+        container ise-harvest-config {
+            description "connection + credentials for ise-rest-api connection and target tennant";
+            config true;
+
+            leaf tenant {
+               type gbp-common:tenant-id;
+               mandatory true;
+               description
+                    "tenant for all extracted sgt";
+            }
+
+            container connection-config {
+                description "rest connection configuration part";
+
+                leaf ise-rest-url {
+                    description "base uri to ise-rest-api";
+                    mandatory true;
+                    type inet:uri;
+                }
+
+                leaf connection-timeout {
+                    description "connection timeout in milliseconds";
+                    type uint16;
+                    default 5000;
+                }
+
+                leaf read-timeout {
+                    description "read from rest timeout in milliseconds";
+                    type uint16;
+                    default 5000;
+                }
+
+                list header {
+                    description "request headers in form key+value";
+                    key name;
+
+                    leaf name {
+                        type string;
+                    }
+                    leaf value {
+                        type string;
+                    }
+                }
+            }
+        }
+
+        container ise-harvest-status {
+            description "result of sgt harvest from ise-rest-api and generating endpoint policy templates";
+            config false;
+
+            leaf success {
+                description "true if all operations succeeded";
+                type boolean;
+            }
+
+            leaf reason {
+                description "failure detail";
+                type string;
+            }
+
+            leaf templates-written {
+                description "amount of endpoint templates written";
+                type uint16;
+            }
+
+            leaf timestamp {
+                description "stamped upon sgts harvested and templates written";
+                type yang:date-and-time;
+            }
+        }
+    }
+}
diff --git a/groupbasedpolicy-ise-adapter/src/test/java/org/opendaylight/groupbasedpolicy/gbp_ise_adapter/impl/GbpIseAdapterProviderTest.java b/groupbasedpolicy-ise-adapter/src/test/java/org/opendaylight/groupbasedpolicy/gbp_ise_adapter/impl/GbpIseAdapterProviderTest.java
new file mode 100644 (file)
index 0000000..236195d
--- /dev/null
@@ -0,0 +1,75 @@
+package org.opendaylight.groupbasedpolicy.gbp_ise_adapter.impl;
+
+import static org.powermock.api.mockito.PowerMockito.verifyNew;
+import static org.powermock.api.mockito.PowerMockito.whenNew;
+
+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.md.sal.binding.api.DataTreeIdentifier;
+import org.opendaylight.controller.sal.binding.api.BindingAwareBroker;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.gbp.ise.adapter.model.rev160630.gbp.ise.adapter.IseHarvestConfig;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.powermock.core.classloader.annotations.PrepareForTest;
+import org.powermock.modules.junit4.PowerMockRunner;
+
+/**
+ * Purpose: cover {@link GbpIseAdapterProvider}
+ */
+@RunWith(PowerMockRunner.class)
+@PrepareForTest({GbpIseAdapterProvider.class})
+public class GbpIseAdapterProviderTest {
+
+    @Mock
+    private DataBroker dataBroker;
+    @Mock
+    private BindingAwareBroker broker;
+    @Mock
+    private BindingAwareBroker.ProviderContext providerContext;
+    @Mock
+    private ListenerRegistration<GbpIseConfigListener> registration;
+    @Mock
+    private SgtToEpgGeneratorImpl generator1;
+    @Mock
+    private SgtToEPTemplateGeneratorImpl generator2;
+    @Mock
+    private GbpIseSgtHarvesterImpl harvester;
+    @Mock
+    private GbpIseConfigListenerImpl listener;
+
+    private GbpIseAdapterProvider provider;
+
+    @Before
+    public void setUp() throws Exception {
+        provider = new GbpIseAdapterProvider(dataBroker, broker);
+        Mockito.verify(broker).registerProvider(provider);
+    }
+
+    @Test
+    public void testOnSessionInitiated() throws Exception {
+        Mockito.when(dataBroker.registerDataTreeChangeListener(
+                Matchers.<DataTreeIdentifier<IseHarvestConfig>>any(),
+                Matchers.<GbpIseConfigListener>any())).thenReturn(registration);
+
+        // prepare expectation for objects in onSessionInitiated (powerMock requirement for later checking)
+        whenNew(SgtToEpgGeneratorImpl.class).withAnyArguments().thenReturn(generator1);
+        whenNew(SgtToEPTemplateGeneratorImpl.class).withAnyArguments().thenReturn(generator2);
+        whenNew(GbpIseSgtHarvesterImpl.class).withArguments(generator1, generator2).thenReturn(harvester);
+        whenNew(GbpIseConfigListenerImpl.class).withAnyArguments().thenReturn(listener);
+        provider.onSessionInitiated(providerContext);
+
+        // check if all expected object got constructed and wired
+        verifyNew(SgtToEpgGeneratorImpl.class).withArguments(dataBroker);
+        verifyNew(SgtToEPTemplateGeneratorImpl.class).withArguments(dataBroker);
+        verifyNew(GbpIseSgtHarvesterImpl.class).withArguments(generator1, generator2);
+        verifyNew(GbpIseConfigListenerImpl.class).withArguments(dataBroker, harvester);
+
+        // close provider check
+        provider.close();
+        Mockito.verify(registration).close();
+    }
+}
\ No newline at end of file
diff --git a/groupbasedpolicy-ise-adapter/src/test/java/org/opendaylight/groupbasedpolicy/gbp_ise_adapter/impl/GbpIseConfigListenerImplTest.java b/groupbasedpolicy-ise-adapter/src/test/java/org/opendaylight/groupbasedpolicy/gbp_ise_adapter/impl/GbpIseConfigListenerImplTest.java
new file mode 100644 (file)
index 0000000..105c3cb
--- /dev/null
@@ -0,0 +1,113 @@
+/*
+ * 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.gbp_ise_adapter.impl;
+
+import com.google.common.util.concurrent.Futures;
+import java.util.Collections;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.InOrder;
+import org.mockito.Matchers;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.runners.MockitoJUnitRunner;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.DataObjectModification;
+import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.gbp.ise.adapter.model.rev160630.gbp.ise.adapter.IseHarvestConfig;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.gbp.ise.adapter.model.rev160630.gbp.ise.adapter.IseHarvestStatus;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+/**
+ * Test for {@link GbpIseConfigListenerImpl}.
+ */
+@RunWith(MockitoJUnitRunner.class)
+public class GbpIseConfigListenerImplTest {
+
+    @Mock
+    private DataBroker dataBroker;
+    @Mock
+    private GbpIseSgtHarvester harvester;
+    @Mock
+    private DataTreeModification<IseHarvestConfig> treeModification;
+    @Mock
+    private DataObjectModification<IseHarvestConfig> dataModification;
+    @Mock
+    private WriteTransaction wTx;
+    @Mock
+    private IseHarvestConfig config;
+
+    private GbpIseConfigListenerImpl listener;
+
+    @Before
+    public void setUp() throws Exception {
+        listener = new GbpIseConfigListenerImpl(dataBroker, harvester);
+    }
+
+    @Test
+    public void testOnDataTreeChanged_noop() throws Exception {
+        Mockito.when(dataModification.getDataAfter()).thenReturn(null);
+        Mockito.when(treeModification.getRootNode()).thenReturn(dataModification);
+
+        listener.onDataTreeChanged(Collections.singleton(treeModification));
+        Mockito.verifyNoMoreInteractions(harvester, dataBroker);
+    }
+
+    @Test
+    public void testOnDataTreeChanged_succeeded() throws Exception {
+        Mockito.when(dataModification.getDataAfter()).thenReturn(config);
+        Mockito.when(treeModification.getRootNode()).thenReturn(dataModification);
+
+        Mockito.when(harvester.harvest(config)).thenReturn(Futures.immediateFuture(42));
+
+        Mockito.when(wTx.submit()).thenReturn(Futures.immediateCheckedFuture(null));
+        Mockito.when(dataBroker.newWriteOnlyTransaction()).thenReturn(wTx);
+
+        listener.onDataTreeChanged(Collections.singleton(treeModification));
+        listener.close();
+
+        final InOrder inOrder = Mockito.inOrder(harvester, dataBroker, wTx);
+        inOrder.verify(harvester).harvest(config);
+        inOrder.verify(dataBroker).newWriteOnlyTransaction();
+        inOrder.verify(wTx).put(Matchers.eq(LogicalDatastoreType.OPERATIONAL),
+                Matchers.<InstanceIdentifier<IseHarvestStatus>>any(),
+                Matchers.<IseHarvestStatus>any(),
+                Matchers.eq(true));
+        inOrder.verify(wTx).submit();
+        inOrder.verifyNoMoreInteractions();
+    }
+
+    @Test
+    public void testOnDataTreeChanged_failed() throws Exception {
+        Mockito.when(dataModification.getDataAfter()).thenReturn(config);
+        Mockito.when(treeModification.getRootNode()).thenReturn(dataModification);
+
+        Mockito.when(harvester.harvest(config)).thenReturn(Futures.immediateFailedFuture(
+                new Exception("extremely poor harvest occurred")));
+
+        Mockito.when(wTx.submit()).thenReturn(Futures.immediateCheckedFuture(null));
+        Mockito.when(dataBroker.newWriteOnlyTransaction()).thenReturn(wTx);
+
+        listener.onDataTreeChanged(Collections.singleton(treeModification));
+        listener.close();
+
+        final InOrder inOrder = Mockito.inOrder(harvester, dataBroker, wTx);
+        inOrder.verify(harvester).harvest(config);
+        inOrder.verify(dataBroker).newWriteOnlyTransaction();
+        inOrder.verify(wTx).put(Matchers.eq(LogicalDatastoreType.OPERATIONAL),
+                Matchers.<InstanceIdentifier<IseHarvestStatus>>any(),
+                Matchers.<IseHarvestStatus>any(),
+                Matchers.eq(true));
+        inOrder.verify(wTx).submit();
+        inOrder.verifyNoMoreInteractions();
+    }
+}
\ No newline at end of file
diff --git a/groupbasedpolicy-ise-adapter/src/test/java/org/opendaylight/groupbasedpolicy/gbp_ise_adapter/impl/GbpIseSgtHarvesterImplTest.java b/groupbasedpolicy-ise-adapter/src/test/java/org/opendaylight/groupbasedpolicy/gbp_ise_adapter/impl/GbpIseSgtHarvesterImplTest.java
new file mode 100644 (file)
index 0000000..85212b6
--- /dev/null
@@ -0,0 +1,143 @@
+/*
+ * 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.gbp_ise_adapter.impl;
+
+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 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.Collections;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.InOrder;
+import org.mockito.Matchers;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.opendaylight.groupbasedpolicy.gbp_ise_adapter.impl.util.RestClientFactory;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.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.gbp.ise.adapter.model.rev160630.gbp.ise.adapter.IseHarvestConfig;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.gbp.ise.adapter.model.rev160630.gbp.ise.adapter.IseHarvestConfigBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.gbp.ise.adapter.model.rev160630.gbp.ise.adapter.ise.harvest.config.ConnectionConfigBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.gbp.ise.adapter.model.rev160630.gbp.ise.adapter.ise.harvest.config.connection.config.HeaderBuilder;
+import org.powermock.core.classloader.annotations.PrepareForTest;
+import org.powermock.modules.junit4.PowerMockRunner;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Test for {@link GbpIseSgtHarvesterImpl}.
+ */
+@RunWith(PowerMockRunner.class)
+@PrepareForTest({RestClientFactory.class})
+public class GbpIseSgtHarvesterImplTest {
+
+    private static final Logger LOG = LoggerFactory.getLogger(GbpIseSgtHarvesterImplTest.class);
+
+    public static final TenantId TENANT_ID = new TenantId("unit-tenant-id-1");
+    public static final Uri ISE_REST_URL = new Uri("https://example.org:9060");
+    public final String iseReplyAllSgts;
+    public final String iseReplySgtDetail;
+
+    @Mock
+    private SgtInfoProcessor processor;
+    @Mock
+    private Client client;
+    @Mock
+    private WebResource webResource;
+    @Mock
+    private WebResource.Builder builder;
+    @Mock
+    private ClientResponse response;
+
+    private IseHarvestConfig config;
+
+    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();
+    }
+
+    @Before
+    public void setUp() throws Exception {
+        config = new IseHarvestConfigBuilder()
+                .setTenant(TENANT_ID)
+                .setConnectionConfig(new ConnectionConfigBuilder()
+                        .setConnectionTimeout(10)
+                        .setReadTimeout(20)
+                        .setHeader(Collections.singletonList(new HeaderBuilder()
+                                .setName("hName")
+                                .setValue("hValue")
+                                .build()))
+                        .setIseRestUrl(ISE_REST_URL)
+                        .build())
+                .build();
+
+        harvester = new GbpIseSgtHarvesterImpl(processor);
+    }
+
+    @Test
+    public void testHarvest() throws Exception {
+        Mockito.when(response.getEntity(String.class)).thenReturn(iseReplyAllSgts, iseReplySgtDetail);
+        Mockito.when(builder.get(Matchers.<Class<ClientResponse>>any())).thenReturn(response);
+        Mockito.when(webResource.getRequestBuilder()).thenReturn(builder);
+        Mockito.when(webResource.path(Matchers.anyString())).thenReturn(webResource);
+        Mockito.when(client.resource(Matchers.<String>any())).thenReturn(webResource);
+        stub(method(RestClientFactory.class, "createIseClient")).toReturn(client);
+
+        Mockito.when(processor.processSgtInfo(Matchers.eq(TENANT_ID), Matchers.<List<SgtInfo>>any())).thenReturn(
+                Futures.immediateCheckedFuture(null));
+
+        final ListenableFuture<Integer> harvestResult = harvester.harvest(config);
+
+        final InOrder inOrder = Mockito.inOrder(client, webResource, builder);
+        inOrder.verify(client).resource(ISE_REST_URL.getValue());
+        // all sgts
+        inOrder.verify(webResource).path("/ers/config/sgt");
+        inOrder.verify(webResource).getRequestBuilder();
+        inOrder.verify(builder).header(Matchers.anyString(),Matchers.anyString());
+        inOrder.verify(builder).get(ClientResponse.class);
+        // sgt detail
+        inOrder.verify(webResource).path("/ers/config/sgt/abc123");
+        inOrder.verify(webResource).getRequestBuilder();
+        inOrder.verify(builder).header(Matchers.anyString(),Matchers.anyString());
+        inOrder.verify(builder).get(ClientResponse.class);
+        inOrder.verifyNoMoreInteractions();
+
+        final Integer count = harvestResult.get(2, TimeUnit.SECONDS);
+        Assert.assertEquals(1, count.intValue());
+    }
+}
\ No newline at end of file
diff --git a/groupbasedpolicy-ise-adapter/src/test/java/org/opendaylight/groupbasedpolicy/gbp_ise_adapter/impl/SgtToEPTemplateGeneratorImplTest.java b/groupbasedpolicy-ise-adapter/src/test/java/org/opendaylight/groupbasedpolicy/gbp_ise_adapter/impl/SgtToEPTemplateGeneratorImplTest.java
new file mode 100644 (file)
index 0000000..6f6f0bb
--- /dev/null
@@ -0,0 +1,100 @@
+/*
+ * 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.gbp_ise_adapter.impl;
+
+import com.google.common.collect.Lists;
+import com.google.common.util.concurrent.CheckedFuture;
+import com.google.common.util.concurrent.Futures;
+import java.util.Collections;
+import java.util.concurrent.TimeUnit;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.InOrder;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.runners.MockitoJUnitRunner;
+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;
+import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
+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.mapper.model.rev160302.SxpMapper;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.mapper.model.rev160302.sxp.mapper.EndpointPolicyTemplateBySgt;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.mapper.model.rev160302.sxp.mapper.EndpointPolicyTemplateBySgtBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.mapper.model.rev160302.sxp.mapper.EndpointPolicyTemplateBySgtKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.sxp.database.rev160308.Sgt;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
+
+/**
+ * Test for {@link SgtToEPTemplateGeneratorImpl}.
+ */
+@RunWith(MockitoJUnitRunner.class)
+public class SgtToEPTemplateGeneratorImplTest {
+
+    public static final TenantId TENANT_ID = new TenantId("tenant-unit-1");
+    public static final Sgt SGT_1 = new Sgt(1);
+    public static final String EPG_NAME_1 = "epg-unit-1";
+    public static final Sgt SGT_2 = new Sgt(2);
+    public static final String EPG_NAME_2 = "epg-unit-2";
+
+    @Mock
+    private DataBroker dataBroker;
+    @Mock
+    private WriteTransaction wTx;
+
+    private SgtToEPTemplateGeneratorImpl generator;
+
+    @Before
+    public void setUp() throws Exception {
+        Mockito.when(wTx.submit()).thenReturn(Futures.immediateCheckedFuture(null));
+        Mockito.when(dataBroker.newWriteOnlyTransaction()).thenReturn(wTx);
+        generator = new SgtToEPTemplateGeneratorImpl(dataBroker);
+    }
+
+    @Test
+    public void testProcessSgtInfo() throws Exception {
+        final SgtInfo sgtInfo1 = new SgtInfo(SGT_1, EPG_NAME_1);
+        final SgtInfo sgtInfo2 = new SgtInfo(SGT_2, EPG_NAME_2);
+
+        final CheckedFuture<Void, TransactionCommitFailedException> outcome =
+                generator.processSgtInfo(TENANT_ID, Lists.newArrayList(sgtInfo1, sgtInfo2));
+
+        outcome.get(10, TimeUnit.SECONDS);
+
+        final KeyedInstanceIdentifier<EndpointPolicyTemplateBySgt, EndpointPolicyTemplateBySgtKey> epTemplatePath1 =
+                InstanceIdentifier.create(SxpMapper.class)
+                        .child(EndpointPolicyTemplateBySgt.class, new EndpointPolicyTemplateBySgtKey(SGT_1));
+        final EndpointPolicyTemplateBySgt epTemplate1 = new EndpointPolicyTemplateBySgtBuilder()
+                .setSgt(SGT_1)
+                .setEndpointGroups(Collections.singletonList(new EndpointGroupId(EPG_NAME_1)))
+                .setTenant(TENANT_ID)
+                .build();
+
+        final KeyedInstanceIdentifier<EndpointPolicyTemplateBySgt, EndpointPolicyTemplateBySgtKey> epTemplatePath2 =
+                InstanceIdentifier.create(SxpMapper.class)
+                        .child(EndpointPolicyTemplateBySgt.class, new EndpointPolicyTemplateBySgtKey(SGT_2));
+        final EndpointPolicyTemplateBySgt epTemplate2 = new EndpointPolicyTemplateBySgtBuilder()
+                .setSgt(SGT_2)
+                .setEndpointGroups(Collections.singletonList(new EndpointGroupId(EPG_NAME_2)))
+                .setTenant(TENANT_ID)
+                .build();
+
+
+        final InOrder inOrder = Mockito.inOrder(wTx);
+        inOrder.verify(wTx, Mockito.calls(1)).put(LogicalDatastoreType.CONFIGURATION, epTemplatePath1, epTemplate1, true);
+        inOrder.verify(wTx, Mockito.calls(1)).put(LogicalDatastoreType.CONFIGURATION, epTemplatePath2, epTemplate2, false);
+        inOrder.verify(wTx).submit();
+
+        Mockito.verifyZeroInteractions(wTx);
+
+    }
+}
\ No newline at end of file
diff --git a/groupbasedpolicy-ise-adapter/src/test/java/org/opendaylight/groupbasedpolicy/gbp_ise_adapter/impl/SgtToEpgGeneratorImplTest.java b/groupbasedpolicy-ise-adapter/src/test/java/org/opendaylight/groupbasedpolicy/gbp_ise_adapter/impl/SgtToEpgGeneratorImplTest.java
new file mode 100644 (file)
index 0000000..415e35f
--- /dev/null
@@ -0,0 +1,96 @@
+/*
+ * 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.gbp_ise_adapter.impl;
+
+import com.google.common.collect.Lists;
+import com.google.common.util.concurrent.CheckedFuture;
+import com.google.common.util.concurrent.Futures;
+import java.util.concurrent.TimeUnit;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.InOrder;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.runners.MockitoJUnitRunner;
+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;
+import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
+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;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.Name;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.TenantId;
+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.sxp.database.rev160308.Sgt;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+/**
+ * Test for {@link SgtToEpgGeneratorImpl}.
+ */
+@RunWith(MockitoJUnitRunner.class)
+public class SgtToEpgGeneratorImplTest {
+
+    public static final TenantId TENANT_ID = new TenantId("tenant-unit-1");
+    public static final Sgt SGT_1 = new Sgt(1);
+    public static final String EPG_NAME_1 = "epg-unit-1";
+    public static final Sgt SGT_2 = new Sgt(2);
+    public static final String EPG_NAME_2 = "epg-unit-2";
+
+    @Mock
+    private DataBroker dataBroker;
+    @Mock
+    private WriteTransaction wTx;
+
+    private SgtToEpgGeneratorImpl generator;
+
+    @Before
+    public void setUp() throws Exception {
+        Mockito.when(wTx.submit()).thenReturn(Futures.immediateCheckedFuture(null));
+        Mockito.when(dataBroker.newWriteOnlyTransaction()).thenReturn(wTx);
+        generator = new SgtToEpgGeneratorImpl(dataBroker);
+    }
+
+    @Test
+    public void testProcessSgtInfo() throws Exception {
+        final SgtInfo sgtInfo1 = new SgtInfo(SGT_1, EPG_NAME_1);
+        final SgtInfo sgtInfo2 = new SgtInfo(SGT_2, EPG_NAME_2);
+
+        final CheckedFuture<Void, TransactionCommitFailedException> outcome =
+                generator.processSgtInfo(TENANT_ID, Lists.newArrayList(sgtInfo1, sgtInfo2));
+
+        outcome.get(10, TimeUnit.SECONDS);
+
+        final EndpointGroupId epgId1 = new EndpointGroupId(EPG_NAME_1);
+        final InstanceIdentifier<EndpointGroup> epgPath1 = IidFactory.endpointGroupIid(TENANT_ID, epgId1);
+        final EndpointGroup epg1 = createEpg(epgId1, SGT_1.getValue());
+
+        final EndpointGroupId epgId2 = new EndpointGroupId(EPG_NAME_2);
+        final InstanceIdentifier<EndpointGroup> epgPath2 = IidFactory.endpointGroupIid(TENANT_ID, epgId2);
+        final EndpointGroup epg2 = createEpg(epgId2, SGT_2.getValue());
+
+        final InOrder inOrder = Mockito.inOrder(wTx);
+        inOrder.verify(wTx, Mockito.calls(1)).put(LogicalDatastoreType.CONFIGURATION, epgPath1, epg1, true);
+        inOrder.verify(wTx, Mockito.calls(1)).put(LogicalDatastoreType.CONFIGURATION, epgPath2, epg2, false);
+        inOrder.verify(wTx).submit();
+
+        Mockito.verifyZeroInteractions(wTx);
+    }
+
+    private EndpointGroup createEpg(final EndpointGroupId epgId1, final int sgt) {
+        final String epgIdValue = epgId1.getValue();
+        return new EndpointGroupBuilder()
+                .setId(epgId1)
+                .setName(new Name(epgIdValue + "--"+sgt))
+                .setDescription(new Description("imported from ISE for sgt="+sgt))
+                .build();
+    }
+}
\ No newline at end of file
diff --git a/groupbasedpolicy-ise-adapter/src/test/java/org/opendaylight/groupbasedpolicy/gbp_ise_adapter/impl/util/RestClientFactoryTest.java b/groupbasedpolicy-ise-adapter/src/test/java/org/opendaylight/groupbasedpolicy/gbp_ise_adapter/impl/util/RestClientFactoryTest.java
new file mode 100644 (file)
index 0000000..3a2d69a
--- /dev/null
@@ -0,0 +1,42 @@
+package org.opendaylight.groupbasedpolicy.gbp_ise_adapter.impl.util;
+
+import com.sun.jersey.api.client.Client;
+import com.sun.jersey.client.urlconnection.HTTPSProperties;
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.runners.MockitoJUnitRunner;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.gbp.ise.adapter.model.rev160630.gbp.ise.adapter.ise.harvest.config.ConnectionConfig;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.gbp.ise.adapter.model.rev160630.gbp.ise.adapter.ise.harvest.config.ConnectionConfigBuilder;
+
+import javax.net.ssl.SSLSession;
+import java.util.Map;
+
+/**
+ * Purpose: cover {@link RestClientFactory}
+ */
+@RunWith(MockitoJUnitRunner.class)
+public class RestClientFactoryTest {
+
+    @Mock
+    private SSLSession sslSession;
+
+    @Test
+    public void testCreateIseClient() throws Exception {
+        ConnectionConfig connectionConfig = new ConnectionConfigBuilder()
+                .setConnectionTimeout(1)
+                .setReadTimeout(2)
+                .build();
+
+        final Client iseClient = RestClientFactory.createIseClient(connectionConfig);
+        final Map<String, Object> properties = iseClient.getProperties();
+        Assert.assertEquals(3, properties.size());
+        Assert.assertEquals(1, properties.get("com.sun.jersey.client.property.connectTimeout"));
+        Assert.assertEquals(2, properties.get("com.sun.jersey.client.property.readTimeout"));
+
+        Assert.assertTrue(properties.get(HTTPSProperties.PROPERTY_HTTPS_PROPERTIES) instanceof HTTPSProperties);
+        final HTTPSProperties httpsProperties = (HTTPSProperties) properties.get(HTTPSProperties.PROPERTY_HTTPS_PROPERTIES);
+        Assert.assertTrue(httpsProperties.getHostnameVerifier().verify("xxx", sslSession));
+    }
+}
\ No newline at end of file
diff --git a/groupbasedpolicy-ise-adapter/src/test/resources/log4j.xml b/groupbasedpolicy-ise-adapter/src/test/resources/log4j.xml
new file mode 100644 (file)
index 0000000..3dee945
--- /dev/null
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<!--\r
+  ~ Copyright (c) 2016 Cisco Systems, Inc. and others.  All rights reserved.\r
+  ~\r
+  ~ This program and the accompanying materials are made available under the\r
+  ~ terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+  ~ and is available at http://www.eclipse.org/legal/epl-v10.html\r
+  -->\r
+\r
+<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">\r
+<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">\r
+\r
+    <appender name="console" class="org.apache.log4j.ConsoleAppender">\r
+        <layout class="org.apache.log4j.PatternLayout">\r
+            <param name="ConversionPattern" value="%-6p %d{HH:mm:ss.SSS} [%10.10t] %30.30c %x - %m%n"/>\r
+        </layout>\r
+        <!--         <param name="Threshold" value="DEBUG" /> -->\r
+    </appender>\r
+\r
+    <logger name="org.opendaylight.groupbasedpolicy.gbp_ise_adapter.impl" additivity="false">\r
+        <level value="TRACE"/>\r
+        <appender-ref ref="console"/>\r
+    </logger>\r
+\r
+    <root>\r
+        <priority value="INFO"/>\r
+        <appender-ref ref="console"/>\r
+    </root>\r
+</log4j:configuration>\r
diff --git a/groupbasedpolicy-ise-adapter/src/test/resources/org/opendaylight/groupbasedpolicy/gbp_ise_adapter/impl/rawIse-allSgts.xml b/groupbasedpolicy-ise-adapter/src/test/resources/org/opendaylight/groupbasedpolicy/gbp_ise_adapter/impl/rawIse-allSgts.xml
new file mode 100644 (file)
index 0000000..c5dc929
--- /dev/null
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<!--
+  ~ 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
+  -->
+
+<ns3:searchResult xmlns:ns5="ers.ise.cisco.com"
+                  xmlns:ns3="v2.ers.ise.cisco.com"
+                  total="1">
+    <ns3:nextPage rel="next" href="" type="application/xml"/>
+    <ns3:resources>
+        <ns5:resource description="" id="abc123" name="boss_group">
+            <link rel="self" href="https://example.org:9060/ers/config/sgt/abc123" type="application/xml"/>
+        </ns5:resource>
+    </ns3:resources>
+</ns3:searchResult>
diff --git a/groupbasedpolicy-ise-adapter/src/test/resources/org/opendaylight/groupbasedpolicy/gbp_ise_adapter/impl/rawIse-sgtDetail.xml b/groupbasedpolicy-ise-adapter/src/test/resources/org/opendaylight/groupbasedpolicy/gbp_ise_adapter/impl/rawIse-sgtDetail.xml
new file mode 100644 (file)
index 0000000..7d3b880
--- /dev/null
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<!--
+  ~ 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
+  -->
+
+<ns4:sgt xmlns:ers="ers.ise.cisco.com"
+         xmlns:xs="http://www.w3.org/2001/XMLSchema"
+         xmlns:ns4="trustsec.ers.ise.cisco.com"
+         description=""
+         id="abc123"
+         name="boss-group">
+    <link rel="self" href="https://example.com:9060/ers/config/sgt/abc123" type="application/xml"/>
+    <generationId>0</generationId>
+    <value>42</value>
+</ns4:sgt>
diff --git a/pom.xml b/pom.xml
index ba05e3a48344d403b6649fb115a5d3c80da6c10c..90e1c4fd0671d70ba8b3b8d30c589ef15b81c15c 100644 (file)
--- a/pom.xml
+++ b/pom.xml
@@ -35,6 +35,7 @@
     <module>distribution-karaf</module>
     <module>features</module>
     <module>sxp-mapper</module>
+    <module>groupbasedpolicy-ise-adapter</module>
   </modules>
 
   <build>