blob: 9ee5435a923ba23b9d6a24f495f1d953fefd38d3 [file] [log] [blame]
/*
* 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.
*/
package org.apache.qpid.protonj2.engine;
import java.util.Collection;
import org.apache.qpid.protonj2.types.messaging.Rejected;
import org.apache.qpid.protonj2.types.messaging.Source;
import org.apache.qpid.protonj2.types.messaging.Terminus;
import org.apache.qpid.protonj2.types.transactions.Coordinator;
import org.apache.qpid.protonj2.types.transactions.Declare;
import org.apache.qpid.protonj2.types.transactions.Declared;
import org.apache.qpid.protonj2.types.transactions.Discharge;
/**
* Transaction Controller link that implements the mechanics of declaring and discharging
* AMQP transactions. A {@link TransactionController} is typically used at the client side
* of an AMQP {@link Link} to create {@link Transaction} instances which the client application
* will enlist its incoming and outgoing deliveries into.
*/
public interface TransactionController extends Endpoint<TransactionController> {
/**
* Returns <code>true</code> if the {@link TransactionController} has capacity to send or buffer
* and {@link Transaction} command to {@link Declare} or {@link Discharge}. If no capacity then
* a call to {@link TransactionController#declare()} or to
* {@link TransactionController#discharge(Transaction, boolean)} would throw an exception.
*
* @return true if the controller will allow declaring or discharging a transaction at this time.
*/
boolean hasCapacity();
/**
* Sets the {@link Source} to assign to the local end of this {@link TransactionController}.
*
* Must be called during setup, i.e. before calling the {@link #open()} method.
*
* @param source
* The {@link Source} that will be set on the local end of this transaction controller.
*
* @return this transaction controller instance.
*
* @throws IllegalStateException if the {@link TransactionController} has already been opened.
*/
TransactionController setSource(Source source) throws IllegalStateException;
/**
* @return the {@link Source} for the local end of this {@link TransactionController}.
*/
Source getSource();
/**
* Sets the {@link Coordinator} target to assign to the local end of this {@link TransactionController}.
*
* Must be called during setup, i.e. before calling the {@link #open()} method.
*
* @param coordinator
* The {@link Coordinator} target that will be set on the local end of this transaction controller.
*
* @return this transaction controller instance.
*
* @throws IllegalStateException if the {@link TransactionController} has already been opened.
*/
TransactionController setCoordinator(Coordinator coordinator) throws IllegalStateException;
/**
* Returns the currently set Coordinator target for this {@link Link}.
*
* @return the link target {@link Coordinator} for the local end of this link.
*/
Coordinator getCoordinator();
/**
* @return the source {@link Source} for the remote end of this {@link TransactionController}.
*/
Source getRemoteSource();
/**
* Returns the remote target {@link Terminus} for this transaction controller which must be of type
* {@link Coordinator} or null if remote did not set a terminus.
*
* @return the remote coordinator {@link Terminus} for the remote end of this link.
*/
Coordinator getRemoteCoordinator();
/**
* Returns a list of {@link Transaction} objects that are active within this {@link TransactionController} which
* have not reached a terminal state meaning they have not been successfully discharged and have not failed in
* either the {@link Declare} phase or the {@link Discharge} phase. If there are no transactions active within
* this {@link TransactionController} this method returns an empty {@link Collection}.
*
* @return a list of Transactions that are allocated to this controller that have not reached a terminal state.
*/
Collection<Transaction<TransactionController>> transactions();
/**
* Creates a new {@link Transaction} instances that is returned in the {@link TransactionState#IDLE} state
* which can be populated with application specific attachments or assigned a linked resource prior to calling
* the
*
* @return a new {@link Transaction} instance that can be correlated with later declared events.
*/
Transaction<TransactionController> newTransaction();
/**
* Request that the remote {@link TransactionManager} declare a new transaction and
* respond with a new transaction Id for that transaction. Upon successful declaration of
* a new transaction the remote will respond and the {@link TransactionController#declaredHandler(EventHandler)}
* event handler will be signaled.
*
* This is a convenience method that is the same as first calling {@link TransactionController#newTransaction()}
* and then passing the result of that to the {@link TransactionController#declare(Transaction)} method.
*
* @return a new {@link Transaction} instance that can be correlated with later declared events.
*/
Transaction<TransactionController> declare();
/**
* Request that the remote {@link TransactionManager} declare a new transaction and
* respond with a new transaction Id for that transaction. Upon successful declaration of
* a new transaction the remote will respond and the {@link TransactionController#declaredHandler(EventHandler)}
* event handler will be signaled.
*
* @param transaction
* The {@link Transaction} that is will be associated with the eventual declared transaction.
*
* @return this {@link TransactionController}
*/
TransactionController declare(Transaction<TransactionController> transaction);
/**
* Request that the remote {@link TransactionManager} discharge the given transaction and
* with the specified failure state (true for failed). Upon successful declaration of
* a new transaction the remote will respond and the {@link TransactionController#declaredHandler(EventHandler)}
* event handler will be signaled.
*
* @param transaction
* The {@link Transaction} that is being discharged.
* @param failed
* boolean value indicating the the discharge indicates the transaction failed (rolled back).
*
* @return this {@link TransactionController}
*/
TransactionController discharge(Transaction<TransactionController> transaction, boolean failed);
/**
* Called when the {@link TransactionManager} end of the link has responded to a previous
* {@link Declare} request and the transaction can now be used to enroll deliveries into the
* active transaction.
*
* @param declaredEventHandler
* An {@link EventHandler} that will act on the transaction declaration request.
*
* @return this {@link TransactionController}.
*/
TransactionController declaredHandler(EventHandler<Transaction<TransactionController>> declaredEventHandler);
/**
* Called when the {@link TransactionManager} end of the link responds to a {@link Transaction} declaration
* with an {@link Rejected} outcome indicating that the transaction could not be successfully declared.
*
* @param declareFailureEventHandler
* An {@link EventHandler} that will be called when a previous transaction declaration fails.
*
* @return this {@link TransactionController}.
*/
TransactionController declareFailureHandler(EventHandler<Transaction<TransactionController>> declareFailureEventHandler);
/**
* Called when the {@link TransactionManager} end of the link has responded to a previous
* {@link TransactionController#discharge(Transaction, boolean)} request and the transaction has
* been retired.
*
* @param dischargedEventHandler
* An {@link EventHandler} that will act on the transaction discharge request.
*
* @return this {@link TransactionController}.
*/
TransactionController dischargedHandler(EventHandler<Transaction<TransactionController>> dischargedEventHandler);
/**
* Called when the {@link TransactionManager} end of the link has responded to a previous
* {@link TransactionController#discharge(Transaction, boolean)} request and the transaction discharge
* failed for some reason.
*
* @param dischargeFailureEventHandler
* An {@link EventHandler} that will act on the transaction discharge failed event.
*
* @return this {@link TransactionController}.
*/
TransactionController dischargeFailureHandler(EventHandler<Transaction<TransactionController>> dischargeFailureEventHandler);
/**
* Allows the caller to add an {@link EventHandler} that will be signaled when the underlying
* link for this {@link TransactionController} has been granted credit which would then allow for
* transaction {@link Declared} and {@link Discharge} commands to be sent to the remote Transactional
* Resource.
*
* If the controller already has credit to send then the handler will be invoked immediately otherwise
* it will be stored until credit becomes available. Once a handler is signaled it is no longer retained
* for future updates and the caller will need to register it again once more transactional work is to be
* completed. Because more than one handler can be added at a time the caller should check again before
* attempting to perform a transaction {@link Declared} or {@link Discharge} is performed as other tasks
* might have already consumed credit if work is done via some asynchronous mechanism.
*
* @param handler
* The {@link EventHandler} that will be signaled once credit is available for transaction work.
*
* @return this {@link TransactionController} instance.
*/
TransactionController addCapacityAvailableHandler(EventHandler<TransactionController> handler);
/**
* Sets a {@link EventHandler} for when the parent {@link Session} or {@link Connection} of this {@link TransactionController}
* is locally closed.
*
* Typically used by clients for logging or other state update event processing. Clients should not perform any
* blocking calls within this context. It is an error for the handler to throw an exception and the outcome of
* doing so is undefined.
*
* @param handler
* The {@link EventHandler} to notify when this transaction controller's parent endpoint is locally closed.
*
* @return the link for chaining.
*/
TransactionController parentEndpointClosedHandler(EventHandler<TransactionController> handler);
}