changeset 2635:543cd4a5912a

Update AgentInfoDAO to communicate with web gateway Reviewed-by: neugens, jkang Review-thread: http://icedtea.classpath.org/pipermail/thermostat/2017-May/022949.html
author Elliott Baron <ebaron@redhat.com>
date Fri, 05 May 2017 12:14:51 -0400
parents ffe33cda8003
children a21f33af2bfd
files storage/core/src/main/java/com/redhat/thermostat/storage/dao/AgentInfoDAO.java storage/core/src/main/java/com/redhat/thermostat/storage/internal/dao/AgentInfoDAOImpl.java storage/core/src/main/java/com/redhat/thermostat/storage/internal/dao/AgentInformationTypeAdapter.java storage/core/src/test/java/com/redhat/thermostat/storage/internal/dao/AgentInfoDAOTest.java storage/core/src/test/java/com/redhat/thermostat/storage/internal/dao/AgentInformationTypeAdapterTest.java
diffstat 5 files changed, 471 insertions(+), 570 deletions(-) [+]
line wrap: on
line diff
--- a/storage/core/src/main/java/com/redhat/thermostat/storage/dao/AgentInfoDAO.java	Fri May 05 12:27:50 2017 -0400
+++ b/storage/core/src/main/java/com/redhat/thermostat/storage/dao/AgentInfoDAO.java	Fri May 05 12:14:51 2017 -0400
@@ -42,8 +42,6 @@
 import com.redhat.thermostat.annotations.Service;
 import com.redhat.thermostat.storage.core.AgentId;
 import com.redhat.thermostat.storage.core.Category;
-import com.redhat.thermostat.storage.core.Countable;
-import com.redhat.thermostat.storage.core.HostRef;
 import com.redhat.thermostat.storage.core.Key;
 import com.redhat.thermostat.storage.model.AgentInformation;
 
@@ -51,7 +49,7 @@
  * Access information about agents that agents publish to storage.
  */
 @Service
-public interface AgentInfoDAO extends Countable {
+public interface AgentInfoDAO {
 
     static final Key<Long> START_TIME_KEY = new Key<>("startTime");
     static final Key<Long> STOP_TIME_KEY = new Key<>("stopTime");
@@ -75,26 +73,6 @@
     List<AgentInformation> getAllAgentInformation();
 
     /**
-     * Get information about all alive agents.
-     *
-     * @return a {@link List} of {@link AgentInformation} for all alive
-     * agents who have published their information. Will be empty if there
-     * is no information or no alive agents.
-     */
-    List<AgentInformation> getAliveAgents();
-
-    /**
-     * Get information about a specific agent.
-     *
-     * @return a {@link AgentInformation} describing information about the agent
-     * indicated by {@code agentRef}. {@code null} if no information about the
-     * agent could be located.
-     */
-    
-    @Deprecated
-    AgentInformation getAgentInformation(HostRef agentRef);
-
-    /**
      * Get information about a specific agent.
      *
      * @return a {@link AgentInformation} describing information about the agent
@@ -111,12 +89,6 @@
     Set<AgentId> getAgentIds();
 
     /**
-     *
-     * @return A set of alive AgentIds, which may be empty.
-     */
-    Set<AgentId> getAliveAgentIds();
-
-    /**
      * Publish information about agent into the storage.
      */
     void addAgentInformation(AgentInformation agentInfo);
@@ -132,10 +104,5 @@
      */
     void removeAgentInformation(AgentInformation agentInfo);
 
-    /**
-     *
-     * @return true if this agent is alive.
-     */
-    boolean isAlive(AgentId agentId);
 }
 
--- a/storage/core/src/main/java/com/redhat/thermostat/storage/internal/dao/AgentInfoDAOImpl.java	Fri May 05 12:27:50 2017 -0400
+++ b/storage/core/src/main/java/com/redhat/thermostat/storage/internal/dao/AgentInfoDAOImpl.java	Fri May 05 12:14:51 2017 -0400
@@ -36,202 +36,220 @@
 
 package com.redhat.thermostat.storage.internal.dao;
 
-import java.util.HashSet;
+import java.io.IOException;
+import java.net.URI;
+import java.util.Arrays;
+import java.util.Collections;
 import java.util.List;
 import java.util.Set;
+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.core.AgentId;
-import com.redhat.thermostat.storage.core.Category;
-import com.redhat.thermostat.storage.core.CategoryAdapter;
-import com.redhat.thermostat.storage.core.HostRef;
-import com.redhat.thermostat.storage.core.Key;
-import com.redhat.thermostat.storage.core.PreparedStatement;
-import com.redhat.thermostat.storage.core.Storage;
-import com.redhat.thermostat.storage.dao.AbstractDaoQuery;
-import com.redhat.thermostat.storage.dao.AbstractDaoStatement;
 import com.redhat.thermostat.storage.dao.AgentInfoDAO;
-import com.redhat.thermostat.storage.dao.BaseCountable;
-import com.redhat.thermostat.storage.dao.SimpleDaoQuery;
+import com.redhat.thermostat.storage.internal.dao.AgentInformationTypeAdapter.AgentInformationUpdateTypeAdapter;
 import com.redhat.thermostat.storage.model.AgentInformation;
-import com.redhat.thermostat.storage.model.AggregateCount;
 
-public class AgentInfoDAOImpl extends BaseCountable implements AgentInfoDAO {
+public class AgentInfoDAOImpl implements AgentInfoDAO {
 
     private static final Logger logger = LoggingUtils.getLogger(AgentInfoDAOImpl.class);
-    static final String QUERY_AGENT_INFO = "QUERY "
-            + CATEGORY.getName() + " WHERE '"
-            + Key.AGENT_ID.getName() + "' = ?s";
-    static final String QUERY_ALL_AGENTS = "QUERY "
-            + CATEGORY.getName();
-    // We can use AgentInfoDAO.CATEGORY.getName() here since this query
-    // only changes the data class. When executed we use the adapted
-    // aggregate category.
-    static final String AGGREGATE_COUNT_ALL_AGENTS = "QUERY-COUNT "
-            + CATEGORY.getName();
-    static final String QUERY_ALIVE_AGENTS = "QUERY "
-            + CATEGORY.getName() + " WHERE '"
-            + ALIVE_KEY.getName() + "' = ?b";
+    
+    private static final String GATEWAY_URL = "http://localhost:26000/api/v100"; // TODO configurable
+    private static final String GATEWAY_PATH = "/agent-config/systems/*/agents/";
+    private static final String CONTENT_TYPE = "application/json";
+    
+    private final HttpHelper httpHelper;
+    private final JsonHelper jsonHelper;
 
-    // ADD agent-config SET
-    //                     'agentId' = ?s , \
-    //                     'startTime' = ?l , \
-    //                     'stopTime' = ?l , \
-    //                     'alive' = ?b , \
-    //                     'configListenAddress' = ?s
-    static final String DESC_ADD_AGENT_INFO = "ADD " + CATEGORY.getName() + " SET " +
-            "'" + Key.AGENT_ID.getName() + "' = ?s , " +
-            "'" + START_TIME_KEY.getName() + "' = ?l , " +
-            "'" + STOP_TIME_KEY.getName() + "' = ?l , " +
-            "'" + ALIVE_KEY.getName() + "' = ?b , " +
-            "'" + CONFIG_LISTEN_ADDRESS.getName() + "' = ?s";
-    // REMOVE agent-config WHERE 'agentId' = ?s
-    static final String DESC_REMOVE_AGENT_INFO = "REMOVE " + CATEGORY.getName() +
-            " WHERE '" + Key.AGENT_ID.getName() + "' = ?s";
-    // UPDATE agent-config SET
-    //                       'startTime' = ?l , \
-    //                       'stopTime' = ?l , \
-    //                       'alive' = ?b , \
-    //                       'configListenAddress' = ?s
-    //                     WHERE 'agentId' = ?s
-    static final String DESC_UPDATE_AGENT_INFO = "UPDATE " + CATEGORY.getName() + " SET " +
-            "'" + START_TIME_KEY.getName() + "' = ?l , " +
-            "'" + STOP_TIME_KEY.getName() + "' = ?l , " +
-            "'" + ALIVE_KEY.getName() + "' = ?b , " +
-            "'" + CONFIG_LISTEN_ADDRESS.getName() + "' = ?s " +
-            "WHERE '" + Key.AGENT_ID.getName() + "' = ?s";
-
-
-    private final Storage storage;
-    private final Category<AggregateCount> aggregateCategory;
-
-    public AgentInfoDAOImpl(Storage storage) {
-        this.storage = storage;
-        CategoryAdapter<AgentInformation, AggregateCount> adapter = new CategoryAdapter<>(CATEGORY);
-        this.aggregateCategory = adapter.getAdapted(AggregateCount.class);
-        storage.registerCategory(CATEGORY);
-        storage.registerCategory(aggregateCategory);
+    public AgentInfoDAOImpl() throws Exception {
+        this(new HttpHelper(new HttpClient()), new JsonHelper(new AgentInformationTypeAdapter(), 
+                new AgentInformationUpdateTypeAdapter()));
     }
 
-    @Override
-    public long getCount() {
-        return getCount(storage, aggregateCategory, AGGREGATE_COUNT_ALL_AGENTS);
+    AgentInfoDAOImpl(HttpHelper httpHelper, JsonHelper jsonHelper) throws Exception {
+        this.httpHelper = httpHelper;
+        this.jsonHelper = jsonHelper;
+        
+        this.httpHelper.startClient();
     }
 
     @Override
     public List<AgentInformation> getAllAgentInformation() {
-        return executeQuery(new SimpleDaoQuery<>(storage, CATEGORY, QUERY_ALL_AGENTS)).asList();
-    }
-
-    @Override
-    public List<AgentInformation> getAliveAgents() {
-        return executeQuery(
-                new AbstractDaoQuery<AgentInformation>(storage, CATEGORY, QUERY_ALIVE_AGENTS) {
-                    @Override
-                    public PreparedStatement<AgentInformation> customize(PreparedStatement<AgentInformation> preparedStatement) {
-                        preparedStatement.setBoolean(0, true);
-                        return preparedStatement;
-                    }
-                }).asList();
-    }
-
-    @Override
-    public AgentInformation getAgentInformation(final HostRef agentRef) {
-        return executeQuery(
-                new AbstractDaoQuery<AgentInformation>(storage, CATEGORY, QUERY_AGENT_INFO) {
-                    @Override
-                    public PreparedStatement<AgentInformation> customize(PreparedStatement<AgentInformation> preparedStatement) {
-                        preparedStatement.setString(0, agentRef.getAgentId());
-                        return preparedStatement;
-                    }
-                }).head();
+        return Collections.emptyList(); // TODO Remove once Agent Id completer is removed
     }
 
     @Override
     public AgentInformation getAgentInformation(final AgentId agentId) {
-        return executeQuery(
-                new AbstractDaoQuery<AgentInformation>(storage, CATEGORY, QUERY_AGENT_INFO) {
-                    @Override
-                    public PreparedStatement<AgentInformation> customize(PreparedStatement<AgentInformation> preparedStatement) {
-                        preparedStatement.setString(0, agentId.get());
-                        return preparedStatement;
-                    }
-                }).head();
+        return null; // TODO Remove once VM Id completer is removed
     }
 
     @Override
     public Set<AgentId> getAgentIds() {
-        return mapToIds(getAllAgentInformation());
-    }
-
-    @Override
-    public Set<AgentId> getAliveAgentIds() {
-        return mapToIds(getAliveAgents());
-    }
-
-    private Set<AgentId> mapToIds(Iterable<AgentInformation> agentInformations) {
-        Set<AgentId> result = new HashSet<>();
-        for (AgentInformation agentInformation : agentInformations) {
-            result.add(toAgentId(agentInformation));
-        }
-        return result;
-    }
-
-    private AgentId toAgentId(AgentInformation agentInfo) {
-        return new AgentId(agentInfo.getAgentId());
+        return Collections.emptySet(); // TODO Remove once VM Id completer is removed
     }
 
     @Override
     public void addAgentInformation(final AgentInformation agentInfo) {
-        executeStatement(new AbstractDaoStatement<AgentInformation>(storage, CATEGORY, DESC_ADD_AGENT_INFO) {
-            @Override
-            public PreparedStatement<AgentInformation> customize(PreparedStatement<AgentInformation> preparedStatement) {
-                preparedStatement.setString(0, agentInfo.getAgentId());
-                preparedStatement.setLong(1, agentInfo.getStartTime());
-                preparedStatement.setLong(2, agentInfo.getStopTime());
-                preparedStatement.setBoolean(3, agentInfo.isAlive());
-                preparedStatement.setString(4, agentInfo.getConfigListenAddress());
-                return preparedStatement;
-            }
-        });
+        try {
+            // Encode as JSON and send as POST request
+            String json = jsonHelper.toJson(Arrays.asList(agentInfo));
+            StringContentProvider provider = httpHelper.createContentProvider(json);
+            
+            String url = getURL(agentInfo.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 agent information to web gateway", e);
+        }
     }
 
     @Override
     public void removeAgentInformation(final AgentInformation agentInfo) {
-        executeStatement(new AbstractDaoStatement<AgentInformation>(storage, CATEGORY, DESC_REMOVE_AGENT_INFO) {
-            @Override
-            public PreparedStatement<AgentInformation> customize(PreparedStatement<AgentInformation> preparedStatement) {
-                preparedStatement.setString(0, agentInfo.getAgentId());
-                return preparedStatement;
-            }
-        });
-    }
-
-    @Override
-    public boolean isAlive(final AgentId agentId) {
-        AgentInformation info = getAgentInformation(agentId);
-        return (info != null && info.isAlive());
+        try {
+            // Delete AgentInformation with matching Agent ID
+            String url = getURL(agentInfo.getAgentId());
+            Request httpRequest = httpHelper.newRequest(url);
+            httpRequest.method(HttpMethod.DELETE);
+            sendRequest(httpRequest);
+        } catch (IOException | InterruptedException | TimeoutException | ExecutionException e) {
+           logger.log(Level.WARNING, "Failed to delete agent information from web gateway", e);
+        }
     }
 
     @Override
     public void updateAgentInformation(final AgentInformation agentInfo) {
-        executeStatement(new AbstractDaoStatement<AgentInformation>(storage, CATEGORY, DESC_UPDATE_AGENT_INFO) {
-            @Override
-            public PreparedStatement<AgentInformation> customize(PreparedStatement<AgentInformation> preparedStatement) {
-                preparedStatement.setLong(0, agentInfo.getStartTime());
-                preparedStatement.setLong(1, agentInfo.getStopTime());
-                preparedStatement.setBoolean(2, agentInfo.isAlive());
-                preparedStatement.setString(3, agentInfo.getConfigListenAddress());
-                preparedStatement.setString(4, agentInfo.getAgentId());
-                return preparedStatement;
-            }
-        });
+        try {
+            // Encode as JSON and send as PUT request
+            AgentInformationUpdate update = new AgentInformationUpdate(agentInfo);
+            String json = jsonHelper.toJson(update);
+            StringContentProvider provider = httpHelper.createContentProvider(json);
+            
+            String url = getURL(agentInfo.getAgentId());
+            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 agent information update to web gateway", e);
+        }
     }
 
-    @Override
-    protected Logger getLogger() {
-        return logger;
+    private void 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());
+        }
+    }
+    
+    private String getURL(String agentId) {
+        StringBuilder builder = new StringBuilder();
+        builder.append(GATEWAY_URL);
+        builder.append(GATEWAY_PATH);
+        builder.append(agentId);
+        return builder.toString();
+    }
+    
+    static class AgentInformationUpdate {
+        
+        private final AgentInformation info;
+        
+        AgentInformationUpdate(AgentInformation info) {
+            this.info = info;
+        }
+        
+        AgentInformation getInfo() {
+            return info;
+        }
+        
+    }
+    
+    // For testing purposes
+    static class JsonHelper {
+        
+        private final AgentInformationTypeAdapter typeAdapter;
+        private final AgentInformationUpdateTypeAdapter updateTypeAdapter;
+        
+        public JsonHelper(AgentInformationTypeAdapter typeAdapter, AgentInformationUpdateTypeAdapter updateTypeAdapter) {
+            this.typeAdapter = typeAdapter;
+            this.updateTypeAdapter = updateTypeAdapter;
+        }
+        
+        String toJson(List<AgentInformation> infos) throws IOException {
+            return typeAdapter.toJson(infos);
+        }
+        
+        String toJson(AgentInformationUpdate 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;
+        }
+        
+    }
+    
 }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/storage/core/src/main/java/com/redhat/thermostat/storage/internal/dao/AgentInformationTypeAdapter.java	Fri May 05 12:14:51 2017 -0400
@@ -0,0 +1,132 @@
+/*
+ * 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.List;
+
+import com.google.gson.TypeAdapter;
+import com.google.gson.stream.JsonReader;
+import com.google.gson.stream.JsonWriter;
+import com.redhat.thermostat.storage.internal.dao.AgentInfoDAOImpl.AgentInformationUpdate;
+import com.redhat.thermostat.storage.model.AgentInformation;
+
+public class AgentInformationTypeAdapter extends TypeAdapter<List<AgentInformation>> {
+    
+    private static final String AGENT_ID = "agentId";
+    private static final String START_TIME = "startTime";
+    private static final String STOP_TIME = "stopTime";
+    private static final String ALIVE = "alive";
+    private static final String CONFIG_LISTEN_ADDRESS = "configListenAddress";
+    private static final String TYPE_LONG = "$numberLong";
+    
+    @Override
+    public void write(JsonWriter out, List<AgentInformation> value) throws IOException {
+        // Request is an array of AgentInformation objects
+        out.beginArray();
+        
+        for (AgentInformation info : value) {
+            writeAgentInformation(out, info);
+        }
+        
+        out.endArray();
+    }
+
+    private void writeAgentInformation(JsonWriter out, AgentInformation info) throws IOException {
+        out.beginObject();
+        
+        // Write each field of AgentInformation as part of a JSON object
+        out.name(AGENT_ID);
+        out.value(info.getAgentId());
+        out.name(START_TIME);
+        writeLong(out, info.getStartTime());
+        out.name(STOP_TIME);
+        writeLong(out, info.getStopTime());
+        out.name(ALIVE);
+        out.value(info.isAlive());
+        out.name(CONFIG_LISTEN_ADDRESS);
+        out.value(info.getConfigListenAddress());
+        
+        out.endObject();
+    }
+
+    private static void writeLong(JsonWriter out, long value) throws IOException {
+        // Write MongoDB representation of a Long
+        out.beginObject();
+        out.name(TYPE_LONG);
+        out.value(String.valueOf(value));
+        out.endObject();
+    }
+    
+    @Override
+    public List<AgentInformation> read(JsonReader in) throws IOException {
+        throw new UnsupportedOperationException();
+    }
+    
+    static class AgentInformationUpdateTypeAdapter extends TypeAdapter<AgentInformationUpdate> {
+        
+        private static final String SET = "set";
+
+        @Override
+        public void write(JsonWriter out, AgentInformationUpdate value) throws IOException {
+            // List fields to update as part of a JSON object with name "set"
+            out.beginObject();
+            out.name(SET);
+            
+            AgentInformation info = value.getInfo();
+            out.beginObject();
+            out.name(START_TIME);
+            writeLong(out, info.getStartTime());
+            out.name(STOP_TIME);
+            writeLong(out, info.getStopTime());
+            out.name(ALIVE);
+            out.value(info.isAlive());
+            out.name(CONFIG_LISTEN_ADDRESS);
+            out.value(info.getConfigListenAddress());
+            out.endObject();
+            
+            out.endObject();
+        }
+
+        @Override
+        public AgentInformationUpdate read(JsonReader in) throws IOException {
+            throw new UnsupportedOperationException();
+        }
+        
+    }
+    
+}
--- a/storage/core/src/test/java/com/redhat/thermostat/storage/internal/dao/AgentInfoDAOTest.java	Fri May 05 12:27:50 2017 -0400
+++ b/storage/core/src/test/java/com/redhat/thermostat/storage/internal/dao/AgentInfoDAOTest.java	Fri May 05 12:14:51 2017 -0400
@@ -37,85 +37,72 @@
 package com.redhat.thermostat.storage.internal.dao;
 
 import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertSame;
 import static org.junit.Assert.assertTrue;
 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.verify;
-import static org.mockito.Mockito.verifyNoMoreInteractions;
 import static org.mockito.Mockito.when;
 
+import java.util.Arrays;
 import java.util.Collection;
-import java.util.List;
-import java.util.NoSuchElementException;
-import java.util.Set;
 
+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 org.mockito.Mockito;
 
-import com.redhat.thermostat.common.Pair;
-import com.redhat.thermostat.storage.core.AgentId;
 import com.redhat.thermostat.storage.core.Category;
-import com.redhat.thermostat.storage.core.Cursor;
-import com.redhat.thermostat.storage.core.DescriptorParsingException;
 import com.redhat.thermostat.storage.core.Key;
-import com.redhat.thermostat.storage.core.PreparedStatement;
-import com.redhat.thermostat.storage.core.StatementDescriptor;
-import com.redhat.thermostat.storage.core.StatementExecutionException;
-import com.redhat.thermostat.storage.core.Storage;
 import com.redhat.thermostat.storage.dao.AgentInfoDAO;
+import com.redhat.thermostat.storage.internal.dao.AgentInfoDAOImpl.AgentInformationUpdate;
+import com.redhat.thermostat.storage.internal.dao.AgentInfoDAOImpl.HttpHelper;
+import com.redhat.thermostat.storage.internal.dao.AgentInfoDAOImpl.JsonHelper;
 import com.redhat.thermostat.storage.model.AgentInformation;
-import com.redhat.thermostat.storage.model.AggregateCount;
 
 public class AgentInfoDAOTest {
 
-    private AgentInformation agentInfo1;
-    private AgentInformation agent1;
+    private static final String URL = "http://localhost:26000/api/v100/agent-config/systems/*/agents/1234";
+    private static final String SOME_JSON = "{\"some\" : \"json\"}";
+    private static final String SOME_OTHER_JSON = "{\"some\" : {\"other\" : \"json\"}}";
+    private static final String CONTENT_TYPE = "application/json";
+
+    private AgentInformation info;
+    private JsonHelper jsonHelper;
+    private HttpHelper httpHelper;
+    private StringContentProvider contentProvider;
+    private Request request;
+    private ContentResponse response;
 
     @Before
-    public void setUp() {
-        agentInfo1 = new AgentInformation("1234");
-        agentInfo1.setAlive(true);
-        agentInfo1.setConfigListenAddress("foobar:666");
-        agentInfo1.setStartTime(100);
-        agentInfo1.setStopTime(10);
-
-        agent1 = new AgentInformation("1234");
-        agent1.setAlive(true);
-        agent1.setConfigListenAddress("foobar:666");
-        agent1.setStartTime(100);
-        agent1.setStopTime(10);
+    public void setUp() throws Exception {
+        info = new AgentInformation("1234");
+        info.setAlive(true);
+        info.setConfigListenAddress("foobar:666");
+        info.setStartTime(100);
+        info.setStopTime(10);
+        
+        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(AgentInformation.class))).thenReturn(SOME_JSON);
+        when(jsonHelper.toJson(any(AgentInformationUpdate.class))).thenReturn(SOME_OTHER_JSON);
     }
 
     @Test
-    public void preparedQueryDescriptorsAreSane() {
-        String expectedAgentInfo = "QUERY agent-config WHERE 'agentId' = ?s";
-        assertEquals(expectedAgentInfo, AgentInfoDAOImpl.QUERY_AGENT_INFO);
-        String expectedAllAgents = "QUERY agent-config";
-        assertEquals(expectedAllAgents, AgentInfoDAOImpl.QUERY_ALL_AGENTS);
-        String expectedAliveAgents = "QUERY agent-config WHERE 'alive' = ?b";
-        assertEquals(expectedAliveAgents, AgentInfoDAOImpl.QUERY_ALIVE_AGENTS);
-        String aggregateAllAgents = "QUERY-COUNT agent-config";
-        assertEquals(aggregateAllAgents, AgentInfoDAOImpl.AGGREGATE_COUNT_ALL_AGENTS);
-        String addAgentInfo = "ADD agent-config SET 'agentId' = ?s , " +
-                                                   "'startTime' = ?l , " +
-                                                   "'stopTime' = ?l , " +
-                                                   "'alive' = ?b , " +
-                                                   "'configListenAddress' = ?s";
-        assertEquals(addAgentInfo, AgentInfoDAOImpl.DESC_ADD_AGENT_INFO);
-        String removeAgentInfo = "REMOVE agent-config WHERE 'agentId' = ?s";
-        assertEquals(removeAgentInfo, AgentInfoDAOImpl.DESC_REMOVE_AGENT_INFO);
-        String updateAgentInfo = "UPDATE agent-config SET 'startTime' = ?l , " +
-                                                         "'stopTime' = ?l , " +
-                                                         "'alive' = ?b , " +
-                                                         "'configListenAddress' = ?s " +
-                                                      "WHERE 'agentId' = ?s";
-        assertEquals(updateAgentInfo, AgentInfoDAOImpl.DESC_UPDATE_AGENT_INFO);
-    }
-    
-    @Test
     public void verifyCategoryName() {
         Category<AgentInformation> category = AgentInfoDAO.CATEGORY;
         assertEquals("agent-config", category.getName());
@@ -142,344 +129,50 @@
     }
 
     @Test
-    public void verifyGetAllAgentInformationWithOneAgentInStorage()
-            throws DescriptorParsingException, StatementExecutionException {
-        @SuppressWarnings("unchecked")
-        Cursor<AgentInformation> agentCursor = (Cursor<AgentInformation>) mock(Cursor.class);
-        when(agentCursor.hasNext()).thenReturn(true).thenReturn(false);
-        when(agentCursor.next()).thenReturn(agent1).thenReturn(null);
-
-        Storage storage = mock(Storage.class);
-        @SuppressWarnings("unchecked")
-        PreparedStatement<AgentInformation> stmt = (PreparedStatement<AgentInformation>) mock(PreparedStatement.class);
-        when(storage.prepareStatement(anyDescriptor())).thenReturn(stmt);
-        when(stmt.executeQuery()).thenReturn(agentCursor);
-        AgentInfoDAOImpl dao = new AgentInfoDAOImpl(storage);
-
-        List<AgentInformation> allAgentInfo = dao.getAllAgentInformation();
-
-        assertEquals(1, allAgentInfo.size());
+    public void verifyAddAgentInformation() throws Exception {
+        AgentInfoDAO dao = new AgentInfoDAOImpl(httpHelper, jsonHelper);
 
-        AgentInformation result = allAgentInfo.get(0);
-        AgentInformation expected = agentInfo1;
-        assertEquals(expected, result);
-    }
-    
-    @Test
-    public void testGetCount()
-            throws DescriptorParsingException, StatementExecutionException {
-        AggregateCount count = new AggregateCount();
-        count.setCount(2);
-
-        @SuppressWarnings("unchecked")
-        Cursor<AggregateCount> c = (Cursor<AggregateCount>) mock(Cursor.class);
-        when(c.hasNext()).thenReturn(true).thenReturn(false);
-        when(c.next()).thenReturn(count).thenThrow(new NoSuchElementException());
-
-        Storage storage = mock(Storage.class);
-        @SuppressWarnings("unchecked")
-        PreparedStatement<AggregateCount> stmt = (PreparedStatement<AggregateCount>) mock(PreparedStatement.class);
-        @SuppressWarnings("unchecked")
-        StatementDescriptor<AggregateCount> desc = any(StatementDescriptor.class);
-        when(storage.prepareStatement(desc)).thenReturn(stmt);
-        when(stmt.executeQuery()).thenReturn(c);
-        AgentInfoDAOImpl dao = new AgentInfoDAOImpl(storage);
+        dao.addAgentInformation(info);
 
-        assertEquals(2, dao.getCount());
-    }
-    
-    @SuppressWarnings("unchecked")
-    private StatementDescriptor<AgentInformation> anyDescriptor() {
-        return (StatementDescriptor<AgentInformation>) any(StatementDescriptor.class);
-    }
-
-    @Test
-    public void verifyGetAliveAgent() throws DescriptorParsingException, StatementExecutionException {
-        @SuppressWarnings("unchecked")
-        Cursor<AgentInformation> agentCursor = (Cursor<AgentInformation>) mock(Cursor.class);
-        when(agentCursor.hasNext()).thenReturn(true).thenReturn(false);
-        when(agentCursor.next()).thenReturn(agent1).thenReturn(null);
-
-        Storage storage = mock(Storage.class);
-        @SuppressWarnings("unchecked")
-        PreparedStatement<AgentInformation> stmt = (PreparedStatement<AgentInformation>) mock(PreparedStatement.class);
-        when(storage.prepareStatement(anyDescriptor())).thenReturn(stmt);
-        when(stmt.executeQuery()).thenReturn(agentCursor);
-
-        AgentInfoDAO dao = new AgentInfoDAOImpl(storage);
-        List<AgentInformation> aliveAgents = dao.getAliveAgents();
-
-        verify(storage).prepareStatement(anyDescriptor());
-        verify(stmt).executeQuery();
-        verify(stmt).setBoolean(0, true);
-        verifyNoMoreInteractions(stmt);
-
-        assertEquals(1, aliveAgents.size());
-
-        AgentInformation result = aliveAgents.get(0);
-        AgentInformation expected = agentInfo1;
-        assertEquals(expected, result);
-    }
-
-    @Test
-    public void verifyGetAgentInformationWhenStorageCantFindIt() throws DescriptorParsingException, StatementExecutionException {
-        AgentId agentId = mock(AgentId.class);
-
-        Storage storage = mock(Storage.class);
-        @SuppressWarnings("unchecked")
-        PreparedStatement<AgentInformation> stmt = (PreparedStatement<AgentInformation>) mock(PreparedStatement.class);
-        when(storage.prepareStatement(anyDescriptor())).thenReturn(stmt);
-        @SuppressWarnings("unchecked")
-        Cursor<AgentInformation> cursor = (Cursor<AgentInformation>) mock(Cursor.class);
-        when(cursor.hasNext()).thenReturn(false);
-        when(cursor.next()).thenReturn(null);
-        when(stmt.executeQuery()).thenReturn(cursor);
-
-        AgentInfoDAO dao = new AgentInfoDAOImpl(storage);
-
-        AgentInformation computed = dao.getAgentInformation(agentId);
-
-        assertEquals(null, computed);
+        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).send();
+        verify(response).getStatus();
     }
 
     @Test
-    public void verifyGetAgentInformation() throws StatementExecutionException, DescriptorParsingException {
-        AgentId agentId = mock(AgentId.class);
-        when(agentId.get()).thenReturn(agentInfo1.getAgentId());
-
-        Storage storage = mock(Storage.class);
-        @SuppressWarnings("unchecked")
-        PreparedStatement<AgentInformation> stmt = (PreparedStatement<AgentInformation>) mock(PreparedStatement.class);
-        when(storage.prepareStatement(anyDescriptor())).thenReturn(stmt);
-        @SuppressWarnings("unchecked")
-        Cursor<AgentInformation> cursor = (Cursor<AgentInformation>) mock(Cursor.class);
-        when(cursor.hasNext()).thenReturn(true).thenReturn(false);
-        when(cursor.next()).thenReturn(agentInfo1).thenReturn(null);
-        when(stmt.executeQuery()).thenReturn(cursor);
-        AgentInfoDAO dao = new AgentInfoDAOImpl(storage);
-
-        AgentInformation computed = dao.getAgentInformation(agentId);
-
-        verify(storage).prepareStatement(anyDescriptor());
-        verify(stmt).setString(0, agentInfo1.getAgentId());
-        verify(stmt).executeQuery();
-        verifyNoMoreInteractions(stmt);
-        AgentInformation expected = agentInfo1;
-        assertSame(expected, computed);
-    }
+    public void verifyUpdateAgentInformation() throws Exception {
+        AgentInfoDAO dao = new AgentInfoDAOImpl(httpHelper, jsonHelper);
 
-    @SuppressWarnings("unchecked")
-    @Test
-    public void verifyAddAgentInformation() throws StatementExecutionException, DescriptorParsingException {
-        Storage storage = mock(Storage.class);
-        PreparedStatement<AgentInformation> add = mock(PreparedStatement.class);
-        when(storage.prepareStatement(any(StatementDescriptor.class))).thenReturn(add);
-
-        AgentInfoDAO dao = new AgentInfoDAOImpl(storage);
-
-        dao.addAgentInformation(agentInfo1);
-
-        @SuppressWarnings("rawtypes")
-        ArgumentCaptor<StatementDescriptor> captor = ArgumentCaptor.forClass(StatementDescriptor.class);
-        
-        verify(storage).prepareStatement(captor.capture());
-        StatementDescriptor<?> desc = captor.getValue();
-        assertEquals(AgentInfoDAOImpl.DESC_ADD_AGENT_INFO, desc.getDescriptor());
-        verify(add).setString(0, agentInfo1.getAgentId());
-        verify(add).setLong(1, agentInfo1.getStartTime());
-        verify(add).setLong(2, agentInfo1.getStopTime());
-        verify(add).setBoolean(3, agentInfo1.isAlive());
-        verify(add).setString(4, agentInfo1.getConfigListenAddress());
-        verify(add).execute();
-        Mockito.verifyNoMoreInteractions(add);
-    }
+        dao.updateAgentInformation(info);
 
-    @SuppressWarnings("unchecked")
-    @Test
-    public void verifyUpdateAgentInformation() throws DescriptorParsingException, StatementExecutionException {
-        Storage storage = mock(Storage.class);
-        PreparedStatement<AgentInformation> update = mock(PreparedStatement.class);
-        when(storage.prepareStatement(any(StatementDescriptor.class))).thenReturn(update);
-        AgentInfoDAO dao = new AgentInfoDAOImpl(storage);
-
-        dao.updateAgentInformation(agentInfo1);
-
-        @SuppressWarnings("rawtypes")
-        ArgumentCaptor<StatementDescriptor> captor = ArgumentCaptor.forClass(StatementDescriptor.class);
-        verify(storage).prepareStatement(captor.capture());
+        verify(httpHelper).newRequest(URL);
+        verify(request).method(HttpMethod.PUT);
         
-        StatementDescriptor<?> desc = captor.getValue();
-        assertEquals(AgentInfoDAO.CATEGORY, desc.getCategory());
-        assertEquals(AgentInfoDAOImpl.DESC_UPDATE_AGENT_INFO, desc.getDescriptor());
-        verify(update).setLong(0, agentInfo1.getStartTime());
-        verify(update).setLong(1, agentInfo1.getStopTime());
-        verify(update).setBoolean(2, agentInfo1.isAlive());
-        verify(update).setString(3, agentInfo1.getConfigListenAddress());
-        verify(update).setString(4, agentInfo1.getAgentId());
-        verify(update).execute();
-        verifyNoMoreInteractions(update);
-    }
-
-    @SuppressWarnings("unchecked")
-    @Test
-    public void verifyRemoveAgentInformation() throws DescriptorParsingException, StatementExecutionException {
-        Storage storage = mock(Storage.class);
-        PreparedStatement<AgentInformation> remove = mock(PreparedStatement.class);
-        when(storage.prepareStatement(any(StatementDescriptor.class))).thenReturn(remove);
-        
-        AgentInfoDAO dao = new AgentInfoDAOImpl(storage);
-
-        dao.removeAgentInformation(agentInfo1);
-
-        verify(remove).setString(0, agentInfo1.getAgentId());
-        verify(remove).execute();
-    }
-
-    @Test
-    public void testGetAgentIdsSingleAgent() throws DescriptorParsingException,
-            StatementExecutionException {
-
-        Pair<Storage, PreparedStatement<AgentInformation>> setup = setupStorageForSingleAgent();
-        Storage storage = setup.getFirst();
-        PreparedStatement<AgentInformation> stmt = setup.getSecond();
-
-        AgentInfoDAO agentInfoDAO = new AgentInfoDAOImpl(storage);
-        Set<AgentId> agentIds = agentInfoDAO.getAgentIds();
-
-        assertEquals(1, agentIds.size());
-        assertTrue(agentIds.contains(new AgentId("1234")));
-        verify(stmt).executeQuery();
+        ArgumentCaptor<AgentInformationUpdate> updateCaptor = ArgumentCaptor.forClass(AgentInformationUpdate.class);
+        verify(jsonHelper).toJson(updateCaptor.capture());
+        AgentInformationUpdate update = updateCaptor.getValue();
+        assertEquals(info, update.getInfo());
+                
+        verify(httpHelper).createContentProvider(SOME_OTHER_JSON);
+        verify(request).content(contentProvider, CONTENT_TYPE);
+        verify(request).send();
+        verify(response).getStatus();
     }
 
     @Test
-    public void testGetAgentIds3Agents() throws DescriptorParsingException,
-            StatementExecutionException {
-
-        Pair<Storage, PreparedStatement<AgentInformation>> setup = setupStorageFor3Agents();
-        Storage storage = setup.getFirst();
-        PreparedStatement<AgentInformation> stmt = setup.getSecond();
-
-        AgentInfoDAO agentInfoDAO = new AgentInfoDAOImpl(storage);
-        Set<AgentId> agentIds = agentInfoDAO.getAgentIds();
-
-        assertEquals(3, agentIds.size());
-        assertTrue(agentIds.contains(new AgentId("1234")));
-        assertTrue(agentIds.contains(new AgentId("4567")));
-        assertTrue(agentIds.contains(new AgentId("8910")));
-        verify(storage).prepareStatement(anyDescriptor());
-        verify(stmt).executeQuery();
-    }
-
-    @Test
-    public void getAliveAgentIdsSingle() throws DescriptorParsingException,
-            StatementExecutionException {
-
-        Pair<Storage, PreparedStatement<AgentInformation>> setup = setupStorageForSingleAgent();
-        Storage storage = setup.getFirst();
-        PreparedStatement<AgentInformation> stmt = setup.getSecond();
-
-        AgentInfoDAO agentInfoDAO = new AgentInfoDAOImpl(storage);
-        Collection<AgentId> agentIds = agentInfoDAO.getAliveAgentIds();
+    public void verifyRemoveAgentInformation() throws Exception {
+        AgentInfoDAO dao = new AgentInfoDAOImpl(httpHelper, jsonHelper);
 
-        assertEquals(1, agentIds.size());
-        assertTrue(agentIds.contains(new AgentId("1234")));
-        verify(storage).prepareStatement(anyDescriptor());
-        verify(stmt).setBoolean(0, true);
-        verify(stmt).executeQuery();
-    }
-
-    @Test
-    public void getAliveAgentIds3() throws DescriptorParsingException, StatementExecutionException {
-        Pair<Storage, PreparedStatement<AgentInformation>> setup = setupStorageFor3Agents();
-        Storage storage = setup.getFirst();
-        PreparedStatement<AgentInformation> stmt = setup.getSecond();
-
-        AgentInfoDAO agentInfoDAO = new AgentInfoDAOImpl(storage);
-        Set<AgentId> agentIds = agentInfoDAO.getAliveAgentIds();
-
-        assertEquals(3, agentIds.size());
-        assertTrue(agentIds.contains(new AgentId("1234")));
-        assertTrue(agentIds.contains(new AgentId("4567")));
-        assertTrue(agentIds.contains(new AgentId("8910")));
-        verify(storage).prepareStatement(anyDescriptor());
-        verify(stmt).setBoolean(0, true);
-        verify(stmt).executeQuery();
-    }
-
-    @Test
-    public void getAliveAgentIdsDescriptorException() throws DescriptorParsingException {
-        Storage storage = mock(Storage.class);
-        AgentInfoDAO agentInfoDAO = new AgentInfoDAOImpl(storage);
-
-        when(storage.prepareStatement(anyDescriptor())).thenThrow(new DescriptorParsingException
-                ("testException"));
-
-        Set<AgentId> agentIds = agentInfoDAO.getAgentIds();
+        dao.removeAgentInformation(info);
 
-        assertEquals(0, agentIds.size());
-    }
-
-    @Test
-    public void getAliveAgentIdsStatementException() throws DescriptorParsingException,
-            StatementExecutionException {
-        Storage storage = mock(Storage.class);
-        AgentInfoDAO agentInfoDAO = new AgentInfoDAOImpl(storage);
-
-        @SuppressWarnings("unchecked")
-        PreparedStatement<AgentInformation> stmt = (PreparedStatement<AgentInformation>) mock(PreparedStatement.class);
-        when(storage.prepareStatement(anyDescriptor())).thenReturn(stmt);
-
-        StatementExecutionException testException = new StatementExecutionException(new Throwable
-                ("testException"));
-        when(stmt.executeQuery()).thenThrow(testException);
-
-        Set<AgentId> agentIds = agentInfoDAO.getAliveAgentIds();
-
-        assertEquals(0, agentIds.size());
-    }
-
-    private Pair<Storage, PreparedStatement<AgentInformation>> setupStorageForSingleAgent()
-            throws DescriptorParsingException, StatementExecutionException {
-
-        @SuppressWarnings("unchecked")
-        Cursor<AgentInformation> agentCursor = (Cursor<AgentInformation>) mock(Cursor.class);
-        when(agentCursor.hasNext()).thenReturn(true).thenReturn(false);
-        when(agentCursor.next()).thenReturn(agentInfo1);
-
-        Storage storage = mock(Storage.class);
-        @SuppressWarnings("unchecked")
-        PreparedStatement<AgentInformation> stmt = (PreparedStatement<AgentInformation>) mock(PreparedStatement.class);
-        when(storage.prepareStatement(anyDescriptor())).thenReturn(stmt);
-        when(stmt.executeQuery()).thenReturn(agentCursor);
-        return new Pair<>(storage, stmt);
-    }
-
-    private Pair<Storage, PreparedStatement<AgentInformation>> setupStorageFor3Agents()
-            throws DescriptorParsingException, StatementExecutionException {
-
-        AgentInformation agentInfo2 = new AgentInformation("4567");
-        agentInfo2.setAlive(true);
-        agentInfo2.setConfigListenAddress("foobar:666");
-        agentInfo2.setStartTime(100);
-        agentInfo2.setStopTime(10);
-
-        AgentInformation agentInfo3 = new AgentInformation("8910");
-        agentInfo3.setAlive(true);
-        agentInfo3.setConfigListenAddress("foobar:666");
-        agentInfo3.setStartTime(100);
-        agentInfo3.setStopTime(10);
-
-        @SuppressWarnings("unchecked")
-        Cursor<AgentInformation> agentCursor = (Cursor<AgentInformation>) mock(Cursor.class);
-        when(agentCursor.hasNext()).thenReturn(true).thenReturn(true).thenReturn(true).thenReturn(false);
-        when(agentCursor.next()).thenReturn(agentInfo1).thenReturn(agentInfo2).thenReturn(agentInfo3);
-
-        Storage storage = mock(Storage.class);
-        @SuppressWarnings("unchecked")
-        PreparedStatement<AgentInformation> stmt = (PreparedStatement<AgentInformation>) mock(PreparedStatement.class);
-        when(storage.prepareStatement(anyDescriptor())).thenReturn(stmt);
-        when(stmt.executeQuery()).thenReturn(agentCursor);
-        return new Pair<>(storage, stmt);
+        verify(httpHelper).newRequest(URL);
+        verify(request).method(HttpMethod.DELETE);
+        verify(request).send();
+        verify(response).getStatus();
     }
 
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/storage/core/src/test/java/com/redhat/thermostat/storage/internal/dao/AgentInformationTypeAdapterTest.java	Fri May 05 12:14:51 2017 -0400
@@ -0,0 +1,91 @@
+/*
+ * 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 java.util.Arrays;
+import java.util.List;
+
+import org.junit.Test;
+
+import com.redhat.thermostat.storage.internal.dao.AgentInfoDAOImpl.AgentInformationUpdate;
+import com.redhat.thermostat.storage.internal.dao.AgentInformationTypeAdapter.AgentInformationUpdateTypeAdapter;
+import com.redhat.thermostat.storage.model.AgentInformation;
+
+public class AgentInformationTypeAdapterTest {
+    
+    @Test
+    public void testWrite() throws Exception {
+        AgentInformationTypeAdapter adapter = new AgentInformationTypeAdapter();
+        final String expected = "[{\"agentId\":\"agent1\",\"startTime\":{\"$numberLong\":\"4000\"},"
+                + "\"stopTime\":{\"$numberLong\":\"6000\"},\"alive\":false,\"configListenAddress\":\"127.0.0.1:12000\"},"
+                + "{\"agentId\":\"agent2\",\"startTime\":{\"$numberLong\":\"5000\"},\"stopTime\":{\"$numberLong\":\"0\"},"
+                + "\"alive\":true,\"configListenAddress\":\"1.2.3.4:12000\"}]";
+        
+        AgentInformation first = createAgentInformation("agent1", 4000L, 6000L, false, "127.0.0.1:12000");
+        AgentInformation second = createAgentInformation("agent2", 5000L, 0L, true, "1.2.3.4:12000");
+        List<AgentInformation> infos = Arrays.asList(first, second);
+        
+        String json = adapter.toJson(infos);
+        assertEquals(expected, json);
+    }
+    
+    @Test
+    public void testUpdate() throws Exception {
+        AgentInformationUpdateTypeAdapter adapter = new AgentInformationUpdateTypeAdapter();
+        final String expected = "{\"set\":{\"startTime\":{\"$numberLong\":\"5000\"},"
+                + "\"stopTime\":{\"$numberLong\":\"7000\"},\"alive\":false,\"configListenAddress\":\"1.2.3.4:12000\"}}";
+        
+        AgentInformation info = createAgentInformation("agent2", 5000L, 7000L, false, "1.2.3.4:12000");
+        AgentInformationUpdate update = new AgentInformationUpdate(info);
+        
+        String json = adapter.toJson(update);
+        assertEquals(expected, json);
+    }
+    
+    private AgentInformation createAgentInformation(String agentId, long startTime, long stopTime, 
+            boolean alive, String configListenAddress) {
+        AgentInformation info = new AgentInformation(agentId);
+        info.setStartTime(startTime);
+        info.setStopTime(stopTime);
+        info.setAlive(alive);
+        info.setConfigListenAddress(configListenAddress);
+        return info;
+    }
+
+}