changeset 2650:c6e6f0375b45

Port VmTlabStatDAO to communicate with Web Gateway. Reviewed By: ebaron Review Thread: http://icedtea.classpath.org/pipermail/thermostat/2017-May/023033.html
author Joshua Matsuoka <jmatsuok@redhat.com>
date Fri, 12 May 2017 10:26:38 -0400
parents 7184d65b1aa7
children 7be582a246e9
files plugins/vm-memory/common/src/main/java/com/redhat/thermostat/vm/memory/common/VmTlabStatDAO.java plugins/vm-memory/common/src/main/java/com/redhat/thermostat/vm/memory/common/internal/Activator.java plugins/vm-memory/common/src/main/java/com/redhat/thermostat/vm/memory/common/internal/VmTlabStatDAOImpl.java plugins/vm-memory/common/src/main/java/com/redhat/thermostat/vm/memory/common/internal/VmTlabStatDAOImplStatementDescriptorRegistration.java plugins/vm-memory/common/src/test/java/com/redhat/thermostat/vm/memory/common/internal/ActivatorTest.java plugins/vm-memory/common/src/test/java/com/redhat/thermostat/vm/memory/common/internal/VmTlabStatDAOTest.java
diffstat 6 files changed, 201 insertions(+), 167 deletions(-) [+]
line wrap: on
line diff
--- a/plugins/vm-memory/common/src/main/java/com/redhat/thermostat/vm/memory/common/VmTlabStatDAO.java	Fri May 12 10:05:08 2017 -0400
+++ b/plugins/vm-memory/common/src/main/java/com/redhat/thermostat/vm/memory/common/VmTlabStatDAO.java	Fri May 12 10:26:38 2017 -0400
@@ -73,20 +73,6 @@
                     KEY_TOTAL_FAST_WASTE, KEY_MAX_FAST_WASTE),
             Arrays.<Key<?>>asList(Key.TIMESTAMP));
 
-    @Deprecated
-    public VmTlabStat getNewestStat(VmRef ref);
-
-    @Deprecated
-    public VmTlabStat getOldestStat(VmRef ref);
-
-    @Deprecated
-    public List<VmTlabStat> getLatestStats(VmRef vm, long since);
-
-    public List<VmTlabStat> getLatestStats(AgentId agentId, VmId vmId, long since);
-
-    @Deprecated
-    public List<VmTlabStat> getStats(VmRef vm, long since, long to);
-
     public void putStat(VmTlabStat stat);
 
 }
--- a/plugins/vm-memory/common/src/main/java/com/redhat/thermostat/vm/memory/common/internal/Activator.java	Fri May 12 10:05:08 2017 -0400
+++ b/plugins/vm-memory/common/src/main/java/com/redhat/thermostat/vm/memory/common/internal/Activator.java	Fri May 12 10:26:38 2017 -0400
@@ -53,6 +53,8 @@
 
     @Override
     public void start(BundleContext context) throws Exception {
+        VmTlabStatDAO vmTlabStatDao = new VmTlabStatDAOImpl();
+        context.registerService(VmTlabStatDAO.class.getName(), vmTlabStatDao, null);
         VmMemoryStatDAO vmMemoryStatDao = new VmMemoryStatDAOImpl();
         context.registerService(VmMemoryStatDAO.class.getName(), vmMemoryStatDao, null);
     }
--- a/plugins/vm-memory/common/src/main/java/com/redhat/thermostat/vm/memory/common/internal/VmTlabStatDAOImpl.java	Fri May 12 10:05:08 2017 -0400
+++ b/plugins/vm-memory/common/src/main/java/com/redhat/thermostat/vm/memory/common/internal/VmTlabStatDAOImpl.java	Fri May 12 10:26:38 2017 -0400
@@ -36,111 +36,105 @@
 
 package com.redhat.thermostat.vm.memory.common.internal;
 
+import java.io.IOException;
+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 com.redhat.thermostat.common.utils.LoggingUtils;
-import com.redhat.thermostat.storage.core.AgentId;
-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.core.VmBoundaryPojoGetter;
-import com.redhat.thermostat.storage.core.VmId;
-import com.redhat.thermostat.storage.core.VmLatestPojoListGetter;
-import com.redhat.thermostat.storage.core.VmRef;
-import com.redhat.thermostat.storage.core.VmTimeIntervalPojoListGetter;
 import com.redhat.thermostat.storage.dao.AbstractDao;
-import com.redhat.thermostat.storage.dao.AbstractDaoStatement;
 import com.redhat.thermostat.vm.memory.common.VmTlabStatDAO;
 import com.redhat.thermostat.vm.memory.common.model.VmTlabStat;
 
+import org.eclipse.jetty.client.HttpClient;
+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;
+
 class VmTlabStatDAOImpl extends AbstractDao implements VmTlabStatDAO {
 
+    private static final String GATEWAY_URL = "http://localhost:30000"; // TODO configurable
+    private static final String GATEWAY_PATH = "/jvm-memory/0.0.2/";
+    private static final String CONTENT_TYPE = "application/json";
+
     private static final Logger logger = LoggingUtils.getLogger(VmTlabStatDAOImpl.class);
 
-    static final String DESC_ADD_VM_TLAB_STAT = "ADD " + vmTlabStatsCategory.getName() +
-            " SET '" + Key.AGENT_ID.getName() + "' = ?s , " +
-                 "'" + Key.VM_ID.getName() + "' = ?s , " +
-                 "'" + Key.TIMESTAMP.getName() + "' = ?l , " +
-                 "'" + KEY_TOTAL_ALLOCATING_THREADS.getName() + "' = ?l , " +
-                 "'" + KEY_TOTAL_ALLOCATIONS.getName() + "' = ?l , " +
-                 "'" + KEY_TOTAL_REFILLS.getName() + "' = ?l , " +
-                 "'" + KEY_MAX_REFILLS.getName() + "' = ?l , " +
-                 "'" + KEY_TOTAL_SLOW_ALLOCATIONS.getName() + "' = ?l , " +
-                 "'" + KEY_MAX_SLOW_ALLOCATIONS.getName() + "' = ?l , " +
-                 "'" + KEY_TOTAL_GC_WASTE.getName() + "' = ?l , " +
-                 "'" + KEY_MAX_GC_WASTE.getName() + "' = ?l , " +
-                 "'" + KEY_TOTAL_SLOW_WASTE.getName() + "' = ?l , " +
-                 "'" + KEY_MAX_SLOW_WASTE.getName() + "' = ?l , " +
-                 "'" + KEY_TOTAL_FAST_WASTE.getName() + "' = ?l , " +
-                 "'" + KEY_MAX_FAST_WASTE.getName() + "' = ?l";
+    private final HttpClient client;
+    private final HttpHelper httpHelper;
+    private final JsonHelper jsonHelper;
 
-    private final Storage storage;
-    private final VmLatestPojoListGetter<VmTlabStat> latestGetter;
-    private final VmTimeIntervalPojoListGetter<VmTlabStat> intervalGetter;
-    private final VmBoundaryPojoGetter<VmTlabStat> boundaryGetter;
-
-    VmTlabStatDAOImpl(Storage storage) {
-        this.storage = storage;
-        storage.registerCategory(vmTlabStatsCategory);
-        latestGetter = new VmLatestPojoListGetter<>(storage, vmTlabStatsCategory);
-        intervalGetter = new VmTimeIntervalPojoListGetter<>(storage, vmTlabStatsCategory);
-        boundaryGetter = new VmBoundaryPojoGetter<>(storage, vmTlabStatsCategory);
+    VmTlabStatDAOImpl() throws Exception {
+        this(new HttpClient(), new HttpHelper(), new JsonHelper(new VmTlabStatTypeAdapter()));
     }
 
-    @Override
-    public VmTlabStat getNewestStat(VmRef ref) {
-        return boundaryGetter.getNewestStat(ref);
+    VmTlabStatDAOImpl(HttpClient client, HttpHelper httpHelper, JsonHelper jsonHelper) throws Exception {
+        this.client = client;
+        this.httpHelper = httpHelper;
+        this.jsonHelper = jsonHelper;
+
+        this.httpHelper.startClient(this.client);
     }
 
-    @Override
-    public VmTlabStat getOldestStat(VmRef ref) {
-        return boundaryGetter.getOldestStat(ref);
-    }
 
     @Override
     public void putStat(final VmTlabStat stat) {
-        executeStatement(new AbstractDaoStatement<VmTlabStat>(storage, vmTlabStatsCategory, DESC_ADD_VM_TLAB_STAT) {
-            @Override
-            public PreparedStatement<VmTlabStat> customize(PreparedStatement<VmTlabStat> preparedStatement) {
-                preparedStatement.setString(0, stat.getAgentId());
-                preparedStatement.setString(1, stat.getVmId());
-                preparedStatement.setLong(2, stat.getTimeStamp());
-                preparedStatement.setLong(3, stat.getTotalAllocatingThreads());
-                preparedStatement.setLong(4, stat.getTotalAllocations());
-                preparedStatement.setLong(5, stat.getTotalRefills());
-                preparedStatement.setLong(6, stat.getMaxRefills());
-                preparedStatement.setLong(7, stat.getTotalSlowAllocations());
-                preparedStatement.setLong(8, stat.getMaxSlowAllocations());
-                preparedStatement.setLong(9, stat.getTotalGcWaste());
-                preparedStatement.setLong(10, stat.getMaxGcWaste());
-                preparedStatement.setLong(11, stat.getTotalSlowWaste());
-                preparedStatement.setLong(12, stat.getMaxSlowWaste());
-                preparedStatement.setLong(13, stat.getTotalFastWaste());
-                preparedStatement.setLong(14, stat.getMaxFastWaste());
-                return preparedStatement;
-            }
-        });
+        try {
+            String json = jsonHelper.toJson(Arrays.asList(stat));
+            StringContentProvider provider = httpHelper.createContentProvider(json);
+
+            String url = GATEWAY_URL + GATEWAY_PATH;
+            Request httpRequest = client.newRequest(url);
+            httpRequest.method(HttpMethod.POST);
+            httpRequest.content(provider, CONTENT_TYPE);
+            sendRequest(httpRequest);
+        } catch (Exception e) {
+            logger.log(Level.WARNING, "Failed to send VmTlabStat to Web Gateway", e);
+        }
     }
 
-    @Override
-    public List<VmTlabStat> getLatestStats(VmRef ref, long since) {
-        return latestGetter.getLatest(ref, since);
-    }
-
-    @Override
-    public List<VmTlabStat> getLatestStats(AgentId agentId, VmId vmId, long since) {
-        return latestGetter.getLatest(agentId, vmId, since);
-    }
-
-    @Override
-    public List<VmTlabStat> getStats(VmRef ref, long since, long to) {
-        return intervalGetter.getLatest(ref, since, to);
+    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());
+        }
     }
 
     @Override
     protected Logger getLogger() {
         return logger;
     }
+
+    static class JsonHelper {
+
+        private final VmTlabStatTypeAdapter adapter;
+
+        public JsonHelper(VmTlabStatTypeAdapter adapter) {
+            this.adapter = adapter;
+        }
+
+        String toJson(List<VmTlabStat> stats) throws IOException {
+            return adapter.toJson(stats);
+        }
+    }
+
+    // For testing purposes
+    static class HttpHelper {
+
+        void startClient(HttpClient httpClient) throws Exception {
+            httpClient.start();
+        }
+
+        StringContentProvider createContentProvider(String content) {
+            return new StringContentProvider(content);
+        }
+
+    }
 }
 
--- a/plugins/vm-memory/common/src/main/java/com/redhat/thermostat/vm/memory/common/internal/VmTlabStatDAOImplStatementDescriptorRegistration.java	Fri May 12 10:05:08 2017 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,74 +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.vm.memory.common.internal;
-
-import java.util.HashSet;
-import java.util.Set;
-
-import com.redhat.thermostat.storage.core.VmBoundaryPojoGetter;
-import com.redhat.thermostat.storage.core.VmLatestPojoListGetter;
-import com.redhat.thermostat.storage.core.VmTimeIntervalPojoListGetter;
-import com.redhat.thermostat.storage.core.auth.StatementDescriptorRegistration;
-import com.redhat.thermostat.vm.memory.common.VmTlabStatDAO;
-
-public class VmTlabStatDAOImplStatementDescriptorRegistration implements
-        StatementDescriptorRegistration {
-
-    static final String latestDescriptor = String.format(VmLatestPojoListGetter.VM_LATEST_QUERY_FORMAT,
-            VmTlabStatDAO.vmTlabStatsCategory.getName());
-    static final String rangeDescriptor = String.format(VmTimeIntervalPojoListGetter.VM_INTERVAL_QUERY_FORMAT,
-            VmTlabStatDAO.vmTlabStatsCategory.getName());
-    static final String latestStatDescriptor = String.format(VmBoundaryPojoGetter.DESC_NEWEST_VM_STAT,
-            VmTlabStatDAO.vmTlabStatsCategory.getName());
-    static final String oldestStatDescriptor = String.format(VmBoundaryPojoGetter.DESC_OLDEST_VM_STAT,
-            VmTlabStatDAO.vmTlabStatsCategory.getName());
-
-    @Override
-    public Set<String> getStatementDescriptors() {
-        Set<String> descs = new HashSet<>(5);
-        descs.add(latestStatDescriptor);
-        descs.add(oldestStatDescriptor);
-        descs.add(VmTlabStatDAOImpl.DESC_ADD_VM_TLAB_STAT);
-
-        descs.add(latestDescriptor);
-        descs.add(rangeDescriptor);
-
-        return descs;
-    }
-
-}
-
--- a/plugins/vm-memory/common/src/test/java/com/redhat/thermostat/vm/memory/common/internal/ActivatorTest.java	Fri May 12 10:05:08 2017 -0400
+++ b/plugins/vm-memory/common/src/test/java/com/redhat/thermostat/vm/memory/common/internal/ActivatorTest.java	Fri May 12 10:26:38 2017 -0400
@@ -61,7 +61,7 @@
         activator.stop(context);
 
         assertEquals(0, context.getServiceListeners().size());
-        assertEquals(1, context.getAllServices().size());
+        assertEquals(2, context.getAllServices().size());
     }
 
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/vm-memory/common/src/test/java/com/redhat/thermostat/vm/memory/common/internal/VmTlabStatDAOTest.java	Fri May 12 10:26:38 2017 -0400
@@ -0,0 +1,126 @@
+/*
+ * 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.vm.memory.common.internal;
+
+import com.redhat.thermostat.vm.memory.common.VmTlabStatDAO;
+import com.redhat.thermostat.vm.memory.common.model.VmTlabStat;
+import org.eclipse.jetty.client.HttpClient;
+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 java.util.Arrays;
+
+import static org.mockito.Matchers.anyListOf;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import static com.redhat.thermostat.vm.memory.common.internal.VmTlabStatDAOImpl.HttpHelper;
+import static com.redhat.thermostat.vm.memory.common.internal.VmTlabStatDAOImpl.JsonHelper;
+
+/**
+ * Created by jmatsuok on 03/05/17.
+ */
+public class VmTlabStatDAOTest {
+
+    private HttpClient httpClient;
+    private HttpHelper httpHelper;
+    private JsonHelper jsonHelper;
+    private StringContentProvider contentProvider;
+    private Request request;
+    private ContentResponse response;
+    private static final String JSON = "{\"this\":\"is\",\"test\":\"JSON\"}";
+    private static final String VM_ID = "0xcafe";
+    private static final String AGENT_ID = "agent";
+    private static final String CONTENT_TYPE = "application/json";
+    private static final String GATEWAY_URL = "http://localhost:30000"; // TODO configurable
+    private static final String GATEWAY_PATH = "/jvm-memory/0.0.2/";
+
+    @Before
+    public void setUp() throws Exception {
+        httpClient = mock(HttpClient.class);
+        request = mock(Request.class);
+        when(httpClient.newRequest(anyString())).thenReturn(request);
+        response = mock(ContentResponse.class);
+        when(response.getStatus()).thenReturn(HttpStatus.OK_200);
+        when(request.send()).thenReturn(response);
+
+        httpHelper = mock(HttpHelper.class);
+        contentProvider = mock(StringContentProvider.class);
+        when(httpHelper.createContentProvider(anyString())).thenReturn(contentProvider);
+        jsonHelper = mock(JsonHelper.class);
+        when(jsonHelper.toJson(anyListOf(VmTlabStat.class))).thenReturn(JSON);
+    }
+
+    @Test
+    public void verifyPutStat() throws Exception {
+        VmTlabStat stat = new VmTlabStat();
+        stat.setAgentId(AGENT_ID);
+        stat.setVmId(VM_ID);
+        stat.setTimeStamp(1000l);
+        stat.setTotalAllocatingThreads(10l);
+        stat.setTotalAllocations(1342l);
+        stat.setTotalRefills(58l);
+        stat.setMaxRefills(90l);
+        stat.setTotalSlowAllocations(343l);
+        stat.setMaxSlowAllocations(989l);
+        stat.setTotalGcWaste(788l);
+        stat.setMaxGcWaste(992l);
+        stat.setTotalSlowWaste(899l);
+        stat.setMaxSlowWaste(634l);
+        stat.setTotalFastWaste(678l);
+        stat.setMaxFastWaste(333l);
+
+        VmTlabStatDAO dao = new VmTlabStatDAOImpl(httpClient, httpHelper, jsonHelper);
+        dao.putStat(stat);
+
+        String url = GATEWAY_URL + GATEWAY_PATH;
+        verify(httpClient).newRequest(url);
+        verify(request).method(HttpMethod.POST);
+        verify(jsonHelper).toJson(Arrays.asList(stat));
+        verify(httpHelper).createContentProvider(JSON);
+        verify(request).content(contentProvider, CONTENT_TYPE);
+        verify(request).send();
+        verify(response).getStatus();
+    }
+}