mirror of https://github.com/apache/activemq.git
Doing repository re-organization discussed here:
cms module was removed since it's been replace with activemq-cpp http://www.nabble.com/SVN-Repository-Reorganization-tf2221183.html git-svn-id: https://svn.apache.org/repos/asf/incubator/activemq/trunk@441202 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
5b53083274
commit
13277055fb
|
@ -1,23 +0,0 @@
|
|||
Welcome to ActiveCluster!
|
||||
=========================
|
||||
|
||||
ActiveCluster is an Apache 2.0 licenced cluster communication toolkit.
|
||||
|
||||
To help you get started, try surfing the following links...
|
||||
|
||||
Building
|
||||
http://activecluster.codehaus.org/Building
|
||||
|
||||
Examples
|
||||
http://activecluster.codehaus.org/Examples
|
||||
|
||||
Refer to the website for details of finding the issue tracker, email lists, wiki or IRC channel
|
||||
http://activecluster.codehaus.org/
|
||||
|
||||
Please help us make ActiveCluster better - we appreciate any feedback you may have.
|
||||
|
||||
Enjoy!
|
||||
|
||||
|
||||
----------------------
|
||||
The ActiveCluster team
|
|
@ -1,66 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.apache.activemq</groupId>
|
||||
<artifactId>activemq-parent</artifactId>
|
||||
<version>4.1-incubator-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>activecluster</artifactId>
|
||||
<name>ActiveCluster</name>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>${pom.groupId}</groupId>
|
||||
<artifactId>activemq-core</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.derby</groupId>
|
||||
<artifactId>derby</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<sourceDirectory>src/java</sourceDirectory>
|
||||
<testSourceDirectory>src/test</testSourceDirectory>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<configuration>
|
||||
<excludes>
|
||||
<exclude implementation="java.lang.String">**/Testing*.java</exclude>
|
||||
<exclude implementation="java.lang.String">**/TestSupport.java</exclude>
|
||||
<exclude implementation="java.lang.String">**/ClusterTest.java</exclude>
|
||||
<exclude implementation="java.lang.String">**/ClusterFunctionTest.java</exclude>
|
||||
</excludes>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
|
@ -1,228 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* 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.activecluster;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Map;
|
||||
import javax.jms.BytesMessage;
|
||||
import javax.jms.Destination;
|
||||
import javax.jms.JMSException;
|
||||
import javax.jms.MapMessage;
|
||||
import javax.jms.Message;
|
||||
import javax.jms.MessageConsumer;
|
||||
import javax.jms.ObjectMessage;
|
||||
import javax.jms.StreamMessage;
|
||||
import javax.jms.TextMessage;
|
||||
|
||||
import org.apache.activecluster.election.ElectionStrategy;
|
||||
|
||||
/**
|
||||
* Represents a logical connection to a cluster. From this object you can
|
||||
* obtain the destination to send messages to, view the members of the cluster,
|
||||
* watch cluster events (nodes joining, leaving, updating their state) as well
|
||||
* as viewing each members state.
|
||||
* <p/>
|
||||
* You may also update the local node's state.
|
||||
*
|
||||
* @version $Revision: 1.5 $
|
||||
*/
|
||||
public interface Cluster extends Service {
|
||||
|
||||
/**
|
||||
* Returns the destination used to send a message to all members of the cluster
|
||||
*
|
||||
* @return the destination to send messages to all members of the cluster
|
||||
*/
|
||||
public Destination getDestination();
|
||||
|
||||
/**
|
||||
* A snapshot of the nodes in the cluster indexed by the Destination
|
||||
* @return a Map containing all the nodes in the cluster, where key=node destination,value=node
|
||||
*/
|
||||
public Map getNodes();
|
||||
|
||||
/**
|
||||
* Adds a new listener to cluster events
|
||||
*
|
||||
* @param listener
|
||||
*/
|
||||
public void addClusterListener(ClusterListener listener);
|
||||
|
||||
/**
|
||||
* Removes a listener to cluster events
|
||||
*
|
||||
* @param listener
|
||||
*/
|
||||
public void removeClusterListener(ClusterListener listener);
|
||||
|
||||
/**
|
||||
* The local Node which allows you to mutate the state or subscribe to the
|
||||
* nodes temporary queue for inbound messages direct to the Node
|
||||
* @return the Node representing this peer in the cluster
|
||||
*/
|
||||
public LocalNode getLocalNode();
|
||||
|
||||
/**
|
||||
* Allows overriding of the default election strategy with a custom
|
||||
* implementation.
|
||||
* @param strategy
|
||||
*/
|
||||
public void setElectionStrategy(ElectionStrategy strategy);
|
||||
|
||||
|
||||
// Messaging helper methods
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Sends a message to a destination, which could be to the entire group
|
||||
* or could be a single Node's destination
|
||||
*
|
||||
* @param destination is either the group topic or a node's destination
|
||||
* @param message the message to be sent
|
||||
* @throws JMSException
|
||||
*/
|
||||
public void send(Destination destination, Message message) throws JMSException;
|
||||
|
||||
|
||||
/**
|
||||
* Creates a consumer of all the messags sent to the given destination,
|
||||
* including messages sent via the send() messages
|
||||
*
|
||||
* @param destination
|
||||
* @return a newly created message consumer
|
||||
* @throws JMSException
|
||||
*/
|
||||
public MessageConsumer createConsumer(Destination destination) throws JMSException;
|
||||
|
||||
/**
|
||||
* Creates a consumer of all message sent to the given destination,
|
||||
* including messages sent via the send() message with an optional SQL 92 based selector to filter
|
||||
* messages
|
||||
*
|
||||
* @param destination
|
||||
* @param selector
|
||||
* @return a newly created message consumer
|
||||
* @throws JMSException
|
||||
*/
|
||||
public MessageConsumer createConsumer(Destination destination, String selector) throws JMSException;
|
||||
|
||||
/**
|
||||
* Creates a consumer of all message sent to the given destination,
|
||||
* including messages sent via the send() message with an optional SQL 92 based selector to filter
|
||||
* messages along with optionally ignoring local traffic - messages sent via the send()
|
||||
* method on this object.
|
||||
*
|
||||
* @param destination the destination to consume from
|
||||
* @param selector an optional SQL 92 filter of messages which could be null
|
||||
* @param noLocal which if true messages sent via send() on this object will not be delivered to the consumer
|
||||
* @return a newly created message consumer
|
||||
* @throws JMSException
|
||||
*/
|
||||
public MessageConsumer createConsumer(Destination destination, String selector, boolean noLocal) throws JMSException;
|
||||
|
||||
|
||||
// Message factory methods
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Creates a new message without a body
|
||||
* @return the create Message
|
||||
*
|
||||
* @throws JMSException
|
||||
*/
|
||||
public Message createMessage() throws JMSException;
|
||||
|
||||
/**
|
||||
* Creates a new bytes message
|
||||
* @return the create BytesMessage
|
||||
*
|
||||
* @throws JMSException
|
||||
*/
|
||||
public BytesMessage createBytesMessage() throws JMSException;
|
||||
|
||||
/**
|
||||
* Creates a new {@link MapMessage}
|
||||
* @return the created MapMessage
|
||||
*
|
||||
* @throws JMSException
|
||||
*/
|
||||
public MapMessage createMapMessage() throws JMSException;
|
||||
|
||||
/**
|
||||
* Creates a new {@link ObjectMessage}
|
||||
* @return the created ObjectMessage
|
||||
*
|
||||
* @throws JMSException
|
||||
*/
|
||||
public ObjectMessage createObjectMessage() throws JMSException;
|
||||
|
||||
/**
|
||||
* Creates a new {@link ObjectMessage}
|
||||
*
|
||||
* @param object
|
||||
* @return the createdObjectMessage
|
||||
* @throws JMSException
|
||||
*/
|
||||
public ObjectMessage createObjectMessage(Serializable object) throws JMSException;
|
||||
|
||||
/**
|
||||
* Creates a new {@link StreamMessage}
|
||||
* @return the create StreamMessage
|
||||
*
|
||||
* @throws JMSException
|
||||
*/
|
||||
public StreamMessage createStreamMessage() throws JMSException;
|
||||
|
||||
/**
|
||||
* Creates a new {@link TextMessage}
|
||||
* @return the create TextMessage
|
||||
*
|
||||
* @throws JMSException
|
||||
*/
|
||||
public TextMessage createTextMessage() throws JMSException;
|
||||
|
||||
/**
|
||||
* Creates a new {@link TextMessage}
|
||||
*
|
||||
* @param text
|
||||
* @return the create TextMessage
|
||||
* @throws JMSException
|
||||
*/
|
||||
public TextMessage createTextMessage(String text) throws JMSException;
|
||||
|
||||
/**
|
||||
* Create a named Destination
|
||||
* @param name
|
||||
* @return the Destinatiion
|
||||
* @throws JMSException
|
||||
*/
|
||||
public Destination createDestination(String name) throws JMSException;
|
||||
|
||||
/**
|
||||
* wait until a the cardimality of the cluster is reaches the expected count. This method will return false if the
|
||||
* cluster isn't started or stopped while waiting
|
||||
*
|
||||
* @param expectedCount the number of expected members of a cluster
|
||||
* @param timeout timeout in milliseconds
|
||||
* @return true if the cluster is fully connected
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
boolean waitForClusterToComplete(int expectedCount, long timeout) throws InterruptedException;
|
||||
}
|
|
@ -1,150 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* 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.activecluster;
|
||||
import java.io.Externalizable;
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInput;
|
||||
import java.io.ObjectOutput;
|
||||
|
||||
/**
|
||||
* A cluster event
|
||||
*
|
||||
* @version $Revision: 1.3 $
|
||||
*/
|
||||
public class ClusterEvent implements Externalizable {
|
||||
|
||||
private static final long serialVersionUID=-4103732679231950873L;
|
||||
/**
|
||||
* A node has joined the cluster
|
||||
*/
|
||||
public static final int ADD_NODE = 1;
|
||||
/**
|
||||
* existing node has updated it's state
|
||||
*/
|
||||
public static final int UPDATE_NODE = 2;
|
||||
/**
|
||||
* A node has left the Cluster
|
||||
*/
|
||||
public static final int REMOVE_NODE = 3;
|
||||
/**
|
||||
* A node has failed due to a system/network error
|
||||
*/
|
||||
public static final int FAILED_NODE = 4;
|
||||
|
||||
/**
|
||||
* this node has been elected Coordinator
|
||||
*/
|
||||
public static final int ELECTED_COORDINATOR = 5;
|
||||
|
||||
private transient Cluster cluster;
|
||||
private Node node;
|
||||
private int type;
|
||||
|
||||
/**
|
||||
* empty constructor
|
||||
*/
|
||||
public ClusterEvent() {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param source
|
||||
* @param node
|
||||
* @param type
|
||||
*/
|
||||
public ClusterEvent(Cluster source, Node node, int type) {
|
||||
this.cluster = source;
|
||||
this.node = node;
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the Cluster
|
||||
*/
|
||||
public Cluster getCluster() {
|
||||
return cluster;
|
||||
}
|
||||
|
||||
/**
|
||||
* set the cluster
|
||||
* @param source
|
||||
*/
|
||||
public void setCluster(Cluster source){
|
||||
this.cluster = source;
|
||||
}
|
||||
/**
|
||||
* @return the node
|
||||
*/
|
||||
public Node getNode() {
|
||||
return node;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the type of event
|
||||
*/
|
||||
public int getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return pretty type
|
||||
*/
|
||||
public String toString() {
|
||||
return "ClusterEvent[" + getTypeAsString() + " : " + node + "]";
|
||||
}
|
||||
|
||||
/**
|
||||
* dump on to a stream
|
||||
*
|
||||
* @param out
|
||||
* @throws IOException
|
||||
*/
|
||||
public void writeExternal(ObjectOutput out) throws IOException {
|
||||
out.writeByte(type);
|
||||
out.writeObject(node);
|
||||
}
|
||||
|
||||
/**
|
||||
* read from stream
|
||||
*
|
||||
* @param in
|
||||
* @throws IOException
|
||||
* @throws ClassNotFoundException
|
||||
*/
|
||||
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
|
||||
type = in.readByte();
|
||||
node = (Node) in.readObject();
|
||||
}
|
||||
|
||||
private String getTypeAsString() {
|
||||
String result = "unknown type";
|
||||
if (type == ADD_NODE) {
|
||||
result = "ADD_NODE";
|
||||
}
|
||||
else if (type == REMOVE_NODE) {
|
||||
result = "REMOVE_NODE";
|
||||
}
|
||||
else if (type == UPDATE_NODE) {
|
||||
result = "UPDATE_NODE";
|
||||
}
|
||||
else if (type == FAILED_NODE) {
|
||||
result = "FAILED_NODE";
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
|
@ -1,28 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* 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.activecluster;
|
||||
|
||||
|
||||
/**
|
||||
* Represents a Cluster related exception
|
||||
*
|
||||
* @version $Revision: 1.2 $
|
||||
*/
|
||||
public class ClusterException extends Exception {
|
||||
}
|
|
@ -1,94 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* 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.activecluster;
|
||||
|
||||
import javax.jms.Destination;
|
||||
import javax.jms.JMSException;
|
||||
|
||||
|
||||
/**
|
||||
* A Factory of Cluster instances
|
||||
*
|
||||
* @version $Revision: 1.3 $
|
||||
*/
|
||||
public interface ClusterFactory {
|
||||
|
||||
/**
|
||||
* Creates a new cluster connection using the given local name and destination name
|
||||
* @param localName
|
||||
* @param destinationName
|
||||
*
|
||||
* @return Cluster
|
||||
* @throws JMSException
|
||||
*/
|
||||
public Cluster createCluster(String localName,String destinationName) throws JMSException;
|
||||
|
||||
/**
|
||||
* Creates a new cluster connection using the given local name and destination name
|
||||
* @param localName
|
||||
* @param destinationName
|
||||
* @param marshaller
|
||||
*
|
||||
* @return Cluster
|
||||
* @throws JMSException
|
||||
*/
|
||||
public Cluster createCluster(String localName,String destinationName,DestinationMarshaller marshaller) throws JMSException;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new cluster connection - generating the localName automatically
|
||||
* @param destinationName
|
||||
* @return the Cluster
|
||||
* @throws JMSException
|
||||
*/
|
||||
public Cluster createCluster(String destinationName) throws JMSException;
|
||||
|
||||
/**
|
||||
* Creates a new cluster connection using the given local name and destination name
|
||||
* @param localName
|
||||
* @param destination
|
||||
*
|
||||
* @return Cluster
|
||||
* @throws JMSException
|
||||
*/
|
||||
public Cluster createCluster(String localName,Destination destination) throws JMSException;
|
||||
|
||||
/**
|
||||
* Creates a new cluster connection using the given local name and destination name
|
||||
* @param localName
|
||||
* @param destination
|
||||
* @param marshaller
|
||||
*
|
||||
* @return Cluster
|
||||
* @throws JMSException
|
||||
*/
|
||||
public Cluster createCluster(String localName,Destination destination, DestinationMarshaller marshaller) throws JMSException;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new cluster connection - generating the localName automatically
|
||||
* @param destination
|
||||
* @return the Cluster
|
||||
* @throws JMSException
|
||||
*/
|
||||
public Cluster createCluster(Destination destination) throws JMSException;
|
||||
}
|
|
@ -1,64 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* 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.activecluster;
|
||||
|
||||
import java.util.EventListener;
|
||||
|
||||
|
||||
/**
|
||||
* Listener to events occuring on the cluster
|
||||
*
|
||||
* @version $Revision: 1.2 $
|
||||
*/
|
||||
public interface ClusterListener extends EventListener {
|
||||
|
||||
/**
|
||||
* A new node has been added
|
||||
*
|
||||
* @param event
|
||||
*/
|
||||
public void onNodeAdd(ClusterEvent event);
|
||||
|
||||
/**
|
||||
* A node has updated its state
|
||||
*
|
||||
* @param event
|
||||
*/
|
||||
public void onNodeUpdate(ClusterEvent event);
|
||||
|
||||
/**
|
||||
* A node has been removed (a clean shutdown)
|
||||
*
|
||||
* @param event
|
||||
*/
|
||||
public void onNodeRemoved(ClusterEvent event);
|
||||
|
||||
/**
|
||||
* A node has failed due to process or network failure
|
||||
*
|
||||
* @param event
|
||||
*/
|
||||
public void onNodeFailed(ClusterEvent event);
|
||||
|
||||
/**
|
||||
* An election has occurred and a new coordinator has been selected
|
||||
* @param event
|
||||
*/
|
||||
public void onCoordinatorChanged(ClusterEvent event);
|
||||
}
|
|
@ -1,46 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* 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.activecluster;
|
||||
|
||||
import javax.jms.Destination;
|
||||
import javax.jms.JMSException;
|
||||
|
||||
/**
|
||||
* A simple marshaller for Destinations
|
||||
*
|
||||
* @version $Revision: 1.5 $
|
||||
*/
|
||||
public interface DestinationMarshaller {
|
||||
|
||||
/**
|
||||
* Builds a destination from a destinationName
|
||||
* @param destinationName
|
||||
*
|
||||
* @return the destination to send messages to all members of the cluster
|
||||
*/
|
||||
public Destination getDestination(String destinationName) throws JMSException;
|
||||
|
||||
/**
|
||||
* Gets a destination's physical name
|
||||
* @param destination
|
||||
* @return the destination's physical name
|
||||
*/
|
||||
public String getDestinationName(Destination destination);
|
||||
}
|
|
@ -1,38 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* 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.activecluster;
|
||||
|
||||
import javax.jms.JMSException;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Represents the local (in process) node
|
||||
*
|
||||
* @version $Revision: 1.2 $
|
||||
*/
|
||||
public interface LocalNode extends Node {
|
||||
|
||||
/**
|
||||
* Allows the local state to be modified, which will
|
||||
* be replicated asynchronously around the cluster
|
||||
* @param state
|
||||
* @throws JMSException
|
||||
*/
|
||||
public void setState(Map state) throws JMSException;
|
||||
|
||||
}
|
|
@ -1,59 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* 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.activecluster;
|
||||
|
||||
import java.util.Map;
|
||||
import javax.jms.Destination;
|
||||
|
||||
|
||||
/**
|
||||
* Represents a node member in a cluster
|
||||
*
|
||||
* @version $Revision: 1.3 $
|
||||
*/
|
||||
public interface Node {
|
||||
|
||||
/**
|
||||
* Access to the queue to send messages direct to this node.
|
||||
*
|
||||
* @return the destination to send messages to this node while its available
|
||||
*/
|
||||
public Destination getDestination();
|
||||
|
||||
/**
|
||||
* @return an immutable map of the nodes state
|
||||
*/
|
||||
public Map getState();
|
||||
|
||||
/**
|
||||
* @return the name of the node
|
||||
*/
|
||||
public String getName();
|
||||
|
||||
/**
|
||||
* @return true if this node has been elected as coordinator
|
||||
*/
|
||||
public boolean isCoordinator();
|
||||
|
||||
/**
|
||||
* Returns the Zone of this node - typically the DMZ zone or the subnet on which the
|
||||
* node is on
|
||||
*/
|
||||
public Object getZone();
|
||||
}
|
|
@ -1,42 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* 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.activecluster;
|
||||
|
||||
import javax.jms.JMSException;
|
||||
|
||||
/**
|
||||
* <p><code>Service</code> represents some service of some kind with a simple start/stop lifecycle.</p>
|
||||
*
|
||||
* @version $Revision: 1.2 $
|
||||
*/
|
||||
public interface Service {
|
||||
|
||||
/**
|
||||
* Called to start the service
|
||||
* @throws JMSException
|
||||
*/
|
||||
public void start() throws JMSException;
|
||||
|
||||
/**
|
||||
* Called to shutdown the service
|
||||
* @throws JMSException
|
||||
*/
|
||||
public void stop() throws JMSException;
|
||||
|
||||
}
|
|
@ -1,40 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* 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.activecluster.election;
|
||||
|
||||
import javax.jms.JMSException;
|
||||
|
||||
import org.apache.activecluster.Cluster;
|
||||
import org.apache.activecluster.Node;
|
||||
|
||||
/**
|
||||
* <p><code>Service</code> Used by the Cluster to elect a coordinator.</p>
|
||||
*
|
||||
* @version $Revision: 1.2 $
|
||||
*/
|
||||
public interface ElectionStrategy {
|
||||
|
||||
/**
|
||||
* Elect a coordinator.
|
||||
* @param cluster
|
||||
* @return the elected Node
|
||||
* @throws JMSException
|
||||
*/
|
||||
public Node doElection(Cluster cluster) throws JMSException;
|
||||
|
||||
}
|
|
@ -1,58 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* 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.activecluster.election.impl;
|
||||
|
||||
import org.apache.activecluster.Cluster;
|
||||
import org.apache.activecluster.Node;
|
||||
import org.apache.activecluster.election.ElectionStrategy;
|
||||
|
||||
import javax.jms.JMSException;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* <p><code>BullyElectionStrategy</code> Use a simple bully algorithm to elect a coordinator.
|
||||
* the member with the lowest lexicographical name is choosen</p>
|
||||
*
|
||||
* @version $Revision: 1.2 $
|
||||
*/
|
||||
public class BullyElectionStrategy implements ElectionStrategy {
|
||||
|
||||
/**
|
||||
* Elect a coordinator.
|
||||
*
|
||||
* @param cluster
|
||||
* @return the elected Node
|
||||
* @throws JMSException
|
||||
*/
|
||||
public Node doElection(Cluster cluster) throws JMSException {
|
||||
Node elect = cluster.getLocalNode();
|
||||
|
||||
Map nodes = cluster.getNodes();
|
||||
for (Iterator i = nodes.values().iterator(); i.hasNext();) {
|
||||
Node node = (Node) i.next();
|
||||
if (elect.getName().compareTo(node.getName()) < 0) {
|
||||
elect = node;
|
||||
}
|
||||
}
|
||||
|
||||
return elect;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,46 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* 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.activecluster.group;
|
||||
|
||||
import org.apache.activecluster.Node;
|
||||
|
||||
/**
|
||||
* A kind of {@link GroupModel} in which every {@link Node} has its
|
||||
* own {@link Group} and other nodes in the cluster act as buddies (slaves)
|
||||
*
|
||||
* @version $Revision: 1.2 $
|
||||
*/
|
||||
public class BuddyGroupModel extends GroupModel {
|
||||
|
||||
public synchronized void addNode(Node node) {
|
||||
Group group = makeNewGroup(node);
|
||||
if (group == null) {
|
||||
if (!addToExistingGroup(node)) {
|
||||
addToUnusedNodes(node);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// now lets try choose some existing nodes to add as buddy's
|
||||
tryToFillGroupWithBuddies(group);
|
||||
|
||||
// now that the group may well be filled, add it to the collections
|
||||
addGroup(group);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,114 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* 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.activecluster.group;
|
||||
|
||||
import org.apache.activecluster.Node;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Represents a logical group of nodes in a cluster,
|
||||
* such as a Master and a number of Slaves which operate as a
|
||||
* logical unit.
|
||||
* <p/>
|
||||
* A cluster can be divided into a single group, or many groups
|
||||
* depending on the policy required.
|
||||
* <p/>
|
||||
* The number of groups could be application defined; created on demand
|
||||
* or there could even be one group for each node, with other nodes acting
|
||||
* as buddy nodes in each nodes' group (i.e. each node is a master with N
|
||||
* buddies/slaves)
|
||||
*
|
||||
* @version $Revision: 1.2 $
|
||||
*/
|
||||
public class Group {
|
||||
private int minimumMemberCount;
|
||||
private int maximumMemberCount;
|
||||
private List members = new ArrayList();
|
||||
private int memberCount;
|
||||
|
||||
public Group() {
|
||||
}
|
||||
|
||||
public Group(int minimumMemberCount, int maximumMemberCount) {
|
||||
this.minimumMemberCount = minimumMemberCount;
|
||||
this.maximumMemberCount = maximumMemberCount;
|
||||
}
|
||||
|
||||
public synchronized List getMembers() {
|
||||
return new ArrayList(members);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a node to the given group
|
||||
*
|
||||
* @return the index of the node in the group (0 = master, 1..N = slave)
|
||||
*/
|
||||
public synchronized int addMember(Node node) {
|
||||
int index = members.indexOf(node);
|
||||
if (index >= 0) {
|
||||
return index;
|
||||
}
|
||||
members.add(node);
|
||||
return memberCount++;
|
||||
}
|
||||
|
||||
public synchronized boolean removeMember(Node node) {
|
||||
boolean answer = members.remove(node);
|
||||
if (answer) {
|
||||
memberCount--;
|
||||
}
|
||||
return answer;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns true if the group is usable, that it has enough members to be used.
|
||||
*/
|
||||
public boolean isUsable() {
|
||||
return memberCount >= minimumMemberCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the group cannot accept any more new members
|
||||
*/
|
||||
public boolean isFull() {
|
||||
return memberCount >= maximumMemberCount;
|
||||
}
|
||||
|
||||
public int getMemberCount() {
|
||||
return memberCount;
|
||||
}
|
||||
|
||||
public int getMaximumMemberCount() {
|
||||
return maximumMemberCount;
|
||||
}
|
||||
|
||||
public void setMaximumMemberCount(int maximumMemberCount) {
|
||||
this.maximumMemberCount = maximumMemberCount;
|
||||
}
|
||||
|
||||
public int getMinimumMemberCount() {
|
||||
return minimumMemberCount;
|
||||
}
|
||||
|
||||
public void setMinimumMemberCount(int minimumMemberCount) {
|
||||
this.minimumMemberCount = minimumMemberCount;
|
||||
}
|
||||
}
|
|
@ -1,60 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* 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.activecluster.group;
|
||||
|
||||
import org.apache.activecluster.ClusterEvent;
|
||||
import org.apache.activecluster.ClusterListener;
|
||||
|
||||
/**
|
||||
* A {@link ClusterListener} which maintains a {@link GroupModel} implementation
|
||||
*
|
||||
* @version $Revision: 1.2 $
|
||||
*/
|
||||
public class GroupClusterListener implements ClusterListener {
|
||||
private GroupModel model;
|
||||
|
||||
public GroupClusterListener(GroupModel model) {
|
||||
this.model = model;
|
||||
}
|
||||
|
||||
// Properties
|
||||
//-------------------------------------------------------------------------
|
||||
public GroupModel getModel() {
|
||||
return model;
|
||||
}
|
||||
|
||||
// ClusterListener interface
|
||||
//-------------------------------------------------------------------------
|
||||
public void onNodeAdd(ClusterEvent event) {
|
||||
model.addNode(event.getNode());
|
||||
}
|
||||
|
||||
public void onNodeUpdate(ClusterEvent event) {
|
||||
}
|
||||
|
||||
public void onNodeRemoved(ClusterEvent event) {
|
||||
model.removeNode(event.getNode());
|
||||
}
|
||||
|
||||
public void onNodeFailed(ClusterEvent event) {
|
||||
model.removeNode(event.getNode());
|
||||
}
|
||||
|
||||
public void onCoordinatorChanged(ClusterEvent event) {
|
||||
}
|
||||
}
|
|
@ -1,330 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* 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.activecluster.group;
|
||||
|
||||
import org.apache.activecluster.Node;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Represents a collection of zero or more groups in a cluster.
|
||||
* The default implementation will create groups as nodes are added to the cluster; filling
|
||||
* the groups with its required number of buddies / slaves until a new group can be created.
|
||||
* <p/>
|
||||
* Nodes which are not allowed to be master nodes will be kept around in a pool ready to be added
|
||||
* as slaves when a new master arrives and forces the creation of a group.
|
||||
*
|
||||
* @version $Revision: 1.2 $
|
||||
* @see Group
|
||||
*/
|
||||
public class GroupModel {
|
||||
private int maximumGroups = -1;
|
||||
private int minimumMemberCount = 2;
|
||||
private int maximumMemberCount = 3;
|
||||
private List groups = new ArrayList();
|
||||
private LinkedList incompleteGroups = new LinkedList();
|
||||
private LinkedList completeGroups = new LinkedList();
|
||||
private LinkedList fullGroups = new LinkedList();
|
||||
private LinkedList unusedNodes = new LinkedList();
|
||||
private NodeFilter masterFilter;
|
||||
private Map nodeMemberships = new HashMap();
|
||||
|
||||
// allow a node to be a master and 2 buddies
|
||||
private int maximumWeighting = 10;
|
||||
|
||||
/**
|
||||
* Adds the new node to this group model; we assume the node has not been added before.
|
||||
*
|
||||
* @param node
|
||||
*/
|
||||
public synchronized void addNode(Node node) {
|
||||
if (!addToExistingGroup(node)) {
|
||||
Group group = makeNewGroup(node);
|
||||
if (group == null) {
|
||||
addToUnusedNodes(node);
|
||||
}
|
||||
else {
|
||||
addGroup(group);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the node from the group model
|
||||
*
|
||||
* @param node
|
||||
*/
|
||||
public synchronized void removeNode(Node node) {
|
||||
unusedNodes.remove(node);
|
||||
|
||||
// lets remove the node from each group
|
||||
for (Iterator iter = groups.iterator(); iter.hasNext();) {
|
||||
Group group = (Group) iter.next();
|
||||
boolean wasFull = group.isFull();
|
||||
boolean wasUsable = group.isUsable();
|
||||
|
||||
if (removeNodeFromGroup(group, node)) {
|
||||
updateGroupCollections(group, wasFull, wasUsable);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Properties
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Returns a snapshot of the groups currently available
|
||||
*/
|
||||
public synchronized List getGroups() {
|
||||
return new ArrayList(groups);
|
||||
}
|
||||
|
||||
public NodeFilter getMasterFilter() {
|
||||
return masterFilter;
|
||||
}
|
||||
|
||||
public void setMasterFilter(NodeFilter masterFilter) {
|
||||
this.masterFilter = masterFilter;
|
||||
}
|
||||
|
||||
public int getMaximumGroups() {
|
||||
return maximumGroups;
|
||||
}
|
||||
|
||||
public void setMaximumGroups(int maximumGroups) {
|
||||
this.maximumGroups = maximumGroups;
|
||||
}
|
||||
|
||||
public int getMaximumMemberCount() {
|
||||
return maximumMemberCount;
|
||||
}
|
||||
|
||||
public void setMaximumMemberCount(int maximumMemberCount) {
|
||||
this.maximumMemberCount = maximumMemberCount;
|
||||
}
|
||||
|
||||
public int getMinimumMemberCount() {
|
||||
return minimumMemberCount;
|
||||
}
|
||||
|
||||
public void setMinimumMemberCount(int minimumMemberCount) {
|
||||
this.minimumMemberCount = minimumMemberCount;
|
||||
}
|
||||
|
||||
public int getMaximumWeighting() {
|
||||
return maximumWeighting;
|
||||
}
|
||||
|
||||
public void setMaximumWeighting(int maximumWeighting) {
|
||||
this.maximumWeighting = maximumWeighting;
|
||||
}
|
||||
|
||||
|
||||
// Implementation methods
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
|
||||
/**
|
||||
* Attempt to make a new group with the current node as the master
|
||||
* or if the node cannot be a master node
|
||||
*
|
||||
* @return the newly created group or false if none was created.
|
||||
*/
|
||||
protected Group makeNewGroup(Node node) {
|
||||
// no pending groups available so lets try and create a new group
|
||||
if (canCreateGroup(node)) {
|
||||
Group group = createGroup(node);
|
||||
addNodeToGroup(group, node);
|
||||
return group;
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
protected void tryToFillGroupWithBuddies(Group group) {
|
||||
boolean continueFillingGroups = true;
|
||||
while (!group.isUsable() && continueFillingGroups) {
|
||||
continueFillingGroups = tryToAddBuddy(group);
|
||||
}
|
||||
|
||||
if (continueFillingGroups) {
|
||||
// lets try fill more unfilled nodes
|
||||
for (Iterator iter = new ArrayList(incompleteGroups).iterator(); iter.hasNext() && continueFillingGroups;) {
|
||||
group = (Group) iter.next();
|
||||
|
||||
boolean wasFull = group.isFull();
|
||||
boolean wasUsable = group.isUsable();
|
||||
|
||||
while (!group.isUsable() && continueFillingGroups) {
|
||||
continueFillingGroups = tryToAddBuddy(group);
|
||||
}
|
||||
|
||||
if (group.isUsable()) {
|
||||
updateGroupCollections(group, wasFull, wasUsable);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean tryToAddBuddy(Group group) {
|
||||
boolean continueFillingGroups = true;
|
||||
// TODO we could make this much faster using a weighting-sorted collection
|
||||
NodeMemberships lowest = null;
|
||||
int lowestWeight = 0;
|
||||
for (Iterator iter = nodeMemberships.values().iterator(); iter.hasNext();) {
|
||||
NodeMemberships memberships = (NodeMemberships) iter.next();
|
||||
if (!memberships.isMember(group)) {
|
||||
int weighting = memberships.getWeighting();
|
||||
if ((lowest == null || weighting < lowestWeight) && weighting < maximumWeighting) {
|
||||
lowest = memberships;
|
||||
lowestWeight = weighting;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (lowest == null) {
|
||||
continueFillingGroups = false;
|
||||
}
|
||||
else {
|
||||
addNodeToGroup(group, lowest.getNode());
|
||||
}
|
||||
return continueFillingGroups;
|
||||
}
|
||||
|
||||
/**
|
||||
* Lets move the group from its current state collection to the new collection if its
|
||||
* state has changed
|
||||
*/
|
||||
protected void updateGroupCollections(Group group, boolean wasFull, boolean wasUsable) {
|
||||
boolean full = group.isFull();
|
||||
if (wasFull && !full) {
|
||||
fullGroups.remove(group);
|
||||
}
|
||||
boolean usable = group.isUsable();
|
||||
if (wasUsable && !usable) {
|
||||
completeGroups.remove(group);
|
||||
}
|
||||
if ((!usable || !full) && (wasFull || wasUsable)) {
|
||||
incompleteGroups.add(group);
|
||||
}
|
||||
}
|
||||
|
||||
protected void addToUnusedNodes(Node node) {
|
||||
// lets add the node to the pool ready to be used if a node fails
|
||||
unusedNodes.add(node);
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to add the node to an incomplete group, or
|
||||
* a not-full group and returns true if its possible - else returns false
|
||||
*
|
||||
* @return true if the node has been added to a groupu
|
||||
*/
|
||||
protected boolean addToExistingGroup(Node node) {
|
||||
if (!addToIncompleteGroup(node)) {
|
||||
if (!addToNotFullGroup(node)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
protected boolean addToNotFullGroup(Node node) {
|
||||
return addToPendingGroup(completeGroups, node);
|
||||
}
|
||||
|
||||
protected boolean addToIncompleteGroup(Node node) {
|
||||
return addToPendingGroup(incompleteGroups, node);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the given node to the first pending group if possible
|
||||
*
|
||||
* @return true if the node was added to the first available group
|
||||
*/
|
||||
protected boolean addToPendingGroup(LinkedList list, Node node) {
|
||||
if (!list.isEmpty()) {
|
||||
Group group = (Group) list.getFirst();
|
||||
addNodeToGroup(group, node);
|
||||
if (group.isFull()) {
|
||||
list.removeFirst();
|
||||
fullGroups.add(group);
|
||||
}
|
||||
else if (group.isUsable()) {
|
||||
list.removeFirst();
|
||||
completeGroups.add(group);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
protected void addNodeToGroup(Group group, Node node) {
|
||||
NodeMemberships memberships = (NodeMemberships) nodeMemberships.get(node);
|
||||
if (memberships == null) {
|
||||
memberships = new NodeMemberships(node);
|
||||
nodeMemberships.put(node, memberships);
|
||||
}
|
||||
memberships.addToGroup(group);
|
||||
}
|
||||
|
||||
protected boolean removeNodeFromGroup(Group group, Node node) {
|
||||
NodeMemberships memberships = (NodeMemberships) nodeMemberships.get(node);
|
||||
if (memberships != null) {
|
||||
return memberships.removeFromGroup(group);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
protected void addGroup(Group group) {
|
||||
groups.add(group);
|
||||
if (group.isFull()) {
|
||||
fullGroups.add(group);
|
||||
}
|
||||
else if (group.isUsable()) {
|
||||
completeGroups.add(group);
|
||||
}
|
||||
else {
|
||||
incompleteGroups.add(group);
|
||||
}
|
||||
}
|
||||
|
||||
protected Group createGroup(Node node) {
|
||||
return new Group(minimumMemberCount, maximumMemberCount);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if we can add a new group to the cluster
|
||||
*/
|
||||
protected boolean canCreateGroup(Node node) {
|
||||
return (maximumGroups < 0 || groups.size() < maximumGroups) && canBeMaster(node);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the given node can be a master
|
||||
*/
|
||||
protected boolean canBeMaster(Node node) {
|
||||
return masterFilter == null || masterFilter.evaluate(node);
|
||||
}
|
||||
}
|
|
@ -1,41 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* 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.activecluster.group;
|
||||
|
||||
import org.apache.activecluster.Node;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* A filter configured with a list of DMZ zones on which to restrict which nodes
|
||||
* are allowed to be master nodes.
|
||||
*
|
||||
* @version $Revision: 1.2 $
|
||||
*/
|
||||
public class MasterZoneFilter implements NodeFilter {
|
||||
private List zones;
|
||||
|
||||
public MasterZoneFilter(List zones) {
|
||||
this.zones = zones;
|
||||
}
|
||||
|
||||
public boolean evaluate(Node node) {
|
||||
Object zone = node.getZone();
|
||||
return zones.contains(zone);
|
||||
}
|
||||
}
|
|
@ -1,64 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* 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.activecluster.group;
|
||||
|
||||
/**
|
||||
* Represents the membership of a Group for a Node
|
||||
*
|
||||
* @version $Revision: 1.2 $
|
||||
*/
|
||||
public class Membership {
|
||||
public static final int STATUS_REQUESTED = 1;
|
||||
public static final int STATUS_SYNCHONIZING = 2;
|
||||
public static final int STATUS_FAILED = 3;
|
||||
public static final int STATUS_OK = 4;
|
||||
|
||||
private Group group;
|
||||
private int index;
|
||||
private int status = STATUS_REQUESTED;
|
||||
|
||||
public Membership(Group group, int index) {
|
||||
this.group = group;
|
||||
this.index = index;
|
||||
}
|
||||
|
||||
public int getIndex() {
|
||||
return index;
|
||||
}
|
||||
|
||||
public void setIndex(int index) {
|
||||
this.index = index;
|
||||
}
|
||||
|
||||
public int getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
public void setStatus(int status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the weighting of this membership
|
||||
*/
|
||||
public int getWeighting() {
|
||||
// lets make master heavy and the further from the end of the
|
||||
// list of slaves, the lighter we become
|
||||
return group.getMaximumMemberCount() - getIndex();
|
||||
}
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* 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.activecluster.group;
|
||||
|
||||
import org.apache.activecluster.Node;
|
||||
|
||||
/**
|
||||
* Represents a filter on a Node to allow a pluggable
|
||||
* Strategy Pattern to decide which nodes can be master nodes etc.
|
||||
*
|
||||
* @version $Revision: 1.2 $
|
||||
*/
|
||||
public interface NodeFilter {
|
||||
|
||||
/**
|
||||
* Returns true if the given node matches the filter
|
||||
*/
|
||||
public boolean evaluate(Node node);
|
||||
}
|
|
@ -1,77 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* 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.activecluster.group;
|
||||
|
||||
import org.apache.activecluster.Node;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Represents all of the memberhips of a node and can be used to act
|
||||
* as a weighting to decide which is the least heavily loaded Node
|
||||
* to be assigned to a buddy group.
|
||||
*
|
||||
* @version $Revision: 1.2 $
|
||||
*/
|
||||
public class NodeMemberships {
|
||||
private Node node;
|
||||
private Map memberships = new HashMap();
|
||||
private int weighting;
|
||||
|
||||
public NodeMemberships(Node node) {
|
||||
this.node = node;
|
||||
}
|
||||
|
||||
public void addToGroup(Group group) {
|
||||
if (!isMember(group)) {
|
||||
int index = group.addMember(node);
|
||||
Membership membership = new Membership(group, index);
|
||||
memberships.put(group, membership);
|
||||
weighting += membership.getWeighting();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean removeFromGroup(Group group) {
|
||||
// TODO when we remove a node from a group, we need to reweight the
|
||||
// other nodes in the group
|
||||
|
||||
memberships.remove(group);
|
||||
return group.removeMember(node);
|
||||
}
|
||||
|
||||
public Node getNode() {
|
||||
return node;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the weighting of how heavily loaded the node is
|
||||
* so that a decision can be made on which node to buddy group
|
||||
* with
|
||||
*/
|
||||
public int getWeighting() {
|
||||
return weighting;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this node is a member of the given group
|
||||
*/
|
||||
public boolean isMember(Group group) {
|
||||
return memberships.containsKey(group);
|
||||
}
|
||||
}
|
|
@ -1,26 +0,0 @@
|
|||
<!--
|
||||
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.
|
||||
-->
|
||||
<html>
|
||||
<head>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
Contains Group Organsisation models and policies for arranging {@link org.apache.activecluster.Node} instances into
|
||||
groups, such as buddy-groups (failover nodes) or master/slave groups for High Availability (HA) protocols.
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -1,61 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* 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.activecluster.impl;
|
||||
|
||||
import org.apache.activemq.ActiveMQConnectionFactory;
|
||||
import org.apache.activecluster.impl.DefaultClusterFactory;
|
||||
|
||||
/**
|
||||
* An implementation of {@link org.apache.activecluster.ClusterFactory} using
|
||||
* <a href="http://activemq.codehaus.org/">ActiveMQ</a>
|
||||
*
|
||||
* @version $Revision: 1.4 $
|
||||
*/
|
||||
public class ActiveMQClusterFactory extends DefaultClusterFactory {
|
||||
|
||||
public static String DEFAULT_CLUSTER_URL = "peer://org.apache.activecluster?persistent=false";
|
||||
|
||||
public ActiveMQClusterFactory() {
|
||||
super(new ActiveMQConnectionFactory(DEFAULT_CLUSTER_URL));
|
||||
}
|
||||
|
||||
public ActiveMQClusterFactory(String brokerURL) {
|
||||
super(new ActiveMQConnectionFactory(brokerURL));
|
||||
}
|
||||
|
||||
public ActiveMQClusterFactory(ActiveMQConnectionFactory connectionFactory) {
|
||||
super(connectionFactory);
|
||||
}
|
||||
|
||||
public ActiveMQClusterFactory(boolean transacted, int acknowledgeMode, String dataTopicPrefix, long inactiveTime) {
|
||||
super(new ActiveMQConnectionFactory(DEFAULT_CLUSTER_URL), transacted, acknowledgeMode, dataTopicPrefix, inactiveTime);
|
||||
}
|
||||
|
||||
public ActiveMQClusterFactory(ActiveMQConnectionFactory connectionFactory, boolean transacted, int acknowledgeMode, String dataTopicPrefix, long inactiveTime) {
|
||||
super(connectionFactory, transacted, acknowledgeMode, dataTopicPrefix, inactiveTime);
|
||||
}
|
||||
|
||||
public ActiveMQConnectionFactory getActiveMQConnectionFactory() {
|
||||
return (ActiveMQConnectionFactory) getConnectionFactory();
|
||||
}
|
||||
|
||||
public void setActiveMQConnectionFactory(ActiveMQConnectionFactory connectionFactory) {
|
||||
setConnectionFactory(connectionFactory);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,233 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* 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.activecluster.impl;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Map;
|
||||
import java.util.Timer;
|
||||
import javax.jms.BytesMessage;
|
||||
import javax.jms.Connection;
|
||||
import javax.jms.Destination;
|
||||
import javax.jms.JMSException;
|
||||
import javax.jms.MapMessage;
|
||||
import javax.jms.Message;
|
||||
import javax.jms.MessageConsumer;
|
||||
import javax.jms.MessageProducer;
|
||||
import javax.jms.ObjectMessage;
|
||||
import javax.jms.Session;
|
||||
import javax.jms.StreamMessage;
|
||||
import javax.jms.TextMessage;
|
||||
|
||||
import org.apache.activecluster.Cluster;
|
||||
import org.apache.activecluster.ClusterListener;
|
||||
import org.apache.activecluster.DestinationMarshaller;
|
||||
import org.apache.activecluster.LocalNode;
|
||||
import org.apache.activecluster.Service;
|
||||
import org.apache.activecluster.election.ElectionStrategy;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import edu.emory.mathcs.backport.java.util.concurrent.atomic.*;
|
||||
/**
|
||||
* A default implementation of ActiveCluster which uses standard JMS operations
|
||||
*
|
||||
* @version $Revision: 1.6 $
|
||||
*/
|
||||
public class DefaultCluster implements Cluster {
|
||||
|
||||
private final static Log log = LogFactory.getLog(DefaultCluster.class);
|
||||
|
||||
private StateServiceImpl stateService;
|
||||
private LocalNode localNode;
|
||||
private Destination destination;
|
||||
private Connection connection;
|
||||
private Session session;
|
||||
private MessageProducer producer;
|
||||
private MessageConsumer consumer;
|
||||
private Timer timer;
|
||||
private DestinationMarshaller marshaller;
|
||||
private AtomicBoolean started = new AtomicBoolean(false);
|
||||
private Object clusterLock = new Object();
|
||||
|
||||
/**
|
||||
* Construct this beast
|
||||
* @param localNode
|
||||
* @param dataDestination
|
||||
* @param destination
|
||||
* @param marshaller
|
||||
* @param connection
|
||||
* @param session
|
||||
* @param producer
|
||||
* @param timer
|
||||
* @param inactiveTime
|
||||
* @throws JMSException
|
||||
*/
|
||||
public DefaultCluster(final LocalNode localNode,Destination dataDestination,Destination destination,
|
||||
DestinationMarshaller marshaller,Connection connection,Session session,MessageProducer producer,
|
||||
Timer timer,long inactiveTime) throws JMSException{
|
||||
this.localNode=localNode;
|
||||
this.destination=destination;
|
||||
this.marshaller=marshaller;
|
||||
this.connection=connection;
|
||||
this.session=session;
|
||||
this.producer=producer;
|
||||
this.timer=timer;
|
||||
if(producer==null){
|
||||
throw new IllegalArgumentException("No producer specified!");
|
||||
}
|
||||
// now lets subscribe the service to the updates from the data topic
|
||||
consumer=session.createConsumer(dataDestination,null,true);
|
||||
log.info("Creating data consumer on topic: "+dataDestination);
|
||||
this.stateService=new StateServiceImpl(this,clusterLock,new Runnable(){
|
||||
public void run(){
|
||||
if(localNode instanceof ReplicatedLocalNode){
|
||||
((ReplicatedLocalNode) localNode).pingRemoteNodes();
|
||||
}
|
||||
}
|
||||
},timer,inactiveTime);
|
||||
consumer.setMessageListener(new StateConsumer(stateService,marshaller));
|
||||
}
|
||||
|
||||
public void addClusterListener(ClusterListener listener) {
|
||||
stateService.addClusterListener(listener);
|
||||
}
|
||||
|
||||
public void removeClusterListener(ClusterListener listener) {
|
||||
stateService.removeClusterListener(listener);
|
||||
}
|
||||
|
||||
public Destination getDestination() {
|
||||
return destination;
|
||||
}
|
||||
|
||||
public LocalNode getLocalNode() {
|
||||
return localNode;
|
||||
}
|
||||
|
||||
public Map getNodes() {
|
||||
return stateService.getNodes();
|
||||
}
|
||||
|
||||
public void setElectionStrategy(ElectionStrategy strategy) {
|
||||
stateService.setElectionStrategy(strategy);
|
||||
}
|
||||
|
||||
|
||||
public void send(Destination replyTo, Message message) throws JMSException{
|
||||
producer.send(replyTo,message);
|
||||
}
|
||||
|
||||
public MessageConsumer createConsumer(Destination destination) throws JMSException {
|
||||
return getSession().createConsumer(destination);
|
||||
}
|
||||
|
||||
public MessageConsumer createConsumer(Destination destination, String selector) throws JMSException {
|
||||
return getSession().createConsumer(destination, selector);
|
||||
}
|
||||
|
||||
public MessageConsumer createConsumer(Destination destination, String selector, boolean noLocal) throws JMSException {
|
||||
return getSession().createConsumer(destination, selector, noLocal);
|
||||
}
|
||||
|
||||
public Message createMessage() throws JMSException {
|
||||
return getSession().createMessage();
|
||||
}
|
||||
|
||||
public BytesMessage createBytesMessage() throws JMSException {
|
||||
return getSession().createBytesMessage();
|
||||
}
|
||||
|
||||
public MapMessage createMapMessage() throws JMSException {
|
||||
return getSession().createMapMessage();
|
||||
}
|
||||
|
||||
public ObjectMessage createObjectMessage() throws JMSException {
|
||||
return getSession().createObjectMessage();
|
||||
}
|
||||
|
||||
public ObjectMessage createObjectMessage(Serializable object) throws JMSException {
|
||||
return getSession().createObjectMessage(object);
|
||||
}
|
||||
|
||||
public StreamMessage createStreamMessage() throws JMSException {
|
||||
return getSession().createStreamMessage();
|
||||
}
|
||||
|
||||
public TextMessage createTextMessage() throws JMSException {
|
||||
return getSession().createTextMessage();
|
||||
}
|
||||
|
||||
public TextMessage createTextMessage(String text) throws JMSException {
|
||||
return getSession().createTextMessage(text);
|
||||
}
|
||||
|
||||
public void start() throws JMSException {
|
||||
if (started.compareAndSet(false, true)) {
|
||||
connection.start();
|
||||
}
|
||||
}
|
||||
|
||||
public void stop() throws JMSException {
|
||||
try {
|
||||
if (localNode instanceof Service) {
|
||||
((Service) localNode).stop();
|
||||
}
|
||||
timer.cancel();
|
||||
session.close();
|
||||
connection.stop();
|
||||
connection.close();
|
||||
}
|
||||
finally {
|
||||
connection = null;
|
||||
session = null;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean waitForClusterToComplete(int expectedCount, long timeout) throws InterruptedException {
|
||||
timeout = timeout > 0 ? timeout : Long.MAX_VALUE;
|
||||
long increment = 500;
|
||||
increment = increment < timeout ? increment : timeout;
|
||||
long waitTime = timeout;
|
||||
long start = System.currentTimeMillis();
|
||||
synchronized (clusterLock) {
|
||||
while (stateService.getNodes().size() < expectedCount && started.get() && waitTime > 0) {
|
||||
clusterLock.wait(increment);
|
||||
waitTime = timeout - (System.currentTimeMillis() - start);
|
||||
}
|
||||
}
|
||||
return stateService.getNodes().size() >= expectedCount;
|
||||
}
|
||||
|
||||
protected Session getSession() throws JMSException {
|
||||
if (session == null) {
|
||||
throw new JMSException("Cannot perform operation, this cluster connection is now closed");
|
||||
}
|
||||
return session;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a named Destination
|
||||
* @param name
|
||||
* @return the Destinatiion
|
||||
* @throws JMSException
|
||||
*/
|
||||
public Destination createDestination(String name) throws JMSException{
|
||||
Destination result = getSession().createTopic(name);
|
||||
return result;
|
||||
}
|
||||
}
|
|
@ -1,196 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* 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.activecluster.impl;
|
||||
|
||||
import java.util.Timer;
|
||||
import javax.jms.Connection;
|
||||
import javax.jms.ConnectionFactory;
|
||||
import javax.jms.DeliveryMode;
|
||||
import javax.jms.Destination;
|
||||
import javax.jms.JMSException;
|
||||
import javax.jms.MessageProducer;
|
||||
import javax.jms.Session;
|
||||
import javax.jms.Topic;
|
||||
import org.apache.activemq.util.IdGenerator;
|
||||
import org.apache.activecluster.Cluster;
|
||||
import org.apache.activecluster.ClusterException;
|
||||
import org.apache.activecluster.ClusterFactory;
|
||||
import org.apache.activecluster.DestinationMarshaller;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
/**
|
||||
* A Factory of DefaultCluster instances
|
||||
*
|
||||
* @version $Revision: 1.4 $
|
||||
*/
|
||||
public class DefaultClusterFactory implements ClusterFactory {
|
||||
|
||||
private final static Log log = LogFactory.getLog(DefaultClusterFactory.class);
|
||||
|
||||
private ConnectionFactory connectionFactory;
|
||||
private boolean transacted;
|
||||
private int acknowledgeMode;
|
||||
private String dataTopicPrefix;
|
||||
private long inactiveTime;
|
||||
private boolean useQueueForInbox = false;
|
||||
private int deliveryMode = DeliveryMode.NON_PERSISTENT;
|
||||
private IdGenerator idGenerator = new IdGenerator();
|
||||
|
||||
public DefaultClusterFactory(ConnectionFactory connectionFactory, boolean transacted, int acknowledgeMode, String dataTopicPrefix, long inactiveTime) {
|
||||
this.connectionFactory = connectionFactory;
|
||||
this.transacted = transacted;
|
||||
this.acknowledgeMode = acknowledgeMode;
|
||||
this.dataTopicPrefix = dataTopicPrefix;
|
||||
this.inactiveTime = inactiveTime;
|
||||
}
|
||||
|
||||
public DefaultClusterFactory(ConnectionFactory connectionFactory) {
|
||||
this(connectionFactory, false, Session.AUTO_ACKNOWLEDGE, "ACTIVECLUSTER.DATA.", 6000L);
|
||||
}
|
||||
|
||||
public Cluster createCluster(Destination groupDestination) throws JMSException {
|
||||
return createCluster(idGenerator.generateId(), groupDestination);
|
||||
}
|
||||
|
||||
public Cluster createCluster(String name,Destination groupDestination) throws JMSException {
|
||||
Connection connection = getConnectionFactory().createConnection();
|
||||
Session session = createSession(connection);
|
||||
return createCluster(connection, session, name,groupDestination,new DefaultDestinationMarshaller(session));
|
||||
}
|
||||
|
||||
public Cluster createCluster(String name,Destination groupDestination,DestinationMarshaller marshaller) throws JMSException {
|
||||
Connection connection = getConnectionFactory().createConnection();
|
||||
Session session = createSession(connection);
|
||||
return createCluster(connection, session, name,groupDestination,marshaller);
|
||||
}
|
||||
|
||||
|
||||
public Cluster createCluster(String name,String groupDestinationName) throws JMSException{
|
||||
Connection connection = getConnectionFactory().createConnection();
|
||||
Session session = createSession(connection);
|
||||
return createCluster(connection, session, name,session.createTopic(groupDestinationName),new DefaultDestinationMarshaller(session));
|
||||
}
|
||||
|
||||
public Cluster createCluster(String name,String groupDestinationName,DestinationMarshaller marshaller) throws JMSException{
|
||||
Connection connection = getConnectionFactory().createConnection();
|
||||
Session session = createSession(connection);
|
||||
return createCluster(connection, session, name,session.createTopic(groupDestinationName),marshaller);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public Cluster createCluster(String groupDestinationName) throws JMSException{
|
||||
return createCluster(idGenerator.generateId(), groupDestinationName);
|
||||
}
|
||||
|
||||
|
||||
// Properties
|
||||
//-------------------------------------------------------------------------
|
||||
public String getDataTopicPrefix() {
|
||||
return dataTopicPrefix;
|
||||
}
|
||||
|
||||
public void setDataTopicPrefix(String dataTopicPrefix) {
|
||||
this.dataTopicPrefix = dataTopicPrefix;
|
||||
}
|
||||
|
||||
public int getAcknowledgeMode() {
|
||||
return acknowledgeMode;
|
||||
}
|
||||
|
||||
public void setAcknowledgeMode(int acknowledgeMode) {
|
||||
this.acknowledgeMode = acknowledgeMode;
|
||||
}
|
||||
|
||||
public long getInactiveTime() {
|
||||
return inactiveTime;
|
||||
}
|
||||
|
||||
public void setInactiveTime(long inactiveTime) {
|
||||
this.inactiveTime = inactiveTime;
|
||||
}
|
||||
|
||||
public boolean isTransacted() {
|
||||
return transacted;
|
||||
}
|
||||
|
||||
public void setTransacted(boolean transacted) {
|
||||
this.transacted = transacted;
|
||||
}
|
||||
|
||||
public boolean isUseQueueForInbox() {
|
||||
return useQueueForInbox;
|
||||
}
|
||||
|
||||
public void setUseQueueForInbox(boolean useQueueForInbox) {
|
||||
this.useQueueForInbox = useQueueForInbox;
|
||||
}
|
||||
|
||||
public ConnectionFactory getConnectionFactory() {
|
||||
return connectionFactory;
|
||||
}
|
||||
|
||||
public void setConnectionFactory(ConnectionFactory connectionFactory) {
|
||||
this.connectionFactory = connectionFactory;
|
||||
}
|
||||
|
||||
public int getDeliveryMode() {
|
||||
return deliveryMode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the delivery mode of the group based producer
|
||||
*/
|
||||
public void setDeliveryMode(int deliveryMode) {
|
||||
this.deliveryMode = deliveryMode;
|
||||
}
|
||||
|
||||
public Cluster createCluster(Connection connection,Session session,String name,Destination groupDestination,
|
||||
DestinationMarshaller marshaller) throws JMSException{
|
||||
String dataDestination = dataTopicPrefix + marshaller.getDestinationName(groupDestination);
|
||||
log.info("Creating cluster group producer on topic: "+groupDestination);
|
||||
MessageProducer producer=createProducer(session,null);
|
||||
producer.setDeliveryMode(deliveryMode);
|
||||
log.info("Creating cluster data producer on data destination: "+dataDestination);
|
||||
Topic dataTopic=session.createTopic(dataDestination);
|
||||
MessageProducer keepAliveProducer=session.createProducer(dataTopic);
|
||||
keepAliveProducer.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
|
||||
StateService serviceStub=new StateServiceStub(session,keepAliveProducer,marshaller);
|
||||
Destination localInboxDestination=session.createTopic(dataDestination+"."+name);
|
||||
ReplicatedLocalNode localNode=new ReplicatedLocalNode(name,localInboxDestination,serviceStub);
|
||||
Timer timer=new Timer();
|
||||
DefaultCluster answer=new DefaultCluster(localNode,dataTopic,groupDestination,marshaller,connection,session,
|
||||
producer,timer,inactiveTime);
|
||||
return answer;
|
||||
}
|
||||
|
||||
/*
|
||||
* protected Cluster createInternalCluster(Session session, Topic dataDestination) { MessageProducer producer =
|
||||
* createProducer(session); return new DefaultCluster(new NonReplicatedLocalNode(), dataDestination, connection,
|
||||
* session, producer); }
|
||||
*/
|
||||
|
||||
protected MessageProducer createProducer(Session session, Topic groupDestination) throws JMSException {
|
||||
return session.createProducer(groupDestination);
|
||||
}
|
||||
|
||||
protected Session createSession(Connection connection) throws JMSException {
|
||||
return connection.createSession(transacted, acknowledgeMode);
|
||||
}
|
||||
}
|
|
@ -1,100 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* 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.activecluster.impl;
|
||||
|
||||
|
||||
|
||||
import java.util.Map;
|
||||
import javax.jms.Destination;
|
||||
import javax.jms.JMSException;
|
||||
import javax.jms.Queue;
|
||||
import javax.jms.Session;
|
||||
import javax.jms.Topic;
|
||||
|
||||
import org.apache.activecluster.DestinationMarshaller;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import edu.emory.mathcs.backport.java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
* A simple marshaller for Destinations
|
||||
*
|
||||
* @version $Revision: 1.5 $
|
||||
*/
|
||||
public class DefaultDestinationMarshaller implements DestinationMarshaller {
|
||||
private final static Log log = LogFactory.getLog(DefaultDestinationMarshaller.class);
|
||||
|
||||
/**
|
||||
* Keep a cache of name to destination mappings for fast lookup.
|
||||
*/
|
||||
private final Map destinations = new ConcurrentHashMap();
|
||||
/**
|
||||
* The active session used to create a new Destination from a name.
|
||||
*/
|
||||
private final Session session;
|
||||
|
||||
/**
|
||||
* Create a marshaller for this specific session.
|
||||
* @param session the session to use when mapping destinations.
|
||||
*/
|
||||
public DefaultDestinationMarshaller(Session session) {
|
||||
this.session = session;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a destination from a destinationName
|
||||
* @param destinationName
|
||||
*
|
||||
* @return the destination to send messages to all members of the cluster
|
||||
*/
|
||||
public Destination getDestination(String destinationName) throws JMSException {
|
||||
if (!destinations.containsKey(destinationName)) {
|
||||
destinations.put(destinationName, session.createTopic(destinationName));
|
||||
}
|
||||
return (Destination) destinations.get(destinationName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a destination's physical name
|
||||
* @param destination
|
||||
* @return the destination's physical name
|
||||
*/
|
||||
public String getDestinationName(Destination destination){
|
||||
String result = null;
|
||||
if (destination != null){
|
||||
if (destination instanceof Topic){
|
||||
Topic topic = (Topic) destination;
|
||||
try{
|
||||
result = topic.getTopicName();
|
||||
}catch(JMSException e){
|
||||
log.error("Failed to get topic name for " + destination,e);
|
||||
}
|
||||
}else{
|
||||
Queue queue = (Queue) destination;
|
||||
try{
|
||||
result = queue.getQueueName();
|
||||
}catch(JMSException e){
|
||||
log.error("Failed to get queue name for " + destination,e);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
|
@ -1,150 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* 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.activecluster.impl;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInput;
|
||||
import java.io.ObjectOutput;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import javax.jms.Destination;
|
||||
import javax.jms.JMSException;
|
||||
|
||||
import org.apache.activecluster.DestinationMarshaller;
|
||||
import org.apache.activecluster.Node;
|
||||
|
||||
|
||||
/**
|
||||
* Default implementation of a remote Node
|
||||
*
|
||||
* @version $Revision: 1.3 $
|
||||
*/
|
||||
public class NodeImpl implements Node{
|
||||
private static final long serialVersionUID=-3909792803360045064L;
|
||||
private String name;
|
||||
private Destination destination;
|
||||
protected Map state;
|
||||
protected boolean coordinator;
|
||||
|
||||
|
||||
/**
|
||||
* Construct an Node from a NodeState
|
||||
* @param nodeState
|
||||
* @param marshaller
|
||||
* @throws JMSException
|
||||
*/
|
||||
public NodeImpl(NodeState nodeState,DestinationMarshaller marshaller) throws JMSException{
|
||||
this(nodeState.getName(),marshaller.getDestination(nodeState.getDestinationName()),nodeState.getState());
|
||||
}
|
||||
/**
|
||||
* Allow a node to be copied for sending it as a message
|
||||
*
|
||||
* @param node
|
||||
*/
|
||||
public NodeImpl(Node node) {
|
||||
this(node.getName(),node.getDestination(), node.getState());
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a Node
|
||||
* @param name
|
||||
* @param destination
|
||||
*/
|
||||
public NodeImpl(String name,Destination destination) {
|
||||
this(name,destination, new HashMap());
|
||||
}
|
||||
|
||||
/**
|
||||
* Create A Node
|
||||
* @param name
|
||||
* @param destination
|
||||
* @param state
|
||||
*/
|
||||
public NodeImpl(String name,Destination destination, Map state) {
|
||||
this.name = name;
|
||||
this.destination = destination;
|
||||
this.state = state;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the name of the node
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return pretty print of the node
|
||||
*/
|
||||
public String toString() {
|
||||
return "Node[<" + name + ">destination: " + destination + " state: " + state + "]";
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the destination of the node
|
||||
*/
|
||||
public Destination getDestination() {
|
||||
return destination;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the State
|
||||
* @return the State of the Node
|
||||
*/
|
||||
public synchronized Map getState() {
|
||||
return new HashMap(state);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return true if this node has been elected as coordinator
|
||||
*/
|
||||
public boolean isCoordinator() {
|
||||
return coordinator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the zone
|
||||
* @return the Zone
|
||||
*/
|
||||
public Object getZone() {
|
||||
return state.get("zone");
|
||||
}
|
||||
|
||||
// Implementation methods
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
protected synchronized void setState(Map state) {
|
||||
this.state = state;
|
||||
}
|
||||
|
||||
protected void setCoordinator(boolean value) {
|
||||
coordinator = value;
|
||||
}
|
||||
|
||||
public void writeExternal(ObjectOutput out) throws IOException{
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
public void readExternal(ObjectInput in) throws IOException,ClassNotFoundException{
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
}
|
|
@ -1,153 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* 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.activecluster.impl;
|
||||
|
||||
import java.io.Externalizable;
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInput;
|
||||
import java.io.ObjectOutput;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.activecluster.DestinationMarshaller;
|
||||
import org.apache.activecluster.Node;
|
||||
/**
|
||||
* Default implementation of a remote Node
|
||||
*
|
||||
* @version $Revision: 1.3 $
|
||||
*/
|
||||
public class NodeState implements Externalizable{
|
||||
private static final long serialVersionUID=-3909792803360045064L;
|
||||
private String name;
|
||||
private String destinationName;
|
||||
protected Map state;
|
||||
protected boolean coordinator;
|
||||
|
||||
/**
|
||||
* DefaultConstructor
|
||||
*
|
||||
*/
|
||||
public NodeState(){
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a NodeState from a Node
|
||||
* @param node
|
||||
* @param marshaller
|
||||
*/
|
||||
public NodeState(Node node, DestinationMarshaller marshaller){
|
||||
this.name = node.getName();
|
||||
this.destinationName = marshaller.getDestinationName(node.getDestination());
|
||||
this.state = node.getState();
|
||||
this.coordinator = node.isCoordinator();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return pretty print of the node
|
||||
*/
|
||||
public String toString(){
|
||||
return "NodeState[<"+name+">destinationName: "+destinationName+" state: "+state+"]";
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Returns the coordinator.
|
||||
*/
|
||||
public boolean isCoordinator(){
|
||||
return coordinator;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param coordinator
|
||||
* The coordinator to set.
|
||||
*/
|
||||
public void setCoordinator(boolean coordinator){
|
||||
this.coordinator=coordinator;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Returns the destinationName.
|
||||
*/
|
||||
public String getDestinationName(){
|
||||
return destinationName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param destinationName
|
||||
* The destinationName to set.
|
||||
*/
|
||||
public void setDestinationName(String destinationName){
|
||||
this.destinationName=destinationName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Returns the name.
|
||||
*/
|
||||
public String getName(){
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param name
|
||||
* The name to set.
|
||||
*/
|
||||
public void setName(String name){
|
||||
this.name=name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Returns the state.
|
||||
*/
|
||||
public Map getState(){
|
||||
return state;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param state
|
||||
* The state to set.
|
||||
*/
|
||||
public void setState(Map state){
|
||||
this.state=state;
|
||||
}
|
||||
|
||||
/**
|
||||
* write to a stream
|
||||
*
|
||||
* @param out
|
||||
* @throws IOException
|
||||
*/
|
||||
public void writeExternal(ObjectOutput out) throws IOException{
|
||||
out.writeUTF((name!=null?name:""));
|
||||
out.writeUTF((destinationName!=null?destinationName:""));
|
||||
out.writeBoolean(coordinator);
|
||||
out.writeObject(state);
|
||||
}
|
||||
|
||||
/**
|
||||
* read from a stream
|
||||
*
|
||||
* @param in
|
||||
* @throws IOException
|
||||
* @throws ClassNotFoundException
|
||||
*/
|
||||
public void readExternal(ObjectInput in) throws IOException,ClassNotFoundException{
|
||||
this.name=in.readUTF();
|
||||
this.destinationName=in.readUTF();
|
||||
this.coordinator=in.readBoolean();
|
||||
this.state=(Map) in.readObject();
|
||||
}
|
||||
}
|
|
@ -1,58 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* 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.activecluster.impl;
|
||||
|
||||
import java.util.Map;
|
||||
import javax.jms.Destination;
|
||||
|
||||
import org.apache.activecluster.LocalNode;
|
||||
|
||||
/**
|
||||
* Default implementation of a local Node which doesn't
|
||||
* have its state replicated
|
||||
*
|
||||
* @version $Revision: 1.4 $
|
||||
*/
|
||||
public class NonReplicatedLocalNode extends NodeImpl implements LocalNode {
|
||||
private static final long serialVersionUID=2525565639637967143L;
|
||||
|
||||
/**
|
||||
* Create a Non-replicated local node
|
||||
* @param name
|
||||
* @param destination
|
||||
*/
|
||||
public NonReplicatedLocalNode(String name, Destination destination) {
|
||||
super(name,destination);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the local state
|
||||
* @param state
|
||||
*/
|
||||
public void setState(Map state) {
|
||||
super.setState(state);
|
||||
}
|
||||
|
||||
/**
|
||||
* Shouldn't be called for non-replicated local nodes
|
||||
*/
|
||||
public void pingRemoteNodes() {
|
||||
throw new RuntimeException("Non-Replicated Local Node should not distribute it's state!");
|
||||
}
|
||||
}
|
|
@ -1,84 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* 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.activecluster.impl;
|
||||
|
||||
import java.util.Map;
|
||||
import javax.jms.Destination;
|
||||
import javax.jms.JMSException;
|
||||
|
||||
import org.apache.activecluster.LocalNode;
|
||||
import org.apache.activecluster.Service;
|
||||
|
||||
|
||||
/**
|
||||
* Default implementation of a local Node which has its
|
||||
* state replicated across the cluster
|
||||
*
|
||||
* @version $Revision: 1.3 $
|
||||
*/
|
||||
public class ReplicatedLocalNode extends NodeImpl implements LocalNode, Service {
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID=4626381612145333540L;
|
||||
private transient StateService serviceStub;
|
||||
|
||||
/**
|
||||
* Create ReplicatedLocalNode
|
||||
* @param name
|
||||
* @param destination
|
||||
* @param serviceStub
|
||||
*/
|
||||
public ReplicatedLocalNode(String name,Destination destination, StateService serviceStub) {
|
||||
super(name,destination);
|
||||
this.serviceStub = serviceStub;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the State of the local node
|
||||
* @param state
|
||||
*/
|
||||
public void setState(Map state) {
|
||||
super.setState(state);
|
||||
serviceStub.keepAlive(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* ping remote nodes
|
||||
*
|
||||
*/
|
||||
public void pingRemoteNodes() {
|
||||
serviceStub.keepAlive(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* start (lifecycle)
|
||||
* @throws JMSException
|
||||
*/
|
||||
public void start() throws JMSException {
|
||||
}
|
||||
|
||||
/**
|
||||
* stop (lifecycle)
|
||||
* @throws JMSException
|
||||
*/
|
||||
public void stop() throws JMSException {
|
||||
}
|
||||
}
|
|
@ -1,76 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* 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.activecluster.impl;
|
||||
|
||||
|
||||
|
||||
import javax.jms.Destination;
|
||||
import javax.jms.JMSException;
|
||||
import javax.jms.Queue;
|
||||
import javax.jms.Topic;
|
||||
import org.apache.activecluster.DestinationMarshaller;
|
||||
import org.apache.activemq.command.ActiveMQTopic;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
/**
|
||||
* A simple marshaller for Destinations
|
||||
*
|
||||
* @version $Revision: 1.5 $
|
||||
*/
|
||||
public class SimpleDestinationMarshaller implements DestinationMarshaller {
|
||||
private final static Log log = LogFactory.getLog(SimpleDestinationMarshaller.class);
|
||||
/**
|
||||
* Builds a destination from a destinationName
|
||||
* @param destinationName
|
||||
*
|
||||
* @return the destination to send messages to all members of the cluster
|
||||
*/
|
||||
public Destination getDestination(String destinationName){
|
||||
return new ActiveMQTopic(destinationName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a destination's physical name
|
||||
* @param destination
|
||||
* @return the destination's physical name
|
||||
*/
|
||||
public String getDestinationName(Destination destination){
|
||||
String result = null;
|
||||
if (destination != null){
|
||||
if (destination instanceof Topic){
|
||||
Topic topic = (Topic) destination;
|
||||
try{
|
||||
result = topic.getTopicName();
|
||||
}catch(JMSException e){
|
||||
log.error("Failed to get topic name for " + destination,e);
|
||||
}
|
||||
}else{
|
||||
Queue queue = (Queue) destination;
|
||||
try{
|
||||
result = queue.getQueueName();
|
||||
}catch(JMSException e){
|
||||
log.error("Failed to get queue name for " + destination,e);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
|
@ -1,78 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* 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.activecluster.impl;
|
||||
|
||||
import org.apache.activecluster.DestinationMarshaller;
|
||||
import org.apache.activecluster.Node;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import javax.jms.Message;
|
||||
import javax.jms.MessageListener;
|
||||
import javax.jms.ObjectMessage;
|
||||
|
||||
|
||||
/**
|
||||
* A JMS MessageListener which processes inbound messages and
|
||||
* applies them to a StateService
|
||||
*
|
||||
* @version $Revision: 1.2 $
|
||||
*/
|
||||
public class StateConsumer implements MessageListener {
|
||||
|
||||
private final static Log log = LogFactory.getLog(StateConsumer.class);
|
||||
|
||||
private StateService stateService;
|
||||
private DestinationMarshaller marshaller;
|
||||
|
||||
public StateConsumer(StateService stateService,DestinationMarshaller marshaller) {
|
||||
if (stateService == null) {
|
||||
throw new IllegalArgumentException("Must specify a valid StateService implementation");
|
||||
}
|
||||
this.stateService = stateService;
|
||||
this.marshaller = marshaller;
|
||||
}
|
||||
|
||||
public void onMessage(Message message) {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Received cluster data message!: " + message);
|
||||
}
|
||||
|
||||
if (message instanceof ObjectMessage) {
|
||||
ObjectMessage objectMessage = (ObjectMessage) message;
|
||||
try {
|
||||
NodeState nodeState = (NodeState) objectMessage.getObject();
|
||||
Node node = new NodeImpl(nodeState,marshaller);
|
||||
String type = objectMessage.getJMSType();
|
||||
if (type != null && type.equals("shutdown")) {
|
||||
stateService.shutdown(node);
|
||||
}
|
||||
else {
|
||||
stateService.keepAlive(node);
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
log.error("Could not extract node from message: " + e + ". Message: " + message, e);
|
||||
}
|
||||
}
|
||||
else {
|
||||
log.warn("Ignoring message: " + message);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,42 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* 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.activecluster.impl;
|
||||
|
||||
import org.apache.activecluster.Node;
|
||||
|
||||
|
||||
/**
|
||||
* A client side proxy to the remove cluster
|
||||
*
|
||||
* @version $Revision: 1.3 $
|
||||
*/
|
||||
public interface StateService {
|
||||
|
||||
/**
|
||||
* Sends a keep alive to the cluster
|
||||
*
|
||||
* @param node
|
||||
*/
|
||||
public void keepAlive(Node node);
|
||||
|
||||
/**
|
||||
* Sends a shutdown message to the cluster
|
||||
*/
|
||||
public void shutdown(Node node);
|
||||
|
||||
}
|
|
@ -1,302 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* 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.activecluster.impl;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
import java.util.Map.Entry;
|
||||
import javax.jms.Destination;
|
||||
import javax.jms.JMSException;
|
||||
|
||||
import org.apache.activecluster.Cluster;
|
||||
import org.apache.activecluster.ClusterEvent;
|
||||
import org.apache.activecluster.ClusterListener;
|
||||
import org.apache.activecluster.Node;
|
||||
import org.apache.activecluster.election.ElectionStrategy;
|
||||
import org.apache.activecluster.election.impl.BullyElectionStrategy;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import edu.emory.mathcs.backport.java.util.concurrent.ConcurrentHashMap;
|
||||
import edu.emory.mathcs.backport.java.util.concurrent.CopyOnWriteArrayList;
|
||||
|
||||
|
||||
/**
|
||||
* Represents a node list
|
||||
*
|
||||
* @version $Revision: 1.4 $
|
||||
*/
|
||||
public class StateServiceImpl implements StateService {
|
||||
|
||||
private final static Log log = LogFactory.getLog(StateServiceImpl.class);
|
||||
private Cluster cluster;
|
||||
private Object clusterLock;
|
||||
private Map nodes = new ConcurrentHashMap();
|
||||
private long inactiveTime;
|
||||
private List listeners = new CopyOnWriteArrayList();
|
||||
private Destination localDestination;
|
||||
private Runnable localNodePing;
|
||||
private NodeImpl coordinator;
|
||||
private ElectionStrategy electionStrategy;
|
||||
|
||||
/**
|
||||
* @param cluster
|
||||
* @param clusterLock
|
||||
* @param localNodePing
|
||||
* @param timer
|
||||
* @param inactiveTime
|
||||
*/
|
||||
/**
|
||||
* Constructor StateServiceImpl
|
||||
* @param cluster
|
||||
* @param clusterLock
|
||||
* @param localNodePing
|
||||
* @param timer
|
||||
* @param inactiveTime
|
||||
*/
|
||||
public StateServiceImpl(Cluster cluster, Object clusterLock, Runnable localNodePing, Timer timer, long inactiveTime) {
|
||||
this.cluster = cluster;
|
||||
this.clusterLock = clusterLock;
|
||||
this.localDestination = cluster.getLocalNode().getDestination();
|
||||
this.localNodePing = localNodePing;
|
||||
this.inactiveTime = inactiveTime;
|
||||
long delay = inactiveTime / 3;
|
||||
timer.scheduleAtFixedRate(createTimerTask(), delay, delay);
|
||||
(this.coordinator = (NodeImpl) cluster.getLocalNode()).setCoordinator(true);
|
||||
this.electionStrategy = new BullyElectionStrategy();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the current election strategy
|
||||
*/
|
||||
public ElectionStrategy getElectionStrategy() {
|
||||
return electionStrategy;
|
||||
}
|
||||
|
||||
/**
|
||||
* set the election strategy
|
||||
*
|
||||
* @param electionStrategy
|
||||
*/
|
||||
public void setElectionStrategy(ElectionStrategy electionStrategy) {
|
||||
this.electionStrategy = electionStrategy;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get time of since last communication
|
||||
* @return length of time inactive
|
||||
*/
|
||||
public long getInactiveTime() {
|
||||
return inactiveTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the time inactive
|
||||
* @param inactiveTime
|
||||
*/
|
||||
public void setInactiveTime(long inactiveTime) {
|
||||
this.inactiveTime = inactiveTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get A Map of nodes - where key = destination, value = node
|
||||
* @return map of destination/nodes
|
||||
*/
|
||||
public Map getNodes() {
|
||||
HashMap answer = new HashMap(nodes.size());
|
||||
for (Iterator iter = nodes.entrySet().iterator(); iter.hasNext();) {
|
||||
Map.Entry entry = (Map.Entry) iter.next();
|
||||
Object key = entry.getKey();
|
||||
NodeEntry nodeEntry = (NodeEntry) entry.getValue();
|
||||
answer.put(key, nodeEntry.node);
|
||||
}
|
||||
return answer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Got a keepalive
|
||||
* @param node
|
||||
*/
|
||||
public void keepAlive(Node node) {
|
||||
Object key = node.getDestination();
|
||||
if (key != null && !localDestination.equals(key)) {
|
||||
NodeEntry entry = (NodeEntry) nodes.get(key);
|
||||
if (entry == null) {
|
||||
entry = new NodeEntry();
|
||||
entry.node = node;
|
||||
nodes.put(key, entry);
|
||||
nodeAdded(node);
|
||||
synchronized (clusterLock) {
|
||||
clusterLock.notifyAll();
|
||||
}
|
||||
}
|
||||
else {
|
||||
// has the data changed
|
||||
if (stateHasChanged(entry.node, node)) {
|
||||
entry.node = node;
|
||||
nodeUpdated(node);
|
||||
}
|
||||
}
|
||||
|
||||
// lets update the timer at which the node will be considered
|
||||
// to be dead
|
||||
entry.lastKeepAlive = getTimeMillis();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* shutdown the node
|
||||
*/
|
||||
public void shutdown(Node node){
|
||||
Object key=node.getDestination();
|
||||
if(key!=null){
|
||||
nodes.remove(key);
|
||||
ClusterEvent event=new ClusterEvent(cluster,node,ClusterEvent.ADD_NODE);
|
||||
for (Iterator i = listeners.iterator(); i.hasNext();){
|
||||
ClusterListener listener=(ClusterListener) i.next();
|
||||
listener.onNodeRemoved(event);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* check nodes are alive
|
||||
*
|
||||
*/
|
||||
|
||||
public void checkForTimeouts() {
|
||||
localNodePing.run();
|
||||
long time = getTimeMillis();
|
||||
for (Iterator iter = nodes.entrySet().iterator(); iter.hasNext();) {
|
||||
Map.Entry entry = (Entry) iter.next();
|
||||
NodeEntry nodeEntry = (NodeEntry) entry.getValue();
|
||||
if (nodeEntry.lastKeepAlive + inactiveTime < time) {
|
||||
iter.remove();
|
||||
nodeFailed(nodeEntry.node);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public TimerTask createTimerTask() {
|
||||
return new TimerTask() {
|
||||
public void run() {
|
||||
checkForTimeouts();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public void addClusterListener(ClusterListener listener) {
|
||||
listeners.add(listener);
|
||||
}
|
||||
|
||||
public void removeClusterListener(ClusterListener listener) {
|
||||
listeners.remove(listener);
|
||||
}
|
||||
|
||||
protected void nodeAdded(Node node) {
|
||||
ClusterEvent event = new ClusterEvent(cluster, node, ClusterEvent.ADD_NODE);
|
||||
// lets take a copy to make contention easier
|
||||
Object[] array = listeners.toArray();
|
||||
for (int i = 0, size = array.length; i < size; i++) {
|
||||
ClusterListener listener = (ClusterListener) array[i];
|
||||
listener.onNodeAdd(event);
|
||||
}
|
||||
doElection();
|
||||
}
|
||||
|
||||
protected void nodeUpdated(Node node) {
|
||||
ClusterEvent event = new ClusterEvent(cluster, node, ClusterEvent.UPDATE_NODE);
|
||||
// lets take a copy to make contention easier
|
||||
Object[] array = listeners.toArray();
|
||||
for (int i = 0, size = array.length; i < size; i++) {
|
||||
ClusterListener listener = (ClusterListener) array[i];
|
||||
listener.onNodeUpdate(event);
|
||||
}
|
||||
}
|
||||
|
||||
protected void nodeFailed(Node node) {
|
||||
ClusterEvent event = new ClusterEvent(cluster, node, ClusterEvent.REMOVE_NODE);
|
||||
// lets take a copy to make contention easier
|
||||
Object[] array = listeners.toArray();
|
||||
for (int i = 0, size = array.length; i < size; i++) {
|
||||
ClusterListener listener = (ClusterListener) array[i];
|
||||
listener.onNodeFailed(event);
|
||||
}
|
||||
doElection();
|
||||
}
|
||||
|
||||
protected void coordinatorChanged(Node node) {
|
||||
ClusterEvent event = new ClusterEvent(cluster, node, ClusterEvent.ELECTED_COORDINATOR);
|
||||
// lets take a copy to make contention easier
|
||||
Object[] array = listeners.toArray();
|
||||
for (int i = 0, size = array.length; i < size; i++) {
|
||||
ClusterListener listener = (ClusterListener) array[i];
|
||||
listener.onCoordinatorChanged(event);
|
||||
}
|
||||
}
|
||||
|
||||
protected void doElection() {
|
||||
if (electionStrategy != null) {
|
||||
try {
|
||||
NodeImpl newElected = (NodeImpl) electionStrategy.doElection(cluster);
|
||||
if (newElected != null && !newElected.equals(coordinator)) {
|
||||
coordinator.setCoordinator(false);
|
||||
coordinator = newElected;
|
||||
coordinator.setCoordinator(true);
|
||||
coordinatorChanged(coordinator);
|
||||
}
|
||||
}
|
||||
catch (JMSException jmsEx) {
|
||||
log.error("do election failed", jmsEx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* For performance we may wish to use a less granualar timing mechanism
|
||||
* only updating the time every x millis since we're only using
|
||||
* the time as a judge of when a node has not pinged for at least a few
|
||||
* hundred millis etc.
|
||||
*/
|
||||
protected long getTimeMillis() {
|
||||
return System.currentTimeMillis();
|
||||
}
|
||||
|
||||
protected static class NodeEntry {
|
||||
public Node node;
|
||||
public long lastKeepAlive;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return true if the node has changed state from the old in memory copy to the
|
||||
* newly arrived copy
|
||||
*/
|
||||
protected boolean stateHasChanged(Node oldNode, Node newNode) {
|
||||
Map oldState = oldNode.getState();
|
||||
Map newState = newNode.getState();
|
||||
if (oldState == newState) {
|
||||
return false;
|
||||
}
|
||||
return oldState == null || newState == null || !oldState.equals(newState);
|
||||
}
|
||||
}
|
|
@ -1,80 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* 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.activecluster.impl;
|
||||
|
||||
import org.apache.activecluster.DestinationMarshaller;
|
||||
import org.apache.activecluster.Node;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import javax.jms.JMSException;
|
||||
import javax.jms.Message;
|
||||
import javax.jms.MessageProducer;
|
||||
import javax.jms.Session;
|
||||
|
||||
|
||||
/**
|
||||
* A local stub for the state service which sends JMS messages
|
||||
* to the cluster
|
||||
*
|
||||
* @version $Revision: 1.2 $
|
||||
*/
|
||||
public class StateServiceStub implements StateService {
|
||||
|
||||
private final Log log = LogFactory.getLog(getClass());
|
||||
|
||||
private Session session;
|
||||
private MessageProducer producer;
|
||||
private DestinationMarshaller marshaller;
|
||||
|
||||
public StateServiceStub(Session session, MessageProducer producer,DestinationMarshaller marshaller) {
|
||||
this.session = session;
|
||||
this.producer = producer;
|
||||
this.marshaller = marshaller;
|
||||
}
|
||||
|
||||
public void keepAlive(Node node) {
|
||||
try {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Sending cluster data message: " + node);
|
||||
}
|
||||
|
||||
Message message = session.createObjectMessage(new NodeState(node,marshaller));
|
||||
producer.send(message);
|
||||
}
|
||||
catch (JMSException e) {
|
||||
log.error("Could not send JMS message: " + e, e);
|
||||
}
|
||||
}
|
||||
|
||||
public void shutdown(Node node) {
|
||||
try {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Sending shutdown message: " + node);
|
||||
}
|
||||
|
||||
Message message = session.createObjectMessage(new NodeState(node,marshaller));
|
||||
message.setJMSType("shutdown");
|
||||
producer.send(message);
|
||||
}
|
||||
catch (JMSException e) {
|
||||
log.error("Could not send JMS message: " + e, e);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,27 +0,0 @@
|
|||
<!--
|
||||
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.
|
||||
-->
|
||||
<html>
|
||||
<head>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<p>
|
||||
Default implementation of ActiveCluster using standard JMS API to build the cluster.
|
||||
</p>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -1,31 +0,0 @@
|
|||
<!--
|
||||
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.
|
||||
-->
|
||||
<html>
|
||||
<head>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<p>
|
||||
ActiveCluster API for working with a simple cluster abstraction for building cluster algorithms
|
||||
like buddy systems, voting, master/slave protocols, electing a controller and so forth.
|
||||
</p>
|
||||
Clusters communicate across a common destination (typically a Topic) but every member (node)of a
|
||||
cluster has a unique name (the generation of unique names is left to the developer), and a
|
||||
unique destination (which uses the unique name).
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -1,146 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* 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.activecluster;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import javax.jms.JMSException;
|
||||
|
||||
import org.apache.activecluster.Cluster;
|
||||
import org.apache.activecluster.ClusterEvent;
|
||||
import org.apache.activecluster.ClusterException;
|
||||
import org.apache.activecluster.ClusterFactory;
|
||||
import org.apache.activecluster.ClusterListener;
|
||||
import org.apache.activecluster.impl.ActiveMQClusterFactory;
|
||||
|
||||
/**
|
||||
* @version $Revision: 1.2 $
|
||||
*/
|
||||
public class ChatDemo implements ClusterListener {
|
||||
private Cluster cluster;
|
||||
private String name = "unknown";
|
||||
|
||||
public static void main(String[] args) {
|
||||
try {
|
||||
ChatDemo test = new ChatDemo();
|
||||
test.run();
|
||||
}
|
||||
catch (JMSException e) {
|
||||
System.out.println("Caught: " + e);
|
||||
e.printStackTrace();
|
||||
Exception c = e.getLinkedException();
|
||||
if (c != null) {
|
||||
System.out.println("Cause: " + c);
|
||||
c.printStackTrace();
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
System.out.println("Caught: " + e);
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public void run() throws Exception {
|
||||
cluster = createCluster();
|
||||
cluster.addClusterListener(this);
|
||||
cluster.start();
|
||||
|
||||
|
||||
System.out.println();
|
||||
System.out.println();
|
||||
System.out.println("Welcome to the ActiveCluster Chat Demo!");
|
||||
System.out.println();
|
||||
System.out.println("Enter text to talk or type");
|
||||
System.out.println(" /quit to terminate the application");
|
||||
System.out.println(" /name foo to change your name to be 'foo'");
|
||||
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
|
||||
boolean running = true;
|
||||
while (running) {
|
||||
String line = reader.readLine();
|
||||
if (line == null || line.trim().equalsIgnoreCase("quit")) {
|
||||
break;
|
||||
}
|
||||
else {
|
||||
running = processCommand(line.trim());
|
||||
}
|
||||
}
|
||||
stop();
|
||||
}
|
||||
|
||||
protected boolean processCommand(String text) throws JMSException {
|
||||
if (text.equals("/quit")) {
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
if (text.startsWith("/name")) {
|
||||
name = text.substring(5).trim();
|
||||
System.out.println("* name now changed to: " + name);
|
||||
}
|
||||
else {
|
||||
// lets talk
|
||||
Map map = new HashMap();
|
||||
map.put("text", text);
|
||||
map.put("name", name);
|
||||
cluster.getLocalNode().setState(map);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void onNodeAdd(ClusterEvent event) {
|
||||
System.out.println("* " + getName(event) + " has joined the room");
|
||||
}
|
||||
|
||||
public void onNodeUpdate(ClusterEvent event) {
|
||||
System.out.println(getName(event) + "> " + getText(event));
|
||||
}
|
||||
|
||||
public void onNodeRemoved(ClusterEvent event) {
|
||||
System.out.println("* " + getName(event) + " has left the room");
|
||||
}
|
||||
|
||||
public void onNodeFailed(ClusterEvent event) {
|
||||
System.out.println("* " + getName(event) + " has failed unexpectedly");
|
||||
}
|
||||
|
||||
public void onCoordinatorChanged(ClusterEvent event){
|
||||
|
||||
}
|
||||
|
||||
protected Object getName(ClusterEvent event) {
|
||||
return event.getNode().getState().get("name");
|
||||
}
|
||||
|
||||
protected Object getText(ClusterEvent event) {
|
||||
return event.getNode().getState().get("text");
|
||||
}
|
||||
|
||||
protected void stop() throws JMSException {
|
||||
cluster.stop();
|
||||
}
|
||||
|
||||
protected Cluster createCluster() throws JMSException, ClusterException {
|
||||
ClusterFactory factory = new ActiveMQClusterFactory();
|
||||
return factory.createCluster("ORG.CODEHAUS.ACTIVEMQ.TEST.CLUSTER");
|
||||
}
|
||||
|
||||
}
|
|
@ -1,112 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* 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.activecluster;
|
||||
|
||||
import org.apache.activecluster.Cluster;
|
||||
import org.apache.activecluster.ClusterException;
|
||||
import org.apache.activecluster.ClusterFactory;
|
||||
import org.apache.activecluster.election.ElectionStrategy;
|
||||
import org.apache.activecluster.election.impl.BullyElectionStrategy;
|
||||
import org.apache.activecluster.impl.ActiveMQClusterFactory;
|
||||
import org.apache.activecluster.impl.DefaultClusterFactory;
|
||||
|
||||
import javax.jms.JMSException;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @version $Revision: 1.2 $
|
||||
*/
|
||||
public class ClusterDemo {
|
||||
protected Cluster cluster;
|
||||
private String name;
|
||||
private ElectionStrategy electionStrategy;
|
||||
|
||||
public static void main(String[] args) {
|
||||
try {
|
||||
ClusterDemo test = new ClusterDemo();
|
||||
if (args.length > 0) {
|
||||
test.name = args[0];
|
||||
}
|
||||
test.demo();
|
||||
}
|
||||
catch (JMSException e) {
|
||||
System.out.println("Caught: " + e);
|
||||
e.printStackTrace();
|
||||
Exception c = e.getLinkedException();
|
||||
if (c != null) {
|
||||
System.out.println("Cause: " + c);
|
||||
c.printStackTrace();
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
System.out.println("Caught: " + e);
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public void demo() throws Exception {
|
||||
start();
|
||||
|
||||
cluster.addClusterListener(new TestingClusterListener(cluster));
|
||||
|
||||
System.out.println("Enter 'quit' to terminate");
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
|
||||
while (true) {
|
||||
String line = reader.readLine();
|
||||
if (line == null || line.trim().equalsIgnoreCase("quit")) {
|
||||
break;
|
||||
}
|
||||
else {
|
||||
Map map = new HashMap();
|
||||
map.put("text", line);
|
||||
cluster.getLocalNode().setState(map);
|
||||
}
|
||||
}
|
||||
stop();
|
||||
}
|
||||
|
||||
|
||||
protected void start() throws JMSException, ClusterException {
|
||||
cluster = createCluster();
|
||||
if (name != null) {
|
||||
System.out.println("Starting node: " + name);
|
||||
|
||||
// TODO could we do cluster.setName() ?
|
||||
Map state = new HashMap();
|
||||
state.put("name", name);
|
||||
cluster.getLocalNode().setState(state);
|
||||
}
|
||||
cluster.start();
|
||||
if (electionStrategy == null) {
|
||||
electionStrategy = new BullyElectionStrategy();
|
||||
}
|
||||
electionStrategy.doElection(cluster);
|
||||
}
|
||||
|
||||
protected void stop() throws JMSException {
|
||||
cluster.stop();
|
||||
}
|
||||
|
||||
protected Cluster createCluster() throws JMSException, ClusterException {
|
||||
ClusterFactory factory = new ActiveMQClusterFactory();
|
||||
return factory.createCluster("ORG.CODEHAUS.ACTIVEMQ.TEST.CLUSTER");
|
||||
}
|
||||
}
|
|
@ -1,209 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* 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.activecluster;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import javax.jms.Connection;
|
||||
import javax.jms.JMSException;
|
||||
import javax.jms.Message;
|
||||
import javax.jms.MessageListener;
|
||||
import javax.jms.ObjectMessage;
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.apache.activecluster.Cluster;
|
||||
import org.apache.activecluster.ClusterEvent;
|
||||
import org.apache.activecluster.ClusterListener;
|
||||
import org.apache.activecluster.impl.DefaultClusterFactory;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.apache.activemq.ActiveMQConnectionFactory;
|
||||
|
||||
/**
|
||||
* Test ActiveCluster, ActiveMQ, with an eye to putting WADI on top of them.
|
||||
*
|
||||
* @author <a href="mailto:jules@coredevelopers.net">Jules Gosnell </a>
|
||||
* @version $Revision: 1.4 $
|
||||
*/
|
||||
public class ClusterFunctionTest extends TestCase {
|
||||
protected Log _log = LogFactory.getLog(ClusterFunctionTest.class);
|
||||
|
||||
public ClusterFunctionTest(String name) {
|
||||
super(name);
|
||||
}
|
||||
protected ActiveMQConnectionFactory _connectionFactory;
|
||||
protected Connection _connection;
|
||||
protected DefaultClusterFactory _clusterFactory;
|
||||
protected Cluster _cluster0;
|
||||
protected Cluster _cluster1;
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
testResponsePassed = false;
|
||||
_connectionFactory = new ActiveMQConnectionFactory("peer://cluster?persistent=false");
|
||||
_clusterFactory = new DefaultClusterFactory(_connectionFactory);
|
||||
_cluster0 = _clusterFactory.createCluster("ORG.CODEHAUS.WADI.TEST.CLUSTER");
|
||||
_cluster1 = _clusterFactory.createCluster("ORG.CODEHAUS.WADI.TEST.CLUSTER");
|
||||
_cluster0.start();
|
||||
_log.info("started node0: " + _cluster0.getLocalNode().getDestination());
|
||||
_cluster1.start();
|
||||
_log.info("started node1: " + _cluster1.getLocalNode().getDestination());
|
||||
}
|
||||
|
||||
protected void tearDown() throws JMSException {
|
||||
// _cluster1.stop();
|
||||
_cluster1 = null;
|
||||
// _cluster0.stop();
|
||||
_cluster0 = null;
|
||||
_clusterFactory = null;
|
||||
// _connection.stop();
|
||||
_connection = null;
|
||||
// _connectionFactory.stop();
|
||||
}
|
||||
//----------------------------------------
|
||||
class MyClusterListener implements ClusterListener {
|
||||
public void onNodeAdd(ClusterEvent ce) {
|
||||
_log.info("node added: " + ce.getNode());
|
||||
}
|
||||
|
||||
public void onNodeFailed(ClusterEvent ce) {
|
||||
_log.info("node failed: " + ce.getNode());
|
||||
}
|
||||
|
||||
public void onNodeRemoved(ClusterEvent ce) {
|
||||
_log.info("node removed: " + ce.getNode());
|
||||
}
|
||||
|
||||
public void onNodeUpdate(ClusterEvent ce) {
|
||||
_log.info("node updated: " + ce.getNode());
|
||||
}
|
||||
|
||||
public void onCoordinatorChanged(ClusterEvent ce) {
|
||||
_log.info("coordinator changed: " + ce.getNode());
|
||||
}
|
||||
}
|
||||
|
||||
public void testCluster() throws Exception {
|
||||
_cluster0.addClusterListener(new MyClusterListener());
|
||||
Map map = new HashMap();
|
||||
map.put("text", "testing123");
|
||||
_cluster0.getLocalNode().setState(map);
|
||||
_log.info("nodes: " + _cluster0.getNodes());
|
||||
Thread.sleep(10000);
|
||||
assertTrue(true);
|
||||
}
|
||||
/**
|
||||
* An invokable piece of work.
|
||||
*/
|
||||
static interface Invocation extends java.io.Serializable {
|
||||
public void invoke(Cluster cluster, ObjectMessage om);
|
||||
}
|
||||
/**
|
||||
* Listen for messages, if they contain Invocations, invoke() them.
|
||||
*/
|
||||
class InvocationListener implements MessageListener {
|
||||
protected Cluster _cluster;
|
||||
|
||||
public InvocationListener(Cluster cluster) {
|
||||
_cluster = cluster;
|
||||
}
|
||||
|
||||
public void onMessage(Message message) {
|
||||
_log.info("message received: " + message);
|
||||
ObjectMessage om = null;
|
||||
Object tmp = null;
|
||||
Invocation invocation = null;
|
||||
try {
|
||||
if (message instanceof ObjectMessage && (om = (ObjectMessage) message) != null
|
||||
&& (tmp = om.getObject()) != null && tmp instanceof Invocation
|
||||
&& (invocation = (Invocation) tmp) != null) {
|
||||
_log.info("invoking message on: " + _cluster.getLocalNode());
|
||||
invocation.invoke(_cluster, om);
|
||||
_log.info("message successfully invoked on: " + _cluster.getLocalNode());
|
||||
}
|
||||
else {
|
||||
_log.warn("bad message: " + message);
|
||||
}
|
||||
}
|
||||
catch (JMSException e) {
|
||||
_log.warn("unexpected problem", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* A request for a piece of work which involves sending a response back to the original requester.
|
||||
*/
|
||||
static class Request implements Invocation {
|
||||
public void invoke(Cluster cluster, ObjectMessage om2) {
|
||||
try {
|
||||
System.out.println("request received");
|
||||
ObjectMessage om = cluster.createObjectMessage();
|
||||
om.setJMSReplyTo(cluster.getLocalNode().getDestination());
|
||||
om.setObject(new Response());
|
||||
System.out.println("sending response");
|
||||
cluster.send(om2.getJMSReplyTo(), om);
|
||||
System.out.println("request processed");
|
||||
}
|
||||
catch (JMSException e) {
|
||||
System.err.println("problem sending response");
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
static boolean testResponsePassed = false;
|
||||
/**
|
||||
* A response containing a piece of work.
|
||||
*/
|
||||
static class Response implements Invocation {
|
||||
public void invoke(Cluster cluster, ObjectMessage om) {
|
||||
try {
|
||||
System.out.println("response arrived from: " + om.getJMSReplyTo());
|
||||
// set a flag to test later
|
||||
ClusterFunctionTest.testResponsePassed = true;
|
||||
System.out.println("response processed on: " + cluster.getLocalNode().getDestination());
|
||||
}
|
||||
catch (JMSException e) {
|
||||
System.err.println("problem processing response");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void testResponse() throws Exception {
|
||||
MessageListener listener0 = new InvocationListener(_cluster0);
|
||||
MessageListener listener1 = new InvocationListener(_cluster1);
|
||||
// 1->(n-1) messages (excludes self)
|
||||
_cluster0.createConsumer(_cluster0.getDestination(), null, true).setMessageListener(listener0);
|
||||
// 1->1 messages
|
||||
_cluster0.createConsumer(_cluster0.getLocalNode().getDestination()).setMessageListener(listener0);
|
||||
// 1->(n-1) messages (excludes self)
|
||||
_cluster1.createConsumer(_cluster1.getDestination(), null, true).setMessageListener(listener1);
|
||||
// 1->1 messages
|
||||
_cluster1.createConsumer(_cluster1.getLocalNode().getDestination()).setMessageListener(listener1);
|
||||
ObjectMessage om = _cluster0.createObjectMessage();
|
||||
om.setJMSReplyTo(_cluster0.getLocalNode().getDestination());
|
||||
om.setObject(new Request());
|
||||
testResponsePassed = false;
|
||||
_cluster0.send(_cluster0.getLocalNode().getDestination(), om);
|
||||
Thread.sleep(3000);
|
||||
assertTrue(testResponsePassed);
|
||||
_log.info("request/response between same node OK");
|
||||
testResponsePassed = false;
|
||||
_cluster0.send(_cluster1.getLocalNode().getDestination(), om);
|
||||
Thread.sleep(3000);
|
||||
assertTrue(testResponsePassed);
|
||||
_log.info("request/response between two different nodes OK");
|
||||
}
|
||||
}
|
|
@ -1,122 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* 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.activecluster;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import javax.jms.Destination;
|
||||
import javax.jms.Message;
|
||||
|
||||
import org.apache.activecluster.Cluster;
|
||||
import org.apache.activecluster.LocalNode;
|
||||
import org.apache.activecluster.Node;
|
||||
|
||||
/**
|
||||
* @version $Revision: 1.4 $
|
||||
*/
|
||||
public class ClusterTest extends ClusterTestSupport {
|
||||
|
||||
protected int count = 3;
|
||||
|
||||
public void testCluster() throws Exception {
|
||||
cluster = createCluster();
|
||||
|
||||
subscribeToCluster();
|
||||
|
||||
cluster.start();
|
||||
|
||||
Destination destination = cluster.getDestination();
|
||||
Message message = cluster.createTextMessage("abcdef");
|
||||
cluster.send(destination, message);
|
||||
|
||||
//clusterListener.waitForMessageToArrive();
|
||||
Thread.sleep(5000);
|
||||
|
||||
List list = clusterListener.flushMessages();
|
||||
assertEquals("Should have received a message: " + list, 1, list.size());
|
||||
|
||||
System.out.println("Received message: " + list.get(0));
|
||||
}
|
||||
|
||||
|
||||
public void testMembershipCluster() throws Exception {
|
||||
Cluster[] clusters = new Cluster[count];
|
||||
for (int i = 0; i < count; i++) {
|
||||
Cluster cluster = createCluster("node:" + i);
|
||||
clusters[i] = cluster;
|
||||
if (i==0){
|
||||
cluster.addClusterListener(new TestingClusterListener(cluster));
|
||||
}
|
||||
cluster.start();
|
||||
System.out.println("started " + clusters[i].getLocalNode().getName());
|
||||
|
||||
}
|
||||
|
||||
System.out.println("waiting to complete ...");
|
||||
for (int i = count - 1; i >= 0; i--) {
|
||||
Cluster cluster = clusters[i];
|
||||
String localName = cluster.getLocalNode().getName();
|
||||
boolean completed = cluster.waitForClusterToComplete(count - 1, 5000);
|
||||
assertTrue("Node: " + i + " with contents: " + dumpConnectedNodes(cluster.getNodes()), completed);
|
||||
|
||||
System.out.println(localName + " completed = " + completed + " nodes = "
|
||||
+ dumpConnectedNodes(cluster.getNodes()));
|
||||
}
|
||||
|
||||
assertClusterMembership(clusters);
|
||||
|
||||
|
||||
assertClusterMembership(clusters);
|
||||
|
||||
Cluster testCluster = clusters[0];
|
||||
LocalNode testNode = testCluster.getLocalNode();
|
||||
String key = "key";
|
||||
String value = "value";
|
||||
|
||||
Map map = testNode.getState();
|
||||
map.put(key, value);
|
||||
testNode.setState(map);
|
||||
|
||||
|
||||
Thread.sleep(500);
|
||||
for (int i = 1; i < count; i++) {
|
||||
Node node = (Node) clusters[i].getNodes().get(testNode.getDestination());
|
||||
|
||||
assertTrue("The current test node should be in the cluster: " + i, node != null);
|
||||
assertTrue(node.getState().get(key).equals(value));
|
||||
}
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
System.out.println(clusters[i].getLocalNode().getName() + " Is coordinator = " + clusters[i].getLocalNode().isCoordinator());
|
||||
clusters[i].stop();
|
||||
Thread.sleep(250);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
protected void assertClusterMembership(Cluster[] clusters) {
|
||||
for (int i = 0; i < count; i++) {
|
||||
System.out.println("Cluster: " + i + " = " + clusters[i].getNodes());
|
||||
|
||||
assertEquals("Size of clusters for cluster: " + i, count - 1, clusters[i].getNodes().size());
|
||||
System.out.println(clusters[i].getLocalNode().getName() + " Is coordinator = " + clusters[i].getLocalNode().isCoordinator());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,78 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* 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.activecluster;
|
||||
|
||||
import org.apache.activecluster.Cluster;
|
||||
import org.apache.activecluster.Node;
|
||||
import org.apache.activecluster.impl.ActiveMQClusterFactory;
|
||||
|
||||
import javax.jms.Destination;
|
||||
import javax.jms.JMSException;
|
||||
import javax.jms.Message;
|
||||
import javax.jms.MessageConsumer;
|
||||
import javax.jms.Topic;
|
||||
|
||||
/**
|
||||
* @version $Revision: 1.3 $
|
||||
*/
|
||||
public abstract class ClusterTestSupport extends TestSupport {
|
||||
|
||||
protected Cluster cluster;
|
||||
protected StubMessageListener clusterListener = new StubMessageListener();
|
||||
protected StubMessageListener inboxListener = new StubMessageListener();
|
||||
private MessageConsumer clusterConsumer;
|
||||
private MessageConsumer inboxConsumer;
|
||||
|
||||
|
||||
protected void sendMessageToNode(Node node, String text) throws Exception {
|
||||
Message message = cluster.createTextMessage(text);
|
||||
cluster.send(node.getDestination(), message);
|
||||
}
|
||||
|
||||
protected void sendMessageToCluster(String text) throws Exception {
|
||||
Message message = cluster.createTextMessage(text);
|
||||
cluster.send(cluster.getDestination(), message);
|
||||
}
|
||||
|
||||
protected void subscribeToCluster() throws Exception {
|
||||
|
||||
// listen to cluster messages
|
||||
Destination clusterDestination = cluster.getDestination();
|
||||
assertTrue("Local destination must not be null", clusterDestination != null);
|
||||
clusterConsumer = cluster.createConsumer(clusterDestination);
|
||||
clusterConsumer.setMessageListener(clusterListener);
|
||||
|
||||
// listen to inbox messages (individual messages)
|
||||
Destination localDestination = cluster.getLocalNode().getDestination();
|
||||
assertTrue("Local destination must not be null", localDestination != null);
|
||||
|
||||
System.out.println("Consuming from local destination: " + localDestination);
|
||||
inboxConsumer = cluster.createConsumer(localDestination);
|
||||
inboxConsumer.setMessageListener(inboxListener);
|
||||
}
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
}
|
||||
|
||||
protected void tearDown() throws Exception {
|
||||
if (cluster != null) {
|
||||
cluster.stop();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,77 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* 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.activecluster;
|
||||
|
||||
import javax.jms.Message;
|
||||
import javax.jms.MessageListener;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* A mock message listener for testing
|
||||
*
|
||||
* @version $Revision: 1.2 $
|
||||
*/
|
||||
public class StubMessageListener implements MessageListener {
|
||||
private List messages = new ArrayList();
|
||||
private Object semaphore;
|
||||
|
||||
public StubMessageListener() {
|
||||
this(new Object());
|
||||
}
|
||||
|
||||
public StubMessageListener(Object semaphore) {
|
||||
this.semaphore = semaphore;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return all the messages on the list so far, clearing the buffer
|
||||
*/
|
||||
public synchronized List flushMessages() {
|
||||
List answer = new ArrayList(messages);
|
||||
messages.clear();
|
||||
return answer;
|
||||
}
|
||||
|
||||
public synchronized void onMessage(Message message) {
|
||||
messages.add(message);
|
||||
synchronized (semaphore) {
|
||||
semaphore.notifyAll();
|
||||
}
|
||||
}
|
||||
|
||||
public void waitForMessageToArrive() {
|
||||
System.out.println("Waiting for message to arrive");
|
||||
|
||||
long start = System.currentTimeMillis();
|
||||
|
||||
try {
|
||||
if (messages.isEmpty()) {
|
||||
synchronized (semaphore) {
|
||||
semaphore.wait(4000);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (InterruptedException e) {
|
||||
System.out.println("Caught: " + e);
|
||||
}
|
||||
long end = System.currentTimeMillis() - start;
|
||||
|
||||
System.out.println("End of wait for " + end + " millis");
|
||||
}
|
||||
}
|
|
@ -1,63 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* 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.activecluster;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import javax.jms.JMSException;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.activecluster.Cluster;
|
||||
import org.apache.activecluster.ClusterException;
|
||||
import org.apache.activecluster.ClusterFactory;
|
||||
import org.apache.activecluster.Node;
|
||||
import org.apache.activecluster.impl.ActiveMQClusterFactory;
|
||||
|
||||
/**
|
||||
* @version $Revision: 1.2 $
|
||||
*/
|
||||
public class TestSupport extends TestCase {
|
||||
protected String dumpConnectedNodes(Map nodes) {
|
||||
String result = "";
|
||||
for (Iterator i = nodes.values().iterator(); i.hasNext();) {
|
||||
|
||||
Object value = i.next();
|
||||
if (value instanceof Node) {
|
||||
Node node = (Node) value;
|
||||
result += node.getName() + ",";
|
||||
}
|
||||
else {
|
||||
System.out.println("Got node of type: " + value.getClass());
|
||||
result += value + ",";
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
protected Cluster createCluster() throws JMSException, ClusterException {
|
||||
ClusterFactory factory = new ActiveMQClusterFactory();
|
||||
return factory.createCluster("ORG.CODEHAUS.ACTIVEMQ.TEST.CLUSTER");
|
||||
}
|
||||
|
||||
protected Cluster createCluster(String name) throws JMSException, ClusterException {
|
||||
ClusterFactory factory = new ActiveMQClusterFactory();
|
||||
return factory.createCluster(name,"ORG.CODEHAUS.ACTIVEMQ.TEST.CLUSTER");
|
||||
}
|
||||
}
|
|
@ -1,58 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* 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.activecluster;
|
||||
|
||||
import org.apache.activecluster.Cluster;
|
||||
import org.apache.activecluster.ClusterEvent;
|
||||
import org.apache.activecluster.ClusterListener;
|
||||
import org.apache.activecluster.impl.DefaultCluster;
|
||||
|
||||
/**
|
||||
* @version $Revision: 1.2 $
|
||||
*/
|
||||
public class TestingClusterListener implements ClusterListener {
|
||||
private Cluster cluster;
|
||||
|
||||
public TestingClusterListener(Cluster cluster){
|
||||
this.cluster = cluster;
|
||||
}
|
||||
public void onNodeAdd(ClusterEvent event) {
|
||||
printEvent("ADDED: ", event);
|
||||
}
|
||||
|
||||
public void onNodeUpdate(ClusterEvent event) {
|
||||
printEvent("UPDATED: ", event);
|
||||
}
|
||||
|
||||
public void onNodeRemoved(ClusterEvent event) {
|
||||
printEvent("REMOVED: ", event);
|
||||
}
|
||||
|
||||
public void onNodeFailed(ClusterEvent event) {
|
||||
printEvent("FAILED: ", event);
|
||||
}
|
||||
|
||||
public void onCoordinatorChanged(ClusterEvent event) {
|
||||
printEvent("COORDINATOR: ", event);
|
||||
}
|
||||
|
||||
protected void printEvent(String text, ClusterEvent event) {
|
||||
System.out.println(text + event.getNode());
|
||||
System.out.println("Current cluster is now: " + cluster.getNodes().keySet());
|
||||
}
|
||||
}
|
|
@ -1,75 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* 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.activecluster.group;
|
||||
|
||||
import java.util.List;
|
||||
import javax.jms.JMSException;
|
||||
|
||||
import org.apache.activecluster.group.BuddyGroupModel;
|
||||
import org.apache.activecluster.group.Group;
|
||||
import org.apache.activecluster.group.GroupModel;
|
||||
|
||||
/**
|
||||
* @version $Revision: 1.4 $
|
||||
*/
|
||||
public class BuddyGroupModelTest extends GroupTestSupport {
|
||||
|
||||
public void testGroups() throws Exception {
|
||||
addNode("a");
|
||||
|
||||
// lets check how many groups have been created
|
||||
List groups = model.getGroups();
|
||||
assertEquals("number of groups: " + groups, 1, model.getGroups().size());
|
||||
|
||||
Group group = (Group) model.getGroups().get(0);
|
||||
assertIncomplete(group);
|
||||
|
||||
addNode("b");
|
||||
assertEquals("number of groups: " + groups, 2, model.getGroups().size());
|
||||
|
||||
// lets see if the first node is now complete
|
||||
assertUsable(group);
|
||||
|
||||
group = (Group) model.getGroups().get(1);
|
||||
assertUsable(group);
|
||||
|
||||
|
||||
addNode("c");
|
||||
assertEquals("number of groups: " + groups, 3, model.getGroups().size());
|
||||
group = (Group) model.getGroups().get(2);
|
||||
assertUsable(group);
|
||||
|
||||
|
||||
addNode("d");
|
||||
assertEquals("number of groups: " + groups, 4, model.getGroups().size());
|
||||
group = (Group) model.getGroups().get(3);
|
||||
assertUsable(group);
|
||||
|
||||
}
|
||||
|
||||
public void testRemoveGroups() throws JMSException {
|
||||
String[] nodeNames = {"a", "b", "c"};
|
||||
addNodes(nodeNames);
|
||||
|
||||
// TODO now lets remove the nodes and check group states..
|
||||
}
|
||||
|
||||
protected GroupModel createGroupModel() {
|
||||
return new BuddyGroupModel();
|
||||
}
|
||||
}
|
|
@ -1,62 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* 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.activecluster.group;
|
||||
|
||||
import java.util.List;
|
||||
import javax.jms.JMSException;
|
||||
|
||||
import org.apache.activecluster.group.Group;
|
||||
|
||||
/**
|
||||
* @version $Revision: 1.4 $
|
||||
*/
|
||||
public class GroupModelTest extends GroupTestSupport {
|
||||
|
||||
public void testGroups() throws Exception {
|
||||
addNode("a");
|
||||
|
||||
// lets check how many groups have been created
|
||||
List groups = model.getGroups();
|
||||
assertEquals("number of groups: " + groups, 1, model.getGroups().size());
|
||||
|
||||
Group group = (Group) model.getGroups().get(0);
|
||||
assertIncomplete(group);
|
||||
|
||||
addNode("b");
|
||||
assertNotFullButUsable(group);
|
||||
assertEquals("number of groups: " + groups, 1, model.getGroups().size());
|
||||
|
||||
addNode("c");
|
||||
assertFull(group);
|
||||
assertEquals("number of groups: " + groups, 1, model.getGroups().size());
|
||||
|
||||
|
||||
addNode("d");
|
||||
assertEquals("number of groups: " + groups, 2, model.getGroups().size());
|
||||
group = (Group) model.getGroups().get(1);
|
||||
assertIncomplete(group);
|
||||
}
|
||||
|
||||
public void testRemoveGroups() throws JMSException {
|
||||
String[] nodeNames = {"a", "b", "c"};
|
||||
addNodes(nodeNames);
|
||||
|
||||
// TODO now lets remove the nodes and check group states..
|
||||
}
|
||||
|
||||
}
|
|
@ -1,84 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* 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.activecluster.group;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import javax.jms.JMSException;
|
||||
import junit.framework.TestCase;
|
||||
import org.apache.activecluster.Cluster;
|
||||
import org.apache.activecluster.ClusterEvent;
|
||||
import org.apache.activecluster.ClusterListener;
|
||||
import org.apache.activecluster.DestinationMarshaller;
|
||||
import org.apache.activecluster.Node;
|
||||
import org.apache.activecluster.impl.NodeImpl;
|
||||
import org.apache.activecluster.impl.SimpleDestinationMarshaller;
|
||||
|
||||
/**
|
||||
* A base class for Group model testing
|
||||
*
|
||||
* @version $Revision: 1.5 $
|
||||
*/
|
||||
public abstract class GroupTestSupport extends TestCase {
|
||||
|
||||
protected GroupModel model;
|
||||
private ClusterListener listener;
|
||||
private Cluster cluster;
|
||||
private Map nodes = new HashMap();
|
||||
private DestinationMarshaller marshaller = new SimpleDestinationMarshaller();
|
||||
|
||||
protected void addNodes(String[] nodeNames) throws JMSException {
|
||||
for (int i = 0; i < nodeNames.length; i++) {
|
||||
String nodeName = nodeNames[i];
|
||||
addNode(nodeName);
|
||||
}
|
||||
}
|
||||
|
||||
protected void addNode(String nodeName) throws JMSException {
|
||||
|
||||
Node node = new NodeImpl(nodeName,marshaller.getDestination(nodeName));
|
||||
nodes.put(nodeName, node);
|
||||
listener.onNodeAdd(new ClusterEvent(cluster, node, ClusterEvent.ADD_NODE));
|
||||
}
|
||||
|
||||
protected void assertFull(Group group) {
|
||||
assertTrue("Group is not full and usable. Members: " + group.getMembers(), group.isFull() && group.isUsable());
|
||||
}
|
||||
|
||||
protected void assertNotFullButUsable(Group group) {
|
||||
assertTrue("Group is not not full but usable. Members: " + group.getMembers(), !group.isFull() && group.isUsable());
|
||||
}
|
||||
|
||||
protected void assertIncomplete(Group group) {
|
||||
assertTrue("Group is not not full or usable. Members: " + group.getMembers(), !group.isFull() && !group.isUsable());
|
||||
}
|
||||
|
||||
protected void assertUsable(Group group) {
|
||||
assertTrue("Group is not usable. Members: " + group.getMembers(), group.isUsable());
|
||||
}
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
model = createGroupModel();
|
||||
listener = new GroupClusterListener(model);
|
||||
}
|
||||
|
||||
protected GroupModel createGroupModel() {
|
||||
return new GroupModel();
|
||||
}
|
||||
}
|
|
@ -1,203 +0,0 @@
|
|||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed 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.
|
||||
|
|
@ -1,15 +0,0 @@
|
|||
====================================================================
|
||||
Building with Maven 2
|
||||
====================================================================
|
||||
|
||||
This module require you to manually install the ibmaio jar into your local maven 2 repository.
|
||||
|
||||
download the package from ibm here;
|
||||
https://www7b.software.ibm.com/dl/AW-0H8/AW-0H8-p
|
||||
|
||||
unpack the zip and install the file like this;
|
||||
mvn install:install-file -Dfile=./ibmaio.jar -DartifactId=ibmaio -DgroupId=com.ibm.io -Dversion=20040616 -Dpackaging=jar
|
||||
|
||||
You should now be able to build this module with maven using:
|
||||
|
||||
mvn install
|
|
@ -1,44 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
<project default="default" xmlns:j="jelly:core" xmlns:ant="jelly:ant">
|
||||
|
||||
<goal name="default">
|
||||
<attainGoal name="jar:install"/>
|
||||
</goal>
|
||||
|
||||
<preGoal name="test:test">
|
||||
<j:choose>
|
||||
<j:when test="${context.getVariable('os.name').startsWith('Windows')}">
|
||||
<ant:copy todir=".">
|
||||
<ant:fileset dir="${maven.repo.local}/ibmaio/libs/win32" includes="*.dll"/>
|
||||
</ant:copy>
|
||||
</j:when>
|
||||
<j:when test="${context.getVariable('os.name').startsWith('Linux') and context.getVariable('os.version').startsWith('2.6.')}">
|
||||
<ant:copy todir=".">
|
||||
<ant:fileset dir="${maven.repo.local}/ibmaio/libs/linux32" includes="*.so"/>
|
||||
</ant:copy>
|
||||
<j:set var="maven.junit.jvmargs" value="${maven.junit.jvmargs} -Djava.library.path=."/>
|
||||
</j:when>
|
||||
<j:otherwise>
|
||||
<echo>Diabling IBM AIO tests since your platform (${context.getVariable('os.name')} ${context.getVariable('os.version')}) is not recognized</echo>
|
||||
<j:set var="maven.junit.jvmargs" value="${maven.junit.jvmargs} -Ddisable.aio.tests=true"/>
|
||||
</j:otherwise>
|
||||
</j:choose>
|
||||
</preGoal>
|
||||
|
||||
</project>
|
|
@ -1,53 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.apache.activemq</groupId>
|
||||
<artifactId>activeio</artifactId>
|
||||
<version>3.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>activeio-aio</artifactId>
|
||||
<name>ActiveIO :: AIO</name>
|
||||
|
||||
<dependencies>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.activemq</groupId>
|
||||
<artifactId>activeio-core</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.activemq</groupId>
|
||||
<artifactId>activeio-core</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<type>test-jar</type>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.ibm.io</groupId>
|
||||
<artifactId>ibmaio</artifactId>
|
||||
<version>20040616</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
</project>
|
|
@ -1,21 +0,0 @@
|
|||
##---------------------------------------------------------------------------
|
||||
## 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.
|
||||
##---------------------------------------------------------------------------
|
||||
|
||||
maven.repo.remote=http://tranql.codehaus.org/maven,http://www.openejb.org/maven,http://www.ibiblio.org/maven
|
||||
|
||||
maven.multiproject.type=jar
|
||||
maven.eclipse.classpath.include=src/main/resources,src/test/resources
|
|
@ -1,77 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE project>
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
<project>
|
||||
|
||||
<pomVersion>3</pomVersion>
|
||||
<extend>${basedir}/../../etc/project.xml</extend>
|
||||
|
||||
<name>ActiveIO :: AIO</name>
|
||||
<artifactId>activeio-aio</artifactId>
|
||||
<currentVersion>3.0-SNAPSHOT</currentVersion>
|
||||
|
||||
<dependencies>
|
||||
<!-- Required Dependencies -->
|
||||
<dependency>
|
||||
<groupId>activemq</groupId>
|
||||
<artifactId>activeio-core</artifactId>
|
||||
<version>${pom.currentVersion}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>backport-util-concurrent</groupId>
|
||||
<artifactId>backport-util-concurrent</artifactId>
|
||||
<version>2.0_01_pd</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>ibmaio</groupId>
|
||||
<artifactId>ibmaio</artifactId>
|
||||
<version>1.0</version>
|
||||
<url>https://www7b.software.ibm.com/dl/AW-0H8/AW-0H8-p</url>
|
||||
</dependency>
|
||||
|
||||
<!-- Unit Test Dependencies -->
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>${junit_version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-logging</groupId>
|
||||
<artifactId>commons-logging</artifactId>
|
||||
<version>${commons_logging_version}</version>
|
||||
<url>http://jakarta.apache.org/commons/logging/</url>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>log4j</groupId>
|
||||
<artifactId>log4j</artifactId>
|
||||
<version>${log4j_version}</version>
|
||||
<url>http://jakarta.apache.org/log4j</url>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>activemq</groupId>
|
||||
<artifactId>activeio-core-test</artifactId>
|
||||
<version>${pom.currentVersion}</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
|
|
@ -1,263 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* 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.activeio.packet.async.aio;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InterruptedIOException;
|
||||
import java.net.InetAddress;
|
||||
import java.net.Socket;
|
||||
import java.net.SocketAddress;
|
||||
import java.net.SocketException;
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import org.apache.activeio.packet.ByteBufferPacket;
|
||||
import org.apache.activeio.packet.EOSPacket;
|
||||
import org.apache.activeio.packet.Packet;
|
||||
import org.apache.activeio.packet.async.AsyncChannel;
|
||||
import org.apache.activeio.packet.async.AsyncChannelListener;
|
||||
import org.apache.activeio.stream.sync.socket.SocketMetadata;
|
||||
|
||||
import edu.emory.mathcs.backport.java.util.concurrent.CountDownLatch;
|
||||
import edu.emory.mathcs.backport.java.util.concurrent.TimeUnit;
|
||||
import edu.emory.mathcs.backport.java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
import com.ibm.io.async.AsyncSocketChannel;
|
||||
import com.ibm.io.async.IAbstractAsyncFuture;
|
||||
import com.ibm.io.async.IAsyncFuture;
|
||||
import com.ibm.io.async.ICompletionListener;
|
||||
|
||||
/**
|
||||
* @version $Revision$
|
||||
*/
|
||||
final public class AIOAsyncChannel implements AsyncChannel, ICompletionListener, SocketMetadata {
|
||||
|
||||
protected static final int DEFAULT_BUFFER_SIZE = ByteBufferPacket.DEFAULT_DIRECT_BUFFER_SIZE;
|
||||
|
||||
private final AsyncSocketChannel socketChannel;
|
||||
private final Socket socket;
|
||||
|
||||
private AsyncChannelListener channelListener;
|
||||
private ByteBuffer inputByteBuffer;
|
||||
|
||||
private final AtomicBoolean running = new AtomicBoolean(false);
|
||||
private CountDownLatch doneCountDownLatch;
|
||||
|
||||
protected AIOAsyncChannel(AsyncSocketChannel socketChannel) throws IOException {
|
||||
this.socketChannel = socketChannel;
|
||||
this.socket = socketChannel.socket();
|
||||
this.socket.setSendBufferSize(DEFAULT_BUFFER_SIZE);
|
||||
this.socket.setReceiveBufferSize(DEFAULT_BUFFER_SIZE);
|
||||
this.socket.setSoTimeout(0);
|
||||
}
|
||||
|
||||
private ByteBuffer allocateBuffer() {
|
||||
return ByteBuffer.allocateDirect(DEFAULT_BUFFER_SIZE);
|
||||
}
|
||||
|
||||
public void setAsyncChannelListener(AsyncChannelListener channelListener) {
|
||||
this.channelListener = channelListener;
|
||||
}
|
||||
|
||||
public AsyncChannelListener getAsyncChannelListener() {
|
||||
return channelListener;
|
||||
}
|
||||
|
||||
public Object getAdapter(Class target) {
|
||||
if( target.isAssignableFrom(getClass()) ) {
|
||||
return this;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void dispose() {
|
||||
if( running.get() && channelListener!=null ) {
|
||||
channelListener.onPacketError(new SocketException("Socket closed."));
|
||||
}
|
||||
try {
|
||||
stop();
|
||||
} catch (IOException e) {
|
||||
}
|
||||
try {
|
||||
socketChannel.close();
|
||||
} catch (IOException e) {
|
||||
}
|
||||
}
|
||||
|
||||
public void start() throws IOException {
|
||||
if( running.compareAndSet(false, true) ) {
|
||||
doneCountDownLatch = new CountDownLatch(1);
|
||||
requestNextRead();
|
||||
}
|
||||
}
|
||||
|
||||
public void stop() throws IOException {
|
||||
if( running.compareAndSet(true, false) ) {
|
||||
try {
|
||||
doneCountDownLatch.await(5, TimeUnit.SECONDS);
|
||||
} catch (InterruptedException e) {
|
||||
throw new InterruptedIOException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void write(Packet packet) throws IOException {
|
||||
ByteBuffer data = ((ByteBufferPacket)packet).getByteBuffer();
|
||||
while( data.hasRemaining() ) {
|
||||
IAsyncFuture future = socketChannel.write(data);
|
||||
try {
|
||||
future.getByteCount();
|
||||
} catch (InterruptedException e) {
|
||||
throw new InterruptedIOException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void flush() throws IOException {
|
||||
}
|
||||
|
||||
public void futureCompleted(IAbstractAsyncFuture abstractFuture, Object attribute) {
|
||||
IAsyncFuture future = (IAsyncFuture)abstractFuture;
|
||||
try {
|
||||
|
||||
if( inputByteBuffer.position()>0 ) {
|
||||
ByteBuffer remaining = inputByteBuffer.slice();
|
||||
Packet data = new ByteBufferPacket(((ByteBuffer)inputByteBuffer.flip()).slice());
|
||||
|
||||
channelListener.onPacket(data);
|
||||
// Keep the remaining buffer around to fill with data.
|
||||
inputByteBuffer = remaining;
|
||||
requestNextRead();
|
||||
|
||||
} else {
|
||||
channelListener.onPacket(EOSPacket.EOS_PACKET);
|
||||
}
|
||||
|
||||
} catch (IOException e) {
|
||||
channelListener.onPacketError(e);
|
||||
}
|
||||
}
|
||||
|
||||
private void requestNextRead() throws InterruptedIOException {
|
||||
|
||||
// Don't do next read if we have stopped running.
|
||||
if( !running.get() ) {
|
||||
doneCountDownLatch.countDown();
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
|
||||
if( inputByteBuffer==null || !inputByteBuffer.hasRemaining() ) {
|
||||
inputByteBuffer = allocateBuffer();
|
||||
}
|
||||
|
||||
IAsyncFuture future = socketChannel.read(inputByteBuffer);
|
||||
future.addCompletionListener(this, null, false);
|
||||
|
||||
} catch (InterruptedException e) {
|
||||
throw new InterruptedIOException();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public InetAddress getInetAddress() {
|
||||
return socket.getInetAddress();
|
||||
}
|
||||
public boolean getKeepAlive() throws SocketException {
|
||||
return socket.getKeepAlive();
|
||||
}
|
||||
public InetAddress getLocalAddress() {
|
||||
return socket.getLocalAddress();
|
||||
}
|
||||
public int getLocalPort() {
|
||||
return socket.getLocalPort();
|
||||
}
|
||||
public SocketAddress getLocalSocketAddress() {
|
||||
return socket.getLocalSocketAddress();
|
||||
}
|
||||
public boolean getOOBInline() throws SocketException {
|
||||
return socket.getOOBInline();
|
||||
}
|
||||
public int getPort() {
|
||||
return socket.getPort();
|
||||
}
|
||||
public int getReceiveBufferSize() throws SocketException {
|
||||
return socket.getReceiveBufferSize();
|
||||
}
|
||||
public SocketAddress getRemoteSocketAddress() {
|
||||
return socket.getRemoteSocketAddress();
|
||||
}
|
||||
public boolean getReuseAddress() throws SocketException {
|
||||
return socket.getReuseAddress();
|
||||
}
|
||||
public int getSendBufferSize() throws SocketException {
|
||||
return socket.getSendBufferSize();
|
||||
}
|
||||
public int getSoLinger() throws SocketException {
|
||||
return socket.getSoLinger();
|
||||
}
|
||||
public int getSoTimeout() throws SocketException {
|
||||
return socket.getSoTimeout();
|
||||
}
|
||||
public boolean getTcpNoDelay() throws SocketException {
|
||||
return socket.getTcpNoDelay();
|
||||
}
|
||||
public int getTrafficClass() throws SocketException {
|
||||
return socket.getTrafficClass();
|
||||
}
|
||||
public boolean isBound() {
|
||||
return socket.isBound();
|
||||
}
|
||||
public boolean isClosed() {
|
||||
return socket.isClosed();
|
||||
}
|
||||
public boolean isConnected() {
|
||||
return socket.isConnected();
|
||||
}
|
||||
public void setKeepAlive(boolean on) throws SocketException {
|
||||
socket.setKeepAlive(on);
|
||||
}
|
||||
public void setOOBInline(boolean on) throws SocketException {
|
||||
socket.setOOBInline(on);
|
||||
}
|
||||
public void setReceiveBufferSize(int size) throws SocketException {
|
||||
socket.setReceiveBufferSize(size);
|
||||
}
|
||||
public void setReuseAddress(boolean on) throws SocketException {
|
||||
socket.setReuseAddress(on);
|
||||
}
|
||||
public void setSendBufferSize(int size) throws SocketException {
|
||||
socket.setSendBufferSize(size);
|
||||
}
|
||||
public void setSoLinger(boolean on, int linger) throws SocketException {
|
||||
socket.setSoLinger(on, linger);
|
||||
}
|
||||
public void setTcpNoDelay(boolean on) throws SocketException {
|
||||
socket.setTcpNoDelay(on);
|
||||
}
|
||||
public void setTrafficClass(int tc) throws SocketException {
|
||||
socket.setTrafficClass(tc);
|
||||
}
|
||||
public void setSoTimeout(int i) throws SocketException {
|
||||
socket.setSoTimeout(i);
|
||||
}
|
||||
public String toString() {
|
||||
return "AIO Connection: "+getLocalSocketAddress()+" -> "+getRemoteSocketAddress();
|
||||
}
|
||||
|
||||
}
|
|
@ -1,116 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* 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.activeio.packet.async.aio;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.InetAddress;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
|
||||
import org.apache.activeio.adapter.SyncToAsyncChannelServer;
|
||||
import org.apache.activeio.packet.ByteBufferPacket;
|
||||
import org.apache.activeio.packet.async.AsyncChannel;
|
||||
import org.apache.activeio.packet.async.AsyncChannelFactory;
|
||||
import org.apache.activeio.packet.async.AsyncChannelServer;
|
||||
import org.apache.activeio.packet.async.filter.WriteBufferedAsyncChannel;
|
||||
import org.apache.activeio.util.URISupport;
|
||||
|
||||
import com.ibm.io.async.AsyncServerSocketChannel;
|
||||
import com.ibm.io.async.AsyncSocketChannel;
|
||||
|
||||
/**
|
||||
* A TcpAsyncChannelFactory creates {@see org.apache.activeio.net.TcpAsyncChannel}
|
||||
* and {@see org.apache.activeio.net.TcpAsyncChannelServer} objects.
|
||||
*
|
||||
* @version $Revision$
|
||||
*/
|
||||
public class AIOAsyncChannelFactory implements AsyncChannelFactory {
|
||||
|
||||
protected static final int DEFAULT_BACKLOG = 500;
|
||||
private int backlog = DEFAULT_BACKLOG;
|
||||
|
||||
/**
|
||||
* Uses the {@param location}'s host and port to create a tcp connection to a remote host.
|
||||
*
|
||||
* @see org.apache.activeio.AsyncChannelFactory#openAsyncChannel(java.net.URI)
|
||||
*/
|
||||
public AsyncChannel openAsyncChannel(URI location) throws IOException {
|
||||
AsyncSocketChannel channel = AsyncSocketChannel.open();
|
||||
channel.connect(new InetSocketAddress(location.getHost(), location.getPort()));
|
||||
return createAsyncChannel(channel);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param channel
|
||||
* @return
|
||||
* @throws IOException
|
||||
*/
|
||||
protected AsyncChannel createAsyncChannel(AsyncSocketChannel socketChannel) throws IOException {
|
||||
AsyncChannel channel = new AIOAsyncChannel(socketChannel);
|
||||
channel = new WriteBufferedAsyncChannel(channel, ByteBufferPacket.createDefaultBuffer(true), false);
|
||||
return channel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Binds a server socket a the {@param location}'s port.
|
||||
*
|
||||
* @see org.apache.activeio.AsyncChannelFactory#bindAsyncChannel(java.net.URI)
|
||||
*/
|
||||
public AsyncChannelServer bindAsyncChannel(URI bindURI) throws IOException {
|
||||
|
||||
String host = bindURI.getHost();
|
||||
InetSocketAddress address;
|
||||
if( host == null || host.length() == 0 || host.equals("localhost") || host.equals("0.0.0.0") || InetAddress.getLocalHost().getHostName().equals(host) ) {
|
||||
address = new InetSocketAddress(bindURI.getPort());
|
||||
} else {
|
||||
address = new InetSocketAddress(bindURI.getHost(), bindURI.getPort());
|
||||
}
|
||||
|
||||
AsyncServerSocketChannel serverSocketChannel = AsyncServerSocketChannel.open();
|
||||
serverSocketChannel.socket().bind(address,backlog);
|
||||
|
||||
URI connectURI = bindURI;
|
||||
try {
|
||||
// connectURI = URISupport.changeHost(connectURI, InetAddress.getLocalHost().getHostName());
|
||||
connectURI = URISupport.changePort(connectURI, serverSocketChannel.socket().getLocalPort());
|
||||
} catch (URISyntaxException e) {
|
||||
throw (IOException)new IOException("Could not build connect URI: "+e).initCause(e);
|
||||
}
|
||||
|
||||
return SyncToAsyncChannelServer.adapt(
|
||||
new AIOSyncChannelServer(serverSocketChannel, bindURI, connectURI));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Returns the backlog.
|
||||
*/
|
||||
public int getBacklog() {
|
||||
return backlog;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param backlog
|
||||
* The backlog to set.
|
||||
*/
|
||||
public void setBacklog(int backlog) {
|
||||
this.backlog = backlog;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -1,108 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* 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.activeio.packet.async.aio;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.SocketException;
|
||||
import java.net.SocketTimeoutException;
|
||||
import java.net.URI;
|
||||
|
||||
import org.apache.activeio.Channel;
|
||||
import org.apache.activeio.packet.ByteBufferPacket;
|
||||
import org.apache.activeio.packet.async.AsyncChannel;
|
||||
import org.apache.activeio.packet.async.filter.WriteBufferedAsyncChannel;
|
||||
import org.apache.activeio.packet.sync.SyncChannelServer;
|
||||
|
||||
import com.ibm.io.async.AsyncServerSocketChannel;
|
||||
|
||||
/**
|
||||
* @version $Revision$
|
||||
*/
|
||||
public class AIOSyncChannelServer implements SyncChannelServer {
|
||||
|
||||
private final AsyncServerSocketChannel serverSocket;
|
||||
private final URI bindURI;
|
||||
private final URI connectURI;
|
||||
private int curentSoTimeout;
|
||||
|
||||
public AIOSyncChannelServer(AsyncServerSocketChannel serverSocket, URI bindURI, URI connectURI) throws IOException {
|
||||
this.serverSocket=serverSocket;
|
||||
this.bindURI=bindURI;
|
||||
this.connectURI=connectURI;
|
||||
this.curentSoTimeout = serverSocket.socket().getSoTimeout();
|
||||
}
|
||||
|
||||
public URI getBindURI() {
|
||||
return bindURI;
|
||||
}
|
||||
|
||||
public URI getConnectURI() {
|
||||
return this.connectURI;
|
||||
}
|
||||
|
||||
public void dispose() {
|
||||
try {
|
||||
serverSocket.close();
|
||||
} catch (IOException e) {
|
||||
}
|
||||
}
|
||||
|
||||
synchronized public void start() throws IOException {
|
||||
}
|
||||
|
||||
synchronized public void stop() {
|
||||
}
|
||||
|
||||
public Channel accept(long timeout) throws IOException {
|
||||
try {
|
||||
|
||||
if (timeout == SyncChannelServer.WAIT_FOREVER_TIMEOUT)
|
||||
setSoTimeout(0);
|
||||
else if (timeout == SyncChannelServer.NO_WAIT_TIMEOUT)
|
||||
setSoTimeout(1);
|
||||
else
|
||||
setSoTimeout((int) timeout);
|
||||
|
||||
AsyncChannel channel = new AIOAsyncChannel(serverSocket.accept());
|
||||
channel = new WriteBufferedAsyncChannel(channel, ByteBufferPacket.createDefaultBuffer(true), false);
|
||||
return channel;
|
||||
|
||||
} catch (SocketTimeoutException ignore) {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private void setSoTimeout(int i) throws SocketException {
|
||||
if (curentSoTimeout != i) {
|
||||
serverSocket.socket().setSoTimeout(i);
|
||||
curentSoTimeout = i;
|
||||
}
|
||||
}
|
||||
|
||||
public Object getAdapter(Class target) {
|
||||
if( target.isAssignableFrom(getClass()) ) {
|
||||
return this;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "AIO Server: "+getConnectURI();
|
||||
}
|
||||
|
||||
}
|
|
@ -1,7 +0,0 @@
|
|||
ActiveMQ is an effort undergoing incubation at the Apache Software Foundation
|
||||
(ASF), sponsored by the Geronimo PMC. Incubation is required of all newly
|
||||
accepted projects until a further review indicates that the infrastructure,
|
||||
communications, and decision making process have stabilized in a manner
|
||||
consistent with other successful ASF projects. While incubation status is not
|
||||
necessarily a reflection of the completeness or stability of the code, it does
|
||||
indicate that the project has yet to be fully endorsed by the ASF.
|
|
@ -1,203 +0,0 @@
|
|||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed 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.
|
||||
|
|
@ -1 +0,0 @@
|
|||
AsyncChannelFactory.class=org.apache.activeio.packet.async.aio.AIOAsyncChannelFactory
|
|
@ -1,48 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* 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.activeio.packet.async.aio;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
|
||||
import org.apache.activeio.Channel;
|
||||
import org.apache.activeio.ChannelServer;
|
||||
import org.apache.activeio.packet.async.aio.AIOAsyncChannelFactory;
|
||||
import org.apache.activeio.packet.sync.SyncChannelTestSupport;
|
||||
|
||||
/**
|
||||
* @version $Revision$
|
||||
*/
|
||||
public class AIOAsyncChannelTest extends SyncChannelTestSupport {
|
||||
|
||||
static boolean disabled = System.getProperty("disable.aio.tests", "false").equals("true");
|
||||
AIOAsyncChannelFactory factory = new AIOAsyncChannelFactory();
|
||||
|
||||
protected Channel openChannel(URI connectURI) throws IOException {
|
||||
return factory.openAsyncChannel(connectURI);
|
||||
}
|
||||
|
||||
protected ChannelServer bindChannel() throws IOException, URISyntaxException {
|
||||
return factory.bindAsyncChannel(new URI("tcp://localhost:0"));
|
||||
}
|
||||
|
||||
protected boolean isDisabled() {
|
||||
return disabled;
|
||||
}
|
||||
}
|
|
@ -1,112 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* 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.activeio.packet.async.aio;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.apache.activeio.AcceptListener;
|
||||
import org.apache.activeio.Channel;
|
||||
import org.apache.activeio.ChannelFactory;
|
||||
import org.apache.activeio.adapter.AsyncToSyncChannel;
|
||||
import org.apache.activeio.adapter.SyncToAsyncChannel;
|
||||
import org.apache.activeio.packet.async.AsyncChannel;
|
||||
import org.apache.activeio.packet.async.AsyncChannelServer;
|
||||
import org.apache.activeio.packet.async.aio.AIOAsyncChannel;
|
||||
import org.apache.activeio.packet.async.aio.AIOSyncChannelServer;
|
||||
import org.apache.activeio.packet.sync.SyncChannel;
|
||||
import org.apache.activeio.packet.sync.SyncChannelServer;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import edu.emory.mathcs.backport.java.util.concurrent.CountDownLatch;
|
||||
import edu.emory.mathcs.backport.java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
*/
|
||||
public class ChannelFactoryTest extends TestCase {
|
||||
|
||||
static final Log log = LogFactory.getLog(ChannelFactoryTest.class);
|
||||
static boolean aioDisabled = System.getProperty("disable.aio.tests", "false").equals("true");
|
||||
|
||||
ChannelFactory factory = new ChannelFactory();
|
||||
|
||||
private SyncChannelServer syncChannelServer;
|
||||
private SyncChannel clientSynchChannel;
|
||||
private SyncChannel serverSynchChannel;
|
||||
|
||||
private AsyncChannelServer asyncChannelServer;
|
||||
private AsyncChannel clientAsyncChannel;
|
||||
private AsyncChannel serverAsyncChannel;
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
log.info("Running: "+getName());
|
||||
}
|
||||
|
||||
public void testAIO() throws IOException, URISyntaxException, InterruptedException {
|
||||
|
||||
if( aioDisabled ) {
|
||||
return;
|
||||
}
|
||||
|
||||
createSynchObjects("aio://localhost:0");
|
||||
assertNotNull( syncChannelServer.getAdapter(AIOSyncChannelServer.class) );
|
||||
assertNotNull( clientSynchChannel.getAdapter(AIOAsyncChannel.class) );
|
||||
assertNotNull( serverSynchChannel.getAdapter(AIOAsyncChannel.class) );
|
||||
|
||||
createAsynchObjects("aio://localhost:0");
|
||||
assertNotNull( asyncChannelServer.getAdapter(AIOSyncChannelServer.class) );
|
||||
assertNotNull( clientAsyncChannel.getAdapter(AIOAsyncChannel.class) );
|
||||
assertNotNull( serverAsyncChannel.getAdapter(AIOAsyncChannel.class) );
|
||||
|
||||
}
|
||||
|
||||
private void createSynchObjects(String bindURI) throws IOException, URISyntaxException {
|
||||
syncChannelServer = factory.bindSyncChannel(new URI(bindURI));
|
||||
syncChannelServer.start();
|
||||
clientSynchChannel = factory.openSyncChannel(syncChannelServer.getConnectURI());
|
||||
serverSynchChannel = AsyncToSyncChannel.adapt( syncChannelServer.accept(1000*5) );
|
||||
serverSynchChannel.dispose();
|
||||
clientSynchChannel.dispose();
|
||||
syncChannelServer.dispose();
|
||||
}
|
||||
|
||||
private void createAsynchObjects(String bindURI) throws IOException, URISyntaxException, InterruptedException {
|
||||
asyncChannelServer = factory.bindAsyncChannel(new URI(bindURI));
|
||||
final CountDownLatch accepted = new CountDownLatch(1);
|
||||
asyncChannelServer.setAcceptListener(new AcceptListener() {
|
||||
public void onAccept(Channel channel) {
|
||||
serverAsyncChannel = SyncToAsyncChannel.adapt(channel);
|
||||
channel.dispose();
|
||||
accepted.countDown();
|
||||
}
|
||||
public void onAcceptError(IOException error) {
|
||||
error.printStackTrace();
|
||||
}
|
||||
});
|
||||
asyncChannelServer.start();
|
||||
clientAsyncChannel = factory.openAsyncChannel(asyncChannelServer.getConnectURI());
|
||||
accepted.await(1000*10, TimeUnit.MILLISECONDS);
|
||||
clientAsyncChannel.dispose();
|
||||
asyncChannelServer.dispose();
|
||||
}
|
||||
|
||||
}
|
|
@ -1,203 +0,0 @@
|
|||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed 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.
|
||||
|
|
@ -1,131 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
<project>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.apache.activemq</groupId>
|
||||
<artifactId>activeio</artifactId>
|
||||
<version>3.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>activeio-core</artifactId>
|
||||
<name>ActiveIO :: Core</name>
|
||||
<description>A high performance IO abstraction framework</description>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
|
||||
<!-- generate the attached tests jar -->
|
||||
<plugin>
|
||||
<artifactId>maven-jar-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>test-jar</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
|
||||
<!-- Configure which tests are included/excuded -->
|
||||
<plugin>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<configuration>
|
||||
<includes>
|
||||
<include>**/*Test.*</include>
|
||||
</includes>
|
||||
<excludes>
|
||||
<!-- This test often hangs -->
|
||||
<exclude>**/ChannelFactoryTest.*</exclude>
|
||||
|
||||
<!-- This test often fails on unix -->
|
||||
<exclude>**/NIOAsyncChannelTest.*</exclude>
|
||||
</excludes>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<dependencies>
|
||||
<!-- Required Dependencies -->
|
||||
<dependency>
|
||||
<groupId>backport-util-concurrent</groupId>
|
||||
<artifactId>backport-util-concurrent</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>commons-logging</groupId>
|
||||
<artifactId>commons-logging</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- For HOWL integration -->
|
||||
<dependency>
|
||||
<groupId>howl</groupId>
|
||||
<artifactId>howl-logger</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>log4j</groupId>
|
||||
<artifactId>log4j</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>commons-beanutils</groupId>
|
||||
<artifactId>commons-beanutils</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-collections</groupId>
|
||||
<artifactId>commons-collections</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- Used by xnet GBean code -->
|
||||
<dependency>
|
||||
<groupId>geronimo</groupId>
|
||||
<artifactId>geronimo-kernel</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>geronimo</groupId>
|
||||
<artifactId>geronimo-j2ee</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>jdk1.4</id>
|
||||
<activation>
|
||||
<jdk>1.4</jdk>
|
||||
</activation>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>mx4j</groupId>
|
||||
<artifactId>mx4j</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</profile>
|
||||
</profiles>
|
||||
|
||||
</project>
|
|
@ -1,45 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* 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.activeio;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
|
||||
/**
|
||||
* An AcceptListener object is used to receive accepted {@see org.apache.activeio.Channel} connections.
|
||||
*
|
||||
* @version $Revision$
|
||||
*/
|
||||
public interface AcceptListener {
|
||||
|
||||
/**
|
||||
* A {@see AsyncChannelServer} will call this method to when a new channel connection has been
|
||||
* accepted.
|
||||
*
|
||||
* @param channel
|
||||
*/
|
||||
void onAccept(Channel channel);
|
||||
|
||||
/**
|
||||
* A {@see AsyncChannelServer} will call this method when a async failure occurs when accepting
|
||||
* a connection.
|
||||
*
|
||||
* @param error the exception that describes the failure.
|
||||
*/
|
||||
void onAcceptError(IOException error);
|
||||
}
|
|
@ -1,36 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* 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.activeio;
|
||||
|
||||
|
||||
/**
|
||||
* Provides an Adaptable interface inspired by eclipse's IAdaptable class. Highly used in ActiveIO since Channel and Packet
|
||||
* implementations may be layered and application code may want request the higher level layers/abstractions to adapt to give access
|
||||
* to the lower layer implementation details.
|
||||
*
|
||||
* @version $Revision$
|
||||
*/
|
||||
public interface Adaptable {
|
||||
|
||||
/**
|
||||
* @Return object that is an instance of requested type and is associated this this object. May return null if no
|
||||
* object of that type is associated.
|
||||
*/
|
||||
Object getAdapter(Class target);
|
||||
}
|
|
@ -1,32 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* 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.activeio;
|
||||
|
||||
|
||||
/**
|
||||
* A Channel provides a standard procedure for regulating data transmission between
|
||||
* applications.
|
||||
*
|
||||
* The activeio API encourages that layered wire protocols be created by wiring
|
||||
* together a chain of Channel objects.
|
||||
*
|
||||
* @version $Revision$
|
||||
*/
|
||||
public interface Channel extends Service, Adaptable {
|
||||
}
|
|
@ -1,145 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* 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.activeio;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.util.HashMap;
|
||||
|
||||
import org.apache.activeio.adapter.AsyncToSyncChannelFactory;
|
||||
import org.apache.activeio.adapter.SyncToAsyncChannelFactory;
|
||||
import org.apache.activeio.packet.async.AsyncChannel;
|
||||
import org.apache.activeio.packet.async.AsyncChannelFactory;
|
||||
import org.apache.activeio.packet.async.AsyncChannelServer;
|
||||
import org.apache.activeio.packet.sync.SyncChannel;
|
||||
import org.apache.activeio.packet.sync.SyncChannelFactory;
|
||||
import org.apache.activeio.packet.sync.SyncChannelServer;
|
||||
import org.apache.activeio.util.FactoryFinder;
|
||||
|
||||
import edu.emory.mathcs.backport.java.util.concurrent.Executor;
|
||||
import edu.emory.mathcs.backport.java.util.concurrent.SynchronousQueue;
|
||||
import edu.emory.mathcs.backport.java.util.concurrent.ThreadFactory;
|
||||
import edu.emory.mathcs.backport.java.util.concurrent.ThreadPoolExecutor;
|
||||
import edu.emory.mathcs.backport.java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* A {@see ChannelFactory}uses the requested URI's scheme to determine the
|
||||
* actual {@see org.apache.activeio.SynchChannelFactory}or
|
||||
* {@see org.apache.activeio.AsyncChannelFactory}implementation to use to create it's
|
||||
* {@see org.apache.activeio.Channel}s and {@see org.apache.activeio.ChannelServer}s.
|
||||
*
|
||||
* Each URI scheme that {@see ChannelFactory}object handles will have a
|
||||
* properties file located at: "META-INF/services/org/apache/activeio/channel/{scheme}".
|
||||
*
|
||||
*/
|
||||
public class ChannelFactory implements SyncChannelFactory, AsyncChannelFactory {
|
||||
|
||||
private final HashMap syncChannelFactoryMap = new HashMap();
|
||||
private final HashMap asyncChannelFactoryMap = new HashMap();
|
||||
|
||||
|
||||
static public final Executor DEFAULT_EXECUTOR = new ThreadPoolExecutor(10, Integer.MAX_VALUE, 5, TimeUnit.SECONDS, new SynchronousQueue());
|
||||
static {
|
||||
((ThreadPoolExecutor) DEFAULT_EXECUTOR).setThreadFactory(new ThreadFactory() {
|
||||
public Thread newThread(Runnable run) {
|
||||
Thread thread = new Thread(run);
|
||||
thread.setDaemon(true);
|
||||
return thread;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static FactoryFinder finder = new FactoryFinder("META-INF/services/org/apache/activeio/channel/");
|
||||
|
||||
public SyncChannel openSyncChannel(URI location) throws IOException {
|
||||
SyncChannelFactory factory = getSynchChannelFactory(location.getScheme());
|
||||
return factory.openSyncChannel(location);
|
||||
}
|
||||
|
||||
public SyncChannelServer bindSyncChannel(URI location) throws IOException {
|
||||
SyncChannelFactory factory = getSynchChannelFactory(location.getScheme());
|
||||
return factory.bindSyncChannel(location);
|
||||
}
|
||||
|
||||
public AsyncChannel openAsyncChannel(URI location) throws IOException {
|
||||
AsyncChannelFactory factory = getAsyncChannelFactory(location.getScheme());
|
||||
return factory.openAsyncChannel(location);
|
||||
}
|
||||
|
||||
public AsyncChannelServer bindAsyncChannel(URI location) throws IOException {
|
||||
AsyncChannelFactory factory = getAsyncChannelFactory(location.getScheme());
|
||||
return factory.bindAsyncChannel(location);
|
||||
}
|
||||
|
||||
private SyncChannelFactory getSynchChannelFactory(String protocol) throws IOException {
|
||||
try {
|
||||
SyncChannelFactory rc = (SyncChannelFactory) syncChannelFactoryMap.get(protocol);
|
||||
if (rc == null) {
|
||||
try {
|
||||
rc = (SyncChannelFactory) finder.newInstance(protocol, "SyncChannelFactory.");
|
||||
} catch (Throwable original) {
|
||||
// try to recovery by using AsyncChannelFactory and adapt
|
||||
// it to be sync.
|
||||
try {
|
||||
AsyncChannelFactory f = (AsyncChannelFactory) finder.newInstance(protocol,
|
||||
"AsyncChannelFactory.");
|
||||
rc = AsyncToSyncChannelFactory.adapt(f);
|
||||
} catch (Throwable e) {
|
||||
// Recovery strategy failed.. throw original exception.
|
||||
throw original;
|
||||
}
|
||||
}
|
||||
syncChannelFactoryMap.put(protocol, rc);
|
||||
}
|
||||
return rc;
|
||||
} catch (Throwable e) {
|
||||
throw (IOException) new IOException("Could not load a SyncChannelFactory for protcol: " + protocol
|
||||
+ ", reason: " + e).initCause(e);
|
||||
}
|
||||
}
|
||||
|
||||
private AsyncChannelFactory getAsyncChannelFactory(String protocol) throws IOException {
|
||||
try {
|
||||
AsyncChannelFactory rc = (AsyncChannelFactory) asyncChannelFactoryMap.get(protocol);
|
||||
if (rc == null) {
|
||||
|
||||
try {
|
||||
rc = (AsyncChannelFactory) finder.newInstance(protocol, "AsyncChannelFactory.");
|
||||
} catch (Throwable original) {
|
||||
// try to recovery by using SynchChannelFactory and adapt it
|
||||
// to be async.
|
||||
try {
|
||||
SyncChannelFactory f = (SyncChannelFactory) finder.newInstance(protocol,
|
||||
"SyncChannelFactory.");
|
||||
rc = SyncToAsyncChannelFactory.adapt(f);
|
||||
} catch (Throwable e) {
|
||||
// Recovery strategy failed.. throw original exception.
|
||||
throw original;
|
||||
}
|
||||
}
|
||||
|
||||
asyncChannelFactoryMap.put(protocol, rc);
|
||||
}
|
||||
return rc;
|
||||
} catch (Throwable e) {
|
||||
throw (IOException) new IOException("Could not load a AsyncChannelFactory for protcol: " + protocol
|
||||
+ ", reason: " + e).initCause(e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,52 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* 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.activeio;
|
||||
|
||||
import java.net.URI;
|
||||
|
||||
/**
|
||||
* A ChannelServer is used to accept incoming requests to establish new Channel sessions.
|
||||
*
|
||||
* Like a normal {@see org.apache.activeio.Channel}, A ChannelServer comes in two falvors, either:
|
||||
* {@see org.apache.activeio.AsyncChannelServer} or
|
||||
* {@see org.apache.activeio.SynchChannelServer}.
|
||||
*
|
||||
* @version $Revision$
|
||||
*/
|
||||
public interface ChannelServer extends Service, Adaptable {
|
||||
|
||||
/**
|
||||
* The URI that was used when the channel was bound. This could be different
|
||||
* than what is used by a client to connect to the ChannelServer. For example,
|
||||
* the bind URI might be tcp://localhost:0 which means the channel should bind to
|
||||
* an anonymous port.
|
||||
*
|
||||
* @return The URI that was used when the channel was bound
|
||||
*/
|
||||
public URI getBindURI();
|
||||
|
||||
/**
|
||||
* Once bound, the channel may be able to construct a URI that is more sutible for when
|
||||
* a client needs to connect to the server. For examle the port of the URI may be
|
||||
* updated to reflect the actual local port that the channel server is listening on.
|
||||
*
|
||||
* @return a URI that a client can use to connect to the server or null if the channel cannot construct the URI.
|
||||
*/
|
||||
public URI getConnectURI();
|
||||
|
||||
}
|
|
@ -1,29 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* 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.activeio;
|
||||
|
||||
|
||||
/**
|
||||
* @version $Revision$
|
||||
*/
|
||||
public interface Disposable {
|
||||
|
||||
/**
|
||||
*/
|
||||
void dispose();
|
||||
}
|
|
@ -1,57 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* 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.activeio;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* The Service interface is used control the running state of a channel.
|
||||
*
|
||||
* Some channels may use background threads to provide SEDA style processing. By
|
||||
* implenting the Service interface, a protcol can allow a container to
|
||||
* control those threads.
|
||||
*
|
||||
* @version $Revision$
|
||||
*/
|
||||
public interface Service {
|
||||
|
||||
static final public long NO_WAIT_TIMEOUT=0;
|
||||
static final public long WAIT_FOREVER_TIMEOUT=-1;
|
||||
|
||||
/**
|
||||
* Starts the channel. Once started, the channel is in the running state.
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
void start() throws IOException;
|
||||
|
||||
/**
|
||||
* Stops the channel. Once stopped, the channel is in the stopped state.
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
void stop() throws IOException;
|
||||
|
||||
/**
|
||||
* Disposes the channel. Once disposed, the channel cannot be used anymore.
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
void dispose();
|
||||
}
|
|
@ -1,73 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* 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.activeio.adapter;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
|
||||
import org.apache.activeio.packet.ByteArrayPacket;
|
||||
import org.apache.activeio.packet.BytePacket;
|
||||
import org.apache.activeio.packet.async.AsyncChannel;
|
||||
|
||||
/**
|
||||
*/
|
||||
public class AsyncChannelToOutputStream extends OutputStream {
|
||||
|
||||
private final AsyncChannel channel;
|
||||
private boolean closed;
|
||||
|
||||
/**
|
||||
* @param channel
|
||||
*/
|
||||
public AsyncChannelToOutputStream(AsyncChannel channel) {
|
||||
this.channel = channel;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see java.io.OutputStream#write(int)
|
||||
*/
|
||||
public void write(int b) throws IOException {
|
||||
channel.write(new BytePacket((byte) b));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see java.io.OutputStream#write(byte[], int, int)
|
||||
*/
|
||||
public void write(byte[] b, int off, int len) throws IOException {
|
||||
channel.write(new ByteArrayPacket(b, off, len));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see java.io.OutputStream#flush()
|
||||
*/
|
||||
public void flush() throws IOException {
|
||||
channel.flush();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see java.io.InputStream#close()
|
||||
*/
|
||||
public void close() throws IOException {
|
||||
closed=true;
|
||||
super.close();
|
||||
}
|
||||
|
||||
public boolean isClosed() {
|
||||
return closed;
|
||||
}
|
||||
}
|
|
@ -1,181 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* 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.activeio.adapter;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InterruptedIOException;
|
||||
|
||||
import org.apache.activeio.packet.Packet;
|
||||
import org.apache.activeio.packet.async.AsyncChannel;
|
||||
import org.apache.activeio.packet.async.AsyncChannelListener;
|
||||
import org.apache.activeio.packet.sync.SyncChannel;
|
||||
|
||||
import edu.emory.mathcs.backport.java.util.concurrent.BlockingQueue;
|
||||
import edu.emory.mathcs.backport.java.util.concurrent.LinkedBlockingQueue;
|
||||
import edu.emory.mathcs.backport.java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* Adapts a {@see org.apache.activeio.AsyncChannel} so that it provides an
|
||||
* {@see org.apache.activeio.SynchChannel} interface.
|
||||
*
|
||||
* This object buffers asynchronous messages from the {@see org.apache.activeio.AsyncChannel}
|
||||
* and buffers them in a {@see edu.emory.mathcs.backport.java.util.concurrent.Channel} util the client receives them.
|
||||
*
|
||||
* @version $Revision$
|
||||
*/
|
||||
final public class AsyncToSyncChannel implements SyncChannel, AsyncChannelListener {
|
||||
|
||||
private final AsyncChannel asyncChannel;
|
||||
private final BlockingQueue buffer;
|
||||
|
||||
static public SyncChannel adapt(org.apache.activeio.Channel channel) {
|
||||
return adapt(channel, new LinkedBlockingQueue());
|
||||
}
|
||||
|
||||
static public SyncChannel adapt(org.apache.activeio.Channel channel, BlockingQueue upPacketChannel) {
|
||||
|
||||
// It might not need adapting
|
||||
if( channel instanceof SyncChannel ) {
|
||||
return (SyncChannel) channel;
|
||||
}
|
||||
|
||||
// Can we just just undo the adaptor
|
||||
if( channel.getClass() == SyncToAsyncChannel.class ) {
|
||||
return ((SyncToAsyncChannel)channel).getSynchChannel();
|
||||
}
|
||||
|
||||
return new AsyncToSyncChannel((AsyncChannel)channel, upPacketChannel);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated {@see #adapt(AsyncChannel)}
|
||||
*/
|
||||
public AsyncToSyncChannel(AsyncChannel asyncChannel) {
|
||||
this(asyncChannel, new LinkedBlockingQueue());
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated {@see #adapt(AsyncChannel, Channel)}
|
||||
*/
|
||||
public AsyncToSyncChannel(AsyncChannel asyncChannel, BlockingQueue upPacketChannel){
|
||||
this.asyncChannel = asyncChannel;
|
||||
this.asyncChannel.setAsyncChannelListener(this);
|
||||
this.buffer=upPacketChannel;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.apache.activeio.Channel#write(org.apache.activeio.packet.Packet)
|
||||
*/
|
||||
public void write(org.apache.activeio.packet.Packet packet) throws IOException {
|
||||
asyncChannel.write(packet);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.apache.activeio.Channel#flush()
|
||||
*/
|
||||
public void flush() throws IOException {
|
||||
asyncChannel.flush();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.apache.activeio.packet.sync.SyncChannel#read(long)
|
||||
*/
|
||||
public Packet read(long timeout) throws IOException {
|
||||
try {
|
||||
|
||||
Object o;
|
||||
if( timeout == NO_WAIT_TIMEOUT ) {
|
||||
o = buffer.poll(0, TimeUnit.MILLISECONDS);
|
||||
} else if( timeout == WAIT_FOREVER_TIMEOUT ) {
|
||||
o = buffer.take();
|
||||
} else {
|
||||
o = buffer.poll(timeout, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
|
||||
if( o == null )
|
||||
return null;
|
||||
|
||||
if( o instanceof Packet )
|
||||
return (Packet)o;
|
||||
|
||||
Throwable e = (Throwable)o;
|
||||
throw (IOException)new IOException("Async error occurred: "+e).initCause(e);
|
||||
|
||||
} catch (InterruptedException e) {
|
||||
throw new InterruptedIOException(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.apache.activeio.Disposable#dispose()
|
||||
*/
|
||||
public void dispose() {
|
||||
asyncChannel.dispose();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.apache.activeio.Service#start()
|
||||
*/
|
||||
public void start() throws IOException {
|
||||
asyncChannel.start();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.apache.activeio.Service#stop()
|
||||
*/
|
||||
public void stop() throws IOException {
|
||||
asyncChannel.stop();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.apache.activeio.packet.async.AsyncChannelListener#onPacket(org.apache.activeio.packet.Packet)
|
||||
*/
|
||||
public void onPacket(Packet packet) {
|
||||
try {
|
||||
buffer.put(packet);
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.apache.activeio.packet.async.AsyncChannelListener#onPacketError(org.apache.activeio.ChannelException)
|
||||
*/
|
||||
public void onPacketError(IOException error) {
|
||||
try {
|
||||
buffer.put(error);
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
}
|
||||
|
||||
public Object getAdapter(Class target) {
|
||||
if( target.isAssignableFrom(getClass()) ) {
|
||||
return this;
|
||||
}
|
||||
return asyncChannel.getAdapter(target);
|
||||
}
|
||||
|
||||
public AsyncChannel getAsyncChannel() {
|
||||
return asyncChannel;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return asyncChannel.toString();
|
||||
}
|
||||
}
|
|
@ -1,66 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* 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.activeio.adapter;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
|
||||
import org.apache.activeio.packet.async.AsyncChannelFactory;
|
||||
import org.apache.activeio.packet.sync.SyncChannel;
|
||||
import org.apache.activeio.packet.sync.SyncChannelFactory;
|
||||
import org.apache.activeio.packet.sync.SyncChannelServer;
|
||||
|
||||
/**
|
||||
* @version $Revision$
|
||||
*/
|
||||
final public class AsyncToSyncChannelFactory implements SyncChannelFactory {
|
||||
|
||||
private AsyncChannelFactory asyncChannelFactory;
|
||||
|
||||
static public SyncChannelFactory adapt(AsyncChannelFactory channelFactory ) {
|
||||
|
||||
// It might not need adapting
|
||||
if( channelFactory instanceof SyncChannelServer ) {
|
||||
return (SyncChannelFactory) channelFactory;
|
||||
}
|
||||
|
||||
// Can we just just undo the adaptor
|
||||
if( channelFactory.getClass() == SyncToAsyncChannelFactory.class ) {
|
||||
return ((SyncToAsyncChannelFactory)channelFactory).getSyncChannelFactory();
|
||||
}
|
||||
|
||||
return new AsyncToSyncChannelFactory((AsyncChannelFactory)channelFactory);
|
||||
}
|
||||
|
||||
|
||||
private AsyncToSyncChannelFactory(AsyncChannelFactory asyncChannelFactory) {
|
||||
this.asyncChannelFactory = asyncChannelFactory;
|
||||
}
|
||||
|
||||
public SyncChannel openSyncChannel(URI location) throws IOException {
|
||||
return AsyncToSyncChannel.adapt( asyncChannelFactory.openAsyncChannel(location) );
|
||||
}
|
||||
|
||||
public SyncChannelServer bindSyncChannel(URI location) throws IOException {
|
||||
return AsyncToSyncChannelServer.adapt(asyncChannelFactory.bindAsyncChannel(location));
|
||||
}
|
||||
|
||||
public AsyncChannelFactory getAsyncChannelFactory() {
|
||||
return asyncChannelFactory;
|
||||
}
|
||||
}
|
|
@ -1,177 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* 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.activeio.adapter;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InterruptedIOException;
|
||||
import java.net.URI;
|
||||
|
||||
import org.apache.activeio.AcceptListener;
|
||||
import org.apache.activeio.Channel;
|
||||
import org.apache.activeio.ChannelServer;
|
||||
import org.apache.activeio.packet.async.AsyncChannelServer;
|
||||
import org.apache.activeio.packet.sync.SyncChannelServer;
|
||||
|
||||
import edu.emory.mathcs.backport.java.util.concurrent.BlockingQueue;
|
||||
import edu.emory.mathcs.backport.java.util.concurrent.LinkedBlockingQueue;
|
||||
import edu.emory.mathcs.backport.java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* Adapts a {@see org.apache.activeio.AsyncChannelServer} so that it provides an
|
||||
* {@see org.apache.activeio.SynchChannelServer} interface.
|
||||
*
|
||||
* This object buffers asynchronous accepts from the {@see org.apache.activeio.AsyncChannelServer}
|
||||
* abs buffers them in a {@see edu.emory.mathcs.backport.java.util.concurrent.Channel} util the client accepts the
|
||||
* connection.
|
||||
*
|
||||
* @version $Revision$
|
||||
*/
|
||||
final public class AsyncToSyncChannelServer implements SyncChannelServer, AcceptListener {
|
||||
|
||||
private final AsyncChannelServer asyncChannelServer;
|
||||
private final BlockingQueue acceptBuffer;
|
||||
|
||||
static public SyncChannelServer adapt(ChannelServer channel) {
|
||||
return adapt(channel, new LinkedBlockingQueue());
|
||||
}
|
||||
|
||||
static public SyncChannelServer adapt(ChannelServer channel, BlockingQueue upPacketChannel) {
|
||||
|
||||
// It might not need adapting
|
||||
if( channel instanceof SyncChannelServer ) {
|
||||
return (SyncChannelServer) channel;
|
||||
}
|
||||
|
||||
// Can we just just undo the adaptor
|
||||
if( channel.getClass() == SyncToAsyncChannelServer.class ) {
|
||||
return ((SyncToAsyncChannelServer)channel).getSynchChannelServer();
|
||||
}
|
||||
|
||||
return new AsyncToSyncChannelServer((AsyncChannelServer)channel, upPacketChannel);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated {@see #adapt(ChannelServer)}
|
||||
*/
|
||||
public AsyncToSyncChannelServer(AsyncChannelServer asyncChannelServer) {
|
||||
this(asyncChannelServer,new LinkedBlockingQueue());
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated {@see #adapt(ChannelServer, edu.emory.mathcs.backport.java.util.concurrent.Channel)}
|
||||
*/
|
||||
public AsyncToSyncChannelServer(AsyncChannelServer asyncChannelServer, BlockingQueue acceptBuffer) {
|
||||
this.asyncChannelServer = asyncChannelServer;
|
||||
this.acceptBuffer=acceptBuffer;
|
||||
this.asyncChannelServer.setAcceptListener(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.apache.activeio.packet.sync.SyncChannelServer#accept(long)
|
||||
*/
|
||||
public org.apache.activeio.Channel accept(long timeout) throws IOException {
|
||||
try {
|
||||
|
||||
Object o;
|
||||
if( timeout == NO_WAIT_TIMEOUT ) {
|
||||
o = acceptBuffer.poll(0, TimeUnit.MILLISECONDS);
|
||||
} else if( timeout == WAIT_FOREVER_TIMEOUT ) {
|
||||
o = acceptBuffer.take();
|
||||
} else {
|
||||
o = acceptBuffer.poll(timeout, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
|
||||
if( o == null )
|
||||
return null;
|
||||
|
||||
if( o instanceof Channel )
|
||||
return (Channel)o;
|
||||
|
||||
Throwable e = (Throwable)o;
|
||||
throw (IOException)new IOException("Async error occurred: "+e).initCause(e);
|
||||
|
||||
} catch (InterruptedException e) {
|
||||
throw new InterruptedIOException(e.getMessage());
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @see org.apache.activeio.Disposable#dispose()
|
||||
*/
|
||||
public void dispose() {
|
||||
asyncChannelServer.dispose();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.apache.activeio.Service#start()
|
||||
*/
|
||||
public void start() throws IOException {
|
||||
asyncChannelServer.start();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.apache.activeio.Service#stop()
|
||||
*/
|
||||
public void stop() throws IOException {
|
||||
asyncChannelServer.stop();
|
||||
}
|
||||
|
||||
public URI getBindURI() {
|
||||
return asyncChannelServer.getBindURI();
|
||||
}
|
||||
|
||||
public URI getConnectURI() {
|
||||
return asyncChannelServer.getConnectURI();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.apache.activeio.AcceptListener#onAccept(org.apache.activeio.Channel)
|
||||
*/
|
||||
public void onAccept(org.apache.activeio.Channel channel) {
|
||||
try {
|
||||
acceptBuffer.put(channel);
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.apache.activeio.AcceptListener#onAcceptError(java.io.IOException)
|
||||
*/
|
||||
public void onAcceptError(IOException error) {
|
||||
try {
|
||||
acceptBuffer.put(error);
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
}
|
||||
|
||||
public AsyncChannelServer getAsyncChannelServer() {
|
||||
return asyncChannelServer;
|
||||
}
|
||||
|
||||
public Object getAdapter(Class target) {
|
||||
if( target.isAssignableFrom(getClass()) ) {
|
||||
return this;
|
||||
}
|
||||
return asyncChannelServer.getAdapter(target);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return asyncChannelServer.toString();
|
||||
}
|
||||
}
|
|
@ -1,110 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* 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.activeio.adapter;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
|
||||
import org.apache.activeio.packet.AppendedPacket;
|
||||
import org.apache.activeio.packet.ByteArrayPacket;
|
||||
import org.apache.activeio.packet.Packet;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
final public class PacketByteArrayOutputStream extends OutputStream {
|
||||
|
||||
private Packet result;
|
||||
private Packet current;
|
||||
int nextAllocationSize=0;
|
||||
|
||||
public PacketByteArrayOutputStream() {
|
||||
this( 1024 );
|
||||
}
|
||||
|
||||
public PacketByteArrayOutputStream(int initialSize) {
|
||||
nextAllocationSize = initialSize;
|
||||
current = allocate();
|
||||
}
|
||||
|
||||
protected Packet allocate() {
|
||||
ByteArrayPacket packet = new ByteArrayPacket(new byte[nextAllocationSize]);
|
||||
nextAllocationSize <<= 3; // x by 8
|
||||
return packet;
|
||||
}
|
||||
|
||||
public void skip(int size) {
|
||||
while( size > 0 ) {
|
||||
if( !current.hasRemaining() ) {
|
||||
allocatedNext();
|
||||
}
|
||||
|
||||
int skip = ((size <= current.remaining()) ? size : current.remaining());
|
||||
current.position(current.position()+skip);
|
||||
size -= skip;
|
||||
}
|
||||
}
|
||||
|
||||
public void write(int b) throws IOException {
|
||||
if( !current.hasRemaining() ) {
|
||||
allocatedNext();
|
||||
}
|
||||
current.write(b);
|
||||
}
|
||||
|
||||
public void write(byte[] b, int off, int len) throws IOException {
|
||||
while( len > 0 ) {
|
||||
if( !current.hasRemaining() ) {
|
||||
allocatedNext();
|
||||
}
|
||||
int wrote = current.write(b,off,len);
|
||||
off+=wrote;
|
||||
len-=wrote;
|
||||
}
|
||||
}
|
||||
|
||||
private void allocatedNext() {
|
||||
if( result == null ) {
|
||||
current.flip();
|
||||
result = current;
|
||||
} else {
|
||||
current.flip();
|
||||
result = AppendedPacket.join(result, current);
|
||||
}
|
||||
current = allocate();
|
||||
}
|
||||
|
||||
public Packet getPacket() {
|
||||
if( result == null ) {
|
||||
current.flip();
|
||||
return current.slice();
|
||||
} else {
|
||||
current.flip();
|
||||
return AppendedPacket.join(result, current);
|
||||
}
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
result = null;
|
||||
current.clear();
|
||||
}
|
||||
|
||||
public int position() {
|
||||
return current.position() + (result==null ? 0 : result.remaining());
|
||||
}
|
||||
}
|
|
@ -1,29 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* 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.activeio.adapter;
|
||||
|
||||
import org.apache.activeio.packet.Packet;
|
||||
|
||||
/**
|
||||
* @deprecated Use PacketToInputStream instead. This class will be removed very soon.
|
||||
*/
|
||||
public class PacketInputStream extends PacketToInputStream {
|
||||
public PacketInputStream(Packet packet) {
|
||||
super(packet);
|
||||
}
|
||||
}
|
|
@ -1,47 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* 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.activeio.adapter;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
|
||||
import org.apache.activeio.packet.Packet;
|
||||
|
||||
/**
|
||||
* Provides an OutputStream for a given Packet.
|
||||
*
|
||||
* @version $Revision$
|
||||
*/
|
||||
public class PacketOutputStream extends OutputStream {
|
||||
|
||||
final Packet packet;
|
||||
|
||||
public PacketOutputStream(Packet packet) {
|
||||
this.packet = packet;
|
||||
}
|
||||
|
||||
public void write(int b) throws IOException {
|
||||
if( !packet.write(b) )
|
||||
throw new IOException("Packet does not have any remaining space to write to.");
|
||||
}
|
||||
|
||||
public void write(byte[] b, int off, int len) throws IOException {
|
||||
if( packet.write(b, off, len)!=len )
|
||||
throw new IOException("Packet does not have "+len+" byte(s) left to write to.");
|
||||
}
|
||||
}
|
|
@ -1,55 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* 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.activeio.adapter;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
import org.apache.activeio.packet.Packet;
|
||||
|
||||
/**
|
||||
* Provides an InputStream for a given Packet.
|
||||
*
|
||||
* @version $Revision$
|
||||
*/
|
||||
public class PacketToInputStream extends InputStream {
|
||||
|
||||
final Packet packet;
|
||||
|
||||
/**
|
||||
* @param packet
|
||||
*/
|
||||
public PacketToInputStream(Packet packet) {
|
||||
this.packet = packet;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see java.io.InputStream#read()
|
||||
*/
|
||||
public int read() throws IOException {
|
||||
return packet.read();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see java.io.InputStream#read(byte[], int, int)
|
||||
*/
|
||||
public int read(byte[] b, int off, int len) throws IOException {
|
||||
return packet.read(b, off, len);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,134 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* 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.activeio.adapter;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InterruptedIOException;
|
||||
import java.net.InetAddress;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.ServerSocket;
|
||||
import java.net.Socket;
|
||||
import java.net.SocketAddress;
|
||||
import java.net.SocketException;
|
||||
import java.net.URI;
|
||||
import java.nio.channels.ServerSocketChannel;
|
||||
|
||||
import org.apache.activeio.Channel;
|
||||
import org.apache.activeio.packet.sync.SyncChannel;
|
||||
import org.apache.activeio.packet.sync.SyncChannelServer;
|
||||
|
||||
/**
|
||||
*/
|
||||
public class SyncChannelServerToServerSocket extends ServerSocket {
|
||||
|
||||
private final SyncChannelServer channelServer;
|
||||
private long timeout = Channel.WAIT_FOREVER_TIMEOUT;
|
||||
boolean closed;
|
||||
private InetAddress inetAddress;
|
||||
private int localPort;
|
||||
private SocketAddress localSocketAddress;
|
||||
private int receiveBufferSize;
|
||||
private boolean reuseAddress;
|
||||
|
||||
/**
|
||||
* @throws IOException
|
||||
*/
|
||||
public SyncChannelServerToServerSocket(SyncChannelServer channelServer) throws IOException {
|
||||
this.channelServer = channelServer;
|
||||
URI connectURI = channelServer.getConnectURI();
|
||||
localPort = connectURI.getPort();
|
||||
inetAddress = InetAddress.getByName(connectURI.getHost());
|
||||
localSocketAddress = new InetSocketAddress(inetAddress, localPort);
|
||||
}
|
||||
|
||||
public synchronized void setSoTimeout(int timeout) throws SocketException {
|
||||
if( timeout <= 0 )
|
||||
this.timeout = Channel.WAIT_FOREVER_TIMEOUT;
|
||||
else
|
||||
this.timeout = timeout;
|
||||
}
|
||||
|
||||
public synchronized int getSoTimeout() throws IOException {
|
||||
if( timeout == Channel.WAIT_FOREVER_TIMEOUT )
|
||||
return 0;
|
||||
return (int) timeout;
|
||||
}
|
||||
|
||||
public Socket accept() throws IOException {
|
||||
Channel channel = channelServer.accept(timeout);
|
||||
if( channel==null )
|
||||
throw new InterruptedIOException();
|
||||
|
||||
SyncChannel syncChannel = AsyncToSyncChannel.adapt(channel);
|
||||
syncChannel.start();
|
||||
return new SyncChannelToSocket(syncChannel);
|
||||
|
||||
}
|
||||
|
||||
public void bind(SocketAddress endpoint, int backlog) throws IOException {
|
||||
if (isClosed())
|
||||
throw new SocketException("Socket is closed");
|
||||
throw new SocketException("Already bound");
|
||||
}
|
||||
|
||||
public void bind(SocketAddress endpoint) throws IOException {
|
||||
if (isClosed())
|
||||
throw new SocketException("Socket is closed");
|
||||
throw new SocketException("Already bound");
|
||||
}
|
||||
|
||||
public ServerSocketChannel getChannel() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public InetAddress getInetAddress() {
|
||||
return inetAddress;
|
||||
}
|
||||
public int getLocalPort() {
|
||||
return localPort;
|
||||
}
|
||||
public SocketAddress getLocalSocketAddress() {
|
||||
return localSocketAddress;
|
||||
}
|
||||
public synchronized int getReceiveBufferSize() throws SocketException {
|
||||
return receiveBufferSize;
|
||||
}
|
||||
|
||||
public boolean getReuseAddress() throws SocketException {
|
||||
return reuseAddress;
|
||||
}
|
||||
|
||||
public boolean isBound() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean isClosed() {
|
||||
return closed;
|
||||
}
|
||||
|
||||
public void setPerformancePreferences(int connectionTime, int latency, int bandwidth) {
|
||||
}
|
||||
|
||||
public synchronized void setReceiveBufferSize(int size) throws SocketException {
|
||||
this.receiveBufferSize = size;
|
||||
}
|
||||
|
||||
public void setReuseAddress(boolean on) throws SocketException {
|
||||
reuseAddress = on;
|
||||
}
|
||||
}
|
|
@ -1,115 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* 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.activeio.adapter;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
import org.apache.activeio.Channel;
|
||||
import org.apache.activeio.packet.EOSPacket;
|
||||
import org.apache.activeio.packet.Packet;
|
||||
import org.apache.activeio.packet.sync.SyncChannel;
|
||||
|
||||
/**
|
||||
* Provides an InputStream for a given SynchChannel.
|
||||
*
|
||||
* @version $Revision$
|
||||
*/
|
||||
public class SyncChannelToInputStream extends InputStream {
|
||||
|
||||
private final SyncChannel channel;
|
||||
private Packet lastPacket;
|
||||
private boolean closed;
|
||||
private long timeout = Channel.WAIT_FOREVER_TIMEOUT;
|
||||
|
||||
/**
|
||||
* @param channel
|
||||
*/
|
||||
public SyncChannelToInputStream(final SyncChannel channel) {
|
||||
this.channel = channel;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see java.io.InputStream#read()
|
||||
*/
|
||||
public int read() throws IOException {
|
||||
while( true ) {
|
||||
if( lastPacket==null ) {
|
||||
try {
|
||||
lastPacket = channel.read(timeout);
|
||||
} catch (IOException e) {
|
||||
throw (IOException)new IOException("Channel failed: "+e.getMessage()).initCause(e);
|
||||
}
|
||||
}
|
||||
if( lastPacket.hasRemaining() ) {
|
||||
return lastPacket.read();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see java.io.InputStream#read(byte[], int, int)
|
||||
*/
|
||||
public int read(byte[] b, int off, int len) throws IOException {
|
||||
while( true ) {
|
||||
if( lastPacket==null || !lastPacket.hasRemaining() ) {
|
||||
try {
|
||||
lastPacket = channel.read(timeout);
|
||||
} catch (IOException e) {
|
||||
throw (IOException)new IOException("Channel failed: "+e.getMessage()).initCause(e);
|
||||
}
|
||||
}
|
||||
if( lastPacket==EOSPacket.EOS_PACKET ) {
|
||||
return -1;
|
||||
}
|
||||
if( lastPacket!=null && lastPacket.hasRemaining() ) {
|
||||
return lastPacket.read(b, off, len);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see java.io.InputStream#close()
|
||||
*/
|
||||
public void close() throws IOException {
|
||||
closed=true;
|
||||
super.close();
|
||||
}
|
||||
|
||||
public boolean isClosed() {
|
||||
return closed;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param timeout
|
||||
*/
|
||||
public void setTimeout(long timeout) {
|
||||
if( timeout <= 0 )
|
||||
timeout = Channel.WAIT_FOREVER_TIMEOUT;
|
||||
this.timeout = timeout;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
public long getTimeout() {
|
||||
if( timeout == Channel.WAIT_FOREVER_TIMEOUT )
|
||||
return 0;
|
||||
return timeout;
|
||||
}
|
||||
}
|
|
@ -1,73 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* 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.activeio.adapter;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
|
||||
import org.apache.activeio.packet.ByteArrayPacket;
|
||||
import org.apache.activeio.packet.BytePacket;
|
||||
import org.apache.activeio.packet.sync.SyncChannel;
|
||||
|
||||
/**
|
||||
*/
|
||||
public class SyncChannelToOutputStream extends OutputStream {
|
||||
|
||||
private final SyncChannel channel;
|
||||
private boolean closed;
|
||||
|
||||
/**
|
||||
* @param channel
|
||||
*/
|
||||
public SyncChannelToOutputStream(SyncChannel channel) {
|
||||
this.channel = channel;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see java.io.OutputStream#write(int)
|
||||
*/
|
||||
public void write(int b) throws IOException {
|
||||
channel.write(new BytePacket((byte) b));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see java.io.OutputStream#write(byte[], int, int)
|
||||
*/
|
||||
public void write(byte[] b, int off, int len) throws IOException {
|
||||
channel.write(new ByteArrayPacket(b, off, len));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see java.io.OutputStream#flush()
|
||||
*/
|
||||
public void flush() throws IOException {
|
||||
channel.flush();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see java.io.InputStream#close()
|
||||
*/
|
||||
public void close() throws IOException {
|
||||
closed=true;
|
||||
super.close();
|
||||
}
|
||||
|
||||
public boolean isClosed() {
|
||||
return closed;
|
||||
}
|
||||
}
|
|
@ -1,222 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* 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.activeio.adapter;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.net.InetAddress;
|
||||
import java.net.Socket;
|
||||
import java.net.SocketAddress;
|
||||
import java.net.SocketException;
|
||||
import java.nio.channels.SocketChannel;
|
||||
|
||||
import org.apache.activeio.packet.ByteArrayPacket;
|
||||
import org.apache.activeio.packet.Packet;
|
||||
import org.apache.activeio.packet.sync.SyncChannel;
|
||||
import org.apache.activeio.stream.sync.socket.SocketMetadata;
|
||||
|
||||
/**
|
||||
* Provides a {@see java.net.Socket} interface to a {@see org.apache.activeio.SynchChannel}.
|
||||
*
|
||||
* If the {@see org.apache.activeio.SynchChannel} being adapted can not be
|
||||
* {@see org.apache.activeio.Channel#narrow(Class)}ed to a {@see org.apache.activeio.net.SocketMetadata}
|
||||
* then all methods accessing socket metadata will throw a {@see java.net.SocketException}.
|
||||
*
|
||||
*/
|
||||
public class SyncChannelToSocket extends Socket {
|
||||
|
||||
private final SyncChannel channel;
|
||||
private final SyncChannelToInputStream inputStream;
|
||||
private final SyncChannelToOutputStream outputStream;
|
||||
private final SocketMetadata socketMetadata;
|
||||
private final Packet urgentPackget = new ByteArrayPacket(new byte[1]);
|
||||
boolean closed;
|
||||
|
||||
public SyncChannelToSocket(SyncChannel channel) {
|
||||
this(channel, (SocketMetadata)channel.getAdapter(SocketMetadata.class));
|
||||
}
|
||||
|
||||
public SyncChannelToSocket(SyncChannel channel, SocketMetadata socketMetadata) {
|
||||
this.channel = channel;
|
||||
this.socketMetadata = socketMetadata;
|
||||
this.inputStream = new SyncChannelToInputStream(channel);
|
||||
this.outputStream = new SyncChannelToOutputStream(channel);
|
||||
}
|
||||
|
||||
public boolean isConnected() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean isBound() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean isClosed() {
|
||||
return closed;
|
||||
}
|
||||
|
||||
public void bind(SocketAddress bindpoint) throws IOException {
|
||||
throw new IOException("Not supported");
|
||||
}
|
||||
|
||||
public synchronized void close() throws IOException {
|
||||
if( closed )
|
||||
return;
|
||||
closed = true;
|
||||
inputStream.close();
|
||||
outputStream.close();
|
||||
channel.stop();
|
||||
}
|
||||
|
||||
public void connect(SocketAddress endpoint) throws IOException {
|
||||
throw new IOException("Not supported");
|
||||
}
|
||||
|
||||
public void connect(SocketAddress endpoint, int timeout) throws IOException {
|
||||
throw new IOException("Not supported");
|
||||
}
|
||||
|
||||
public SocketChannel getChannel() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public InputStream getInputStream() throws IOException {
|
||||
return inputStream;
|
||||
}
|
||||
|
||||
public OutputStream getOutputStream() throws IOException {
|
||||
return outputStream;
|
||||
}
|
||||
|
||||
public boolean isInputShutdown() {
|
||||
return inputStream.isClosed();
|
||||
}
|
||||
|
||||
public boolean isOutputShutdown() {
|
||||
return outputStream.isClosed();
|
||||
}
|
||||
|
||||
public void sendUrgentData(int data) throws IOException {
|
||||
urgentPackget.clear();
|
||||
urgentPackget.write(data);
|
||||
urgentPackget.flip();
|
||||
channel.write(urgentPackget);
|
||||
}
|
||||
|
||||
public int getSoTimeout() throws SocketException {
|
||||
return (int) inputStream.getTimeout();
|
||||
}
|
||||
|
||||
public synchronized void setSoTimeout(int timeout) throws SocketException {
|
||||
inputStream.setTimeout(timeout);
|
||||
}
|
||||
|
||||
public void shutdownOutput() throws IOException {
|
||||
outputStream.close();
|
||||
}
|
||||
|
||||
public void shutdownInput() throws IOException {
|
||||
inputStream.close();
|
||||
}
|
||||
|
||||
protected SocketMetadata getSocketMetadata() throws SocketException {
|
||||
if( socketMetadata == null )
|
||||
throw new SocketException("No socket metadata available.");
|
||||
return socketMetadata;
|
||||
}
|
||||
|
||||
public InetAddress getInetAddress() {
|
||||
if( socketMetadata ==null )
|
||||
return null;
|
||||
return socketMetadata.getInetAddress();
|
||||
}
|
||||
public boolean getKeepAlive() throws SocketException {
|
||||
return getSocketMetadata().getKeepAlive();
|
||||
}
|
||||
public InetAddress getLocalAddress() {
|
||||
if( socketMetadata ==null )
|
||||
return null;
|
||||
return socketMetadata.getLocalAddress();
|
||||
}
|
||||
public int getLocalPort() {
|
||||
if( socketMetadata ==null )
|
||||
return -1;
|
||||
return socketMetadata.getLocalPort();
|
||||
}
|
||||
public SocketAddress getLocalSocketAddress() {
|
||||
if( socketMetadata ==null )
|
||||
return null;
|
||||
return socketMetadata.getLocalSocketAddress();
|
||||
}
|
||||
public boolean getOOBInline() throws SocketException {
|
||||
return getSocketMetadata().getOOBInline();
|
||||
}
|
||||
public int getPort() {
|
||||
if( socketMetadata ==null )
|
||||
return -1;
|
||||
return socketMetadata.getPort();
|
||||
}
|
||||
public int getReceiveBufferSize() throws SocketException {
|
||||
return getSocketMetadata().getReceiveBufferSize();
|
||||
}
|
||||
public SocketAddress getRemoteSocketAddress() {
|
||||
if( socketMetadata ==null )
|
||||
return null;
|
||||
return socketMetadata.getRemoteSocketAddress();
|
||||
}
|
||||
public boolean getReuseAddress() throws SocketException {
|
||||
return getSocketMetadata().getReuseAddress();
|
||||
}
|
||||
public int getSendBufferSize() throws SocketException {
|
||||
return getSocketMetadata().getSendBufferSize();
|
||||
}
|
||||
public int getSoLinger() throws SocketException {
|
||||
return getSocketMetadata().getSoLinger();
|
||||
}
|
||||
public boolean getTcpNoDelay() throws SocketException {
|
||||
return getSocketMetadata().getTcpNoDelay();
|
||||
}
|
||||
public int getTrafficClass() throws SocketException {
|
||||
return getSocketMetadata().getTrafficClass();
|
||||
}
|
||||
public void setKeepAlive(boolean on) throws SocketException {
|
||||
getSocketMetadata().setKeepAlive(on);
|
||||
}
|
||||
public void setOOBInline(boolean on) throws SocketException {
|
||||
getSocketMetadata().setOOBInline(on);
|
||||
}
|
||||
public void setReceiveBufferSize(int size) throws SocketException {
|
||||
getSocketMetadata().setReceiveBufferSize(size);
|
||||
}
|
||||
public void setReuseAddress(boolean on) throws SocketException {
|
||||
getSocketMetadata().setReuseAddress(on);
|
||||
}
|
||||
public void setSendBufferSize(int size) throws SocketException {
|
||||
getSocketMetadata().setSendBufferSize(size);
|
||||
}
|
||||
public void setSoLinger(boolean on, int linger) throws SocketException {
|
||||
getSocketMetadata().setSoLinger(on, linger);
|
||||
}
|
||||
public void setTcpNoDelay(boolean on) throws SocketException {
|
||||
getSocketMetadata().setTcpNoDelay(on);
|
||||
}
|
||||
public void setTrafficClass(int tc) throws SocketException {
|
||||
getSocketMetadata().setTrafficClass(tc);
|
||||
}
|
||||
}
|
|
@ -1,201 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* 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.activeio.adapter;
|
||||
|
||||
import edu.emory.mathcs.backport.java.util.concurrent.CountDownLatch;
|
||||
import edu.emory.mathcs.backport.java.util.concurrent.Executor;
|
||||
import edu.emory.mathcs.backport.java.util.concurrent.TimeUnit;
|
||||
import edu.emory.mathcs.backport.java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
import org.apache.activeio.Channel;
|
||||
import org.apache.activeio.ChannelFactory;
|
||||
import org.apache.activeio.packet.EOSPacket;
|
||||
import org.apache.activeio.packet.Packet;
|
||||
import org.apache.activeio.packet.async.AsyncChannel;
|
||||
import org.apache.activeio.packet.async.AsyncChannelListener;
|
||||
import org.apache.activeio.packet.sync.SyncChannel;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Adapts a {@see org.apache.activeio.SynchChannel} so that it provides an
|
||||
* {@see org.apache.activeio.AsyncChannel} interface. When this channel
|
||||
* is started, a background thread is used to poll the {@see org.apache.activeio.SynchChannel}
|
||||
* for packets comming up the channel which are then delivered to the
|
||||
* {@see org.apache.activeio.ChannelConsumer}.
|
||||
*
|
||||
* @version $Revision$
|
||||
*/
|
||||
public class SyncToAsyncChannel implements AsyncChannel, Runnable {
|
||||
|
||||
private final AtomicBoolean running = new AtomicBoolean(false);
|
||||
private final SyncChannel syncChannel;
|
||||
private final Executor executor;
|
||||
private AsyncChannelListener channelListener;
|
||||
private CountDownLatch doneCountDownLatch;
|
||||
|
||||
|
||||
static public AsyncChannel adapt(Channel channel) {
|
||||
return adapt(channel, ChannelFactory.DEFAULT_EXECUTOR);
|
||||
}
|
||||
|
||||
static public AsyncChannel adapt(Channel channel, Executor executor) {
|
||||
|
||||
// It might not need adapting
|
||||
if( channel instanceof AsyncChannel ) {
|
||||
return (AsyncChannel) channel;
|
||||
}
|
||||
|
||||
// Can we just just undo the adaptor
|
||||
if( channel.getClass() == SyncToAsyncChannel.class ) {
|
||||
return ((AsyncToSyncChannel)channel).getAsyncChannel();
|
||||
}
|
||||
|
||||
return new SyncToAsyncChannel((SyncChannel) channel, executor);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @deprecated {@see #adapt(SynchChannel)}
|
||||
*/
|
||||
public SyncToAsyncChannel(SyncChannel syncChannel) {
|
||||
this(syncChannel, ChannelFactory.DEFAULT_EXECUTOR);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated {@see #adapt(SynchChannel, Executor)}
|
||||
*/
|
||||
public SyncToAsyncChannel(SyncChannel syncChannel, Executor executor) {
|
||||
this.syncChannel = syncChannel;
|
||||
this.executor = executor;
|
||||
}
|
||||
|
||||
synchronized public void start() throws IOException {
|
||||
if (running.compareAndSet(false, true)) {
|
||||
|
||||
if (channelListener == null)
|
||||
throw new IllegalStateException("UpPacketListener must be set before object can be started.");
|
||||
|
||||
syncChannel.start();
|
||||
|
||||
doneCountDownLatch = new CountDownLatch(1);
|
||||
executor.execute(this);
|
||||
}
|
||||
}
|
||||
|
||||
synchronized public void stop() throws IOException {
|
||||
if (running.compareAndSet(true, false)) {
|
||||
try {
|
||||
doneCountDownLatch.await(5, TimeUnit.SECONDS);
|
||||
} catch (Throwable e) {
|
||||
}
|
||||
syncChannel.stop();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* reads packets from a Socket
|
||||
*/
|
||||
public void run() {
|
||||
|
||||
// Change the thread name.
|
||||
String oldName = Thread.currentThread().getName();
|
||||
Thread.currentThread().setName( syncChannel.toString() );
|
||||
try {
|
||||
while (running.get()) {
|
||||
try {
|
||||
Packet packet = syncChannel.read(500);
|
||||
if( packet==null )
|
||||
continue;
|
||||
|
||||
if( packet == EOSPacket.EOS_PACKET ) {
|
||||
channelListener.onPacket(packet);
|
||||
return;
|
||||
}
|
||||
|
||||
if( packet.hasRemaining() ) {
|
||||
channelListener.onPacket(packet);
|
||||
}
|
||||
|
||||
} catch (IOException e) {
|
||||
channelListener.onPacketError(e);
|
||||
} catch (Throwable e) {
|
||||
channelListener.onPacketError((IOException)new IOException("Unexpected Error: "+e).initCause(e));
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
if( doneCountDownLatch!=null )
|
||||
doneCountDownLatch.countDown();
|
||||
Thread.currentThread().setName(oldName);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.apache.activeio.packet.async.AsyncChannel#setAsyncChannelListener(org.apache.activeio.UpPacketListener)
|
||||
*/
|
||||
public void setAsyncChannelListener(AsyncChannelListener channelListener) {
|
||||
if (running.get())
|
||||
throw new IllegalStateException("Cannot change the UpPacketListener while the object is running.");
|
||||
this.channelListener = channelListener;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.apache.activeio.Channel#write(org.apache.activeio.packet.Packet)
|
||||
*/
|
||||
public void write(org.apache.activeio.packet.Packet packet) throws IOException {
|
||||
syncChannel.write(packet);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.apache.activeio.Channel#flush()
|
||||
*/
|
||||
public void flush() throws IOException {
|
||||
syncChannel.flush();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.apache.activeio.Disposable#dispose()
|
||||
*/
|
||||
public void dispose() {
|
||||
try {
|
||||
stop();
|
||||
} catch ( IOException ignore) {
|
||||
}
|
||||
syncChannel.dispose();
|
||||
}
|
||||
|
||||
public AsyncChannelListener getAsyncChannelListener() {
|
||||
return channelListener;
|
||||
}
|
||||
|
||||
public Object getAdapter(Class target) {
|
||||
if( target.isAssignableFrom(getClass()) ) {
|
||||
return this;
|
||||
}
|
||||
return syncChannel.getAdapter(target);
|
||||
}
|
||||
|
||||
public SyncChannel getSynchChannel() {
|
||||
return syncChannel;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return syncChannel.toString();
|
||||
}
|
||||
}
|
|
@ -1,84 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* 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.activeio.adapter;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
|
||||
import org.apache.activeio.ChannelFactory;
|
||||
import org.apache.activeio.packet.async.AsyncChannel;
|
||||
import org.apache.activeio.packet.async.AsyncChannelFactory;
|
||||
import org.apache.activeio.packet.async.AsyncChannelServer;
|
||||
import org.apache.activeio.packet.sync.SyncChannelFactory;
|
||||
|
||||
import edu.emory.mathcs.backport.java.util.concurrent.Executor;
|
||||
|
||||
/**
|
||||
* @version $Revision$
|
||||
*/
|
||||
public class SyncToAsyncChannelFactory implements AsyncChannelFactory {
|
||||
|
||||
private final SyncChannelFactory syncChannelFactory;
|
||||
private final Executor executor;
|
||||
|
||||
static public AsyncChannelFactory adapt(SyncChannelFactory channelFactory) {
|
||||
return adapt(channelFactory, ChannelFactory.DEFAULT_EXECUTOR);
|
||||
}
|
||||
|
||||
static public AsyncChannelFactory adapt(SyncChannelFactory channelFactory, Executor executor ) {
|
||||
|
||||
// It might not need adapting
|
||||
if( channelFactory instanceof AsyncChannelFactory ) {
|
||||
return (AsyncChannelFactory) channelFactory;
|
||||
}
|
||||
|
||||
// Can we just just undo the adaptor
|
||||
if( channelFactory.getClass() == AsyncToSyncChannelFactory.class ) {
|
||||
return ((AsyncToSyncChannelFactory)channelFactory).getAsyncChannelFactory();
|
||||
}
|
||||
|
||||
return new SyncToAsyncChannelFactory((SyncChannelFactory)channelFactory, executor);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated {@see #adapt(SyncChannelFactory)}
|
||||
*/
|
||||
public SyncToAsyncChannelFactory(final SyncChannelFactory next) {
|
||||
this(next, ChannelFactory.DEFAULT_EXECUTOR);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated {@see #adapt(SyncChannelFactory, Executor)}
|
||||
*/
|
||||
public SyncToAsyncChannelFactory(final SyncChannelFactory next, Executor executor) {
|
||||
this.syncChannelFactory = next;
|
||||
this.executor = executor;
|
||||
}
|
||||
|
||||
public AsyncChannel openAsyncChannel(URI location) throws IOException {
|
||||
return SyncToAsyncChannel.adapt(syncChannelFactory.openSyncChannel(location),executor);
|
||||
}
|
||||
|
||||
public AsyncChannelServer bindAsyncChannel(URI location) throws IOException {
|
||||
return new SyncToAsyncChannelServer(syncChannelFactory.bindSyncChannel(location),executor);
|
||||
}
|
||||
|
||||
public SyncChannelFactory getSyncChannelFactory() {
|
||||
return syncChannelFactory;
|
||||
}
|
||||
}
|
|
@ -1,172 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* 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.activeio.adapter;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
|
||||
import org.apache.activeio.AcceptListener;
|
||||
import org.apache.activeio.Channel;
|
||||
import org.apache.activeio.ChannelFactory;
|
||||
import org.apache.activeio.ChannelServer;
|
||||
import org.apache.activeio.packet.async.AsyncChannelServer;
|
||||
import org.apache.activeio.packet.sync.SyncChannelServer;
|
||||
|
||||
import edu.emory.mathcs.backport.java.util.concurrent.CountDownLatch;
|
||||
import edu.emory.mathcs.backport.java.util.concurrent.Executor;
|
||||
import edu.emory.mathcs.backport.java.util.concurrent.TimeUnit;
|
||||
import edu.emory.mathcs.backport.java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
/**
|
||||
* Adapts a {@see org.apache.activeio,SynchChannelServer} so that it provides an
|
||||
* {@see org.apache.activeio.AsyncChannelServer} interface. When this channel
|
||||
* is started, a background thread is used to poll the (@see org.apache.activeio.SynchChannelServer}
|
||||
* for accepted channel connections which are then delivered to the {@see org.apache.activeio.AcceptConsumer}.
|
||||
*
|
||||
* @version $Revision$
|
||||
*/
|
||||
final public class SyncToAsyncChannelServer implements AsyncChannelServer, Runnable {
|
||||
|
||||
private final SyncChannelServer syncChannelServer;
|
||||
private final AtomicBoolean running = new AtomicBoolean(false);
|
||||
private final Executor executor;
|
||||
private AcceptListener acceptListener;
|
||||
private CountDownLatch doneCountDownLatch;
|
||||
|
||||
|
||||
static public AsyncChannelServer adapt(ChannelServer channel) {
|
||||
return adapt(channel, ChannelFactory.DEFAULT_EXECUTOR);
|
||||
}
|
||||
|
||||
static public AsyncChannelServer adapt(ChannelServer channel, Executor executor) {
|
||||
|
||||
// It might not need adapting
|
||||
if( channel instanceof AsyncChannelServer ) {
|
||||
return (AsyncChannelServer) channel;
|
||||
}
|
||||
|
||||
// Can we just just undo the adaptor
|
||||
if( channel.getClass() == AsyncToSyncChannelServer.class ) {
|
||||
return ((AsyncToSyncChannelServer)channel).getAsyncChannelServer();
|
||||
}
|
||||
|
||||
return new SyncToAsyncChannelServer((SyncChannelServer)channel, executor);
|
||||
}
|
||||
|
||||
public SyncToAsyncChannelServer(SyncChannelServer syncServer) {
|
||||
this(syncServer, ChannelFactory.DEFAULT_EXECUTOR);
|
||||
}
|
||||
|
||||
public SyncToAsyncChannelServer(SyncChannelServer syncServer, Executor executor) {
|
||||
this.syncChannelServer = syncServer;
|
||||
this.executor=executor;
|
||||
}
|
||||
|
||||
synchronized public void start() throws IOException {
|
||||
if (running.compareAndSet(false, true)) {
|
||||
|
||||
if( acceptListener == null )
|
||||
throw new IllegalStateException("AcceptListener must be set before object can be started.");
|
||||
|
||||
syncChannelServer.start();
|
||||
|
||||
doneCountDownLatch = new CountDownLatch(1);
|
||||
executor.execute(this);
|
||||
}
|
||||
}
|
||||
|
||||
synchronized public void stop() throws IOException {
|
||||
if (running.compareAndSet(true, false)) {
|
||||
try {
|
||||
doneCountDownLatch.await(5, TimeUnit.SECONDS);
|
||||
} catch (Throwable e) {
|
||||
}
|
||||
syncChannelServer.stop();
|
||||
}
|
||||
}
|
||||
|
||||
public void run() {
|
||||
// Change the thread name.
|
||||
String oldName = Thread.currentThread().getName();
|
||||
Thread.currentThread().setName( syncChannelServer.toString() );
|
||||
try {
|
||||
while (running.get()) {
|
||||
try {
|
||||
Channel channel = syncChannelServer.accept(500);
|
||||
if( channel == null )
|
||||
continue;
|
||||
acceptListener.onAccept(channel);
|
||||
} catch (IOException e) {
|
||||
if( running.get() )
|
||||
acceptListener.onAcceptError(e);
|
||||
} catch (Throwable e) {
|
||||
if( running.get() )
|
||||
acceptListener.onAcceptError((IOException)new IOException("Unexpected Error: "+e).initCause(e));
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
if( doneCountDownLatch!=null )
|
||||
doneCountDownLatch.countDown();
|
||||
Thread.currentThread().setName(oldName);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.apache.activeio.packet.async.AsyncChannelServer#setAcceptListener(org.apache.activeio.AcceptListener)
|
||||
*/
|
||||
public void setAcceptListener(AcceptListener acceptListener) {
|
||||
if(running.get())
|
||||
throw new IllegalStateException("Cannot change the AcceptListener while the object is running.");
|
||||
this.acceptListener = acceptListener;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.apache.activeio.Disposable#dispose()
|
||||
*/
|
||||
public void dispose() {
|
||||
try {
|
||||
stop();
|
||||
} catch ( IOException ignore) {
|
||||
}
|
||||
syncChannelServer.dispose();
|
||||
}
|
||||
|
||||
public URI getBindURI() {
|
||||
return syncChannelServer.getBindURI();
|
||||
}
|
||||
|
||||
public URI getConnectURI() {
|
||||
return syncChannelServer.getConnectURI();
|
||||
}
|
||||
|
||||
public SyncChannelServer getSynchChannelServer() {
|
||||
return syncChannelServer;
|
||||
}
|
||||
|
||||
public Object getAdapter(Class target) {
|
||||
if( target.isAssignableFrom(getClass()) ) {
|
||||
return this;
|
||||
}
|
||||
return syncChannelServer.getAdapter(target);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return syncChannelServer.toString();
|
||||
}
|
||||
}
|
|
@ -1,56 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* 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.activeio.adapter;
|
||||
|
||||
import org.apache.activeio.Channel;
|
||||
import org.apache.activeio.packet.async.AsyncChannel;
|
||||
import org.apache.activeio.packet.sync.SyncChannel;
|
||||
|
||||
import edu.emory.mathcs.backport.java.util.concurrent.Executor;
|
||||
|
||||
/**
|
||||
* @deprecated Use AsyncChannelServer instead. This class will be removed very soon.
|
||||
*/
|
||||
public class SynchToAsynchChannelAdapter extends SyncToAsyncChannel{
|
||||
public SynchToAsynchChannelAdapter(SyncChannel syncChannel) {
|
||||
super(syncChannel);
|
||||
}
|
||||
|
||||
public SynchToAsynchChannelAdapter(SyncChannel syncChannel, Executor executor) {
|
||||
super(syncChannel, executor);
|
||||
}
|
||||
static public AsyncChannel adapt(Channel channel, Executor executor) {
|
||||
|
||||
// It might not need adapting
|
||||
if( channel instanceof AsyncChannel ) {
|
||||
return (AsyncChannel) channel;
|
||||
}
|
||||
|
||||
// Can we just just undo the adaptor
|
||||
if( channel.getClass() == SyncToAsyncChannel.class ) {
|
||||
return ((AsyncToSyncChannel)channel).getAsyncChannel();
|
||||
}
|
||||
// Can we just just undo the adaptor
|
||||
if( channel.getClass() == org.apache.activeio.adapter.SynchToAsynchChannelAdapter.class ) {
|
||||
return ((AsyncToSyncChannel)channel).getAsyncChannel();
|
||||
}
|
||||
|
||||
return new SyncToAsyncChannel((SyncChannel) channel, executor);
|
||||
|
||||
}
|
||||
}
|
|
@ -1,28 +0,0 @@
|
|||
<!--
|
||||
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.
|
||||
-->
|
||||
<html>
|
||||
<head>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<p>
|
||||
The Adapter package provides classes that make it easy ot bridge between the the
|
||||
SynchChannel, AsyncChannel, InputStream, OutputStream, Socket, and ServerSocket domains.
|
||||
</p>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -1,82 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* 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.activeio.command;
|
||||
|
||||
import org.apache.activeio.packet.EOSPacket;
|
||||
import org.apache.activeio.packet.Packet;
|
||||
import org.apache.activeio.packet.async.AsyncChannel;
|
||||
import org.apache.activeio.packet.async.AsyncChannelListener;
|
||||
|
||||
import java.io.EOFException;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* @version $Revision: 1.1 $
|
||||
*/
|
||||
public class AsyncChannelToAsyncCommandChannel implements AsyncCommandChannel {
|
||||
private AsyncChannel channel;
|
||||
private WireFormat wireFormat;
|
||||
|
||||
public AsyncChannelToAsyncCommandChannel(AsyncChannel channel, WireFormat wireFormat) {
|
||||
this.channel = channel;
|
||||
this.wireFormat = wireFormat;
|
||||
}
|
||||
|
||||
public void writeCommand(Object command) throws IOException {
|
||||
channel.write(wireFormat.marshal(command));
|
||||
channel.flush();
|
||||
}
|
||||
|
||||
public Object getAdapter(Class target) {
|
||||
return channel.getAdapter(target);
|
||||
}
|
||||
|
||||
public void dispose() {
|
||||
channel.dispose();
|
||||
}
|
||||
|
||||
public void start() throws IOException {
|
||||
channel.start();
|
||||
}
|
||||
|
||||
public void stop() throws IOException {
|
||||
channel.stop();
|
||||
}
|
||||
|
||||
public void setCommandListener(final CommandListener listener) {
|
||||
channel.setAsyncChannelListener(new AsyncChannelListener() {
|
||||
public void onPacket(Packet packet) {
|
||||
if( packet == EOSPacket.EOS_PACKET ) {
|
||||
listener.onError(new EOFException("Peer disconnected."));
|
||||
return;
|
||||
}
|
||||
try {
|
||||
Object command = wireFormat.unmarshal(packet);
|
||||
listener.onCommand(command);
|
||||
}
|
||||
catch (IOException e) {
|
||||
listener.onError(e);
|
||||
}
|
||||
}
|
||||
|
||||
public void onPacketError(IOException error) {
|
||||
listener.onError(error);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
|
@ -1,46 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* 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.activeio.command;
|
||||
|
||||
import org.apache.activeio.Channel;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Allows command objects to be written into a channel
|
||||
*
|
||||
* @version $Revision: 1.1 $
|
||||
*/
|
||||
public interface AsyncCommandChannel extends Channel {
|
||||
|
||||
/**
|
||||
* Sends a command down the channel towards the media, using a WireFormat
|
||||
* to decide how to marshal the command onto the media.
|
||||
*
|
||||
* @param command
|
||||
* @throws java.io.IOException
|
||||
*/
|
||||
void writeCommand(Object command) throws IOException;
|
||||
|
||||
/**
|
||||
* Allows a listener to be added for commands
|
||||
*
|
||||
* @param listener
|
||||
*/
|
||||
void setCommandListener(CommandListener listener);
|
||||
}
|
|
@ -1,240 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* 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.activeio.command;
|
||||
|
||||
import java.lang.reflect.Array;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Utilities for loading classes.
|
||||
*
|
||||
* @version $Rev: 109957 $ $Date: 2005/03/11 21:14:53 $
|
||||
*/
|
||||
public class ClassLoading {
|
||||
|
||||
/**
|
||||
* Load a class for the given name. <p/>
|
||||
* <p>
|
||||
* Handles loading primitive types as well as VM class and array syntax.
|
||||
*
|
||||
* @param className
|
||||
* The name of the Class to be loaded.
|
||||
* @param classLoader
|
||||
* The class loader to load the Class object from.
|
||||
* @return The Class object for the given name.
|
||||
* @throws ClassNotFoundException
|
||||
* Failed to load Class object.
|
||||
*/
|
||||
public static Class loadClass(final String className, final ClassLoader classLoader) throws ClassNotFoundException {
|
||||
if (className == null) {
|
||||
throw new IllegalArgumentException("className is null");
|
||||
}
|
||||
|
||||
// First just try to load
|
||||
try {
|
||||
return load(className, classLoader);
|
||||
} catch (ClassNotFoundException ignore) {
|
||||
// handle special cases below
|
||||
}
|
||||
|
||||
Class type = null;
|
||||
|
||||
// Check if it is a primitive type
|
||||
type = getPrimitiveType(className);
|
||||
if (type != null)
|
||||
return type;
|
||||
|
||||
// Check if it is a vm primitive
|
||||
type = getVMPrimitiveType(className);
|
||||
if (type != null)
|
||||
return type;
|
||||
|
||||
// Handle VM class syntax (Lclassname;)
|
||||
if (className.charAt(0) == 'L' && className.charAt(className.length() - 1) == ';') {
|
||||
String name = className.substring(1, className.length() - 1);
|
||||
return load(name, classLoader);
|
||||
}
|
||||
|
||||
// Handle VM array syntax ([type)
|
||||
if (className.charAt(0) == '[') {
|
||||
int arrayDimension = className.lastIndexOf('[') + 1;
|
||||
String componentClassName = className.substring(arrayDimension, className.length());
|
||||
type = loadClass(componentClassName, classLoader);
|
||||
|
||||
int dim[] = new int[arrayDimension];
|
||||
java.util.Arrays.fill(dim, 0);
|
||||
return Array.newInstance(type, dim).getClass();
|
||||
}
|
||||
|
||||
// Handle user friendly type[] syntax
|
||||
if (className.endsWith("[]")) {
|
||||
// get the base component class name and the arrayDimensions
|
||||
int arrayDimension = 0;
|
||||
String componentClassName = className;
|
||||
while (componentClassName.endsWith("[]")) {
|
||||
componentClassName = componentClassName.substring(0, componentClassName.length() - 2);
|
||||
arrayDimension++;
|
||||
}
|
||||
|
||||
// load the base type
|
||||
type = loadClass(componentClassName, classLoader);
|
||||
|
||||
// return the array type
|
||||
int[] dim = new int[arrayDimension];
|
||||
java.util.Arrays.fill(dim, 0);
|
||||
return Array.newInstance(type, dim).getClass();
|
||||
}
|
||||
|
||||
// Else we can not load (give up)
|
||||
throw new ClassNotFoundException(className);
|
||||
}
|
||||
|
||||
private static Class load(final String className, final ClassLoader classLoader) throws ClassNotFoundException {
|
||||
if (classLoader == null)
|
||||
return Class.forName(className);
|
||||
else
|
||||
return classLoader.loadClass(className);
|
||||
}
|
||||
|
||||
public static String getClassName(Class clazz) {
|
||||
StringBuffer rc = new StringBuffer();
|
||||
while (clazz.isArray()) {
|
||||
rc.append('[');
|
||||
clazz = clazz.getComponentType();
|
||||
}
|
||||
if (!clazz.isPrimitive()) {
|
||||
rc.append('L');
|
||||
rc.append(clazz.getName());
|
||||
rc.append(';');
|
||||
} else {
|
||||
rc.append(VM_PRIMITIVES_REVERSE.get(clazz));
|
||||
}
|
||||
return rc.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Primitive type name -> class map.
|
||||
*/
|
||||
private static final Map PRIMITIVES = new HashMap();
|
||||
|
||||
/** Setup the primitives map. */
|
||||
static {
|
||||
PRIMITIVES.put("boolean", Boolean.TYPE);
|
||||
PRIMITIVES.put("byte", Byte.TYPE);
|
||||
PRIMITIVES.put("char", Character.TYPE);
|
||||
PRIMITIVES.put("short", Short.TYPE);
|
||||
PRIMITIVES.put("int", Integer.TYPE);
|
||||
PRIMITIVES.put("long", Long.TYPE);
|
||||
PRIMITIVES.put("float", Float.TYPE);
|
||||
PRIMITIVES.put("double", Double.TYPE);
|
||||
PRIMITIVES.put("void", Void.TYPE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the primitive type for the given primitive name.
|
||||
*
|
||||
* @param name
|
||||
* Primitive type name (boolean, byte, int, ...)
|
||||
* @return Primitive type or null.
|
||||
*/
|
||||
private static Class getPrimitiveType(final String name) {
|
||||
return (Class) PRIMITIVES.get(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* VM primitive type name -> primitive type
|
||||
*/
|
||||
private static final HashMap VM_PRIMITIVES = new HashMap();
|
||||
|
||||
/** Setup the vm primitives map. */
|
||||
static {
|
||||
VM_PRIMITIVES.put("B", byte.class);
|
||||
VM_PRIMITIVES.put("C", char.class);
|
||||
VM_PRIMITIVES.put("D", double.class);
|
||||
VM_PRIMITIVES.put("F", float.class);
|
||||
VM_PRIMITIVES.put("I", int.class);
|
||||
VM_PRIMITIVES.put("J", long.class);
|
||||
VM_PRIMITIVES.put("S", short.class);
|
||||
VM_PRIMITIVES.put("Z", boolean.class);
|
||||
VM_PRIMITIVES.put("V", void.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* VM primitive type primitive type -> name
|
||||
*/
|
||||
private static final HashMap VM_PRIMITIVES_REVERSE = new HashMap();
|
||||
|
||||
/** Setup the vm primitives reverse map. */
|
||||
static {
|
||||
VM_PRIMITIVES_REVERSE.put(byte.class, "B");
|
||||
VM_PRIMITIVES_REVERSE.put(char.class, "C");
|
||||
VM_PRIMITIVES_REVERSE.put(double.class, "D");
|
||||
VM_PRIMITIVES_REVERSE.put(float.class, "F");
|
||||
VM_PRIMITIVES_REVERSE.put(int.class, "I");
|
||||
VM_PRIMITIVES_REVERSE.put(long.class, "J");
|
||||
VM_PRIMITIVES_REVERSE.put(short.class, "S");
|
||||
VM_PRIMITIVES_REVERSE.put(boolean.class, "Z");
|
||||
VM_PRIMITIVES_REVERSE.put(void.class, "V");
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the primitive type for the given VM primitive name. <p/>
|
||||
* <p>
|
||||
* Mapping:
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* B - byte
|
||||
* C - char
|
||||
* D - double
|
||||
* F - float
|
||||
* I - int
|
||||
* J - long
|
||||
* S - short
|
||||
* Z - boolean
|
||||
* V - void
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @param name
|
||||
* VM primitive type name (B, C, J, ...)
|
||||
* @return Primitive type or null.
|
||||
*/
|
||||
private static Class getVMPrimitiveType(final String name) {
|
||||
return (Class) VM_PRIMITIVES.get(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Map of primitive types to their wrapper classes
|
||||
*/
|
||||
private static final Map PRIMITIVE_WRAPPERS = new HashMap();
|
||||
|
||||
/** Setup the wrapper map. */
|
||||
static {
|
||||
PRIMITIVE_WRAPPERS.put(Boolean.TYPE, Boolean.class);
|
||||
PRIMITIVE_WRAPPERS.put(Byte.TYPE, Byte.class);
|
||||
PRIMITIVE_WRAPPERS.put(Character.TYPE, Character.class);
|
||||
PRIMITIVE_WRAPPERS.put(Double.TYPE, Double.class);
|
||||
PRIMITIVE_WRAPPERS.put(Float.TYPE, Float.class);
|
||||
PRIMITIVE_WRAPPERS.put(Integer.TYPE, Integer.class);
|
||||
PRIMITIVE_WRAPPERS.put(Long.TYPE, Long.class);
|
||||
PRIMITIVE_WRAPPERS.put(Short.TYPE, Short.class);
|
||||
PRIMITIVE_WRAPPERS.put(Void.TYPE, Void.class);
|
||||
}
|
||||
}
|
|
@ -1,68 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* 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.activeio.command;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectStreamClass;
|
||||
import java.lang.reflect.Proxy;
|
||||
|
||||
/**
|
||||
* An input stream which uses the {@link org.apache.activeio.command.ClassLoading} helper class
|
||||
*
|
||||
* @version $Revision: 1.1 $
|
||||
*/
|
||||
public class ClassLoadingAwareObjectInputStream extends ObjectInputStream {
|
||||
|
||||
private static final ClassLoader myClassLoader = DefaultWireFormat.class.getClassLoader();
|
||||
|
||||
public ClassLoadingAwareObjectInputStream(InputStream in) throws IOException {
|
||||
super(in);
|
||||
}
|
||||
|
||||
protected Class resolveClass(ObjectStreamClass classDesc) throws IOException, ClassNotFoundException {
|
||||
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
|
||||
return loadClass(classDesc.getName(), classLoader);
|
||||
}
|
||||
|
||||
protected Class resolveProxyClass(String[] interfaces) throws IOException, ClassNotFoundException {
|
||||
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
|
||||
Class[] interfaceClasses = new Class[interfaces.length];
|
||||
for (int i = 0; i < interfaces.length; i++) {
|
||||
interfaceClasses[i] = loadClass(interfaces[i], classLoader);
|
||||
}
|
||||
|
||||
try {
|
||||
return Proxy.getProxyClass(interfaceClasses[0].getClassLoader(), interfaceClasses);
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
throw new ClassNotFoundException(null, e);
|
||||
}
|
||||
}
|
||||
|
||||
protected Class loadClass(String className, ClassLoader classLoader) throws ClassNotFoundException {
|
||||
try {
|
||||
return ClassLoading.loadClass(className, classLoader);
|
||||
}
|
||||
catch (ClassNotFoundException e) {
|
||||
return ClassLoading.loadClass(className, myClassLoader);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,39 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* 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.activeio.command;
|
||||
|
||||
|
||||
/**
|
||||
* A listener of command objects
|
||||
*
|
||||
* @version $Revision: 1.1 $
|
||||
*/
|
||||
public interface CommandListener {
|
||||
|
||||
/**
|
||||
* Called when a command is received
|
||||
*
|
||||
*/
|
||||
public void onCommand(Object command);
|
||||
|
||||
/**
|
||||
* Called when an error occurs trying to
|
||||
* read a new command.
|
||||
*/
|
||||
void onError(Exception e);
|
||||
}
|
|
@ -1,75 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* 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.activeio.command;
|
||||
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectOutputStream;
|
||||
|
||||
import org.apache.activeio.adapter.PacketToInputStream;
|
||||
import org.apache.activeio.packet.ByteArrayPacket;
|
||||
import org.apache.activeio.packet.Packet;
|
||||
import org.apache.activeio.util.ByteArrayOutputStream;
|
||||
|
||||
/**
|
||||
* A default implementation which uses serialization
|
||||
*
|
||||
* @version $Revision: 1.1 $
|
||||
*/
|
||||
public class DefaultWireFormat implements WireFormat {
|
||||
|
||||
public Packet marshal(Object command) throws IOException {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
DataOutputStream ds = new DataOutputStream(baos);
|
||||
marshal(command, ds);
|
||||
ds.close();
|
||||
return new ByteArrayPacket(baos.toByteSequence());
|
||||
}
|
||||
|
||||
public Object unmarshal(Packet packet) throws IOException {
|
||||
return unmarshal(new DataInputStream(new PacketToInputStream(packet)));
|
||||
}
|
||||
|
||||
public void marshal(Object command, DataOutputStream ds) throws IOException {
|
||||
ObjectOutputStream out = new ObjectOutputStream(ds);
|
||||
out.writeObject(command);
|
||||
out.flush();
|
||||
out.reset();
|
||||
}
|
||||
|
||||
public Object unmarshal(DataInputStream ds) throws IOException {
|
||||
try {
|
||||
ClassLoadingAwareObjectInputStream in = new ClassLoadingAwareObjectInputStream(ds);
|
||||
Object command;
|
||||
command = in.readObject();
|
||||
in.close();
|
||||
return command;
|
||||
} catch (ClassNotFoundException e) {
|
||||
throw (IOException)new IOException("unmarshal failed: "+e).initCause(e);
|
||||
}
|
||||
}
|
||||
|
||||
public void setVersion(int version) {
|
||||
}
|
||||
|
||||
public int getVersion() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,64 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* 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.activeio.command;
|
||||
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
import org.apache.activeio.packet.Packet;
|
||||
|
||||
/**
|
||||
* Provides a mechanism to marshal commands into and out of packets
|
||||
* or into and out of streams, Channels and Datagrams.
|
||||
*
|
||||
* @version $Revision: 1.1 $
|
||||
*/
|
||||
public interface WireFormat {
|
||||
|
||||
/**
|
||||
* Packet based marshaling
|
||||
*/
|
||||
Packet marshal(Object command) throws IOException;
|
||||
|
||||
/**
|
||||
* Packet based un-marshaling
|
||||
*/
|
||||
Object unmarshal(Packet packet) throws IOException;
|
||||
|
||||
/**
|
||||
* Stream based marshaling
|
||||
*/
|
||||
void marshal(Object command, DataOutputStream out) throws IOException;
|
||||
|
||||
/**
|
||||
* Packet based un-marshaling
|
||||
*/
|
||||
Object unmarshal(DataInputStream in) throws IOException;
|
||||
|
||||
/**
|
||||
* @param the version of the wire format
|
||||
*/
|
||||
public void setVersion(int version);
|
||||
|
||||
/**
|
||||
* @return the version of the wire format
|
||||
*/
|
||||
public int getVersion();
|
||||
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* 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.activeio.command;
|
||||
|
||||
public interface WireFormatFactory {
|
||||
WireFormat createWireFormat();
|
||||
}
|
|
@ -1,29 +0,0 @@
|
|||
<!--
|
||||
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.
|
||||
-->
|
||||
<html>
|
||||
<head>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<p>
|
||||
An API and helper classes for working with Command objects; which are application level objects
|
||||
along with a WireFormat to reader/write directly with the media allowing higher layers to work directly
|
||||
with command objects and WireFormat instances instead of turning things into Packets and byte arrays etc.
|
||||
</p>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -1,60 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* 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.activeio.journal;
|
||||
|
||||
/**
|
||||
* Exception thrown by a Journal to indicate that an invalid RecordLocation was detected.
|
||||
*
|
||||
* @version $Revision: 1.1 $
|
||||
*/
|
||||
public class InvalidRecordLocationException extends Exception {
|
||||
|
||||
/**
|
||||
* Comment for <code>serialVersionUID</code>
|
||||
*/
|
||||
private static final long serialVersionUID = 3618414947307239475L;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public InvalidRecordLocationException() {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param msg
|
||||
*/
|
||||
public InvalidRecordLocationException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param msg
|
||||
* @param rootCause
|
||||
*/
|
||||
public InvalidRecordLocationException(String msg, Throwable rootCause) {
|
||||
super(msg, rootCause);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param rootCause
|
||||
*/
|
||||
public InvalidRecordLocationException(Throwable rootCause) {
|
||||
super(rootCause);
|
||||
}
|
||||
}
|
|
@ -1,128 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* 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.activeio.journal;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.apache.activeio.packet.Packet;
|
||||
|
||||
/**
|
||||
* A Journal is a record logging Interface that can be used to implement
|
||||
* a transaction log.
|
||||
*
|
||||
*
|
||||
* This interface was largely extracted out of the HOWL project to allow
|
||||
* ActiveMQ to switch between different Journal implementations verry easily.
|
||||
*
|
||||
* @version $Revision: 1.1 $
|
||||
*/
|
||||
public interface Journal {
|
||||
|
||||
/**
|
||||
* Writes a {@see Packet} of data to the journal. If <code>sync</code>
|
||||
* is true, then this call blocks until the data has landed on the physical
|
||||
* disk. Otherwise, this enqueues the write request and returns.
|
||||
*
|
||||
* @param record - the data to be written to disk.
|
||||
* @param sync - If this call should block until the data lands on disk.
|
||||
*
|
||||
* @return RecordLocation the location where the data will be written to on disk.
|
||||
*
|
||||
* @throws IOException if the write failed.
|
||||
* @throws IllegalStateException if the journal is closed.
|
||||
*/
|
||||
public RecordLocation write(Packet packet, boolean sync) throws IOException, IllegalStateException;
|
||||
|
||||
/**
|
||||
* Reads a previously written record from the journal.
|
||||
*
|
||||
* @param location is where to read the record from.
|
||||
*
|
||||
* @return the data previously written at the <code>location</code>.
|
||||
*
|
||||
* @throws InvalidRecordLocationException if <code>location</code> parameter is out of range.
|
||||
* It cannot be a location that is before the current mark.
|
||||
* @throws IOException if the record could not be read.
|
||||
* @throws IllegalStateException if the journal is closed.
|
||||
*/
|
||||
public Packet read(RecordLocation location) throws InvalidRecordLocationException, IOException, IllegalStateException;
|
||||
|
||||
/**
|
||||
* Informs the journal that all the journal space up to the <code>location</code> is no longer
|
||||
* needed and can be reclaimed for reuse.
|
||||
*
|
||||
* @param location the location of the record to mark. All record locations before the marked
|
||||
* location will no longger be vaild.
|
||||
*
|
||||
* @param sync if this call should block until the mark is set on the journal.
|
||||
*
|
||||
* @throws InvalidRecordLocationException if <code>location</code> parameter is out of range.
|
||||
* It cannot be a location that is before the current mark.
|
||||
* @throws IOException if the record could not be read.
|
||||
* @throws IllegalStateException if the journal is closed.
|
||||
*/
|
||||
public abstract void setMark(RecordLocation location, boolean sync)
|
||||
throws InvalidRecordLocationException, IOException, IllegalStateException;
|
||||
|
||||
/**
|
||||
* Obtains the mark that was set in the Journal.
|
||||
*
|
||||
* @see read(RecordLocation location);
|
||||
* @return the mark that was set in the Journal.
|
||||
* @throws IllegalStateException if the journal is closed.
|
||||
*/
|
||||
public RecordLocation getMark() throws IllegalStateException;
|
||||
|
||||
|
||||
/**
|
||||
* Close the Journal.
|
||||
* This is blocking operation that waits for any pending put opperations to be forced to disk.
|
||||
* Once the Journal is closed, all other methods of the journal should throw IllegalStateException.
|
||||
*
|
||||
* @throws IOException if an error occurs while the journal is being closed.
|
||||
*/
|
||||
public abstract void close() throws IOException;
|
||||
|
||||
/**
|
||||
* Allows you to get the next RecordLocation after the <code>location</code> that
|
||||
* is in the journal.
|
||||
*
|
||||
* @param location the reference location the is used to find the next location.
|
||||
* To get the oldest location available in the journal, <code>location</code>
|
||||
* should be set to null.
|
||||
*
|
||||
*
|
||||
* @return the next record location
|
||||
*
|
||||
* @throws InvalidRecordLocationException if <code>location</code> parameter is out of range.
|
||||
* It cannot be a location that is before the current mark.
|
||||
* @throws IllegalStateException if the journal is closed.
|
||||
*/
|
||||
public abstract RecordLocation getNextRecordLocation(RecordLocation location)
|
||||
throws InvalidRecordLocationException, IOException, IllegalStateException;
|
||||
|
||||
|
||||
/**
|
||||
* Registers a <code>JournalEventListener</code> that will receive notifications from the Journal.
|
||||
*
|
||||
* @param listener object that will receive journal events.
|
||||
* @throws IllegalStateException if the journal is closed.
|
||||
*/
|
||||
public abstract void setJournalEventListener(JournalEventListener listener) throws IllegalStateException;
|
||||
|
||||
}
|
|
@ -1,38 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* 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.activeio.journal;
|
||||
|
||||
/**
|
||||
* Defines an object which listens for Journal Events.
|
||||
*
|
||||
* @version $Revision: 1.1 $
|
||||
*/
|
||||
public interface JournalEventListener {
|
||||
|
||||
/**
|
||||
* This event is issues when a Journal implementations wants to recover
|
||||
* disk space used by old records. If journal space is not reliquised
|
||||
* by setting the Journal's mark at or past the <code>safeLocation</code>
|
||||
* further write opperations against the Journal may casuse IOExceptions
|
||||
* to occur due to a log overflow condition.
|
||||
*
|
||||
* @param safeLocation the oldest location that the journal recomends the mark to be set.
|
||||
*/
|
||||
void overflowNotification(RecordLocation safeLocation);
|
||||
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue