/* * JBoss, Home of Professional Open Source. * Copyright 2011, Red Hat, Inc., 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; import java.io.IOException; import java.util.concurrent.Executor; import org.jboss.remoting3.Channel; /** * The context for handling a management request. Besides providing basic state associated with the request, * one of the primary purposes of the {@code ManagementRequestContext} is to support asynchronous task execution * by request handlers. Handlers should avoid doing blocking tasks in the remoting threads that invoke them, so * the asynchronous task execution facilities of this class allow that work to be offloaded to other threads. Handlers * also should be careful about performing IO writes using threads that have invoked management operations, as those * threads may be interrupted if the caller cancels the operation, and if that interruption happens during IO the * remote channel will be incorrectly closed. The asynchronous task execution facilities of this class allow the IO * writes to be done in a separate thread. * * @param <A> the type of the attachment that can be retrieved from the context * * @author Emanuel Muckenhuber */ public interface ManagementRequestContext<A> { /** * Get the current batch id for the overall operation. * * @return the batch id */ Integer getOperationId(); /** * Get any attachment used to maintain shared state across possibly multiple requests associated with a * larger overall operation. * {@see org.jboss.as.protocol.mgmt.ActiveOperation#getAttachment()} * * @return the attachment, can be {@code null} */ A getAttachment(); /** * Get the underlying channel. * * @return the channel */ Channel getChannel(); /** * Get the protocol header. * * @return the protocol header */ ManagementProtocolHeader getRequestHeader(); /** * Execute a cancellable task at some point in the future, using this object's internal {@link Executor}. * Equivalent to {@code executeAsync(task, true)}. * <p> * If the executor {@link java.util.concurrent.RejectedExecutionException rejects} the task, or if the task itself * throws an exception during execution, the * {@link ActiveOperation.ResultHandler#failed(Throwable) failed method} of the * {@code ResultHander} associated with the request will be invoked, and if it returns {@code true} a failure * message will be sent to the remote client. * </p> * * @param task the task * * @return {@code true} if the task was accepted for execution; {@code false} if the executor rejected it */ boolean executeAsync(final AsyncTask<A> task); /** * Execute a possibly cancellable task at some point in the future, using this object's internal {@link Executor}. * <p> * If the executor {@link java.util.concurrent.RejectedExecutionException rejects} the task, or if the task itself * throws an exception during execution, the * {@link ActiveOperation.ResultHandler#failed(Throwable) failed method} of the * {@code ResultHander} associated with the request will be invoked, and if it returns {@code true} a failure * message will be sent to the remote client. * </p> * * @param task the task * @param cancellable {@code true} if the task can be cancelled as part of overall request cancellation * * @return {@code true} if the task was accepted for execution; {@code false} if the executor rejected it */ boolean executeAsync(final AsyncTask<A> task, boolean cancellable); /** * Execute a cancellable task at some point in the future, using the given {@link Executor}. * Equivalent to {@code executeAsync(task, true, executor)}. * <p> * If the executor {@link java.util.concurrent.RejectedExecutionException rejects} the task, or if the task itself * throws an exception during execution, the * {@link ActiveOperation.ResultHandler#failed(Throwable) failed method} of the * {@code ResultHander} associated with the request will be invoked, and if it returns {@code true} a failure * message will be sent to the remote client. * </p> * * @param task the task * @param executor the executor * * @return {@code true} if the task was accepted for execution; {@code false} if the executor rejected it */ boolean executeAsync(final AsyncTask<A> task, Executor executor); /** * Execute a possibly cancellable task at some point in the future, using the given {@link Executor}. * Equivalent to {@code executeAsync(task, true, executor)}. * <p> * If the executor {@link java.util.concurrent.RejectedExecutionException rejects} the task, or if the task itself * throws an exception during execution, the * {@link ActiveOperation.ResultHandler#failed(Throwable) failed method} of the * {@code ResultHander} associated with the request will be invoked, and if it returns {@code true} a failure * message will be sent to the remote client. * </p> * * @param task the task * @param cancellable {@code true} if the task can be cancelled as part of overall request cancellation * @param executor the executor * * @return {@code true} if the task was accepted for execution; {@code false} if the executor rejected it */ boolean executeAsync(final AsyncTask<A> task, boolean cancellable, Executor executor); /** * Initiates writing a new message to the remote side, using the given header. * * @param header the protocol header * @return the message output stream to use for writing further data associated with the message * @throws IOException */ FlushableDataOutput writeMessage(final ManagementProtocolHeader header) throws IOException; /** A task that can be executed asynchronously by a {@link ManagementRequestContext} */ interface AsyncTask<A> { /** * Execute the task. * <p> * If the task throws an exception during execution, the * {@link ActiveOperation.ResultHandler#failed(Throwable) failed method} of the * {@code ResultHander} associated with the request will be invoked, and if it returns {@code true} a failure * message will be sent to the remote client. * </p> * * @param context the request context * @throws Exception */ void execute(final ManagementRequestContext<A> context) throws Exception; } /** * {@link org.jboss.as.protocol.mgmt.ManagementRequestContext.AsyncTask} subinterface implemented * by tasks where the appropriate request header to use for notifying a remote process of a * failure varies through the course of the task. * * @deprecated this is a bit of a hack, plus we can move this method into AsyncTask with a default impl * once this module no longer requires JDK 6 source level */ @Deprecated interface MultipleResponseAsyncTask<A> extends AsyncTask<A> { /** * Gets the current request header for which an error response should be sent * @return the header, or {@code null} if the * {@linkplain ManagementRequestContext#getRequestHeader() default header for the request context} * should be used */ ManagementProtocolHeader getCurrentRequestHeader(); } }