/* * JBoss, Home of Professional Open Source. * Copyright 2006, Red Hat Middleware LLC, and individual contributors * as indicated by the @author tags. See the copyright.txt file in the * distribution for a full listing of individual contributors. * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This software 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this software; if not, write to the Free * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. */ package org.jboss.as.protocol.mgmt.support; import java.io.DataInput; import java.io.IOException; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; import org.jboss.as.protocol.mgmt.AbstractManagementRequest; import org.jboss.as.protocol.mgmt.ActiveOperation; import org.jboss.as.protocol.mgmt.FlushableDataOutput; import org.jboss.as.protocol.mgmt.ManagementChannelReceiver; import org.jboss.as.protocol.mgmt.AbstractMessageHandler; import org.jboss.as.protocol.mgmt.ManagementProtocolHeader; import org.jboss.as.protocol.mgmt.ManagementRequest; import org.jboss.as.protocol.mgmt.ManagementRequestContext; import org.jboss.as.protocol.mgmt.ManagementRequestHandler; import org.jboss.as.protocol.mgmt.ManagementRequestHeader; import org.jboss.as.protocol.mgmt.ProtocolUtils; import org.jboss.remoting3.Channel; import org.jboss.remoting3.CloseHandler; import org.jboss.threads.AsyncFuture; /** * * @author <a href="kabir.khan@jboss.com">Kabir Khan</a> * @version $Revision: 1.1 $ */ public class SimpleHandlers { public static final byte SIMPLE_REQUEST = 102; public static final byte REQUEST_WITH_NO_HANDLER = 103; public static final byte REQUEST_WITH_BAD_READ = 104; public static final byte REQUEST_WITH_BAD_WRITE = 105; public static final byte REQUEST_WITH_NO_RESPONSE = 106; public static class Request extends AbstractManagementRequest<Integer, Void> { final int sentData; final byte requestCode; public Request(byte requestCode, int sentData) { this.requestCode = requestCode; this.sentData = sentData; } @Override protected void sendRequest(ActiveOperation.ResultHandler<Integer> resultHandler, ManagementRequestContext<Void> context, FlushableDataOutput output) throws IOException { output.writeInt(sentData); } @Override public byte getOperationType() { return requestCode; } @Override public void handleRequest(DataInput input, ActiveOperation.ResultHandler<Integer> resultHandler, ManagementRequestContext<Void> context) throws IOException { resultHandler.done(input.readInt()); } } public static class OperationHandler extends AbstractMessageHandler { public OperationHandler() { super(Executors.newCachedThreadPool()); } @Override protected ManagementRequestHeader validateRequest(ManagementProtocolHeader header) throws IOException { ManagementRequestHeader request = super.validateRequest(header); super.registerActiveOperation(request.getBatchId(), (Void) null); return request; } @Override protected ManagementRequestHandler<?, ?> getRequestHandler(final ManagementRequestHeader header) { final byte operationType = header.getOperationId(); switch (operationType) { case SIMPLE_REQUEST: return new RequestHandler(); case REQUEST_WITH_BAD_READ: return new BadReadRequestHandler(); case REQUEST_WITH_BAD_WRITE: return new BadWriteRequestHandler(); case REQUEST_WITH_NO_RESPONSE: return new NoResponseHandler(); case REQUEST_WITH_NO_HANDLER: //No handler for this default: return super.getRequestHandler(header); } } } private abstract static class AbstractHandler implements ManagementRequestHandler<Void, Void> { abstract int readRequest(DataInput input) throws IOException; abstract void writeResponse(final FlushableDataOutput output, int data) throws IOException; @Override public void handleRequest(final DataInput input, final ActiveOperation.ResultHandler<Void> resultHandler, final ManagementRequestContext<Void> context) throws IOException { final int data = readRequest(input); context.executeAsync(new ManagementRequestContext.AsyncTask<Void>() { @Override public void execute(ManagementRequestContext<Void> context) throws Exception { ProtocolUtils.writeResponse(new ProtocolUtils.ResponseWriter() { @Override public void write(final FlushableDataOutput output) throws IOException { writeResponse(output, data); } }, context); resultHandler.done(null); } }); } } public static class RequestHandler extends AbstractHandler { @Override public int readRequest(DataInput input) throws IOException { return input.readInt(); } @Override public void writeResponse(FlushableDataOutput output, int data) throws IOException { output.writeInt(data * 2); } } public static class BadReadRequestHandler extends AbstractHandler { @Override public int readRequest(DataInput input) throws IOException { throw new IOException("BadReadRequest"); } @Override void writeResponse(FlushableDataOutput output, int data) throws IOException { throw new IllegalStateException(); } } public static class BadWriteRequestHandler extends AbstractHandler { @Override public int readRequest(DataInput input) throws IOException { return input.readInt(); } @Override public void writeResponse(FlushableDataOutput output, int data) throws IOException { throw new IOException("BadWriteRequest"); } } public static class NoResponseHandler implements ManagementRequestHandler<Void, Void> { @Override public void handleRequest(DataInput input, ActiveOperation.ResultHandler<Void> voidResultHandler, ManagementRequestContext<Void> voidManagementRequestContext) throws IOException { input.readInt(); } } public static class SimpleClient extends AbstractMessageHandler { private final Channel channel; SimpleClient(final Channel channel, final ExecutorService executorService) { super(executorService); this.channel = channel; } public Integer executeForResult(ManagementRequest<Integer, Void> request) throws ExecutionException, InterruptedException { return execute(request).get(); } public AsyncFuture<Integer> execute(ManagementRequest<Integer, Void> request) { final ActiveOperation<Integer, Void> support = super.registerActiveOperation(null); return super.executeRequest(request, channel, support); } public static SimpleClient create(final Channel channel, final ExecutorService executorService) { final SimpleClient client = new SimpleClient(channel, executorService); channel.addCloseHandler(new CloseHandler<Channel>() { @Override public void handleClose(Channel closed, IOException exception) { client.shutdownNow(); } }); channel.receiveMessage(ManagementChannelReceiver.createDelegating(client)); return client; } public void shutdown() { super.shutdown(); } public boolean awaitCompletion(long timeout, TimeUnit unit) throws InterruptedException { return super.awaitCompletion(timeout, unit); } public static SimpleClient create(final RemotingChannelPairSetup setup) { final Channel channel = setup.getClientChannel(); return create(channel, setup.getExecutorService()); } } }