changeset 535:6def633267ae

Expose RequestQueue as osgi service. Add an activator to the client-command bundle, move implementation classes for this bundle into private subpackage. reviewed-by: neugens review-thread: http://icedtea.classpath.org/pipermail/thermostat/2012-August/002676.html PR925
author Jon VanAlten <jon.vanalten@redhat.com>
date Thu, 16 Aug 2012 14:35:55 -0400
parents 5943d72a26b5
children 797047eb544a
files client/command/pom.xml client/command/src/main/java/com/redhat/thermostat/client/command/ConfigurationRequestContext.java client/command/src/main/java/com/redhat/thermostat/client/command/RequestEncoder.java client/command/src/main/java/com/redhat/thermostat/client/command/RequestQueue.java client/command/src/main/java/com/redhat/thermostat/client/command/ResponseDecoder.java client/command/src/main/java/com/redhat/thermostat/client/command/ResponseHandler.java client/command/src/main/java/com/redhat/thermostat/client/command/internal/Activator.java client/command/src/main/java/com/redhat/thermostat/client/command/internal/ConfigurationRequestContext.java client/command/src/main/java/com/redhat/thermostat/client/command/internal/RequestEncoder.java client/command/src/main/java/com/redhat/thermostat/client/command/internal/RequestQueueImpl.java client/command/src/main/java/com/redhat/thermostat/client/command/internal/ResponseDecoder.java client/command/src/main/java/com/redhat/thermostat/client/command/internal/ResponseHandler.java
diffstat 12 files changed, 476 insertions(+), 347 deletions(-) [+]
line wrap: on
line diff
--- a/client/command/pom.xml	Thu Aug 16 14:35:54 2012 -0400
+++ b/client/command/pom.xml	Thu Aug 16 14:35:55 2012 -0400
@@ -65,9 +65,20 @@
       <groupId>org.jboss.netty</groupId>
       <artifactId>netty</artifactId>
     </dependency>
+    <dependency>
+      <groupId>org.osgi</groupId>
+      <artifactId>org.osgi.core</artifactId>
+      <scope>provided</scope>
+    </dependency>
 
     <dependency>
       <groupId>com.redhat.thermostat</groupId>
+      <artifactId>thermostat-common-core</artifactId>
+      <version>${project.version}</version>
+      <type>bundle</type>
+    </dependency>
+    <dependency>
+      <groupId>com.redhat.thermostat</groupId>
       <artifactId>thermostat-common-command</artifactId>
       <version>${project.version}</version>
       <type>bundle</type>
@@ -85,10 +96,13 @@
         <configuration>
           <instructions>
             <Bundle-Vendor>Red Hat, Inc.</Bundle-Vendor>
-            <!-- >Bundle-Activator>com.redhat.thermostat.client.command.AgentConfigurationActivator</Bundle-Activator -->
+            <Bundle-Activator>com.redhat.thermostat.client.command.internal.Activator</Bundle-Activator>
             <Export-Package>
               com.redhat.thermostat.client.command
             </Export-Package>
+            <Private-Package>
+              com.redhat.thermostat.client.command.internal
+            </Private-Package>
             <!-- Do not autogenerate uses clauses in Manifests -->
             <_nouses>true</_nouses>
           </instructions>
--- a/client/command/src/main/java/com/redhat/thermostat/client/command/ConfigurationRequestContext.java	Thu Aug 16 14:35:54 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,93 +0,0 @@
-/*
- * Copyright 2012 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.client.command;
-
-import java.util.concurrent.Executors;
-
-import org.jboss.netty.bootstrap.Bootstrap;
-import org.jboss.netty.bootstrap.ClientBootstrap;
-import org.jboss.netty.channel.ChannelPipeline;
-import org.jboss.netty.channel.ChannelPipelineFactory;
-import org.jboss.netty.channel.Channels;
-import org.jboss.netty.channel.socket.nio.NioClientSocketChannelFactory;
-
-import com.redhat.thermostat.common.command.ConfigurationCommandContext;
-
-public class ConfigurationRequestContext extends ConfigurationCommandContext {
-
-    private final ClientBootstrap bootstrap;
-
-    ConfigurationRequestContext() {
-        this.bootstrap = createBootstrap();
-    }
-
-    @Override
-    public
-    Bootstrap getBootstrap() {
-        return bootstrap;
-    }
-
-    private ClientBootstrap createBootstrap() {
-        // Configure the client.
-        ClientBootstrap bootstrap = new ClientBootstrap(
-                new NioClientSocketChannelFactory(
-                        Executors.newCachedThreadPool(),
-                        Executors.newCachedThreadPool()));
-
-        // Set up the pipeline factory.
-        bootstrap.setPipelineFactory(new ClientPipelineFactory());
-
-        bootstrap.setOption("tcpNoDelay", true);
-        bootstrap.setOption("keepAlive", true);
-        bootstrap.setOption("reuseAddress", true);
-        bootstrap.setOption("connectTimeoutMillis", 100);
-        bootstrap.setOption("readWriteFair", true);
-        return bootstrap;
-    }
-
-    private class ClientPipelineFactory implements ChannelPipelineFactory {
-
-        @Override
-        public ChannelPipeline getPipeline() throws Exception {
-            ChannelPipeline pipeline = Channels.pipeline();
-            pipeline.addLast("decoder", new ResponseDecoder());
-            pipeline.addLast("encoder", new RequestEncoder());
-            return pipeline;
-        }
-        
-    }
-}
--- a/client/command/src/main/java/com/redhat/thermostat/client/command/RequestEncoder.java	Thu Aug 16 14:35:54 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,67 +0,0 @@
-/*
- * Copyright 2012 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.client.command;
-
-import org.jboss.netty.buffer.ChannelBuffer;
-import static org.jboss.netty.buffer.ChannelBuffers.wrappedBuffer;
-import org.jboss.netty.channel.ChannelHandlerContext;
-import org.jboss.netty.channel.Channels;
-import org.jboss.netty.channel.MessageEvent;
-
-import com.redhat.thermostat.common.command.EncodingHelper;
-import com.redhat.thermostat.common.command.MessageEncoder;
-import com.redhat.thermostat.common.command.Request;
-
-
-class RequestEncoder extends MessageEncoder {
-
-    @Override
-    public void writeRequested(ChannelHandlerContext ctx, MessageEvent e) {
-
-        Request request = (Request) e.getMessage();
-
-        // Request Type
-        String requestType = EncodingHelper.trimType(request.getType().toString());
-        byte[] message = requestType.getBytes();
-        ChannelBuffer typeBuffer = EncodingHelper.encode(message);
-
-        // Compose the full message.
-        ChannelBuffer buf = wrappedBuffer(typeBuffer);
-        Channels.write(ctx, e.getFuture(), buf);
-    }
-
-}
\ No newline at end of file
--- a/client/command/src/main/java/com/redhat/thermostat/client/command/RequestQueue.java	Thu Aug 16 14:35:54 2012 -0400
+++ b/client/command/src/main/java/com/redhat/thermostat/client/command/RequestQueue.java	Thu Aug 16 14:35:55 2012 -0400
@@ -36,64 +36,10 @@
 
 package com.redhat.thermostat.client.command;
 
-import java.util.concurrent.ArrayBlockingQueue;
-import java.util.concurrent.BlockingQueue;
-
-import org.jboss.netty.bootstrap.ClientBootstrap;
-import org.jboss.netty.channel.Channel;
-import org.jboss.netty.channel.ChannelFuture;
-
 import com.redhat.thermostat.common.command.Request;
 
-class RequestQueue {
-
-    private final BlockingQueue<Request> queue;
-    private final ConfigurationRequestContext ctx;
-    private boolean processing;
-
-    RequestQueue(ConfigurationRequestContext ctx) {
-        processing = false;
-        this.ctx = ctx;
-        queue = new ArrayBlockingQueue<Request>(16, true);
-    }
-
-    void putRequest(Request request) {
-        queue.add(request);
-    }
-
-    void startProcessingRequests() {
-        if (!processing) {
-            processing = true;
-            new QueueRunner().start();
-        }
-    }
+public interface RequestQueue {
 
-    void stopProcessingRequests() {
-        processing = false;
-    }
-
-    private class QueueRunner extends Thread {
+    public void putRequest(Request request);
 
-        @Override
-        public void run() {
-            while (processing) {
-                Request request = null;
-                try {
-                    request = queue.take();
-                } catch (InterruptedException e) {
-                    if (Thread.interrupted()) {
-                        Thread.currentThread().interrupt();
-                    }
-                }
-                if (request == null) {
-                    break;
-                }
-                ChannelFuture f = ((ClientBootstrap) ctx.getBootstrap()).connect(request.getTarget());
-                f.awaitUninterruptibly();
-                Channel c = f.getChannel();
-                c.getPipeline().addLast("responseHandler", new ResponseHandler(request));
-                c.write(request);
-            }
-        }
-    }
 }
--- a/client/command/src/main/java/com/redhat/thermostat/client/command/ResponseDecoder.java	Thu Aug 16 14:35:54 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,60 +0,0 @@
-/*
- * Copyright 2012 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.client.command;
-
-import org.jboss.netty.buffer.ChannelBuffer;
-import org.jboss.netty.channel.Channel;
-import org.jboss.netty.channel.ChannelHandlerContext;
-
-import com.redhat.thermostat.common.command.DecodingHelper;
-import com.redhat.thermostat.common.command.MessageDecoder;
-import com.redhat.thermostat.common.command.Response;
-import com.redhat.thermostat.common.command.Response.ResponseType;
-
-class ResponseDecoder extends MessageDecoder {
-
-    @Override
-    protected Object decode(ChannelHandlerContext ctx, Channel channel,
-            ChannelBuffer buffer) {
-        String typeAsString = DecodingHelper.decodeString(buffer);
-        if (typeAsString == null) {
-            return null;
-        }
-        return new Response(ResponseType.valueOf(typeAsString));
-    }
-
-}
\ No newline at end of file
--- a/client/command/src/main/java/com/redhat/thermostat/client/command/ResponseHandler.java	Thu Aug 16 14:35:54 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,70 +0,0 @@
-/*
- * Copyright 2012 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.client.command;
-
-import java.util.logging.Logger;
-
-import org.jboss.netty.channel.ChannelHandlerContext;
-import org.jboss.netty.channel.MessageEvent;
-import org.jboss.netty.channel.SimpleChannelUpstreamHandler;
-
-import com.redhat.thermostat.common.command.Request;
-import com.redhat.thermostat.common.command.RequestResponseListener;
-import com.redhat.thermostat.common.command.Response;
-
-public class ResponseHandler extends SimpleChannelUpstreamHandler {
-
-    private static final Logger logger = Logger.getLogger(
-            ResponseHandler.class.getName());
-
-    private final Request request;
-
-    ResponseHandler(Request request) {
-        this.request = request;
-    }
-
-    @Override
-    public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
-        ctx.getPipeline().remove(this);
-        Response response = (Response) e.getMessage();
-        logger.info((response).getType().toString());
-        e.getChannel().close();
-        for (RequestResponseListener listener : request.getListeners()) {
-            listener.fireComplete(request, response);
-        }
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/command/src/main/java/com/redhat/thermostat/client/command/internal/Activator.java	Thu Aug 16 14:35:55 2012 -0400
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2012 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.client.command.internal;
+
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceRegistration;
+
+import com.redhat.thermostat.client.command.RequestQueue;
+
+public class Activator implements BundleActivator {
+
+    private RequestQueueImpl queue;
+    private ServiceRegistration queueRegistration;
+
+    public Activator() {
+        queue = new RequestQueueImpl(new ConfigurationRequestContext());
+    }
+
+    @Override
+    public void start(BundleContext context) throws Exception {
+        queueRegistration = context.registerService(RequestQueue.class.getName(), queue, null);
+        queue.startProcessingRequests();
+    }
+
+    @Override
+    public void stop(BundleContext context) throws Exception {
+        queue.stopProcessingRequests();
+        if (queueRegistration != null) {
+            queueRegistration.unregister();
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/command/src/main/java/com/redhat/thermostat/client/command/internal/ConfigurationRequestContext.java	Thu Aug 16 14:35:55 2012 -0400
@@ -0,0 +1,93 @@
+/*
+ * Copyright 2012 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.client.command.internal;
+
+import java.util.concurrent.Executors;
+
+import org.jboss.netty.bootstrap.Bootstrap;
+import org.jboss.netty.bootstrap.ClientBootstrap;
+import org.jboss.netty.channel.ChannelPipeline;
+import org.jboss.netty.channel.ChannelPipelineFactory;
+import org.jboss.netty.channel.Channels;
+import org.jboss.netty.channel.socket.nio.NioClientSocketChannelFactory;
+
+import com.redhat.thermostat.common.command.ConfigurationCommandContext;
+
+public class ConfigurationRequestContext extends ConfigurationCommandContext {
+
+    private final ClientBootstrap bootstrap;
+
+    ConfigurationRequestContext() {
+        this.bootstrap = createBootstrap();
+    }
+
+    @Override
+    public
+    Bootstrap getBootstrap() {
+        return bootstrap;
+    }
+
+    private ClientBootstrap createBootstrap() {
+        // Configure the client.
+        ClientBootstrap bootstrap = new ClientBootstrap(
+                new NioClientSocketChannelFactory(
+                        Executors.newCachedThreadPool(),
+                        Executors.newCachedThreadPool()));
+
+        // Set up the pipeline factory.
+        bootstrap.setPipelineFactory(new ClientPipelineFactory());
+
+        bootstrap.setOption("tcpNoDelay", true);
+        bootstrap.setOption("keepAlive", true);
+        bootstrap.setOption("reuseAddress", true);
+        bootstrap.setOption("connectTimeoutMillis", 100);
+        bootstrap.setOption("readWriteFair", true);
+        return bootstrap;
+    }
+
+    private class ClientPipelineFactory implements ChannelPipelineFactory {
+
+        @Override
+        public ChannelPipeline getPipeline() throws Exception {
+            ChannelPipeline pipeline = Channels.pipeline();
+            pipeline.addLast("decoder", new ResponseDecoder());
+            pipeline.addLast("encoder", new RequestEncoder());
+            return pipeline;
+        }
+        
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/command/src/main/java/com/redhat/thermostat/client/command/internal/RequestEncoder.java	Thu Aug 16 14:35:55 2012 -0400
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2012 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.client.command.internal;
+
+import org.jboss.netty.buffer.ChannelBuffer;
+import static org.jboss.netty.buffer.ChannelBuffers.wrappedBuffer;
+import org.jboss.netty.channel.ChannelHandlerContext;
+import org.jboss.netty.channel.Channels;
+import org.jboss.netty.channel.MessageEvent;
+
+import com.redhat.thermostat.common.command.EncodingHelper;
+import com.redhat.thermostat.common.command.MessageEncoder;
+import com.redhat.thermostat.common.command.Request;
+
+
+class RequestEncoder extends MessageEncoder {
+
+    @Override
+    public void writeRequested(ChannelHandlerContext ctx, MessageEvent e) {
+
+        Request request = (Request) e.getMessage();
+
+        // Request Type
+        String requestType = EncodingHelper.trimType(request.getType().toString());
+        byte[] message = requestType.getBytes();
+        ChannelBuffer typeBuffer = EncodingHelper.encode(message);
+
+        // Compose the full message.
+        ChannelBuffer buf = wrappedBuffer(typeBuffer);
+        Channels.write(ctx, e.getFuture(), buf);
+    }
+
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/command/src/main/java/com/redhat/thermostat/client/command/internal/RequestQueueImpl.java	Thu Aug 16 14:35:55 2012 -0400
@@ -0,0 +1,101 @@
+/*
+ * Copyright 2012 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.client.command.internal;
+
+import java.util.concurrent.ArrayBlockingQueue;
+import java.util.concurrent.BlockingQueue;
+
+import org.jboss.netty.bootstrap.ClientBootstrap;
+import org.jboss.netty.channel.Channel;
+import org.jboss.netty.channel.ChannelFuture;
+
+import com.redhat.thermostat.client.command.RequestQueue;
+import com.redhat.thermostat.common.command.Request;
+
+class RequestQueueImpl implements RequestQueue {
+
+    private final BlockingQueue<Request> queue;
+    private final ConfigurationRequestContext ctx;
+    private boolean processing;
+
+    RequestQueueImpl(ConfigurationRequestContext ctx) {
+        processing = false;
+        this.ctx = ctx;
+        queue = new ArrayBlockingQueue<Request>(16, true);
+    }
+
+    @Override
+    public void putRequest(Request request) {
+        queue.add(request);
+    }
+
+    void startProcessingRequests() {
+        if (!processing) {
+            processing = true;
+            new QueueRunner().start();
+        }
+    }
+
+    void stopProcessingRequests() {
+        processing = false;
+    }
+
+    private class QueueRunner extends Thread {
+
+        @Override
+        public void run() {
+            while (processing) {
+                Request request = null;
+                try {
+                    request = queue.take();
+                } catch (InterruptedException e) {
+                    if (Thread.interrupted()) {
+                        Thread.currentThread().interrupt();
+                    }
+                }
+                if (request == null) {
+                    break;
+                }
+                ChannelFuture f = ((ClientBootstrap) ctx.getBootstrap()).connect(request.getTarget());
+                f.awaitUninterruptibly();
+                Channel c = f.getChannel();
+                c.getPipeline().addLast("responseHandler", new ResponseHandler(request));
+                c.write(request);
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/command/src/main/java/com/redhat/thermostat/client/command/internal/ResponseDecoder.java	Thu Aug 16 14:35:55 2012 -0400
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2012 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.client.command.internal;
+
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.jboss.netty.channel.Channel;
+import org.jboss.netty.channel.ChannelHandlerContext;
+
+import com.redhat.thermostat.common.command.DecodingHelper;
+import com.redhat.thermostat.common.command.MessageDecoder;
+import com.redhat.thermostat.common.command.Response;
+import com.redhat.thermostat.common.command.Response.ResponseType;
+
+class ResponseDecoder extends MessageDecoder {
+
+    @Override
+    protected Object decode(ChannelHandlerContext ctx, Channel channel,
+            ChannelBuffer buffer) {
+        String typeAsString = DecodingHelper.decodeString(buffer);
+        if (typeAsString == null) {
+            return null;
+        }
+        return new Response(ResponseType.valueOf(typeAsString));
+    }
+
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/command/src/main/java/com/redhat/thermostat/client/command/internal/ResponseHandler.java	Thu Aug 16 14:35:55 2012 -0400
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2012 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.client.command.internal;
+
+import java.util.logging.Logger;
+
+import org.jboss.netty.channel.ChannelHandlerContext;
+import org.jboss.netty.channel.MessageEvent;
+import org.jboss.netty.channel.SimpleChannelUpstreamHandler;
+
+import com.redhat.thermostat.common.command.Request;
+import com.redhat.thermostat.common.command.RequestResponseListener;
+import com.redhat.thermostat.common.command.Response;
+
+public class ResponseHandler extends SimpleChannelUpstreamHandler {
+
+    private static final Logger logger = Logger.getLogger(
+            ResponseHandler.class.getName());
+
+    private final Request request;
+
+    ResponseHandler(Request request) {
+        this.request = request;
+    }
+
+    @Override
+    public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
+        ctx.getPipeline().remove(this);
+        Response response = (Response) e.getMessage();
+        logger.info((response).getType().toString());
+        e.getChannel().close();
+        for (RequestResponseListener listener : request.getListeners()) {
+            listener.fireComplete(request, response);
+        }
+    }
+}