changeset 2717:08b2cadf2d42

add host-network backend, get rid of system-backend This patch creates a new backend plugin from the ashes of system-backend. The new backend will submit a list of network interfaces to the gateway, at startup, and whenever the list changes (which could happen due to DHCP renewal, or a USB Ethernet port being plugged in, for example). The old method resulted in about 30 reads and 30 writes; this method is simpler and results in one PST to the gateway. Reviewed-by: jkang Review-thread: http://icedtea.classpath.org/pipermail/thermostat/2017-June/023920.html Review-thread: http://icedtea.classpath.org/pipermail/thermostat/2017-July/023987.html
author Simon Tooke <stooke@redhat.com>
date Thu, 06 Jul 2017 13:05:47 -0400
parents cc297a1bf67f
children 084cba24ae87
files agent/core/src/main/java/com/redhat/thermostat/agent/http/HttpRequestService.java distribution/assembly/core-assembly-macosx.xml distribution/assembly/core-assembly-windows.xml distribution/assembly/core-assembly.xml distribution/assembly/plugin-assembly.xml distribution/config/commands/agent.properties distribution/pom.xml plugins/host-network/agent/pom.xml plugins/host-network/agent/src/main/java/com/redhat/thermostat/host/network/internal/HostNetworkBackend.java plugins/host-network/agent/src/main/java/com/redhat/thermostat/host/network/internal/NetworkInfoBuilder.java plugins/host-network/agent/src/main/java/com/redhat/thermostat/host/network/internal/NetworkInfoListDAO.java plugins/host-network/agent/src/main/java/com/redhat/thermostat/host/network/internal/NetworkInfoListDAOImpl.java plugins/host-network/agent/src/main/java/com/redhat/thermostat/host/network/model/NetworkInfoList.java plugins/host-network/agent/src/main/java/com/redhat/thermostat/host/network/model/NetworkInfoListTypeAdapter.java plugins/host-network/agent/src/main/java/com/redhat/thermostat/host/network/model/NetworkInterfaceInfo.java plugins/host-network/agent/src/main/java/com/redhat/thermostat/host/network/model/NetworkInterfaceInfoTypeAdapter.java plugins/host-network/agent/src/test/java/com/redhat/thermostat/host/network/internal/HostNetworkBackendTest.java plugins/host-network/agent/src/test/java/com/redhat/thermostat/host/network/internal/NetworkInfoBuilderTest.java plugins/host-network/agent/src/test/java/com/redhat/thermostat/host/network/internal/NetworkInfoListDAOTest.java plugins/host-network/agent/src/test/java/com/redhat/thermostat/host/network/model/NetworkInfoListTest.java plugins/host-network/agent/src/test/java/com/redhat/thermostat/host/network/model/NetworkInfoListTypeAdapterTest.java plugins/host-network/agent/src/test/java/com/redhat/thermostat/host/network/model/NetworkInterfaceInfoTest.java plugins/host-network/agent/src/test/java/com/redhat/thermostat/host/network/model/NetworkInterfaceInfoTypeAdapterTest.java plugins/host-network/distribution/assemblies/plugin-assembly.xml plugins/host-network/distribution/configFiles/gateway.properties plugins/host-network/distribution/pom.xml plugins/host-network/distribution/thermostat-plugin.xml plugins/host-network/pom.xml plugins/pom.xml pom.xml storage/core/src/main/java/com/redhat/thermostat/storage/dao/NetworkInterfaceInfoDAO.java storage/core/src/main/java/com/redhat/thermostat/storage/internal/Activator.java storage/core/src/main/java/com/redhat/thermostat/storage/internal/dao/NetworkInterfaceInfoDAOImpl.java storage/core/src/main/java/com/redhat/thermostat/storage/internal/dao/NetworkInterfaceInfoTypeAdapter.java storage/core/src/main/java/com/redhat/thermostat/storage/model/NetworkInterfaceInfo.java storage/core/src/test/java/com/redhat/thermostat/storage/internal/ActivatorTest.java storage/core/src/test/java/com/redhat/thermostat/storage/internal/dao/NetworkInterfaceInfoDAOTest.java storage/core/src/test/java/com/redhat/thermostat/storage/internal/dao/NetworkInterfaceInfoTypeAdapterTest.java storage/core/src/test/java/com/redhat/thermostat/storage/model/NetworkInterfaceInfoTest.java storage/core/src/test/java/com/redhat/thermostat/storage/model/PojoModelInstantiationTest.java system-backend/pom.xml system-backend/src/main/java/com/redhat/thermostat/backend/system/internal/NetworkInfoBuilder.java system-backend/src/main/java/com/redhat/thermostat/backend/system/internal/SystemBackend.java system-backend/src/main/java/com/redhat/thermostat/backend/system/internal/SystemBackendActivator.java system-backend/src/test/java/com/redhat/thermostat/backend/system/internal/NetworkInfoBuilderTest.java system-backend/src/test/java/com/redhat/thermostat/backend/system/internal/SystemBackendTest.java
diffstat 46 files changed, 2225 insertions(+), 1797 deletions(-) [+]
line wrap: on
line diff
--- a/agent/core/src/main/java/com/redhat/thermostat/agent/http/HttpRequestService.java	Wed Jul 05 14:29:14 2017 -0400
+++ b/agent/core/src/main/java/com/redhat/thermostat/agent/http/HttpRequestService.java	Thu Jul 06 13:05:47 2017 -0400
@@ -121,6 +121,7 @@
      * @return The returned body for GET requests. {@code null} otherwise.
      */
     public String sendHttpRequest(String jsonPayload, String url, String requestType) throws RequestFailedException {
+        // TODO: refactor agent pass around HttpMethod enum instead of string - it's faster and takes less space.
         HttpMethod requestMethod = HttpMethod.valueOf(requestType);
         Request request = client.newRequest(url);
         if (jsonPayload != null) {
--- a/distribution/assembly/core-assembly-macosx.xml	Wed Jul 05 14:29:14 2017 -0400
+++ b/distribution/assembly/core-assembly-macosx.xml	Thu Jul 06 13:05:47 2017 -0400
@@ -65,7 +65,6 @@
         <include>com.redhat.thermostat:thermostat-common-portability</include>
         <include>com.redhat.thermostat:thermostat-process-handler</include>
         <include>com.redhat.thermostat:thermostat-storage-core</include>
-        <include>com.redhat.thermostat:thermostat-system-backend</include>
         <include>org.osgi:org.osgi.compendium</include>
         <include>org.apache:org.apache.felix.scr</include>
         <include>commons-codec:commons-codec</include>
--- a/distribution/assembly/core-assembly-windows.xml	Wed Jul 05 14:29:14 2017 -0400
+++ b/distribution/assembly/core-assembly-windows.xml	Thu Jul 06 13:05:47 2017 -0400
@@ -65,7 +65,6 @@
         <include>com.redhat.thermostat:thermostat-common-portability</include>
         <include>com.redhat.thermostat:thermostat-process-handler</include>
         <include>com.redhat.thermostat:thermostat-storage-core</include>
-        <include>com.redhat.thermostat:thermostat-system-backend</include>
         <include>org.osgi:org.osgi.compendium</include>
         <include>org.apache:org.apache.felix.scr</include>
         <include>commons-codec:commons-codec</include>
--- a/distribution/assembly/core-assembly.xml	Wed Jul 05 14:29:14 2017 -0400
+++ b/distribution/assembly/core-assembly.xml	Thu Jul 06 13:05:47 2017 -0400
@@ -63,7 +63,6 @@
         <include>com.redhat.thermostat:thermostat-common-portability</include>
         <include>com.redhat.thermostat:thermostat-process-handler</include>
         <include>com.redhat.thermostat:thermostat-storage-core</include>
-        <include>com.redhat.thermostat:thermostat-system-backend</include>
         <include>org.osgi:org.osgi.compendium</include>
         <include>org.apache:org.apache.felix.scr</include>
         <include>commons-codec:commons-codec</include>
--- a/distribution/assembly/plugin-assembly.xml	Wed Jul 05 14:29:14 2017 -0400
+++ b/distribution/assembly/plugin-assembly.xml	Thu Jul 06 13:05:47 2017 -0400
@@ -52,6 +52,7 @@
         <include>com.redhat.thermostat:thermostat-host-overview-distribution</include>
         <include>com.redhat.thermostat:thermostat-host-cpu-distribution</include>
         <include>com.redhat.thermostat:thermostat-host-memory-distribution</include>
+        <include>com.redhat.thermostat:thermostat-host-network-distribution</include>
         <include>com.redhat.thermostat:thermostat-jvm-overview-distribution</include>
         <include>com.redhat.thermostat:thermostat-vm-gc-distribution</include>
         <include>com.redhat.thermostat:thermostat-vm-memory-distribution</include>
--- a/distribution/config/commands/agent.properties	Wed Jul 05 14:29:14 2017 -0400
+++ b/distribution/config/commands/agent.properties	Thu Jul 06 13:05:47 2017 -0400
@@ -1,5 +1,4 @@
 bundles = com.redhat.thermostat.agent.cli=@project.version@, \
-          com.redhat.thermostat.backend.system=@project.version@, \
           com.redhat.thermostat.agent.ipc.tcpsocket.server=@project.version@, \
           com.redhat.thermostat.process=@project.version@ \
           @agent_extra_bundles@
--- a/distribution/pom.xml	Wed Jul 05 14:29:14 2017 -0400
+++ b/distribution/pom.xml	Thu Jul 06 13:05:47 2017 -0400
@@ -466,11 +466,6 @@
         <artifactId>thermostat-process-handler</artifactId>
         <version>${project.version}</version>
     </dependency>
-    <dependency>
-        <groupId>com.redhat.thermostat</groupId>
-        <artifactId>thermostat-system-backend</artifactId>
-        <version>${project.version}</version>
-    </dependency>
 
     <!-- Plugins -->
 
@@ -496,6 +491,12 @@
     </dependency>
     <dependency>
       <groupId>com.redhat.thermostat</groupId>
+      <artifactId>thermostat-host-network-distribution</artifactId>
+      <version>${project.version}</version>
+      <type>zip</type>
+    </dependency>
+    <dependency>
+      <groupId>com.redhat.thermostat</groupId>
       <artifactId>thermostat-jvm-overview-distribution</artifactId>
       <version>${project.version}</version>
       <type>zip</type>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/host-network/agent/pom.xml	Thu Jul 06 13:05:47 2017 -0400
@@ -0,0 +1,208 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ Copyright 2012-2017 Red Hat, Inc.
+
+ This file is part of Thermostat.
+
+ Thermostat is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 2, or (at your
+ option) any later version.
+
+ Thermostat is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with Thermostat; see the file COPYING.  If not see
+ <http://www.gnu.org/licenses/>.
+
+ Linking this code with other modules is making a combined work
+ based on this code.  Thus, the terms and conditions of the GNU
+ General Public License cover the whole combination.
+
+ As a special exception, the copyright holders of this code give
+ you permission to link this code with independent modules to
+ produce an executable, regardless of the license terms of these
+ independent modules, and to copy and distribute the resulting
+ executable under terms of your choice, provided that you also
+ meet, for each linked independent module, the terms and conditions
+ of the license of that module.  An independent module is a module
+ which is not derived from or based on this code.  If you modify
+ this code, you may extend this exception to your version of the
+ library, but you are not obligated to do so.  If you do not wish
+ to do so, delete this exception statement from your version.
+
+-->
+<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>
+    <artifactId>thermostat-host-network</artifactId>
+    <groupId>com.redhat.thermostat</groupId>
+    <version>1.99.12-SNAPSHOT</version>
+  </parent>
+
+  <artifactId>thermostat-host-network-agent</artifactId>
+  <packaging>bundle</packaging>
+
+  <name>Thermostat Host Network Agent plugin</name>
+
+  <build>
+
+    <resources>
+      <resource>
+        <directory>src/main/resources</directory>
+        <filtering>true</filtering>
+        <excludes>
+          <exclude>**/*.png</exclude>
+        </excludes>
+      </resource>
+      <resource>
+        <directory>src/main/resources</directory>
+        <filtering>false</filtering>
+        <includes>
+          <include>**/*.png</include>
+        </includes>
+      </resource>
+    </resources>
+
+    <plugins>
+      <plugin>
+        <groupId>org.apache.felix</groupId>
+        <artifactId>maven-bundle-plugin</artifactId>
+        <extensions>true</extensions>
+        <configuration>
+          <instructions>
+            <Bundle-Vendor>Red Hat, Inc.</Bundle-Vendor>
+            <Bundle-SymbolicName>com.redhat.thermostat.host.network.agent</Bundle-SymbolicName>
+            <Export-Package>
+                com.redhat.thermostat.host.network.model
+            </Export-Package>
+            <Private-Package>
+              com.redhat.thermostat.host.network.internal
+            </Private-Package>
+            <!-- Do not autogenerate uses clauses in Manifests -->
+            <_nouses>true</_nouses>
+          </instructions>
+        </configuration>
+      </plugin>
+
+      <plugin>
+        <groupId>org.apache.felix</groupId>
+        <artifactId>maven-scr-plugin</artifactId>
+        <executions>
+          <execution>
+            <id>generate-scr-scrdescriptor</id>
+            <goals>
+              <goal>scr</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-resources-plugin</artifactId>
+        <executions>
+          <execution>
+            <id>copy</id>
+            <phase>generate-resources</phase>
+            <goals>
+              <goal>copy-resources</goal>
+            </goals>
+            <configuration>
+              <overwrite>true</overwrite>
+              <outputDirectory>${project.build.directory}</outputDirectory>
+              <resources>
+                <resource>
+                  <directory>../../../common/portability/target</directory>
+                  <includes>
+                    <include>${sharedlib.prefix}thermostat-common-portability${sharedlib.suffix}</include>
+                  </includes>
+                </resource>
+              </resources>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-surefire-plugin</artifactId>
+        <configuration>
+          <!-- the test needs to link to common-portability native libraries -->
+          <systemPropertyVariables>
+            <com.redhat.thermostat.shared.loader.testNativesHome>${project.build.directory}</com.redhat.thermostat.shared.loader.testNativesHome>
+          </systemPropertyVariables>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+
+  <dependencies>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.mockito</groupId>
+      <artifactId>mockito-core</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.osgi</groupId>
+      <artifactId>org.osgi.core</artifactId>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.osgi</groupId>
+      <artifactId>org.osgi.compendium</artifactId>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
+      <groupId>com.redhat.thermostat</groupId>
+      <artifactId>thermostat-common-core</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>com.redhat.thermostat</groupId>
+      <artifactId>thermostat-common-plugin</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>com.redhat.thermostat</groupId>
+      <artifactId>thermostat-common-portability</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>com.redhat.thermostat</groupId>
+      <artifactId>thermostat-agent-core</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>com.redhat.thermostat</groupId>
+      <artifactId>thermostat-storage-core</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>com.redhat.thermostat</groupId>
+      <artifactId>thermostat-common-test</artifactId>
+      <version>${project.version}</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>com.google.code.gson</groupId>
+      <artifactId>gson</artifactId>
+      <version>${gson.version}</version>
+    </dependency>
+    <!-- declarative services -->
+    <dependency>
+      <groupId>org.apache.felix</groupId>
+      <artifactId>org.apache.felix.scr.annotations</artifactId>
+    </dependency>
+  </dependencies>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/host-network/agent/src/main/java/com/redhat/thermostat/host/network/internal/HostNetworkBackend.java	Thu Jul 06 13:05:47 2017 -0400
@@ -0,0 +1,135 @@
+/*
+ * Copyright 2012-2017 Red Hat, Inc.
+ *
+ * This file is part of Thermostat.
+ *
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.host.network.internal;
+
+import java.util.List;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+
+import com.redhat.thermostat.backend.Backend;
+import com.redhat.thermostat.backend.HostPollingAction;
+import com.redhat.thermostat.backend.HostPollingBackend;
+import com.redhat.thermostat.common.Version;
+import com.redhat.thermostat.common.Clock;
+import com.redhat.thermostat.common.SystemClock;
+import com.redhat.thermostat.host.network.model.NetworkInfoList;
+import com.redhat.thermostat.host.network.model.NetworkInterfaceInfo;
+import com.redhat.thermostat.storage.core.WriterID;
+
+import org.apache.felix.scr.annotations.Activate;
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Deactivate;
+import org.apache.felix.scr.annotations.Reference;
+import org.apache.felix.scr.annotations.Service;
+import org.osgi.framework.BundleContext;
+
+@Component
+@Service(value = Backend.class)
+public class HostNetworkBackend extends HostPollingBackend {
+
+    private final long procCheckInterval = 1000; // TODO make this configurable.
+    private final Clock clock;
+
+    @Reference
+    private NetworkInfoListDAO networkInterfaceInfoDAO;
+
+    @Reference
+    private WriterID writerID;
+
+    public HostNetworkBackend() {
+        this(Executors.newSingleThreadScheduledExecutor());
+    }
+
+    private HostNetworkBackend(ScheduledExecutorService executor) {
+        this("Host Network Backend",
+                "Gathers network interface information from the system",
+                "Red Hat, Inc.", new Version(), executor);
+    }
+
+    HostNetworkBackend(String name, String descr, String vendor, Version version, ScheduledExecutorService executor) {
+        super(name, descr, vendor, version, executor);
+        this.clock = new SystemClock();
+    }
+
+    @Activate
+    public void componentActivated(BundleContext context) {
+        Version version = new Version(context.getBundle());
+        setVersion(version.getVersionNumber());
+        registerAction(new BackendAction(writerID, clock, networkInterfaceInfoDAO));
+    }
+
+    @Deactivate
+    protected void componentDeactivated() {
+        if (isActive()) {
+            deactivate();
+        }
+    }
+
+    private static class BackendAction implements HostPollingAction {
+
+        private final NetworkInfoBuilder builder;
+        private final NetworkInfoListDAO dao;
+        private WriterID writerID;
+        private Clock clock;
+        private int oldHash = 0;
+
+        BackendAction(WriterID writerID, Clock clock, NetworkInfoListDAO dao) {
+            builder = new NetworkInfoBuilder();
+            this.writerID = writerID;
+            this.clock = clock;
+            this.dao = dao;
+        }
+
+        @Override
+        public void run() {
+            final List<NetworkInterfaceInfo> ifaceList = builder.build();
+            int hash = ifaceList.hashCode();
+            if (hash != oldHash) {
+                NetworkInfoList obj = new NetworkInfoList(writerID.getWriterID(), clock.getRealTimeMillis(), ifaceList);
+                dao.put(obj);
+                oldHash = hash;
+            }
+        }
+
+    }
+
+    @Override
+    public int getOrderValue() {
+        return ORDER_DEFAULT_GROUP;
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/host-network/agent/src/main/java/com/redhat/thermostat/host/network/internal/NetworkInfoBuilder.java	Thu Jul 06 13:05:47 2017 -0400
@@ -0,0 +1,93 @@
+/*
+ * Copyright 2012-2017 Red Hat, Inc.
+ *
+ * This file is part of Thermostat.
+ *
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.host.network.internal;
+
+import java.net.Inet4Address;
+import java.net.Inet6Address;
+import java.net.InetAddress;
+import java.net.NetworkInterface;
+import java.net.SocketException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.List;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import com.redhat.thermostat.common.utils.LoggingUtils;
+import com.redhat.thermostat.host.network.model.NetworkInterfaceInfo;
+
+class NetworkInfoBuilder {
+
+    private static final Logger logger = LoggingUtils.getLogger(NetworkInfoBuilder.class);
+
+    private void addInterfaces(List<NetworkInterfaceInfo> infos, List<NetworkInterface> ifaceList, boolean addAll, boolean addUnconnected) {
+        for (NetworkInterface iface : ifaceList) {
+            NetworkInterfaceInfo info = new NetworkInterfaceInfo(iface.getName());
+            List<InetAddress> addrList = Collections.list(iface.getInetAddresses());
+            final boolean want = addAll || (addrList.isEmpty() == addUnconnected);
+            for (InetAddress addr : addrList) {
+                if (addr instanceof Inet4Address) {
+                    info.setIp4Addr(addr.getHostAddress());
+                } else if (addr instanceof Inet6Address) {
+                    info.setIp6Addr(addr.getHostAddress());
+                }
+            }
+            if (want) {
+                info.setDisplayName(iface.getDisplayName());
+                infos.add(info);
+            }
+        }
+    }
+
+    List<NetworkInterfaceInfo> build() {
+        final List<NetworkInterfaceInfo> infos = new ArrayList<>();
+        try {
+            final Enumeration<NetworkInterface> ifaces = NetworkInterface.getNetworkInterfaces();
+            final List<NetworkInterface> ifaceList = Collections.list(ifaces);
+            // list connected interfaces first (there is a lot of noise on windows)
+            addInterfaces(infos, ifaceList, false, false);
+            addInterfaces(infos, ifaceList, false, true);
+
+        } catch (SocketException e) {
+            logger.log(Level.WARNING, "error enumerating network interfaces");
+        }
+        return infos;
+    }
+
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/host-network/agent/src/main/java/com/redhat/thermostat/host/network/internal/NetworkInfoListDAO.java	Thu Jul 06 13:05:47 2017 -0400
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2012-2017 Red Hat, Inc.
+ *
+ * This file is part of Thermostat.
+ *
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.host.network.internal;
+
+import com.redhat.thermostat.annotations.Service;
+import com.redhat.thermostat.host.network.model.NetworkInfoList;
+
+@Service
+public interface NetworkInfoListDAO {
+
+    void put(NetworkInfoList infolist);
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/host-network/agent/src/main/java/com/redhat/thermostat/host/network/internal/NetworkInfoListDAOImpl.java	Thu Jul 06 13:05:47 2017 -0400
@@ -0,0 +1,153 @@
+/*
+ * Copyright 2012-2017 Red Hat, Inc.
+ *
+ * This file is part of Thermostat.
+ *
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.host.network.internal;
+
+import java.io.IOException;
+import java.util.logging.Logger;
+
+import com.redhat.thermostat.agent.http.HttpRequestService;
+import com.redhat.thermostat.common.config.experimental.ConfigurationInfoSource;
+import com.redhat.thermostat.common.plugin.PluginConfiguration;
+import com.redhat.thermostat.common.plugin.PluginDAOBase;
+import com.redhat.thermostat.common.plugin.SystemID;
+import com.redhat.thermostat.host.network.model.NetworkInfoList;
+import com.redhat.thermostat.host.network.model.NetworkInfoListTypeAdapter;
+
+import org.apache.felix.scr.annotations.Activate;
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Reference;
+import org.apache.felix.scr.annotations.Service;
+
+import com.redhat.thermostat.common.utils.LoggingUtils;
+
+@Component
+@Service(value = NetworkInfoListDAO.class)
+public class NetworkInfoListDAOImpl extends PluginDAOBase<NetworkInfoList, NetworkInfoListDAOImpl> implements NetworkInfoListDAO {
+
+    private static final Logger logger = LoggingUtils.getLogger(NetworkInfoListDAOImpl.class);
+
+    static final String PLUGIN_ID = "host-network";
+
+    private final ConfigurationCreator configCreator;
+    private PluginConfiguration config;
+
+    private final JsonHelper jsonHelper;
+
+    @Reference
+    private SystemID systemID;
+
+    @Reference
+    private HttpRequestService httpRequestService;
+
+    @Reference
+    private ConfigurationInfoSource configurationInfoSource;
+
+    public NetworkInfoListDAOImpl() throws Exception {
+        this(new JsonHelper(new NetworkInfoListTypeAdapter()), new ConfigurationCreator());
+    }
+
+    @Activate
+    void activate() throws Exception {
+        config = configCreator.create(configurationInfoSource);
+    }
+
+    NetworkInfoListDAOImpl(JsonHelper jsonHelper, ConfigurationCreator creator) throws Exception {
+        this.jsonHelper = jsonHelper;
+        this.configCreator = creator;
+    }
+
+    @Override
+    protected String toJsonString(NetworkInfoList obj) throws IOException {
+        return jsonHelper.toJson(obj);
+    }
+
+    @Override
+    protected HttpRequestService getHttpRequestService() {
+        return httpRequestService;
+    }
+
+    @Override
+    protected PluginConfiguration getConfig() {
+        return config;
+    }
+
+    @Override
+    protected String getURL(String basepath) {
+        return basepath + "/systems/" + systemID.getSystemID();
+    }
+
+    @Override
+    protected Logger getLogger() {
+        return null;
+    }
+
+    // DS bind method
+    void bindSystemID(SystemID systemid) {
+        this.systemID = systemid;
+    }
+
+    void bindConfigurationInfoSource(ConfigurationInfoSource cfg) {
+        this.configurationInfoSource = cfg;
+    }
+
+    void bindHttpRequestService(HttpRequestService httpRequestService) {
+        this.httpRequestService = httpRequestService;
+    }
+
+    // For testing purposes
+    static class JsonHelper {
+        
+        private final NetworkInfoListTypeAdapter typeAdapter;
+        
+        JsonHelper(NetworkInfoListTypeAdapter typeAdapter) {
+            this.typeAdapter = typeAdapter;
+        }
+
+        String toJson(NetworkInfoList infos) throws IOException {
+            return typeAdapter.toJson(infos);
+        }
+    }
+
+    // For Testing purposes
+    static class ConfigurationCreator {
+
+        PluginConfiguration create(ConfigurationInfoSource source) {
+            return new PluginConfiguration(source, PLUGIN_ID);
+        }
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/host-network/agent/src/main/java/com/redhat/thermostat/host/network/model/NetworkInfoList.java	Thu Jul 06 13:05:47 2017 -0400
@@ -0,0 +1,93 @@
+/*
+ * Copyright 2012-2017 Red Hat, Inc.
+ *
+ * This file is part of Thermostat.
+ *
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.host.network.model;
+
+import java.util.List;
+import java.util.Objects;
+
+import com.redhat.thermostat.storage.core.Entity;
+import com.redhat.thermostat.storage.model.BasePojo;
+
+@Entity
+public class NetworkInfoList extends BasePojo {
+
+    private long timeStamp;
+    private List<NetworkInterfaceInfo> interfaces;
+
+    public NetworkInfoList(String writerID, long timeStamp, List<NetworkInterfaceInfo> list) {
+        super(writerID);
+        this.timeStamp = timeStamp;
+        this.interfaces = list;
+    }
+
+    public List<NetworkInterfaceInfo> getList() {
+        return interfaces;
+    }
+
+    public int size() {
+        return interfaces.size();
+    }
+
+    public NetworkInterfaceInfo get(int n) {
+        return interfaces.get(n);
+    }
+
+    public long getTimeStamp() {
+        return timeStamp;
+    }
+
+    public void setTimeStamp(long timeStamp) {
+        this.timeStamp = timeStamp;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(timeStamp, interfaces, super.hashCode());
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj)
+            return true;
+        if (obj == null)
+            return false;
+        if (getClass() != obj.getClass())
+            return false;
+        NetworkInfoList other = (NetworkInfoList) obj;
+        return timeStamp == other.timeStamp && interfaces.equals(other.interfaces) && super.equals(other);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/host-network/agent/src/main/java/com/redhat/thermostat/host/network/model/NetworkInfoListTypeAdapter.java	Thu Jul 06 13:05:47 2017 -0400
@@ -0,0 +1,157 @@
+/*
+ * Copyright 2012-2017 Red Hat, Inc.
+ *
+ * This file is part of Thermostat.
+ *
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.host.network.model;
+
+import java.io.IOException;
+import java.util.List;
+
+import com.google.gson.TypeAdapter;
+import com.google.gson.stream.JsonReader;
+import com.google.gson.stream.JsonWriter;
+
+public class NetworkInfoListTypeAdapter extends TypeAdapter<NetworkInfoList> {
+
+    private static final String AGENT_ID = "agentId";
+    private static final String TIMESTAMP = "timeStamp";
+    private static final String INTERFACE_LIST = "interfaces";
+    private static final String RESPONSE_ROOT = "response";
+    private static final String SERVER_TIME = "time";
+    private static final String TYPE_LONG = "$numberLong";
+
+    private final NetworkInterfaceInfoTypeAdapter infoTypeAdapter = new NetworkInterfaceInfoTypeAdapter();
+
+    public void write(final JsonWriter out, final NetworkInfoList value) throws IOException {
+
+        out.beginObject();
+
+        out.name(AGENT_ID);
+        out.value(value.getAgentId());
+
+        out.name(TIMESTAMP);
+        writeLong(out, value.getTimeStamp());
+
+        out.name("interfaces");
+        infoTypeAdapter.write(out, value.getList());
+
+        out.endObject();
+    }
+
+    @Override
+    public NetworkInfoList read(final JsonReader in) throws IOException {
+        NetworkInfoList infos = null;
+
+        try {
+            // Parse root object
+            in.beginObject();
+            while (in.hasNext()) {
+                String name = in.nextName();
+                switch (name) {
+                    case RESPONSE_ROOT:
+                        infos = readResponse(in);
+                        break;
+                    case SERVER_TIME:
+                        in.nextString();
+                        break;
+                    default:
+                        throw new IOException("Unexpected JSON name in gateway response: '" + name + "'");
+                }
+            }
+            in.endObject();
+        } catch (IllegalStateException e) {
+            throw new IOException("Reading JSON response from web gateway failed", e);
+        }
+
+        return infos;
+    }
+
+    private NetworkInfoList readResponse(final JsonReader in) throws IOException {
+
+        String agentId = null;
+        long timeStamp = 0;
+        List<NetworkInterfaceInfo> infos = null;
+
+        // Begin parsing a NetworkInterfaceInfo record
+        in.beginObject();
+
+        while (in.hasNext()) {
+            String name = in.nextName();
+            switch (name) {
+                case AGENT_ID:
+                    agentId = in.nextString();
+                    break;
+                case TIMESTAMP:
+                    timeStamp = readLong(in);
+                    break;
+                case INTERFACE_LIST: {
+                    infos = infoTypeAdapter.readList(in);
+                }
+                break;
+                default:
+                    throw new IOException("Unexpected JSON name in record: '" + name + "'");
+            }
+        }
+
+        in.endObject();
+
+        return new NetworkInfoList(agentId, timeStamp, infos);
+    }
+
+    private void writeLong(final JsonWriter out, final long input) throws IOException {
+        // Write MongoDB representation of a Long
+        out.beginObject();
+        out.name(TYPE_LONG);
+        out.value(String.valueOf(input));
+        out.endObject();
+    }
+
+    private long readLong(final JsonReader in) throws IOException {
+        // Read MongoDB representation of a Long
+        in.beginObject();
+        String name = in.nextName();
+        expectName(TYPE_LONG, name);
+        long ret = Long.valueOf(in.nextString());
+        in.endObject();
+        return ret;
+    }
+
+    private void expectName(final String expected, final String actual) throws IOException {
+        if (!expected.equals(actual)) {
+            throw new IOException("Expected JSON name '" + expected + "', got '" + actual + "'");
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/host-network/agent/src/main/java/com/redhat/thermostat/host/network/model/NetworkInterfaceInfo.java	Thu Jul 06 13:05:47 2017 -0400
@@ -0,0 +1,125 @@
+/*
+ * Copyright 2012-2017 Red Hat, Inc.
+ *
+ * This file is part of Thermostat.
+ *
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.host.network.model;
+
+import java.util.Objects;
+
+import com.redhat.thermostat.storage.core.Entity;
+import com.redhat.thermostat.storage.core.Persist;
+
+@Entity
+public class NetworkInterfaceInfo {
+
+    private String iFace;
+    private String displayName;
+    private String ip4Addr;
+    private String ip6Addr;
+
+
+    public NetworkInterfaceInfo(String iFace) {
+        this.iFace = iFace;
+        this.ip4Addr = null;
+        this.ip6Addr = null;
+    }
+
+    @Persist
+    public String getInterfaceName() {
+        return iFace;
+    }
+
+    @Persist
+    public void setInterfaceName(String iFace) {
+        this.iFace = iFace;
+    }
+
+    @Persist
+    public String getDisplayName() {
+        return displayName;
+    }
+
+    @Persist
+    public void setDisplayName(String dn) {
+        this.displayName = dn;
+    }
+
+    @Persist
+    public String getIp4Addr() {
+        return ip4Addr;
+    }
+
+    @Persist
+    public void setIp4Addr(String newAddr) {
+        ip4Addr = newAddr;
+    }
+
+    public void clearIp4Addr() {
+        ip4Addr = null;
+    }
+
+    @Persist
+    public String getIp6Addr() {
+        return ip6Addr;
+    }
+
+    @Persist
+    public void setIp6Addr(String newAddr) {
+        ip6Addr = newAddr;
+    }
+
+    public void clearIp6Addr() {
+        ip6Addr = null;
+    }
+    
+    @Override
+    public int hashCode() {
+        return Objects.hash(iFace, ip4Addr, ip6Addr);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj)
+            return true;
+        if (obj == null)
+            return false;
+        if (getClass() != obj.getClass())
+            return false;
+            NetworkInterfaceInfo other = (NetworkInterfaceInfo) obj;
+            return Objects.equals(iFace, other.iFace) && Objects.equals(ip4Addr, other.ip4Addr)
+                    && Objects.equals(ip6Addr, other.ip6Addr);
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/host-network/agent/src/main/java/com/redhat/thermostat/host/network/model/NetworkInterfaceInfoTypeAdapter.java	Thu Jul 06 13:05:47 2017 -0400
@@ -0,0 +1,185 @@
+/*
+ * Copyright 2012-2017 Red Hat, Inc.
+ *
+ * This file is part of Thermostat.
+ *
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.host.network.model;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import com.google.gson.TypeAdapter;
+import com.google.gson.stream.JsonReader;
+import com.google.gson.stream.JsonToken;
+import com.google.gson.stream.JsonWriter;
+
+public class NetworkInterfaceInfoTypeAdapter extends TypeAdapter<List<NetworkInterfaceInfo>> {
+
+    private static final String INTERFACE_NAME = "interfaceName";
+    private static final String DISPLAY_NAME = "displayName";
+    private static final String IP4_ADDR = "ip4Addr";
+    private static final String IP6_ADDR = "ip6Addr";
+    private static final String RESPONSE_ROOT = "response";
+    private static final String SERVER_TIME = "time";
+
+    @Override
+    public void write(JsonWriter out, List<NetworkInterfaceInfo> value) throws IOException {
+
+        // Request is an array of NetworkInterfaceInfo objects
+        out.beginArray();
+        
+        for (NetworkInterfaceInfo info : value) {
+            writeNetworkInterfaceInfo(out, info);
+        }
+        
+        out.endArray();
+    }
+
+    private void writeNetworkInterfaceInfo(JsonWriter out, NetworkInterfaceInfo info) throws IOException {
+        out.beginObject();
+        
+        // Write each field of NetworkInterfaceInfo as part of a JSON object
+        out.name(INTERFACE_NAME);
+        out.value(info.getInterfaceName());
+
+        if (info.getDisplayName() != null) {
+            out.name(DISPLAY_NAME);
+            out.value(info.getDisplayName());
+        }
+        out.name(IP4_ADDR);
+        out.value(info.getIp4Addr());
+        out.name(IP6_ADDR);
+        out.value(info.getIp6Addr());
+        
+        out.endObject();
+    }
+
+    @Override
+    public List<NetworkInterfaceInfo> read(JsonReader in) throws IOException {
+        List<NetworkInterfaceInfo> infos = null;
+        
+        try {
+            // Parse root object
+            in.beginObject();
+            while (in.hasNext()) {
+                String name = in.nextName();
+                switch (name) {
+                case RESPONSE_ROOT:
+                    infos = readList(in);
+                    break;
+                case SERVER_TIME:
+                    in.nextString();
+                    break;
+                default:
+                    throw new IOException("Unexpected JSON name in gateway response: '" + name + "'");
+                }
+            }
+            in.endObject();
+        } catch (IllegalStateException e) {
+            throw new IOException("Reading JSON response from web gateway failed", e);
+        }
+        
+        return infos;
+    }
+    
+    List<NetworkInterfaceInfo> readList(JsonReader in) throws IOException {
+        List<NetworkInterfaceInfo> infos = new ArrayList<>();
+        
+        // Parse array of NetworkInterfaceInfos
+        in.beginArray();
+        
+        while (in.hasNext()) {
+            NetworkInterfaceInfo info = readNetworkInterfaceInfo(in);
+            infos.add(info);
+        }
+        in.endArray();
+        
+        return infos;
+    }
+    
+    private NetworkInterfaceInfo readNetworkInterfaceInfo(JsonReader in) throws IOException {
+        String interfaceName = null;
+        String ipv4Addr = null;
+        String ipv6Addr = null;
+        String displayName = null;
+        
+        // Begin parsing a NetworkInterfaceInfo record
+        in.beginObject();
+        
+        while (in.hasNext()) {
+            String name = in.nextName();
+            switch (name) {
+            case INTERFACE_NAME:
+                interfaceName = in.nextString();
+                break;
+            case DISPLAY_NAME:
+                displayName = in.nextString();
+                break;
+            case IP4_ADDR: // Addresses may be null
+                ipv4Addr = readStringOrNull(in);
+                break;
+            case IP6_ADDR:
+                ipv6Addr = readStringOrNull(in);
+                break;
+            default:
+                throw new IOException("Unexpected JSON name in record: '" + name + "'");
+            }
+        }
+        
+        in.endObject();
+        
+        // Create NetworkInterfaceInfo if all required fields present
+        if (interfaceName == null) {
+            throw new IOException("Network interface information record is incomplete");
+        }
+        NetworkInterfaceInfo result = new NetworkInterfaceInfo(interfaceName);
+        result.setIp4Addr(ipv4Addr);
+        result.setIp6Addr(ipv6Addr);
+        result.setDisplayName(displayName);
+        
+        return result;
+    }
+    
+    private String readStringOrNull(JsonReader in) throws IOException {
+        String result = null;
+        JsonToken token = in.peek();
+        if (token == JsonToken.NULL) {
+            in.nextNull();
+        } else {
+            result = in.nextString();
+        }
+        return result;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/host-network/agent/src/test/java/com/redhat/thermostat/host/network/internal/HostNetworkBackendTest.java	Thu Jul 06 13:05:47 2017 -0400
@@ -0,0 +1,95 @@
+/*
+ * Copyright 2012-2017 Red Hat, Inc.
+ *
+ * This file is part of Thermostat.
+ *
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.host.network.internal;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.redhat.thermostat.common.Version;
+
+import java.util.concurrent.ScheduledExecutorService;
+
+public class HostNetworkBackendTest {
+
+    private static final String VERSION = "0.0.0";
+    private HostNetworkBackend b;
+
+    @Before
+    public void setUp() {
+        ScheduledExecutorService executor = mock(ScheduledExecutorService.class);
+        Version version = mock(Version.class);
+        when(version.getVersionNumber()).thenReturn(VERSION);
+        b = new HostNetworkBackend("backend", "test backend", "redhat", version, executor);
+    }
+
+    @Test
+    public void testBasicBackend() {
+        Assert.assertFalse(b.isActive());
+        b.activate();
+        assertTrue(b.isActive());
+        b.deactivate();
+        assertFalse(b.isActive());
+    }
+
+    @Test
+    public void testActivateTwice() {
+        b.activate();
+        b.activate();
+        Assert.assertTrue(b.isActive());
+    }
+
+    @Test
+    public void testDeactiateWhenNotActive() {
+        b.deactivate();
+        b.deactivate();
+        assertFalse(b.isActive());
+    }
+    
+    @Test
+    public void testVersion() {
+        assertEquals(VERSION, b.getVersion());
+    }
+
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/host-network/agent/src/test/java/com/redhat/thermostat/host/network/internal/NetworkInfoBuilderTest.java	Thu Jul 06 13:05:47 2017 -0400
@@ -0,0 +1,88 @@
+/*
+ * Copyright 2012-2017 Red Hat, Inc.
+ *
+ * This file is part of Thermostat.
+ *
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.host.network.internal;
+
+import java.util.List;
+
+import com.redhat.thermostat.host.network.model.NetworkInterfaceInfo;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class NetworkInfoBuilderTest {
+
+    @Test
+    public void testBuilder() {
+        NetworkInfoBuilder builder = new NetworkInfoBuilder();
+        List<NetworkInterfaceInfo> info = builder.build();
+        Assert.assertNotNull(info);
+        for (NetworkInterfaceInfo iface: info) {
+            Assert.assertNotNull(iface);
+            Assert.assertNotNull(iface.getInterfaceName());
+            if (iface.getIp4Addr() != null) {
+                // ipv4 address matches the form XX.XX.XX.XX
+                Assert.assertTrue(iface.getIp4Addr().matches("\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}"));
+            }
+            if (iface.getIp6Addr() != null) {
+                validateIpv6Address(iface.getIp6Addr());
+            }
+        }
+
+    }
+
+    private void validateIpv6Address(String address) {
+        // ipv6 addresses may contain a scope id
+        if (address.contains("%")) {
+            int index = address.indexOf("%");
+            Assert.assertTrue(index >= 0);
+            String scopeId = address.substring(index);
+            Assert.assertFalse(scopeId.isEmpty());
+            address = address.substring(0, index);
+        }
+
+        String[] parts = address.split(":");
+        Assert.assertEquals(8, parts.length);
+
+        for (String part : parts) {
+            Assert.assertNotNull(part);
+            if (!part.isEmpty()) {
+                Assert.assertTrue(part.matches("[0-9a-f]*"));
+            }
+        }
+    }
+
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/host-network/agent/src/test/java/com/redhat/thermostat/host/network/internal/NetworkInfoListDAOTest.java	Thu Jul 06 13:05:47 2017 -0400
@@ -0,0 +1,127 @@
+/*
+ * Copyright 2012-2017 Red Hat, Inc.
+ *
+ * This file is part of Thermostat.
+ *
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.host.network.internal;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Map;
+
+import com.redhat.thermostat.agent.http.HttpRequestService;
+import com.redhat.thermostat.common.config.experimental.ConfigurationInfoSource;
+import com.redhat.thermostat.common.plugin.PluginConfiguration;
+import com.redhat.thermostat.common.plugin.SystemID;
+import com.redhat.thermostat.host.network.model.NetworkInfoList;
+import com.redhat.thermostat.host.network.model.NetworkInterfaceInfo;
+import com.redhat.thermostat.host.network.internal.NetworkInfoListDAOImpl.JsonHelper;
+
+import org.eclipse.jetty.client.api.ContentResponse;
+import org.eclipse.jetty.http.HttpMethod;
+import org.eclipse.jetty.http.HttpStatus;
+
+import org.junit.Before;
+import org.junit.Test;
+
+public class NetworkInfoListDAOTest {
+
+    private static final String URL = "http://localhost:26000/api/v100/network-info/systems/";
+    private static final String INTERFACE_NAME = "some interface. maybe eth0";
+    private static final long TIMESTAMP = 333;
+    private static final String IPV4_ADDR = "256.256.256.256";
+    private static final String IPV6_ADDR = "100:100:100::::1";
+    private static final String SOME_JSON = "{\"some\" : \"json\"}";
+    private static final String URL_PROP = "gatewayURL";
+    private static final String HOST_NAME = "somehostname";
+    private static final String AGENT_ID = "xxx some agent";
+
+    private JsonHelper jsonHelper;
+
+    private ConfigurationInfoSource cfiSource;
+    private NetworkInfoListDAOImpl.ConfigurationCreator configCreator;
+
+    private SystemID idservice;
+    private HttpRequestService httpRequestService;
+
+    @Before
+    public void setup() throws Exception {
+        NetworkInterfaceInfo info = new NetworkInterfaceInfo(INTERFACE_NAME);
+        info.setIp4Addr(IPV4_ADDR);
+        info.setIp6Addr(IPV6_ADDR);
+        
+        jsonHelper = mock(JsonHelper.class);
+        when(jsonHelper.toJson(any(NetworkInfoList.class))).thenReturn(SOME_JSON);
+
+        cfiSource = mock(ConfigurationInfoSource.class);
+        Map<String,String> map = new HashMap<>();
+        map.put(URL_PROP, URL);
+        when(cfiSource.getConfiguration(anyString(),anyString())).thenReturn(map);
+
+        configCreator = mock(NetworkInfoListDAOImpl.ConfigurationCreator.class);
+        when(configCreator.create(eq(cfiSource))).thenReturn(new PluginConfiguration(cfiSource, NetworkInfoListDAOImpl.PLUGIN_ID));
+
+        httpRequestService = mock(HttpRequestService.class);
+        ContentResponse contentResponse = mock(ContentResponse.class);
+       // when(httpRequestService.sendHttpRequest(anyString(), anyString(), anyString())).thenReturn(contentResponse);
+        when(contentResponse.getStatus()).thenReturn(HttpStatus.OK_200);
+
+        idservice = mock(SystemID.class);
+        when(idservice.getSystemID()).thenReturn(HOST_NAME);
+    }
+
+    @Test
+    public void testPut() throws Exception {
+
+        NetworkInfoListDAOImpl dao = new NetworkInfoListDAOImpl(jsonHelper, configCreator);
+        dao.bindSystemID(idservice);
+        dao.bindConfigurationInfoSource(cfiSource);
+        dao.bindHttpRequestService(httpRequestService);
+        dao.activate();
+
+        NetworkInfoList obj = new NetworkInfoList(AGENT_ID, TIMESTAMP, new ArrayList<NetworkInterfaceInfo>());
+        dao.put(obj);
+
+        verify(httpRequestService, times(1)).sendHttpRequest(SOME_JSON, URL + "/systems/" + HOST_NAME, HttpMethod.POST.asString());
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/host-network/agent/src/test/java/com/redhat/thermostat/host/network/model/NetworkInfoListTest.java	Thu Jul 06 13:05:47 2017 -0400
@@ -0,0 +1,117 @@
+/*
+ * Copyright 2012-2017 Red Hat, Inc.
+ *
+ * This file is part of Thermostat.
+ *
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.host.network.model;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import java.util.ArrayList;
+
+public class NetworkInfoListTest {
+
+    private NetworkInfoList info;
+
+    private static final String WRITER_ID = "some-agent-id";
+    private static final long TIMESTAMP = 333;
+
+    @Before
+    public void setup() {
+        info = createInfo("if1", "1.2.3.4", "1:2:3:4:5:6:7:8");
+    }
+
+    @Test
+    public void testEquals() {
+        NetworkInfoList other = createInfo( "if1", "1.2.3.4", "1:2:3:4:5:6:7:8");
+        assertTrue(info.equals(other));
+    }
+
+    @Test
+    public void testEqualsWrongInterface() {
+        NetworkInfoList other = createInfo("if2", "1.2.3.4", "1:2:3:4:5:6:7:8");
+        assertFalse(info.equals(other));
+    }
+
+    @Test
+    public void testEqualsWrongIpV4() {
+        NetworkInfoList other = createInfo("if1", "1.2.3.5", "1:2:3:4:5:6:7:8");
+        assertFalse(info.equals(other));
+    }
+
+    @Test
+    public void testEqualsWrongIpV6() {
+        NetworkInfoList other = createInfo("if1", "1.2.3.4", "1:2:3:4:5:6:7:9");
+        assertFalse(info.equals(other));
+    }
+
+    @Test
+    public void testHashCode() {
+        NetworkInfoList other = createInfo("if1", "1.2.3.4", "1:2:3:4:5:6:7:8");
+        assertEquals(info.hashCode(), other.hashCode());
+    }
+
+    @Test
+    public void testHashCodeWrongInterface() {
+        NetworkInfoList other = createInfo("if2", "1.2.3.4", "1:2:3:4:5:6:7:8");
+        assertFalse(info.hashCode() == other.hashCode());
+    }
+
+    @Test
+    public void testHashCodeWrongIpV4() {
+        NetworkInfoList other = createInfo("if1", "1.2.3.5", "1:2:3:4:5:6:7:8");
+        assertFalse(info.hashCode() == other.hashCode());
+    }
+
+    @Test
+    public void testHashCodeWrongIpV6() {
+        NetworkInfoList other = createInfo("if1", "1.2.3.4", "1:2:3:4:5:6:7:9");
+        assertFalse(info.hashCode() == other.hashCode());
+    }
+
+    private NetworkInfoList createInfo(String iFace, String ip4Addr, String ip6Addr) {
+        NetworkInterfaceInfo info = new NetworkInterfaceInfo(iFace);
+        info.setIp4Addr(ip4Addr);
+        info.setIp6Addr(ip6Addr);
+        ArrayList<NetworkInterfaceInfo> list = new ArrayList<NetworkInterfaceInfo>(1);
+        list.add(info);
+        NetworkInfoList ilist = new NetworkInfoList(WRITER_ID, TIMESTAMP, list);
+        return ilist;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/host-network/agent/src/test/java/com/redhat/thermostat/host/network/model/NetworkInfoListTypeAdapterTest.java	Thu Jul 06 13:05:47 2017 -0400
@@ -0,0 +1,113 @@
+/*
+ * Copyright 2012-2017 Red Hat, Inc.
+ *
+ * This file is part of Thermostat.
+ *
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.host.network.model;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+
+import java.util.ArrayList;
+
+import org.junit.Test;
+
+public class NetworkInfoListTypeAdapterTest {
+
+    private static final String WRITER_ID = "some-agent-id";
+    private static final long TIMESTAMP = 333;
+
+    @Test
+    public void testWrite() throws Exception {
+        NetworkInfoListTypeAdapter adapter = new NetworkInfoListTypeAdapter();
+        final String expected = "{\"agentId\":\"some-agent-id\",\"timeStamp\":{\"$numberLong\":\"333\"},\"interfaces\":[{\"interfaceName\":\"lo\",\"ip4Addr\":\"127.0.0.1\","
+                + "\"ip6Addr\":\"0:0:0:0:0:0:0:1%lo\"},{\"interfaceName\":\"if1\","
+                + "\"ip4Addr\":\"1.2.3.4\",\"ip6Addr\":\"1:2:3:4:5:6:7:8%if1\"}]}";
+
+        NetworkInterfaceInfo first = createInfo("lo", "127.0.0.1", "0:0:0:0:0:0:0:1%lo");
+        NetworkInterfaceInfo second = createInfo("if1", "1.2.3.4", "1:2:3:4:5:6:7:8%if1");
+        NetworkInfoList infos = createNetworkInfoList(first, second);
+
+        String json = adapter.toJson(infos);
+        assertEquals(expected, json);
+    }
+
+    @Test
+    public void testRead() throws Exception {
+        NetworkInfoListTypeAdapter adapter = new NetworkInfoListTypeAdapter();
+        final String json = "{\"response\" : {\"agentId\":\"some-agent-id\",\"timeStamp\":{\"$numberLong\":\"333\"},\"interfaces\":[{\"interfaceName\" : \"lo\", "
+                + "\"ip4Addr\" : \"127.0.0.1\", \"ip6Addr\" : \"0:0:0:0:0:0:0:1%lo\"}, "
+                + "{\"interfaceName\" : \"if1\", "
+                + "\"ip4Addr\" : \"1.2.3.4\", \"ip6Addr\" : null}]}, "
+                + "\"time\" : \"500000000\"}";
+
+        NetworkInfoList infos = adapter.fromJson(json);
+        assertEquals(2, infos.size());
+
+        NetworkInterfaceInfo first = infos.get(0);
+        assertEquals("lo", first.getInterfaceName());
+        assertEquals("127.0.0.1", first.getIp4Addr());
+        assertEquals("0:0:0:0:0:0:0:1%lo", first.getIp6Addr());
+
+        NetworkInterfaceInfo second = infos.get(1);
+        assertEquals("if1", second.getInterfaceName());
+        assertEquals("1.2.3.4", second.getIp4Addr());
+        assertNull(second.getIp6Addr());
+    }
+
+    private NetworkInfoList createNetworkInfoList(String iFace, String ip4Addr, String ip6Addr) {
+        NetworkInterfaceInfo info = new NetworkInterfaceInfo(iFace);
+        info.setIp4Addr(ip4Addr);
+        info.setIp6Addr(ip6Addr);
+        ArrayList<NetworkInterfaceInfo> list = new ArrayList<NetworkInterfaceInfo>(1);
+        list.add(info);
+        final NetworkInfoList ilist = new NetworkInfoList(WRITER_ID, TIMESTAMP, list);
+        return ilist;
+    }
+
+    private NetworkInfoList createNetworkInfoList(NetworkInterfaceInfo n1, NetworkInterfaceInfo n2) {
+        ArrayList<NetworkInterfaceInfo> list = new ArrayList<NetworkInterfaceInfo>(2);
+        list.add(n1);
+        list.add(n2);
+        final NetworkInfoList ilist = new NetworkInfoList(WRITER_ID, TIMESTAMP, list);
+        return ilist;
+    }
+
+    private NetworkInterfaceInfo createInfo(String iFace, String ip4Addr, String ip6Addr) {
+        NetworkInterfaceInfo info = new NetworkInterfaceInfo(iFace);
+        info.setIp4Addr(ip4Addr);
+        info.setIp6Addr(ip6Addr);
+        return info;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/host-network/agent/src/test/java/com/redhat/thermostat/host/network/model/NetworkInterfaceInfoTest.java	Thu Jul 06 13:05:47 2017 -0400
@@ -0,0 +1,108 @@
+/*
+ * Copyright 2012-2017 Red Hat, Inc.
+ *
+ * This file is part of Thermostat.
+ *
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.host.network.model;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+public class NetworkInterfaceInfoTest {
+    
+    private NetworkInterfaceInfo info;
+    
+    @Before
+    public void setup() {
+        info = createInfo("if1", "1.2.3.4", "1:2:3:4:5:6:7:8");
+    }
+
+    @Test
+    public void testEquals() {
+        NetworkInterfaceInfo other = createInfo( "if1", "1.2.3.4", "1:2:3:4:5:6:7:8");
+        Assert.assertTrue(info.equals(other));
+    }
+    
+    @Test
+    public void testEqualsWrongInterface() {
+        NetworkInterfaceInfo other = createInfo("if2", "1.2.3.4", "1:2:3:4:5:6:7:8");
+        Assert.assertFalse(info.equals(other));
+    }
+    
+    @Test
+    public void testEqualsWrongIpV4() {
+        NetworkInterfaceInfo other = createInfo("if1", "1.2.3.5", "1:2:3:4:5:6:7:8");
+        Assert.assertFalse(info.equals(other));
+    }
+    
+    @Test
+    public void testEqualsWrongIpV6() {
+        NetworkInterfaceInfo other = createInfo("if1", "1.2.3.4", "1:2:3:4:5:6:7:9");
+        Assert.assertFalse(info.equals(other));
+    }
+    
+    @Test
+    public void testHashCode() {
+        NetworkInterfaceInfo other = createInfo("if1", "1.2.3.4", "1:2:3:4:5:6:7:8");
+        assertEquals(info.hashCode(), other.hashCode());
+    }
+    
+    @Test
+    public void testHashCodeWrongInterface() {
+        NetworkInterfaceInfo other = createInfo("if2", "1.2.3.4", "1:2:3:4:5:6:7:8");
+        Assert.assertFalse(info.hashCode() == other.hashCode());
+    }
+    
+    @Test
+    public void testHashCodeWrongIpV4() {
+        NetworkInterfaceInfo other = createInfo("if1", "1.2.3.5", "1:2:3:4:5:6:7:8");
+        Assert.assertFalse(info.hashCode() == other.hashCode());
+    }
+    
+    @Test
+    public void testHashCodeWrongIpV6() {
+        NetworkInterfaceInfo other = createInfo("if1", "1.2.3.4", "1:2:3:4:5:6:7:9");
+        Assert.assertFalse(info.hashCode() == other.hashCode());
+    }
+
+    private NetworkInterfaceInfo createInfo(String iFace, String ip4Addr, String ip6Addr) {
+        NetworkInterfaceInfo info = new NetworkInterfaceInfo(iFace);
+        info.setIp4Addr(ip4Addr);
+        info.setIp6Addr(ip6Addr);
+        return info;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/host-network/agent/src/test/java/com/redhat/thermostat/host/network/model/NetworkInterfaceInfoTypeAdapterTest.java	Thu Jul 06 13:05:47 2017 -0400
@@ -0,0 +1,95 @@
+/*
+ * Copyright 2012-2017 Red Hat, Inc.
+ *
+ * This file is part of Thermostat.
+ *
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.host.network.model;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+
+import java.util.Arrays;
+import java.util.List;
+
+import org.junit.Test;
+
+public class NetworkInterfaceInfoTypeAdapterTest {
+    
+    @Test
+    public void testWrite() throws Exception {
+        NetworkInterfaceInfoTypeAdapter adapter = new NetworkInterfaceInfoTypeAdapter();
+        final String expected = "[{\"interfaceName\":\"lo\",\"ip4Addr\":\"127.0.0.1\","
+                + "\"ip6Addr\":\"0:0:0:0:0:0:0:1%lo\"},{\"interfaceName\":\"if1\","
+                + "\"ip4Addr\":\"1.2.3.4\",\"ip6Addr\":\"1:2:3:4:5:6:7:8%if1\"}]";
+        
+        NetworkInterfaceInfo first = createNetworkInterfaceInfo("lo", "127.0.0.1", "0:0:0:0:0:0:0:1%lo");
+        NetworkInterfaceInfo second = createNetworkInterfaceInfo("if1", "1.2.3.4", "1:2:3:4:5:6:7:8%if1");
+        List<NetworkInterfaceInfo> infos = Arrays.asList(first, second);
+        
+        String json = adapter.toJson(infos);
+        assertEquals(expected, json);
+    }
+    
+    @Test
+    public void testRead() throws Exception {
+        NetworkInterfaceInfoTypeAdapter adapter = new NetworkInterfaceInfoTypeAdapter();
+        final String json = "{\"response\" : [{\"interfaceName\" : \"lo\", "
+                + "\"ip4Addr\" : \"127.0.0.1\", \"ip6Addr\" : \"0:0:0:0:0:0:0:1%lo\"}, "
+                + "{\"interfaceName\" : \"if1\", "
+                + "\"ip4Addr\" : \"1.2.3.4\", \"ip6Addr\" : null}], "
+                + "\"time\" : \"500000000\"}";
+        
+        List<NetworkInterfaceInfo> infos = adapter.fromJson(json);
+        assertEquals(2, infos.size());
+        
+        NetworkInterfaceInfo first = infos.get(0);
+        assertEquals("lo", first.getInterfaceName());
+        assertEquals("127.0.0.1", first.getIp4Addr());
+        assertEquals("0:0:0:0:0:0:0:1%lo", first.getIp6Addr());
+        
+        NetworkInterfaceInfo second = infos.get(1);
+        assertEquals("if1", second.getInterfaceName());
+        assertEquals("1.2.3.4", second.getIp4Addr());
+        assertNull(second.getIp6Addr());
+    }
+    
+    private NetworkInterfaceInfo createNetworkInterfaceInfo(String iFace, String ip4Addr, String ip6Addr) {
+        NetworkInterfaceInfo info = new NetworkInterfaceInfo(iFace);
+        info.setIp4Addr(ip4Addr);
+        info.setIp6Addr(ip6Addr);
+        info.setDisplayName(null);
+        return info;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/host-network/distribution/assemblies/plugin-assembly.xml	Thu Jul 06 13:05:47 2017 -0400
@@ -0,0 +1,73 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ Copyright 2012-2017 Red Hat, Inc.
+
+ This file is part of Thermostat.
+
+ Thermostat is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 2, or (at your
+ option) any later version.
+
+ Thermostat is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with Thermostat; see the file COPYING.  If not see
+ <http://www.gnu.org/licenses/>.
+
+ Linking this code with other modules is making a combined work
+ based on this code.  Thus, the terms and conditions of the GNU
+ General Public License cover the whole combination.
+
+ As a special exception, the copyright holders of this code give
+ you permission to link this code with independent modules to
+ produce an executable, regardless of the license terms of these
+ independent modules, and to copy and distribute the resulting
+ executable under terms of your choice, provided that you also
+ meet, for each linked independent module, the terms and conditions
+ of the license of that module.  An independent module is a module
+ which is not derived from or based on this code.  If you modify
+ this code, you may extend this exception to your version of the
+ library, but you are not obligated to do so.  If you do not wish
+ to do so, delete this exception statement from your version.
+
+-->
+<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2"
+          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+          xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd">
+    <id>plugin-assembly</id>
+    <formats>
+        <format>zip</format>
+    </formats>
+    <includeBaseDirectory>false</includeBaseDirectory>
+
+    <dependencySets>
+        <dependencySet>
+            <includes>
+                <include>com.redhat.thermostat:thermostat-host-network-agent</include>
+            </includes>
+            <useProjectArtifact>false</useProjectArtifact>
+            <useStrictFiltering>true</useStrictFiltering>
+            <outputDirectory>plugins/${thermostat.plugin}</outputDirectory>
+        </dependencySet>
+    </dependencySets>
+
+    <fileSets>
+        <fileSet>
+            <includes>
+                <include>thermostat-plugin.xml</include>
+            </includes>
+            <outputDirectory>plugins/${thermostat.plugin}</outputDirectory>
+            <filtered>true</filtered>
+        </fileSet>
+        <fileSet>
+            <directory>configFiles</directory>
+            <outputDirectory>etc/plugins.d/${thermostat.plugin}</outputDirectory>
+            <filtered>true</filtered>
+        </fileSet>
+    </fileSets>
+</assembly>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/host-network/distribution/configFiles/gateway.properties	Thu Jul 06 13:05:47 2017 -0400
@@ -0,0 +1,2 @@
+# URL to the microservice provided by the Thermostat web gateway
+gatewayURL=http://localhost:30000/system-network/0.0.1
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/host-network/distribution/pom.xml	Thu Jul 06 13:05:47 2017 -0400
@@ -0,0 +1,89 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ Copyright 2012-2017 Red Hat, Inc.
+
+ This file is part of Thermostat.
+
+ Thermostat is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 2, or (at your
+ option) any later version.
+
+ Thermostat is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with Thermostat; see the file COPYING.  If not see
+ <http://www.gnu.org/licenses/>.
+
+ Linking this code with other modules is making a combined work
+ based on this code.  Thus, the terms and conditions of the GNU
+ General Public License cover the whole combination.
+
+ As a special exception, the copyright holders of this code give
+ you permission to link this code with independent modules to
+ produce an executable, regardless of the license terms of these
+ independent modules, and to copy and distribute the resulting
+ executable under terms of your choice, provided that you also
+ meet, for each linked independent module, the terms and conditions
+ of the license of that module.  An independent module is a module
+ which is not derived from or based on this code.  If you modify
+ this code, you may extend this exception to your version of the
+ library, but you are not obligated to do so.  If you do not wish
+ to do so, delete this exception statement from your version.
+
+-->
+<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>com.redhat.thermostat</groupId>
+    <artifactId>thermostat-host-network</artifactId>
+    <version>1.99.12-SNAPSHOT</version>
+  </parent>
+
+  <artifactId>thermostat-host-network-distribution</artifactId>
+  <packaging>pom</packaging>
+
+  <name>Thermostat Host Network plugin distribution</name>
+  
+  <properties>
+    <thermostat.plugin>host-network</thermostat.plugin>
+  </properties>
+
+  <build>
+    <plugins>
+      <plugin>
+        <artifactId>maven-assembly-plugin</artifactId>
+        <configuration>
+          <descriptors>
+            <descriptor>assemblies/plugin-assembly.xml</descriptor>
+          </descriptors>
+          <appendAssemblyId>false</appendAssemblyId>
+        </configuration>
+        <executions>
+          <execution>
+            <id>assemble-plugin</id>
+            <phase>package</phase>
+            <goals>
+              <goal>single</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+    </plugins>
+  </build>
+  
+  <dependencies>
+    <dependency>
+      <groupId>com.redhat.thermostat</groupId>
+      <artifactId>thermostat-host-network-agent</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+  </dependencies>
+
+</project>
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/host-network/distribution/thermostat-plugin.xml	Thu Jul 06 13:05:47 2017 -0400
@@ -0,0 +1,51 @@
+<?xml version="1.0"?>
+<!--
+
+ Copyright 2012-2017 Red Hat, Inc.
+
+ This file is part of Thermostat.
+
+ Thermostat is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 2, or (at your
+ option) any later version.
+
+ Thermostat is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with Thermostat; see the file COPYING.  If not see
+ <http://www.gnu.org/licenses/>.
+
+ Linking this code with other modules is making a combined work
+ based on this code.  Thus, the terms and conditions of the GNU
+ General Public License cover the whole combination.
+
+ As a special exception, the copyright holders of this code give
+ you permission to link this code with independent modules to
+ produce an executable, regardless of the license terms of these
+ independent modules, and to copy and distribute the resulting
+ executable under terms of your choice, provided that you also
+ meet, for each linked independent module, the terms and conditions
+ of the license of that module.  An independent module is a module
+ which is not derived from or based on this code.  If you modify
+ this code, you may extend this exception to your version of the
+ library, but you are not obligated to do so.  If you do not wish
+ to do so, delete this exception statement from your version.
+
+-->
+<plugin xmlns="http://icedtea.classpath.org/thermostat/plugins/v1.0"
+  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://icedtea.classpath.org/thermostat/plugins/v1.0 thermostat-plugin.xsd">
+  <extensions>
+    <extension>
+      <name>agent</name>
+      <bundles>
+        <bundle><symbolic-name>com.redhat.thermostat.host.network.agent</symbolic-name><version>${project.version}</version></bundle>
+      </bundles>
+    </extension>
+  </extensions>
+</plugin>
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/host-network/pom.xml	Thu Jul 06 13:05:47 2017 -0400
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ Copyright 2012-2017 Red Hat, Inc.
+
+ This file is part of Thermostat.
+
+ Thermostat is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 2, or (at your
+ option) any later version.
+
+ Thermostat is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with Thermostat; see the file COPYING.  If not see
+ <http://www.gnu.org/licenses/>.
+
+ Linking this code with other modules is making a combined work
+ based on this code.  Thus, the terms and conditions of the GNU
+ General Public License cover the whole combination.
+
+ As a special exception, the copyright holders of this code give
+ you permission to link this code with independent modules to
+ produce an executable, regardless of the license terms of these
+ independent modules, and to copy and distribute the resulting
+ executable under terms of your choice, provided that you also
+ meet, for each linked independent module, the terms and conditions
+ of the license of that module.  An independent module is a module
+ which is not derived from or based on this code.  If you modify
+ this code, you may extend this exception to your version of the
+ library, but you are not obligated to do so.  If you do not wish
+ to do so, delete this exception statement from your version.
+
+-->
+<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>com.redhat.thermostat</groupId>
+        <artifactId>thermostat-plugins</artifactId>
+        <version>1.99.12-SNAPSHOT</version>
+    </parent>
+
+    <artifactId>thermostat-host-network</artifactId>
+    <packaging>pom</packaging>
+
+    <name>Thermostat Host Network plugin</name>
+
+    <modules>
+        <module>agent</module>
+        <module>distribution</module>
+    </modules>
+
+</project>
+
--- a/plugins/pom.xml	Wed Jul 05 14:29:14 2017 -0400
+++ b/plugins/pom.xml	Thu Jul 06 13:05:47 2017 -0400
@@ -56,6 +56,7 @@
     <module>host-overview</module>
     <module>host-cpu</module>
     <module>host-memory</module>
+    <module>host-network</module>
     <module>jvm-overview</module>
     <module>vm-gc</module>
     <module>vm-memory</module>
--- a/pom.xml	Wed Jul 05 14:29:14 2017 -0400
+++ b/pom.xml	Thu Jul 06 13:05:47 2017 -0400
@@ -339,7 +339,6 @@
     <module>common</module>
     <module>agent</module>
     <module>process-handler</module>
-    <module>system-backend</module>
     <module>storage</module>
     <module>thermostat-plugin-validator</module>
     <module>config</module>
--- a/storage/core/src/main/java/com/redhat/thermostat/storage/dao/NetworkInterfaceInfoDAO.java	Wed Jul 05 14:29:14 2017 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,47 +0,0 @@
-/*
- * Copyright 2012-2017 Red Hat, Inc.
- *
- * This file is part of Thermostat.
- *
- * Thermostat is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2, or (at your
- * option) any later version.
- *
- * Thermostat is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Thermostat; see the file COPYING.  If not see
- * <http://www.gnu.org/licenses/>.
- *
- * Linking this code with other modules is making a combined work
- * based on this code.  Thus, the terms and conditions of the GNU
- * General Public License cover the whole combination.
- *
- * As a special exception, the copyright holders of this code give
- * you permission to link this code with independent modules to
- * produce an executable, regardless of the license terms of these
- * independent modules, and to copy and distribute the resulting
- * executable under terms of your choice, provided that you also
- * meet, for each linked independent module, the terms and conditions
- * of the license of that module.  An independent module is a module
- * which is not derived from or based on this code.  If you modify
- * this code, you may extend this exception to your version of the
- * library, but you are not obligated to do so.  If you do not wish
- * to do so, delete this exception statement from your version.
- */
-
-package com.redhat.thermostat.storage.dao;
-
-import com.redhat.thermostat.annotations.Service;
-import com.redhat.thermostat.storage.model.NetworkInterfaceInfo;
-
-@Service
-public interface NetworkInterfaceInfoDAO {
-
-    public void putNetworkInterfaceInfo(NetworkInterfaceInfo info);
-}
-
--- a/storage/core/src/main/java/com/redhat/thermostat/storage/internal/Activator.java	Wed Jul 05 14:29:14 2017 -0400
+++ b/storage/core/src/main/java/com/redhat/thermostat/storage/internal/Activator.java	Thu Jul 06 13:05:47 2017 -0400
@@ -45,8 +45,6 @@
 import org.osgi.framework.ServiceRegistration;
 
 import com.redhat.thermostat.storage.core.WriterID;
-import com.redhat.thermostat.storage.dao.NetworkInterfaceInfoDAO;
-import com.redhat.thermostat.storage.internal.dao.NetworkInterfaceInfoDAOImpl;
 
 public class Activator implements BundleActivator {
     
@@ -66,10 +64,6 @@
         final WriterID writerID = new WriterIDImpl(WRITER_UUID);
         ServiceRegistration<?> reg = context.registerService(WriterID.class, writerID, null);
         regs.add(reg);
-
-        NetworkInterfaceInfoDAO networkInfoDao = new NetworkInterfaceInfoDAOImpl();
-        reg = context.registerService(NetworkInterfaceInfoDAO.class.getName(), networkInfoDao, null);
-        regs.add(reg);
     }
 
     private void unregisterServices() {
--- a/storage/core/src/main/java/com/redhat/thermostat/storage/internal/dao/NetworkInterfaceInfoDAOImpl.java	Wed Jul 05 14:29:14 2017 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,290 +0,0 @@
-/*
- * Copyright 2012-2017 Red Hat, Inc.
- *
- * This file is part of Thermostat.
- *
- * Thermostat is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2, or (at your
- * option) any later version.
- *
- * Thermostat is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Thermostat; see the file COPYING.  If not see
- * <http://www.gnu.org/licenses/>.
- *
- * Linking this code with other modules is making a combined work
- * based on this code.  Thus, the terms and conditions of the GNU
- * General Public License cover the whole combination.
- *
- * As a special exception, the copyright holders of this code give
- * you permission to link this code with independent modules to
- * produce an executable, regardless of the license terms of these
- * independent modules, and to copy and distribute the resulting
- * executable under terms of your choice, provided that you also
- * meet, for each linked independent module, the terms and conditions
- * of the license of that module.  An independent module is a module
- * which is not derived from or based on this code.  If you modify
- * this code, you may extend this exception to your version of the
- * library, but you are not obligated to do so.  If you do not wish
- * to do so, delete this exception statement from your version.
- */
-
-package com.redhat.thermostat.storage.internal.dao;
-
-import java.io.IOException;
-import java.io.UnsupportedEncodingException;
-import java.net.URI;
-import java.net.URLEncoder;
-import java.util.Arrays;
-import java.util.List;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.TimeoutException;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-import org.eclipse.jetty.client.HttpClient;
-import org.eclipse.jetty.client.HttpContentResponse;
-import org.eclipse.jetty.client.HttpRequest;
-import org.eclipse.jetty.client.api.ContentResponse;
-import org.eclipse.jetty.client.api.Request;
-import org.eclipse.jetty.client.util.StringContentProvider;
-import org.eclipse.jetty.http.HttpMethod;
-import org.eclipse.jetty.http.HttpStatus;
-
-import com.redhat.thermostat.common.utils.LoggingUtils;
-import com.redhat.thermostat.storage.dao.NetworkInterfaceInfoDAO;
-import com.redhat.thermostat.storage.internal.dao.NetworkInterfaceInfoTypeAdapter.NetworkInterfaceInfoUpdateTypeAdapter;
-import com.redhat.thermostat.storage.model.NetworkInterfaceInfo;
-
-public class NetworkInterfaceInfoDAOImpl implements NetworkInterfaceInfoDAO {
-
-    private static final Logger logger = LoggingUtils.getLogger(NetworkInterfaceInfoDAOImpl.class);
-
-    private static final String GATEWAY_URL = "http://localhost:26000/api/v100"; // TODO configurable
-    private static final String GATEWAY_PATH = "/network-info/systems/*/agents/";
-    private static final String CONTENT_TYPE = "application/json";
-    private static final String GATEWAY_QUERY = "?q=";
-    private static final String QUERY_INTERFACE_PARAM = "interfaceName==";
-    
-    private final HttpHelper httpHelper;
-    private final JsonHelper jsonHelper;
-
-    public NetworkInterfaceInfoDAOImpl() throws Exception {
-        this(new HttpHelper(new HttpClient()), new JsonHelper(new NetworkInterfaceInfoTypeAdapter(), 
-                new NetworkInterfaceInfoUpdateTypeAdapter()));
-    }
-
-    NetworkInterfaceInfoDAOImpl(HttpHelper httpHelper, JsonHelper jsonHelper) throws Exception {
-        this.httpHelper = httpHelper;
-        this.jsonHelper = jsonHelper;
-        
-        this.httpHelper.startClient();
-    }
-
-    @Override
-    public void putNetworkInterfaceInfo(final NetworkInterfaceInfo info) {
-        try {
-            // Check if there is an existing entry for this interface
-            NetworkInterfaceInfo existing = getExistingInfo(info.getAgentId(), info.getInterfaceName());
-            if (existing == null) {
-                // Add a new network interface info record
-                addNetworkInterfaceInfo(info);
-            } else if (!existing.equals(info)) { // Check if update necessary
-                // Update existing record
-                updateNetworkInterfaceInfo(info);
-            }
-        } catch (IOException | InterruptedException | TimeoutException | ExecutionException e) {
-            logger.log(Level.WARNING, "Failed to query network interface information from web gateway", e);
-        }
-    }
-    
-    private NetworkInterfaceInfo getExistingInfo(String agentId, String interfaceName) throws InterruptedException, TimeoutException, ExecutionException, IOException {
-        NetworkInterfaceInfo result = null;
-        // Query NetworkInterfaceInfo with matching interface name
-        String url = getURLWithQueryString(agentId, interfaceName);
-        Request httpRequest = httpHelper.newRequest(url);
-        httpRequest.method(HttpMethod.GET);
-        ContentResponse response = sendRequest(httpRequest);
-        String json = response.getContentAsString();
-
-        // Return the first item, or null if there was no match
-        List<NetworkInterfaceInfo> infos = jsonHelper.fromJson(json);
-        if (!infos.isEmpty()) {
-            result = infos.get(0);
-        }
-        return result;
-    }
-    
-    private void addNetworkInterfaceInfo(NetworkInterfaceInfo info) {
-        try {
-            // Encode as JSON and send as POST request
-            String json = jsonHelper.toJson(Arrays.asList(info));
-            StringContentProvider provider = httpHelper.createContentProvider(json);
-            
-            String url = getURL(info.getAgentId());
-            Request httpRequest = httpHelper.newRequest(url);
-            httpRequest.method(HttpMethod.POST);
-            httpRequest.content(provider, CONTENT_TYPE);
-            sendRequest(httpRequest);
-        } catch (IOException | InterruptedException | TimeoutException | ExecutionException e) {
-           logger.log(Level.WARNING, "Failed to send network interface information to web gateway", e);
-        }
-    }
-    
-    private void updateNetworkInterfaceInfo(NetworkInterfaceInfo info) {
-        try {
-            // Encode as JSON and send as PUT request
-            NetworkInterfaceInfoUpdate update = new NetworkInterfaceInfoUpdate(info.getIp4Addr(), info.getIp6Addr());
-            String json = jsonHelper.toJson(update);
-            StringContentProvider provider = httpHelper.createContentProvider(json);
-            
-            String url = getURLWithQueryString(info.getAgentId(), info.getInterfaceName());
-            Request httpRequest = httpHelper.newRequest(url);
-            httpRequest.method(HttpMethod.PUT);
-            httpRequest.content(provider, CONTENT_TYPE);
-            sendRequest(httpRequest);
-        } catch (IOException | InterruptedException | TimeoutException | ExecutionException e) {
-           logger.log(Level.WARNING, "Failed to send network interface information update to web gateway", e);
-        }
-    }
-
-    private ContentResponse sendRequest(Request httpRequest)
-            throws InterruptedException, TimeoutException, ExecutionException, IOException {
-        ContentResponse resp = httpRequest.send();
-        int status = resp.getStatus();
-        if (status != HttpStatus.OK_200) {
-            throw new IOException("Gateway returned HTTP status " + String.valueOf(status) + " - " + resp.getReason());
-        }
-        return resp;
-    }
-    
-    private String getURL(String agentId) {
-        StringBuilder builder = buildURL(agentId);
-        return builder.toString();
-    }
-    
-    private String getURLWithQueryString(String agentId, String interfaceName) throws UnsupportedEncodingException {
-        StringBuilder builder = buildURL(agentId);
-        builder.append(GATEWAY_QUERY);
-        String query = QUERY_INTERFACE_PARAM.concat(interfaceName);
-        String encodedQuery = URLEncoder.encode(query, "UTF-8");
-        builder.append(encodedQuery);
-        return builder.toString();
-    }
-
-    private StringBuilder buildURL(String agentId) {
-        StringBuilder builder = new StringBuilder();
-        builder.append(GATEWAY_URL);
-        builder.append(GATEWAY_PATH);
-        builder.append(agentId);
-        return builder;
-    }
-    
-    static class NetworkInterfaceInfoUpdate {
-        
-        private final String ipv4Addr;
-        private final String ipv6Addr;
-        
-        public NetworkInterfaceInfoUpdate(String ipv4Addr, String ipv6Addr) {
-            this.ipv4Addr = ipv4Addr;
-            this.ipv6Addr = ipv6Addr;
-        }
-        
-        String getIPv4Addr() {
-            return ipv4Addr;
-        }
-        
-        String getIPv6Addr() {
-            return ipv6Addr;
-        }
-        
-    }
-    
-    // For testing purposes
-    static class JsonHelper {
-        
-        private final NetworkInterfaceInfoTypeAdapter typeAdapter;
-        private final NetworkInterfaceInfoUpdateTypeAdapter updateTypeAdapter;
-        
-        public JsonHelper(NetworkInterfaceInfoTypeAdapter typeAdapter, NetworkInterfaceInfoUpdateTypeAdapter updateTypeAdapter) {
-            this.typeAdapter = typeAdapter;
-            this.updateTypeAdapter = updateTypeAdapter;
-        }
-        
-        List<NetworkInterfaceInfo> fromJson(String json) throws IOException {
-            return typeAdapter.fromJson(json);
-        }
-        
-        String toJson(List<NetworkInterfaceInfo> infos) throws IOException {
-            return typeAdapter.toJson(infos);
-        }
-        
-        String toJson(NetworkInterfaceInfoUpdate update) throws IOException {
-            return updateTypeAdapter.toJson(update);
-        }
-        
-    }
-    
-    // For testing purposes
-    static class HttpHelper {
-        
-        private final HttpClient httpClient;
-
-        HttpHelper(HttpClient httpClient) {
-            this.httpClient = httpClient;
-        }
-        
-        void startClient() throws Exception {
-            httpClient.start();
-        }
-        
-        StringContentProvider createContentProvider(String content) {
-            return new StringContentProvider(content);
-        }
-        
-        Request newRequest(String url) {
-            return new MockRequest(httpClient, URI.create(url));
-        }
-        
-    }
-    
-    // FIXME This class should be removed when the web gateway has a microservice for this DAO
-    private static class MockRequest extends HttpRequest {
-
-        MockRequest(HttpClient client, URI uri) {
-            super(client, uri);
-        }
-        
-        @Override
-        public ContentResponse send() throws InterruptedException, TimeoutException, ExecutionException {
-            return new MockResponse();
-        }
-        
-    }
-    
-    // FIXME This class should be removed when the web gateway has a microservice for this DAO
-    private static class MockResponse extends HttpContentResponse {
-
-        MockResponse() {
-            super(null, null, null);
-        }
-        
-        @Override
-        public int getStatus() {
-            return HttpStatus.OK_200;
-        }
-        
-        @Override
-        public String getContentAsString() {
-            // Simulate empty response
-            return "{\"response\" : [], \"time\" : \"0\"}";
-        }
-        
-    }
-}
-
--- a/storage/core/src/main/java/com/redhat/thermostat/storage/internal/dao/NetworkInterfaceInfoTypeAdapter.java	Wed Jul 05 14:29:14 2017 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,210 +0,0 @@
-/*
- * Copyright 2012-2017 Red Hat, Inc.
- *
- * This file is part of Thermostat.
- *
- * Thermostat is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2, or (at your
- * option) any later version.
- *
- * Thermostat is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Thermostat; see the file COPYING.  If not see
- * <http://www.gnu.org/licenses/>.
- *
- * Linking this code with other modules is making a combined work
- * based on this code.  Thus, the terms and conditions of the GNU
- * General Public License cover the whole combination.
- *
- * As a special exception, the copyright holders of this code give
- * you permission to link this code with independent modules to
- * produce an executable, regardless of the license terms of these
- * independent modules, and to copy and distribute the resulting
- * executable under terms of your choice, provided that you also
- * meet, for each linked independent module, the terms and conditions
- * of the license of that module.  An independent module is a module
- * which is not derived from or based on this code.  If you modify
- * this code, you may extend this exception to your version of the
- * library, but you are not obligated to do so.  If you do not wish
- * to do so, delete this exception statement from your version.
- */
-
-package com.redhat.thermostat.storage.internal.dao;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-
-import com.google.gson.TypeAdapter;
-import com.google.gson.stream.JsonReader;
-import com.google.gson.stream.JsonToken;
-import com.google.gson.stream.JsonWriter;
-import com.redhat.thermostat.storage.internal.dao.NetworkInterfaceInfoDAOImpl.NetworkInterfaceInfoUpdate;
-import com.redhat.thermostat.storage.model.NetworkInterfaceInfo;
-
-public class NetworkInterfaceInfoTypeAdapter extends TypeAdapter<List<NetworkInterfaceInfo>> {
-    
-    private static final String AGENT_ID = "agentId";
-    private static final String INTERFACE_NAME = "interfaceName";
-    private static final String IP4_ADDR = "ip4Addr";
-    private static final String IP6_ADDR = "ip6Addr";
-    private static final String RESPONSE_ROOT = "response";
-    private static final String SERVER_TIME = "time";
-    
-    @Override
-    public void write(JsonWriter out, List<NetworkInterfaceInfo> value) throws IOException {
-        // Request is an array of NetworkInterfaceInfo objects
-        out.beginArray();
-        
-        for (NetworkInterfaceInfo info : value) {
-            writeNetworkInterfaceInfo(out, info);
-        }
-        
-        out.endArray();
-    }
-
-    private void writeNetworkInterfaceInfo(JsonWriter out, NetworkInterfaceInfo info) throws IOException {
-        out.beginObject();
-        
-        // Write each field of NetworkInterfaceInfo as part of a JSON object
-        out.name(AGENT_ID);
-        out.value(info.getAgentId());
-        out.name(INTERFACE_NAME);
-        out.value(info.getInterfaceName());
-        out.name(IP4_ADDR);
-        out.value(info.getIp4Addr());
-        out.name(IP6_ADDR);
-        out.value(info.getIp6Addr());
-        
-        out.endObject();
-    }
-
-    @Override
-    public List<NetworkInterfaceInfo> read(JsonReader in) throws IOException {
-        List<NetworkInterfaceInfo> infos = null;
-        
-        try {
-            // Parse root object
-            in.beginObject();
-            while (in.hasNext()) {
-                String name = in.nextName();
-                switch (name) {
-                case RESPONSE_ROOT:
-                    infos = readResponse(in);
-                    break;
-                case SERVER_TIME:
-                    in.nextString();
-                    break;
-                default:
-                    throw new IOException("Unexpected JSON name in gateway response: '" + name + "'");
-                }
-            }
-            in.endObject();
-        } catch (IllegalStateException e) {
-            throw new IOException("Reading JSON response from web gateway failed", e);
-        }
-        
-        return infos;
-    }
-    
-    private List<NetworkInterfaceInfo> readResponse(JsonReader in) throws IOException {
-        List<NetworkInterfaceInfo> infos = new ArrayList<>();
-        
-        // Parse array of NetworkInterfaceInfos
-        in.beginArray();
-        
-        while (in.hasNext()) {
-            NetworkInterfaceInfo info = readNetworkInterfaceInfo(in);
-            infos.add(info);
-        }
-        in.endArray();
-        
-        return infos;
-    }
-    
-    private NetworkInterfaceInfo readNetworkInterfaceInfo(JsonReader in) throws IOException {
-        String agentId = null;
-        String interfaceName = null;
-        String ipv4Addr = null;
-        String ipv6Addr = null;
-        
-        // Begin parsing a NetworkInterfaceInfo record
-        in.beginObject();
-        
-        while (in.hasNext()) {
-            String name = in.nextName();
-            switch (name) {
-            case AGENT_ID:
-                agentId = in.nextString();
-                break;
-            case INTERFACE_NAME:
-                interfaceName = in.nextString();
-                break;
-            case IP4_ADDR: // Addresses may be null
-                ipv4Addr = readStringOrNull(in);
-                break;
-            case IP6_ADDR:
-                ipv6Addr = readStringOrNull(in);
-                break;
-            default:
-                throw new IOException("Unexpected JSON name in record: '" + name + "'");
-            }
-        }
-        
-        in.endObject();
-        
-        // Create NetworkInterfaceInfo if all required fields present
-        if (agentId == null || interfaceName == null) {
-            throw new IOException("Network interface information record is incomplete");
-        }
-        NetworkInterfaceInfo result = new NetworkInterfaceInfo(agentId, interfaceName);
-        result.setIp4Addr(ipv4Addr);
-        result.setIp6Addr(ipv6Addr);
-        
-        return result;
-    }
-    
-    private String readStringOrNull(JsonReader in) throws IOException {
-        String result = null;
-        JsonToken token = in.peek();
-        if (token == JsonToken.NULL) {
-            in.nextNull();
-        } else {
-            result = in.nextString();
-        }
-        return result;
-    }
-    
-    static class NetworkInterfaceInfoUpdateTypeAdapter extends TypeAdapter<NetworkInterfaceInfoUpdate> {
-        
-        private static final String SET = "set";
-
-        @Override
-        public void write(JsonWriter out, NetworkInterfaceInfoUpdate value) throws IOException {
-            // List fields to update as part of a JSON object with name "set"
-            out.beginObject();
-            out.name(SET);
-            
-            out.beginObject();
-            out.name(IP4_ADDR);
-            out.value(value.getIPv4Addr());
-            out.name(IP6_ADDR);
-            out.value(value.getIPv6Addr());
-            out.endObject();
-            
-            out.endObject();
-        }
-
-        @Override
-        public NetworkInterfaceInfoUpdate read(JsonReader in) throws IOException {
-            throw new UnsupportedOperationException();
-        }
-        
-    }
-    
-}
--- a/storage/core/src/main/java/com/redhat/thermostat/storage/model/NetworkInterfaceInfo.java	Wed Jul 05 14:29:14 2017 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,118 +0,0 @@
-/*
- * Copyright 2012-2017 Red Hat, Inc.
- *
- * This file is part of Thermostat.
- *
- * Thermostat is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2, or (at your
- * option) any later version.
- *
- * Thermostat is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Thermostat; see the file COPYING.  If not see
- * <http://www.gnu.org/licenses/>.
- *
- * Linking this code with other modules is making a combined work
- * based on this code.  Thus, the terms and conditions of the GNU
- * General Public License cover the whole combination.
- *
- * As a special exception, the copyright holders of this code give
- * you permission to link this code with independent modules to
- * produce an executable, regardless of the license terms of these
- * independent modules, and to copy and distribute the resulting
- * executable under terms of your choice, provided that you also
- * meet, for each linked independent module, the terms and conditions
- * of the license of that module.  An independent module is a module
- * which is not derived from or based on this code.  If you modify
- * this code, you may extend this exception to your version of the
- * library, but you are not obligated to do so.  If you do not wish
- * to do so, delete this exception statement from your version.
- */
-
-package com.redhat.thermostat.storage.model;
-
-import java.util.Objects;
-
-import com.redhat.thermostat.storage.core.Entity;
-import com.redhat.thermostat.storage.core.Persist;
-
-@Entity
-public class NetworkInterfaceInfo extends BasePojo {
-
-    private String iFace;
-    private String ip4Addr;
-    private String ip6Addr;
-
-    public NetworkInterfaceInfo() {
-        this(null, null);
-    }
-
-    public NetworkInterfaceInfo(String writerId, String iFace) {
-        super(writerId);
-        this.iFace = iFace;
-        this.ip4Addr = null;
-        this.ip6Addr = null;
-    }
-
-    @Persist
-    public String getInterfaceName() {
-        return iFace;
-    }
-
-    @Persist
-    public void setInterfaceName(String iFace) {
-        this.iFace = iFace;
-    }
-
-    @Persist
-    public String getIp4Addr() {
-        return ip4Addr;
-    }
-
-    @Persist
-    public void setIp4Addr(String newAddr) {
-        ip4Addr = newAddr;
-    }
-
-    public void clearIp4Addr() {
-        ip4Addr = null;
-    }
-
-    @Persist
-    public String getIp6Addr() {
-        return ip6Addr;
-    }
-
-    @Persist
-    public void setIp6Addr(String newAddr) {
-        ip6Addr = newAddr;
-    }
-
-    public void clearIp6Addr() {
-        ip6Addr = null;
-    }
-    
-    @Override
-    public boolean equals(Object obj) {
-        // Super implementation should check for class and agentId equality and check for null
-        boolean equal = super.equals(obj);
-        if (equal) {
-            NetworkInterfaceInfo other = (NetworkInterfaceInfo) obj;
-            equal = Objects.equals(iFace, other.iFace) && Objects.equals(ip4Addr, other.ip4Addr)
-                    && Objects.equals(ip6Addr, other.ip6Addr);
-        }
-        return equal;
-    }
-    
-    @Override
-    public int hashCode() {
-        // Super implementation should hash agentId
-        return Objects.hash(super.hashCode(), iFace, ip4Addr, ip6Addr);
-    }
-}
-
--- a/storage/core/src/test/java/com/redhat/thermostat/storage/internal/ActivatorTest.java	Wed Jul 05 14:29:14 2017 -0400
+++ b/storage/core/src/test/java/com/redhat/thermostat/storage/internal/ActivatorTest.java	Thu Jul 06 13:05:47 2017 -0400
@@ -43,8 +43,6 @@
 import org.junit.Test;
 
 import com.redhat.thermostat.storage.core.WriterID;
-import com.redhat.thermostat.storage.dao.NetworkInterfaceInfoDAO;
-import com.redhat.thermostat.storage.internal.dao.NetworkInterfaceInfoDAOImpl;
 import com.redhat.thermostat.testutils.StubBundleContext;
 
 public class ActivatorTest {
@@ -57,7 +55,6 @@
         activator.start(context);
 
         assertTrue(context.isServiceRegistered(WriterID.class.getName(), WriterIDImpl.class));
-        assertTrue(context.isServiceRegistered(NetworkInterfaceInfoDAO.class.getName(), NetworkInterfaceInfoDAOImpl.class));
 
         activator.stop(context);
 
@@ -74,8 +71,7 @@
         activator.start(context);
 
         activator.stop(context);
-        
-        assertFalse(context.isServiceRegistered(NetworkInterfaceInfoDAO.class.getName(), NetworkInterfaceInfoDAOImpl.class));
+
         assertFalse(context.isServiceRegistered(WriterID.class.getName(), WriterIDImpl.class));
         
         assertEquals(0, context.getServiceListeners().size());
@@ -90,9 +86,8 @@
 
         activator.start(context);
 
-        assertTrue(context.isServiceRegistered(NetworkInterfaceInfoDAO.class.getName(), NetworkInterfaceInfoDAOImpl.class));
         assertTrue(context.isServiceRegistered(WriterID.class.getName(), WriterIDImpl.class));
-        assertEquals(2, context.getAllServices().size());
+        assertEquals(1, context.getAllServices().size());
 
         activator.stop(context);
         
@@ -101,9 +96,8 @@
         
         activator.start(context);
 
-        assertTrue(context.isServiceRegistered(NetworkInterfaceInfoDAO.class.getName(), NetworkInterfaceInfoDAOImpl.class));
         assertTrue(context.isServiceRegistered(WriterID.class.getName(), WriterIDImpl.class));
-        assertEquals(2, context.getAllServices().size());
+        assertEquals(1, context.getAllServices().size());
 
         activator.stop(context);
 
--- a/storage/core/src/test/java/com/redhat/thermostat/storage/internal/dao/NetworkInterfaceInfoDAOTest.java	Wed Jul 05 14:29:14 2017 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,186 +0,0 @@
-/*
- * Copyright 2012-2017 Red Hat, Inc.
- *
- * This file is part of Thermostat.
- *
- * Thermostat is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2, or (at your
- * option) any later version.
- *
- * Thermostat is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Thermostat; see the file COPYING.  If not see
- * <http://www.gnu.org/licenses/>.
- *
- * Linking this code with other modules is making a combined work
- * based on this code.  Thus, the terms and conditions of the GNU
- * General Public License cover the whole combination.
- *
- * As a special exception, the copyright holders of this code give
- * you permission to link this code with independent modules to
- * produce an executable, regardless of the license terms of these
- * independent modules, and to copy and distribute the resulting
- * executable under terms of your choice, provided that you also
- * meet, for each linked independent module, the terms and conditions
- * of the license of that module.  An independent module is a module
- * which is not derived from or based on this code.  If you modify
- * this code, you may extend this exception to your version of the
- * library, but you are not obligated to do so.  If you do not wish
- * to do so, delete this exception statement from your version.
- */
-
-package com.redhat.thermostat.storage.internal.dao;
-
-import static org.junit.Assert.assertEquals;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyListOf;
-import static org.mockito.Matchers.anyString;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-
-import org.eclipse.jetty.client.api.ContentResponse;
-import org.eclipse.jetty.client.api.Request;
-import org.eclipse.jetty.client.util.StringContentProvider;
-import org.eclipse.jetty.http.HttpMethod;
-import org.eclipse.jetty.http.HttpStatus;
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.ArgumentCaptor;
-
-import com.redhat.thermostat.storage.dao.NetworkInterfaceInfoDAO;
-import com.redhat.thermostat.storage.internal.dao.NetworkInterfaceInfoDAOImpl.HttpHelper;
-import com.redhat.thermostat.storage.internal.dao.NetworkInterfaceInfoDAOImpl.JsonHelper;
-import com.redhat.thermostat.storage.internal.dao.NetworkInterfaceInfoDAOImpl.NetworkInterfaceInfoUpdate;
-import com.redhat.thermostat.storage.model.NetworkInterfaceInfo;
-
-public class NetworkInterfaceInfoDAOTest {
-
-    private static final String URL = "http://localhost:26000/api/v100/network-info/systems/*/agents/fooAgent";
-    private static final String QUERY_URL = URL + "?q=interfaceName%3D%3Dsome+interface.+maybe+eth0";
-    private static final String INTERFACE_NAME = "some interface. maybe eth0";
-    private static final String IPV4_ADDR = "256.256.256.256";
-    private static final String IPV6_ADDR = "100:100:100::::1";
-    private static final String SOME_JSON = "{\"some\" : \"json\"}";
-    private static final String SOME_OTHER_JSON = "{\"some\" : {\"other\" : \"json\"}}";
-    private static final String EMPTY_JSON = "{}";
-    private static final String CONTENT_TYPE = "application/json";
-
-    private NetworkInterfaceInfo info;
-    private JsonHelper jsonHelper;
-    private HttpHelper httpHelper;
-    private StringContentProvider contentProvider;
-    private Request request;
-    private ContentResponse response;
-    
-    @Before
-    public void setup() throws Exception {
-        info = new NetworkInterfaceInfo("fooAgent", INTERFACE_NAME);
-        info.setIp4Addr(IPV4_ADDR);
-        info.setIp6Addr(IPV6_ADDR);
-        
-        httpHelper = mock(HttpHelper.class);
-        contentProvider = mock(StringContentProvider.class);
-        when(httpHelper.createContentProvider(anyString())).thenReturn(contentProvider);
-        request = mock(Request.class);
-        when(httpHelper.newRequest(anyString())).thenReturn(request);
-        response = mock(ContentResponse.class);
-        when(response.getStatus()).thenReturn(HttpStatus.OK_200);
-        when(request.send()).thenReturn(response);
-        
-        jsonHelper = mock(JsonHelper.class);
-        when(jsonHelper.toJson(anyListOf(NetworkInterfaceInfo.class))).thenReturn(SOME_JSON);
-        when(jsonHelper.toJson(any(NetworkInterfaceInfoUpdate.class))).thenReturn(SOME_OTHER_JSON);
-        List<NetworkInterfaceInfo> emptyList = Collections.emptyList(); 
-        when(jsonHelper.fromJson(EMPTY_JSON)).thenReturn(emptyList);
-        when(jsonHelper.fromJson(SOME_JSON)).thenReturn(Arrays.asList(info));
-    }
-
-    @Test
-    public void testPutNetworkInterfaceInfoAdd() throws Exception {
-        NetworkInterfaceInfoDAO dao = new NetworkInterfaceInfoDAOImpl(httpHelper, jsonHelper);
-        when(response.getContentAsString()).thenReturn(EMPTY_JSON);
-        dao.putNetworkInterfaceInfo(info);
-        
-        // Check query first
-        verify(httpHelper).newRequest(QUERY_URL);
-        verify(request).method(HttpMethod.GET);
-        verify(jsonHelper).fromJson(EMPTY_JSON);
-
-        // Check data added
-        verify(httpHelper).newRequest(URL);
-        verify(request).method(HttpMethod.POST);
-        verify(jsonHelper).toJson(eq(Arrays.asList(info)));
-        verify(httpHelper).createContentProvider(SOME_JSON);
-        verify(request).content(contentProvider, CONTENT_TYPE);
-        
-        verify(request, times(2)).send();
-        verify(response, times(2)).getStatus();
-    }
-    
-    @Test
-    public void testPutNetworkInterfaceInfoUpdate() throws Exception {
-        NetworkInterfaceInfoDAO dao = new NetworkInterfaceInfoDAOImpl(httpHelper, jsonHelper);
-        
-        when(response.getContentAsString()).thenReturn(SOME_JSON);
-        NetworkInterfaceInfo other = new NetworkInterfaceInfo("fooAgent", INTERFACE_NAME);
-        other.setIp4Addr("1.2.3.4");
-        other.setIp6Addr(IPV6_ADDR);
-        when(jsonHelper.fromJson(SOME_JSON)).thenReturn(Arrays.asList(other));
-        dao.putNetworkInterfaceInfo(info);
-        
-        // Check query first
-        verify(request).method(HttpMethod.GET);
-        verify(jsonHelper).fromJson(SOME_JSON);
-
-        // Check data updated
-        verify(httpHelper, times(2)).newRequest(QUERY_URL);
-        verify(request).method(HttpMethod.PUT);
-        
-        ArgumentCaptor<NetworkInterfaceInfoUpdate> updateCaptor = ArgumentCaptor.forClass(NetworkInterfaceInfoUpdate.class);
-        verify(jsonHelper).toJson(updateCaptor.capture());
-        NetworkInterfaceInfoUpdate update = updateCaptor.getValue();
-        assertEquals(IPV4_ADDR, update.getIPv4Addr());
-        assertEquals(IPV6_ADDR, update.getIPv6Addr());
-        
-        verify(httpHelper).createContentProvider(SOME_OTHER_JSON);
-        verify(request).content(contentProvider, CONTENT_TYPE);
-        
-        verify(request, times(2)).send();
-        verify(response, times(2)).getStatus();
-    }
-
-    @Test
-    public void testPutNetworkInterfaceInfoNoUpdate() throws Exception {
-        NetworkInterfaceInfoDAO dao = new NetworkInterfaceInfoDAOImpl(httpHelper, jsonHelper);
-        
-        when(response.getContentAsString()).thenReturn(SOME_JSON);
-        dao.putNetworkInterfaceInfo(info);
-        
-        // Check query first
-        verify(httpHelper).newRequest(QUERY_URL);
-        verify(request).method(HttpMethod.GET);
-        verify(jsonHelper).fromJson(SOME_JSON);
-        verify(request).send();
-        verify(response).getStatus();
-
-        // Check no update sent
-        verify(request, never()).method(HttpMethod.PUT);
-        verify(jsonHelper, never()).toJson(any(NetworkInterfaceInfoUpdate.class));
-        verify(httpHelper, never()).createContentProvider(SOME_OTHER_JSON);
-        verify(request, never()).content(contentProvider, CONTENT_TYPE);
-    }
-}
-
--- a/storage/core/src/test/java/com/redhat/thermostat/storage/internal/dao/NetworkInterfaceInfoTypeAdapterTest.java	Wed Jul 05 14:29:14 2017 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,112 +0,0 @@
-/*
- * Copyright 2012-2017 Red Hat, Inc.
- *
- * This file is part of Thermostat.
- *
- * Thermostat is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2, or (at your
- * option) any later version.
- *
- * Thermostat is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Thermostat; see the file COPYING.  If not see
- * <http://www.gnu.org/licenses/>.
- *
- * Linking this code with other modules is making a combined work
- * based on this code.  Thus, the terms and conditions of the GNU
- * General Public License cover the whole combination.
- *
- * As a special exception, the copyright holders of this code give
- * you permission to link this code with independent modules to
- * produce an executable, regardless of the license terms of these
- * independent modules, and to copy and distribute the resulting
- * executable under terms of your choice, provided that you also
- * meet, for each linked independent module, the terms and conditions
- * of the license of that module.  An independent module is a module
- * which is not derived from or based on this code.  If you modify
- * this code, you may extend this exception to your version of the
- * library, but you are not obligated to do so.  If you do not wish
- * to do so, delete this exception statement from your version.
- */
-
-package com.redhat.thermostat.storage.internal.dao;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNull;
-
-import java.util.Arrays;
-import java.util.List;
-
-import org.junit.Test;
-
-import com.redhat.thermostat.storage.internal.dao.NetworkInterfaceInfoDAOImpl.NetworkInterfaceInfoUpdate;
-import com.redhat.thermostat.storage.internal.dao.NetworkInterfaceInfoTypeAdapter.NetworkInterfaceInfoUpdateTypeAdapter;
-import com.redhat.thermostat.storage.model.NetworkInterfaceInfo;
-
-public class NetworkInterfaceInfoTypeAdapterTest {
-    
-    @Test
-    public void testWrite() throws Exception {
-        NetworkInterfaceInfoTypeAdapter adapter = new NetworkInterfaceInfoTypeAdapter();
-        final String expected = "[{\"agentId\":\"agent1\",\"interfaceName\":\"lo\",\"ip4Addr\":\"127.0.0.1\","
-                + "\"ip6Addr\":\"0:0:0:0:0:0:0:1%lo\"},{\"agentId\":\"agent2\",\"interfaceName\":\"if1\","
-                + "\"ip4Addr\":\"1.2.3.4\",\"ip6Addr\":\"1:2:3:4:5:6:7:8%if1\"}]";
-        
-        NetworkInterfaceInfo first = createNetworkInterfaceInfo("agent1", "lo", "127.0.0.1", "0:0:0:0:0:0:0:1%lo");
-        NetworkInterfaceInfo second = createNetworkInterfaceInfo("agent2", "if1", "1.2.3.4", "1:2:3:4:5:6:7:8%if1");
-        List<NetworkInterfaceInfo> infos = Arrays.asList(first, second);
-        
-        String json = adapter.toJson(infos);
-        assertEquals(expected, json);
-    }
-    
-    @Test
-    public void testRead() throws Exception {
-        NetworkInterfaceInfoTypeAdapter adapter = new NetworkInterfaceInfoTypeAdapter();
-        final String json = "{\"response\" : [{\"agentId\" : \"agent1\", \"interfaceName\" : \"lo\", "
-                + "\"ip4Addr\" : \"127.0.0.1\", \"ip6Addr\" : \"0:0:0:0:0:0:0:1%lo\"}, "
-                + "{\"agentId\" : \"agent2\", \"interfaceName\" : \"if1\", "
-                + "\"ip4Addr\" : \"1.2.3.4\", \"ip6Addr\" : null}], "
-                + "\"time\" : \"500000000\"}";
-        
-        List<NetworkInterfaceInfo> infos = adapter.fromJson(json);
-        assertEquals(2, infos.size());
-        
-        NetworkInterfaceInfo first = infos.get(0);
-        assertEquals("agent1", first.getAgentId());
-        assertEquals("lo", first.getInterfaceName());
-        assertEquals("127.0.0.1", first.getIp4Addr());
-        assertEquals("0:0:0:0:0:0:0:1%lo", first.getIp6Addr());
-        
-        NetworkInterfaceInfo second = infos.get(1);
-        assertEquals("agent2", second.getAgentId());
-        assertEquals("if1", second.getInterfaceName());
-        assertEquals("1.2.3.4", second.getIp4Addr());
-        assertNull(second.getIp6Addr());
-    }
-    
-    @Test
-    public void testUpdate() throws Exception {
-        NetworkInterfaceInfoUpdateTypeAdapter adapter = new NetworkInterfaceInfoUpdateTypeAdapter();
-        final String expected = "{\"set\":{\"ip4Addr\":\"1.2.3.4\",\"ip6Addr\":\"1:2:3:4:5:6:7:8%if0\"}}";
-        
-        NetworkInterfaceInfoUpdate update = new NetworkInterfaceInfoUpdate("1.2.3.4", "1:2:3:4:5:6:7:8%if0");
-        
-        String json = adapter.toJson(update);
-        assertEquals(expected, json);
-    }
-    
-    private NetworkInterfaceInfo createNetworkInterfaceInfo(String agentId, String iFace, String ip4Addr, 
-            String ip6Addr) {
-        NetworkInterfaceInfo info = new NetworkInterfaceInfo(agentId, iFace);
-        info.setIp4Addr(ip4Addr);
-        info.setIp6Addr(ip6Addr);
-        return info;
-    }
-
-}
--- a/storage/core/src/test/java/com/redhat/thermostat/storage/model/NetworkInterfaceInfoTest.java	Wed Jul 05 14:29:14 2017 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,121 +0,0 @@
-/*
- * Copyright 2012-2017 Red Hat, Inc.
- *
- * This file is part of Thermostat.
- *
- * Thermostat is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2, or (at your
- * option) any later version.
- *
- * Thermostat is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Thermostat; see the file COPYING.  If not see
- * <http://www.gnu.org/licenses/>.
- *
- * Linking this code with other modules is making a combined work
- * based on this code.  Thus, the terms and conditions of the GNU
- * General Public License cover the whole combination.
- *
- * As a special exception, the copyright holders of this code give
- * you permission to link this code with independent modules to
- * produce an executable, regardless of the license terms of these
- * independent modules, and to copy and distribute the resulting
- * executable under terms of your choice, provided that you also
- * meet, for each linked independent module, the terms and conditions
- * of the license of that module.  An independent module is a module
- * which is not derived from or based on this code.  If you modify
- * this code, you may extend this exception to your version of the
- * library, but you are not obligated to do so.  If you do not wish
- * to do so, delete this exception statement from your version.
- */
-
-package com.redhat.thermostat.storage.model;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
-import org.junit.Before;
-import org.junit.Test;
-
-public class NetworkInterfaceInfoTest {
-    
-    private NetworkInterfaceInfo info;
-    
-    @Before
-    public void setup() {
-        info = createInfo("agent1", "if1", "1.2.3.4", "1:2:3:4:5:6:7:8");
-    }
-
-    @Test
-    public void testEquals() {
-        NetworkInterfaceInfo other = createInfo("agent1", "if1", "1.2.3.4", "1:2:3:4:5:6:7:8");
-        assertTrue(info.equals(other));
-    }
-    
-    @Test
-    public void testEqualsWrongAgentId() {
-        NetworkInterfaceInfo other = createInfo("agent2", "if1", "1.2.3.4", "1:2:3:4:5:6:7:8");
-        assertFalse(info.equals(other));
-    }
-    
-    @Test
-    public void testEqualsWrongInterface() {
-        NetworkInterfaceInfo other = createInfo("agent1", "if2", "1.2.3.4", "1:2:3:4:5:6:7:8");
-        assertFalse(info.equals(other));
-    }
-    
-    @Test
-    public void testEqualsWrongIpV4() {
-        NetworkInterfaceInfo other = createInfo("agent1", "if1", "1.2.3.5", "1:2:3:4:5:6:7:8");
-        assertFalse(info.equals(other));
-    }
-    
-    @Test
-    public void testEqualsWrongIpV6() {
-        NetworkInterfaceInfo other = createInfo("agent1", "if1", "1.2.3.4", "1:2:3:4:5:6:7:9");
-        assertFalse(info.equals(other));
-    }
-    
-    @Test
-    public void testHashCode() {
-        NetworkInterfaceInfo other = createInfo("agent1", "if1", "1.2.3.4", "1:2:3:4:5:6:7:8");
-        assertEquals(info.hashCode(), other.hashCode());
-    }
-    
-    @Test
-    public void testHashCodeWrongAgentId() {
-        NetworkInterfaceInfo other = createInfo("agent2", "if1", "1.2.3.4", "1:2:3:4:5:6:7:8");
-        assertFalse(info.hashCode() == other.hashCode());
-    }
-    
-    @Test
-    public void testHashCodeWrongInterface() {
-        NetworkInterfaceInfo other = createInfo("agent1", "if2", "1.2.3.4", "1:2:3:4:5:6:7:8");
-        assertFalse(info.hashCode() == other.hashCode());
-    }
-    
-    @Test
-    public void testHashCodeWrongIpV4() {
-        NetworkInterfaceInfo other = createInfo("agent1", "if1", "1.2.3.5", "1:2:3:4:5:6:7:8");
-        assertFalse(info.hashCode() == other.hashCode());
-    }
-    
-    @Test
-    public void testHashCodeWrongIpV6() {
-        NetworkInterfaceInfo other = createInfo("agent1", "if1", "1.2.3.4", "1:2:3:4:5:6:7:9");
-        assertFalse(info.hashCode() == other.hashCode());
-    }
-
-    private NetworkInterfaceInfo createInfo(String agentId, String iFace, String ip4Addr, String ip6Addr) {
-        NetworkInterfaceInfo info = new NetworkInterfaceInfo(agentId, iFace);
-        info.setIp4Addr(ip4Addr);
-        info.setIp6Addr(ip6Addr);
-        return info;
-    }
-}
--- a/storage/core/src/test/java/com/redhat/thermostat/storage/model/PojoModelInstantiationTest.java	Wed Jul 05 14:29:14 2017 -0400
+++ b/storage/core/src/test/java/com/redhat/thermostat/storage/model/PojoModelInstantiationTest.java	Thu Jul 06 13:05:47 2017 -0400
@@ -43,7 +43,6 @@
     private static final Class<?>[] CLASSES_LIST = new Class[] {
         AgentInformation.class,
         BackendInformation.class,
-        NetworkInterfaceInfo.class,
     };
 
     @Override
--- a/system-backend/pom.xml	Wed Jul 05 14:29:14 2017 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,173 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-
- Copyright 2012-2017 Red Hat, Inc.
-
- This file is part of Thermostat.
-
- Thermostat is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 2, or (at your
- option) any later version.
-
- Thermostat is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Thermostat; see the file COPYING.  If not see
- <http://www.gnu.org/licenses/>.
-
- Linking this code with other modules is making a combined work
- based on this code.  Thus, the terms and conditions of the GNU
- General Public License cover the whole combination.
-
- As a special exception, the copyright holders of this code give
- you permission to link this code with independent modules to
- produce an executable, regardless of the license terms of these
- independent modules, and to copy and distribute the resulting
- executable under terms of your choice, provided that you also
- meet, for each linked independent module, the terms and conditions
- of the license of that module.  An independent module is a module
- which is not derived from or based on this code.  If you modify
- this code, you may extend this exception to your version of the
- library, but you are not obligated to do so.  If you do not wish
- to do so, delete this exception statement from your version.
-
--->
-<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>com.redhat.thermostat</groupId>
-    <artifactId>thermostat</artifactId>
-    <version>1.99.12-SNAPSHOT</version>
-  </parent>
-
-  <artifactId>thermostat-system-backend</artifactId>
-  <packaging>bundle</packaging>
-
-  <name>Thermostat System Backend</name>
-
-  <dependencies>
-    <dependency>
-      <groupId>junit</groupId>
-      <artifactId>junit</artifactId>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.mockito</groupId>
-      <artifactId>mockito-core</artifactId>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>com.redhat.thermostat</groupId>
-      <artifactId>thermostat-common-test</artifactId>
-      <version>${project.version}</version>
-      <scope>test</scope>
-    </dependency>
-
-    <dependency>
-      <groupId>com.redhat.thermostat</groupId>
-      <artifactId>thermostat-common-portability</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-
-    <dependency>
-      <groupId>com.redhat.thermostat</groupId>
-      <artifactId>thermostat-common-core</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-       
-    <dependency>
-      <groupId>com.redhat.thermostat</groupId>
-      <artifactId>thermostat-agent-core</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    
-    <dependency>
-      <groupId>com.redhat.thermostat</groupId>
-      <artifactId>thermostat-storage-core</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    
-    <dependency>
-      <groupId>org.osgi</groupId>
-      <artifactId>org.osgi.core</artifactId>
-      <scope>provided</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.osgi</groupId>
-      <artifactId>org.osgi.compendium</artifactId>
-      <scope>provided</scope>
-    </dependency>
-
-  </dependencies>
-
-  <build>
-    <plugins>
-      <plugin>
-        <groupId>org.apache.felix</groupId>
-        <artifactId>maven-bundle-plugin</artifactId>
-        <extensions>true</extensions>
-        <configuration>
-          <instructions>
-            <Bundle-Vendor>Red Hat, Inc.</Bundle-Vendor>
-            <Bundle-Activator>com.redhat.thermostat.backend.system.internal.SystemBackendActivator</Bundle-Activator>
-            <Bundle-SymbolicName>com.redhat.thermostat.backend.system</Bundle-SymbolicName>
-            <Private-Package>
-              com.redhat.thermostat.backend.system.internal,
-              com.redhat.thermostat.backend.system.internal.linux,
-              com.redhat.thermostat.backend.system.internal.windows,
-              com.redhat.thermostat.backend.system.internal.models
-            </Private-Package>
-            <!-- Do not autogenerate uses clauses in Manifests -->
-            <_nouses>true</_nouses>
-          </instructions>
-        </configuration>
-      </plugin>
-
-
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-resources-plugin</artifactId>
-        <executions>
-          <execution>
-            <id>copy</id>
-            <phase>generate-resources</phase>
-            <goals>
-              <goal>copy-resources</goal>
-            </goals>
-            <configuration>
-              <overwrite>true</overwrite>
-              <outputDirectory>${project.build.directory}</outputDirectory>
-              <resources>
-                <resource>
-                  <directory>../common/portability/target</directory>
-                  <includes>
-                    <include>${sharedlib.prefix}thermostat-common-portability${sharedlib.suffix}</include>
-                  </includes>
-                </resource>
-              </resources>
-            </configuration>
-          </execution>
-        </executions>
-      </plugin>
-
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-          <artifactId>maven-surefire-plugin</artifactId>
-          <configuration>
-            <!-- the test needs to link to common-portability native libraries -->
-            <systemPropertyVariables>
-              <com.redhat.thermostat.shared.loader.testNativesHome>${project.build.directory}</com.redhat.thermostat.shared.loader.testNativesHome>
-            </systemPropertyVariables>            
-          </configuration>
-      </plugin>      
-      
-    </plugins>
-  </build>
-
-</project>
-
--- a/system-backend/src/main/java/com/redhat/thermostat/backend/system/internal/NetworkInfoBuilder.java	Wed Jul 05 14:29:14 2017 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,100 +0,0 @@
-/*
- * Copyright 2012-2017 Red Hat, Inc.
- *
- * This file is part of Thermostat.
- *
- * Thermostat is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2, or (at your
- * option) any later version.
- *
- * Thermostat is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Thermostat; see the file COPYING.  If not see
- * <http://www.gnu.org/licenses/>.
- *
- * Linking this code with other modules is making a combined work
- * based on this code.  Thus, the terms and conditions of the GNU
- * General Public License cover the whole combination.
- *
- * As a special exception, the copyright holders of this code give
- * you permission to link this code with independent modules to
- * produce an executable, regardless of the license terms of these
- * independent modules, and to copy and distribute the resulting
- * executable under terms of your choice, provided that you also
- * meet, for each linked independent module, the terms and conditions
- * of the license of that module.  An independent module is a module
- * which is not derived from or based on this code.  If you modify
- * this code, you may extend this exception to your version of the
- * library, but you are not obligated to do so.  If you do not wish
- * to do so, delete this exception statement from your version.
- */
-
-package com.redhat.thermostat.backend.system.internal;
-
-import java.net.Inet4Address;
-import java.net.Inet6Address;
-import java.net.InetAddress;
-import java.net.NetworkInterface;
-import java.net.SocketException;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Enumeration;
-import java.util.List;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-import com.redhat.thermostat.common.utils.LoggingUtils;
-import com.redhat.thermostat.storage.core.WriterID;
-import com.redhat.thermostat.storage.model.NetworkInterfaceInfo;
-
-public class NetworkInfoBuilder {
-
-    private static final Logger logger = LoggingUtils.getLogger(NetworkInfoBuilder.class);
-
-    private final WriterID writerId;
-    
-    public NetworkInfoBuilder(WriterID writerId) {
-        this.writerId = writerId;
-    }
-
-    private void addInterfaces(final String wId, List<NetworkInterfaceInfo> infos, List<NetworkInterface> ifaceList, boolean addAll, boolean addUnconnected) {
-        for (NetworkInterface iface : ifaceList) {
-            NetworkInterfaceInfo info = new NetworkInterfaceInfo(wId, iface.getName());
-            List<InetAddress> addrList = Collections.list(iface.getInetAddresses());
-            final boolean want = addAll || (addrList.isEmpty() == addUnconnected);
-            for (InetAddress addr : addrList) {
-                if (addr instanceof Inet4Address) {
-                    info.setIp4Addr(addr.getHostAddress());
-                } else if (addr instanceof Inet6Address) {
-                    info.setIp6Addr(addr.getHostAddress());
-                }
-            }
-            if (want) {
-                infos.add(info);
-            }
-        }
-    }
-
-    public List<NetworkInterfaceInfo> build() {
-        final List<NetworkInterfaceInfo> infos = new ArrayList<NetworkInterfaceInfo>();
-        final String wId = writerId.getWriterID();
-        try {
-            final Enumeration<NetworkInterface> ifaces = NetworkInterface.getNetworkInterfaces();
-            final List<NetworkInterface> ifaceList = Collections.list(ifaces);
-            // list connected interfaces first (there is a lot of noise on windows)
-            addInterfaces(wId, infos, ifaceList, false, false);
-            addInterfaces(wId, infos, ifaceList, false, true);
-
-        } catch (SocketException e) {
-            logger.log(Level.WARNING, "error enumerating network interfaces");
-        }
-        return infos;
-    }
-
-}
-
--- a/system-backend/src/main/java/com/redhat/thermostat/backend/system/internal/SystemBackend.java	Wed Jul 05 14:29:14 2017 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,118 +0,0 @@
-/*
- * Copyright 2012-2017 Red Hat, Inc.
- *
- * This file is part of Thermostat.
- *
- * Thermostat is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2, or (at your
- * option) any later version.
- *
- * Thermostat is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Thermostat; see the file COPYING.  If not see
- * <http://www.gnu.org/licenses/>.
- *
- * Linking this code with other modules is making a combined work
- * based on this code.  Thus, the terms and conditions of the GNU
- * General Public License cover the whole combination.
- *
- * As a special exception, the copyright holders of this code give
- * you permission to link this code with independent modules to
- * produce an executable, regardless of the license terms of these
- * independent modules, and to copy and distribute the resulting
- * executable under terms of your choice, provided that you also
- * meet, for each linked independent module, the terms and conditions
- * of the license of that module.  An independent module is a module
- * which is not derived from or based on this code.  If you modify
- * this code, you may extend this exception to your version of the
- * library, but you are not obligated to do so.  If you do not wish
- * to do so, delete this exception statement from your version.
- */
-
-package com.redhat.thermostat.backend.system.internal;
-
-import java.util.Timer;
-import java.util.TimerTask;
-import java.util.logging.Logger;
-
-import com.redhat.thermostat.backend.BaseBackend;
-import com.redhat.thermostat.common.Version;
-import com.redhat.thermostat.common.utils.LoggingUtils;
-import com.redhat.thermostat.storage.core.WriterID;
-import com.redhat.thermostat.storage.dao.NetworkInterfaceInfoDAO;
-import com.redhat.thermostat.storage.model.NetworkInterfaceInfo;
-
-public class SystemBackend extends BaseBackend {
-
-    private static final Logger logger = LoggingUtils.getLogger(SystemBackend.class);
-
-    private NetworkInterfaceInfoDAO networkInterfaces;
-
-    private long procCheckInterval = 1000; // TODO make this configurable.
-
-    private Timer timer = null;
-
-    private final NetworkInfoBuilder networkInfoBuilder;
-
-    public SystemBackend(NetworkInterfaceInfoDAO netInfoDAO,
-            Version version, WriterID writerId) {
-        super("System Backend",
-                "Gathers basic information from the system",
-                "Red Hat, Inc.", "1.0",
-                true);
-        this.networkInterfaces = netInfoDAO;
-        setVersion(version.getVersionNumber());
-        networkInfoBuilder = new NetworkInfoBuilder(writerId);
-    }
-
-    @Override
-    public synchronized boolean activate() {
-        if (timer != null) {
-            return true;
-        }
-
-        if (!getObserveNewJvm()) {
-            logger.fine("not monitoring new vms");
-        }
-
-        timer = new Timer();
-        timer.scheduleAtFixedRate(new TimerTask() {
-            @Override
-            public void run() {
-                for (NetworkInterfaceInfo info: networkInfoBuilder.build()) {
-                    networkInterfaces.putNetworkInterfaceInfo(info);
-                }
-            }
-        }, 0, procCheckInterval);
-
-        return true;
-    }
-
-    @Override
-    public synchronized boolean deactivate() {
-        if (timer == null) {
-            return true;
-        }
-
-        timer.cancel();
-        timer = null;
-
-        return true;
-    }
-
-    @Override
-    public synchronized boolean isActive() {
-        return (timer != null);
-    }
-
-    @Override
-    public int getOrderValue() {
-        return ORDER_DEFAULT_GROUP;
-    }
-}
-
--- a/system-backend/src/main/java/com/redhat/thermostat/backend/system/internal/SystemBackendActivator.java	Wed Jul 05 14:29:14 2017 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,102 +0,0 @@
-/*
- * Copyright 2012-2017 Red Hat, Inc.
- *
- * This file is part of Thermostat.
- *
- * Thermostat is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2, or (at your
- * option) any later version.
- *
- * Thermostat is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Thermostat; see the file COPYING.  If not see
- * <http://www.gnu.org/licenses/>.
- *
- * Linking this code with other modules is making a combined work
- * based on this code.  Thus, the terms and conditions of the GNU
- * General Public License cover the whole combination.
- *
- * As a special exception, the copyright holders of this code give
- * you permission to link this code with independent modules to
- * produce an executable, regardless of the license terms of these
- * independent modules, and to copy and distribute the resulting
- * executable under terms of your choice, provided that you also
- * meet, for each linked independent module, the terms and conditions
- * of the license of that module.  An independent module is a module
- * which is not derived from or based on this code.  If you modify
- * this code, you may extend this exception to your version of the
- * library, but you are not obligated to do so.  If you do not wish
- * to do so, delete this exception statement from your version.
- */
-
-package com.redhat.thermostat.backend.system.internal;
-
-import org.osgi.framework.BundleActivator;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.ServiceRegistration;
-
-import com.redhat.thermostat.backend.Backend;
-import com.redhat.thermostat.backend.BackendService;
-import com.redhat.thermostat.common.MultipleServiceTracker;
-import com.redhat.thermostat.common.MultipleServiceTracker.Action;
-import com.redhat.thermostat.common.MultipleServiceTracker.DependencyProvider;
-import com.redhat.thermostat.common.Version;
-import com.redhat.thermostat.common.portability.UserNameUtil;
-import com.redhat.thermostat.storage.core.WriterID;
-import com.redhat.thermostat.storage.dao.NetworkInterfaceInfoDAO;
-
-@SuppressWarnings("rawtypes")
-public class SystemBackendActivator implements BundleActivator {
-
-    private MultipleServiceTracker tracker;
-    private SystemBackend backend;
-    private ServiceRegistration reg;
-
-    @Override
-    public void start(final BundleContext context) throws Exception {
-
-        Class<?>[] deps = new Class<?>[] {
-                BackendService.class,
-                NetworkInterfaceInfoDAO.class,
-                UserNameUtil.class,
-                WriterID.class, // system backend uses it
-        };
-        tracker = new MultipleServiceTracker(context, deps, new Action() {
-            @Override
-            public void dependenciesAvailable(DependencyProvider services) {
-                NetworkInterfaceInfoDAO netInfoDAO = services.get(NetworkInterfaceInfoDAO.class);
-                Version version = new Version(context.getBundle());
-                WriterID id = services.get(WriterID.class);
-//                UserNameUtil userNameUtil = services.get(UserNameUtil.class);
-//                VmBlacklist blacklist = services.get(VmBlacklist.class);
-                backend = new SystemBackend(netInfoDAO, version, id);
-                reg = context.registerService(Backend.class, backend, null);
-            }
-            
-            @Override
-            public void dependenciesUnavailable() {
-                if (backend.isActive()) {
-                    backend.deactivate();
-                }
-                reg.unregister();
-            }
-            
-        });
-                
-        tracker.open();
-    }
-    
-    @Override
-    public void stop(BundleContext context) throws Exception {
-        if (backend != null && backend.isActive()) {
-            backend.deactivate();
-        }
-        tracker.close();
-    }
-}
-
--- a/system-backend/src/test/java/com/redhat/thermostat/backend/system/internal/NetworkInfoBuilderTest.java	Wed Jul 05 14:29:14 2017 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,98 +0,0 @@
-/*
- * Copyright 2012-2017 Red Hat, Inc.
- *
- * This file is part of Thermostat.
- *
- * Thermostat is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2, or (at your
- * option) any later version.
- *
- * Thermostat is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Thermostat; see the file COPYING.  If not see
- * <http://www.gnu.org/licenses/>.
- *
- * Linking this code with other modules is making a combined work
- * based on this code.  Thus, the terms and conditions of the GNU
- * General Public License cover the whole combination.
- *
- * As a special exception, the copyright holders of this code give
- * you permission to link this code with independent modules to
- * produce an executable, regardless of the license terms of these
- * independent modules, and to copy and distribute the resulting
- * executable under terms of your choice, provided that you also
- * meet, for each linked independent module, the terms and conditions
- * of the license of that module.  An independent module is a module
- * which is not derived from or based on this code.  If you modify
- * this code, you may extend this exception to your version of the
- * library, but you are not obligated to do so.  If you do not wish
- * to do so, delete this exception statement from your version.
- */
-
-package com.redhat.thermostat.backend.system.internal;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.Mockito.mock;
-
-import java.util.List;
-
-import org.junit.Test;
-
-import com.redhat.thermostat.storage.core.WriterID;
-import com.redhat.thermostat.storage.model.NetworkInterfaceInfo;
-
-public class NetworkInfoBuilderTest {
-
-    @Test
-    public void testBuilder() {
-
-        WriterID id = mock(WriterID.class);
-        
-        NetworkInfoBuilder builder = new NetworkInfoBuilder(id);
-        List<NetworkInterfaceInfo> info = builder.build();
-        assertNotNull(info);
-        for (NetworkInterfaceInfo iface: info) {
-            assertNotNull(iface);
-            assertNotNull(iface.getInterfaceName());
-            if (iface.getIp4Addr() != null) {
-                // ipv4 address matches the form XX.XX.XX.XX
-                assertTrue(iface.getIp4Addr().matches("\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}"));
-            }
-            if (iface.getIp6Addr() != null) {
-                validateIpv6Address(iface.getIp6Addr());
-            }
-        }
-
-    }
-
-    private void validateIpv6Address(String address) {
-        // ipv6 addresses may contain a scope id
-        if (address.contains("%")) {
-            int index = address.indexOf("%");
-            assertTrue(index >= 0);
-            String scopeId = address.substring(index);
-            assertFalse(scopeId.isEmpty());
-            address = address.substring(0, index);
-        }
-
-        String[] parts = address.split(":");
-        assertEquals(8, parts.length);
-
-        for (String part : parts) {
-            assertNotNull(part);
-            if (!part.isEmpty()) {
-                assertTrue(part.matches("[0-9a-f]*"));
-            }
-        }
-    }
-
-}
-
--- a/system-backend/src/test/java/com/redhat/thermostat/backend/system/internal/SystemBackendTest.java	Wed Jul 05 14:29:14 2017 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,96 +0,0 @@
-/*
- * Copyright 2012-2017 Red Hat, Inc.
- *
- * This file is part of Thermostat.
- *
- * Thermostat is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2, or (at your
- * option) any later version.
- *
- * Thermostat is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Thermostat; see the file COPYING.  If not see
- * <http://www.gnu.org/licenses/>.
- *
- * Linking this code with other modules is making a combined work
- * based on this code.  Thus, the terms and conditions of the GNU
- * General Public License cover the whole combination.
- *
- * As a special exception, the copyright holders of this code give
- * you permission to link this code with independent modules to
- * produce an executable, regardless of the license terms of these
- * independent modules, and to copy and distribute the resulting
- * executable under terms of your choice, provided that you also
- * meet, for each linked independent module, the terms and conditions
- * of the license of that module.  An independent module is a module
- * which is not derived from or based on this code.  If you modify
- * this code, you may extend this exception to your version of the
- * library, but you are not obligated to do so.  If you do not wish
- * to do so, delete this exception statement from your version.
- */
-
-package com.redhat.thermostat.backend.system.internal;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-import org.junit.Before;
-import org.junit.Test;
-
-import com.redhat.thermostat.common.Version;
-import com.redhat.thermostat.storage.core.WriterID;
-import com.redhat.thermostat.storage.dao.NetworkInterfaceInfoDAO;
-
-public class SystemBackendTest {
-
-    private static final String VERSION = "0.0.0";
-    private SystemBackend b;
-
-    @Before
-    public void setUp() {
-        NetworkInterfaceInfoDAO nDAO = mock(NetworkInterfaceInfoDAO.class);
-        Version version = mock(Version.class);
-        when(version.getVersionNumber()).thenReturn(VERSION);
-        WriterID id = mock(WriterID.class);
-
-        b = new SystemBackend(nDAO, version, id);
-    }
-
-    @Test
-    public void testBasicBackend() {
-        assertFalse(b.isActive());
-        b.activate();
-        assertTrue(b.isActive());
-        b.deactivate();
-        assertFalse(b.isActive());
-    }
-
-    @Test
-    public void testActivateTwice() {
-        b.activate();
-        b.activate();
-        assertTrue(b.isActive());
-    }
-
-    @Test
-    public void testDeactiateWhenNotActive() {
-        b.deactivate();
-        b.deactivate();
-        assertFalse(b.isActive());
-    }
-    
-    @Test
-    public void testVersion() {
-        assertEquals(VERSION, b.getVersion());
-    }
-
-}
-