init
This commit is contained in:
100
java/org/apache/catalina/tribes/ByteMessage.java
Normal file
100
java/org/apache/catalina/tribes/ByteMessage.java
Normal file
@@ -0,0 +1,100 @@
|
||||
/*
|
||||
* 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.catalina.tribes;
|
||||
|
||||
import java.io.Externalizable;
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInput;
|
||||
import java.io.ObjectOutput;
|
||||
|
||||
/**
|
||||
* A byte message is not serialized and deserialized by the channel
|
||||
* instead it is sent as a byte array<br>
|
||||
* By default Tribes uses java serialization when it receives an object
|
||||
* to be sent over the wire. Java serialization is not the most
|
||||
* efficient of serializing data, and Tribes might not even
|
||||
* have access to the correct class loaders to deserialize the object properly.
|
||||
* <br>
|
||||
* The ByteMessage class is a class where the channel when it receives it will
|
||||
* not attempt to perform serialization, instead it will simply stream the <code>getMessage()</code>
|
||||
* bytes.<br>
|
||||
* If you are using multiple applications on top of Tribes you should add some sort of header
|
||||
* so that you can decide with the <code>ChannelListener.accept()</code> whether this message was intended
|
||||
* for you.
|
||||
*/
|
||||
public class ByteMessage implements Externalizable {
|
||||
/**
|
||||
* Storage for the message to be sent
|
||||
*/
|
||||
private byte[] message;
|
||||
|
||||
|
||||
/**
|
||||
* Creates an empty byte message
|
||||
* Constructor also for deserialization
|
||||
*/
|
||||
public ByteMessage() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a byte message wit h
|
||||
* @param data byte[] - the message contents
|
||||
*/
|
||||
public ByteMessage(byte[] data) {
|
||||
message = data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the message contents of this byte message
|
||||
* @return byte[] - message contents, can be null
|
||||
*/
|
||||
public byte[] getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the message contents of this byte message
|
||||
* @param message byte[]
|
||||
*/
|
||||
public void setMessage(byte[] message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see java.io.Externalizable#readExternal
|
||||
* @param in ObjectInput
|
||||
* @throws IOException An IO error occurred
|
||||
*/
|
||||
@Override
|
||||
public void readExternal(ObjectInput in ) throws IOException {
|
||||
int length = in.readInt();
|
||||
message = new byte[length];
|
||||
in.readFully(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see java.io.Externalizable#writeExternal
|
||||
* @param out ObjectOutput
|
||||
* @throws IOException An IO error occurred
|
||||
*/
|
||||
@Override
|
||||
public void writeExternal(ObjectOutput out) throws IOException {
|
||||
out.writeInt(message!=null?message.length:0);
|
||||
if ( message!=null ) out.write(message,0,message.length);
|
||||
}
|
||||
|
||||
}
|
||||
372
java/org/apache/catalina/tribes/Channel.java
Normal file
372
java/org/apache/catalina/tribes/Channel.java
Normal file
@@ -0,0 +1,372 @@
|
||||
/*
|
||||
* 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.catalina.tribes;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* Channel interface<br>
|
||||
* A channel is a representation of a group of nodes all participating in some sort of
|
||||
* communication with each other.<br>
|
||||
* The channel is the main API class for Tribes, this is essentially the only class
|
||||
* that an application needs to be aware of. Through the channel the application can:<br>
|
||||
* 1. send messages<br>
|
||||
* 2. receive message (by registering a <code>ChannelListener</code><br>
|
||||
* 3. get all members of the group <code>getMembers()</code><br>
|
||||
* 4. receive notifications of members added and members disappeared by
|
||||
* registering a <code>MembershipListener</code><br>
|
||||
* <br>
|
||||
* The channel has 5 major components:<br>
|
||||
* 1. Data receiver, with a built in thread pool to receive messages from other peers<br>
|
||||
* 2. Data sender, an implementation for sending data using NIO or java.io<br>
|
||||
* 3. Membership listener,listens for membership broadcasts<br>
|
||||
* 4. Membership broadcaster, broadcasts membership pings.<br>
|
||||
* 5. Channel interceptors, the ability to manipulate messages as they are sent or arrive<br><br>
|
||||
* The channel layout is:
|
||||
* <pre><code>
|
||||
* ChannelListener_1..ChannelListener_N MembershipListener_1..MembershipListener_N [Application Layer]
|
||||
* \ \ / /
|
||||
* \ \ / /
|
||||
* \ \ / /
|
||||
* \ \ / /
|
||||
* \ \ / /
|
||||
* \ \ / /
|
||||
* ---------------------------------------
|
||||
* |
|
||||
* |
|
||||
* Channel
|
||||
* |
|
||||
* ChannelInterceptor_1
|
||||
* | [Channel stack]
|
||||
* ChannelInterceptor_N
|
||||
* |
|
||||
* Coordinator (implements MessageListener,MembershipListener,ChannelInterceptor)
|
||||
* --------------------
|
||||
* / | \
|
||||
* / | \
|
||||
* / | \
|
||||
* / | \
|
||||
* / | \
|
||||
* MembershipService ChannelSender ChannelReceiver [IO layer]
|
||||
* </code></pre>
|
||||
*
|
||||
* For example usage @see org.apache.catalina.tribes.group.GroupChannel
|
||||
*/
|
||||
public interface Channel {
|
||||
|
||||
/**
|
||||
* Start and stop sequences can be controlled by these constants
|
||||
* This allows you to start separate components of the channel <br>
|
||||
* DEFAULT - starts or stops all components in the channel
|
||||
* @see #start(int)
|
||||
* @see #stop(int)
|
||||
*/
|
||||
public static final int DEFAULT = 15;
|
||||
|
||||
/**
|
||||
* Start and stop sequences can be controlled by these constants
|
||||
* This allows you to start separate components of the channel <br>
|
||||
* SND_RX_SEQ - starts or stops the data receiver. Start means opening a server socket
|
||||
* in case of a TCP implementation
|
||||
* @see #start(int)
|
||||
* @see #stop(int)
|
||||
*/
|
||||
public static final int SND_RX_SEQ = 1;
|
||||
|
||||
/**
|
||||
* Start and stop sequences can be controlled by these constants
|
||||
* This allows you to start separate components of the channel <br>
|
||||
* SND_TX_SEQ - starts or stops the data sender. This should not open any sockets,
|
||||
* as sockets are opened on demand when a message is being sent
|
||||
* @see #start(int)
|
||||
* @see #stop(int)
|
||||
*/
|
||||
public static final int SND_TX_SEQ = 2;
|
||||
|
||||
/**
|
||||
* Start and stop sequences can be controlled by these constants
|
||||
* This allows you to start separate components of the channel <br>
|
||||
* MBR_RX_SEQ - starts or stops the membership listener. In a multicast implementation
|
||||
* this will open a datagram socket and join a group and listen for membership messages
|
||||
* members joining
|
||||
* @see #start(int)
|
||||
* @see #stop(int)
|
||||
*/
|
||||
public static final int MBR_RX_SEQ = 4;
|
||||
|
||||
/**
|
||||
* Start and stop sequences can be controlled by these constants
|
||||
* This allows you to start separate components of the channel <br>
|
||||
* MBR_TX_SEQ - starts or stops the membership broadcaster. In a multicast implementation
|
||||
* this will open a datagram socket and join a group and broadcast the local member information
|
||||
* @see #start(int)
|
||||
* @see #stop(int)
|
||||
*/
|
||||
public static final int MBR_TX_SEQ = 8;
|
||||
|
||||
/**
|
||||
* Send options, when a message is sent, it can have an option flag
|
||||
* to trigger certain behavior. Most flags are used to trigger channel interceptors
|
||||
* as the message passes through the channel stack. <br>
|
||||
* However, there are five default flags that every channel implementation must implement<br>
|
||||
* SEND_OPTIONS_BYTE_MESSAGE - The message is a pure byte message and no marshaling or unmarshaling will
|
||||
* be performed.<br>
|
||||
*
|
||||
* @see #send(Member[], Serializable , int)
|
||||
* @see #send(Member[], Serializable, int, ErrorHandler)
|
||||
*/
|
||||
public static final int SEND_OPTIONS_BYTE_MESSAGE = 0x0001;
|
||||
|
||||
/**
|
||||
* Send options, when a message is sent, it can have an option flag
|
||||
* to trigger certain behavior. Most flags are used to trigger channel interceptors
|
||||
* as the message passes through the channel stack. <br>
|
||||
* However, there are five default flags that every channel implementation must implement<br>
|
||||
* SEND_OPTIONS_USE_ACK - Message is sent and an ACK is received when the message has been received by the recipient<br>
|
||||
* If no ack is received, the message is not considered successful<br>
|
||||
* @see #send(Member[], Serializable , int)
|
||||
* @see #send(Member[], Serializable, int, ErrorHandler)
|
||||
*/
|
||||
public static final int SEND_OPTIONS_USE_ACK = 0x0002;
|
||||
|
||||
/**
|
||||
* Send options, when a message is sent, it can have an option flag
|
||||
* to trigger certain behavior. Most flags are used to trigger channel interceptors
|
||||
* as the message passes through the channel stack. <br>
|
||||
* However, there are five default flags that every channel implementation must implement<br>
|
||||
* SEND_OPTIONS_SYNCHRONIZED_ACK - Message is sent and an ACK is received when the message has been received and
|
||||
* processed by the recipient<br>
|
||||
* If no ack is received, the message is not considered successful<br>
|
||||
* @see #send(Member[], Serializable , int)
|
||||
* @see #send(Member[], Serializable, int, ErrorHandler)
|
||||
*/
|
||||
public static final int SEND_OPTIONS_SYNCHRONIZED_ACK = 0x0004;
|
||||
|
||||
/**
|
||||
* Send options, when a message is sent, it can have an option flag
|
||||
* to trigger certain behavior. Most flags are used to trigger channel interceptors
|
||||
* as the message passes through the channel stack. <br>
|
||||
* However, there are five default flags that every channel implementation must implement<br>
|
||||
* SEND_OPTIONS_ASYNCHRONOUS - Message is sent and an ACK is received when the message has been received and
|
||||
* processed by the recipient<br>
|
||||
* If no ack is received, the message is not considered successful<br>
|
||||
* @see #send(Member[], Serializable , int)
|
||||
* @see #send(Member[], Serializable, int, ErrorHandler)
|
||||
*/
|
||||
public static final int SEND_OPTIONS_ASYNCHRONOUS = 0x0008;
|
||||
|
||||
/**
|
||||
* Send options, when a message is sent, it can have an option flag
|
||||
* to trigger certain behavior. Most flags are used to trigger channel interceptors
|
||||
* as the message passes through the channel stack. <br>
|
||||
* However, there are five default flags that every channel implementation must implement<br>
|
||||
* SEND_OPTIONS_SECURE - Message is sent over an encrypted channel<br>
|
||||
* @see #send(Member[], Serializable , int)
|
||||
* @see #send(Member[], Serializable, int, ErrorHandler)
|
||||
*/
|
||||
public static final int SEND_OPTIONS_SECURE = 0x0010;
|
||||
|
||||
/**
|
||||
* Send options. When a message is sent with this flag on
|
||||
* the system sends the message using UDP instead of TCP
|
||||
* @see #send(Member[], Serializable , int)
|
||||
* @see #send(Member[], Serializable, int, ErrorHandler)
|
||||
*/
|
||||
public static final int SEND_OPTIONS_UDP = 0x0020;
|
||||
|
||||
/**
|
||||
* Send options. When a message is sent with this flag on
|
||||
* the system sends a UDP message on the Multicast address instead of UDP or TCP to individual addresses
|
||||
* @see #send(Member[], Serializable , int)
|
||||
* @see #send(Member[], Serializable, int, ErrorHandler)
|
||||
*/
|
||||
public static final int SEND_OPTIONS_MULTICAST = 0x0040;
|
||||
|
||||
/**
|
||||
* Send options, when a message is sent, it can have an option flag
|
||||
* to trigger certain behavior. Most flags are used to trigger channel interceptors
|
||||
* as the message passes through the channel stack. <br>
|
||||
* However, there are five default flags that every channel implementation must implement<br>
|
||||
* SEND_OPTIONS_DEFAULT - the default sending options, just a helper variable. <br>
|
||||
* The default is <code>int SEND_OPTIONS_DEFAULT = SEND_OPTIONS_USE_ACK;</code><br>
|
||||
* @see #SEND_OPTIONS_USE_ACK
|
||||
* @see #send(Member[], Serializable , int)
|
||||
* @see #send(Member[], Serializable, int, ErrorHandler)
|
||||
*/
|
||||
public static final int SEND_OPTIONS_DEFAULT = SEND_OPTIONS_USE_ACK;
|
||||
|
||||
|
||||
/**
|
||||
* Adds an interceptor to the channel message chain.
|
||||
* @param interceptor ChannelInterceptor
|
||||
*/
|
||||
public void addInterceptor(ChannelInterceptor interceptor);
|
||||
|
||||
/**
|
||||
* Starts up the channel. This can be called multiple times for individual services to start
|
||||
* The svc parameter can be the logical or value of any constants
|
||||
* @param svc int value of <BR>
|
||||
* DEFAULT - will start all services <BR>
|
||||
* MBR_RX_SEQ - starts the membership receiver <BR>
|
||||
* MBR_TX_SEQ - starts the membership broadcaster <BR>
|
||||
* SND_TX_SEQ - starts the replication transmitter<BR>
|
||||
* SND_RX_SEQ - starts the replication receiver<BR>
|
||||
* <b>Note:</b> In order for the membership broadcaster to
|
||||
* transmit the correct information, it has to be started after the replication receiver.
|
||||
* @throws ChannelException if a startup error occurs or the service is already started or an error occurs.
|
||||
*/
|
||||
public void start(int svc) throws ChannelException;
|
||||
|
||||
/**
|
||||
* Shuts down the channel. This can be called multiple times for individual services to shutdown
|
||||
* The svc parameter can be the logical or value of any constants
|
||||
* @param svc int value of <BR>
|
||||
* DEFAULT - will shutdown all services <BR>
|
||||
* MBR_RX_SEQ - stops the membership receiver <BR>
|
||||
* MBR_TX_SEQ - stops the membership broadcaster <BR>
|
||||
* SND_TX_SEQ - stops the replication transmitter<BR>
|
||||
* SND_RX_SEQ - stops the replication receiver<BR>
|
||||
* @throws ChannelException if a startup error occurs or the service is already stopped or an error occurs.
|
||||
*/
|
||||
public void stop(int svc) throws ChannelException;
|
||||
|
||||
/**
|
||||
* Send a message to one or more members in the cluster
|
||||
* @param destination Member[] - the destinations, cannot be null or zero length, the reason for that
|
||||
* is that a membership change can occur and at that time the application is uncertain what group the message
|
||||
* actually got sent to.
|
||||
* @param msg Serializable - the message to send, has to be serializable, or a <code>ByteMessage</code> to
|
||||
* send a pure byte array
|
||||
* @param options int - sender options, see class documentation for each interceptor that is configured in order to trigger interceptors
|
||||
* @return a unique Id that identifies the message that is sent
|
||||
* @throws ChannelException if a serialization error happens.
|
||||
* @see ByteMessage
|
||||
* @see #SEND_OPTIONS_USE_ACK
|
||||
* @see #SEND_OPTIONS_ASYNCHRONOUS
|
||||
* @see #SEND_OPTIONS_SYNCHRONIZED_ACK
|
||||
*/
|
||||
public UniqueId send(Member[] destination, Serializable msg, int options) throws ChannelException;
|
||||
|
||||
/**
|
||||
* Send a message to one or more members in the cluster
|
||||
* @param destination Member[] - the destinations, null or zero length means all
|
||||
* @param msg ClusterMessage - the message to send
|
||||
* @param options int - sender options, see class documentation
|
||||
* @param handler ErrorHandler - handle errors through a callback, rather than throw it
|
||||
* @return a unique Id that identifies the message that is sent
|
||||
* @exception ChannelException - if a serialization error happens.
|
||||
*/
|
||||
public UniqueId send(Member[] destination, Serializable msg, int options, ErrorHandler handler) throws ChannelException;
|
||||
|
||||
/**
|
||||
* Sends a heart beat through the interceptor stacks
|
||||
* Use this method to alert interceptors and other components to
|
||||
* clean up garbage, timed out messages etc.<br>
|
||||
* If you application has a background thread, then you can save one thread,
|
||||
* by configuring your channel to not use an internal heartbeat thread
|
||||
* and invoking this method.
|
||||
* @see #setHeartbeat(boolean)
|
||||
*/
|
||||
public void heartbeat();
|
||||
|
||||
/**
|
||||
* Enables or disables internal heartbeat.
|
||||
* @param enable boolean - default value is implementation specific
|
||||
* @see #heartbeat()
|
||||
*/
|
||||
public void setHeartbeat(boolean enable);
|
||||
|
||||
/**
|
||||
* Add a membership listener, will get notified when a new member joins, leaves or crashes
|
||||
* <br>If the membership listener implements the Heartbeat interface
|
||||
* the <code>heartbeat()</code> method will be invoked when the heartbeat runs on the channel
|
||||
* @param listener MembershipListener
|
||||
* @see MembershipListener
|
||||
*/
|
||||
public void addMembershipListener(MembershipListener listener);
|
||||
|
||||
/**
|
||||
* Add a channel listener, this is a callback object when messages are received
|
||||
* <br>If the channel listener implements the Heartbeat interface
|
||||
* the <code>heartbeat()</code> method will be invoked when the heartbeat runs on the channel
|
||||
* @param listener ChannelListener
|
||||
* @see ChannelListener
|
||||
* @see Heartbeat
|
||||
*/
|
||||
public void addChannelListener(ChannelListener listener);
|
||||
|
||||
/**
|
||||
* remove a membership listener, listeners are removed based on Object.hashCode and Object.equals
|
||||
* @param listener MembershipListener
|
||||
* @see MembershipListener
|
||||
*/
|
||||
public void removeMembershipListener(MembershipListener listener);
|
||||
/**
|
||||
* remove a channel listener, listeners are removed based on Object.hashCode and Object.equals
|
||||
* @param listener ChannelListener
|
||||
* @see ChannelListener
|
||||
*/
|
||||
public void removeChannelListener(ChannelListener listener);
|
||||
|
||||
/**
|
||||
* Returns true if there are any members in the group,
|
||||
* this call is the same as <code>getMembers().length > 0</code>
|
||||
* @return boolean - true if there are any members automatically discovered
|
||||
*/
|
||||
public boolean hasMembers() ;
|
||||
|
||||
/**
|
||||
* Get all current group members
|
||||
* @return all members or empty array, never null
|
||||
*/
|
||||
public Member[] getMembers() ;
|
||||
|
||||
/**
|
||||
* Return the member that represents this node. This is also the data
|
||||
* that gets broadcasted through the membership broadcaster component
|
||||
* @param incAlive - optimization, true if you want it to calculate alive time
|
||||
* since the membership service started.
|
||||
* @return Member
|
||||
*/
|
||||
public Member getLocalMember(boolean incAlive);
|
||||
|
||||
/**
|
||||
* Returns the member from the membership service with complete and
|
||||
* recent data. Some implementations might serialize and send
|
||||
* membership information along with a message, and instead of sending
|
||||
* complete membership details, only send the primary identifier for the member
|
||||
* but not the payload or other information. When such message is received
|
||||
* the application can retrieve the cached member through this call.<br>
|
||||
* In most cases, this is not necessary.
|
||||
* @param mbr Member
|
||||
* @return Member
|
||||
*/
|
||||
public Member getMember(Member mbr);
|
||||
|
||||
/**
|
||||
* Return the name of this channel.
|
||||
* @return channel name
|
||||
*/
|
||||
public String getName();
|
||||
|
||||
/**
|
||||
* Set the name of this channel
|
||||
* @param name The new channel name
|
||||
*/
|
||||
public void setName(String name);
|
||||
|
||||
}
|
||||
183
java/org/apache/catalina/tribes/ChannelException.java
Normal file
183
java/org/apache/catalina/tribes/ChannelException.java
Normal file
@@ -0,0 +1,183 @@
|
||||
/*
|
||||
* 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.catalina.tribes;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* Channel Exception<br>
|
||||
* A channel exception is thrown when an internal error happens
|
||||
* somewhere in the channel. <br>
|
||||
* When a global error happens, the cause can be retrieved using <code>getCause()</code><br><br>
|
||||
* If an application is sending a message and some of the recipients fail to receive it,
|
||||
* the application can retrieve what recipients failed by using the <code>getFaultyMembers()</code>
|
||||
* method. This way, an application will always know if a message was delivered successfully or not.
|
||||
*/
|
||||
public class ChannelException extends Exception {
|
||||
private static final long serialVersionUID = 1L;
|
||||
/**
|
||||
* Empty list to avoid reinstantiating lists
|
||||
*/
|
||||
protected static final FaultyMember[] EMPTY_LIST = new FaultyMember[0];
|
||||
/**
|
||||
* Holds a list of faulty members
|
||||
*/
|
||||
private ArrayList<FaultyMember> faultyMembers=null;
|
||||
|
||||
/**
|
||||
* Constructor, creates a ChannelException
|
||||
* @see java.lang.Exception#Exception()
|
||||
*/
|
||||
public ChannelException() {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor, creates a ChannelException with an error message
|
||||
* @param message The error message
|
||||
* @see java.lang.Exception#Exception(String)
|
||||
*/
|
||||
public ChannelException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor, creates a ChannelException with an error message and a cause
|
||||
* @param message The error message
|
||||
* @param cause Throwable
|
||||
* @see java.lang.Exception#Exception(String,Throwable)
|
||||
*/
|
||||
public ChannelException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor, creates a ChannelException with a cause
|
||||
* @param cause Throwable
|
||||
* @see java.lang.Exception#Exception(Throwable)
|
||||
*/
|
||||
public ChannelException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the message for this exception
|
||||
* @return the error message
|
||||
* @see java.lang.Exception#getMessage()
|
||||
*/
|
||||
@Override
|
||||
public String getMessage() {
|
||||
StringBuilder buf = new StringBuilder(super.getMessage());
|
||||
if (faultyMembers==null || faultyMembers.size() == 0 ) {
|
||||
buf.append("; No faulty members identified.");
|
||||
} else {
|
||||
buf.append("; Faulty members:");
|
||||
for ( int i=0; i<faultyMembers.size(); i++ ) {
|
||||
FaultyMember mbr = faultyMembers.get(i);
|
||||
buf.append(mbr.getMember().getName());
|
||||
buf.append("; ");
|
||||
}
|
||||
}
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a faulty member, and the reason the member failed.
|
||||
* @param mbr Member
|
||||
* @param x Exception
|
||||
* @return <code>true</code> if the member was added
|
||||
*/
|
||||
public boolean addFaultyMember(Member mbr, Exception x ) {
|
||||
return addFaultyMember(new FaultyMember(mbr,x));
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a list of faulty members
|
||||
* @param mbrs FaultyMember[]
|
||||
* @return the number of members added
|
||||
*/
|
||||
public int addFaultyMember(FaultyMember[] mbrs) {
|
||||
int result = 0;
|
||||
for (int i=0; mbrs!=null && i<mbrs.length; i++ ) {
|
||||
if ( addFaultyMember(mbrs[i]) ) result++;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a faulty member
|
||||
* @param mbr FaultyMember
|
||||
* @return <code>true</code> if the member was added
|
||||
*/
|
||||
public boolean addFaultyMember(FaultyMember mbr) {
|
||||
if ( this.faultyMembers==null ) this.faultyMembers = new ArrayList<>();
|
||||
if ( !faultyMembers.contains(mbr) ) return faultyMembers.add(mbr);
|
||||
else return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of members that failed and the reason they failed.
|
||||
* @return FaultyMember[]
|
||||
*/
|
||||
public FaultyMember[] getFaultyMembers() {
|
||||
if ( this.faultyMembers==null ) return EMPTY_LIST;
|
||||
return faultyMembers.toArray(new FaultyMember[faultyMembers.size()]);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* <p>Title: FaultyMember class</p>
|
||||
*
|
||||
* <p>Description: Represent a failure to a specific member when a message was sent
|
||||
* to more than one member</p>
|
||||
*
|
||||
* @version 1.0
|
||||
*/
|
||||
public static class FaultyMember {
|
||||
protected final Exception cause;
|
||||
protected final Member member;
|
||||
public FaultyMember(Member mbr, Exception x) {
|
||||
this.member = mbr;
|
||||
this.cause = x;
|
||||
}
|
||||
|
||||
public Member getMember() {
|
||||
return member;
|
||||
}
|
||||
|
||||
public Exception getCause() {
|
||||
return cause;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "FaultyMember:"+member.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return (member!=null)?member.hashCode():0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (member==null || (!(o instanceof FaultyMember)) || (((FaultyMember)o).member==null)) return false;
|
||||
return member.equals(((FaultyMember)o).member);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
190
java/org/apache/catalina/tribes/ChannelInterceptor.java
Normal file
190
java/org/apache/catalina/tribes/ChannelInterceptor.java
Normal file
@@ -0,0 +1,190 @@
|
||||
/*
|
||||
* 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.catalina.tribes;
|
||||
|
||||
import org.apache.catalina.tribes.group.InterceptorPayload;
|
||||
|
||||
/**
|
||||
* A ChannelInterceptor is an interceptor that intercepts
|
||||
* messages and membership messages in the channel stack.
|
||||
* This allows interceptors to modify the message or perform
|
||||
* other actions when a message is sent or received.<br>
|
||||
* Interceptors are tied together in a linked list.
|
||||
* @see org.apache.catalina.tribes.group.ChannelInterceptorBase
|
||||
*/
|
||||
public interface ChannelInterceptor extends MembershipListener, Heartbeat {
|
||||
|
||||
/**
|
||||
* An interceptor can react to a message based on a set bit on the
|
||||
* message options. <br>
|
||||
* When a message is sent, the options can be retrieved from ChannelMessage.getOptions()
|
||||
* and if the bit is set, this interceptor will react to it.<br>
|
||||
* A simple evaluation if an interceptor should react to the message would be:<br>
|
||||
* <code>boolean react = (getOptionFlag() == (getOptionFlag() & ChannelMessage.getOptions()));</code><br>
|
||||
* The default option is 0, meaning there is no way for the application to trigger the
|
||||
* interceptor. The interceptor itself will decide.<br>
|
||||
* @return int
|
||||
* @see ChannelMessage#getOptions()
|
||||
*/
|
||||
public int getOptionFlag();
|
||||
|
||||
/**
|
||||
* Sets the option flag
|
||||
* @param flag int
|
||||
* @see #getOptionFlag()
|
||||
*/
|
||||
public void setOptionFlag(int flag);
|
||||
|
||||
/**
|
||||
* Set the next interceptor in the list of interceptors
|
||||
* @param next ChannelInterceptor
|
||||
*/
|
||||
public void setNext(ChannelInterceptor next) ;
|
||||
|
||||
/**
|
||||
* Retrieve the next interceptor in the list
|
||||
* @return ChannelInterceptor - returns the next interceptor in the list or null if no more interceptors exist
|
||||
*/
|
||||
public ChannelInterceptor getNext();
|
||||
|
||||
/**
|
||||
* Set the previous interceptor in the list
|
||||
* @param previous ChannelInterceptor
|
||||
*/
|
||||
public void setPrevious(ChannelInterceptor previous);
|
||||
|
||||
/**
|
||||
* Retrieve the previous interceptor in the list
|
||||
* @return ChannelInterceptor - returns the previous interceptor in the list or null if no more interceptors exist
|
||||
*/
|
||||
public ChannelInterceptor getPrevious();
|
||||
|
||||
/**
|
||||
* The <code>sendMessage</code> method is called when a message is being sent to one more destinations.
|
||||
* The interceptor can modify any of the parameters and then pass on the message down the stack by
|
||||
* invoking <code>getNext().sendMessage(destination,msg,payload)</code><br>
|
||||
* Alternatively the interceptor can stop the message from being sent by not invoking
|
||||
* <code>getNext().sendMessage(destination,msg,payload)</code><br>
|
||||
* If the message is to be sent asynchronous the application can be notified of completion and
|
||||
* errors by passing in an error handler attached to a payload object.<br>
|
||||
* The ChannelMessage.getAddress contains Channel.getLocalMember, and can be overwritten
|
||||
* to simulate a message sent from another node.<br>
|
||||
* @param destination Member[] - the destination for this message
|
||||
* @param msg ChannelMessage - the message to be sent
|
||||
* @param payload InterceptorPayload - the payload, carrying an error handler and future useful data, can be null
|
||||
* @throws ChannelException if a serialization error happens.
|
||||
* @see ErrorHandler
|
||||
* @see InterceptorPayload
|
||||
*/
|
||||
public void sendMessage(Member[] destination, ChannelMessage msg, InterceptorPayload payload) throws ChannelException;
|
||||
|
||||
/**
|
||||
* the <code>messageReceived</code> is invoked when a message is received.
|
||||
* <code>ChannelMessage.getAddress()</code> is the sender, or the reply-to address
|
||||
* if it has been overwritten.
|
||||
* @param data ChannelMessage
|
||||
*/
|
||||
public void messageReceived(ChannelMessage data);
|
||||
|
||||
/**
|
||||
* The <code>heartbeat()</code> method gets invoked periodically
|
||||
* to allow interceptors to clean up resources, time out object and
|
||||
* perform actions that are unrelated to sending/receiving data.
|
||||
*/
|
||||
@Override
|
||||
public void heartbeat();
|
||||
|
||||
/**
|
||||
* Intercepts the <code>Channel.hasMembers()</code> method
|
||||
* @return boolean - if the channel has members in its membership group
|
||||
* @see Channel#hasMembers()
|
||||
*/
|
||||
public boolean hasMembers() ;
|
||||
|
||||
/**
|
||||
* Intercepts the <code>Channel.getMembers()</code> method
|
||||
* @return Member[]
|
||||
* @see Channel#getMembers()
|
||||
*/
|
||||
public Member[] getMembers() ;
|
||||
|
||||
/**
|
||||
* Intercepts the <code>Channel.getLocalMember(boolean)</code> method
|
||||
* @param incAliveTime boolean
|
||||
* @return Member
|
||||
* @see Channel#getLocalMember(boolean)
|
||||
*/
|
||||
public Member getLocalMember(boolean incAliveTime) ;
|
||||
|
||||
/**
|
||||
* Intercepts the <code>Channel.getMember(Member)</code> method
|
||||
* @param mbr Member
|
||||
* @return Member - the actual member information, including stay alive
|
||||
* @see Channel#getMember(Member)
|
||||
*/
|
||||
public Member getMember(Member mbr);
|
||||
|
||||
/**
|
||||
* Starts up the channel. This can be called multiple times for individual services to start
|
||||
* The svc parameter can be the logical or value of any constants
|
||||
* @param svc int value of <BR>
|
||||
* Channel.DEFAULT - will start all services <BR>
|
||||
* Channel.MBR_RX_SEQ - starts the membership receiver <BR>
|
||||
* Channel.MBR_TX_SEQ - starts the membership broadcaster <BR>
|
||||
* Channel.SND_TX_SEQ - starts the replication transmitter<BR>
|
||||
* Channel.SND_RX_SEQ - starts the replication receiver<BR>
|
||||
* @throws ChannelException if a startup error occurs or the service is already started.
|
||||
* @see Channel
|
||||
*/
|
||||
public void start(int svc) throws ChannelException;
|
||||
|
||||
/**
|
||||
* Shuts down the channel. This can be called multiple times for individual services to shutdown
|
||||
* The svc parameter can be the logical or value of any constants
|
||||
* @param svc int value of <BR>
|
||||
* Channel.DEFAULT - will shutdown all services <BR>
|
||||
* Channel.MBR_RX_SEQ - stops the membership receiver <BR>
|
||||
* Channel.MBR_TX_SEQ - stops the membership broadcaster <BR>
|
||||
* Channel.SND_TX_SEQ - stops the replication transmitter<BR>
|
||||
* Channel.SND_RX_SEQ - stops the replication receiver<BR>
|
||||
* @throws ChannelException if a startup error occurs or the service is already started.
|
||||
* @see Channel
|
||||
*/
|
||||
public void stop(int svc) throws ChannelException;
|
||||
|
||||
public void fireInterceptorEvent(InterceptorEvent event);
|
||||
|
||||
/**
|
||||
* Return the channel that is related to this interceptor
|
||||
* @return Channel
|
||||
*/
|
||||
public Channel getChannel();
|
||||
|
||||
/**
|
||||
* Set the channel that is related to this interceptor
|
||||
* @param channel The channel
|
||||
*/
|
||||
public void setChannel(Channel channel);
|
||||
|
||||
interface InterceptorEvent {
|
||||
int getEventType();
|
||||
String getEventTypeDesc();
|
||||
ChannelInterceptor getInterceptor();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
69
java/org/apache/catalina/tribes/ChannelListener.java
Normal file
69
java/org/apache/catalina/tribes/ChannelListener.java
Normal file
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* 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.catalina.tribes;
|
||||
|
||||
import java.io.Serializable;
|
||||
/**
|
||||
*
|
||||
* <p>Title: ChannelListener</p>
|
||||
*
|
||||
* <p>Description: An interface to listens to incoming messages from a channel </p>
|
||||
* When a message is received, the Channel will invoke the channel listener in a conditional sequence.
|
||||
* <code>if ( listener.accept(msg,sender) ) listener.messageReceived(msg,sender);</code><br>
|
||||
* A ChannelListener implementation MUST NOT return true on <code>accept(Serializable, Member)</code>
|
||||
* if it doesn't intend to process the message. The channel can this way track whether a message
|
||||
* was processed by an above application or if it was just received and forgot about, a feature required
|
||||
* to support message-response(RPC) calls<br>
|
||||
*
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
public interface ChannelListener {
|
||||
|
||||
/**
|
||||
* Receive a message from the channel
|
||||
* @param msg Serializable
|
||||
* @param sender - the source of the message
|
||||
*/
|
||||
public void messageReceived(Serializable msg, Member sender);
|
||||
|
||||
/**
|
||||
* Invoked by the channel to determine if the listener will process this message or not.
|
||||
* @param msg Serializable
|
||||
* @param sender Member
|
||||
* @return boolean
|
||||
*/
|
||||
public boolean accept(Serializable msg, Member sender);
|
||||
|
||||
/**
|
||||
*
|
||||
* @param listener Object
|
||||
* @return boolean
|
||||
* @see Object#equals(Object)
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object listener);
|
||||
|
||||
/**
|
||||
*
|
||||
* @return int
|
||||
* @see Object#hashCode()
|
||||
*/
|
||||
@Override
|
||||
public int hashCode();
|
||||
|
||||
}
|
||||
107
java/org/apache/catalina/tribes/ChannelMessage.java
Normal file
107
java/org/apache/catalina/tribes/ChannelMessage.java
Normal file
@@ -0,0 +1,107 @@
|
||||
/*
|
||||
* 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.catalina.tribes;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import org.apache.catalina.tribes.io.XByteBuffer;
|
||||
|
||||
/**
|
||||
* Message that is passed through the interceptor stack after the
|
||||
* data serialized in the Channel object and then passed down to the
|
||||
* interceptor and eventually down to the ChannelSender component
|
||||
*
|
||||
*/
|
||||
public interface ChannelMessage extends Serializable, Cloneable {
|
||||
|
||||
|
||||
/**
|
||||
* Get the address that this message originated from.
|
||||
* Almost always <code>Channel.getLocalMember(boolean)</code><br>
|
||||
* This would be set to a different address
|
||||
* if the message was being relayed from a host other than the one
|
||||
* that originally sent it.
|
||||
* @return the source or reply-to address of this message
|
||||
*/
|
||||
public Member getAddress();
|
||||
|
||||
/**
|
||||
* Sets the source or reply-to address of this message
|
||||
* @param member Member
|
||||
*/
|
||||
public void setAddress(Member member);
|
||||
|
||||
/**
|
||||
* Timestamp of when the message was created.
|
||||
* @return long timestamp in milliseconds
|
||||
*/
|
||||
public long getTimestamp();
|
||||
|
||||
/**
|
||||
*
|
||||
* Sets the timestamp of this message
|
||||
* @param timestamp The timestamp
|
||||
*/
|
||||
public void setTimestamp(long timestamp);
|
||||
|
||||
/**
|
||||
* Each message must have a globally unique Id.
|
||||
* interceptors heavily depend on this id for message processing
|
||||
* @return byte
|
||||
*/
|
||||
public byte[] getUniqueId();
|
||||
|
||||
/**
|
||||
* The byte buffer that contains the actual message payload
|
||||
* @param buf XByteBuffer
|
||||
*/
|
||||
public void setMessage(XByteBuffer buf);
|
||||
|
||||
/**
|
||||
* returns the byte buffer that contains the actual message payload
|
||||
* @return XByteBuffer
|
||||
*/
|
||||
public XByteBuffer getMessage();
|
||||
|
||||
/**
|
||||
* The message options is a 32 bit flag set
|
||||
* that triggers interceptors and message behavior.
|
||||
* @see Channel#send(Member[], Serializable, int)
|
||||
* @see ChannelInterceptor#getOptionFlag
|
||||
* @return int - the option bits set for this message
|
||||
*/
|
||||
public int getOptions();
|
||||
|
||||
/**
|
||||
* sets the option bits for this message
|
||||
* @param options int
|
||||
* @see #getOptions()
|
||||
*/
|
||||
public void setOptions(int options);
|
||||
|
||||
/**
|
||||
* Shallow clone, what gets cloned depends on the implementation
|
||||
* @return ChannelMessage
|
||||
*/
|
||||
public Object clone();
|
||||
|
||||
/**
|
||||
* Deep clone, all fields MUST get cloned
|
||||
* @return ChannelMessage
|
||||
*/
|
||||
public Object deepclone();
|
||||
}
|
||||
93
java/org/apache/catalina/tribes/ChannelReceiver.java
Normal file
93
java/org/apache/catalina/tribes/ChannelReceiver.java
Normal file
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* 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.catalina.tribes;
|
||||
|
||||
|
||||
/**
|
||||
* ChannelReceiver Interface<br>
|
||||
* The <code>ChannelReceiver</code> interface is the data receiver component
|
||||
* at the bottom layer, the IO layer (for layers see the javadoc for the {@link Channel} interface).
|
||||
* This class may optionally implement a thread pool for parallel processing of incoming messages.
|
||||
*/
|
||||
public interface ChannelReceiver extends Heartbeat {
|
||||
public static final int MAX_UDP_SIZE = 65535;
|
||||
|
||||
/**
|
||||
* Start listening for incoming messages on the host/port
|
||||
* @throws java.io.IOException Listen failed
|
||||
*/
|
||||
public void start() throws java.io.IOException;
|
||||
|
||||
/**
|
||||
* Stop listening for messages
|
||||
*/
|
||||
public void stop();
|
||||
|
||||
/**
|
||||
* String representation of the IPv4 or IPv6 address that this host is listening
|
||||
* to.
|
||||
* @return the host that this receiver is listening to
|
||||
*/
|
||||
public String getHost();
|
||||
|
||||
|
||||
/**
|
||||
* Returns the listening port
|
||||
* @return port
|
||||
*/
|
||||
public int getPort();
|
||||
|
||||
/**
|
||||
* Returns the secure listening port
|
||||
* @return port, -1 if a secure port is not activated
|
||||
*/
|
||||
public int getSecurePort();
|
||||
|
||||
/**
|
||||
* Returns the UDP port
|
||||
* @return port, -1 if the UDP port is not activated.
|
||||
*/
|
||||
public int getUdpPort();
|
||||
|
||||
/**
|
||||
* Sets the message listener to receive notification of incoming
|
||||
* @param listener MessageListener
|
||||
* @see MessageListener
|
||||
*/
|
||||
public void setMessageListener(MessageListener listener);
|
||||
|
||||
/**
|
||||
* Returns the message listener that is associated with this receiver
|
||||
* @return MessageListener
|
||||
* @see MessageListener
|
||||
*/
|
||||
public MessageListener getMessageListener();
|
||||
|
||||
/**
|
||||
* Return the channel that is related to this ChannelReceiver
|
||||
* @return Channel
|
||||
*/
|
||||
public Channel getChannel();
|
||||
|
||||
/**
|
||||
* Set the channel that is related to this ChannelReceiver
|
||||
* @param channel The channel
|
||||
*/
|
||||
public void setChannel(Channel channel);
|
||||
|
||||
}
|
||||
84
java/org/apache/catalina/tribes/ChannelSender.java
Normal file
84
java/org/apache/catalina/tribes/ChannelSender.java
Normal file
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
* 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.catalina.tribes;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
|
||||
/**
|
||||
* ChannelReceiver Interface<br>
|
||||
* The <code>ChannelSender</code> interface is the data sender component
|
||||
* at the bottom layer, the IO layer (for layers see the javadoc for the {@link Channel} interface).<br>
|
||||
* The channel sender must support "silent" members, ie, be able to send a message to a member
|
||||
* that is not in the membership, but is part of the destination parameter
|
||||
*/
|
||||
public interface ChannelSender extends Heartbeat
|
||||
{
|
||||
/**
|
||||
* Notify the sender of a member being added to the group.<br>
|
||||
* Optional. This can be an empty implementation, that does nothing
|
||||
* @param member Member
|
||||
*/
|
||||
public void add(Member member);
|
||||
/**
|
||||
* Notification that a member has been removed or crashed.
|
||||
* Can be used to clean up open connections etc
|
||||
* @param member Member
|
||||
*/
|
||||
public void remove(Member member);
|
||||
|
||||
/**
|
||||
* Start the channel sender
|
||||
* @throws IOException if preprocessing takes place and an error happens
|
||||
*/
|
||||
public void start() throws IOException;
|
||||
|
||||
/**
|
||||
* Stop the channel sender
|
||||
*/
|
||||
public void stop();
|
||||
|
||||
/**
|
||||
* A channel heartbeat, use this method to clean up resources
|
||||
*/
|
||||
@Override
|
||||
public void heartbeat() ;
|
||||
|
||||
/**
|
||||
* Send a message to one or more recipients.
|
||||
* @param message ChannelMessage - the message to be sent
|
||||
* @param destination Member[] - the destinations
|
||||
* @throws ChannelException - if an error happens, the ChannelSender MUST report
|
||||
* individual send failures on a per member basis, using ChannelException.addFaultyMember
|
||||
* @see ChannelException#addFaultyMember(Member,java.lang.Exception)
|
||||
*/
|
||||
public void sendMessage(ChannelMessage message, Member[] destination) throws ChannelException;
|
||||
|
||||
/**
|
||||
* Return the channel that is related to this ChannelSender
|
||||
* @return Channel
|
||||
*/
|
||||
public Channel getChannel();
|
||||
|
||||
/**
|
||||
* Set the channel that is related to this ChannelSender
|
||||
* @param channel The channel
|
||||
*/
|
||||
public void setChannel(Channel channel);
|
||||
|
||||
}
|
||||
45
java/org/apache/catalina/tribes/ErrorHandler.java
Normal file
45
java/org/apache/catalina/tribes/ErrorHandler.java
Normal file
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* 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.catalina.tribes;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* The <code>ErrorHandler</code> class is used when sending messages
|
||||
* that are sent asynchronously and the application still needs to get
|
||||
* confirmation when the message was sent successfully or when a message errored out.
|
||||
* @version 1.0
|
||||
*/
|
||||
public interface ErrorHandler {
|
||||
|
||||
/**
|
||||
* Invoked if the message is dispatched async, and an error occurs
|
||||
* @param x ChannelException - the error that happened
|
||||
* @param id - the unique id for the message
|
||||
* @see Channel#send(Member[], java.io.Serializable, int, ErrorHandler)
|
||||
*/
|
||||
public void handleError(ChannelException x, UniqueId id);
|
||||
|
||||
/**
|
||||
* Invoked when the message has been sent successfully.
|
||||
* @param id - the unique id for the message
|
||||
* @see Channel#send(Member[], java.io.Serializable, int, ErrorHandler)
|
||||
*/
|
||||
public void handleCompletion(UniqueId id);
|
||||
|
||||
}
|
||||
33
java/org/apache/catalina/tribes/Heartbeat.java
Normal file
33
java/org/apache/catalina/tribes/Heartbeat.java
Normal file
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* 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.catalina.tribes;
|
||||
|
||||
/**
|
||||
* Can be implemented by the ChannelListener and Membership listeners to receive heartbeat
|
||||
* notifications from the Channel
|
||||
* @version 1.0
|
||||
* @see Channel
|
||||
* @see Channel#heartbeat()
|
||||
*/
|
||||
public interface Heartbeat {
|
||||
|
||||
/**
|
||||
* Heartbeat invocation for resources cleanup etc
|
||||
*/
|
||||
public void heartbeat();
|
||||
|
||||
}
|
||||
60
java/org/apache/catalina/tribes/JmxChannel.java
Normal file
60
java/org/apache/catalina/tribes/JmxChannel.java
Normal file
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* 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.catalina.tribes;
|
||||
|
||||
import javax.management.MBeanRegistration;
|
||||
|
||||
|
||||
public interface JmxChannel extends MBeanRegistration {
|
||||
|
||||
/**
|
||||
* If set to true, this channel is registered with jmx.
|
||||
* @return true if this channel will be registered with jmx.
|
||||
*/
|
||||
public boolean isJmxEnabled();
|
||||
|
||||
/**
|
||||
* If set to true, this channel is registered with jmx.
|
||||
* @param jmxEnabled set to true if this channel should be registered with jmx.
|
||||
*/
|
||||
public void setJmxEnabled(boolean jmxEnabled);
|
||||
|
||||
/**
|
||||
* Return the jmx domain which this channel is registered.
|
||||
* @return jmxDomain
|
||||
*/
|
||||
public String getJmxDomain();
|
||||
|
||||
/**
|
||||
* Set the jmx domain which this channel should be registered.
|
||||
* @param jmxDomain The jmx domain which this channel should be registered.
|
||||
*/
|
||||
public void setJmxDomain(String jmxDomain);
|
||||
|
||||
/**
|
||||
* Return the jmx prefix which will be used with channel ObjectName.
|
||||
* @return jmxPrefix
|
||||
*/
|
||||
public String getJmxPrefix();
|
||||
|
||||
/**
|
||||
* Set the jmx prefix which will be used with channel ObjectName.
|
||||
* @param jmxPrefix The jmx prefix which will be used with channel ObjectName.
|
||||
*/
|
||||
public void setJmxPrefix(String jmxPrefix);
|
||||
|
||||
}
|
||||
76
java/org/apache/catalina/tribes/ManagedChannel.java
Normal file
76
java/org/apache/catalina/tribes/ManagedChannel.java
Normal file
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* 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.catalina.tribes;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
/**
|
||||
* Channel interface
|
||||
* A managed channel interface gives you access to the components of the channels
|
||||
* such as senders, receivers, interceptors etc for configurations purposes
|
||||
*/
|
||||
public interface ManagedChannel extends Channel {
|
||||
|
||||
/**
|
||||
* Sets the channel sender
|
||||
* @param sender ChannelSender
|
||||
* @see ChannelSender
|
||||
*/
|
||||
public void setChannelSender(ChannelSender sender);
|
||||
|
||||
/**
|
||||
* Sets the channel receiver
|
||||
* @param receiver ChannelReceiver
|
||||
* @see ChannelReceiver
|
||||
*/
|
||||
public void setChannelReceiver(ChannelReceiver receiver);
|
||||
|
||||
/**
|
||||
* Sets the membership service
|
||||
* @param service MembershipService
|
||||
* @see MembershipService
|
||||
*/
|
||||
public void setMembershipService(MembershipService service);
|
||||
|
||||
/**
|
||||
* returns the channel sender
|
||||
* @return ChannelSender
|
||||
* @see ChannelSender
|
||||
*/
|
||||
public ChannelSender getChannelSender();
|
||||
|
||||
/**
|
||||
* returns the channel receiver
|
||||
* @return ChannelReceiver
|
||||
* @see ChannelReceiver
|
||||
*/
|
||||
public ChannelReceiver getChannelReceiver();
|
||||
|
||||
/**
|
||||
* Returns the membership service
|
||||
* @return MembershipService
|
||||
* @see MembershipService
|
||||
*/
|
||||
public MembershipService getMembershipService();
|
||||
|
||||
/**
|
||||
* Returns the interceptor stack
|
||||
* @return Iterator
|
||||
* @see Channel#addInterceptor(ChannelInterceptor)
|
||||
*/
|
||||
public Iterator<ChannelInterceptor> getInterceptors();
|
||||
}
|
||||
160
java/org/apache/catalina/tribes/Member.java
Normal file
160
java/org/apache/catalina/tribes/Member.java
Normal file
@@ -0,0 +1,160 @@
|
||||
/*
|
||||
* 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.catalina.tribes;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* The Member interface, defines a member in the group.
|
||||
* Each member can carry a set of properties, defined by the actual implementation.<BR>
|
||||
* A member is identified by the host/ip/uniqueId<br>
|
||||
* The host is what interface the member is listening to, to receive data<br>
|
||||
* The port is what port the member is listening to, to receive data<br>
|
||||
* The uniqueId defines the session id for the member. This is an important feature
|
||||
* since a member that has crashed and the starts up again on the same port/host is
|
||||
* not guaranteed to be the same member, so no state transfers will ever be confused
|
||||
*/
|
||||
public interface Member extends Serializable {
|
||||
|
||||
/**
|
||||
* When a member leaves the cluster, the payload of the memberDisappeared member
|
||||
* will be the following bytes. This indicates a soft shutdown, and not a crash
|
||||
*/
|
||||
public static final byte[] SHUTDOWN_PAYLOAD = new byte[] {66, 65, 66, 89, 45, 65, 76, 69, 88};
|
||||
|
||||
/**
|
||||
* @return the name of this node, should be unique within the group.
|
||||
*/
|
||||
public String getName();
|
||||
|
||||
/**
|
||||
* Returns the listen host for the ChannelReceiver implementation
|
||||
* @return IPv4 or IPv6 representation of the host address this member listens to incoming data
|
||||
* @see ChannelReceiver
|
||||
*/
|
||||
public byte[] getHost();
|
||||
|
||||
/**
|
||||
* Returns the listen port for the ChannelReceiver implementation
|
||||
* @return the listen port for this member, -1 if its not listening on an insecure port
|
||||
* @see ChannelReceiver
|
||||
*/
|
||||
public int getPort();
|
||||
|
||||
/**
|
||||
* Returns the secure listen port for the ChannelReceiver implementation.
|
||||
* Returns -1 if its not listening to a secure port.
|
||||
* @return the listen port for this member, -1 if its not listening on a secure port
|
||||
* @see ChannelReceiver
|
||||
*/
|
||||
public int getSecurePort();
|
||||
|
||||
/**
|
||||
* Returns the UDP port that this member is listening to for UDP messages.
|
||||
* @return the listen UDP port for this member, -1 if its not listening on a UDP port
|
||||
*/
|
||||
public int getUdpPort();
|
||||
|
||||
|
||||
/**
|
||||
* Contains information on how long this member has been online.
|
||||
* The result is the number of milli seconds this member has been
|
||||
* broadcasting its membership to the group.
|
||||
* @return nr of milliseconds since this member started.
|
||||
*/
|
||||
public long getMemberAliveTime();
|
||||
|
||||
public void setMemberAliveTime(long memberAliveTime);
|
||||
|
||||
/**
|
||||
* The current state of the member
|
||||
* @return boolean - true if the member is functioning correctly
|
||||
*/
|
||||
public boolean isReady();
|
||||
/**
|
||||
* The current state of the member
|
||||
* @return boolean - true if the member is suspect, but the crash has not been confirmed
|
||||
*/
|
||||
public boolean isSuspect();
|
||||
|
||||
/**
|
||||
*
|
||||
* @return boolean - true if the member has been confirmed to malfunction
|
||||
*/
|
||||
public boolean isFailing();
|
||||
|
||||
/**
|
||||
* returns a UUID unique for this member over all sessions.
|
||||
* If the member crashes and restarts, the uniqueId will be different.
|
||||
* @return byte[]
|
||||
*/
|
||||
public byte[] getUniqueId();
|
||||
|
||||
/**
|
||||
* returns the payload associated with this member
|
||||
* @return byte[]
|
||||
*/
|
||||
public byte[] getPayload();
|
||||
|
||||
public void setPayload(byte[] payload);
|
||||
|
||||
/**
|
||||
* returns the command associated with this member
|
||||
* @return byte[]
|
||||
*/
|
||||
public byte[] getCommand();
|
||||
|
||||
public void setCommand(byte[] command);
|
||||
|
||||
/**
|
||||
* Domain for this cluster
|
||||
* @return byte[]
|
||||
*/
|
||||
public byte[] getDomain();
|
||||
|
||||
/**
|
||||
* Highly optimized version of serializing a member into a byte array
|
||||
* Returns a cached byte[] reference, do not modify this data
|
||||
* @param getalive calculate memberAlive time
|
||||
* @return the data as a byte array
|
||||
*/
|
||||
public byte[] getData(boolean getalive);
|
||||
|
||||
/**
|
||||
* Highly optimized version of serializing a member into a byte array
|
||||
* Returns a cached byte[] reference, do not modify this data
|
||||
* @param getalive calculate memberAlive time
|
||||
* @param reset reset the cached data package, and create a new one
|
||||
* @return the data as a byte array
|
||||
*/
|
||||
public byte[] getData(boolean getalive, boolean reset);
|
||||
|
||||
/**
|
||||
* Length of a message obtained by {@link #getData(boolean)} or
|
||||
* {@link #getData(boolean, boolean)}.
|
||||
* @return the data length
|
||||
*/
|
||||
public int getDataLength();
|
||||
|
||||
/**
|
||||
* @return boolean - true if the member is local member
|
||||
*/
|
||||
public boolean isLocal();
|
||||
|
||||
public void setLocal(boolean local);
|
||||
}
|
||||
40
java/org/apache/catalina/tribes/MembershipListener.java
Normal file
40
java/org/apache/catalina/tribes/MembershipListener.java
Normal file
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* 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.catalina.tribes;
|
||||
|
||||
/**
|
||||
* The MembershipListener interface is used as a callback to the
|
||||
* membership service. It has two methods that will notify the listener
|
||||
* when a member has joined the group and when a member has disappeared (crashed)
|
||||
*/
|
||||
public interface MembershipListener {
|
||||
/**
|
||||
* A member was added to the group
|
||||
* @param member Member - the member that was added
|
||||
*/
|
||||
public void memberAdded(Member member);
|
||||
|
||||
/**
|
||||
* A member was removed from the group<br>
|
||||
* If the member left voluntarily, the Member.getCommand will contain the Member.SHUTDOWN_PAYLOAD data
|
||||
* @param member Member
|
||||
* @see Member#SHUTDOWN_PAYLOAD
|
||||
*/
|
||||
public void memberDisappeared(Member member);
|
||||
|
||||
}
|
||||
159
java/org/apache/catalina/tribes/MembershipService.java
Normal file
159
java/org/apache/catalina/tribes/MembershipService.java
Normal file
@@ -0,0 +1,159 @@
|
||||
/*
|
||||
* 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.catalina.tribes;
|
||||
|
||||
|
||||
/**
|
||||
* MembershipService Interface<br>
|
||||
* The <code>MembershipService</code> interface is the membership component
|
||||
* at the bottom layer, the IO layer (for layers see the javadoc for the {@link Channel} interface).<br>
|
||||
*/
|
||||
public interface MembershipService {
|
||||
|
||||
public static final int MBR_RX = Channel.MBR_RX_SEQ;
|
||||
public static final int MBR_TX = Channel.MBR_TX_SEQ;
|
||||
|
||||
/**
|
||||
* Sets the properties for the membership service. This must be called before
|
||||
* the <code>start()</code> method is called.
|
||||
* The properties are implementation specific.
|
||||
* @param properties - to be used to configure the membership service.
|
||||
*/
|
||||
public void setProperties(java.util.Properties properties);
|
||||
|
||||
/**
|
||||
* @return the properties for the configuration used.
|
||||
*/
|
||||
public java.util.Properties getProperties();
|
||||
|
||||
/**
|
||||
* Starts the membership service. If a membership listeners is added
|
||||
* the listener will start to receive membership events.
|
||||
* Performs a start level 1 and 2
|
||||
* @throws java.lang.Exception if the service fails to start.
|
||||
*/
|
||||
public void start() throws java.lang.Exception;
|
||||
|
||||
/**
|
||||
* Starts the membership service. If a membership listeners is added
|
||||
* the listener will start to receive membership events.
|
||||
* @param level - level MBR_RX starts listening for members, level MBR_TX
|
||||
* starts broad casting the server
|
||||
* @throws java.lang.Exception if the service fails to start.
|
||||
* @throws java.lang.IllegalArgumentException if the level is incorrect.
|
||||
*/
|
||||
public void start(int level) throws java.lang.Exception;
|
||||
|
||||
|
||||
/**
|
||||
* Starts the membership service. If a membership listeners is added
|
||||
* the listener will start to receive membership events.
|
||||
* @param level - level MBR_RX stops listening for members, level MBR_TX
|
||||
* stops broad casting the server
|
||||
* @throws java.lang.IllegalArgumentException if the level is incorrect.
|
||||
*/
|
||||
public void stop(int level);
|
||||
|
||||
/**
|
||||
* @return true if the the group contains members
|
||||
*/
|
||||
public boolean hasMembers();
|
||||
|
||||
/**
|
||||
* Retrieve the specified member from the membership.
|
||||
* @param mbr The member to retrieve
|
||||
* @return the member
|
||||
*/
|
||||
public Member getMember(Member mbr);
|
||||
|
||||
/**
|
||||
* @return a list of all the members in the cluster.
|
||||
*/
|
||||
public Member[] getMembers();
|
||||
|
||||
/**
|
||||
* Get the local member.
|
||||
* @return the member object that defines this member
|
||||
* @param incAliveTime <code>true</code> to set the alive time
|
||||
* on the local member
|
||||
*/
|
||||
public Member getLocalMember(boolean incAliveTime);
|
||||
|
||||
/**
|
||||
* @return all members by name
|
||||
*/
|
||||
public String[] getMembersByName();
|
||||
|
||||
/**
|
||||
* Get a member.
|
||||
* @param name The member name
|
||||
* @return the member
|
||||
*/
|
||||
public Member findMemberByName(String name);
|
||||
|
||||
/**
|
||||
* Sets the local member properties for broadcasting.
|
||||
*
|
||||
* @param listenHost Listen to host
|
||||
* @param listenPort Listen to port
|
||||
* @param securePort Use a secure port
|
||||
* @param udpPort Use UDP
|
||||
*/
|
||||
public void setLocalMemberProperties(String listenHost, int listenPort, int securePort, int udpPort);
|
||||
|
||||
/**
|
||||
* Sets the membership listener, only one listener can be added.
|
||||
* If you call this method twice, the last listener will be used.
|
||||
* @param listener The listener
|
||||
*/
|
||||
public void setMembershipListener(MembershipListener listener);
|
||||
|
||||
/**
|
||||
* Removes the membership listener.
|
||||
*/
|
||||
public void removeMembershipListener();
|
||||
|
||||
/**
|
||||
* Set a payload to be broadcasted with each membership
|
||||
* broadcast.
|
||||
* @param payload byte[]
|
||||
*/
|
||||
public void setPayload(byte[] payload);
|
||||
|
||||
public void setDomain(byte[] domain);
|
||||
|
||||
/**
|
||||
* Broadcasts a message to all members.
|
||||
* @param message The message to broadcast
|
||||
* @throws ChannelException Message broadcast failed
|
||||
*/
|
||||
public void broadcast(ChannelMessage message) throws ChannelException;
|
||||
|
||||
/**
|
||||
* Return the channel that is related to this MembershipService
|
||||
* @return Channel
|
||||
*/
|
||||
public Channel getChannel();
|
||||
|
||||
/**
|
||||
* Set the channel that is related to this MembershipService
|
||||
* @param channel The channel
|
||||
*/
|
||||
public void setChannel(Channel channel);
|
||||
|
||||
}
|
||||
37
java/org/apache/catalina/tribes/MessageListener.java
Normal file
37
java/org/apache/catalina/tribes/MessageListener.java
Normal file
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* 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.catalina.tribes;
|
||||
|
||||
/**
|
||||
*
|
||||
* <p>Title: MessageListener</p>
|
||||
*
|
||||
* <p>Description: The listener to be registered with the ChannelReceiver, internal Tribes component</p>
|
||||
*
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
public interface MessageListener {
|
||||
|
||||
/**
|
||||
* Receive a message from the IO components in the Channel stack
|
||||
* @param msg ChannelMessage
|
||||
*/
|
||||
public void messageReceived(ChannelMessage msg);
|
||||
|
||||
public boolean accept(ChannelMessage msg);
|
||||
}
|
||||
48
java/org/apache/catalina/tribes/RemoteProcessException.java
Normal file
48
java/org/apache/catalina/tribes/RemoteProcessException.java
Normal file
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* 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.catalina.tribes;
|
||||
|
||||
/**
|
||||
* <p>Title: RemoteProcessException</p>
|
||||
*
|
||||
* <p>Description: Message thrown by a sender when USE_SYNC_ACK receives a FAIL_ACK_COMMAND.<br>
|
||||
* This means that the message was received on the remote node but the processing of the message failed.
|
||||
* This message will be embedded in a ChannelException.FaultyMember
|
||||
* </p>
|
||||
* @see ChannelException
|
||||
* @version 1.0
|
||||
*/
|
||||
public class RemoteProcessException extends RuntimeException {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public RemoteProcessException() {
|
||||
super();
|
||||
}
|
||||
|
||||
public RemoteProcessException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public RemoteProcessException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
public RemoteProcessException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
}
|
||||
78
java/org/apache/catalina/tribes/UniqueId.java
Normal file
78
java/org/apache/catalina/tribes/UniqueId.java
Normal file
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* 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.catalina.tribes;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import org.apache.catalina.tribes.util.Arrays;
|
||||
|
||||
/**
|
||||
* <p>Title: Represents a globally unique Id</p>
|
||||
*
|
||||
* <p>Company: </p>
|
||||
*
|
||||
* @version 1.0
|
||||
*/
|
||||
public final class UniqueId implements Serializable{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
final byte[] id;
|
||||
|
||||
public UniqueId() {
|
||||
this(null);
|
||||
}
|
||||
|
||||
public UniqueId(byte[] id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public UniqueId(byte[] id, int offset, int length) {
|
||||
this.id = new byte[length];
|
||||
System.arraycopy(id,offset,this.id,0,length);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
if ( id == null ) return 0;
|
||||
return Arrays.hashCode(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object other) {
|
||||
boolean result = (other instanceof UniqueId);
|
||||
if ( result ) {
|
||||
UniqueId uid = (UniqueId)other;
|
||||
if ( this.id == null && uid.id == null ) result = true;
|
||||
else if ( this.id == null && uid.id != null ) result = false;
|
||||
else if ( this.id != null && uid.id == null ) result = false;
|
||||
else result = Arrays.equals(this.id,uid.id);
|
||||
}//end if
|
||||
return result;
|
||||
}
|
||||
|
||||
public byte[] getBytes() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder buf = new StringBuilder("UniqueId");
|
||||
buf.append(Arrays.toString(id));
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
}
|
||||
120
java/org/apache/catalina/tribes/group/AbsoluteOrder.java
Normal file
120
java/org/apache/catalina/tribes/group/AbsoluteOrder.java
Normal file
@@ -0,0 +1,120 @@
|
||||
/*
|
||||
* 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.catalina.tribes.group;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Arrays;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.catalina.tribes.Member;
|
||||
|
||||
/**
|
||||
* <p>Title: Membership - Absolute Order</p>
|
||||
*
|
||||
* <p>Description: A simple, yet agreeable and efficient way of ordering members</p>
|
||||
* <p>
|
||||
* Ordering members can serve as a basis for electing a leader or coordinating efforts.<br>
|
||||
* This is stinky simple, it works on the basis of the <code>Member</code> interface
|
||||
* and orders members in the following format:
|
||||
* </p>
|
||||
* <ol>
|
||||
* <li>IP comparison - byte by byte, lower byte higher rank</li>
|
||||
* <li>IPv4 addresses rank higher than IPv6, ie the lesser number of bytes, the higher rank</li>
|
||||
* <li>Port comparison - lower port, higher rank</li>
|
||||
* <li>UniqueId comparison- byte by byte, lower byte higher rank</li>
|
||||
* </ol>
|
||||
*
|
||||
*
|
||||
* @version 1.0
|
||||
* @see org.apache.catalina.tribes.Member
|
||||
*/
|
||||
public class AbsoluteOrder {
|
||||
public static final AbsoluteComparator comp = new AbsoluteComparator();
|
||||
|
||||
protected AbsoluteOrder() {
|
||||
super();
|
||||
}
|
||||
|
||||
|
||||
public static void absoluteOrder(Member[] members) {
|
||||
if ( members == null || members.length <= 1 ) return;
|
||||
Arrays.sort(members,comp);
|
||||
}
|
||||
|
||||
public static void absoluteOrder(List<Member> members) {
|
||||
if ( members == null || members.size() <= 1 ) return;
|
||||
java.util.Collections.sort(members, comp);
|
||||
}
|
||||
|
||||
public static class AbsoluteComparator implements Comparator<Member>,
|
||||
Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Override
|
||||
public int compare(Member m1, Member m2) {
|
||||
int result = compareIps(m1,m2);
|
||||
if ( result == 0 ) result = comparePorts(m1,m2);
|
||||
if ( result == 0 ) result = compareIds(m1,m2);
|
||||
return result;
|
||||
}
|
||||
|
||||
public int compareIps(Member m1, Member m2) {
|
||||
return compareBytes(m1.getHost(),m2.getHost());
|
||||
}
|
||||
|
||||
public int comparePorts(Member m1, Member m2) {
|
||||
return compareInts(m1.getPort(),m2.getPort());
|
||||
}
|
||||
|
||||
public int compareIds(Member m1, Member m2) {
|
||||
return compareBytes(m1.getUniqueId(),m2.getUniqueId());
|
||||
}
|
||||
|
||||
protected int compareBytes(byte[] d1, byte[] d2) {
|
||||
int result = 0;
|
||||
if ( d1.length == d2.length ) {
|
||||
for (int i=0; (result==0) && (i<d1.length); i++) {
|
||||
result = compareBytes(d1[i],d2[i]);
|
||||
}
|
||||
} else if ( d1.length < d2.length) {
|
||||
result = -1;
|
||||
} else {
|
||||
result = 1;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
protected int compareBytes(byte b1, byte b2) {
|
||||
return compareInts(b1,b2);
|
||||
}
|
||||
|
||||
protected int compareInts(int b1, int b2) {
|
||||
int result = 0;
|
||||
if ( b1 == b2 ) {
|
||||
|
||||
} else if ( b1 < b2) {
|
||||
result = -1;
|
||||
} else {
|
||||
result = 1;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
359
java/org/apache/catalina/tribes/group/ChannelCoordinator.java
Normal file
359
java/org/apache/catalina/tribes/group/ChannelCoordinator.java
Normal file
@@ -0,0 +1,359 @@
|
||||
/*
|
||||
* 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.catalina.tribes.group;
|
||||
|
||||
import org.apache.catalina.tribes.Channel;
|
||||
import org.apache.catalina.tribes.ChannelException;
|
||||
import org.apache.catalina.tribes.ChannelMessage;
|
||||
import org.apache.catalina.tribes.ChannelReceiver;
|
||||
import org.apache.catalina.tribes.ChannelSender;
|
||||
import org.apache.catalina.tribes.Member;
|
||||
import org.apache.catalina.tribes.MembershipService;
|
||||
import org.apache.catalina.tribes.MessageListener;
|
||||
import org.apache.catalina.tribes.UniqueId;
|
||||
import org.apache.catalina.tribes.membership.McastService;
|
||||
import org.apache.catalina.tribes.membership.StaticMember;
|
||||
import org.apache.catalina.tribes.transport.ReplicationTransmitter;
|
||||
import org.apache.catalina.tribes.transport.SenderState;
|
||||
import org.apache.catalina.tribes.transport.nio.NioReceiver;
|
||||
import org.apache.catalina.tribes.util.Arrays;
|
||||
import org.apache.catalina.tribes.util.Logs;
|
||||
import org.apache.catalina.tribes.util.StringManager;
|
||||
|
||||
/**
|
||||
* The channel coordinator object coordinates the membership service,
|
||||
* the sender and the receiver.
|
||||
* This is the last interceptor in the chain.
|
||||
*/
|
||||
public class ChannelCoordinator extends ChannelInterceptorBase implements MessageListener {
|
||||
protected static final StringManager sm = StringManager.getManager(ChannelCoordinator.class);
|
||||
private ChannelReceiver clusterReceiver;
|
||||
private ChannelSender clusterSender;
|
||||
private MembershipService membershipService;
|
||||
|
||||
private int startLevel = 0;
|
||||
|
||||
public ChannelCoordinator() {
|
||||
this(new NioReceiver(), new ReplicationTransmitter(),
|
||||
new McastService());
|
||||
}
|
||||
|
||||
public ChannelCoordinator(ChannelReceiver receiver,
|
||||
ChannelSender sender,
|
||||
MembershipService service) {
|
||||
|
||||
this.optionFlag = Channel.SEND_OPTIONS_BYTE_MESSAGE |
|
||||
Channel.SEND_OPTIONS_USE_ACK |
|
||||
Channel.SEND_OPTIONS_SYNCHRONIZED_ACK;
|
||||
|
||||
this.setClusterReceiver(receiver);
|
||||
this.setClusterSender(sender);
|
||||
this.setMembershipService(service);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a message to one or more members in the cluster
|
||||
* @param destination Member[] - the destinations, null or zero length means all
|
||||
* @param msg ClusterMessage - the message to send
|
||||
* @param payload TBA
|
||||
*/
|
||||
@Override
|
||||
public void sendMessage(Member[] destination, ChannelMessage msg, InterceptorPayload payload)
|
||||
throws ChannelException {
|
||||
if ( destination == null ) destination = membershipService.getMembers();
|
||||
if ((msg.getOptions()&Channel.SEND_OPTIONS_MULTICAST) == Channel.SEND_OPTIONS_MULTICAST) {
|
||||
membershipService.broadcast(msg);
|
||||
} else {
|
||||
clusterSender.sendMessage(msg,destination);
|
||||
}
|
||||
if ( Logs.MESSAGES.isTraceEnabled() ) {
|
||||
Logs.MESSAGES.trace("ChannelCoordinator - Sent msg:" + new UniqueId(msg.getUniqueId()) +
|
||||
" at " + new java.sql.Timestamp(System.currentTimeMillis()) + " to " +
|
||||
Arrays.toNameString(destination));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Starts up the channel. This can be called multiple times for individual services to start
|
||||
* The svc parameter can be the logical or value of any constants
|
||||
* @param svc int value of <BR>
|
||||
* DEFAULT - will start all services <BR>
|
||||
* MBR_RX_SEQ - starts the membership receiver <BR>
|
||||
* MBR_TX_SEQ - starts the membership broadcaster <BR>
|
||||
* SND_TX_SEQ - starts the replication transmitter<BR>
|
||||
* SND_RX_SEQ - starts the replication receiver<BR>
|
||||
* @throws ChannelException if a startup error occurs or the service is already started.
|
||||
*/
|
||||
@Override
|
||||
public void start(int svc) throws ChannelException {
|
||||
this.internalStart(svc);
|
||||
}
|
||||
|
||||
/**
|
||||
* Shuts down the channel. This can be called multiple times for individual services to shutdown
|
||||
* The svc parameter can be the logical or value of any constants
|
||||
* @param svc int value of <BR>
|
||||
* DEFAULT - will shutdown all services <BR>
|
||||
* MBR_RX_SEQ - stops the membership receiver <BR>
|
||||
* MBR_TX_SEQ - stops the membership broadcaster <BR>
|
||||
* SND_TX_SEQ - stops the replication transmitter<BR>
|
||||
* SND_RX_SEQ - stops the replication receiver<BR>
|
||||
* @throws ChannelException if a startup error occurs or the service is already started.
|
||||
*/
|
||||
@Override
|
||||
public void stop(int svc) throws ChannelException {
|
||||
this.internalStop(svc);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Starts up the channel. This can be called multiple times for individual services to start
|
||||
* The svc parameter can be the logical or value of any constants
|
||||
* @param svc int value of <BR>
|
||||
* DEFAULT - will start all services <BR>
|
||||
* MBR_RX_SEQ - starts the membership receiver <BR>
|
||||
* MBR_TX_SEQ - starts the membership broadcaster <BR>
|
||||
* SND_TX_SEQ - starts the replication transmitter<BR>
|
||||
* SND_RX_SEQ - starts the replication receiver<BR>
|
||||
* @throws ChannelException if a startup error occurs or the service is already started.
|
||||
*/
|
||||
protected synchronized void internalStart(int svc) throws ChannelException {
|
||||
try {
|
||||
boolean valid = false;
|
||||
//make sure we don't pass down any flags that are unrelated to the bottom layer
|
||||
svc = svc & Channel.DEFAULT;
|
||||
|
||||
if (startLevel == Channel.DEFAULT) return; //we have already started up all components
|
||||
if (svc == 0 ) return;//nothing to start
|
||||
|
||||
if (svc == (svc & startLevel)) {
|
||||
throw new ChannelException(sm.getString("channelCoordinator.alreadyStarted",
|
||||
Integer.toString(svc)));
|
||||
}
|
||||
|
||||
//must start the receiver first so that we can coordinate the port it
|
||||
//listens to with the local membership settings
|
||||
if ( Channel.SND_RX_SEQ==(svc & Channel.SND_RX_SEQ) ) {
|
||||
clusterReceiver.setMessageListener(this);
|
||||
clusterReceiver.setChannel(getChannel());
|
||||
clusterReceiver.start();
|
||||
//synchronize, big time FIXME
|
||||
Member localMember = getChannel().getLocalMember(false);
|
||||
if (localMember instanceof StaticMember) {
|
||||
// static member
|
||||
StaticMember staticMember = (StaticMember)localMember;
|
||||
staticMember.setHost(getClusterReceiver().getHost());
|
||||
staticMember.setPort(getClusterReceiver().getPort());
|
||||
staticMember.setSecurePort(getClusterReceiver().getSecurePort());
|
||||
} else {
|
||||
// multicast member
|
||||
membershipService.setLocalMemberProperties(getClusterReceiver().getHost(),
|
||||
getClusterReceiver().getPort(),
|
||||
getClusterReceiver().getSecurePort(),
|
||||
getClusterReceiver().getUdpPort());
|
||||
}
|
||||
valid = true;
|
||||
}
|
||||
if ( Channel.SND_TX_SEQ==(svc & Channel.SND_TX_SEQ) ) {
|
||||
clusterSender.setChannel(getChannel());
|
||||
clusterSender.start();
|
||||
valid = true;
|
||||
}
|
||||
|
||||
if ( Channel.MBR_RX_SEQ==(svc & Channel.MBR_RX_SEQ) ) {
|
||||
membershipService.setMembershipListener(this);
|
||||
membershipService.setChannel(getChannel());
|
||||
if (membershipService instanceof McastService) {
|
||||
((McastService)membershipService).setMessageListener(this);
|
||||
}
|
||||
membershipService.start(MembershipService.MBR_RX);
|
||||
valid = true;
|
||||
}
|
||||
if ( Channel.MBR_TX_SEQ==(svc & Channel.MBR_TX_SEQ) ) {
|
||||
membershipService.setChannel(getChannel());
|
||||
membershipService.start(MembershipService.MBR_TX);
|
||||
valid = true;
|
||||
}
|
||||
|
||||
if (!valid) {
|
||||
throw new IllegalArgumentException(sm.getString("channelCoordinator.invalid.startLevel"));
|
||||
}
|
||||
startLevel = (startLevel | svc);
|
||||
}catch ( ChannelException cx ) {
|
||||
throw cx;
|
||||
}catch ( Exception x ) {
|
||||
throw new ChannelException(x);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Shuts down the channel. This can be called multiple times for individual services to shutdown
|
||||
* The svc parameter can be the logical or value of any constants
|
||||
* @param svc int value of <BR>
|
||||
* DEFAULT - will shutdown all services <BR>
|
||||
* MBR_RX_SEQ - starts the membership receiver <BR>
|
||||
* MBR_TX_SEQ - starts the membership broadcaster <BR>
|
||||
* SND_TX_SEQ - starts the replication transmitter<BR>
|
||||
* SND_RX_SEQ - starts the replication receiver<BR>
|
||||
* @throws ChannelException if a startup error occurs or the service is already started.
|
||||
*/
|
||||
protected synchronized void internalStop(int svc) throws ChannelException {
|
||||
try {
|
||||
//make sure we don't pass down any flags that are unrelated to the bottom layer
|
||||
svc = svc & Channel.DEFAULT;
|
||||
|
||||
if (startLevel == 0) return; //we have already stopped up all components
|
||||
if (svc == 0 ) return;//nothing to stop
|
||||
|
||||
boolean valid = false;
|
||||
if ( Channel.SND_RX_SEQ==(svc & Channel.SND_RX_SEQ) ) {
|
||||
clusterReceiver.stop();
|
||||
clusterReceiver.setMessageListener(null);
|
||||
valid = true;
|
||||
}
|
||||
if ( Channel.SND_TX_SEQ==(svc & Channel.SND_TX_SEQ) ) {
|
||||
clusterSender.stop();
|
||||
valid = true;
|
||||
}
|
||||
|
||||
if ( Channel.MBR_RX_SEQ==(svc & Channel.MBR_RX_SEQ) ) {
|
||||
membershipService.stop(MembershipService.MBR_RX);
|
||||
membershipService.setMembershipListener(null);
|
||||
valid = true;
|
||||
|
||||
}
|
||||
if ( Channel.MBR_TX_SEQ==(svc & Channel.MBR_TX_SEQ) ) {
|
||||
valid = true;
|
||||
membershipService.stop(MembershipService.MBR_TX);
|
||||
}
|
||||
if ( !valid) {
|
||||
throw new IllegalArgumentException(sm.getString("channelCoordinator.invalid.startLevel"));
|
||||
}
|
||||
|
||||
startLevel = (startLevel & (~svc));
|
||||
setChannel(null);
|
||||
} catch (Exception x) {
|
||||
throw new ChannelException(x);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void memberAdded(Member member){
|
||||
SenderState.getSenderState(member);
|
||||
super.memberAdded(member);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void memberDisappeared(Member member){
|
||||
SenderState.removeSenderState(member);
|
||||
super.memberDisappeared(member);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void messageReceived(ChannelMessage msg) {
|
||||
if ( Logs.MESSAGES.isTraceEnabled() ) {
|
||||
Logs.MESSAGES.trace("ChannelCoordinator - Received msg:" +
|
||||
new UniqueId(msg.getUniqueId()) + " at " +
|
||||
new java.sql.Timestamp(System.currentTimeMillis()) + " from " +
|
||||
msg.getAddress().getName());
|
||||
}
|
||||
super.messageReceived(msg);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean accept(ChannelMessage msg) {
|
||||
return true;
|
||||
}
|
||||
|
||||
public ChannelReceiver getClusterReceiver() {
|
||||
return clusterReceiver;
|
||||
}
|
||||
|
||||
public ChannelSender getClusterSender() {
|
||||
return clusterSender;
|
||||
}
|
||||
|
||||
public MembershipService getMembershipService() {
|
||||
return membershipService;
|
||||
}
|
||||
|
||||
public void setClusterReceiver(ChannelReceiver clusterReceiver) {
|
||||
if ( clusterReceiver != null ) {
|
||||
this.clusterReceiver = clusterReceiver;
|
||||
this.clusterReceiver.setMessageListener(this);
|
||||
} else {
|
||||
if (this.clusterReceiver!=null ) this.clusterReceiver.setMessageListener(null);
|
||||
this.clusterReceiver = null;
|
||||
}
|
||||
}
|
||||
|
||||
public void setClusterSender(ChannelSender clusterSender) {
|
||||
this.clusterSender = clusterSender;
|
||||
}
|
||||
|
||||
public void setMembershipService(MembershipService membershipService) {
|
||||
this.membershipService = membershipService;
|
||||
this.membershipService.setMembershipListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void heartbeat() {
|
||||
if ( clusterSender!=null ) clusterSender.heartbeat();
|
||||
super.heartbeat();
|
||||
}
|
||||
|
||||
/**
|
||||
* has members
|
||||
*/
|
||||
@Override
|
||||
public boolean hasMembers() {
|
||||
return this.getMembershipService().hasMembers();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all current cluster members
|
||||
* @return all members or empty array
|
||||
*/
|
||||
@Override
|
||||
public Member[] getMembers() {
|
||||
return this.getMembershipService().getMembers();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param mbr Member
|
||||
* @return Member
|
||||
*/
|
||||
@Override
|
||||
public Member getMember(Member mbr){
|
||||
return this.getMembershipService().getMember(mbr);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return the member that represents this node.
|
||||
*
|
||||
* @return Member
|
||||
*/
|
||||
@Override
|
||||
public Member getLocalMember(boolean incAlive) {
|
||||
return this.getMembershipService().getLocalMember(incAlive);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,216 @@
|
||||
/*
|
||||
* 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.catalina.tribes.group;
|
||||
|
||||
import javax.management.ObjectName;
|
||||
|
||||
import org.apache.catalina.tribes.Channel;
|
||||
import org.apache.catalina.tribes.ChannelException;
|
||||
import org.apache.catalina.tribes.ChannelInterceptor;
|
||||
import org.apache.catalina.tribes.ChannelMessage;
|
||||
import org.apache.catalina.tribes.Member;
|
||||
import org.apache.catalina.tribes.jmx.JmxRegistry;
|
||||
|
||||
/**
|
||||
* Abstract class for the interceptor base class.
|
||||
*/
|
||||
public abstract class ChannelInterceptorBase implements ChannelInterceptor {
|
||||
|
||||
private ChannelInterceptor next;
|
||||
private ChannelInterceptor previous;
|
||||
private Channel channel;
|
||||
//default value, always process
|
||||
protected int optionFlag = 0;
|
||||
|
||||
/**
|
||||
* the ObjectName of this ChannelInterceptor.
|
||||
*/
|
||||
private ObjectName oname = null;
|
||||
|
||||
public ChannelInterceptorBase() {
|
||||
|
||||
}
|
||||
|
||||
public boolean okToProcess(int messageFlags) {
|
||||
if (this.optionFlag == 0 ) return true;
|
||||
return ((optionFlag&messageFlags) == optionFlag);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void setNext(ChannelInterceptor next) {
|
||||
this.next = next;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final ChannelInterceptor getNext() {
|
||||
return next;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void setPrevious(ChannelInterceptor previous) {
|
||||
this.previous = previous;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setOptionFlag(int optionFlag) {
|
||||
this.optionFlag = optionFlag;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final ChannelInterceptor getPrevious() {
|
||||
return previous;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOptionFlag() {
|
||||
return optionFlag;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendMessage(Member[] destination, ChannelMessage msg, InterceptorPayload payload) throws
|
||||
ChannelException {
|
||||
if (getNext() != null) getNext().sendMessage(destination, msg, payload);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void messageReceived(ChannelMessage msg) {
|
||||
if (getPrevious() != null) getPrevious().messageReceived(msg);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void memberAdded(Member member) {
|
||||
//notify upwards
|
||||
if (getPrevious() != null) getPrevious().memberAdded(member);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void memberDisappeared(Member member) {
|
||||
//notify upwards
|
||||
if (getPrevious() != null) getPrevious().memberDisappeared(member);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void heartbeat() {
|
||||
if (getNext() != null) getNext().heartbeat();
|
||||
}
|
||||
|
||||
/**
|
||||
* has members
|
||||
*/
|
||||
@Override
|
||||
public boolean hasMembers() {
|
||||
if ( getNext()!=null )return getNext().hasMembers();
|
||||
else return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all current cluster members
|
||||
* @return all members or empty array
|
||||
*/
|
||||
@Override
|
||||
public Member[] getMembers() {
|
||||
if ( getNext()!=null ) return getNext().getMembers();
|
||||
else return null;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param mbr Member
|
||||
* @return Member
|
||||
*/
|
||||
@Override
|
||||
public Member getMember(Member mbr) {
|
||||
if ( getNext()!=null) return getNext().getMember(mbr);
|
||||
else return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the member that represents this node.
|
||||
*
|
||||
* @return Member
|
||||
*/
|
||||
@Override
|
||||
public Member getLocalMember(boolean incAlive) {
|
||||
if ( getNext()!=null ) return getNext().getLocalMember(incAlive);
|
||||
else return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts up the channel. This can be called multiple times for individual services to start
|
||||
* The svc parameter can be the logical or value of any constants
|
||||
* @param svc int value of <BR>
|
||||
* DEFAULT - will start all services <BR>
|
||||
* MBR_RX_SEQ - starts the membership receiver <BR>
|
||||
* MBR_TX_SEQ - starts the membership broadcaster <BR>
|
||||
* SND_TX_SEQ - starts the replication transmitter<BR>
|
||||
* SND_RX_SEQ - starts the replication receiver<BR>
|
||||
* @throws ChannelException if a startup error occurs or the service is already started.
|
||||
*/
|
||||
@Override
|
||||
public void start(int svc) throws ChannelException {
|
||||
if ( getNext()!=null ) getNext().start(svc);
|
||||
// register jmx
|
||||
JmxRegistry jmxRegistry = JmxRegistry.getRegistry(channel);
|
||||
if (jmxRegistry != null) this.oname = jmxRegistry.registerJmx(
|
||||
",component=Interceptor,interceptorName=" + getClass().getSimpleName(), this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Shuts down the channel. This can be called multiple times for individual services to shutdown
|
||||
* The svc parameter can be the logical or value of any constants
|
||||
* @param svc int value of <BR>
|
||||
* DEFAULT - will shutdown all services <BR>
|
||||
* MBR_RX_SEQ - stops the membership receiver <BR>
|
||||
* MBR_TX_SEQ - stops the membership broadcaster <BR>
|
||||
* SND_TX_SEQ - stops the replication transmitter<BR>
|
||||
* SND_RX_SEQ - stops the replication receiver<BR>
|
||||
* @throws ChannelException if a startup error occurs or the service is already started.
|
||||
*/
|
||||
@Override
|
||||
public void stop(int svc) throws ChannelException {
|
||||
if (getNext() != null) getNext().stop(svc);
|
||||
if (oname != null) {
|
||||
JmxRegistry.getRegistry(channel).unregisterJmx(oname);
|
||||
oname = null;
|
||||
}
|
||||
channel = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fireInterceptorEvent(InterceptorEvent event) {
|
||||
//empty operation
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the channel that is related to this interceptor
|
||||
* @return Channel
|
||||
*/
|
||||
@Override
|
||||
public Channel getChannel() {
|
||||
return channel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the channel that is related to this interceptor
|
||||
* @param channel The channel
|
||||
*/
|
||||
@Override
|
||||
public void setChannel(Channel channel) {
|
||||
this.channel = channel;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* 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.catalina.tribes.group;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import org.apache.catalina.tribes.Member;
|
||||
/**
|
||||
* Extension to the {@link RpcCallback} interface. Allows a RPC messenger to get a confirmation if the reply
|
||||
* was sent successfully to the original sender.
|
||||
*
|
||||
*/
|
||||
public interface ExtendedRpcCallback extends RpcCallback {
|
||||
|
||||
/**
|
||||
* The reply failed.
|
||||
* @param request - the original message that requested the reply
|
||||
* @param response - the reply message to the original message
|
||||
* @param sender - the sender requested that reply
|
||||
* @param reason - the reason the reply failed
|
||||
*/
|
||||
public void replyFailed(Serializable request, Serializable response, Member sender, Exception reason);
|
||||
|
||||
/**
|
||||
* The reply succeeded
|
||||
* @param request - the original message that requested the reply
|
||||
* @param response - the reply message to the original message
|
||||
* @param sender - the sender requested that reply
|
||||
*/
|
||||
public void replySucceeded(Serializable request, Serializable response, Member sender);
|
||||
}
|
||||
820
java/org/apache/catalina/tribes/group/GroupChannel.java
Normal file
820
java/org/apache/catalina/tribes/group/GroupChannel.java
Normal file
File diff suppressed because it is too large
Load Diff
62
java/org/apache/catalina/tribes/group/GroupChannelMBean.java
Normal file
62
java/org/apache/catalina/tribes/group/GroupChannelMBean.java
Normal file
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* 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.catalina.tribes.group;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import org.apache.catalina.tribes.ChannelException;
|
||||
import org.apache.catalina.tribes.ChannelListener;
|
||||
import org.apache.catalina.tribes.ErrorHandler;
|
||||
import org.apache.catalina.tribes.Member;
|
||||
import org.apache.catalina.tribes.MembershipListener;
|
||||
import org.apache.catalina.tribes.UniqueId;
|
||||
|
||||
public interface GroupChannelMBean {
|
||||
|
||||
// Attributes
|
||||
public boolean getOptionCheck();
|
||||
|
||||
public boolean getHeartbeat();
|
||||
|
||||
public long getHeartbeatSleeptime();
|
||||
|
||||
// Operations
|
||||
public void start(int svc) throws ChannelException;
|
||||
|
||||
public void stop(int svc) throws ChannelException;
|
||||
|
||||
public UniqueId send(Member[] destination, Serializable msg, int options)
|
||||
throws ChannelException;
|
||||
|
||||
public UniqueId send(Member[] destination, Serializable msg, int options, ErrorHandler handler)
|
||||
throws ChannelException;
|
||||
|
||||
public void addMembershipListener(MembershipListener listener);
|
||||
|
||||
public void addChannelListener(ChannelListener listener);
|
||||
|
||||
public void removeMembershipListener(MembershipListener listener);
|
||||
|
||||
public void removeChannelListener(ChannelListener listener);
|
||||
|
||||
public boolean hasMembers() ;
|
||||
|
||||
public Member[] getMembers() ;
|
||||
|
||||
public Member getLocalMember(boolean incAlive);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* 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.catalina.tribes.group;
|
||||
|
||||
import org.apache.catalina.tribes.ErrorHandler;
|
||||
|
||||
/**
|
||||
* @version 1.0
|
||||
*/
|
||||
public class InterceptorPayload {
|
||||
private ErrorHandler errorHandler;
|
||||
|
||||
public ErrorHandler getErrorHandler() {
|
||||
return errorHandler;
|
||||
}
|
||||
|
||||
public void setErrorHandler(ErrorHandler errorHandler) {
|
||||
this.errorHandler = errorHandler;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
# 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.
|
||||
|
||||
channelCoordinator.alreadyStarted=Channel already started for level:[{0}]
|
||||
channelCoordinator.invalid.startLevel=Invalid start level, valid levels are:SND_RX_SEQ,SND_TX_SEQ,MBR_TX_SEQ,MBR_RX_SEQ
|
||||
|
||||
groupChannel.listener.alreadyExist=Listener already exists:[{0}][{1}]
|
||||
groupChannel.noDestination=No destination given
|
||||
groupChannel.nullMessage=Cannot send a NULL message
|
||||
groupChannel.optionFlag.conflict=Interceptor option flag conflict: [{0}]
|
||||
groupChannel.receiving.error=Error receiving message:
|
||||
groupChannel.sendFail.noRpcChannelReply=Unable to find rpc channel, failed to send NoRpcChannelReply.
|
||||
groupChannel.unable.deserialize=Unable to deserialize message:[{0}]
|
||||
groupChannel.unable.sendHeartbeat=Unable to send heartbeat through Tribes interceptor stack. Will try to sleep again.
|
||||
|
||||
rpcChannel.replyFailed=Unable to send back reply in RpcChannel.
|
||||
@@ -0,0 +1,19 @@
|
||||
# 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.
|
||||
|
||||
channelCoordinator.invalid.startLevel=Nivel de inicion inválido, los niveles válidos son:SND_RX_SEQ,SND_TX_SEQ,MBR_TX_SEQ,MBR_RX_SEQ\n
|
||||
|
||||
groupChannel.listener.alreadyExist=El escuchador ya existe:[{0}][{1}]
|
||||
groupChannel.unable.sendHeartbeat=Imposible enviar heartbeat através del Tribes interceptor stack. Tratré de dormir y esperar nuevamente.\n
|
||||
@@ -0,0 +1,28 @@
|
||||
# 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.
|
||||
|
||||
channelCoordinator.alreadyStarted=Canal déjà démarré pour le niveau: [{0}]
|
||||
channelCoordinator.invalid.startLevel=Niveau de départ invalide, les niveaux valides sont : SND_RX_SEQ,SND_TX_SEQ,MBR_TX_SEQ,MBR_RX_SEQ
|
||||
|
||||
groupChannel.listener.alreadyExist=L''écouteur existe déjà: [{0}][{1}]
|
||||
groupChannel.noDestination=Aucune destination donnée
|
||||
groupChannel.nullMessage=Impossible d'envoyer un message null
|
||||
groupChannel.optionFlag.conflict=Conflit sur le drapeau optionnel d''un intercepteur: [{0}]
|
||||
groupChannel.receiving.error=Erreur lors de la réception du message:
|
||||
groupChannel.sendFail.noRpcChannelReply=Incapable de trouver le canal RPM, échec d'envoi de NoRpcChannelReply
|
||||
groupChannel.unable.deserialize=Impossible de désérialiser le message [{0}]
|
||||
groupChannel.unable.sendHeartbeat=Impossible d'envoyer l’événement périodique dans la pile d'intercepteurs de Tribes
|
||||
|
||||
rpcChannel.replyFailed=Impossible de renvoyer la réponse dans le RpcChannel
|
||||
@@ -0,0 +1,28 @@
|
||||
# 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.
|
||||
|
||||
channelCoordinator.alreadyStarted=チャンネルは既にレベル:[{0}]で開始されました。
|
||||
channelCoordinator.invalid.startLevel=不正な開始レベルです。正常なレベルは SND_RX_SEQ や SND_TX_SEQ、MBR_TX_SEQ や MBR_RX_SEQ です。
|
||||
|
||||
groupChannel.listener.alreadyExist=チャンネルリスナー [{0}][{1}] はすでに存在します。
|
||||
groupChannel.noDestination=宛先が指定されていません。
|
||||
groupChannel.nullMessage=Null メッセージを送信することが出来ません。
|
||||
groupChannel.optionFlag.conflict=Interceptor のoption フラグが衝突しています: [{0}]
|
||||
groupChannel.receiving.error=エラー受信メッセージ:
|
||||
groupChannel.sendFail.noRpcChannelReply=RPC チャンネルが見つからないため NoRpcChannelReply を送信できません。
|
||||
groupChannel.unable.deserialize=メッセージをデシリアライズできません: [{0}]
|
||||
groupChannel.unable.sendHeartbeat=Tribesインターセプタスタックを介してハートビートを送信できません。 もう一sleep します。
|
||||
|
||||
rpcChannel.replyFailed=RpcChannel へ返信を送信できません。
|
||||
@@ -0,0 +1,28 @@
|
||||
# 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.
|
||||
|
||||
channelCoordinator.alreadyStarted=채널이 이미 레벨 [{0}](으)로 시작되었습니다.
|
||||
channelCoordinator.invalid.startLevel=유요하지 않은 시작 레벨입니다. 유효한 레벨은 SND_RX_SEQ, SND_TX_SEQ, MBR_TX_SEQ, MBR_RX_SEQ입니다.
|
||||
|
||||
groupChannel.listener.alreadyExist=리스너가 이미 존재합니다: [{0}][{1}]
|
||||
groupChannel.noDestination=그룹 채널에서 전송 대상 멤버가 없습니다.
|
||||
groupChannel.nullMessage=널 메시지를 전송할 수 없습니다.
|
||||
groupChannel.optionFlag.conflict=인터셉터 옵션 플래그가 충돌합니다: [{0}]
|
||||
groupChannel.receiving.error=메시지 수신 중 오류 발생
|
||||
groupChannel.sendFail.noRpcChannelReply=RPC 채널을 찾을 수 없습니다. NoRpcChannelReply을 보내지 못했습니다.
|
||||
groupChannel.unable.deserialize=메시지를 역직렬화할 수 없습니다:[{0}]
|
||||
groupChannel.unable.sendHeartbeat=Tribes 인터셉터 스택을 통해 heartbeat를 보낼 수 없습니다. 다시 sleep을 시도할 것입니다.
|
||||
|
||||
rpcChannel.replyFailed=RpcChannel에서 응답을 되돌려 보낼 수 없습니다.
|
||||
@@ -0,0 +1,24 @@
|
||||
# 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.
|
||||
|
||||
channelCoordinator.alreadyStarted=通道已经启动,级别:[{0}]
|
||||
channelCoordinator.invalid.startLevel=启动级别无效,有效级别为:SND_RX_SEQ,SND_TX_SEQ,MBR_TX_SEQ,MBR_RX_SEQ
|
||||
|
||||
groupChannel.listener.alreadyExist=侦听器已存在:[{0}][{1}]
|
||||
groupChannel.noDestination=没有指定目的地
|
||||
groupChannel.nullMessage=无法发送空消息
|
||||
groupChannel.optionFlag.conflict=拦截器选项标志冲突:[{0}]
|
||||
groupChannel.unable.deserialize=无法反序列化消息:[{0}]
|
||||
groupChannel.unable.sendHeartbeat=无法通过Tribes拦截器堆栈发送心跳。 会再试一次。
|
||||
53
java/org/apache/catalina/tribes/group/Response.java
Normal file
53
java/org/apache/catalina/tribes/group/Response.java
Normal file
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* 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.catalina.tribes.group;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import org.apache.catalina.tribes.Member;
|
||||
|
||||
/**
|
||||
* A response object holds a message from a responding partner.
|
||||
* @version 1.0
|
||||
*/
|
||||
public class Response {
|
||||
private Member source;
|
||||
private Serializable message;
|
||||
public Response() {
|
||||
}
|
||||
|
||||
public Response(Member source, Serializable message) {
|
||||
this.source = source;
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
public void setSource(Member source) {
|
||||
this.source = source;
|
||||
}
|
||||
|
||||
public void setMessage(Serializable message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
public Member getSource() {
|
||||
return source;
|
||||
}
|
||||
|
||||
public Serializable getMessage() {
|
||||
return message;
|
||||
}
|
||||
}
|
||||
46
java/org/apache/catalina/tribes/group/RpcCallback.java
Normal file
46
java/org/apache/catalina/tribes/group/RpcCallback.java
Normal file
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* 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.catalina.tribes.group;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import org.apache.catalina.tribes.Member;
|
||||
|
||||
/**
|
||||
* The RpcCallback interface is an interface for the Tribes channel to request a
|
||||
* response object to a request that came in.
|
||||
* @version 1.0
|
||||
*/
|
||||
public interface RpcCallback {
|
||||
|
||||
/**
|
||||
* Allows sending a response to a received message.
|
||||
* @param msg The message
|
||||
* @param sender Member
|
||||
* @return Serializable object, <code>null</code> if no reply should be sent
|
||||
*/
|
||||
public Serializable replyRequest(Serializable msg, Member sender);
|
||||
|
||||
/**
|
||||
* If the reply has already been sent to the requesting thread,
|
||||
* the rpc callback can handle any data that comes in after the fact.
|
||||
* @param msg The message
|
||||
* @param sender Member
|
||||
*/
|
||||
public void leftOver(Serializable msg, Member sender);
|
||||
|
||||
}
|
||||
301
java/org/apache/catalina/tribes/group/RpcChannel.java
Normal file
301
java/org/apache/catalina/tribes/group/RpcChannel.java
Normal file
@@ -0,0 +1,301 @@
|
||||
/*
|
||||
* 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.catalina.tribes.group;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
|
||||
import org.apache.catalina.tribes.Channel;
|
||||
import org.apache.catalina.tribes.ChannelException;
|
||||
import org.apache.catalina.tribes.ChannelListener;
|
||||
import org.apache.catalina.tribes.ErrorHandler;
|
||||
import org.apache.catalina.tribes.Member;
|
||||
import org.apache.catalina.tribes.UniqueId;
|
||||
import org.apache.catalina.tribes.util.StringManager;
|
||||
import org.apache.catalina.tribes.util.UUIDGenerator;
|
||||
import org.apache.juli.logging.Log;
|
||||
import org.apache.juli.logging.LogFactory;
|
||||
|
||||
/**
|
||||
* A channel to handle RPC messaging
|
||||
*/
|
||||
public class RpcChannel implements ChannelListener {
|
||||
private static final Log log = LogFactory.getLog(RpcChannel.class);
|
||||
protected static final StringManager sm = StringManager.getManager(RpcChannel.class);
|
||||
|
||||
public static final int FIRST_REPLY = 1;
|
||||
public static final int MAJORITY_REPLY = 2;
|
||||
public static final int ALL_REPLY = 3;
|
||||
public static final int NO_REPLY = 4;
|
||||
|
||||
private Channel channel;
|
||||
private RpcCallback callback;
|
||||
private byte[] rpcId;
|
||||
private int replyMessageOptions = 0;
|
||||
|
||||
private final ConcurrentMap<RpcCollectorKey, RpcCollector> responseMap = new ConcurrentHashMap<>();
|
||||
|
||||
/**
|
||||
* Create an RPC channel. You can have several RPC channels attached to a group
|
||||
* all separated out by the uniqueness
|
||||
* @param rpcId - the unique Id for this RPC group
|
||||
* @param channel Channel
|
||||
* @param callback RpcCallback
|
||||
*/
|
||||
public RpcChannel(byte[] rpcId, Channel channel, RpcCallback callback) {
|
||||
this.channel = channel;
|
||||
this.callback = callback;
|
||||
this.rpcId = rpcId;
|
||||
channel.addChannelListener(this);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Send a message and wait for the response.
|
||||
* @param destination Member[] - the destination for the message, and the members you request a reply from
|
||||
* @param message Serializable - the message you are sending out
|
||||
* @param rpcOptions int - FIRST_REPLY, MAJORITY_REPLY or ALL_REPLY
|
||||
* @param channelOptions channel sender options
|
||||
* @param timeout long - timeout in milliseconds, if no reply is received within this time null is returned
|
||||
* @return Response[] - an array of response objects.
|
||||
* @throws ChannelException Error sending message
|
||||
*/
|
||||
public Response[] send(Member[] destination,
|
||||
Serializable message,
|
||||
int rpcOptions,
|
||||
int channelOptions,
|
||||
long timeout) throws ChannelException {
|
||||
|
||||
if ( destination==null || destination.length == 0 ) return new Response[0];
|
||||
|
||||
//avoid dead lock
|
||||
int sendOptions =
|
||||
channelOptions & ~Channel.SEND_OPTIONS_SYNCHRONIZED_ACK;
|
||||
|
||||
RpcCollectorKey key = new RpcCollectorKey(UUIDGenerator.randomUUID(false));
|
||||
RpcCollector collector = new RpcCollector(key,rpcOptions,destination.length);
|
||||
try {
|
||||
synchronized (collector) {
|
||||
if ( rpcOptions != NO_REPLY ) responseMap.put(key, collector);
|
||||
RpcMessage rmsg = new RpcMessage(rpcId, key.id, message);
|
||||
channel.send(destination, rmsg, sendOptions);
|
||||
if ( rpcOptions != NO_REPLY ) collector.wait(timeout);
|
||||
}
|
||||
} catch ( InterruptedException ix ) {
|
||||
Thread.currentThread().interrupt();
|
||||
} finally {
|
||||
responseMap.remove(key);
|
||||
}
|
||||
return collector.getResponses();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void messageReceived(Serializable msg, Member sender) {
|
||||
RpcMessage rmsg = (RpcMessage)msg;
|
||||
RpcCollectorKey key = new RpcCollectorKey(rmsg.uuid);
|
||||
if ( rmsg.reply ) {
|
||||
RpcCollector collector = responseMap.get(key);
|
||||
if (collector == null) {
|
||||
if (!(rmsg instanceof RpcMessage.NoRpcChannelReply))
|
||||
callback.leftOver(rmsg.message, sender);
|
||||
} else {
|
||||
synchronized (collector) {
|
||||
//make sure it hasn't been removed
|
||||
if ( responseMap.containsKey(key) ) {
|
||||
if ( (rmsg instanceof RpcMessage.NoRpcChannelReply) )
|
||||
collector.destcnt--;
|
||||
else
|
||||
collector.addResponse(rmsg.message, sender);
|
||||
if (collector.isComplete()) collector.notifyAll();
|
||||
} else {
|
||||
if (! (rmsg instanceof RpcMessage.NoRpcChannelReply) )
|
||||
callback.leftOver(rmsg.message, sender);
|
||||
}
|
||||
}//synchronized
|
||||
}//end if
|
||||
} else {
|
||||
boolean finished = false;
|
||||
final ExtendedRpcCallback excallback = (callback instanceof ExtendedRpcCallback)?((ExtendedRpcCallback)callback) : null;
|
||||
boolean asyncReply = ((replyMessageOptions & Channel.SEND_OPTIONS_ASYNCHRONOUS) == Channel.SEND_OPTIONS_ASYNCHRONOUS);
|
||||
Serializable reply = callback.replyRequest(rmsg.message,sender);
|
||||
ErrorHandler handler = null;
|
||||
final Serializable request = msg;
|
||||
final Serializable response = reply;
|
||||
final Member fsender = sender;
|
||||
if (excallback!=null && asyncReply) {
|
||||
handler = new ErrorHandler() {
|
||||
@Override
|
||||
public void handleError(ChannelException x, UniqueId id) {
|
||||
excallback.replyFailed(request, response, fsender, x);
|
||||
}
|
||||
@Override
|
||||
public void handleCompletion(UniqueId id) {
|
||||
excallback.replySucceeded(request, response, fsender);
|
||||
}
|
||||
};
|
||||
}
|
||||
rmsg.reply = true;
|
||||
rmsg.message = reply;
|
||||
try {
|
||||
if (handler!=null) {
|
||||
channel.send(new Member[] {sender}, rmsg,replyMessageOptions & ~Channel.SEND_OPTIONS_SYNCHRONIZED_ACK, handler);
|
||||
} else {
|
||||
channel.send(new Member[] {sender}, rmsg,replyMessageOptions & ~Channel.SEND_OPTIONS_SYNCHRONIZED_ACK);
|
||||
}
|
||||
finished = true;
|
||||
} catch ( Exception x ) {
|
||||
if (excallback != null && !asyncReply) {
|
||||
excallback.replyFailed(rmsg.message, reply, sender, x);
|
||||
} else {
|
||||
log.error(sm.getString("rpcChannel.replyFailed"),x);
|
||||
}
|
||||
}
|
||||
if (finished && excallback != null && !asyncReply) {
|
||||
excallback.replySucceeded(rmsg.message, reply, sender);
|
||||
}
|
||||
}//end if
|
||||
}
|
||||
|
||||
public void breakdown() {
|
||||
channel.removeChannelListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void finalize() throws Throwable {
|
||||
breakdown();
|
||||
super.finalize();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean accept(Serializable msg, Member sender) {
|
||||
if ( msg instanceof RpcMessage ) {
|
||||
RpcMessage rmsg = (RpcMessage)msg;
|
||||
return Arrays.equals(rmsg.rpcId,rpcId);
|
||||
} else return false;
|
||||
}
|
||||
|
||||
public Channel getChannel() {
|
||||
return channel;
|
||||
}
|
||||
|
||||
public RpcCallback getCallback() {
|
||||
return callback;
|
||||
}
|
||||
|
||||
public byte[] getRpcId() {
|
||||
return rpcId;
|
||||
}
|
||||
|
||||
public void setChannel(Channel channel) {
|
||||
this.channel = channel;
|
||||
}
|
||||
|
||||
public void setCallback(RpcCallback callback) {
|
||||
this.callback = callback;
|
||||
}
|
||||
|
||||
public void setRpcId(byte[] rpcId) {
|
||||
this.rpcId = rpcId;
|
||||
}
|
||||
|
||||
public int getReplyMessageOptions() {
|
||||
return replyMessageOptions;
|
||||
}
|
||||
|
||||
public void setReplyMessageOptions(int replyMessageOptions) {
|
||||
this.replyMessageOptions = replyMessageOptions;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Class that holds all response.
|
||||
* @version 1.0
|
||||
*/
|
||||
public static class RpcCollector {
|
||||
public final ArrayList<Response> responses = new ArrayList<>();
|
||||
public final RpcCollectorKey key;
|
||||
public final int options;
|
||||
public int destcnt;
|
||||
|
||||
public RpcCollector(RpcCollectorKey key, int options, int destcnt) {
|
||||
this.key = key;
|
||||
this.options = options;
|
||||
this.destcnt = destcnt;
|
||||
}
|
||||
|
||||
public void addResponse(Serializable message, Member sender) {
|
||||
Response resp = new Response(sender,message);
|
||||
responses.add(resp);
|
||||
}
|
||||
|
||||
public boolean isComplete() {
|
||||
if ( destcnt <= 0 ) return true;
|
||||
switch (options) {
|
||||
case ALL_REPLY:
|
||||
return destcnt == responses.size();
|
||||
case MAJORITY_REPLY:
|
||||
float perc = ((float)responses.size()) / ((float)destcnt);
|
||||
return perc >= 0.50f;
|
||||
case FIRST_REPLY:
|
||||
return responses.size()>0;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return key.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if ( o instanceof RpcCollector ) {
|
||||
RpcCollector r = (RpcCollector)o;
|
||||
return r.key.equals(this.key);
|
||||
} else return false;
|
||||
}
|
||||
|
||||
public Response[] getResponses() {
|
||||
return responses.toArray(new Response[responses.size()]);
|
||||
}
|
||||
}
|
||||
|
||||
public static class RpcCollectorKey {
|
||||
final byte[] id;
|
||||
public RpcCollectorKey(byte[] id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return id[0]+id[1]+id[2]+id[3];
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if ( o instanceof RpcCollectorKey ) {
|
||||
RpcCollectorKey r = (RpcCollectorKey)o;
|
||||
return Arrays.equals(id,r.id);
|
||||
} else return false;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
111
java/org/apache/catalina/tribes/group/RpcMessage.java
Normal file
111
java/org/apache/catalina/tribes/group/RpcMessage.java
Normal file
@@ -0,0 +1,111 @@
|
||||
/*
|
||||
* 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.catalina.tribes.group;
|
||||
|
||||
import java.io.Externalizable;
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInput;
|
||||
import java.io.ObjectOutput;
|
||||
import java.io.Serializable;
|
||||
|
||||
import org.apache.catalina.tribes.util.Arrays;
|
||||
|
||||
public class RpcMessage implements Externalizable {
|
||||
|
||||
protected Serializable message;
|
||||
protected byte[] uuid;
|
||||
protected byte[] rpcId;
|
||||
protected boolean reply = false;
|
||||
|
||||
public RpcMessage() {
|
||||
//for serialization
|
||||
}
|
||||
|
||||
public RpcMessage(byte[] rpcId, byte[] uuid, Serializable message) {
|
||||
this.rpcId = rpcId;
|
||||
this.uuid = uuid;
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readExternal(ObjectInput in) throws IOException,ClassNotFoundException {
|
||||
reply = in.readBoolean();
|
||||
int length = in.readInt();
|
||||
uuid = new byte[length];
|
||||
in.readFully(uuid);
|
||||
length = in.readInt();
|
||||
rpcId = new byte[length];
|
||||
in.readFully(rpcId);
|
||||
message = (Serializable)in.readObject();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeExternal(ObjectOutput out) throws IOException {
|
||||
out.writeBoolean(reply);
|
||||
out.writeInt(uuid.length);
|
||||
out.write(uuid, 0, uuid.length);
|
||||
out.writeInt(rpcId.length);
|
||||
out.write(rpcId, 0, rpcId.length);
|
||||
out.writeObject(message);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder buf = new StringBuilder("RpcMessage[");
|
||||
buf.append(super.toString());
|
||||
buf.append("] rpcId=");
|
||||
buf.append(Arrays.toString(rpcId));
|
||||
buf.append("; uuid=");
|
||||
buf.append(Arrays.toString(uuid));
|
||||
buf.append("; msg=");
|
||||
buf.append(message);
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
public static class NoRpcChannelReply extends RpcMessage {
|
||||
public NoRpcChannelReply() {
|
||||
|
||||
}
|
||||
|
||||
public NoRpcChannelReply(byte[] rpcid, byte[] uuid) {
|
||||
super(rpcid,uuid,null);
|
||||
reply = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
|
||||
reply = true;
|
||||
int length = in.readInt();
|
||||
uuid = new byte[length];
|
||||
in.readFully(uuid);
|
||||
length = in.readInt();
|
||||
rpcId = new byte[length];
|
||||
in.readFully(rpcId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeExternal(ObjectOutput out) throws IOException {
|
||||
out.writeInt(uuid.length);
|
||||
out.write(uuid, 0, uuid.length);
|
||||
out.writeInt(rpcId.length);
|
||||
out.write(rpcId, 0, rpcId.length);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,147 @@
|
||||
/*
|
||||
* 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.catalina.tribes.group.interceptors;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import org.apache.catalina.tribes.ChannelMessage;
|
||||
import org.apache.catalina.tribes.Member;
|
||||
import org.apache.catalina.tribes.group.ChannelInterceptorBase;
|
||||
import org.apache.catalina.tribes.membership.Membership;
|
||||
import org.apache.catalina.tribes.util.StringManager;
|
||||
import org.apache.juli.logging.Log;
|
||||
import org.apache.juli.logging.LogFactory;
|
||||
|
||||
/**
|
||||
* <p>Title: Member domain filter interceptor </p>
|
||||
*
|
||||
* <p>Description: Filters membership based on domain.
|
||||
* </p>
|
||||
*
|
||||
* @version 1.0
|
||||
*/
|
||||
public class DomainFilterInterceptor extends ChannelInterceptorBase
|
||||
implements DomainFilterInterceptorMBean {
|
||||
|
||||
private static final Log log = LogFactory.getLog(DomainFilterInterceptor.class);
|
||||
protected static final StringManager sm = StringManager.getManager(DomainFilterInterceptor.class);
|
||||
protected volatile Membership membership = null;
|
||||
|
||||
protected byte[] domain = new byte[0];
|
||||
protected int logInterval = 100;
|
||||
private final AtomicInteger logCounter = new AtomicInteger(logInterval);
|
||||
|
||||
@Override
|
||||
public void messageReceived(ChannelMessage msg) {
|
||||
if (Arrays.equals(domain, msg.getAddress().getDomain())) {
|
||||
super.messageReceived(msg);
|
||||
} else {
|
||||
if (logCounter.incrementAndGet() >= logInterval) {
|
||||
logCounter.set(0);
|
||||
if (log.isWarnEnabled())
|
||||
log.warn(sm.getString("domainFilterInterceptor.message.refused", msg.getAddress()));
|
||||
}
|
||||
}
|
||||
}//messageReceived
|
||||
|
||||
|
||||
@Override
|
||||
public void memberAdded(Member member) {
|
||||
if ( membership == null ) setupMembership();
|
||||
boolean notify = false;
|
||||
synchronized (membership) {
|
||||
notify = Arrays.equals(domain,member.getDomain());
|
||||
if ( notify ) notify = membership.memberAlive(member);
|
||||
}
|
||||
if ( notify ) {
|
||||
super.memberAdded(member);
|
||||
} else {
|
||||
if(log.isInfoEnabled()) log.info(sm.getString("domainFilterInterceptor.member.refused", member));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void memberDisappeared(Member member) {
|
||||
if ( membership == null ) setupMembership();
|
||||
boolean notify = false;
|
||||
synchronized (membership) {
|
||||
notify = Arrays.equals(domain,member.getDomain());
|
||||
if ( notify ) membership.removeMember(member);
|
||||
}
|
||||
if ( notify ) super.memberDisappeared(member);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasMembers() {
|
||||
if ( membership == null ) setupMembership();
|
||||
return membership.hasMembers();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Member[] getMembers() {
|
||||
if ( membership == null ) setupMembership();
|
||||
return membership.getMembers();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Member getMember(Member mbr) {
|
||||
if ( membership == null ) setupMembership();
|
||||
return membership.getMember(mbr);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Member getLocalMember(boolean incAlive) {
|
||||
return super.getLocalMember(incAlive);
|
||||
}
|
||||
|
||||
|
||||
protected synchronized void setupMembership() {
|
||||
if ( membership == null ) {
|
||||
membership = new Membership(super.getLocalMember(true));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] getDomain() {
|
||||
return domain;
|
||||
}
|
||||
|
||||
public void setDomain(byte[] domain) {
|
||||
this.domain = domain;
|
||||
}
|
||||
|
||||
public void setDomain(String domain) {
|
||||
if ( domain == null ) return;
|
||||
if (domain.startsWith("{"))
|
||||
setDomain(org.apache.catalina.tribes.util.Arrays.fromString(domain));
|
||||
else
|
||||
setDomain(org.apache.catalina.tribes.util.Arrays.convert(domain));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLogInterval() {
|
||||
return logInterval;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLogInterval(int logInterval) {
|
||||
this.logInterval = logInterval;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* 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.catalina.tribes.group.interceptors;
|
||||
|
||||
public interface DomainFilterInterceptorMBean {
|
||||
|
||||
public int getOptionFlag();
|
||||
|
||||
public byte[] getDomain();
|
||||
|
||||
public int getLogInterval();
|
||||
|
||||
public void setLogInterval(int logInterval);
|
||||
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* 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.catalina.tribes.group.interceptors;
|
||||
|
||||
public interface EncryptInterceptorMBean {
|
||||
|
||||
// Config
|
||||
public int getOptionFlag();
|
||||
public void setOptionFlag(int optionFlag);
|
||||
|
||||
public void setEncryptionAlgorithm(String algorithm);
|
||||
public String getEncryptionAlgorithm();
|
||||
public void setEncryptionKey(byte[] key);
|
||||
public byte[] getEncryptionKey();
|
||||
public void setProviderName(String provider);
|
||||
public String getProviderName();
|
||||
}
|
||||
@@ -0,0 +1,250 @@
|
||||
/*
|
||||
* 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.catalina.tribes.group.interceptors;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.catalina.tribes.ChannelException;
|
||||
import org.apache.catalina.tribes.ChannelMessage;
|
||||
import org.apache.catalina.tribes.Member;
|
||||
import org.apache.catalina.tribes.group.ChannelInterceptorBase;
|
||||
import org.apache.catalina.tribes.group.InterceptorPayload;
|
||||
import org.apache.catalina.tribes.io.XByteBuffer;
|
||||
import org.apache.catalina.tribes.util.StringManager;
|
||||
import org.apache.juli.logging.Log;
|
||||
import org.apache.juli.logging.LogFactory;
|
||||
|
||||
/**
|
||||
*
|
||||
* The fragmentation interceptor splits up large messages into smaller messages and assembles them on the other end.
|
||||
* This is very useful when you don't want large messages hogging the sending sockets
|
||||
* and smaller messages can make it through.
|
||||
*
|
||||
* <br><b>Configuration Options</b><br>
|
||||
* FragmentationInterceptor.expire=<milliseconds> - how long do we keep the fragments in memory and wait for the rest to arrive <b>default=60,000ms -> 60seconds</b>
|
||||
* This setting is useful to avoid OutOfMemoryErrors<br>
|
||||
* FragmentationInterceptor.maxSize=<max message size> - message size in bytes <b>default=1024*100 (around a tenth of a MB)</b><br>
|
||||
* @version 1.0
|
||||
*/
|
||||
public class FragmentationInterceptor extends ChannelInterceptorBase implements FragmentationInterceptorMBean {
|
||||
private static final Log log = LogFactory.getLog(FragmentationInterceptor.class);
|
||||
protected static final StringManager sm = StringManager.getManager(FragmentationInterceptor.class);
|
||||
|
||||
protected final HashMap<FragKey, FragCollection> fragpieces = new HashMap<>();
|
||||
private int maxSize = 1024*100;
|
||||
private long expire = 1000 * 60; //one minute expiration
|
||||
protected final boolean deepclone = true;
|
||||
|
||||
|
||||
@Override
|
||||
public void sendMessage(Member[] destination, ChannelMessage msg, InterceptorPayload payload) throws ChannelException {
|
||||
int size = msg.getMessage().getLength();
|
||||
boolean frag = (size>maxSize) && okToProcess(msg.getOptions());
|
||||
if ( frag ) {
|
||||
frag(destination, msg, payload);
|
||||
} else {
|
||||
msg.getMessage().append(frag);
|
||||
super.sendMessage(destination, msg, payload);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void messageReceived(ChannelMessage msg) {
|
||||
boolean isFrag = XByteBuffer.toBoolean(msg.getMessage().getBytesDirect(),msg.getMessage().getLength()-1);
|
||||
msg.getMessage().trim(1);
|
||||
if ( isFrag ) {
|
||||
defrag(msg);
|
||||
} else {
|
||||
super.messageReceived(msg);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public FragCollection getFragCollection(FragKey key, ChannelMessage msg) {
|
||||
FragCollection coll = fragpieces.get(key);
|
||||
if ( coll == null ) {
|
||||
synchronized (fragpieces) {
|
||||
coll = fragpieces.get(key);
|
||||
if ( coll == null ) {
|
||||
coll = new FragCollection(msg);
|
||||
fragpieces.put(key, coll);
|
||||
}
|
||||
}
|
||||
}
|
||||
return coll;
|
||||
}
|
||||
|
||||
public void removeFragCollection(FragKey key) {
|
||||
fragpieces.remove(key);
|
||||
}
|
||||
|
||||
public void defrag(ChannelMessage msg ) {
|
||||
FragKey key = new FragKey(msg.getUniqueId());
|
||||
FragCollection coll = getFragCollection(key,msg);
|
||||
coll.addMessage((ChannelMessage)msg.deepclone());
|
||||
|
||||
if ( coll.complete() ) {
|
||||
removeFragCollection(key);
|
||||
ChannelMessage complete = coll.assemble();
|
||||
super.messageReceived(complete);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public void frag(Member[] destination, ChannelMessage msg, InterceptorPayload payload) throws ChannelException {
|
||||
int size = msg.getMessage().getLength();
|
||||
|
||||
int count = ((size / maxSize )+(size%maxSize==0?0:1));
|
||||
ChannelMessage[] messages = new ChannelMessage[count];
|
||||
int remaining = size;
|
||||
for ( int i=0; i<count; i++ ) {
|
||||
ChannelMessage tmp = (ChannelMessage)msg.clone();
|
||||
int offset = (i*maxSize);
|
||||
int length = Math.min(remaining,maxSize);
|
||||
tmp.getMessage().clear();
|
||||
tmp.getMessage().append(msg.getMessage().getBytesDirect(),offset,length);
|
||||
//add the msg nr
|
||||
//tmp.getMessage().append(XByteBuffer.toBytes(i),0,4);
|
||||
tmp.getMessage().append(i);
|
||||
//add the total nr of messages
|
||||
//tmp.getMessage().append(XByteBuffer.toBytes(count),0,4);
|
||||
tmp.getMessage().append(count);
|
||||
//add true as the frag flag
|
||||
//byte[] flag = XByteBuffer.toBytes(true);
|
||||
//tmp.getMessage().append(flag,0,flag.length);
|
||||
tmp.getMessage().append(true);
|
||||
messages[i] = tmp;
|
||||
remaining -= length;
|
||||
|
||||
}
|
||||
for ( int i=0; i<messages.length; i++ ) {
|
||||
super.sendMessage(destination,messages[i],payload);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void heartbeat() {
|
||||
try {
|
||||
Set<FragKey> set = fragpieces.keySet();
|
||||
Object[] keys = set.toArray();
|
||||
for ( int i=0; i<keys.length; i++ ) {
|
||||
FragKey key = (FragKey)keys[i];
|
||||
if ( key != null && key.expired(getExpire()) )
|
||||
removeFragCollection(key);
|
||||
}
|
||||
}catch ( Exception x ) {
|
||||
if ( log.isErrorEnabled() ) {
|
||||
log.error(sm.getString("fragmentationInterceptor.heartbeat.failed"),x);
|
||||
}
|
||||
}
|
||||
super.heartbeat();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxSize() {
|
||||
return maxSize;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getExpire() {
|
||||
return expire;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMaxSize(int maxSize) {
|
||||
this.maxSize = maxSize;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setExpire(long expire) {
|
||||
this.expire = expire;
|
||||
}
|
||||
|
||||
public static class FragCollection {
|
||||
private final long received = System.currentTimeMillis();
|
||||
private final ChannelMessage msg;
|
||||
private final XByteBuffer[] frags;
|
||||
public FragCollection(ChannelMessage msg) {
|
||||
//get the total messages
|
||||
int count = XByteBuffer.toInt(msg.getMessage().getBytesDirect(),msg.getMessage().getLength()-4);
|
||||
frags = new XByteBuffer[count];
|
||||
this.msg = msg;
|
||||
}
|
||||
|
||||
public void addMessage(ChannelMessage msg) {
|
||||
//remove the total messages
|
||||
msg.getMessage().trim(4);
|
||||
//get the msg nr
|
||||
int nr = XByteBuffer.toInt(msg.getMessage().getBytesDirect(),msg.getMessage().getLength()-4);
|
||||
//remove the msg nr
|
||||
msg.getMessage().trim(4);
|
||||
frags[nr] = msg.getMessage();
|
||||
|
||||
}
|
||||
|
||||
public boolean complete() {
|
||||
boolean result = true;
|
||||
for ( int i=0; (i<frags.length) && (result); i++ ) result = (frags[i] != null);
|
||||
return result;
|
||||
}
|
||||
|
||||
public ChannelMessage assemble() {
|
||||
if ( !complete() ) throw new IllegalStateException(sm.getString("fragmentationInterceptor.fragments.missing"));
|
||||
int buffersize = 0;
|
||||
for (int i=0; i<frags.length; i++ ) buffersize += frags[i].getLength();
|
||||
XByteBuffer buf = new XByteBuffer(buffersize,false);
|
||||
msg.setMessage(buf);
|
||||
for ( int i=0; i<frags.length; i++ ) {
|
||||
msg.getMessage().append(frags[i].getBytesDirect(),0,frags[i].getLength());
|
||||
}
|
||||
return msg;
|
||||
}
|
||||
|
||||
public boolean expired(long expire) {
|
||||
return (System.currentTimeMillis()-received)>expire;
|
||||
}
|
||||
}
|
||||
|
||||
public static class FragKey {
|
||||
private final byte[] uniqueId;
|
||||
private final long received = System.currentTimeMillis();
|
||||
public FragKey(byte[] id ) {
|
||||
this.uniqueId = id;
|
||||
}
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return XByteBuffer.toInt(uniqueId,0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o ) {
|
||||
if ( o instanceof FragKey ) {
|
||||
return Arrays.equals(uniqueId,((FragKey)o).uniqueId);
|
||||
} else return false;
|
||||
|
||||
}
|
||||
|
||||
public boolean expired(long expire) {
|
||||
return (System.currentTimeMillis()-received)>expire;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* 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.catalina.tribes.group.interceptors;
|
||||
|
||||
public interface FragmentationInterceptorMBean {
|
||||
|
||||
// Attributes
|
||||
public int getMaxSize();
|
||||
|
||||
public long getExpire();
|
||||
|
||||
public void setMaxSize(int maxSize);
|
||||
|
||||
public void setExpire(long expire);
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
/*
|
||||
* 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.catalina.tribes.group.interceptors;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.zip.GZIPInputStream;
|
||||
import java.util.zip.GZIPOutputStream;
|
||||
|
||||
import org.apache.catalina.tribes.ChannelException;
|
||||
import org.apache.catalina.tribes.ChannelMessage;
|
||||
import org.apache.catalina.tribes.Member;
|
||||
import org.apache.catalina.tribes.group.ChannelInterceptorBase;
|
||||
import org.apache.catalina.tribes.group.InterceptorPayload;
|
||||
import org.apache.catalina.tribes.util.StringManager;
|
||||
import org.apache.juli.logging.Log;
|
||||
import org.apache.juli.logging.LogFactory;
|
||||
|
||||
|
||||
/**
|
||||
* @version 1.0
|
||||
*/
|
||||
public class GzipInterceptor extends ChannelInterceptorBase {
|
||||
|
||||
private static final Log log = LogFactory.getLog(GzipInterceptor.class);
|
||||
protected static final StringManager sm = StringManager.getManager(GzipInterceptor.class);
|
||||
|
||||
public static final int DEFAULT_BUFFER_SIZE = 2048;
|
||||
|
||||
@Override
|
||||
public void sendMessage(Member[] destination, ChannelMessage msg, InterceptorPayload payload) throws ChannelException {
|
||||
try {
|
||||
byte[] data = compress(msg.getMessage().getBytes());
|
||||
msg.getMessage().trim(msg.getMessage().getLength());
|
||||
msg.getMessage().append(data,0,data.length);
|
||||
super.sendMessage(destination, msg, payload);
|
||||
} catch ( IOException x ) {
|
||||
log.error(sm.getString("gzipInterceptor.compress.failed"));
|
||||
throw new ChannelException(x);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void messageReceived(ChannelMessage msg) {
|
||||
try {
|
||||
byte[] data = decompress(msg.getMessage().getBytes());
|
||||
msg.getMessage().trim(msg.getMessage().getLength());
|
||||
msg.getMessage().append(data,0,data.length);
|
||||
super.messageReceived(msg);
|
||||
} catch ( IOException x ) {
|
||||
log.error(sm.getString("gzipInterceptor.decompress.failed"),x);
|
||||
}
|
||||
}
|
||||
|
||||
public static byte[] compress(byte[] data) throws IOException {
|
||||
ByteArrayOutputStream bout = new ByteArrayOutputStream();
|
||||
GZIPOutputStream gout = new GZIPOutputStream(bout);
|
||||
gout.write(data);
|
||||
gout.flush();
|
||||
gout.close();
|
||||
return bout.toByteArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param data Data to decompress
|
||||
* @return Decompressed data
|
||||
* @throws IOException Compression error
|
||||
*/
|
||||
public static byte[] decompress(byte[] data) throws IOException {
|
||||
ByteArrayOutputStream bout =
|
||||
new ByteArrayOutputStream(DEFAULT_BUFFER_SIZE);
|
||||
ByteArrayInputStream bin = new ByteArrayInputStream(data);
|
||||
GZIPInputStream gin = new GZIPInputStream(bin);
|
||||
byte[] tmp = new byte[DEFAULT_BUFFER_SIZE];
|
||||
int length = gin.read(tmp);
|
||||
while (length > -1) {
|
||||
bout.write(tmp, 0, length);
|
||||
length = gin.read(tmp);
|
||||
}
|
||||
return bout.toByteArray();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
# 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.
|
||||
|
||||
domainFilterInterceptor.member.refused=Member [{0}] was refused to join cluster
|
||||
domainFilterInterceptor.message.refused=Received message from cluster[{0}] was refused.
|
||||
|
||||
encryptInterceptor.algorithm.required=Encryption algorithm is required, fully-specified e.g. AES/CBC/PKCS5Padding
|
||||
encryptInterceptor.algorithm.unsupported-mode=EncryptInterceptor does not support block cipher mode [{0}]
|
||||
encryptInterceptor.decrypt.error.short-message=Failed to decrypt message: premature end-of-message
|
||||
encryptInterceptor.decrypt.failed=Failed to decrypt message
|
||||
encryptInterceptor.encrypt.failed=Failed to encrypt message
|
||||
encryptInterceptor.init.failed=Failed to initialize EncryptInterceptor
|
||||
encryptInterceptor.key.required=Encryption key is required
|
||||
encryptInterceptor.tcpFailureDetector.ordering=EncryptInterceptor must be upstream of TcpFailureDetector. Please re-order EncryptInterceptor to be listed before TcpFailureDetector in your channel interceptor pipeline.
|
||||
|
||||
fragmentationInterceptor.fragments.missing=Fragments are missing.
|
||||
fragmentationInterceptor.heartbeat.failed=Unable to perform heartbeat clean up in the frag interceptor
|
||||
|
||||
gzipInterceptor.compress.failed=Unable to compress byte contents
|
||||
gzipInterceptor.decompress.failed=Unable to decompress byte contents
|
||||
|
||||
messageDispatchInterceptor.AsyncMessage.failed=Error while processing async message.
|
||||
messageDispatchInterceptor.completeMessage.failed=Unable to report back completed message.
|
||||
messageDispatchInterceptor.errorMessage.failed=Unable to report back error message.
|
||||
messageDispatchInterceptor.queue.full=Asynchronous queue is full, reached its limit of [{0}] bytes, current:[{1}] bytes.
|
||||
messageDispatchInterceptor.unableAdd.queue=Unable to add the message to the async queue, queue bug?
|
||||
messageDispatchInterceptor.warning.optionflag=Warning, you are overriding the asynchronous option flag, this will disable the Channel.SEND_OPTIONS_ASYNCHRONOUS that other apps might use.
|
||||
|
||||
nonBlockingCoordinator.electionMessage.sendfailed=Unable to send election message to:[{0}]
|
||||
nonBlockingCoordinator.heartbeat.failed=Unable to perform heartbeat.
|
||||
nonBlockingCoordinator.heartbeat.inconsistency=Heartbeat found inconsistency, restart election
|
||||
nonBlockingCoordinator.memberAdded.failed=Unable to start election when member was added.
|
||||
nonBlockingCoordinator.memberAlive.failed=Unable to perform member alive check, assuming member down.
|
||||
nonBlockingCoordinator.memberDisappeared.failed=Unable to start election when member was removed.
|
||||
nonBlockingCoordinator.processCoordinationMessage.failed=Error processing coordination message. Could be fatal.
|
||||
|
||||
orderInterceptor.messageAdded.sameCounter=Message added has the same counter, synchronization bug. Disable the order interceptor
|
||||
|
||||
staticMembershipInterceptor.no.failureDetector=There is no TcpFailureDetector. Automatic detection of static members does not work properly. By defining the StaticMembershipInterceptor under the TcpFailureDetector, automatic detection of the static members will work.
|
||||
staticMembershipInterceptor.no.pingInterceptor=There is no TcpPingInterceptor. The health check of static members does not work properly. By defining the TcpPingInterceptor, the health check of static members will work.
|
||||
staticMembershipInterceptor.sendLocalMember.failed=Local member notification failed.
|
||||
staticMembershipInterceptor.sendShutdown.failed=Shutdown notification failed.
|
||||
|
||||
tcpFailureDetector.already.disappeared=Verification complete. Member already disappeared[{0}]
|
||||
tcpFailureDetector.failureDetection.failed=Unable to perform failure detection check, assuming member down.[{0}]
|
||||
tcpFailureDetector.heartbeat.failed=Unable to perform heartbeat on the TcpFailureDetector.
|
||||
tcpFailureDetector.member.disappeared=Verification complete. Member disappeared[{0}]
|
||||
tcpFailureDetector.memberDisappeared.verify=Received memberDisappeared[{0}] message. Will verify.
|
||||
tcpFailureDetector.performBasicCheck.memberAdded=Member added, even though we weren''t notified:[{0}]
|
||||
tcpFailureDetector.still.alive=Verification complete. Member still alive[{0}]
|
||||
tcpFailureDetector.suspectMember.alive=Suspect member, confirmed alive.[{0}]
|
||||
tcpFailureDetector.suspectMember.dead=Suspect member, confirmed dead.[{0}]
|
||||
|
||||
tcpPingInterceptor.ping.failed=Unable to send TCP ping.
|
||||
tcpPingInterceptor.pingFailed.pingThread=Unable to send ping from TCP ping thread.
|
||||
|
||||
throughputInterceptor.report=ThroughputInterceptor Report[\n\
|
||||
\tTx Msg:{0} messages\n\
|
||||
\tSent:{1} MB (total)\n\
|
||||
\tSent:{2} MB (application)\n\
|
||||
\tTime:{3} seconds\n\
|
||||
\tTx Speed:{4} MB/sec (total)\n\
|
||||
\tTx Speed:{5} MB/sec (application)\n\
|
||||
\tError Msg:{6}\n\
|
||||
\tRx Msg:{7} messages\n\
|
||||
\tRx Speed:{8} MB/sec (since 1st msg)\n\
|
||||
\tReceived:{9} MB]\n
|
||||
|
||||
twoPhaseCommitInterceptor.heartbeat.failed=Unable to perform heartbeat on the TwoPhaseCommit interceptor.
|
||||
twoPhaseCommitInterceptor.originalMessage.missing=Received a confirmation, but original message is missing. Id:[{0}]
|
||||
@@ -0,0 +1,32 @@
|
||||
# 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.
|
||||
|
||||
domainFilterInterceptor.member.refused=Mitglied [{0}] wurde nicht zum Cluster zugelassen
|
||||
|
||||
encryptInterceptor.decrypt.error.short-message=Konnte die Nachricht nicht entschlüsseln: Vorzeitiges Ende der Nachricht
|
||||
encryptInterceptor.decrypt.failed=Nachricht konnte nicht entschlüsselt werden
|
||||
|
||||
messageDispatchInterceptor.queue.full=Asynchrone Warteschlange ist voll. Das Limit von [{0}] Bytes ist erreicht mit aktuell [{1}] Bytes.
|
||||
|
||||
nonBlockingCoordinator.processCoordinationMessage.failed=Fehler beim Verarbeiten der Koordinationsnachricht. Könnte Fatal sein.
|
||||
|
||||
staticMembershipInterceptor.sendShutdown.failed=Benachrichtigung über den Shutdown schlug fehl.
|
||||
|
||||
tcpFailureDetector.failureDetection.failed=Überprüng zur Fehlererkennung fehlgeschlagen, Mitglied [{0}]
|
||||
tcpFailureDetector.still.alive=Verifikation abgeschlossen. Member sind immer noch am Leben [{0}]
|
||||
|
||||
tcpPingInterceptor.ping.failed=Konnte kein TCP Ping senden.
|
||||
|
||||
twoPhaseCommitInterceptor.heartbeat.failed=Kann den Heartbeat auf dem TwoPhaseCommit Interceptor nicht durchführen.
|
||||
@@ -0,0 +1,47 @@
|
||||
# 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.
|
||||
|
||||
domainFilterInterceptor.message.refused=El mensaje [{0}] recibido del cluster fue rechazado
|
||||
|
||||
encryptInterceptor.decrypt.error.short-message=Fallo al descifrar el mensaje: fin-de-mensaje prematuro
|
||||
|
||||
messageDispatchInterceptor.queue.full=La cola asincrónica esta llena, se alcanzó el limite de [{0}] bytes, actualmente:[{1}] bytes.\n
|
||||
|
||||
nonBlockingCoordinator.memberAlive.failed=No se puede verificar si el miembro esta vivo, asumiendo que el miembro esta inactivo.
|
||||
nonBlockingCoordinator.processCoordinationMessage.failed=Error procesando el mensaje de coordinación. Puede ser fatal.\n
|
||||
|
||||
staticMembershipInterceptor.no.pingInterceptor=No existe TcpPingInterceptor. El verificador de estado de miembros estáticos no trabaja correctamente. Al definir el TcpPingInterceptor, el verificador de estado de miembros estáticos trabajará correctamente.
|
||||
staticMembershipInterceptor.sendShutdown.failed=El aviso de apagado falló.
|
||||
|
||||
tcpFailureDetector.failureDetection.failed=No se pudo realizar la verificación de detección de fallos, se asume que el membro esta abajo.[{0}]
|
||||
tcpFailureDetector.heartbeat.failed=Imposible ejecutar heartbeat en el TcpFailureDetector.
|
||||
tcpFailureDetector.member.disappeared=Verificación completada. Miembro desaparecido[{0}]
|
||||
tcpFailureDetector.still.alive=Verificación completa. El miembro aun esta vivo [{0}]
|
||||
tcpFailureDetector.suspectMember.alive=Se confima que esta vivo el miembro.[{0}]\n
|
||||
|
||||
tcpPingInterceptor.ping.failed=Imposible enviar ping TCP
|
||||
|
||||
throughputInterceptor.report=ThroughputInterceptor Reporte[\n\
|
||||
\tTx Msg:{0} mensajes\n\
|
||||
\tEnviados:{2} MB (aplicación)\n\
|
||||
\tTiempo:{3} segundos\n\
|
||||
\tTx Speed:{4} MB/seg(total)\n\
|
||||
\tTx Speed::{5} MB/seg(aplicación)\n\
|
||||
\tMsg error:{6}\n\
|
||||
\tRx Msg:{7} mensajes\n\
|
||||
\tRx Speed:{8} MB/sec (desde 1er msg)\n\
|
||||
\tRecivido:{9} MB]
|
||||
|
||||
twoPhaseCommitInterceptor.heartbeat.failed=Incapáz de ejecutar heartbeat en el interceptor TwoPhaseCommit
|
||||
@@ -0,0 +1,82 @@
|
||||
# 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.
|
||||
|
||||
domainFilterInterceptor.member.refused=Le membre [{0}] a été refusé dans le cluster
|
||||
domainFilterInterceptor.message.refused=Le message reçu du cluster [{0}] a été refusé
|
||||
|
||||
encryptInterceptor.algorithm.required=Un algorithme de cryptage est requis, avec une spécification complète telle que AES/CBC/PKCS5Padding
|
||||
encryptInterceptor.algorithm.unsupported-mode=L''EncryptInterceptor ne supporte pas le mode de chiffrage de bloc [{0}]
|
||||
encryptInterceptor.decrypt.error.short-message=Erreur de décryptage du message: fin de message prématuré
|
||||
encryptInterceptor.decrypt.failed=Echec de décryptage du message
|
||||
encryptInterceptor.encrypt.failed=Erreur de cryptage du message
|
||||
encryptInterceptor.init.failed=Echec de l'initalisation d'EncryptInterceptor
|
||||
encryptInterceptor.key.required=Une clé de cryptage est requise
|
||||
encryptInterceptor.tcpFailureDetector.ordering=EncryptInterceptor doit être en amont de TcpFailureDetector, l'EncryptInterceptor doit être repositionné pour être listé avant TcpFailureDetector dans le pipeline d'intercepteurs du canal
|
||||
|
||||
fragmentationInterceptor.fragments.missing=Les fragments sont manquants
|
||||
fragmentationInterceptor.heartbeat.failed=Impossible d'effectuer le nettoyage périodique de l'intercepteur de fragments
|
||||
|
||||
gzipInterceptor.compress.failed=Impossible de compresser un contenu binaire
|
||||
gzipInterceptor.decompress.failed=Impossible de décompresser le contenu des octets
|
||||
|
||||
messageDispatchInterceptor.AsyncMessage.failed=Erreur lors du traitement du message asynchrone
|
||||
messageDispatchInterceptor.completeMessage.failed=Impossible de renvoyer le message complet
|
||||
messageDispatchInterceptor.errorMessage.failed=Impossible d'envoyer le message d'erreur
|
||||
messageDispatchInterceptor.queue.full=La file d''attente asynchrone est pleine, ayant atteint sa limite de [{0}] octets. Actuellement: [{1}] octets.
|
||||
messageDispatchInterceptor.unableAdd.queue=Impossible d'ajouter le message à la file asynchrone. Bogue de file ?
|
||||
messageDispatchInterceptor.warning.optionflag=Attention, vous passez outre le drapeau d'option d'asynchronicité ("asynchronous option flag"), cela désactivera Channel.SEND_OPTIONS_ASYNCHRONOUS, que d'autres applications sont susceptibles d'utiliser.
|
||||
|
||||
nonBlockingCoordinator.electionMessage.sendfailed=Impossible d''envoyer le message d''élection à: [{0}]
|
||||
nonBlockingCoordinator.heartbeat.failed=Impossible d'effectuer le signal périodique
|
||||
nonBlockingCoordinator.heartbeat.inconsistency=Le coordinateur à trouvé un état inconsistant, redémarrage de l'élection
|
||||
nonBlockingCoordinator.memberAdded.failed=Impossible de démarrer une élection quand le membre a été ajouté
|
||||
nonBlockingCoordinator.memberAlive.failed=Impossible d'effectuer le test de vie du membre, assume membre inactif.
|
||||
nonBlockingCoordinator.memberDisappeared.failed=Impossible de démarrer une élection lorsqu'un membre a été enlevé
|
||||
nonBlockingCoordinator.processCoordinationMessage.failed=Echec de traitement de message de coordination. Pourrait être fatal.
|
||||
|
||||
orderInterceptor.messageAdded.sameCounter=Le message ajouté a le même compteur, à cause d'un bug de synchronisation, l'intercepteur d'ordre doit être désactivé
|
||||
|
||||
staticMembershipInterceptor.no.failureDetector=Il n'y a pas de détecteur TcpFailureDetector. La détection automatique de membres statiques ne fonctionne pas correctement. Par la définition d'un intercepteur StaticMembershipInterceptor sous le TcpFailureDetector, cette détection automatique fonctionnera.
|
||||
staticMembershipInterceptor.no.pingInterceptor=Il n'y a pas de TcpPingInterceptor. Le test de bonne santé des membres statiques ne fonctionne pas correctement. En définissant le TcpPingInterceptor, le test de bonne santé des membres statiques fonctionnera.
|
||||
staticMembershipInterceptor.sendLocalMember.failed=La notification du membre local a échouée
|
||||
staticMembershipInterceptor.sendShutdown.failed=La notification d'arrêt a échoué
|
||||
|
||||
tcpFailureDetector.already.disappeared=La vérification est terminée, le membre avait déjà disparu [{0}]
|
||||
tcpFailureDetector.failureDetection.failed=Impossible d''effectuer le test de détection de faute. Membre [{0}] supposé inactif.
|
||||
tcpFailureDetector.heartbeat.failed=Incapable de faire une pulsation ("heatbeat") sur le TcpFailureDector
|
||||
tcpFailureDetector.member.disappeared=La vérfication est complète, le membre a disparu [{0}]
|
||||
tcpFailureDetector.memberDisappeared.verify=Reçu un message memberDisappeared[{0}], qui sera vérifié
|
||||
tcpFailureDetector.performBasicCheck.memberAdded=Le membre a été ajouté bien qu''aucune notification n''ait été reçue: [{0}]
|
||||
tcpFailureDetector.still.alive=Vérification terminée. Le membre [{0}] vit toujours
|
||||
tcpFailureDetector.suspectMember.alive=Membre suspect, confirmé vivant.[{0}]
|
||||
tcpFailureDetector.suspectMember.dead=Un membre suspect a été confirmé mort [{0}]
|
||||
|
||||
tcpPingInterceptor.ping.failed=Impossible d'envoyer un ping TCP.
|
||||
tcpPingInterceptor.pingFailed.pingThread=Impossible d'envoyer un ping à partir du thread des ping TCP
|
||||
|
||||
throughputInterceptor.report=Rapport de l''intercepteur du débit ("ThroughputInterceptor Report") [\n\
|
||||
\tMsg Transmis (Tx Msg):{0} messages\n\
|
||||
\tEnvoyé (Sent):{1} MB (total)\n\
|
||||
\tEnvoyé (Sent):{2} MB (application)\n\
|
||||
\tDurée (Time):{3} secondes\n\
|
||||
\tVitesse d''écriture (Tx Speed):{4} MB/sec (total)\n\
|
||||
\tVitesse d''écriture (Tx Speed):{5} MB/sec (application)\n\
|
||||
\tMsg d''erreur (Error Msg):{6}\n\
|
||||
\tMsg Reçus (Rx Msg):{7} messages\n\
|
||||
\tVitesse de Réception (Rx Speed):{8} MB/sec (depuis le 1er message)\n\
|
||||
\tReçu:{9} MB]
|
||||
|
||||
twoPhaseCommitInterceptor.heartbeat.failed=Impossible d'exécuter un battement de coeur (heartbeat) sur l'intercepteur (interceptor) "TwoPhaseCommit".
|
||||
twoPhaseCommitInterceptor.originalMessage.missing=Reçue une confirmation mais le message d''origine manque, id: [{0}]
|
||||
@@ -0,0 +1,82 @@
|
||||
# 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.
|
||||
|
||||
domainFilterInterceptor.member.refused=メンバーはクラスター [{0}] への参加を拒否されました。
|
||||
domainFilterInterceptor.message.refused=クラスター [{0}] から受信したメッセージは拒否されました。
|
||||
|
||||
encryptInterceptor.algorithm.required=暗号化アルゴリズムが必要です。完全指定。 AES/CBC/PKCS5Padding
|
||||
encryptInterceptor.algorithm.unsupported-mode=EncryptInterceptorはブロック暗号モード [{0}]をサポートしていません。
|
||||
encryptInterceptor.decrypt.error.short-message=メッセージの復号に失敗: メッセージの末尾が途切れています
|
||||
encryptInterceptor.decrypt.failed=メッセージの復号に失敗しました。
|
||||
encryptInterceptor.encrypt.failed=メッセージを暗号化できません。
|
||||
encryptInterceptor.init.failed=EncryptInterceptorの初期化に失敗しました
|
||||
encryptInterceptor.key.required=暗号化キーが必要です。
|
||||
encryptInterceptor.tcpFailureDetector.ordering=EncryptInterceptorはTcpFailureDetectorの上流になければなりません。 チャネルインターセプターパイプラインのTcpFailureDetectorの前にリストされるようにEncryptInterceptorを再設定してください。
|
||||
|
||||
fragmentationInterceptor.fragments.missing=フラグメントが見つかりません。
|
||||
fragmentationInterceptor.heartbeat.failed=fragmentationInterceptorでハートビートクリーンアップを実行できません。
|
||||
|
||||
gzipInterceptor.compress.failed=バイトデータを圧縮できません。
|
||||
gzipInterceptor.decompress.failed=圧縮されたバイトデータを展開できません。
|
||||
|
||||
messageDispatchInterceptor.AsyncMessage.failed=非同期メッセージの処理中にエラーが発生しました。
|
||||
messageDispatchInterceptor.completeMessage.failed=完了したメッセージを報告できません。
|
||||
messageDispatchInterceptor.errorMessage.failed=エラーメッセージを返すことができません。
|
||||
messageDispatchInterceptor.queue.full=非同期キューが満杯です。現在は [{1}] バイトで上限の [{0}] バイトに達しています。
|
||||
messageDispatchInterceptor.unableAdd.queue=非同期キューにメッセージを登録できませんでした。キューの不具合かもしれません。
|
||||
messageDispatchInterceptor.warning.optionflag=警告です。非同期オプションフラグを上書きしたため、他のアプリケーションが使用する可能性のある Channel.SEND_OPTIONS_ASYNCHRONOUS は無効化されます。
|
||||
|
||||
nonBlockingCoordinator.electionMessage.sendfailed=メンバー [{0}] に調停メッセージを送信できません。
|
||||
nonBlockingCoordinator.heartbeat.failed=ハートビートを実行できません。
|
||||
nonBlockingCoordinator.heartbeat.inconsistency=ハートビートが不一致を発見し、イレクションを再開します。
|
||||
nonBlockingCoordinator.memberAdded.failed=メンバーが追加されたときにイレクションを開始できません。
|
||||
nonBlockingCoordinator.memberAlive.failed=動作チェックが実行できなかったため、メンバーは停止しているものとして扱います。
|
||||
nonBlockingCoordinator.memberDisappeared.failed=メンバーが削除されたときにイレクションを開始できません。
|
||||
nonBlockingCoordinator.processCoordinationMessage.failed=調停メッセージを処理できませんでした。致命的な問題が発生している可能性があります。
|
||||
|
||||
orderInterceptor.messageAdded.sameCounter=同じカウンタにメッセージが追加されました。同期バグがあります。 Order インターセプタを無効にして下さい。
|
||||
|
||||
staticMembershipInterceptor.no.failureDetector=TcpFailureDetector がありません。静的メンバーの自動検出機能は正常に動作しません。TcpFailureDetector 配下に StaticMembershipInterceptor を定義すれば、静的メンバーの自動検出機能が動作するでしょう。
|
||||
staticMembershipInterceptor.no.pingInterceptor=TcpPingInterceptorが存在しないため、静的メンバーのヘルスチェックは正常に機能しません。TcpPingInterceptorを定義すれば機能するでしょう。
|
||||
staticMembershipInterceptor.sendLocalMember.failed=ローカルメンバーの通知は失敗しました。
|
||||
staticMembershipInterceptor.sendShutdown.failed=シャットダウン通知が失敗しました
|
||||
|
||||
tcpFailureDetector.already.disappeared=検証完了。メンバーはすでに離脱していることを確認しました [{0}]
|
||||
tcpFailureDetector.failureDetection.failed=故障検出チェックが実行できないため、メンバーが停止しているものとして扱います。
|
||||
tcpFailureDetector.heartbeat.failed=TcpFailureDetector のハートビートチェックができませんでした。
|
||||
tcpFailureDetector.member.disappeared=メンバ検証が完了しました。 メンバーが消えました[{0}]
|
||||
tcpFailureDetector.memberDisappeared.verify=memberDisappeared[{0}]メッセージを受信しました。 メンバ検証します。
|
||||
tcpFailureDetector.performBasicCheck.memberAdded=私たちに通知されなかったにもかかわらず、メンバーが追加されました:[{0}]
|
||||
tcpFailureDetector.still.alive=故障検出チェックが完了しました。メンバー [{0}] は正常です。
|
||||
tcpFailureDetector.suspectMember.alive=疑わしいクラスタメンバーの生存を確認しました。 [{0}]
|
||||
tcpFailureDetector.suspectMember.dead=疑義メンバが死亡したことが確認されました。[{0}]
|
||||
|
||||
tcpPingInterceptor.ping.failed=TCP の ping メッセージを送信できませんでした。
|
||||
tcpPingInterceptor.pingFailed.pingThread=TCP pingスレッドからpingを送信できません。
|
||||
|
||||
throughputInterceptor.report=ThroughputInterceptor Report[\n\
|
||||
\ 送信メッセージ (Tx Msg):{0} messages\n\
|
||||
\ 送信済み (Sent):{1} MB (total)\n\
|
||||
\ 送信済み (Sent):{2} MB (application)\n\
|
||||
\ 時間 (Time):{3} seconds\n\
|
||||
\ 送信速度 (Tx Speed):{4} MB/sec (total)\n\
|
||||
\ 送信速度 (Tx Speed):{5} MB/sec (application)\n\
|
||||
\ エラーメッセージ (Error Msg):{6}\n\
|
||||
\ 受信メッセージ (Rx Msg):{7} messages\n\
|
||||
\ 受信速度 (Rx Speed):{8} MB/sec (since 1st msg)\n\
|
||||
\ 受信済み (Received):{9} MB]
|
||||
|
||||
twoPhaseCommitInterceptor.heartbeat.failed=TwoPhaseCommit インターセプターのハートビートが失敗しました。
|
||||
twoPhaseCommitInterceptor.originalMessage.missing=確認を受信しましたが、元のメッセージがありません。 Id:[{0}]
|
||||
@@ -0,0 +1,83 @@
|
||||
# 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.
|
||||
|
||||
domainFilterInterceptor.member.refused=멤버 [{0}]이(가) 클러스터에 참가하는 것이 거부되었습니다.
|
||||
domainFilterInterceptor.message.refused=클러스터 [{0}](으)로부터 받은 메시지가 거부되었습니다.
|
||||
|
||||
encryptInterceptor.algorithm.required=암호화 알고리즘을 완전하게 지정해야 합니다. 예) AES/CBC/PKCS5Padding.
|
||||
encryptInterceptor.algorithm.unsupported-mode=EncryptInterceptor가 블록 cipher 모드 [{0}]을(를) 지원하지 않습니다.
|
||||
encryptInterceptor.decrypt.error.short-message=메시지를 해독하지 못했습니다: 메시지가 너무 일찍 끝났습니다 (premature end-of-message).
|
||||
encryptInterceptor.decrypt.failed=메시지를 해독하지 못했습니다.
|
||||
encryptInterceptor.encrypt.failed=메시지를 암호화하지 못했습니다.
|
||||
encryptInterceptor.init.failed=EncryptInterceptor를 초기화하지 못했습니다.
|
||||
encryptInterceptor.key.required=암호화 키가 필수적입니다.
|
||||
encryptInterceptor.tcpFailureDetector.ordering=EncryptInterceptor는 반드시 TcpFailureDetector 보다 먼저 위치해야 합니다. 채널 인터셉터 파이프라인 내에서, EncryptInterceptor가 TcpFailureDetector 보다 먼저 위치하도록 조정하십시오.
|
||||
|
||||
fragmentationInterceptor.fragments.missing=Fragment들이 없습니다.
|
||||
fragmentationInterceptor.heartbeat.failed=FragmentationInterceptor에서 heartbeat를 clean up 할 수 없습니다.
|
||||
|
||||
gzipInterceptor.compress.failed=바이트 컨텐트들을 압축할 수 없습니다.
|
||||
gzipInterceptor.decompress.failed=바이트 컨텐트들의 압축을 풀 수 없습니다.
|
||||
|
||||
messageDispatchInterceptor.AsyncMessage.failed=비동기 메시지를 처리하는 중 오류 발생
|
||||
messageDispatchInterceptor.completeMessage.failed=완료된 메시지를 되돌려 보고할 수 없습니다.
|
||||
messageDispatchInterceptor.errorMessage.failed=오류 메시지를 되돌려 보고할 수 없습니다.
|
||||
messageDispatchInterceptor.queue.full=비동기 큐가 꽉 차서 한계값인 [{0}] 바이트에 도달했습니다. 현재 값: [{1}] 바이트.
|
||||
messageDispatchInterceptor.unableAdd.queue=비동기 큐에 메시지를 추가할 수 없습니다. 큐의 버그일까요?
|
||||
messageDispatchInterceptor.warning.optionflag=경고: 귀하는 비동기 옵션 플래그를 오버라이드하고 있는데, 이는 다른 애플리케이션들이 사용할 수도 있는 Channel.SEND_OPTIONS_ASYNCHRONOUS 옵션을 사용 불능 상태로 만들 것입니다.
|
||||
|
||||
nonBlockingCoordinator.electionMessage.sendfailed=Election 메시지를 [{0}]에 보낼 수 없습니다.
|
||||
nonBlockingCoordinator.heartbeat.failed=Heartbeat를 수행할 수 없습니다.
|
||||
nonBlockingCoordinator.heartbeat.inconsistency=Heartbeat가 일관되지 않은 상태로 발견되었습니다. Election을 다시 시작합니다.
|
||||
nonBlockingCoordinator.memberAdded.failed=멤버가 추가되었을 때, election을 시작할 수 없었습니다.
|
||||
nonBlockingCoordinator.memberAlive.failed=멤버가 살아있는지 점검할 수 없습니다. 아마도 해당 멤버가 다운된 것 같습니다.
|
||||
nonBlockingCoordinator.memberDisappeared.failed=멤버가 제거되었을 때, election을 시작할 수 없었습니다.
|
||||
nonBlockingCoordinator.processCoordinationMessage.failed=CoordinationMessage 처리 중 오류 발생. 치명적인 오류일 수 있습니다.
|
||||
|
||||
orderInterceptor.messageAdded.sameCounter=추가된 메시지가 동일한 카운터를 가지고 있습니다. 동기화 결함입니다. OrderInterceptor를 사용불능 상태로 설정하십시오.
|
||||
|
||||
staticMembershipInterceptor.no.failureDetector=TcpFailureDetector가 없습니다. 정적 멤버들에 대한 자동 탐지가 정상 동작하지 않을 것입니다. TcpFailureDetector 아래에 StaticMembershipInterceptor를 정의하게 되면, 정적 멤버들에 대한 자동 탐지가 정상 동작할 것입니다.
|
||||
staticMembershipInterceptor.no.pingInterceptor=TcpPingInterceptor가 존재하지 않습니다. 정적 멤버들에 대한 heath check는 제대로 동작하지 않을 것입니다. TcpPingInterceptor를 정의함으로써, 정적 멤버들에 대한 health check가 정상 동작할 것입니다.
|
||||
staticMembershipInterceptor.sendLocalMember.failed=로컬 멤버 통지 실패
|
||||
staticMembershipInterceptor.sendShutdown.failed=시스템을 셧다운하기 위한 통지가 실패했습니다.
|
||||
|
||||
tcpFailureDetector.already.disappeared=검증 완료. 멤버가 이미 사라졌습니다: [{0}]
|
||||
tcpFailureDetector.failureDetection.failed=멤버에 대한 실패 탐지 점검을 수행할 수 없습니다. 아마도 해당 멤버 [{0}]이(가) 다운된 것 같습니다.
|
||||
tcpFailureDetector.heartbeat.failed=TcpFailureDetector에서 heartbeat 점검을 수행할 수 없습니다.
|
||||
tcpFailureDetector.member.disappeared=검증 완료. 멤버가 사라졌습니다: [{0}]
|
||||
tcpFailureDetector.memberDisappeared.verify=멤버 사라짐 메시지를 받았습니다: [{0}]. 이를 검증할 것입니다.
|
||||
tcpFailureDetector.performBasicCheck.memberAdded=통지 받지는 못했지만, 멤버가 추가되었습니다: [{0}]
|
||||
tcpFailureDetector.still.alive=검증 완료. 멤버가 아직 살아 있습니다: [{0}]
|
||||
tcpFailureDetector.suspectMember.alive=의심 멤버 서버가 살아 있음을 확인했습니다. [{0}]
|
||||
tcpFailureDetector.suspectMember.dead=의심 멤버가 다운된 것으로 확인됨: [{0}]
|
||||
|
||||
tcpPingInterceptor.ping.failed=TCP ping을 보낼 수 없습니다.
|
||||
tcpPingInterceptor.pingFailed.pingThread=TCP ping 쓰레드로부터, ping을 전송할 수 없습니다.
|
||||
|
||||
throughputInterceptor.report=ThroughputInterceptor의 보고 [\n\
|
||||
\tTx Msg:{0} 메시지(들)\n\
|
||||
\tSent:{1} MB (전체)\n\
|
||||
\tSent:{2} MB (애플리케이션)\n\
|
||||
\tTime:{3} 초\n\
|
||||
\tTx Speed:{4} MB/sec (전체)\n\
|
||||
\tTx Speed:{5} MB/sec (애플리케이션)\n\
|
||||
\tError Msg:{6}\n\
|
||||
\tRx Msg:{7} 메시지\n\
|
||||
\tRx Speed:{8} MB/sec (첫번째 메시지 이후로)\n\
|
||||
\tReceived:{9} MB]\n\
|
||||
\n
|
||||
|
||||
twoPhaseCommitInterceptor.heartbeat.failed=해당 TwoPhaseCommit 인터셉터에서 heartbeat를 수행할 수 없습니다.
|
||||
twoPhaseCommitInterceptor.originalMessage.missing=확인 플래그를 받았지만, 원본 메시지가 없습니다. ID:[{0}]
|
||||
@@ -0,0 +1,22 @@
|
||||
# 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.
|
||||
|
||||
encryptInterceptor.decrypt.error.short-message=Невозможно расшифровать сообщение: слишком мало символов
|
||||
|
||||
nonBlockingCoordinator.memberAlive.failed=Невозможно проверить участника, считаем что упал
|
||||
|
||||
staticMembershipInterceptor.sendShutdown.failed=Не удалось сообщить об отключении.
|
||||
|
||||
tcpFailureDetector.still.alive=Проверка завершена. Участник ещё жив [{0}]
|
||||
@@ -0,0 +1,60 @@
|
||||
# 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.
|
||||
|
||||
domainFilterInterceptor.member.refused=成员被拒绝加入集群 cluster[{0}]
|
||||
domainFilterInterceptor.message.refused=从集群[{0}]中接收的消息被拒绝
|
||||
|
||||
encryptInterceptor.decrypt.error.short-message=解密消息失败: 结尾消息提前结束
|
||||
encryptInterceptor.decrypt.failed=无法解密信息
|
||||
encryptInterceptor.encrypt.failed=无法加密信息
|
||||
encryptInterceptor.init.failed=初始化EncryptInterceptor失败
|
||||
encryptInterceptor.tcpFailureDetector.ordering=加密拦截器必须位于TCP故障检测器的上游。请重新订购加密拦截器,将其列在通道拦截器管道中的TCP故障检测器之前。
|
||||
|
||||
messageDispatchInterceptor.errorMessage.failed=无法回传错误信息
|
||||
messageDispatchInterceptor.queue.full=异步队列已满,达到 [{0}] 字节的限制,当前:[{1}] 字节
|
||||
messageDispatchInterceptor.unableAdd.queue=无法将消息添加到异步队列,队列 bug?
|
||||
messageDispatchInterceptor.warning.optionflag=警告!你正在覆盖异步选项标志,这将禁用其它程序可能用到的 Channel.SEND_OPTIONS_ASYNCHRONOUS。
|
||||
|
||||
nonBlockingCoordinator.heartbeat.inconsistency=心跳发现不一致,重新启动选举
|
||||
nonBlockingCoordinator.memberAlive.failed=无法执行成员活动检查,猜测成员下线。
|
||||
nonBlockingCoordinator.processCoordinationMessage.failed=处理协调消息时出错。 可能是致命的。
|
||||
|
||||
staticMembershipInterceptor.no.failureDetector=没有TcpFailureDetector。 自动检测静态成员无法正常工作。 通过在TcpFailureDetector下定义StaticMembershipInterceptor,可以自动检测静态成员。
|
||||
staticMembershipInterceptor.no.pingInterceptor=在没有TcpPingInterceptor的情况下,静态成员的健康检查不会正常工作。只有定义了TcpPingInterceptor,才能使健康检查正常进行。
|
||||
staticMembershipInterceptor.sendShutdown.failed=关闭通知失败。
|
||||
|
||||
tcpFailureDetector.failureDetection.failed=无法进行失败监测,假定成员宕机。[{0}]
|
||||
tcpFailureDetector.heartbeat.failed=TCP心跳检测器无法执行心跳
|
||||
tcpFailureDetector.member.disappeared=认证完成。成员消失[{0}]
|
||||
tcpFailureDetector.memberDisappeared.verify=(:收到的membermissed[{0}]消息。将验证。
|
||||
tcpFailureDetector.still.alive=验证完成。成员 [{0}] 仍然存活
|
||||
tcpFailureDetector.suspectMember.alive=验证可疑成员服务器还活着。[{0}]
|
||||
|
||||
tcpPingInterceptor.ping.failed=无法发送 TCP ping
|
||||
tcpPingInterceptor.pingFailed.pingThread=不能从ping 线程发送ping
|
||||
|
||||
throughputInterceptor.report=吞吐量拦截器 报告[\n\
|
||||
\ 传输消息: {0} 消息数.\n\
|
||||
\ 发送: {1} MB(总共)\n\
|
||||
\ 发送: {2} MB (应用)\n\
|
||||
\ 耗时: {3} 秒\n\
|
||||
\ 传输速率: {4}MB/sec (总共)\n\
|
||||
\ 传输速率: {5}MB/sec (应用)\n\
|
||||
\ 错误消息: {6}\n\
|
||||
\ 接收消息: {7} 消息数\n\
|
||||
\ 接收速率: {8} MB/sec (从第一个消息开始)\n\
|
||||
\ 收到: {9}MB]
|
||||
|
||||
twoPhaseCommitInterceptor.heartbeat.failed=无法在两阶段提交拦截器上执行心跳。
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user