diff --git a/build.gradle b/build.gradle index f299512d..a3c56038 100644 --- a/build.gradle +++ b/build.gradle @@ -75,7 +75,6 @@ subprojects { subproject -> ext { cglibVersion = '3.1' commonsIoVersion = '2.4' - erlangOtpVersion = '1.5.6' hamcrestVersion = '1.3' jacksonVersion = '1.9.13' jackson2Version = '2.3.2' @@ -190,26 +189,11 @@ project('spring-amqp') { } -project('spring-erlang') { - description = 'Spring Erlang Support' - dependencies { - - compile "org.springframework:spring-beans:$springVersion" - compile "commons-io:commons-io:$commonsIoVersion" - - compile ("javax.annotation:jsr250-api:1.0", optional) - compile "org.erlang.otp:jinterface:$erlangOtpVersion" - - } - -} - project('spring-rabbit') { description = 'Spring RabbitMQ Support' dependencies { compile project(":spring-amqp") - testCompile project(":spring-erlang") compile "com.rabbitmq:amqp-client:$rabbitmqVersion" compile ("com.rabbitmq:http-client:$rabbitmqHttpClientVersion", optional) diff --git a/settings.gradle b/settings.gradle index f31f626f..ba9b0a34 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,6 +1,5 @@ rootProject.name = 'spring-amqp-dist' include 'spring-amqp' -include 'spring-erlang' include 'spring-rabbit' diff --git a/spring-erlang/src/main/java/org/springframework/erlang/ErlangBadRpcException.java b/spring-erlang/src/main/java/org/springframework/erlang/ErlangBadRpcException.java deleted file mode 100644 index 19dc0996..00000000 --- a/spring-erlang/src/main/java/org/springframework/erlang/ErlangBadRpcException.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright 2002-2010 the original author or authors. - * - * 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. - */ -package org.springframework.erlang; - -import com.ericsson.otp.erlang.OtpErlangTuple; - -/** - * Exception thrown when an 'badrpc' is received from an Erlang RPC call. - * @author Mark Pollack - * - */ -@SuppressWarnings("serial") -public class ErlangBadRpcException extends OtpException { - - private OtpErlangTuple reasonTuple; - - public ErlangBadRpcException(String reason) { - super(reason); - } - - public ErlangBadRpcException(OtpErlangTuple tuple) { - super(tuple.toString()); - this.reasonTuple = tuple; - } - - public OtpErlangTuple getReasonTuple() { - return reasonTuple; - } - - - - - - - -} diff --git a/spring-erlang/src/main/java/org/springframework/erlang/ErlangErrorRpcException.java b/spring-erlang/src/main/java/org/springframework/erlang/ErlangErrorRpcException.java deleted file mode 100644 index 6d32fa4f..00000000 --- a/spring-erlang/src/main/java/org/springframework/erlang/ErlangErrorRpcException.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright 2002-2010 the original author or authors. - * - * 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. - */ -package org.springframework.erlang; - -import com.ericsson.otp.erlang.OtpErlangTuple; - -/** - * Exception thrown when an 'error' is received from an Erlang RPC call - * - * @author Mark Pollack - */ -@SuppressWarnings("serial") -public class ErlangErrorRpcException extends OtpException { - - private OtpErlangTuple reasonTuple; - - public ErlangErrorRpcException(String message) { - super(message); - } - - public ErlangErrorRpcException(OtpErlangTuple tuple) { - super(tuple.toString()); - this.reasonTuple = tuple; - } - - public OtpErlangTuple getReasonTuple() { - return reasonTuple; - } - - -} diff --git a/spring-erlang/src/main/java/org/springframework/erlang/OtpAuthException.java b/spring-erlang/src/main/java/org/springframework/erlang/OtpAuthException.java deleted file mode 100644 index 2749a31e..00000000 --- a/spring-erlang/src/main/java/org/springframework/erlang/OtpAuthException.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright 2002-2010 the original author or authors. - * - * 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. - */ - -package org.springframework.erlang; - -/** - * Runtime exception mirroring the OTP OtpAuthException. - * - * @author Mark Pollack - */ -@SuppressWarnings("serial") -public class OtpAuthException extends OtpException { - - public OtpAuthException(com.ericsson.otp.erlang.OtpAuthException cause) { - super(cause); - } - - public OtpAuthException(String msg, com.ericsson.otp.erlang.OtpAuthException cause) { - super(msg, cause); - } - -} diff --git a/spring-erlang/src/main/java/org/springframework/erlang/OtpException.java b/spring-erlang/src/main/java/org/springframework/erlang/OtpException.java deleted file mode 100644 index f5c42a51..00000000 --- a/spring-erlang/src/main/java/org/springframework/erlang/OtpException.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright 2002-2010 the original author or authors. - * - * 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. - */ - -package org.springframework.erlang; - -/** - * Base RuntimeException for errors that occur when executing OTP operations. - * - * @author Mark Pollack - */ -@SuppressWarnings("serial") -public class OtpException extends RuntimeException { - - public OtpException(String message) { - super(message); - } - - public OtpException(Throwable cause) { - super(cause); - } - - public OtpException(String message, Throwable cause) { - super(message, cause); - } - -} diff --git a/spring-erlang/src/main/java/org/springframework/erlang/OtpIOException.java b/spring-erlang/src/main/java/org/springframework/erlang/OtpIOException.java deleted file mode 100644 index 50594d96..00000000 --- a/spring-erlang/src/main/java/org/springframework/erlang/OtpIOException.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright 2002-2010 the original author or authors. - * - * 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. - */ - -package org.springframework.erlang; - -import java.io.IOException; - -/** - * RuntimeException wrapper for an {@link IOException} which - * can be commonly thrown from OTP operations. - * - * @author Mark Pollack - * @author Mark Fisher - */ -@SuppressWarnings("serial") -public class OtpIOException extends OtpException { - - public OtpIOException(IOException cause) { - super(cause); - } - - public OtpIOException(String message, IOException cause) { - super(message, cause); - } - -} diff --git a/spring-erlang/src/main/java/org/springframework/erlang/UncategorizedOtpException.java b/spring-erlang/src/main/java/org/springframework/erlang/UncategorizedOtpException.java deleted file mode 100644 index deb11a71..00000000 --- a/spring-erlang/src/main/java/org/springframework/erlang/UncategorizedOtpException.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright 2002-2010 the original author or authors. - * - * 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. - */ - -package org.springframework.erlang; - -/** - * A "catch-all" exception type within the OtpException hierarchy - * when no more specific cause is known. - * - * @author Mark Pollack - */ -@SuppressWarnings("serial") -public class UncategorizedOtpException extends OtpException { - - public UncategorizedOtpException(Throwable cause) { - super(cause); - } - - public UncategorizedOtpException(String message, Throwable cause) { - super(message, cause); - } - -} \ No newline at end of file diff --git a/spring-erlang/src/main/java/org/springframework/erlang/connection/Connection.java b/spring-erlang/src/main/java/org/springframework/erlang/connection/Connection.java deleted file mode 100644 index d4966119..00000000 --- a/spring-erlang/src/main/java/org/springframework/erlang/connection/Connection.java +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright 2002-2015 the original author or authors. - * - * 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. - */ - -package org.springframework.erlang.connection; - -import java.io.IOException; - -import com.ericsson.otp.erlang.OtpAuthException; -import com.ericsson.otp.erlang.OtpErlangExit; -import com.ericsson.otp.erlang.OtpErlangList; -import com.ericsson.otp.erlang.OtpErlangObject; - -/** - * A simple interface that is used to wrap access to the {@code OtpConnection} class - * in order to support caching of {@code OtpConnection}s via method interception. - * - * Note: The surface area of the API is all that is required to implement administrative - * functionality for the Spring AMQP admin project. - * To access the underlying {@code OtpConnection}, use the method {@code getTargetConnection} - * on the interface {@code ConnectionProxy} that is implemented by {@code DefaultConnection}. - * - * @author Mark Pollack - * @author aArtem Bilan - */ -public interface Connection { - - /** - * Close the connection to the remote node. - */ - void close(); - - /** - * Send an RPC request to the remote Erlang node. This convenience function - * creates the following message and sends it to 'rex' on the remote node: - *
-     * { self, { call, Mod, Fun, Args, user } }
-     * 
- *

- * Note that this method has unpredictable results if the remote node is not - * an Erlang node. - * @param mod the name of the Erlang module containing the function to be called. - * @param fun the name of the function to call. - * @param args a list of Erlang terms, to be used as arguments to the function. - * @exception java.io.IOException if the connection is not active or a communication - * error occurs. - */ - void sendRPC(final String mod, final String fun, final OtpErlangList args) throws IOException; - - /** - * Receive an RPC reply from the remote Erlang node. This convenience - * function receives a message from the remote node, and expects it to have - * the following format: - *

-     * { rex, Term }
-     * 
- * @return the second element of the tuple if the received message is a - * two-tuple, otherwise null. No further error checking is - * performed. - * @exception java.io.IOException if the connection is not active or a communication - * error occurs. - * @exception OtpErlangExit if an exit signal is received from a process on the - * peer node. - * @exception OtpAuthException if the remote node sends a message containing an - * invalid cookie. - */ - OtpErlangObject receiveRPC() throws IOException, OtpErlangExit, OtpAuthException; - - /** - * Send an RPC request to the remote Erlang node and receive result. - * The implementation must ensure {@code synchronized} mode of this method since - * the underlying {@code OtpConnection} isn't thread-safe. - * @param mod the name of the Erlang module containing the function to be called. - * @param fun the name of the function to call. - * @param args a list of Erlang terms, to be used as arguments to the function. - * @return the second element of the tuple if the received message is a - * two-tuple, otherwise null. No further error checking is - * performed. - * @exception java.io.IOException if the connection is not active or a communication - * error occurs. - * @exception OtpErlangExit if an exit signal is received from a process on the - * peer node. - * @exception OtpAuthException if the remote node sends a message containing an - * invalid cookie. - * @since 1.5 - */ - OtpErlangObject sendAndReceiveRPC(final String mod, final String fun, final OtpErlangList args) - throws IOException, OtpErlangExit, OtpAuthException; - -} diff --git a/spring-erlang/src/main/java/org/springframework/erlang/connection/ConnectionFactory.java b/spring-erlang/src/main/java/org/springframework/erlang/connection/ConnectionFactory.java deleted file mode 100644 index bdda9e5c..00000000 --- a/spring-erlang/src/main/java/org/springframework/erlang/connection/ConnectionFactory.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright 2002-2010 the original author or authors. - * - * 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. - */ - -package org.springframework.erlang.connection; - -import java.io.IOException; -import java.net.UnknownHostException; - -import com.ericsson.otp.erlang.OtpAuthException; -import com.ericsson.otp.erlang.OtpConnection; - -/** - * An interface based ConnectionFactory for creating {@link OtpConnection}s. - * - *

NOTE: The Rabbit API contains a ConnectionFactory class (same name). - * - * @author Mark Pollack - */ -public interface ConnectionFactory { - - Connection createConnection() throws UnknownHostException, OtpAuthException, IOException; - -} diff --git a/spring-erlang/src/main/java/org/springframework/erlang/connection/ConnectionFactoryUtils.java b/spring-erlang/src/main/java/org/springframework/erlang/connection/ConnectionFactoryUtils.java deleted file mode 100644 index 498b1cc5..00000000 --- a/spring-erlang/src/main/java/org/springframework/erlang/connection/ConnectionFactoryUtils.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright 2002-2015 the original author or authors. - * - * 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. - */ - -package org.springframework.erlang.connection; - - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -/** - * @author Mark Pollack - * @author Gary Russell - */ -public class ConnectionFactoryUtils { - - private static final Log logger = LogFactory.getLog(ConnectionFactoryUtils.class); - - - /** - * Release the given Connection by closing it. - * - * @param con The connection. - * @param cf The connection factory. - */ - public static void releaseConnection(Connection con, ConnectionFactory cf) { - if (con == null) { - return; - } - try { - con.close(); - } - catch (Exception ex) { - logger.debug("Could not close Otp Connection", ex); - } - } - -} diff --git a/spring-erlang/src/main/java/org/springframework/erlang/connection/ConnectionParameters.java b/spring-erlang/src/main/java/org/springframework/erlang/connection/ConnectionParameters.java deleted file mode 100644 index 43e3d226..00000000 --- a/spring-erlang/src/main/java/org/springframework/erlang/connection/ConnectionParameters.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright 2002-2010 the original author or authors. - * - * 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. - */ - - -package org.springframework.erlang.connection; - -import org.springframework.util.Assert; - -import com.ericsson.otp.erlang.OtpPeer; -import com.ericsson.otp.erlang.OtpSelf; - -/** - * Encapsulate properties to create a OtpConnection - * @author Mark Pollack - * - */ -public class ConnectionParameters { - - private OtpSelf otpSelf; - - private OtpPeer otpPeer; - - public ConnectionParameters(OtpSelf otpSelf, OtpPeer otpPeer) { - Assert.notNull(otpSelf, "OtpSelf must be non-null"); - Assert.notNull(otpPeer, "OtpPeer must be non-null"); - this.otpSelf = otpSelf; - this.otpPeer = otpPeer; - } - - public OtpSelf getOtpSelf() { - return otpSelf; - } - - public OtpPeer getOtpPeer() { - return otpPeer; - } - -} diff --git a/spring-erlang/src/main/java/org/springframework/erlang/connection/ConnectionProxy.java b/spring-erlang/src/main/java/org/springframework/erlang/connection/ConnectionProxy.java deleted file mode 100644 index 4bd4de15..00000000 --- a/spring-erlang/src/main/java/org/springframework/erlang/connection/ConnectionProxy.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright 2002-2010 the original author or authors. - * - * 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. - */ - -package org.springframework.erlang.connection; - -import com.ericsson.otp.erlang.OtpConnection; - -/** - * Subinterface of {@link Connection} to be implemented by Connection proxies. - * Allows access to the underlying target Connection - * - * @author Mark Pollack - * - */ -public interface ConnectionProxy extends Connection { - - OtpConnection getTargetConnection(); -} diff --git a/spring-erlang/src/main/java/org/springframework/erlang/connection/DefaultConnection.java b/spring-erlang/src/main/java/org/springframework/erlang/connection/DefaultConnection.java deleted file mode 100644 index 5a6bd6b1..00000000 --- a/spring-erlang/src/main/java/org/springframework/erlang/connection/DefaultConnection.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright 2002-2015 the original author or authors. - * - * 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. - */ - -package org.springframework.erlang.connection; - -import java.io.IOException; - -import com.ericsson.otp.erlang.OtpAuthException; -import com.ericsson.otp.erlang.OtpConnection; -import com.ericsson.otp.erlang.OtpErlangExit; -import com.ericsson.otp.erlang.OtpErlangList; -import com.ericsson.otp.erlang.OtpErlangObject; - -/** - * Basic implementation of {@link ConnectionProxy} that delegates - * to an underlying {@link OtpConnection}. - * @author Mark Pollack - * @author Artem Bilan - */ -public class DefaultConnection implements ConnectionProxy { - - private OtpConnection otpConnection; - - - public DefaultConnection(OtpConnection otpConnection) { - this.otpConnection = otpConnection; - } - - @Override - public void close() { - this.otpConnection.close(); - } - - @Override - public void sendRPC(String mod, String fun, OtpErlangList args) throws IOException { - this.otpConnection.sendRPC(mod, fun, args); - } - - @Override - public OtpErlangObject receiveRPC() throws IOException, OtpErlangExit, OtpAuthException { - return this.otpConnection.receiveRPC(); - } - - @Override - public synchronized OtpErlangObject sendAndReceiveRPC(String mod, String fun, OtpErlangList args) - throws IOException, OtpErlangExit, OtpAuthException { - sendRPC(mod, fun, args); - return receiveRPC(); - } - - public OtpConnection getTargetConnection() { - return this.otpConnection; - } - -} diff --git a/spring-erlang/src/main/java/org/springframework/erlang/connection/SimpleConnectionFactory.java b/spring-erlang/src/main/java/org/springframework/erlang/connection/SimpleConnectionFactory.java deleted file mode 100644 index 1f232483..00000000 --- a/spring-erlang/src/main/java/org/springframework/erlang/connection/SimpleConnectionFactory.java +++ /dev/null @@ -1,138 +0,0 @@ -/* - * Copyright 2002-2010 the original author or authors. - * - * 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. - */ - -package org.springframework.erlang.connection; - -import java.io.IOException; -import java.net.UnknownHostException; -import java.util.UUID; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.springframework.beans.factory.InitializingBean; -import org.springframework.erlang.OtpIOException; -import org.springframework.util.Assert; -import org.springframework.util.StringUtils; - -import com.ericsson.otp.erlang.OtpAuthException; -import com.ericsson.otp.erlang.OtpPeer; -import com.ericsson.otp.erlang.OtpSelf; - -/** - *

- * A simple implementation of {@link ConnectionFactory} that return a new connection for each invocation of the - * createConnection method. - *

- *

- * Note that use of this ConnectionFactory with ErlangTemplate has unstable behavior when invoked frequently and will be - * deprecated. See {@link SingleConnectionFactory} for an alternative implementation. - *

- *

- * Provides a more traditional API to creating a connection to a remote erlang node than the JInterface API. - *

- *

- * The following is taken from the JInterface javadocs that describe the valid node names that can be used. These naming - * constraints apply to the string values you pass into the node names in SimpleConnectionFactory's constructor. - *

- *

- * About nodenames: Erlang nodenames consist of two components, an alivename and a hostname separated by '@'. - * Additionally, there are two nodename formats: short and long. Short names are of the form "alive@hostname", while - * long names are of the form "alive@host.fully.qualified.domainname". Erlang has special requirements regarding the use - * of the short and long formats, in particular they cannot be mixed freely in a network of communicating nodes, however - * Jinterface makes no distinction. See the Erlang documentation for more information about nodenames. - *

- * - *

- * The constructors for the AbstractNode classes will create names exactly as you provide them as long as the name - * contains '@'. If the string you provide contains no '@', it will be treated as an alivename and the name of the local - * host will be appended, resulting in a shortname. Nodenames longer than 255 characters will be truncated without - * warning. - *

- * - *

- * Upon initialization, this class attempts to read the file .erlang.cookie in the user's home directory, and uses the - * trimmed first line of the file as the default cookie by those constructors lacking a cookie argument. If for any - * reason the file cannot be found or read, the default cookie will be set to the empty string (""). The location of a - * user's home directory is determined using the system property "user.home", which may not be automatically set on all - * platforms. - *

- * @author Mark Pollack - * @author Mark Fisher - * @author Dave Syer - */ -public class SimpleConnectionFactory implements ConnectionFactory, InitializingBean { - - protected final Log logger = LogFactory.getLog(getClass()); - - private boolean uniqueSelfNodeName = true; - - private final String selfNodeName; - - private final String peerNodeName; - - private final String cookie; - - private OtpSelf otpSelf; - - private OtpPeer otpPeer; - - public SimpleConnectionFactory(String selfNodeName, String peerNodeName, String cookie) { - this.selfNodeName = selfNodeName; - this.peerNodeName = peerNodeName; - this.cookie = cookie; - } - - public SimpleConnectionFactory(String selfNodeName, String peerNodeName) { - this(selfNodeName, peerNodeName, null); - } - - public Connection createConnection() throws UnknownHostException, OtpAuthException, IOException { - try { - return new DefaultConnection(otpSelf.connect(otpPeer)); - } catch (IOException ex) { - throw new OtpIOException("failed to connect from '" + this.selfNodeName + "' to peer node '" - + this.peerNodeName + "'", ex); - } - } - - public boolean isUniqueSelfNodeName() { - return uniqueSelfNodeName; - } - - public void setUniqueSelfNodeName(boolean uniqueSelfNodeName) { - this.uniqueSelfNodeName = uniqueSelfNodeName; - } - - public void afterPropertiesSet() { - - Assert.isTrue(this.selfNodeName != null && this.peerNodeName != null, - "'selfNodeName' and 'peerNodeName' are required"); - String selfNodeNameToUse = this.selfNodeName; - if (isUniqueSelfNodeName()) { - selfNodeNameToUse = this.selfNodeName + "-" + UUID.randomUUID().toString(); - logger.debug("Creating OtpSelf with node name = [" + selfNodeNameToUse + "]"); - } - try { - if (StringUtils.hasText(cookie)) { - this.otpSelf = new OtpSelf(selfNodeNameToUse.trim(), this.cookie); - } else { - this.otpSelf = new OtpSelf(selfNodeNameToUse.trim()); - } - } catch (IOException e) { - throw new OtpIOException(e); - } - this.otpPeer = new OtpPeer(this.peerNodeName.trim()); - - } - -} diff --git a/spring-erlang/src/main/java/org/springframework/erlang/connection/SingleConnectionFactory.java b/spring-erlang/src/main/java/org/springframework/erlang/connection/SingleConnectionFactory.java deleted file mode 100644 index dbc43207..00000000 --- a/spring-erlang/src/main/java/org/springframework/erlang/connection/SingleConnectionFactory.java +++ /dev/null @@ -1,300 +0,0 @@ -/* - * Copyright 2002-2015 the original author or authors. - * - * 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. - */ - -package org.springframework.erlang.connection; - -import java.io.IOException; -import java.lang.reflect.InvocationHandler; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.lang.reflect.Proxy; -import java.net.UnknownHostException; -import java.util.ArrayList; -import java.util.List; -import java.util.UUID; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import org.springframework.beans.factory.DisposableBean; -import org.springframework.beans.factory.InitializingBean; -import org.springframework.erlang.OtpIOException; -import org.springframework.util.Assert; - -import com.ericsson.otp.erlang.OtpAuthException; -import com.ericsson.otp.erlang.OtpPeer; -import com.ericsson.otp.erlang.OtpSelf; - -/** - * A {@link ConnectionFactory} implementation that returns the same Connections from all - * {@link #createConnection()} calls, and ignores calls to {@link Connection#close()}. - * - * Provides a more traditional API to creating a connection to a remote erlang - * node than the JInterface API. - * - *

- * The following is taken from the JInterface javadocs that describe the valid - * node names that can be used. These naming constraints apply to the string - * values you pass into the node names in SimpleConnectionFactory's constructor. - *

- * About nodenames: Erlang nodenames consist of two components, an alivename and - * a hostname separated by '@'. Additionally, there are two nodename formats: - * short and long. Short names are of the form "alive@hostname", while long - * names are of the form "alive@host.fully.qualified.domainname". Erlang has - * special requirements regarding the use of the short and long formats, in - * particular they cannot be mixed freely in a network of communicating nodes, - * however Jinterface makes no distinction. See the Erlang documentation for - * more information about nodenames. - *

- * - *

- * The constructors for the AbstractNode classes will create names exactly as - * you provide them as long as the name contains '@'. If the string you provide - * contains no '@', it will be treated as an alivename and the name of the local - * host will be appended, resulting in a shortname. Nodenames longer than 255 - * characters will be truncated without warning. - *

- * - *

- * Upon initialization, this class attempts to read the file .erlang.cookie in - * the user's home directory, and uses the trimmed first line of the file as the - * default cookie by those constructors lacking a cookie argument. If for any - * reason the file cannot be found or read, the default cookie will be set to - * the empty string (""). The location of a user's home directory is determined - * using the system property "user.home", which may not be automatically set on - * all platforms. - *

- * - * @author Mark Pollack - */ -public class SingleConnectionFactory implements ConnectionFactory, - InitializingBean, DisposableBean { - - protected final Log logger = LogFactory.getLog(getClass()); - - private boolean uniqueSelfNodeName = true; - - private final String selfNodeName; - - private String cookie; - - private final String peerNodeName; - - private OtpSelf otpSelf; - - private OtpPeer otpPeer; - - /** Raw JInterface Connection */ - private Connection targetConnection; - - /** Proxy Connection */ - private Connection connection; - - /** Synchronization monitor for the shared Connection */ - private final Object connectionMonitor = new Object(); - - public SingleConnectionFactory(String selfNodeName, String cookie, - String peerNodeName) { - this.selfNodeName = selfNodeName; - this.cookie = cookie; - this.peerNodeName = peerNodeName; - } - - public SingleConnectionFactory(String selfNodeName, String peerNodeName) { - this.selfNodeName = selfNodeName; - this.peerNodeName = peerNodeName; - } - - public boolean isUniqueSelfNodeName() { - return uniqueSelfNodeName; - } - - public void setUniqueSelfNodeName(boolean uniqueSelfNodeName) { - this.uniqueSelfNodeName = uniqueSelfNodeName; - } - - @Override - public Connection createConnection() throws UnknownHostException, - OtpAuthException { - synchronized (this.connectionMonitor) { - if (this.connection == null) { - try { - initConnection(); - } catch (IOException e) { - throw new OtpIOException("failed to connect from '" - + this.selfNodeName + "' to peer node '" - + this.peerNodeName + "'", e); - } - - } - return this.connection; - } - } - - public void initConnection() throws IOException, OtpAuthException { - synchronized (this.connectionMonitor) { - if (this.targetConnection != null) { - closeConnection(this.targetConnection); - } - this.targetConnection = doCreateConnection(); - prepareConnection(this.targetConnection); - if (logger.isInfoEnabled()) { - logger.info("Established shared Rabbit Connection: " - + this.targetConnection); - } - this.connection = getSharedConnectionProxy(this.targetConnection); - } - } - - /** - * Close the underlying shared connection. - * The provider of this ConnectionFactory needs to care for proper shutdown. - *

As this bean implements DisposableBean, a bean factory will - * automatically invoke this on destruction of its cached singletons. - */ - @Override - public void destroy() { - resetConnection(); - } - - /** - * Reset the underlying shared Connection, to be reinitialized on next access. - */ - public void resetConnection() { - synchronized (this.connectionMonitor) { - if (this.targetConnection != null) { - closeConnection(this.targetConnection); - } - this.targetConnection = null; - this.connection = null; - } - } - - /** - * Close the given Connection. - * - * @param connection - * the Connection to close - */ - protected void closeConnection(Connection connection) { - if (logger.isDebugEnabled()) { - logger.debug("Closing shared Rabbit Connection: " - + this.targetConnection); - } - try { - // TODO there are other close overloads close(int closeCode, - // java.lang.String closeMessage, int timeout) - connection.close(); - } - catch (Exception ex) { - logger.debug("Could not close shared Rabbit Connection", ex); - } - } - - /** - * Create a JInterface Connection via this class's ConnectionFactory. - * - * @return the new Otp Connection - * @throws OtpAuthException Any. - * @throws IOException Any. - */ - protected Connection doCreateConnection() throws IOException, - OtpAuthException { - return new DefaultConnection(otpSelf.connect(otpPeer)); - } - - protected void prepareConnection(Connection con) throws IOException { - } - - /** - * Wrap the given OtpConnection with a proxy that delegates every method - * call to it but suppresses close calls. This is useful for allowing - * application code to handle a special framework Connection just like an - * ordinary Connection from a Rabbit ConnectionFactory. - * - * @param target - * the original Connection to wrap - * @return the wrapped Connection - */ - protected Connection getSharedConnectionProxy(Connection target) { - List> classes = new ArrayList>(1); - classes.add(Connection.class); - return (Connection) Proxy.newProxyInstance( - Connection.class.getClassLoader(), - classes.toArray(new Class[classes.size()]), - new SharedConnectionInvocationHandler(target)); - } - - /* - * (non-Javadoc) - * - * @see - * org.springframework.beans.factory.InitializingBean#afterPropertiesSet() - */ - @Override - public void afterPropertiesSet() { - Assert.isTrue(this.selfNodeName != null || this.peerNodeName != null, - "'selfNodeName' or 'peerNodeName' is required"); - String selfNodeNameToUse = this.selfNodeName; - if (isUniqueSelfNodeName()) { - selfNodeNameToUse = this.selfNodeName + "-" + UUID.randomUUID().toString(); - logger.debug("Creating OtpSelf with node name = [" + selfNodeNameToUse + "]"); - } - try { - if (this.cookie == null) { - this.otpSelf = new OtpSelf(selfNodeNameToUse.trim()); - } else { - this.otpSelf = new OtpSelf(selfNodeNameToUse.trim(), this.cookie); - } - } catch (IOException e) { - throw new OtpIOException(e); - } - this.otpPeer = new OtpPeer(this.peerNodeName.trim()); - } - - private static class SharedConnectionInvocationHandler implements - InvocationHandler { - - private final Connection target; - - public SharedConnectionInvocationHandler(Connection target) { - this.target = target; - } - - @Override - public Object invoke(Object proxy, Method method, Object[] args) - throws Throwable { - if (method.getName().equals("equals")) { - // Only consider equal when proxies are identical. - return (proxy == args[0]); - } else if (method.getName().equals("hashCode")) { - // Use hashCode of Connection proxy. - return System.identityHashCode(proxy); - } else if (method.getName().equals("toString")) { - return "Shared Otp Connection: " + this.target; - } else if (method.getName().equals("close")) { - // Handle close method: don't pass the call on. - return null; - } - try { - return method.invoke(this.target, args); - } catch (InvocationTargetException ex) { - throw ex.getTargetException(); - } - } - } - -} diff --git a/spring-erlang/src/main/java/org/springframework/erlang/connection/package-info.java b/spring-erlang/src/main/java/org/springframework/erlang/connection/package-info.java deleted file mode 100644 index c272960a..00000000 --- a/spring-erlang/src/main/java/org/springframework/erlang/connection/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -/** - * Provides classes supporting connections. - */ -package org.springframework.erlang.connection; diff --git a/spring-erlang/src/main/java/org/springframework/erlang/core/Application.java b/spring-erlang/src/main/java/org/springframework/erlang/core/Application.java deleted file mode 100644 index 29f0e7cf..00000000 --- a/spring-erlang/src/main/java/org/springframework/erlang/core/Application.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright 2002-2010 the original author or authors. - * - * 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. - */ - -package org.springframework.erlang.core; - -import java.io.Serializable; - -/** - * Describes an Erlang application. Only three fields are supported as that is the level - * of information that rabbitmq returns when performing a status request. - * - * See http://www.erlang.org/doc/man/app.html for full details - * - * @author Mark Pollack - * - */ -@SuppressWarnings("serial") -public class Application implements Serializable { - - private String description; - - private String id; - - private String version; - - public Application(String description, String id, String version) { - super(); - this.description = description; - this.id = id; - this.version = version; - } - - public String getDescription() { - return description; - } - - public String getId() { - return id; - } - - - public String getVersion() { - return version; - } - - @Override - public String toString() { - return "Application [description=" + description + ", id=" + id - + ", version=" + version + "]"; - } - - - -} diff --git a/spring-erlang/src/main/java/org/springframework/erlang/core/ConnectionCallback.java b/spring-erlang/src/main/java/org/springframework/erlang/core/ConnectionCallback.java deleted file mode 100644 index e302bb70..00000000 --- a/spring-erlang/src/main/java/org/springframework/erlang/core/ConnectionCallback.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright 2002-2014 the original author or authors. - * - * 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. - */ - -package org.springframework.erlang.core; - -import org.springframework.erlang.connection.Connection; - -/** - * Basic callback for use in ErlangTemplate - * @author Mark Pollack - */ -public interface ConnectionCallback { - - /** - * Execute any number of operations against the supplied OTP connection, - * possibly returning a result. - * - * @param connection The connection. - * @return The result. - * @throws Exception We are not sure everything it throws. - */ - T doInConnection(Connection connection) throws Exception; - -} diff --git a/spring-erlang/src/main/java/org/springframework/erlang/core/ErlangOperations.java b/spring-erlang/src/main/java/org/springframework/erlang/core/ErlangOperations.java deleted file mode 100644 index 19f0270b..00000000 --- a/spring-erlang/src/main/java/org/springframework/erlang/core/ErlangOperations.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2002-2010 the original author or authors. - * - * 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. - */ - - -package org.springframework.erlang.core; - -import org.springframework.erlang.OtpException; -import org.springframework.erlang.support.converter.ErlangConverter; - -import com.ericsson.otp.erlang.OtpErlangList; -import com.ericsson.otp.erlang.OtpErlangObject; - -/** - * Operations to perform against OTP/Erlang - * @author Mark Pollack - * - */ -public interface ErlangOperations { - - T execute(ConnectionCallback action) throws OtpException; - - OtpErlangObject executeErlangRpc(String module, String function, OtpErlangList args) throws OtpException; - - - OtpErlangObject executeErlangRpc(String module, String function, OtpErlangObject... args) throws OtpException; - - - OtpErlangObject executeRpc(String module, String function, Object... args) throws OtpException; - - Object executeAndConvertRpc(String module, String function, ErlangConverter converterToUse, Object... args) throws OtpException; - - Object executeAndConvertRpc(String module, String function, Object... args) throws OtpException; -} diff --git a/spring-erlang/src/main/java/org/springframework/erlang/core/ErlangTemplate.java b/spring-erlang/src/main/java/org/springframework/erlang/core/ErlangTemplate.java deleted file mode 100644 index 72f4295e..00000000 --- a/spring-erlang/src/main/java/org/springframework/erlang/core/ErlangTemplate.java +++ /dev/null @@ -1,152 +0,0 @@ -/* - * Copyright 2002-2015 the original author or authors. - * - * 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. - */ - -package org.springframework.erlang.core; - -import org.springframework.erlang.ErlangBadRpcException; -import org.springframework.erlang.ErlangErrorRpcException; -import org.springframework.erlang.OtpException; -import org.springframework.erlang.connection.Connection; -import org.springframework.erlang.connection.ConnectionFactory; -import org.springframework.erlang.support.ErlangAccessor; -import org.springframework.erlang.support.ErlangUtils; -import org.springframework.erlang.support.converter.ErlangConverter; -import org.springframework.erlang.support.converter.SimpleErlangConverter; -import org.springframework.util.Assert; - -import com.ericsson.otp.erlang.*; - - -/** - * @author Mark Pollack - * @author Artem Bilan - */ -public class ErlangTemplate extends ErlangAccessor implements ErlangOperations { - - - private volatile ErlangConverter erlangConverter = new SimpleErlangConverter(); - - public ErlangTemplate(ConnectionFactory connectionFactory) { - setConnectionFactory(connectionFactory); - afterPropertiesSet(); - } - - public OtpErlangObject executeErlangRpc(final String module, final String function, final OtpErlangList args) { - return execute(new ConnectionCallback() { - public OtpErlangObject doInConnection(Connection connection) throws Exception { - logger.debug("Sending RPC for module [" + module + "] function [" + function + "] args [" + args); - OtpErlangObject response = connection.sendAndReceiveRPC(module, function, args); - logger.debug("Response received = " + response.toString()); - handleResponseError(module, function, response); - return response; - } - }); - } - - public void handleResponseError(String module, String function, OtpErlangObject result) { - //{badrpc,{'EXIT',{undef,[{rabbit_access_control,list_users,[[]]},{rpc,'-handle_call/3-fun-0-',5}]}}} - - if (result instanceof OtpErlangTuple) { - OtpErlangTuple msg = (OtpErlangTuple)result; - if (msg.elementAt(0) instanceof OtpErlangAtom) - { - OtpErlangAtom responseAtom = (OtpErlangAtom)msg.elementAt(0); - //TODO consider error handler strategy. - if (responseAtom.atomValue().equals("badrpc")) { - if (msg.elementAt(1) instanceof OtpErlangTuple) { - throw new ErlangBadRpcException( (OtpErlangTuple)msg.elementAt(1)); - } else { - throw new ErlangBadRpcException( msg.elementAt(1).toString()); - } - } else if (responseAtom.atomValue().equals("error")) { - if (msg.elementAt(1) instanceof OtpErlangTuple) { - throw new ErlangErrorRpcException( (OtpErlangTuple)msg.elementAt(1)); - } else { - throw new ErlangErrorRpcException( msg.elementAt(1).toString()); - } - } - } - } - } - - public OtpErlangObject executeErlangRpc(String module, String function, OtpErlangObject... args) { - return executeRpc(module, function, new OtpErlangList(args)); - } - - public OtpErlangObject executeRpc(String module, String function, Object... args) { - return executeErlangRpc(module, function, (OtpErlangList) erlangConverter.toErlang(args)); - } - - public Object executeAndConvertRpc(String module, String function, ErlangConverter converterToUse, Object... args) { - return converterToUse.fromErlang(executeRpc(module, function, converterToUse.toErlang(args))); - } - - public Object executeAndConvertRpc(String module, String function, Object... args) { - return erlangConverter.fromErlangRpc(module, function, executeErlangRpc(module, function, (OtpErlangList)erlangConverter.toErlang(args))); - } - - public ErlangConverter getErlangConverter() { - return erlangConverter; - } - - public void setErlangConverter(ErlangConverter erlangConverter) { - this.erlangConverter = erlangConverter; - } - - public T execute(ConnectionCallback action) throws OtpException { - - Assert.notNull(action, "Callback object must not be null"); - Connection con = null; - try { - con = createConnection(); - return action.doInConnection(con); - } - catch (OtpException ex) { - throw ex; - } - catch (Exception ex) { - throw convertOtpAccessException(ex); - } - finally { - org.springframework.erlang.connection.ConnectionFactoryUtils.releaseConnection(con, getConnectionFactory()); - } - // TODO: physically close and reopen the connection if there is an exception - - } - - /** - * Convert the specified checked exception to - * a Spring runtime exception equivalent. - *

The default implementation delegates to the - * {@link org.springframework.erlang.support.ErlangUtils#convertOtpAccessException} method. - * @param ex the original checked {@link Exception} to convert - * @return the Spring runtime wrapping ex - * @see org.springframework.erlang.support.ErlangUtils#convertOtpAccessException - */ - protected OtpException convertOtpAccessException(Exception ex) { - return ErlangUtils.convertOtpAccessException(ex); - } - - - - - - - - - - -} diff --git a/spring-erlang/src/main/java/org/springframework/erlang/core/Node.java b/spring-erlang/src/main/java/org/springframework/erlang/core/Node.java deleted file mode 100644 index 0dfa95d1..00000000 --- a/spring-erlang/src/main/java/org/springframework/erlang/core/Node.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright 2002-2010 the original author or authors. - * - * 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. - */ - -/** - * Describes an Erlang node. - */ -package org.springframework.erlang.core; - -import java.io.Serializable; - -/** - * Simple description class for an Erlang node. - * - * @author Mark Pollack - * - */ -@SuppressWarnings("serial") -public class Node implements Serializable { - - private String name; - - public Node(String name) { - this.name = name; - } - - public String getName() { - return name; - } - - @Override - public String toString() { - return "Node [name=" + name + "]"; - } - -} diff --git a/spring-erlang/src/main/java/org/springframework/erlang/core/package-info.java b/spring-erlang/src/main/java/org/springframework/erlang/core/package-info.java deleted file mode 100644 index 447c4497..00000000 --- a/spring-erlang/src/main/java/org/springframework/erlang/core/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -/** - * Provides core classes for Spring Erlang. - */ -package org.springframework.erlang.core; diff --git a/spring-erlang/src/main/java/org/springframework/erlang/package-info.java b/spring-erlang/src/main/java/org/springframework/erlang/package-info.java deleted file mode 100644 index 77ec4756..00000000 --- a/spring-erlang/src/main/java/org/springframework/erlang/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -/** - * Base package for Spring Erlang. - */ -package org.springframework.erlang; diff --git a/spring-erlang/src/main/java/org/springframework/erlang/support/ErlangAccessor.java b/spring-erlang/src/main/java/org/springframework/erlang/support/ErlangAccessor.java deleted file mode 100644 index 31685adc..00000000 --- a/spring-erlang/src/main/java/org/springframework/erlang/support/ErlangAccessor.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright 2002-2010 the original author or authors. - * - * 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. - */ - -package org.springframework.erlang.support; - -import java.io.IOException; -import java.net.UnknownHostException; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import org.springframework.beans.factory.InitializingBean; -import org.springframework.erlang.OtpException; -import org.springframework.erlang.connection.Connection; -import org.springframework.erlang.connection.ConnectionFactory; - -import com.ericsson.otp.erlang.OtpAuthException; - -/** - * @author Mark Pollack - */ -public abstract class ErlangAccessor implements InitializingBean { - - /** Logger available to subclasses */ - protected final Log logger = LogFactory.getLog(getClass()); - - private ConnectionFactory connectionFactory; - - protected Connection createConnection() throws UnknownHostException, OtpAuthException, IOException { - return getConnectionFactory().createConnection(); - } - - public void setConnectionFactory(ConnectionFactory connectionFactory) { - this.connectionFactory = connectionFactory; - } - - public ConnectionFactory getConnectionFactory() { - return this.connectionFactory; - } - - - public void afterPropertiesSet() { - if (getConnectionFactory() == null) { - throw new IllegalArgumentException("Property 'connectionFactory' is required"); - } - } - - protected OtpException convertOtpAccessException(Exception ex) { - return ErlangUtils.convertOtpAccessException(ex); - } -} diff --git a/spring-erlang/src/main/java/org/springframework/erlang/support/ErlangUtils.java b/spring-erlang/src/main/java/org/springframework/erlang/support/ErlangUtils.java deleted file mode 100644 index edf2f602..00000000 --- a/spring-erlang/src/main/java/org/springframework/erlang/support/ErlangUtils.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright 2002-2010 the original author or authors. - * - * 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. - */ - -package org.springframework.erlang.support; - -import java.io.IOException; - -import org.springframework.erlang.OtpException; -import org.springframework.erlang.OtpIOException; -import org.springframework.erlang.UncategorizedOtpException; -import org.springframework.util.Assert; - -import com.ericsson.otp.erlang.OtpAuthException; -import com.ericsson.otp.erlang.OtpConnection; - -/** - * @author Mark Pollack - */ -public class ErlangUtils { - - /** - * Close the given Connection. - * @param con the Connection to close if necessary - * (if this is null, the call will be ignored) - */ - public static void releaseConnection(OtpConnection con) { - if (con == null) { - return; - } - con.close(); - } - - public static OtpException convertOtpAccessException(Exception ex) { - Assert.notNull(ex, "Exception must not be null"); - if (ex instanceof IOException) { - return new OtpIOException((IOException) ex); - } - if (ex instanceof OtpAuthException) { - return new org.springframework.erlang.OtpAuthException((OtpAuthException) ex); - } - //fallback - return new UncategorizedOtpException(ex); - } -} diff --git a/spring-erlang/src/main/java/org/springframework/erlang/support/converter/ErlangConversionException.java b/spring-erlang/src/main/java/org/springframework/erlang/support/converter/ErlangConversionException.java deleted file mode 100644 index 50195eab..00000000 --- a/spring-erlang/src/main/java/org/springframework/erlang/support/converter/ErlangConversionException.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright 2002-2010 the original author or authors. - * - * 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. - */ - -package org.springframework.erlang.support.converter; - -import org.springframework.erlang.OtpException; - -/** - * @author Mark Pollack - */ -@SuppressWarnings("serial") -public class ErlangConversionException extends OtpException { - - public ErlangConversionException(String message, Throwable cause) { - super(message, cause); - } - - public ErlangConversionException(String message) { - super(message); - } - -} diff --git a/spring-erlang/src/main/java/org/springframework/erlang/support/converter/ErlangConverter.java b/spring-erlang/src/main/java/org/springframework/erlang/support/converter/ErlangConverter.java deleted file mode 100644 index f493c351..00000000 --- a/spring-erlang/src/main/java/org/springframework/erlang/support/converter/ErlangConverter.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright 2002-2010 the original author or authors. - * - * 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. - */ - -package org.springframework.erlang.support.converter; - -import com.ericsson.otp.erlang.OtpErlangObject; - -/** - * Converter between Java and Erlang Types. Additional support for converting results from RPC calls. - * - * @author Mark Pollack - */ -public interface ErlangConverter { - - /** - * Convert a Java object to a Erlang data type. - * @param object the object to convert - * @return the Erlang data type - * @throws ErlangConversionException in case of conversion failure - */ - OtpErlangObject toErlang(Object object) throws ErlangConversionException; - - /** - * Convert from a Erlang data type to a Java object. - * @param erlangObject the Elang object to convert - * @return the converted Java object - * @throws ErlangConversionException in case of conversion failure - */ - Object fromErlang(OtpErlangObject erlangObject) throws ErlangConversionException; - - Object fromErlangRpc(String module, String function, OtpErlangObject erlangObject) throws ErlangConversionException; -} diff --git a/spring-erlang/src/main/java/org/springframework/erlang/support/converter/SimpleErlangConverter.java b/spring-erlang/src/main/java/org/springframework/erlang/support/converter/SimpleErlangConverter.java deleted file mode 100644 index 178aa768..00000000 --- a/spring-erlang/src/main/java/org/springframework/erlang/support/converter/SimpleErlangConverter.java +++ /dev/null @@ -1,158 +0,0 @@ -/* - * Copyright 2002-2010 the original author or authors. - * - * 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. - */ - -package org.springframework.erlang.support.converter; - -import java.util.ArrayList; - -import com.ericsson.otp.erlang.OtpErlangAtom; -import com.ericsson.otp.erlang.OtpErlangBinary; -import com.ericsson.otp.erlang.OtpErlangBoolean; -import com.ericsson.otp.erlang.OtpErlangByte; -import com.ericsson.otp.erlang.OtpErlangChar; -import com.ericsson.otp.erlang.OtpErlangDouble; -import com.ericsson.otp.erlang.OtpErlangFloat; -import com.ericsson.otp.erlang.OtpErlangInt; -import com.ericsson.otp.erlang.OtpErlangList; -import com.ericsson.otp.erlang.OtpErlangLong; -import com.ericsson.otp.erlang.OtpErlangObject; -import com.ericsson.otp.erlang.OtpErlangPid; -import com.ericsson.otp.erlang.OtpErlangRangeException; -import com.ericsson.otp.erlang.OtpErlangShort; -import com.ericsson.otp.erlang.OtpErlangString; - -/** - * Converter that supports the basic types and arrays. - * @author Mark Pollack - * - */ -public class SimpleErlangConverter implements ErlangConverter { - - public Object fromErlang(OtpErlangObject erlangObject) - throws ErlangConversionException { - //TODO support arrays. - return convertErlangToBasicType(erlangObject); - } - - public Object fromErlangRpc(String module, String function, - OtpErlangObject erlangObject) throws ErlangConversionException { - return this.fromErlang(erlangObject); - } - - public OtpErlangObject toErlang(Object obj) - throws ErlangConversionException { - if (obj instanceof OtpErlangObject) { - return (OtpErlangObject) obj; - } - if (obj instanceof Object[]) { - Object[] objectsToConvert = (Object[]) obj; - if (objectsToConvert.length != 0) { - ArrayList tempList = new ArrayList(); - - for (Object objectToConvert : objectsToConvert) { - OtpErlangObject erlangObject = convertBasicTypeToErlang(objectToConvert); - tempList.add(erlangObject); - } - OtpErlangObject ia[] = new OtpErlangObject[tempList.size()]; - return new OtpErlangList(tempList.toArray(ia)); - } else { - return new OtpErlangList(); - } - } else { - return convertBasicTypeToErlang(obj); - } - } - - protected OtpErlangObject convertBasicTypeToErlang(Object obj) { - if (obj instanceof byte[]) { - return new OtpErlangBinary((byte[]) obj); - } else if (obj instanceof Boolean) { - return new OtpErlangBoolean((Boolean) obj); - } else if (obj instanceof Byte) { - return new OtpErlangByte((Byte) obj); - } else if (obj instanceof Character) { - return new OtpErlangChar((Character) obj); - } else if (obj instanceof Double) { - return new OtpErlangDouble((Double) obj); - } else if (obj instanceof Float) { - return new OtpErlangFloat((Float) obj); - } else if (obj instanceof Integer) { - return new OtpErlangInt((Integer) obj); - } else if (obj instanceof Long) { - return new OtpErlangLong((Long) obj); - } else if (obj instanceof Short) { - return new OtpErlangShort((Short) obj); - } else if (obj instanceof String) { - return new OtpErlangString((String) obj); - } else { - throw new ErlangConversionException( - "Could not convert Java object of type [" + obj.getClass() - + "] to an Erlang data type."); - } - } - - protected Object convertErlangToBasicType(OtpErlangObject erlangObject) { - try { - if (erlangObject instanceof OtpErlangBinary) { - return ((OtpErlangBinary) erlangObject).binaryValue(); - } else if (erlangObject instanceof OtpErlangAtom) { - return ((OtpErlangAtom) erlangObject).atomValue(); - } else if (erlangObject instanceof OtpErlangBinary) { - return ((OtpErlangBinary) erlangObject).binaryValue(); - } else if (erlangObject instanceof OtpErlangBoolean) { - return extractBoolean(erlangObject); - } else if (erlangObject instanceof OtpErlangByte) { - return ((OtpErlangByte) erlangObject).byteValue(); - } else if (erlangObject instanceof OtpErlangChar) { - return ((OtpErlangChar) erlangObject).charValue(); - } else if (erlangObject instanceof OtpErlangDouble) { - return ((OtpErlangDouble) erlangObject).doubleValue(); - } else if (erlangObject instanceof OtpErlangFloat) { - return ((OtpErlangFloat) erlangObject).floatValue(); - } else if (erlangObject instanceof OtpErlangInt) { - return ((OtpErlangInt) erlangObject).intValue(); - } else if (erlangObject instanceof OtpErlangLong) { - return ((OtpErlangLong) erlangObject).longValue(); - } else if (erlangObject instanceof OtpErlangShort) { - return ((OtpErlangShort) erlangObject).shortValue(); - } else if (erlangObject instanceof OtpErlangString) { - return ((OtpErlangString) erlangObject).stringValue(); - } else if (erlangObject instanceof OtpErlangPid) { - return ((OtpErlangPid) erlangObject).toString(); - } else { - throw new ErlangConversionException( - "Could not convert Erlang object [" - + erlangObject.getClass() + "] to Java type."); - } - } catch (OtpErlangRangeException e) { - throw new ErlangConversionException( - "Could not convert Erlang object [" - + erlangObject.getClass() + "] to Java type.", e); - } - } - - public static boolean extractBoolean(OtpErlangObject erlangObject) { - return ((OtpErlangBoolean) erlangObject).booleanValue(); - } - - public static String extractPid(OtpErlangObject value) { - return ((OtpErlangPid)value).toString(); - } - - public static long extractLong(OtpErlangObject value) { - return ((OtpErlangLong)value).longValue(); - } -} diff --git a/spring-erlang/src/main/java/org/springframework/erlang/support/converter/package-info.java b/spring-erlang/src/main/java/org/springframework/erlang/support/converter/package-info.java deleted file mode 100644 index 2e188918..00000000 --- a/spring-erlang/src/main/java/org/springframework/erlang/support/converter/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -/** - * Provides classes conversion between Java and Erlang types. - */ -package org.springframework.erlang.support.converter; diff --git a/spring-erlang/src/main/java/org/springframework/erlang/support/package-info.java b/spring-erlang/src/main/java/org/springframework/erlang/support/package-info.java deleted file mode 100644 index 21015005..00000000 --- a/spring-erlang/src/main/java/org/springframework/erlang/support/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -/** - * Provides support classes for Spring Erlang. - */ -package org.springframework.erlang.support; diff --git a/spring-erlang/src/main/java/org/springframework/util/exec/Background.java b/spring-erlang/src/main/java/org/springframework/util/exec/Background.java deleted file mode 100644 index ba28bc5a..00000000 --- a/spring-erlang/src/main/java/org/springframework/util/exec/Background.java +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Copyright 2002-2014 the original author or authors. - * - * 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. - */ - -package org.springframework.util.exec; - -import java.io.File; -import java.io.IOException; -import java.util.ArrayList; - -/** - * Class to execute processes in the background. These processes - * will not exit once the controlling Java process exits. - */ -public class Background { - /** - * Execute the command (and its args, ala Runtime.exec), sending the - * output and error streams to the void. - * - * @param cmd The command and args. - * @throws IOException Any. - */ - public static void exec(String[] cmd) - throws IOException - { - File devNull; - if(Os.isFamily("unix")) { - devNull = new File("/dev/null"); - } - else if (Os.isFamily("windows")) { - devNull = new File("NUL"); - } - else { - throw new IllegalStateException("Unhandled Java environment"); - } - exec(cmd, devNull, false, devNull, false); - } - - /** - * Execute a command (and its args, ala Runtime.exec) - * - * @param cmd The command and args. - * @param outFile File to send standard out from the process to - * @param appendOut If true, append the file with standard out, - * else truncate or create a new file - * @param errFile File to send standard err from the process to - * @param appendErr If true, append the file with standard error, - * else truncate or create a new file - * - * @throws IOException Any. - */ - public static void exec(String[] cmd, - File outFile, boolean appendOut, - File errFile, boolean appendErr) - throws IOException - { - if(Os.isFamily("unix")) { - execUnix(cmd, outFile, appendOut, errFile, appendErr); - } - else if (Os.isFamily("windows")) { - execWin(cmd, outFile, appendOut, errFile, appendErr); - } - else { - throw new IllegalStateException("Unhandled Java environment"); - } - } - - private static void execUnix(String[] cmd, - File outFile, boolean appendOut, - File errFile, boolean appendErr) - throws IOException - { - StringBuffer escaped; - String[] execCmd; - - escaped = new StringBuffer(); - for(int i=0; i>" : ">") + - Escape.escape(outFile.getAbsolutePath()) + - " 2" + (appendErr == true ? ">>" : " >") + - Escape.escape(errFile.getAbsolutePath()) + - " tmpCmd = new ArrayList(); - - tmpCmd.add("cmd"); - tmpCmd.add("/c"); - tmpCmd.add("start"); - tmpCmd.add("/b"); - tmpCmd.add("\"\""); - tmpCmd.add("/MIN"); - for(int i=0; i>" : ">") + - Escape.escape(outFile.getAbsolutePath())); - tmpCmd.add((outFile.equals(errFile) ? " 2&" : " 2") + - (appendErr == true ? ">>" : " >") + - Escape.escape(errFile.getAbsolutePath())); - - Runtime.getRuntime().exec(tmpCmd.toArray(cmd)); - } - - public static void main(String[] args) throws Exception { - Background.exec(new String[] {"javaq", "foo bar", "bar" }, - new File("garfo"), true, new File("barfo"), true); - } -} diff --git a/spring-erlang/src/main/java/org/springframework/util/exec/Escape.java b/spring-erlang/src/main/java/org/springframework/util/exec/Escape.java deleted file mode 100644 index a5fc9ff5..00000000 --- a/spring-erlang/src/main/java/org/springframework/util/exec/Escape.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright 2002-2014 the original author or authors. - * - * 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. - */ - -package org.springframework.util.exec; - -public class Escape { - private static char[] enlargeArray(char[] in){ - char[] res; - - res = new char[in.length * 2]; - System.arraycopy(in, 0, res, 0, in.length); - return res; - } - - /** - * Escape a string by quoting the magical elements - * (such as whitespace, quotes, slashes, etc.) - * - * @param in The string to escape. - * @return The escaped string. - */ - public static String escape(String in){ - char[] inChars, outChars; - int numOut; - - inChars = new char[in.length()]; - outChars = new char[inChars.length]; - in.getChars(0, inChars.length, inChars, 0); - numOut = 0; - - for(int i=0; i procEnvironment = null; - - /** - * Find the list of environment variables for this process. - * - * @return The environment. - */ - public static synchronized Vector getProcEnvironment() { - - if (procEnvironment != null) { - return procEnvironment; - } - - procEnvironment = new Vector(); - try { - ByteArrayOutputStream out = new ByteArrayOutputStream(); - Execute exe = new Execute(new PumpStreamHandler(out)); - exe.setCommandline(getProcEnvCommand()); - // Make sure we do not recurse forever - exe.setNewenvironment(true); - exe.execute(); - - BufferedReader in = new BufferedReader(new StringReader(out.toString()));//NOSONAR (default charset) - String var = null; - String line, lineSep = System.getProperty("line.separator"); - while ((line = in.readLine()) != null) { - if (line.indexOf('=') == -1) { - // Chunk part of previous env var (UNIX env vars can - // contain embedded new lines). - if (var == null) { - var = lineSep + line; - } else { - var += lineSep + line;//NOSONAR - } - } else { - // New env var...append the previous one if we have it. - if (var != null) { - procEnvironment.addElement(var); - } - var = line; - } - } - // Since we "look ahead" before adding, there's one last env var. - procEnvironment.addElement(var); - } - catch (Exception exc) { - exc.printStackTrace(); - // Just try to see how much we got - } - return procEnvironment; - } - - private static String[] getProcEnvCommand() { - if (Os.isFamily("os/2")) { - // OS/2 - use same mechanism as Windows 2000 - // Not sure - String[] cmd = { "cmd", "/c", "set" }; - return cmd; - } else if (Os.isFamily("windows")) { - String[] cmd = { "cmd", "/c", "set" }; - return cmd; - } else if (Os.isFamily("unix")) { - // Generic UNIX - // Alternatively one could use: /bin/sh -c env - String[] cmd = { "/usr/bin/env" }; - return cmd; - } else if (Os.isFamily("netware")) { - String[] cmd = { "env" }; - return cmd; - } else { - // MAC OS 9 and previous - // TODO: I have no idea how to get it, someone must fix it - String[] cmd = null; - return cmd; - } - } - - /** - * Creates a new execute object using PumpStreamHandler for stream handling. - */ - public Execute() { - this(new PumpStreamHandler(), null); - } - - /** - * Creates a new execute object. - * - * @param streamHandler the stream handler used to handle the input and output streams of the subprocess. - */ - public Execute(ExecuteStreamHandler streamHandler) { - this(streamHandler, null); - } - - /** - * Creates a new execute object. - * - * @param streamHandler the stream handler used to handle the input and output streams of the subprocess. - * @param watchdog a watchdog for the subprocess or null to to disable a timeout for the subprocess. - */ - public Execute(ExecuteStreamHandler streamHandler, ExecuteWatchdog watchdog) { - this.streamHandler = streamHandler; - this.watchdog = watchdog; - } - - /** - * Returns the commandline used to create a subprocess. - * - * @return the commandline used to create a subprocess - */ - public String[] getCommandline() { - return cmdl;//NOSONAR - } - - public String getCommandLineString() { - return array2string(getCommandline()); - } - - /** - * Sets the commandline of the subprocess to launch. - * - * @param commandline the commandline of the subprocess to launch - */ - public void setCommandline(String[] commandline) { - cmdl = Arrays.copyOf(commandline, commandline.length); - } - - /** - * Set whether to propagate the default environment or not. - * - * @param newenv whether to propagate the process environment. - */ - public void setNewenvironment(boolean newenv) { - newEnvironment = newenv; - } - - /** - * Returns the environment used to create a subprocess. - * - * @return the environment used to create a subprocess - */ - public String[] getEnvironment() { - if (env == null || newEnvironment) { - return env;//NOSONAR - } - return patchEnvironment(); - } - - /** - * Sets the environment variables for the subprocess to launch. - * - * @param env array of Strings, each element of which has an environment variable settings in format - * key=value - */ - public void setEnvironment(String[] env) { - this.env = Arrays.copyOf(env, env.length); - } - - /** - * Sets the working directory of the process to execute. - * - *

This is emulated using the antRun scripts unless the OS is Windows NT in which case a cmd.exe is spawned, or - * MRJ and setting user.dir works, or JDK 1.3 and there is official support in java.lang.Runtime. - * - * @param wd the working directory of the process. - */ - public void setWorkingDirectory(File wd) { - workingDirectory = wd; - } - - /** - * Runs a process defined by the command line and returns its exit status. - * - * @return the exit status of the subprocess or INVALID - * @throws Exception if launching of the subprocess failed - */ - public int execute() throws Exception { - process = Runtime.getRuntime().exec(getCommandline(), getEnvironment(), workingDirectory); - try { - streamHandler.setProcessInputStream(process.getOutputStream()); - streamHandler.setProcessOutputStream(process.getInputStream()); - streamHandler.setProcessErrorStream(process.getErrorStream()); - } catch (IOException e) { - process.destroy(); - throw e; - } - streamHandler.start(); - - if (watchdog != null) { - watchdog.start(process, Thread.currentThread()); - } - - if (log.isTraceEnabled()) { - log.trace("Waiting process "); - } - waitFor(process); - process = null; - - if (log.isTraceEnabled()) { - log.trace("End waiting, stop threads "); - } - if (watchdog != null) { - watchdog.stop(); - } - if (log.isTraceEnabled()) { - log.trace("Watchdog stopped "); - } - streamHandler.stop(); - if (log.isTraceEnabled()) { - log.trace("Stream handler stopped "); - } - if (watchdog != null) { - Exception ex = watchdog.getException(); - if (ex != null) { - throw ex; - } - } - int exit = getExitValue(); - - if (log.isDebugEnabled()) { - log.debug("Done exit=" + exit + " " + getCommandLineString()); - } - return exit; - } - - public void kill() { - if (process != null) { - process.destroy(); - } - } - - private String array2string(String sa[]) { - if (sa == null) { - return "null"; - } - StringBuffer sb = new StringBuffer(); - for (int i = 0; i < sa.length; i++) { - sb.append(sa[i]).append(" "); - } - return sb.toString(); - } - - protected void waitFor(Process process) { - try { - process.waitFor(); - setExitValue(process.exitValue()); - } catch (InterruptedException e) { - log.info("waitFor() interrupted "); - Thread.currentThread().interrupt(); - } - } - - protected void setExitValue(int value) { - exitValue = value; - } - - /** - * query the exit value of the process. - * - * @return the exit value, 1 if the process was killed, or Project.INVALID if no exit value has been received - */ - public int getExitValue() { - return exitValue; - } - - /** - * Patch the current environment with the new values from the user. - * - * @return the patched environment - */ - private String[] patchEnvironment() { - @SuppressWarnings("unchecked") - Vector osEnv = (Vector) getProcEnvironment().clone(); - for (int i = 0; i < env.length; i++) { - int pos = env[i].indexOf('='); - // Get key including "=" - String key = env[i].substring(0, pos + 1); - int size = osEnv.size(); - for (int j = 0; j < size; j++) { - if ((osEnv.elementAt(j)).startsWith(key)) { - osEnv.removeElementAt(j); - break; - } - } - osEnv.addElement(env[i]); - } - String[] result = new String[osEnv.size()]; - osEnv.copyInto(result); - return result; - } - - public static int execute(Vector envVars, String cmd, File baseDir) { - Vector v = new Vector(); - StringTokenizer st = new StringTokenizer(cmd, " "); - while (st.hasMoreTokens()) { - v.addElement(st.nextToken()); - } - - return execute(envVars, v, baseDir); - } - - public static int execute(Vector envVars, Vector cmd, File baseDir) { - return execute(envVars, cmd, baseDir, 10000 /* default time to wait */); - } - - /** - * Wrapper for common execution patterns - * - * @param envVars Environment variables to execute with (optional) - * @param cmd a vector of the commands to execute - * @param baseDir the base directory to run from (optional) - * @param timeToWait milliseconds to wait for completion - * - * @return The result. - */ - public static int execute(Vector envVars, Vector cmd, File baseDir, int timeToWait) { - try { - // We can collect the out or provide in if needed - ExecuteWatchdog watchdog = new ExecuteWatchdog(timeToWait); - watchdog.setDontkill(true); - PumpStreamHandler out = new PumpStreamHandler(); - Execute exec = new Execute(out, watchdog); - - String cmdA[] = new String[cmd.size()]; - cmd.toArray(cmdA); - if (log.isDebugEnabled()) { - StringBuffer sb = new StringBuffer(); - for (int i = 0; i < cmdA.length; i++) { - sb.append(cmdA[i] + " "); - } - log.debug("Exec: " + sb.toString()); - } - exec.setCommandline(cmdA); - - if (envVars != null) { - String env[] = new String[envVars.size()]; - envVars.toArray(env); - exec.setEnvironment(env); - } - - exec.setNewenvironment(false); - if (baseDir != null) { - exec.setWorkingDirectory(baseDir); - } - - exec.execute(); - int status = exec.getExitValue(); - log.debug("Exit value " + status); - return status; - } catch (Exception ex) { - System.err.println("An error has occurred in Execute."); - return -1; - } - } - -} diff --git a/spring-erlang/src/main/java/org/springframework/util/exec/ExecuteStreamHandler.java b/spring-erlang/src/main/java/org/springframework/util/exec/ExecuteStreamHandler.java deleted file mode 100644 index a94ad36b..00000000 --- a/spring-erlang/src/main/java/org/springframework/util/exec/ExecuteStreamHandler.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright 2002-2014 the original author or authors. - * - * 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. - */ - -package org.springframework.util.exec; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; - - -/** - * Used by Execute to handle input and output stream of - * subprocesses. - * - * @author thomas.haas@softwired-inc.com - */ -public interface ExecuteStreamHandler { - - /** - * Install a handler for the input stream of the subprocess. - * - * @param os output stream to write to the standard input stream of the - * subprocess - * @throws IOException Any. - */ - void setProcessInputStream(OutputStream os) throws IOException; - - /** - * Install a handler for the error stream of the subprocess. - * - * @param is input stream to read from the error stream from the subprocess - * @throws IOException Any. - */ - void setProcessErrorStream(InputStream is) throws IOException; - - /** - * Install a handler for the output stream of the subprocess. - * - * @param is input stream to read from the error stream from the subprocess - * @throws IOException Any. - */ - void setProcessOutputStream(InputStream is) throws IOException; - - /** - * Start handling of the streams. - * - * @throws IOException Any. - */ - void start() throws IOException; - - /** - * Stop handling of the streams - will not be restarted. - */ - void stop(); -} diff --git a/spring-erlang/src/main/java/org/springframework/util/exec/ExecuteWatchdog.java b/spring-erlang/src/main/java/org/springframework/util/exec/ExecuteWatchdog.java deleted file mode 100644 index bd45c836..00000000 --- a/spring-erlang/src/main/java/org/springframework/util/exec/ExecuteWatchdog.java +++ /dev/null @@ -1,180 +0,0 @@ -/* - * Copyright 2002-2015 the original author or authors. - * - * 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. - */ - -package org.springframework.util.exec; - - -/** - * Destroys a process running for too long. - * For example: - *

- * {@code
- *     ExecuteWatchdog watchdog = new ExecuteWatchdog(30000);
- *     Execute exec = new Execute(myloghandler, watchdog);
- *     exec.setCommandLine(mycmdline);
- *     int exitvalue = exec.execute();
- *     if (exitvalue != SUCCESS && watchdog.killedProcess()){
- *              // it was killed on purpose by the watchdog
- *     }
- * }
- * 
- - * @author thomas.haas@softwired-inc.com - * @author Stephane Bailliez - * @see Execute - */ -public class ExecuteWatchdog implements Runnable { - - /** the process to execute and watch for duration */ - private Process process; - - /** timeout duration. Once the process running time exceeds this it should be killed */ - private final int timeout; - - /** say whether or not the watchog is currently monitoring a process */ - private boolean watch = false; - - /** exception that might be thrown during the process execution */ - private Exception caught = null; - - /** say whether or not the process was killed due to running overtime */ - private boolean killedProcess = false; - - Thread execThread; - private boolean dontkill=false; - /** - * Creates a new watchdog with a given timeout. - * - * @param timeout the timeout for the process in milliseconds. It must be greather than 0. - */ - public ExecuteWatchdog(int timeout) { - if (timeout < 1) { - throw new IllegalArgumentException("timeout lesser than 1."); - } - this.timeout = timeout; - } - - - public void setDontkill( boolean b ) { - dontkill=b;//NOSONAR - } - - /** - * Watches the given process and terminates it, if it runs for too long. - * All information from the previous run are reset. - * @param process the process to monitor. It cannot be null - * @param execThread The thread. - * @throws IllegalStateException thrown if a process is still being monitored. - */ - public synchronized void start(Process process, Thread execThread) { - if (process == null) { - throw new NullPointerException("process is null."); - } - if (this.process != null) { - throw new IllegalStateException("Already running."); - } - this.caught = null; - this.killedProcess = false; - this.watch = true; - this.process = process; - final Thread thread = new Thread(this, "WATCHDOG"); - this.execThread=execThread; - thread.setDaemon(true); - thread.start(); - } - - /** - * Stops the watcher. It will notify all threads possibly waiting on this object. - */ - public synchronized void stop() { - watch = false; - notifyAll(); - } - - - /** - * Watches the process and terminates it, if it runs for too long. - */ - @Override - public synchronized void run() { - try { - // This isn't a Task, don't have a Project object to log. - // project.log("ExecuteWatchdog: timeout = "+timeout+" msec", Project.MSG_VERBOSE); - final long until = System.currentTimeMillis() + timeout; - long now; - while (watch && until > (now = System.currentTimeMillis())) { - try { - wait(until - now); - } catch (InterruptedException e) {} - } - - // If we are here, either someone stopped the watchdog, - // we are on timeout and the process must be killed, or - // we are on timeout and the process has already stopped. - try { - // We must check if the process was not stopped - // before being here - process.exitValue(); - } catch (IllegalThreadStateException e){ - // The process is not terminated, if this is really - // a timeout and not a manual stop then kill it. - if (watch){ - killedProcess = true; - if( ! dontkill ) { - process.destroy(); - } - if( execThread != null ) { - execThread.interrupt(); - } - } - } - } catch(Exception e) { - caught = e; - } finally { - cleanUp(); - } - } - - - /** - * reset the monitor flag and the process. - */ - protected void cleanUp() { - watch = false; - process = null; - } - - public Exception getException() { - return caught; - } - - /** - * Indicates whether or not the watchdog is still monitoring the process. - * @return true if the process is still running, otherwise false. - */ - public boolean isWatching(){ - return watch; - } - - /** - * Indicates whether the last process run was killed on timeout or not. - * @return true if the process was killed otherwise false. - */ - public boolean killedProcess(){ - return killedProcess; - } -} - diff --git a/spring-erlang/src/main/java/org/springframework/util/exec/Os.java b/spring-erlang/src/main/java/org/springframework/util/exec/Os.java deleted file mode 100644 index 128a6ec0..00000000 --- a/spring-erlang/src/main/java/org/springframework/util/exec/Os.java +++ /dev/null @@ -1,148 +0,0 @@ -/* - * Copyright 2002-2014 the original author or authors. - * - * 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. - */ - -package org.springframework.util.exec; - -import java.util.Locale; - -/** - * Condition that tests the OS type. - * - * @author Stefan Bodewig - * @author Magesh Umasankar - */ -public class Os { - private static final String osName = - System.getProperty("os.name").toLowerCase(Locale.US); - private static final String osArch = - System.getProperty("os.arch").toLowerCase(Locale.US); - private static final String osVersion = - System.getProperty("os.version").toLowerCase(Locale.US); - private static final String pathSep = System.getProperty("path.separator"); - - /** - * Determines if the OS on which Ant is executing matches the - * given OS family. - * - * @param family The OS family type desired
- * Possible values:
- * - * @return true if the OS is in the family. - * @since 1.5 - */ - public static boolean isFamily(String family) { - return isOs(family, null, null, null); - } - - /** - * Determines if the OS on which Ant is executing matches the - * given OS name. - * - * @param name The name. - * @return The result. - * @since 1.7 - */ - public static boolean isName(String name) { - return isOs(null, name, null, null); - } - - /** - * Determines if the OS on which Ant is executing matches the - * given OS architecture. - * - * @param arch The arch. - * @return The result. - * @since 1.7 - */ - public static boolean isArch(String arch) { - return isOs(null, null, arch, null); - } - - /** - * Determines if the OS on which Ant is executing matches the - * given OS version. - * - * @param version The version. - * @return The result. - * @since 1.7 - */ - public static boolean isVersion(String version) { - return isOs(null, null, null, version); - } - - /** - * Determines if the OS on which Ant is executing matches the - * given OS family, name, architecture and version - * - * @param family The OS family - * @param name The OS name - * @param arch The OS architecture - * @param version The OS version - * - * @return The result. - * @since 1.7 - */ - public static boolean isOs(String family, String name, String arch, - String version) { - boolean retValue = false; - - if (family != null || name != null || arch != null - || version != null) { - - boolean isFamily = true; - boolean isName = true; - boolean isArch = true; - boolean isVersion = true; - - if (family != null) { - if (family.equals("windows")) { - isFamily = osName.indexOf("windows") > -1; - } else if (family.equals("os/2")) { - isFamily = osName.indexOf("os/2") > -1; - } else if (family.equals("netware")) { - isFamily = osName.indexOf("netware") > -1; - } else if (family.equals("dos")) { - isFamily = pathSep.equals(";") && !isFamily("netware"); - } else if (family.equals("mac")) { - isFamily = osName.indexOf("mac") > -1; - } else if (family.equals("unix")) { - isFamily = pathSep.equals(":") - && (!isFamily("mac") || osName.endsWith("x")); - } else { - throw new RuntimeException( - "Don\'t know how to detect os family \"" - + family + "\""); - } - } - if (name != null) { - isName = name.equals(osName); - } - if (arch != null) { - isArch = arch.equals(osArch); - } - if (version != null) { - isVersion = version.equals(osVersion); - } - retValue = isFamily && isName && isArch && isVersion; - } - return retValue; - } -} diff --git a/spring-erlang/src/main/java/org/springframework/util/exec/PumpStreamHandler.java b/spring-erlang/src/main/java/org/springframework/util/exec/PumpStreamHandler.java deleted file mode 100644 index 36d5b6da..00000000 --- a/spring-erlang/src/main/java/org/springframework/util/exec/PumpStreamHandler.java +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Copyright 2002-2014 the original author or authors. - * - * 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. - */ -package org.springframework.util.exec; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; - -/** - * Copies standard output and error of subprocesses to standard output and - * error of the parent process. - * - * TODO: standard input of the subprocess is not implemented. - * - * @author thomas.haas@softwired-inc.com - */ -public class PumpStreamHandler implements ExecuteStreamHandler { - - private Thread inputThread; - private Thread errorThread; - - private final OutputStream out, err; - boolean running=false; - - public PumpStreamHandler(OutputStream out, OutputStream err) { - this.out = out; - this.err = err; - } - - public PumpStreamHandler(OutputStream outAndErr) { - this(outAndErr, outAndErr); - } - - public PumpStreamHandler() { - this(System.out, System.err); - } - - @Override - public void setProcessOutputStream(InputStream is) { - createProcessOutputPump(is, out); - } - - - @Override - public void setProcessErrorStream(InputStream is) { - createProcessErrorPump(is, err); - } - - - @Override - public void setProcessInputStream(OutputStream os) { - } - - - @Override - public void start() { - inputThread.start(); - errorThread.start(); - running=true; - } - - - @Override - public void stop() { - if( !running ) { - return; - } - try { - inputThread.join(1000); - } catch(InterruptedException e) {} - try { - errorThread.join(1000); - } catch(InterruptedException e) {} - try { - err.flush(); - } catch (IOException e) {} - try { - out.flush(); - } catch (IOException e) {} - running=false; - } - - protected OutputStream getErr() { - return err; - } - - protected OutputStream getOut() { - return out; - } - - protected void createProcessOutputPump(InputStream is, OutputStream os) { - inputThread = createPump(is, os); - } - - protected void createProcessErrorPump(InputStream is, OutputStream os) { - errorThread = createPump(is, os); - } - - - /** - * Creates a stream pumper to copy the given input stream to the given output stream. - * - * @param is The input stream. - * @param os The output stream. - * @return The thread. - */ - protected Thread createPump(InputStream is, OutputStream os) { - final Thread result = new Thread(new StreamPumper(is, os)); - result.setDaemon(true); - return result; - } - -} diff --git a/spring-erlang/src/main/java/org/springframework/util/exec/StreamPumper.java b/spring-erlang/src/main/java/org/springframework/util/exec/StreamPumper.java deleted file mode 100644 index e84b44cc..00000000 --- a/spring-erlang/src/main/java/org/springframework/util/exec/StreamPumper.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright 2002-2013 the original author or authors. - * - * 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. - */ - -package org.springframework.util.exec; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; - -/** - * Copies all data from an input stream to an output stream. - * - * @author thomas.haas@softwired-inc.com - */ -public class StreamPumper implements Runnable { - - // TODO: make SIZE and SLEEP instance variables. - // TODO: add a status flag to note if an error occured in run. - - private static final int SLEEP = 5; - private static final int SIZE = 128; - private InputStream is; - private OutputStream os; - - - /** - * Create a new stream pumper. - * - * @param is input stream to read data from - * @param os output stream to write data to. - */ - public StreamPumper(InputStream is, OutputStream os) { - this.is = is; - this.os = os; - } - - - /** - * Copies data from the input stream to the output stream. - * - * Terminates as soon as the input stream is closed or an error occurs. - */ - public void run() { - final byte[] buf = new byte[SIZE]; - - int length; - try { - while ((length = is.read(buf)) > 0) { - os.write(buf, 0, length); - try { - Thread.sleep(SLEEP); - } catch (InterruptedException e) {} - } - } catch(IOException e) {} - } -} diff --git a/spring-erlang/src/main/java/org/springframework/util/exec/package-info.java b/spring-erlang/src/main/java/org/springframework/util/exec/package-info.java deleted file mode 100644 index 7596d870..00000000 --- a/spring-erlang/src/main/java/org/springframework/util/exec/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -/** - * Provides classes supporting execution. - */ -package org.springframework.util.exec; diff --git a/spring-rabbit/src/test/java/org/springframework/amqp/rabbit/admin/JInterfaceIntegrationTests.java b/spring-rabbit/src/test/java/org/springframework/amqp/rabbit/admin/JInterfaceIntegrationTests.java deleted file mode 100755 index 7330557d..00000000 --- a/spring-rabbit/src/test/java/org/springframework/amqp/rabbit/admin/JInterfaceIntegrationTests.java +++ /dev/null @@ -1,219 +0,0 @@ -/* - * Copyright 2002-2015 the original author or authors. - * - * 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. - */ - -package org.springframework.amqp.rabbit.admin; - -import static org.junit.Assert.assertTrue; - -import java.io.BufferedReader; -import java.io.File; -import java.io.FileReader; -import java.io.IOException; -import java.net.UnknownHostException; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.TimeUnit; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.junit.After; -import org.junit.Assert; -import org.junit.Before; -import org.junit.ClassRule; -import org.junit.Test; - -import org.springframework.amqp.rabbit.test.BrokerTestUtils; -import org.springframework.amqp.rabbit.test.EnvironmentAvailable; -import org.springframework.erlang.connection.SingleConnectionFactory; -import org.springframework.erlang.core.ErlangTemplate; - -import com.ericsson.otp.erlang.OtpConnection; -import com.ericsson.otp.erlang.OtpErlangBinary; -import com.ericsson.otp.erlang.OtpErlangList; -import com.ericsson.otp.erlang.OtpErlangObject; -import com.ericsson.otp.erlang.OtpPeer; -import com.ericsson.otp.erlang.OtpSelf; - -/** - * @author Mark Pollack - * @author Mark Fisher - * @author Chris Beams - * @author Dave Syer - * @author Gary Russell - * @author Artem Bilan - */ -public class JInterfaceIntegrationTests { - - private static Log logger = LogFactory.getLog(JInterfaceIntegrationTests.class); - - private static int counter; - - private static final String NODE_NAME = "spring@localhost"; - - private OtpConnection connection = null; - - private RabbitBrokerAdmin brokerAdmin; - - @ClassRule - public static EnvironmentAvailable environment = new EnvironmentAvailable("BROKER_INTEGRATION_TEST"); - - @Before - public void init() { - brokerAdmin = BrokerTestUtils.getRabbitBrokerAdmin(NODE_NAME); - RabbitStatus status = brokerAdmin.getStatus(); - if (!status.isRunning()) { - brokerAdmin.startBrokerApplication(); - } - } - - @After - public void close() { - if (connection != null) { - connection.close(); - } - if (brokerAdmin != null) { - brokerAdmin.stopNode(); - } - } - - @Test - public void testRawApi() throws Exception { - - OtpSelf self = new OtpSelf("rabbit-monitor"); - - String hostName = NODE_NAME; - OtpPeer peer = new OtpPeer(hostName); - connection = self.connect(peer); - - OtpErlangObject[] objectArray = { new OtpErlangBinary("/".getBytes()) }; - - connection.sendRPC("rabbit_amqqueue", "info_all", new OtpErlangList(objectArray)); - - OtpErlangObject received = connection.receiveRPC(); - System.out.println(received); - System.out.println(received.getClass()); - - } - - @Test - public void otpTemplate() throws UnknownHostException { - - String selfNodeName = "rabbit-monitor"; - String peerNodeName = NODE_NAME; - - SingleConnectionFactory cf = new SingleConnectionFactory(selfNodeName, peerNodeName); - - cf.afterPropertiesSet(); - ErlangTemplate template = new ErlangTemplate(cf); - template.afterPropertiesSet(); - - long number = (Long) template.executeAndConvertRpc("erlang", "abs", -161803399); - Assert.assertEquals(161803399, number); - - cf.destroy(); - - } - - @Test - public void testRawOtpConnect() throws Exception { - createConnection(); - } - - @Test - public void stressTest() throws Exception { - String cookie = readCookie(); - logger.info("Cookie: " + cookie); - OtpConnection con = createConnection(); - boolean recycleConnection = false; - for (int i = 0; i < 100; i++) { - executeRpc(con, recycleConnection, "rabbit", "status"); - executeRpc(con, recycleConnection, "rabbit", "stop"); - executeRpc(con, recycleConnection, "rabbit", "status"); - executeRpc(con, recycleConnection, "rabbit", "start"); - executeRpc(con, recycleConnection, "rabbit", "status"); - if (i % 10 == 0) { - logger.debug("i = " + i); - } - } - } - - @Test - public void testConcurrency() throws Exception { - SingleConnectionFactory cf = new SingleConnectionFactory("rabbit-monitor", NODE_NAME); - cf.afterPropertiesSet(); - final ErlangTemplate template = new ErlangTemplate(cf); - template.afterPropertiesSet(); - - ExecutorService executorService = Executors.newFixedThreadPool(10); - - for (int i = 0; i < 10; i++) { - final int j = i; - executorService.execute(new Runnable() { - - @Override - public void run() { - Assert.assertEquals((long) j, template.executeAndConvertRpc("erlang", "abs", -j)); - } - - }); - } - - executorService.shutdown(); - - assertTrue(executorService.awaitTermination(10, TimeUnit.SECONDS)); - - cf.destroy(); - } - - public OtpConnection createConnection() throws Exception { - OtpSelf self = new OtpSelf("rabbit-monitor-" + counter++); - OtpPeer peer = new OtpPeer(NODE_NAME); - return self.connect(peer); - } - - private void executeRpc(OtpConnection con, boolean recycleConnection, String module, String function) - throws Exception, UnknownHostException { - con.sendRPC(module, function, new OtpErlangList()); - OtpErlangObject response = con.receiveRPC(); - logger.debug(module + " response received = " + response.toString()); - if (recycleConnection) { - con.close(); - con = createConnection(); - } - } - - private String readCookie() throws Exception { - String cookie = null; - final String dotCookieFilename = System.getProperty("user.home") + File.separator + ".erlang.cookie"; - BufferedReader br = null; - - try { - final File dotCookieFile = new File(dotCookieFilename); - - br = new BufferedReader(new FileReader(dotCookieFile)); - cookie = br.readLine().trim(); - return cookie; - } finally { - try { - if (br != null) { - br.close(); - } - } catch (final IOException e) { - } - } - } - -} diff --git a/spring-rabbit/src/test/java/org/springframework/amqp/rabbit/admin/QueueInfo.java b/spring-rabbit/src/test/java/org/springframework/amqp/rabbit/admin/QueueInfo.java deleted file mode 100755 index 1ff82671..00000000 --- a/spring-rabbit/src/test/java/org/springframework/amqp/rabbit/admin/QueueInfo.java +++ /dev/null @@ -1,176 +0,0 @@ -/* - * Copyright 2002-2010 the original author or authors. - * - * 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. - */ -package org.springframework.amqp.rabbit.admin; - - -/** - * This class represents a Queue that is configured on the RabbitMQ broker - * - * @author Mark Pollack - * - */ -public class QueueInfo { - /*{app.stock.request={transactions=0, acks_uncommitted=0, - * consumers=0, pid=#Pid, - * durable=false, messages=0, memory=2320, auto_delete=false, - * messages_ready=0, arguments=[], name=app.stock.request, - * messages_unacknowledged=0, messages_uncommitted=0}, - */ - - private long transactions; - - private long acksUncommitted; - - private long consumers; - - private String pid; - - private boolean durable; - - private long messages; - - private long memory; - - private boolean autoDelete; - - private long messagesReady; - - private String[] arguments; - - private String name; - - private long messagesUnacknowledged; - - private long messageUncommitted; - - public long getTransactions() { - return transactions; - } - - public void setTransactions(long transations) { - this.transactions = transations; - } - - public long getAcksUncommitted() { - return acksUncommitted; - } - - public void setAcksUncommitted(long acksUncommitted) { - this.acksUncommitted = acksUncommitted; - } - - public long getConsumers() { - return consumers; - } - - public void setConsumers(long consumers) { - this.consumers = consumers; - } - - public String getPid() { - return pid; - } - - public void setPid(String pid) { - this.pid = pid; - } - - public boolean isDurable() { - return durable; - } - - public void setDurable(boolean durable) { - this.durable = durable; - } - - public long getMessages() { - return messages; - } - - public void setMessages(long messages) { - this.messages = messages; - } - - public long getMemory() { - return memory; - } - - public void setMemory(long memory) { - this.memory = memory; - } - - public boolean isAutoDelete() { - return autoDelete; - } - - public void setAutoDelete(boolean autoDelete) { - this.autoDelete = autoDelete; - } - - public long getMessagesReady() { - return messagesReady; - } - - public void setMessagesReady(long messagesReady) { - this.messagesReady = messagesReady; - } - - public String[] getArguments() { - return arguments; - } - - public void setArguments(String[] args) { - this.arguments = args; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public long getMessagesUnacknowledged() { - return messagesUnacknowledged; - } - - public void setMessagesUnacknowledged(long messagesUnacknowledged) { - this.messagesUnacknowledged = messagesUnacknowledged; - } - - public long getMessageUncommitted() { - return messageUncommitted; - } - - public void setMessageUncommitted(long messageUncommitted) { - this.messageUncommitted = messageUncommitted; - } - - @Override - public String toString() { - return "QueueInfo [name=" + name + ", durable=" + durable - + ", autoDelete=" + autoDelete + ", arguments=" + arguments - + ", memory=" + memory + ", messages=" + messages - + ", consumers=" + consumers + ", transations=" + transactions - + ", acksUncommitted=" + acksUncommitted + ", messagesReady=" - + messagesReady + ", messageUncommitted=" + messageUncommitted - + ", messagesUnacknowledged=" + messagesUnacknowledged - + ", pid=" + pid + "]"; - } - - -} diff --git a/spring-rabbit/src/test/java/org/springframework/amqp/rabbit/admin/RabbitAdminAuthException.java b/spring-rabbit/src/test/java/org/springframework/amqp/rabbit/admin/RabbitAdminAuthException.java deleted file mode 100755 index 14d7edaa..00000000 --- a/spring-rabbit/src/test/java/org/springframework/amqp/rabbit/admin/RabbitAdminAuthException.java +++ /dev/null @@ -1,12 +0,0 @@ -package org.springframework.amqp.rabbit.admin; - -import org.springframework.erlang.OtpAuthException; - -@SuppressWarnings("serial") -public class RabbitAdminAuthException extends OtpAuthException { - - public RabbitAdminAuthException(String message, OtpAuthException cause) { - super(message, (com.ericsson.otp.erlang.OtpAuthException) cause.getCause()); - } - -} diff --git a/spring-rabbit/src/test/java/org/springframework/amqp/rabbit/admin/RabbitBrokerAdmin.java b/spring-rabbit/src/test/java/org/springframework/amqp/rabbit/admin/RabbitBrokerAdmin.java deleted file mode 100755 index 87ee5fde..00000000 --- a/spring-rabbit/src/test/java/org/springframework/amqp/rabbit/admin/RabbitBrokerAdmin.java +++ /dev/null @@ -1,713 +0,0 @@ -/* - * Copyright 2002-2011 the original author or authors. - * - * 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. - */ - -package org.springframework.amqp.rabbit.admin; - -import java.io.File; -import java.io.FilenameFilter; -import java.io.UnsupportedEncodingException; -import java.net.InetAddress; -import java.net.UnknownHostException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.concurrent.Callable; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.Future; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.regex.Pattern; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.springframework.core.task.AsyncTaskExecutor; -import org.springframework.core.task.SimpleAsyncTaskExecutor; -import org.springframework.erlang.OtpAuthException; -import org.springframework.erlang.OtpException; -import org.springframework.erlang.connection.ConnectionFactory; -import org.springframework.erlang.connection.SimpleConnectionFactory; -import org.springframework.erlang.core.Application; -import org.springframework.erlang.core.ErlangTemplate; -import org.springframework.erlang.core.Node; -import org.springframework.jmx.export.annotation.ManagedOperation; -import org.springframework.util.Assert; -import org.springframework.util.StringUtils; -import org.springframework.util.exec.Execute; -import org.springframework.util.exec.Os; - -/** - * Rabbit broker administration. Features: - * - * - * - * Depending on your platform, to {@link #startNode() start the broker} you might need to set some environment - * properties. The most common are available via constructors or setters in this class (e.g. - * {@link #setRabbitLogBaseDirectory(String) RABBITMQ_LOG_BASE}). All others you can set via the OS (any setting that - * RabbtMQ allows in its startup script), and some work via System properties as special convenience cases ( - * ERLANG_HOME and RABBITMQ_HOME ). - * - * @author Mark Pollack - * @author Dave Syer - * @author Helena Edelson - */ -public class RabbitBrokerAdmin implements RabbitBrokerOperations { - - private static final String DEFAULT_VHOST = "/"; - - private static String DEFAULT_NODE_NAME; - - private static final int DEFAULT_PORT = 5672; - - private static final String DEFAULT_ENCODING = "UTF-8"; - - /** Logger available to subclasses */ - protected final Log logger = LogFactory.getLog(getClass()); - - private ErlangTemplate erlangTemplate; - - private String encoding = DEFAULT_ENCODING; - - private long timeout = 0; - - private AsyncTaskExecutor executor; - - private final String nodeName; - - private final String cookie; - - private final int port; - - private String rabbitLogBaseDirectory; - - private String rabbitMnesiaBaseDirectory; - - private Map moduleAdapter = new HashMap(); - - static { - try { - String hostName = InetAddress.getLocalHost().getHostName(); - DEFAULT_NODE_NAME = "rabbit@" + hostName; - } catch (UnknownHostException e) { - DEFAULT_NODE_NAME = "rabbit@localhost"; - } - } - - public RabbitBrokerAdmin() { - this(DEFAULT_NODE_NAME); - } - - /** - * Create an instance by supplying the erlang node name (e.g. "rabbit@myserver"), or simply the hostname (if the - * alive name is "rabbit"). - * - * @param nodeName the node name or hostname to use - */ - public RabbitBrokerAdmin(String nodeName) { - this(nodeName, null); - } - - /** - * Create an instance by supplying the erlang node name and cookie (unique string). - * - * @param nodeName the node name or hostname to use - * - * @param cookie the cookie value to use - */ - public RabbitBrokerAdmin(String nodeName, String cookie) { - this(nodeName, DEFAULT_PORT, cookie); - } - - /** - * Create an instance by supplying the erlang node name and port number. Use this on a UN*X system if you want to - * run the broker as a user without root privileges, supplying values that do not clash with the default broker - * (usually "rabbit@<servername>" and 5672). If, as well as managing an existing broker, you need to start the - * broker process, you will also need to set {@link #setRabbitLogBaseDirectory(String) RABBITMQ_LOG_BASE} and - * {@link #setRabbitMnesiaBaseDirectory(String) RABBITMQ_MNESIA_BASE} to point to writable directories). - * - * @param nodeName the node name or hostname to use - * @param port the port number (overriding the default which is 5672) - */ - public RabbitBrokerAdmin(String nodeName, int port) { - this(nodeName, port, null); - } - - /** - * Create an instance by supplying the erlang node name, port number and cookie (unique string). If the node name - * does not contain an @ character, it will be prepended with an alivename rabbit@ - * (interpreting the supplied value as just the hostname). - * - * @param nodeName the node name or hostname to use - * @param port the port number (overriding the default which is 5672) - * @param cookie the cookie value to use - */ - public RabbitBrokerAdmin(String nodeName, int port, String cookie) { - - if (!nodeName.contains("@")) { - nodeName = "rabbit@" + nodeName; // it was just the host - } - - String[] parts = nodeName.split("@"); - Assert.state(parts.length == 2, "The node name should be in the form alivename@host, e.g. rabbit@myserver"); - if (Os.isFamily("windows") && !DEFAULT_NODE_NAME.equals(nodeName)) { - nodeName = parts[0] + "@" + parts[1].toUpperCase(); - } - - this.port = port; - this.cookie = cookie; - this.nodeName = nodeName; - SimpleAsyncTaskExecutor executor = new SimpleAsyncTaskExecutor(); - executor.setDaemon(true); - this.executor = executor; - - } - - /** - * An async task executor for launching background processing when starting or stopping the broker. - * - * @param executor the executor to set - */ - public void setExecutor(AsyncTaskExecutor executor) { - this.executor = executor; - } - - /** - * The location of RABBITMQ_LOG_BASE to override the system default (which may be owned by another - * user). Only needed for launching the broker process. Can also be set as a system property. - * - * @param rabbitLogBaseDirectory the rabbit log base directory to set - */ - public void setRabbitLogBaseDirectory(String rabbitLogBaseDirectory) { - this.rabbitLogBaseDirectory = rabbitLogBaseDirectory; - } - - /** - * The location of RABBITMQ_MNESIA_BASE to override the system default (which may be owned by another - * user). Only needed for launching the broker process. Can also be set as a system property. - * - * @param rabbitMnesiaBaseDirectory the rabbit Mnesia base directory to set - */ - public void setRabbitMnesiaBaseDirectory(String rabbitMnesiaBaseDirectory) { - this.rabbitMnesiaBaseDirectory = rabbitMnesiaBaseDirectory; - } - - /** - * The encoding to use for converting host names to byte arrays (which is needed on the remote side). - * @param encoding the encoding to use (default UTF-8) - */ - public void setEncoding(String encoding) { - this.encoding = encoding; - } - - /** - * Timeout (milliseconds) to wait for the broker to come up. If the provided timeout is greater than zero then we - * wait for that period for the broker to be ready. If it is not ready after that time the process is stopped. - * Defaults to 0 (no wait). - * - * @param timeout the timeout value to set in milliseconds - */ - public void setStartupTimeout(long timeout) { - this.timeout = timeout; - } - - /** - * Allows users to adapt Erlang RPC (module, function) pairs to older, or different, versions of the - * broker than the current target. The map is from String to String in the form - * input_module%input_function -> output_module%output_function (using a % separator). - * - * @param moduleAdapter the module adapter to set - */ - public void setModuleAdapter(Map moduleAdapter) { - this.moduleAdapter = moduleAdapter; - } - - @SuppressWarnings("unchecked") - public List getQueues() { - return (List) executeAndConvertRpc("rabbit_amqqueue", "info_all", getBytes(DEFAULT_VHOST)); - } - - @SuppressWarnings("unchecked") - public List getQueues(String virtualHost) { - return (List) executeAndConvertRpc("rabbit_amqqueue", "info_all", getBytes(virtualHost)); - } - - // User management - - @ManagedOperation() - public void addUser(String username, String password) { - executeAndConvertRpc("rabbit_auth_backend_internal", "add_user", getBytes(username), getBytes(password)); - } - - @ManagedOperation - public void deleteUser(String username) { - executeAndConvertRpc("rabbit_auth_backend_internal", "delete_user", getBytes(username)); - } - - @ManagedOperation - public void changeUserPassword(String username, String newPassword) { - executeAndConvertRpc("rabbit_auth_backend_internal", "change_password", getBytes(username), - getBytes(newPassword)); - } - - @SuppressWarnings("unchecked") - @ManagedOperation - public List listUsers() { - return (List) executeAndConvertRpc("rabbit_auth_backend_internal", "list_users"); - } - - public int addVhost(String vhostPath) { - // TODO Auto-generated method stub - return 0; - } - - public int deleteVhost(String vhostPath) { - // TODO Auto-generated method stub - return 0; - } - - public void setPermissions(String username, Pattern configure, Pattern read, Pattern write) { - // TODO Auto-generated method stub - } - - public void setPermissions(String username, Pattern configure, Pattern read, Pattern write, String vhostPath) { - // TODO Auto-generated method stub - } - - public void clearPermissions(String username) { - // TODO Auto-generated method stub - } - - public void clearPermissions(String username, String vhostPath) { - // TODO Auto-generated method stub - } - - public List listPermissions() { - // TODO Auto-generated method stub - return null; - } - - public List listPermissions(String vhostPath) { - // TODO Auto-generated method stub - return null; - } - - public List listUserPermissions(String username) { - // TODO Auto-generated method stub - return null; - } - - @ManagedOperation - public void startBrokerApplication() { - RabbitStatus status = getStatus(); - if (status.isReady()) { - logger.info("Rabbit Application already running."); - return; - } - if (!status.isAlive()) { - logger.info("Rabbit Process not running."); - startNode(); - return; - } - logger.info("Starting Rabbit Application."); - - // This call in particular seems to be prone to hanging, so do it in the background... - final CountDownLatch latch = new CountDownLatch(1); - Future result = executor.submit(new Callable() { - public Object call() throws Exception { - try { - return executeAndConvertRpc("rabbit", "start"); - } finally { - latch.countDown(); - } - } - }); - boolean started = false; - try { - started = latch.await(timeout, TimeUnit.MILLISECONDS); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - result.cancel(true); - return; - } - if (timeout > 0 && started) { - if (!waitForReadyState() && !result.isDone()) { - result.cancel(true); - } - } - } - - @ManagedOperation - public void stopBrokerApplication() { - logger.info("Stopping Rabbit Application."); - executeAndConvertRpc("rabbit", "stop"); - if (timeout > 0) { - waitForUnreadyState(); - } - } - - @ManagedOperation - public void startNode() { - - RabbitStatus status = getStatus(); - if (status.isAlive()) { - logger.info("Rabbit Process already running."); - startBrokerApplication(); - return; - } - - if (!status.isRunning() && status.isReady()) { - logger.info("Rabbit Process not running but status is ready. Restarting."); - stopNode(); - } - - logger.info("Starting RabbitMQ node by shelling out command line."); - final Execute execute = new Execute(); - - String rabbitStartScript = null; - String hint = ""; - if (Os.isFamily("windows") || Os.isFamily("dos")) { - rabbitStartScript = "sbin/rabbitmq-server.bat"; - } else if (Os.isFamily("unix") || Os.isFamily("mac")) { - rabbitStartScript = "bin/rabbitmq-server"; - hint = "Depending on your platform it might help to set RABBITMQ_LOG_BASE and RABBITMQ_MNESIA_BASE System properties to an empty directory."; - } - Assert.notNull(rabbitStartScript, "unsupported OS family"); - - String rabbitHome = System.getProperty("RABBITMQ_HOME", System.getenv("RABBITMQ_HOME")); - if (rabbitHome == null) { - if (Os.isFamily("windows") || Os.isFamily("dos")) { - rabbitHome = findDirectoryName("c:/Program Files", "rabbitmq"); - } else if (Os.isFamily("unix") || Os.isFamily("mac")) { - rabbitHome = "/usr/lib/rabbitmq"; - } - } - Assert.notNull(rabbitHome, "RABBITMQ_HOME system property (or environment variable) not set."); - - rabbitHome = StringUtils.cleanPath(rabbitHome); - String rabbitStartCommand = rabbitHome + "/" + rabbitStartScript; - String[] commandline = new String[] { rabbitStartCommand }; - - List env = new ArrayList(); - - if (rabbitLogBaseDirectory != null) { - env.add("RABBITMQ_LOG_BASE=" + rabbitLogBaseDirectory); - } else { - addEnvironment(env, "RABBITMQ_LOG_BASE"); - } - if (rabbitMnesiaBaseDirectory != null) { - env.add("RABBITMQ_MNESIA_BASE=" + rabbitMnesiaBaseDirectory); - } else { - addEnvironment(env, "RABBITMQ_MNESIA_BASE"); - } - addEnvironment(env, "ERLANG_HOME"); - - // Make the nodename explicitly the same so the erl process knows who we are - env.add("RABBITMQ_NODENAME=" + nodeName); - - // Set the port number for the new process - env.add("RABBITMQ_NODE_PORT=" + port); - - // Ask for a detached erl process so stdout doesn't get diverted to a black hole when the JVM dies (without this - // you can start the Rabbit broker form Java but if you forget to stop it, the erl process is hosed). - env.add("RABBITMQ_SERVER_ERL_ARGS=-detached"); - - execute.setCommandline(commandline); - execute.setEnvironment(env.toArray(new String[0])); - - final CountDownLatch running = new CountDownLatch(1); - final AtomicBoolean finished = new AtomicBoolean(false); - final String errorHint = hint; - - executor.execute(new Runnable() { - public void run() { - try { - running.countDown(); - int exit = execute.execute(); - finished.set(true); - logger.info("Finished broker launcher process with exit code=" + exit); - if (exit != 0) { - throw new IllegalStateException("Could not start process." + errorHint); - } - } catch (Exception e) { - logger.error("Failed to start node", e); - } - } - }); - - try { - logger.info("Waiting for Rabbit process to be started"); - Assert.state(running.await(1000L, TimeUnit.MILLISECONDS), - "Timed out waiting for thread to start Rabbit process."); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - } - - if (finished.get()) { - // throw new - // IllegalStateException("Expected broker process to start in background, but it has exited early."); - } - - if (timeout > 0) { - waitForReadyState(); - } - - } - - private boolean waitForReadyState() { - return waitForState(new StatusCallback() { - public boolean get(RabbitStatus status) { - return status.isReady(); - } - }, "ready"); - } - - private boolean waitForUnreadyState() { - return waitForState(new StatusCallback() { - public boolean get(RabbitStatus status) { - return !status.isRunning(); - } - }, "unready"); - } - - private boolean waitForStoppedState() { - return waitForState(new StatusCallback() { - public boolean get(RabbitStatus status) { - return !status.isReady() && !status.isRunning(); - } - }, "stopped"); - } - - private boolean waitForState(final StatusCallback callable, String state) { - - if (timeout <= 0) { - return true; - } - - RabbitStatus status = getStatus(); - - if (!callable.get(status)) { - - logger.info("Waiting for broker to enter state: " + state); - - Future started = executor.submit(new Callable() { - public RabbitStatus call() throws Exception { - RabbitStatus status = getStatus(); - while (!callable.get(status)) { - // Any less than 1000L and we tend to clog up the socket? - Thread.sleep(500L); - status = getStatus(); - } - return status; - } - }); - - try { - status = started.get(timeout, TimeUnit.MILLISECONDS); - // This seems to help... really it just means we didn't get the right status data - Thread.sleep(500L); - } catch (TimeoutException e) { - started.cancel(true); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - } catch (ExecutionException e) { - logger.error("Exception checking broker status for " + state, e.getCause()); - } - - if (!callable.get(status)) { - logger.error("Rabbit broker not in " + state + " state after timeout. Stopping process."); - stopNode(); - return false; - } else { - logger.info("Finished waiting for broker to enter state: " + state); - if (logger.isDebugEnabled()) { - logger.info("Status: " + status); - } - return true; - } - - } else { - logger.info("Broker already in state: " + state); - } - - return true; - - } - - /** - * Find a directory whose name starts with a substring in a given parent directory. If there is none return null, - * otherwise sort the results and return the best match (an exact match if there is one or the last one in a lexical - * sort). - * - * @param parent - * @param child - * @return the full name of a directory - */ - private String findDirectoryName(String parent, String child) { - String result = null; - String[] names = new File(parent).list(new FilenameFilter() { - public boolean accept(File dir, String name) { - return name.equals("rabbitmq") && new File(dir, name).isDirectory(); - } - }); - if (names.length == 1) { - result = new File(parent, names[0]).getAbsolutePath(); - return result; - } - List sorted = Arrays.asList(new File(parent).list(new FilenameFilter() { - public boolean accept(File dir, String name) { - return name.startsWith("rabbitmq") && new File(dir, name).isDirectory(); - } - })); - Collections.sort(sorted, Collections.reverseOrder()); - if (!sorted.isEmpty()) { - result = new File(parent, sorted.get(0)).getAbsolutePath(); - } - return result; - } - - private void addEnvironment(List env, String key) { - String value = System.getProperty(key); - if (value != null) { - logger.debug("Adding environment variable: " + key + "=" + value); - env.add(key + "=" + value); - } - } - - @ManagedOperation - public void stopNode() { - logger.info("Stopping RabbitMQ node."); - try { - executeAndConvertRpc("rabbit", "stop_and_halt"); - } catch (Exception e) { - logger.error("Failed to send stop signal", e); - } - if (timeout >= 0) { - waitForStoppedState(); - } - } - - @ManagedOperation - public void resetNode() { - executeAndConvertRpc("rabbit_mnesia", "reset"); - } - - @ManagedOperation - public void forceResetNode() { - executeAndConvertRpc("rabbit_mnesia", "force_reset"); - - } - - @ManagedOperation - public RabbitStatus getStatus() { - try { - return (RabbitStatus) executeAndConvertRpc("rabbit", "status"); - } catch (OtpAuthException e) { - throw new RabbitAdminAuthException( - "Could not authorise connection to Erlang process. This can happen if the broker is running, " - + "but as root or rabbitmq and the current user is not authorised to connect. Try starting the " - + "broker again as a different user.", e); - } catch (OtpException e) { - logger.debug("Ignoring OtpException (assuming that the broker is simply not running)"); - if (logger.isTraceEnabled()) { - logger.trace("Status not available owing to exception", e); - } - return new RabbitStatus(Collections. emptyList(), Collections. emptyList(), - Collections. emptyList()); - } - } - - protected void initializeDefaultErlangTemplate() { - String peerNodeName = nodeName; - logger.debug("Creating jinterface connection with peerNodeName = [" + peerNodeName + "]"); - SimpleConnectionFactory otpConnectionFactory = new SimpleConnectionFactory("rabbit-spring-monitor", - peerNodeName, this.cookie); - otpConnectionFactory.afterPropertiesSet(); - createErlangTemplate(otpConnectionFactory); - } - - protected void createErlangTemplate(ConnectionFactory otpConnectionFactory) { - erlangTemplate = new ErlangTemplate(otpConnectionFactory); - erlangTemplate.setErlangConverter(new RabbitControlErlangConverter(moduleAdapter)); - erlangTemplate.afterPropertiesSet(); - } - - /** - * Convenience method for lazy initialization of the {@link ErlangTemplate} and associated trimmings. All RPC calls - * should go through this method. - * - * @param the type of the result - * @param module the module to address remotely - * @param function the function to call - * @param args the arguments to pass - * - * @return the result from the remote erl process converted to the correct type - */ - @SuppressWarnings("unchecked") - private T executeAndConvertRpc(String module, String function, Object... args) { - - if (erlangTemplate == null) { - synchronized (this) { - if (erlangTemplate == null) { - initializeDefaultErlangTemplate(); - } - } - } - - String key = module + "%" + function; - if (moduleAdapter.containsKey(key)) { - String adapter = moduleAdapter.get(key); - String[] values = adapter.split("%"); - Assert.state(values.length == 2, - "The module adapter should be a map from 'module%function' to 'module%function'. " - + "This one contained [" + adapter + "] which cannot be parsed to a module, function pair."); - module = values[0]; - function = values[1]; - } - - return (T) erlangTemplate.executeAndConvertRpc(module, function, args); - - } - - /** - * Safely convert a string to its bytes using the encoding provided. - * - * @see #setEncoding(String) - * - * @param string the value to convert - * - * @return the bytes from the string using the encoding provided - * - * @throws IllegalStateException if the encoding is ont supported - */ - private byte[] getBytes(String string) { - try { - return string.getBytes(encoding); - } catch (UnsupportedEncodingException e) { - throw new IllegalStateException("Unsupported encoding: " + encoding); - } - } - - private static interface StatusCallback { - boolean get(RabbitStatus status); - } -} diff --git a/spring-rabbit/src/test/java/org/springframework/amqp/rabbit/admin/RabbitBrokerAdminIntegrationTests.java b/spring-rabbit/src/test/java/org/springframework/amqp/rabbit/admin/RabbitBrokerAdminIntegrationTests.java deleted file mode 100755 index f49c2f73..00000000 --- a/spring-rabbit/src/test/java/org/springframework/amqp/rabbit/admin/RabbitBrokerAdminIntegrationTests.java +++ /dev/null @@ -1,138 +0,0 @@ -/* - * Copyright 2002-2014 the original author or authors. - * - * 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. - */ - -package org.springframework.amqp.rabbit.admin; - -import static org.junit.Assert.assertEquals; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.apache.log4j.Level; -import org.junit.AfterClass; -import org.junit.BeforeClass; -import org.junit.ClassRule; -import org.junit.Rule; -import org.junit.Test; - -import org.springframework.amqp.core.Queue; -import org.springframework.amqp.rabbit.connection.SingleConnectionFactory; -import org.springframework.amqp.rabbit.core.RabbitAdmin; -import org.springframework.amqp.rabbit.test.BrokerPanic; -import org.springframework.amqp.rabbit.test.BrokerTestUtils; -import org.springframework.amqp.rabbit.test.EnvironmentAvailable; -import org.springframework.amqp.rabbit.test.Log4jLevelAdjuster; - -/** - * - * @author Mark Pollack - * @author Dave Syer - * @author Helena Edelson - * @author Gunnar Hillert - */ -public class RabbitBrokerAdminIntegrationTests { - - @Rule - public Log4jLevelAdjuster logLevel = new Log4jLevelAdjuster(Level.INFO, RabbitBrokerAdmin.class); - - @ClassRule - public static EnvironmentAvailable environment = new EnvironmentAvailable("BROKER_INTEGRATION_TEST"); - - /* - * Ensure broker dies if a test fails (otherwise the erl process might have to be killed manually) - */ - @ClassRule - public static BrokerPanic panic = new BrokerPanic(); - - private static RabbitBrokerAdmin brokerAdmin; - - @BeforeClass - public static void start() throws Exception { - if (environment.isActive()) { - // Set up broker admin for non-root user - brokerAdmin = BrokerTestUtils.getRabbitBrokerAdmin(); - brokerAdmin.startNode(); - panic.setBrokerAdmin(brokerAdmin); - } - } - - @AfterClass - public static void stop() throws Exception { - if (environment.isActive()) { - brokerAdmin.stopNode(); - } - } - - @Test - public void integrationTestsUserCrud() throws Exception { - List users = brokerAdmin.listUsers(); - if (users.contains("joe")) { - brokerAdmin.deleteUser("joe"); - } - Thread.sleep(200L); - brokerAdmin.addUser("joe", "trader"); - Thread.sleep(200L); - brokerAdmin.changeUserPassword("joe", "sales"); - Thread.sleep(200L); - users = brokerAdmin.listUsers(); - if (users.contains("joe")) { - Thread.sleep(200L); - brokerAdmin.deleteUser("joe"); - } - } - - @Test - public void integrationTestsUserCrudWithModuleAdapter() throws Exception { - - Map adapter = new HashMap(); - // Switch two functions with identical inputs! - adapter.put("rabbit_auth_backend_internal%add_user", "rabbit_auth_backend_internal%change_password"); - adapter.put("rabbit_auth_backend_internal%change_password", "rabbit_auth_backend_internal%add_user"); - brokerAdmin.setModuleAdapter(adapter); - - List users = brokerAdmin.listUsers(); - if (users.contains("joe")) { - brokerAdmin.deleteUser("joe"); - } - Thread.sleep(200L); - brokerAdmin.changeUserPassword("joe", "sales"); - Thread.sleep(200L); - brokerAdmin.addUser("joe", "trader"); - Thread.sleep(200L); - users = brokerAdmin.listUsers(); - if (users.contains("joe")) { - Thread.sleep(200L); - brokerAdmin.deleteUser("joe"); - } - - } - - @Test - public void testGetEmptyQueues() throws Exception { - List queues = brokerAdmin.getQueues(); - assertEquals(0, queues.size()); - } - - @Test - public void testGetQueues() throws Exception { - SingleConnectionFactory connectionFactory = new SingleConnectionFactory(); - connectionFactory.setPort(BrokerTestUtils.getAdminPort()); - Queue queue = new RabbitAdmin(connectionFactory).declareQueue(); - assertEquals("/", connectionFactory.getVirtualHost()); - List queues = brokerAdmin.getQueues(); - assertEquals(queue.getName(), queues.get(0).getName()); - connectionFactory.destroy(); - } - -} diff --git a/spring-rabbit/src/test/java/org/springframework/amqp/rabbit/admin/RabbitBrokerAdminLifecycleIntegrationTests.java b/spring-rabbit/src/test/java/org/springframework/amqp/rabbit/admin/RabbitBrokerAdminLifecycleIntegrationTests.java deleted file mode 100755 index f3446e94..00000000 --- a/spring-rabbit/src/test/java/org/springframework/amqp/rabbit/admin/RabbitBrokerAdminLifecycleIntegrationTests.java +++ /dev/null @@ -1,138 +0,0 @@ -/* - * Copyright 2002-2014 the original author or authors. - * - * 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. - */ - -package org.springframework.amqp.rabbit.admin; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - -import java.io.File; - -import org.apache.commons.io.FileUtils; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.apache.log4j.Level; -import org.junit.Before; -import org.junit.ClassRule; -import org.junit.Rule; -import org.junit.Test; - -import org.springframework.amqp.rabbit.test.BrokerTestUtils; -import org.springframework.amqp.rabbit.test.EnvironmentAvailable; -import org.springframework.amqp.rabbit.test.Log4jLevelAdjuster; -import org.springframework.erlang.OtpException; - -/** - * @author Mark Pollack - * @author Dave Syer - * @author Gary Russell - */ -public class RabbitBrokerAdminLifecycleIntegrationTests { - - private static Log logger = LogFactory.getLog(RabbitBrokerAdminLifecycleIntegrationTests.class); - - private static final String NODE_NAME = "spring@localhost"; - - @Rule - public Log4jLevelAdjuster logLevel = new Log4jLevelAdjuster(Level.INFO, RabbitBrokerAdmin.class); - - @ClassRule - public static EnvironmentAvailable environment = new EnvironmentAvailable("BROKER_INTEGRATION_TEST"); - - @Before - public void init() throws Exception { - FileUtils.deleteDirectory(new File("target/rabbitmq")); - } - - @Test - public void testStartNode() throws Exception { - - // Set up broker admin for non-root user - final RabbitBrokerAdmin brokerAdmin = BrokerTestUtils.getRabbitBrokerAdmin(NODE_NAME); - RabbitStatus status = brokerAdmin.getStatus(); - try { - // Stop it if it is already running - if (status.isReady()) { - brokerAdmin.stopBrokerApplication(); - Thread.sleep(1000L); - } - } catch (OtpException e) { - // Not useful for test. - } - status = brokerAdmin.getStatus(); - if (!status.isRunning()) { - brokerAdmin.startBrokerApplication(); - } - status = brokerAdmin.getStatus(); - - try { - - assertFalse("Broker node did not start. Check logs for hints.", status.getNodes().isEmpty()); - assertTrue("Broker node not running. Check logs for hints.", status.isRunning()); - assertTrue("Broker application not running. Check logs for hints.", status.isReady()); - - Thread.sleep(1000L); - brokerAdmin.stopBrokerApplication(); - Thread.sleep(1000L); - - } finally { - brokerAdmin.stopNode(); - } - - } - - @Test - public void testStopAndStartBroker() throws Exception { - - // Set up broker admin for non-root user - final RabbitBrokerAdmin brokerAdmin = BrokerTestUtils.getRabbitBrokerAdmin(NODE_NAME); - RabbitStatus status = brokerAdmin.getStatus(); - - status = brokerAdmin.getStatus(); - if (!status.isRunning()) { - brokerAdmin.startBrokerApplication(); - } - - brokerAdmin.stopBrokerApplication(); - - status = brokerAdmin.getStatus(); - assertEquals(0, status.getRunningNodes().size()); - - brokerAdmin.startBrokerApplication(); - status = brokerAdmin.getStatus(); - assertBrokerAppRunning(status); - - } - - @Test - public void repeatLifecycle() throws Exception { - for (int i = 1; i <= 20; i++) { - testStopAndStartBroker(); - Thread.sleep(200); - if (i % 5 == 0) { - logger.debug("i = " + i); - } - } - } - - /** - * Asserts that the named-node is running. - * @param status - */ - private void assertBrokerAppRunning(RabbitStatus status) { - assertEquals(1, status.getRunningNodes().size()); - assertTrue(status.getRunningNodes().get(0).getName().contains(NODE_NAME)); - } - -} diff --git a/spring-rabbit/src/test/java/org/springframework/amqp/rabbit/admin/RabbitBrokerOperations.java b/spring-rabbit/src/test/java/org/springframework/amqp/rabbit/admin/RabbitBrokerOperations.java deleted file mode 100755 index 579fede6..00000000 --- a/spring-rabbit/src/test/java/org/springframework/amqp/rabbit/admin/RabbitBrokerOperations.java +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright 2002-2011 the original author or authors. - * - * 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. - */ - -package org.springframework.amqp.rabbit.admin; - -import java.util.List; -import java.util.regex.Pattern; - -/** - * Performs administration tasks for RabbitMQ broker administration.

Goal is to support full CRUD of Exchanges, - * Queues, Bindings, User, VHosts, etc.

Current implementations expose operations with basic type arguments via JMX. - * - * @author Mark Pollack - */ -public interface RabbitBrokerOperations { - - // Queue operations - - public List getQueues(); - - public List getQueues(String virtualHost); - - // User management - - void addUser(String username, String password); - - void deleteUser(String username); - - void changeUserPassword(String username, String newPassword); - - List listUsers(); - - // VHost management - - int addVhost(String vhostPath); - - int deleteVhost(String vhostPath); - - // permissions - - void setPermissions(String username, Pattern configure, Pattern read, Pattern write); - - void setPermissions(String username, Pattern configure, Pattern read, Pattern write, String vhostPath); - - void clearPermissions(String username); - - void clearPermissions(String username, String vhostPath); - - List listPermissions(); - - List listPermissions(String vhostPath); - - List listUserPermissions(String username); - - // Start/Stop/Reset broker - - /** - * Starts the RabbitMQ application on an already running node. This command is typically run after performing other - * management actions that required the RabbitMQ application to be stopped, e.g. reset. - */ - void startBrokerApplication(); - - /** - * Stops the RabbitMQ application, leaving the Erlang node running. - */ - void stopBrokerApplication(); - - /** - * Starts the Erlang node where RabbitMQ is running by shelling out to the directory specified by RABBITMQ_HOME and - * executing the standard named start script. It spawns the shell command execution into its own thread. - */ - void startNode(); - - /** - * Stops the halts the Erlang node on which RabbitMQ is running. To restart the node you will need to execute the - * start script from a command line or via other means. - */ - void stopNode(); - - /** - * Removes the node from any cluster it belongs to, removes all data from the management database, such as - * configured users and vhosts, and deletes all persistent messages.

For {@link #resetNode} and - * {@link #forceResetNode} to succeed the RabbitMQ application must have been stopped, e.g. - * {@link #stopBrokerApplication} - */ - void resetNode(); - - /** - * The forceResetNode command differs from {@link #resetNode} in that it resets the node unconditionally, regardless - * of the current management database state and cluster configuration. It should only be used as a last resort if - * the database or cluster configuration has been corrupted.

For {@link #resetNode} and {@link #forceResetNode} - * to succeed the RabbitMQ application must have been stopped, e.g. {@link #stopBrokerApplication} - */ - void forceResetNode(); - - /** - * Returns the status of the node. - * @return status of the node. - */ - RabbitStatus getStatus(); - -} diff --git a/spring-rabbit/src/test/java/org/springframework/amqp/rabbit/admin/RabbitControlErlangConverter.java b/spring-rabbit/src/test/java/org/springframework/amqp/rabbit/admin/RabbitControlErlangConverter.java deleted file mode 100755 index e216d21c..00000000 --- a/spring-rabbit/src/test/java/org/springframework/amqp/rabbit/admin/RabbitControlErlangConverter.java +++ /dev/null @@ -1,269 +0,0 @@ -/* - * Copyright 2002-2010 the original author or authors. - * - * 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. - */ - -package org.springframework.amqp.rabbit.admin; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.springframework.erlang.core.Application; -import org.springframework.erlang.core.Node; -import org.springframework.erlang.support.converter.ErlangConversionException; -import org.springframework.erlang.support.converter.ErlangConverter; -import org.springframework.erlang.support.converter.SimpleErlangConverter; -import org.springframework.util.Assert; - -import com.ericsson.otp.erlang.OtpErlangAtom; -import com.ericsson.otp.erlang.OtpErlangBinary; -import com.ericsson.otp.erlang.OtpErlangList; -import com.ericsson.otp.erlang.OtpErlangObject; -import com.ericsson.otp.erlang.OtpErlangTuple; - -/*** - * Converter that understands the responses from the rabbit control module and related functionality. - * - * @author Mark Pollack - * @author Mark Fisher - * @author Helena Edelson - */ -public class RabbitControlErlangConverter extends SimpleErlangConverter implements ErlangConverter { - - protected final Log logger = LogFactory.getLog(getClass()); - - private final Map converterMap = new HashMap(); - - private final Map moduleAdapter; - - public RabbitControlErlangConverter(Map moduleAdapter) { - this.moduleAdapter = moduleAdapter; - initializeConverterMap(); - } - - public Object fromErlangRpc(String module, String function, OtpErlangObject erlangObject) - throws ErlangConversionException { - ErlangConverter converter = getConverter(module, function); - if (converter != null) { - return converter.fromErlang(erlangObject); - } else { - return super.fromErlangRpc(module, function, erlangObject); - } - } - - protected ErlangConverter getConverter(String module, String function) { - return converterMap.get(generateKey(module, function)); - } - - protected void initializeConverterMap() { - registerConverter("rabbit_auth_backend_internal", "list_users", new ListUsersConverter()); - registerConverter("rabbit", "status", new StatusConverter()); - registerConverter("rabbit_amqqueue", "info_all", new QueueInfoAllConverter()); - } - - protected void registerConverter(String module, String function, ErlangConverter listUsersConverter) { - String key = generateKey(module, function); - if (moduleAdapter.containsKey(key)) { - String adapter = moduleAdapter.get(key); - String[] values = adapter.split("%"); - Assert.state(values.length == 2, - "The module adapter should be a map from 'module%function' to 'module%function'. " - + "This one contained [" + adapter + "] which cannot be parsed to a module, function pair."); - module = values[0]; - function = values[1]; - } - converterMap.put(generateKey(module, function), listUsersConverter); - } - - protected String generateKey(String module, String function) { - return module + "%" + function; - } - - public class ListUsersConverter extends SimpleErlangConverter { - - public Object fromErlang(OtpErlangObject erlangObject) throws ErlangConversionException { - - List users = new ArrayList(); - if (erlangObject instanceof OtpErlangList) { - OtpErlangList erlangList = (OtpErlangList) erlangObject; - for (OtpErlangObject obj : erlangList) { - String value = extractString(obj); - if (value != null) { - users.add(value); - } - } - } - return users; - } - - private String extractString(OtpErlangObject obj) { - - if (obj instanceof OtpErlangBinary) { - OtpErlangBinary binary = (OtpErlangBinary) obj; - return new String(binary.binaryValue()); - } else if (obj instanceof OtpErlangTuple) { - OtpErlangTuple tuple = (OtpErlangTuple) obj; - return extractString(tuple.elementAt(0)); - } - return null; - } - } - - public class StatusConverter extends SimpleErlangConverter { - - public Object fromErlang(OtpErlangObject erlangObject) throws ErlangConversionException { - - List applications = new ArrayList(); - List nodes = new ArrayList(); - List runningNodes = new ArrayList(); - if (erlangObject instanceof OtpErlangList) { - OtpErlangList erlangList = (OtpErlangList) erlangObject; - - OtpErlangTuple runningAppTuple = (OtpErlangTuple) erlangList.elementAt(0); - OtpErlangList appList = (OtpErlangList) runningAppTuple.elementAt(1); - extractApplications(applications, appList); - - OtpErlangTuple nodesTuple = (OtpErlangTuple) erlangList.elementAt(1); - OtpErlangList nodesList = (OtpErlangList) nodesTuple.elementAt(1); - extractNodes(nodes, nodesList); - - OtpErlangTuple runningNodesTuple = (OtpErlangTuple) erlangList.elementAt(2); - nodesList = (OtpErlangList) runningNodesTuple.elementAt(1); - extractNodes(runningNodes, nodesList); - - /* - * for (OtpErlangObject obj : erlangList) { if (obj instanceof OtpErlangBinary) { OtpErlangBinary binary - * = (OtpErlangBinary) obj; users.add(new String(binary.binaryValue())); } } - */ - } - - return new RabbitStatus(applications, nodes, runningNodes); - } - - private void extractNodes(List nodes, OtpErlangList nodesList) { - for (OtpErlangObject erlangNodeName : nodesList) { - String nodeName = erlangNodeName.toString(); - nodes.add(new Node(nodeName)); - } - } - - private void extractApplications(List applications, OtpErlangList appList) { - for (OtpErlangObject appDescription : appList) { - OtpErlangTuple appDescriptionTuple = (OtpErlangTuple) appDescription; - String name = appDescriptionTuple.elementAt(0).toString(); - String description = appDescriptionTuple.elementAt(1).toString(); - String version = appDescriptionTuple.elementAt(2).toString(); - applications.add(new Application(name, description, version)); - } - } - } - - public enum QueueInfoField { - transactions, acks_uncommitted, consumers, pid, durable, messages, memory, auto_delete, messages_ready, arguments, name, messages_unacknowledged, messages_uncommitted, NOVALUE; - - public static QueueInfoField toQueueInfoField(String str) { - try { - return valueOf(str); - } catch (Exception ex) { - return NOVALUE; - } - } - } - - public class QueueInfoAllConverter extends SimpleErlangConverter { - - @Override - public Object fromErlang(OtpErlangObject erlangObject) throws ErlangConversionException { - List queueInfoList = new ArrayList(); - if (erlangObject instanceof OtpErlangList) { - OtpErlangList erlangList = (OtpErlangList) erlangObject; - for (OtpErlangObject element : erlangList.elements()) { - QueueInfo queueInfo = new QueueInfo(); - OtpErlangList itemList = (OtpErlangList) element; - for (OtpErlangObject item : itemList.elements()) { - OtpErlangTuple tuple = (OtpErlangTuple) item; - if (tuple.arity() == 2) { - String key = tuple.elementAt(0).toString(); - OtpErlangObject value = tuple.elementAt(1); - switch (QueueInfoField.toQueueInfoField(key)) { - case name: - queueInfo.setName(extractNameValueFromTuple((OtpErlangTuple) value)); - break; - case transactions: - queueInfo.setTransactions(extractLong(value)); - break; - case acks_uncommitted: - queueInfo.setAcksUncommitted(extractLong(value)); - break; - case consumers: - queueInfo.setConsumers(extractLong(value)); - break; - case pid: - queueInfo.setPid(extractPid(value)); - break; - case durable: - queueInfo.setDurable(extractAtomBoolean(value)); - break; - case messages: - queueInfo.setMessages(extractLong(value)); - break; - case memory: - queueInfo.setMemory(extractLong(value)); - break; - case auto_delete: - queueInfo.setAutoDelete(extractAtomBoolean(value)); - break; - case messages_ready: - queueInfo.setMessagesReady(extractLong(value)); - break; - case arguments: - OtpErlangList list = (OtpErlangList) value; - if (list != null) { - String[] args = new String[list.arity()]; - for (int i = 0; i < list.arity(); i++) { - OtpErlangObject obj = list.elementAt(i); - args[i] = obj.toString(); - } - queueInfo.setArguments(args); - } - break; - case messages_unacknowledged: - queueInfo.setMessagesUnacknowledged(extractLong(value)); - break; - case messages_uncommitted: - queueInfo.setMessageUncommitted(extractLong(value)); - break; - default: - break; - } - } - } - queueInfoList.add(queueInfo); - } - } - return queueInfoList; - } - - private boolean extractAtomBoolean(OtpErlangObject value) { - return ((OtpErlangAtom) value).booleanValue(); - } - - private String extractNameValueFromTuple(OtpErlangTuple value) { - Object nameElement = value.elementAt(3); - return new String(((OtpErlangBinary) nameElement).binaryValue()); - } - } - -} diff --git a/spring-rabbit/src/test/java/org/springframework/amqp/rabbit/admin/RabbitStatus.java b/spring-rabbit/src/test/java/org/springframework/amqp/rabbit/admin/RabbitStatus.java deleted file mode 100755 index 079cd9df..00000000 --- a/spring-rabbit/src/test/java/org/springframework/amqp/rabbit/admin/RabbitStatus.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright 2002-2010 the original author or authors. - * - * 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. - */ - -package org.springframework.amqp.rabbit.admin; - -import java.io.Serializable; -import java.util.List; - -import org.springframework.erlang.core.Application; -import org.springframework.erlang.core.Node; - -/** - * The status object returned from querying the broker - * - * @author Mark Pollack - * - */ -@SuppressWarnings("serial") -public class RabbitStatus implements Serializable { - - private List runningApplications; - - private List nodes; - - private List runningNodes; - - public RabbitStatus(List runningApplications, - List nodes, List runningNodes) { - super(); - this.runningApplications = runningApplications; - this.nodes = nodes; - this.runningNodes = runningNodes; - } - - /** - * @return true if the broker process is running but not necessarily the application - */ - public boolean isAlive() { - return !nodes.isEmpty(); - } - - /** - * @return true if the broker process is running - */ - public boolean isRunning() { - return !runningNodes.isEmpty(); - } - - /** - * @return true if the broker application is running - */ - public boolean isReady() { - return isRunning() && !runningApplications.isEmpty(); - } - - public List getRunningApplications() { - return runningApplications; - } - - public List getNodes() { - return nodes; - } - - public List getRunningNodes() { - return runningNodes; - } - - @Override - public String toString() { - return "RabbitStatus [runningApplications=" + runningApplications - + ", runningNodes=" + runningNodes + ", nodes=" + nodes + "]"; - } - -} diff --git a/spring-rabbit/src/test/java/org/springframework/amqp/rabbit/listener/MessageListenerBrokerInterruptionIntegrationTests.java b/spring-rabbit/src/test/java/org/springframework/amqp/rabbit/listener/MessageListenerBrokerInterruptionIntegrationTests.java deleted file mode 100644 index 0a5d4c3b..00000000 --- a/spring-rabbit/src/test/java/org/springframework/amqp/rabbit/listener/MessageListenerBrokerInterruptionIntegrationTests.java +++ /dev/null @@ -1,205 +0,0 @@ -/* - * Copyright 2010-2014 the original author or authors. - * - * 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. - */ -package org.springframework.amqp.rabbit.listener; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; - -import java.io.File; -import java.util.List; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.TimeUnit; - -import org.apache.commons.io.FileUtils; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.junit.After; -import org.junit.Before; -import org.junit.ClassRule; -import org.junit.Rule; -import org.junit.Test; - -import org.springframework.amqp.core.AcknowledgeMode; -import org.springframework.amqp.core.Message; -import org.springframework.amqp.core.Queue; -import org.springframework.amqp.rabbit.admin.QueueInfo; -import org.springframework.amqp.rabbit.admin.RabbitBrokerAdmin; -import org.springframework.amqp.rabbit.connection.CachingConnectionFactory; -import org.springframework.amqp.rabbit.connection.ConnectionFactory; -import org.springframework.amqp.rabbit.core.ChannelAwareMessageListener; -import org.springframework.amqp.rabbit.core.RabbitTemplate; -import org.springframework.amqp.rabbit.listener.adapter.MessageListenerAdapter; -import org.springframework.amqp.rabbit.test.BrokerPanic; -import org.springframework.amqp.rabbit.test.BrokerRunning; -import org.springframework.amqp.rabbit.test.BrokerTestUtils; -import org.springframework.amqp.rabbit.test.EnvironmentAvailable; - -import com.rabbitmq.client.Channel; - -/** - * @author Dave Syer - * @author Gunnar Hillert - * @author Gary Russell - * @since 1.0 - * - */ -public class MessageListenerBrokerInterruptionIntegrationTests { - - private static Log logger = LogFactory.getLog(MessageListenerBrokerInterruptionIntegrationTests.class); - - // Ensure queue is durable, or it won't survive the broker restart - private final Queue queue = new Queue("test.queue", true); - - private final int concurrentConsumers = 2; - - private final int messageCount = 60; - - private final int txSize = 1; - - private final boolean transactional = false; - - private final AcknowledgeMode acknowledgeMode = AcknowledgeMode.AUTO; - - private SimpleMessageListenerContainer container; - - @ClassRule - public static EnvironmentAvailable environment = new EnvironmentAvailable("BROKER_INTEGRATION_TEST"); - - /* - * Ensure broker dies if a test fails (otherwise the erl process might have to be killed manually) - */ - @ClassRule - public static BrokerPanic panic = new BrokerPanic(); - - @Rule - public BrokerRunning brokerIsRunning = BrokerRunning.isRunningWithEmptyQueues(queue); - - private CachingConnectionFactory connectionFactory; - - private final RabbitBrokerAdmin brokerAdmin; - - public MessageListenerBrokerInterruptionIntegrationTests() throws Exception { - FileUtils.deleteDirectory(new File("target/rabbitmq")); - brokerIsRunning.setPort(BrokerTestUtils.getAdminPort()); - logger.debug("Setting up broker"); - brokerAdmin = BrokerTestUtils.getRabbitBrokerAdmin(); - panic.setBrokerAdmin(brokerAdmin); - if (environment.isActive()) { - brokerAdmin.startNode(); - } - } - - @Before - public void createConnectionFactory() { - if (environment.isActive()) { - CachingConnectionFactory connectionFactory = new CachingConnectionFactory(); - connectionFactory.setHost("localhost"); - connectionFactory.setChannelCacheSize(concurrentConsumers); - connectionFactory.setPort(BrokerTestUtils.getAdminPort()); - this.connectionFactory = connectionFactory; - } - } - - @After - public void clear() throws Exception { - if (environment.isActive()) { - // Wait for broker communication to finish before trying to stop container - Thread.sleep(300L); - logger.debug("Shutting down at end of test"); - if (container != null) { - container.shutdown(); - } - brokerAdmin.stopNode(); - // Remove all trace of the durable queue... - FileUtils.deleteDirectory(new File("target/rabbitmq")); - - if (this.connectionFactory != null) { - this.connectionFactory.destroy(); - } - } - } - - @Test - public void testListenerRecoversFromDeadBroker() throws Exception { - - List queues = brokerAdmin.getQueues(); - logger.info("Queues: " + queues); - assertEquals(1, queues.size()); - assertTrue(queues.get(0).isDurable()); - - RabbitTemplate template = new RabbitTemplate(connectionFactory); - - CountDownLatch latch = new CountDownLatch(messageCount); - assertEquals("No more messages to receive before even sent!", messageCount, latch.getCount()); - container = createContainer(queue.getName(), new VanillaListener(latch), connectionFactory); - for (int i = 0; i < messageCount; i++) { - template.convertAndSend(queue.getName(), i + "foo"); - } - - assertTrue("No more messages to receive before broker stopped", latch.getCount() > 0); - brokerAdmin.stopBrokerApplication(); - assertTrue("No more messages to receive after broker stopped", latch.getCount() > 0); - boolean waited = latch.await(500, TimeUnit.MILLISECONDS); - assertFalse("Did not time out waiting for message", waited); - - container.stop(); - assertEquals(0, container.getActiveConsumerCount()); - - brokerAdmin.startBrokerApplication(); - queues = brokerAdmin.getQueues(); - logger.info("Queues: " + queues); - container.start(); - assertEquals(concurrentConsumers, container.getActiveConsumerCount()); - - int timeout = Math.min(4 + messageCount / (4 * concurrentConsumers), 30); - logger.debug("Waiting for messages with timeout = " + timeout + " (s)"); - waited = latch.await(timeout, TimeUnit.SECONDS); - assertTrue("Timed out waiting for message", waited); - - assertNull(template.receiveAndConvert(queue.getName())); - - } - - private SimpleMessageListenerContainer createContainer(String queueName, Object listener, - ConnectionFactory connectionFactory) { - SimpleMessageListenerContainer container = new SimpleMessageListenerContainer(connectionFactory); - container.setMessageListener(new MessageListenerAdapter(listener)); - container.setQueueNames(queueName); - container.setTxSize(txSize); - container.setPrefetchCount(txSize); - container.setConcurrentConsumers(concurrentConsumers); - container.setChannelTransacted(transactional); - container.setAcknowledgeMode(acknowledgeMode); - container.afterPropertiesSet(); - container.start(); - return container; - } - - public static class VanillaListener implements ChannelAwareMessageListener { - - private final CountDownLatch latch; - - public VanillaListener(CountDownLatch latch) { - this.latch = latch; - } - - @Override - public void onMessage(Message message, Channel channel) throws Exception { - String value = new String(message.getBody()); - logger.debug("Receiving: " + value); - latch.countDown(); - } - } -} diff --git a/spring-rabbit/src/test/java/org/springframework/amqp/rabbit/test/BrokerPanic.java b/spring-rabbit/src/test/java/org/springframework/amqp/rabbit/test/BrokerPanic.java deleted file mode 100755 index 624da65b..00000000 --- a/spring-rabbit/src/test/java/org/springframework/amqp/rabbit/test/BrokerPanic.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright 2002-2014 the original author or authors. - * - * 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. - */ -package org.springframework.amqp.rabbit.test; - -import org.junit.rules.TestWatcher; -import org.junit.runner.Description; -import org.junit.runners.model.Statement; - -import org.springframework.amqp.rabbit.admin.RabbitBrokerAdmin; - -public class BrokerPanic extends TestWatcher { - - private RabbitBrokerAdmin brokerAdmin; - - /** - * @param brokerAdmin the brokerAdmin to set - */ - public void setBrokerAdmin(RabbitBrokerAdmin brokerAdmin) { - this.brokerAdmin = brokerAdmin; - } - - @Override - public Statement apply(final Statement base, Description description) { - return new Statement() { - @Override - public void evaluate() throws Throwable { - try { - base.evaluate(); - } - catch (Throwable t) { - if (brokerAdmin != null) { - try { - brokerAdmin.stopNode(); - } catch (Throwable e) { - // don't hide original error (so ignored) - } - } - throw t; - } - } - }; - } - -} diff --git a/spring-rabbit/src/test/java/org/springframework/amqp/rabbit/test/BrokerTestUtils.java b/spring-rabbit/src/test/java/org/springframework/amqp/rabbit/test/BrokerTestUtils.java index 62539d9e..62fcb384 100644 --- a/spring-rabbit/src/test/java/org/springframework/amqp/rabbit/test/BrokerTestUtils.java +++ b/spring-rabbit/src/test/java/org/springframework/amqp/rabbit/test/BrokerTestUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2010 the original author or authors. + * Copyright 2002-2015 the original author or authors. * * 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 @@ -12,24 +12,19 @@ */ package org.springframework.amqp.rabbit.test; -import org.springframework.amqp.rabbit.admin.RabbitBrokerAdmin; import org.springframework.amqp.rabbit.connection.ConnectionFactory; /** * Global convenience class for all integration tests, carrying constants and other utilities for broker set up. * * @author Dave Syer + * @author Gary Russell * */ public class BrokerTestUtils { public static final int DEFAULT_PORT = 5672; - public static final int TRACER_PORT = 5673; - - public static final String ADMIN_NODE_NAME = "spring@localhost"; - - /** * The port that the broker is listening on (e.g. as input for a {@link ConnectionFactory}). * @@ -39,62 +34,4 @@ public class BrokerTestUtils { return DEFAULT_PORT; } - /** - * The port that the tracer is listening on (e.g. as input for a {@link ConnectionFactory}). - * - * @return a port number - */ - public static int getTracerPort() { - return TRACER_PORT; - } - - /** - * An alternative port number than can safely be used to stop and start a broker, even when one is already running - * on the standard port as a privileged user. Useful for tests involving {@link RabbitBrokerAdmin} on UN*X. - * - * @return a port number - */ - public static int getAdminPort() { - return 15672; - } - - /** - * Convenience factory for a {@link RabbitBrokerAdmin} instance that will usually start and stop cleanly on all - * systems. - * - * @return a {@link RabbitBrokerAdmin} instance - */ - public static RabbitBrokerAdmin getRabbitBrokerAdmin() { - return getRabbitBrokerAdmin(ADMIN_NODE_NAME, getAdminPort()); - } - - /** - * Convenience factory for a {@link RabbitBrokerAdmin} instance that will usually start and stop cleanly on all - * systems. - * - * @param nodeName the name of the node - * - * @return a {@link RabbitBrokerAdmin} instance - */ - public static RabbitBrokerAdmin getRabbitBrokerAdmin(String nodeName) { - return getRabbitBrokerAdmin(nodeName, getAdminPort()); - } - - /** - * Convenience factory for a {@link RabbitBrokerAdmin} instance that will usually start and stop cleanly on all - * systems. - * - * @param nodeName the name of the node - * @param port the port to listen on - * - * @return a {@link RabbitBrokerAdmin} instance - */ - public static RabbitBrokerAdmin getRabbitBrokerAdmin(String nodeName, int port) { - RabbitBrokerAdmin brokerAdmin = new RabbitBrokerAdmin(nodeName, port); - brokerAdmin.setRabbitLogBaseDirectory("target/rabbitmq/log"); - brokerAdmin.setRabbitMnesiaBaseDirectory("target/rabbitmq/mnesia"); - brokerAdmin.setStartupTimeout(10000L); - return brokerAdmin; - } - } diff --git a/src/reference/asciidoc/whats-new.adoc b/src/reference/asciidoc/whats-new.adoc index 593713f8..b657047b 100644 --- a/src/reference/asciidoc/whats-new.adoc +++ b/src/reference/asciidoc/whats-new.adoc @@ -3,6 +3,12 @@ ==== Changes in 1.5 Since 1.4 +===== spring-erlang is No Longer Supported + +The `spring-erlang` jar is no longer included in the distribution. +Use <> instead. + + ===== Empty Addresses Property in CachingConnectionFactory Previously, if the connection factory was configured with a host/port, but also an empty String was supplied for `addresses`, the host and port were ignored. @@ -68,6 +74,8 @@ Previously, bean names were composed from the ids of the `` The `@RabbitListener` annotation can now be applied at the class level. Together with the new `@RabbitHandler` method annotation, this allows the handler method to be selected based on payload type. See <> for more information.==== Changes in 1.4 Since 1.3 +==== Changes in 1.4 Since 1.3 + ===== @RabbitListener Annotation POJO listeners can be annotated with `@RabbitListener`, enabled by `@EnableRabbit` or ``.