Author: ivol37 at gmail.com
Date: Tue Jan 11 12:45:54 2011
New Revision: 591

Log:
simple cassandra client gadget, useful for testing

Added:
   sandbox/ivol/cassandra-gadget/
   sandbox/ivol/cassandra-gadget/pom.xml
   sandbox/ivol/cassandra-gadget/src/
   sandbox/ivol/cassandra-gadget/src/main/
   sandbox/ivol/cassandra-gadget/src/main/java/
   sandbox/ivol/cassandra-gadget/src/main/java/org/
   sandbox/ivol/cassandra-gadget/src/main/java/org/amdatu/
   sandbox/ivol/cassandra-gadget/src/main/java/org/amdatu/cassandra/
   sandbox/ivol/cassandra-gadget/src/main/java/org/amdatu/cassandra/gadget/
   sandbox/ivol/cassandra-gadget/src/main/java/org/amdatu/cassandra/gadget/osgi/
   
sandbox/ivol/cassandra-gadget/src/main/java/org/amdatu/cassandra/gadget/osgi/Activator.java
   
sandbox/ivol/cassandra-gadget/src/main/java/org/amdatu/cassandra/gadget/service/
   
sandbox/ivol/cassandra-gadget/src/main/java/org/amdatu/cassandra/gadget/service/CassandraClientGadgetImpl.java
   sandbox/ivol/cassandra-gadget/src/main/resources/
   sandbox/ivol/cassandra-gadget/src/main/resources/jsp/
   
sandbox/ivol/cassandra-gadget/src/main/resources/jsp/CassandraClientGadget.jsp
   sandbox/ivol/cassandra-gadget/src/main/resources/static/
   sandbox/ivol/cassandra-gadget/src/main/resources/static/images/
   
sandbox/ivol/cassandra-gadget/src/main/resources/static/images/cassandra.jpeg   
(contents, props changed)

Added: sandbox/ivol/cassandra-gadget/pom.xml
==============================================================================
--- (empty file)
+++ sandbox/ivol/cassandra-gadget/pom.xml       Tue Jan 11 12:45:54 2011
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<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/maven-v4_0_0.xsd";>
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <groupId>org.amdatu</groupId>
+    <artifactId>org.amdatu.cassandra</artifactId>
+    <version>0.1.0-SNAPSHOT</version>
+  </parent>
+  <groupId>org.amdatu.cassandra</groupId>
+  <artifactId>gadget</artifactId>
+  <packaging>bundle</packaging>
+  <name>Amdatu Cassandra - Client gadget</name>
+  <description>Provides a cassandra client gadget</description>
+
+  <dependencies>
+    <dependency>
+      <groupId>org.amdatu.web</groupId>
+      <artifactId>httpcontext</artifactId>
+      <version>${platform.version}</version>
+      <scope>provided</scope>
+      <type>bundle</type>
+    </dependency>
+    <dependency>
+      <groupId>org.amdatu.cassandra</groupId>
+      <artifactId>application</artifactId>
+      <scope>provided</scope>
+      <type>bundle</type>
+    </dependency>
+    <dependency>
+      <groupId>org.amdatu.opensocial</groupId>
+      <artifactId>shindig</artifactId>
+      <scope>provided</scope>
+      <version>${platform.version}</version>
+      <type>bundle</type>
+    </dependency>
+    <dependency>
+      <groupId>org.amdatu.opensocial</groupId>
+      <artifactId>gadgetmanagement</artifactId>
+      <version>${platform.version}</version>
+      <scope>provided</scope>
+      <type>bundle</type>
+    </dependency>
+    <dependency>
+      <groupId>org.json</groupId>
+      <artifactId>json</artifactId>
+      <version>20090211</version>
+      <scope>compile</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.amdatu.web.rest</groupId>
+      <artifactId>jaxrs</artifactId>
+      <version>${platform.version}</version>
+      <scope>provided</scope>
+      <type>bundle</type>
+    </dependency>
+  </dependencies>
+
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.felix</groupId>
+        <artifactId>maven-bundle-plugin</artifactId>
+        <configuration>
+          <instructions>
+            
<Bundle-Activator>org.amdatu.cassandra.gadget.osgi.Activator</Bundle-Activator>
+            
<Bundle-SymbolicName>org.amdatu.cassandra.gadget</Bundle-SymbolicName>
+            <Embed-Dependency>*;scope=compile</Embed-Dependency>
+            <Embed-Transitive>true</Embed-Transitive>
+          </instructions>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+</project>

Added: 
sandbox/ivol/cassandra-gadget/src/main/java/org/amdatu/cassandra/gadget/osgi/Activator.java
==============================================================================
--- (empty file)
+++ 
sandbox/ivol/cassandra-gadget/src/main/java/org/amdatu/cassandra/gadget/osgi/Activator.java
 Tue Jan 11 12:45:54 2011
@@ -0,0 +1,53 @@
+/*
+    Copyright (C) 2010 Amdatu.org
+
+    This program 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 3 of the License, or
+    (at your option) any later version.
+
+    This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.amdatu.cassandra.gadget.osgi;
+
+import org.amdatu.cassandra.application.CassandraDaemonService;
+import org.amdatu.cassandra.gadget.service.CassandraClientGadgetImpl;
+import org.amdatu.opensocial.gadgetmanagement.GadgetManagement;
+import org.amdatu.web.httpcontext.HttpContextServiceFactory;
+import org.amdatu.web.httpcontext.ResourceProvider;
+import org.apache.felix.dm.DependencyActivatorBase;
+import org.apache.felix.dm.DependencyManager;
+import org.osgi.framework.BundleContext;
+import org.osgi.service.log.LogService;
+
+/**
+ * This is the OSGi activator for this gadget bundle.
+ * @author ivol
+ */
+public class Activator extends DependencyActivatorBase {
+    // The resource identifier for this bundle. Resources are only considered 
to be 'ours' when
+    // it is prefixed with this id
+    public final static String RESOURCE_ID = "gadget/cassandra";
+
+    @Override
+    public void init(BundleContext context, DependencyManager manager) throws 
Exception {
+        // Create the LoginServiceImpl which has dependencies with the Log 
service
+        // and HTTP service
+        
manager.add(createComponent().setInterface(ResourceProvider.class.getName(), 
null)
+            .setImplementation(CassandraClientGadgetImpl.class)
+            
.add(createServiceDependency().setService(LogService.class).setRequired(true))
+            
.add(createServiceDependency().setService(GadgetManagement.class).setRequired(true))
+            
.add(createServiceDependency().setService(HttpContextServiceFactory.class).setRequired(true))
+            
.add(createServiceDependency().setService(CassandraDaemonService.class).setRequired(true)));
+    }
+
+    @Override
+    public void destroy(BundleContext arg0, DependencyManager arg1) throws 
Exception {
+    }
+}

Added: 
sandbox/ivol/cassandra-gadget/src/main/java/org/amdatu/cassandra/gadget/service/CassandraClientGadgetImpl.java
==============================================================================
--- (empty file)
+++ 
sandbox/ivol/cassandra-gadget/src/main/java/org/amdatu/cassandra/gadget/service/CassandraClientGadgetImpl.java
      Tue Jan 11 12:45:54 2011
@@ -0,0 +1,205 @@
+/*
+    Copyright (C) 2010 Amdatu.org
+
+    This program 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 3 of the License, or
+    (at your option) any later version.
+
+    This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.amdatu.cassandra.gadget.service;
+
+import java.io.UnsupportedEncodingException;
+import java.net.URL;
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.core.MediaType;
+
+import org.amdatu.cassandra.application.CassandraDaemonService;
+import org.amdatu.cassandra.gadget.osgi.Activator;
+import org.amdatu.opensocial.gadgetmanagement.GadgetManagement;
+import org.amdatu.opensocial.shindig.GadgetCategory;
+import org.amdatu.opensocial.shindig.GadgetDefinition;
+import org.amdatu.web.httpcontext.HttpContextServiceFactory;
+import org.amdatu.web.httpcontext.ResourceProvider;
+import org.apache.cassandra.thrift.ColumnParent;
+import org.apache.cassandra.thrift.ConsistencyLevel;
+import org.apache.cassandra.thrift.InvalidRequestException;
+import org.apache.cassandra.thrift.KeyRange;
+import org.apache.cassandra.thrift.KeySlice;
+import org.apache.cassandra.thrift.NotFoundException;
+import org.apache.cassandra.thrift.SlicePredicate;
+import org.apache.cassandra.thrift.SliceRange;
+import org.apache.cassandra.thrift.TimedOutException;
+import org.apache.cassandra.thrift.UnavailableException;
+import org.apache.cassandra.thrift.Cassandra.Iface;
+import org.apache.felix.dm.Component;
+import org.apache.thrift.TException;
+import org.osgi.framework.BundleContext;
+import org.osgi.service.log.LogService;
+
+/**
+ * This service provides the cassandra client gadget.
+ * @author ivol
+ */
+ at Path("cassandra/client")
+public class CassandraClientGadgetImpl implements ResourceProvider {
+    // Service dependencies, injected by the Felix dependency manager
+    private volatile LogService m_logService;
+    private volatile BundleContext m_bundleContext;
+    private volatile HttpContextServiceFactory m_httpContextServiceFactory;
+    private volatile GadgetManagement m_gadgetManagement;
+
+    private volatile CassandraDaemonService m_daemon;
+
+    // The private HTTP context service for this bundle
+    private Component m_httpContextComponent;
+
+    /**
+     * The init() method is invoked by the Felix dependency manager.
+     */
+    public void start() {
+        // Create our own http context service which registers static 
resources and JSPs automatically
+        m_httpContextComponent = 
m_httpContextServiceFactory.create(m_bundleContext, this);
+
+        // Register the gadget with the Gadget management service. Note that 
we can do this as
+        // many times as we want, since the gadget URL is the unique identifier
+        String gadgetSpecUrl = "/" + Activator.RESOURCE_ID + 
"/jsp/CassandraClientGadget.jsp";
+        GadgetDefinition gadgetDef = new GadgetDefinition(gadgetSpecUrl, 
GadgetCategory.AMDATU_PLATFORM, true);
+        gadgetDef.setRank(0);
+        m_gadgetManagement.addGadget(gadgetDef);
+        m_logService.log(LogService.LOG_INFO, "Cassandra client gadget 
registered on URL '" + gadgetSpecUrl + "'");
+
+        m_logService.log(LogService.LOG_INFO, getClass().getName() + " service 
started");
+    }
+
+    // The destroy() method is automatically invoked by the Felix dependency 
manager
+    public void destroy() {
+        // Stop the HTTP context service we created ourselves
+        m_httpContextComponent.stop();
+    }
+
+    public URL getResource(String name) {
+        return null;
+    }
+
+    public String getResourceId() {
+        return Activator.RESOURCE_ID;
+    }
+
+    /**
+     * This method can be used to check the availability of the Login Service.
+     * 
+     * @return The text "Login service online"
+     */
+    @GET
+    @Produces( { MediaType.TEXT_HTML })
+    public String getAll() {
+        try {
+            String html = "<table 
border=\"1\"><tr><th>keyspace</th><th>ColumnFamily</th><th>Rows</th></tr>";
+            List<String> keyspaces = m_daemon.getKeyspaces();
+            for (String keyspace : keyspaces) {
+                List<String> columnFamilies = 
m_daemon.getColumnFamilies(keyspace);
+                for (String columnFamily : columnFamilies) {
+                    String rowKeyHtml = "";
+                    List<String> rowKeys = getRowKeys(keyspace, columnFamily);
+                    int i=1;
+                    for (String rowKey : rowKeys) {
+                        rowKeyHtml += "("+i+") "+rowKey + "<br/>";
+                        i++;
+                    }
+                    html +=  "<tr><td>" + keyspace + "</td><td>" + 
columnFamily + "</td><td>" + rowKeyHtml + "</td></tr>";
+                }
+            }
+            return html;
+        }
+        catch (TException e) {
+            e.printStackTrace();
+            throw new WebApplicationException(e);
+        }
+        catch (InvalidRequestException e) {
+            e.printStackTrace();
+            throw new WebApplicationException(e);
+        }
+        catch (NotFoundException e) {
+            e.printStackTrace();
+            throw new WebApplicationException(e);
+        }
+        catch (UnsupportedEncodingException e) {
+            e.printStackTrace();
+            throw new WebApplicationException(e);
+        }
+        catch (UnavailableException e) {
+            e.printStackTrace();
+            throw new WebApplicationException(e);
+        }
+        catch (TimedOutException e) {
+            e.printStackTrace();
+            throw new WebApplicationException(e);
+        }
+    }
+
+
+    // Maximum amount of rows to retrieve in queries
+    private final static int ROW_LIMIT = 1000000;
+
+    // Maximum amount of columns to retrieve in queries
+    private final static int COLUMN_LIMIT = 1000000;
+
+    // Empty byte array
+    private final static ByteBuffer EMPTY = ByteBuffer.wrap(new byte[0]);
+
+    // Investigation pointed out that retrying succeeds after about 10 times.
+    private final static int MAX_RETRIES = 10;
+
+    /**
+     * Returns all keys for a certain ColumnFamily (think of all primary keys 
of all records in a certain table)
+     * @throws TException
+     * @throws InvalidRequestException
+     * @throws TimedOutException
+     * @throws UnavailableException
+     * @throws UnsupportedEncodingException
+     */
+    public List<String> getRowKeys(String keyspace, String columnFamilyName) 
throws InvalidRequestException, TException, UnavailableException, 
TimedOutException, UnsupportedEncodingException {
+        ColumnParent columnParent = new ColumnParent(columnFamilyName);
+        SlicePredicate p = new SlicePredicate();
+
+        // Create and set slice range with a maximum of COLUMN_LIMIT columns
+        SliceRange sliceRange = new SliceRange(EMPTY, EMPTY, false, 
COLUMN_LIMIT);
+        p.setSlice_range(sliceRange);
+
+        // Set key range to maximum ROW_LIMIT results
+        KeyRange range = new KeyRange(ROW_LIMIT);
+        range.setStart_key(EMPTY);
+        range.setEnd_key(EMPTY);
+
+        Iface cs = m_daemon.getCassandraServer();
+        cs.set_keyspace(keyspace);
+        List<KeySlice> keySlices = cs.get_range_slices(columnParent, p, range, 
ConsistencyLevel.ONE);
+
+        List<String> keys = new ArrayList<String>();
+        for (KeySlice keySlice : keySlices) {
+            // This may be a bangling row key marked for removal, check that!
+            if (keySlice.getColumnsSize() > 0) {
+                keys.add(new String(keySlice.getKey(), "UTF-8"));
+            }
+        }
+        m_logService.log(LogService.LOG_DEBUG, "Found " + keys.size() + " keys 
for ColumnFamily '"
+            + columnFamilyName
+            + "' in getRowKeys");
+        return keys;
+    }
+}
\ No newline at end of file

Added: 
sandbox/ivol/cassandra-gadget/src/main/resources/jsp/CassandraClientGadget.jsp
==============================================================================
--- (empty file)
+++ 
sandbox/ivol/cassandra-gadget/src/main/resources/jsp/CassandraClientGadget.jsp  
    Tue Jan 11 12:45:54 2011
@@ -0,0 +1,67 @@
+<%@ page language="java" session="false" buffer="none" %>
+<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"; %>
+
+<c:set var="baseRestUrl" value="/rest/cassandra/client"/>
+<c:set var="gadgetBaseUrl" value="/gadget/cassandra"/>
+
+<?xml version="1.0" encoding="UTF-8" ?>
+<!--
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+-->
+
+<Module>
+  <ModulePrefs
+    title="Amdatu Cassandra Client Gadget"
+    description="Provides a cassandra client interface"
+    author="Ivo Ladage-van Doorn"
+    screenshot="${gadgetBaseUrl}/static/images/cassandra.jpeg"
+    icon="/static/images/cassandra.jpeg"
+    height="400">
+    <Require feature="osapi"/>
+    <Require feature="dynamic-height"/>
+  </ModulePrefs>
+  <Content type="html">
+    <![CDATA[
+    <link rel="stylesheet" href="/dashboard/static/css/dashboard.css">
+
+    <script type="text/javascript" 
src="/dashboard/static/js/lib/jquery-1.4.2.min.js"></script>
+    <script type="text/javascript" 
src="/dashboard/static/js/lib/jquery-ui-1.8.2.custom.min.js"></script>
+
+    <div id="result"></div>
+
+    <script type="text/javascript">
+      function getAll() {
+        var url = "${baseRestUrl}";
+        jQuery.ajax({
+          url: url,
+          type: "GET",
+          dataType: "html",
+          async:true,
+          success: function(response) {
+             document.getElementById("result").innerHTML = response;
+             gadgets.window.adjustHeight();
+            }
+          }
+        );
+      }
+
+      getAll();
+    </script>
+    ]]>
+  </Content>
+</Module>

Added: 
sandbox/ivol/cassandra-gadget/src/main/resources/static/images/cassandra.jpeg
==============================================================================
Binary file. No diff available.

Reply via email to