ARTEMIS-3987 Removing ActiveMQ Artemis Rest from the codebase.

As we discussed on the dev list, this module hasn't been used for a while, and we have been asking users to use stomp and stomp-WS instead.
This commit is contained in:
Clebert Suconic 2022-09-09 10:02:26 -04:00 committed by clebertsuconic
parent 4ad830fb95
commit e654eba0de
153 changed files with 0 additions and 18897 deletions

View File

@ -74,7 +74,6 @@ cd queue-requestor; mvn verify; cd ..
cd queue-selector; mvn verify; cd ..
cd reattach-node; mvn verify; cd ..
cd request-reply; mvn verify; cd ..
cd rest; mvn verify; cd ..
cd scheduled-message; mvn verify; cd ..
cd security; mvn verify; cd ..
cd security-ldap; mvn verify; cd ..

View File

@ -77,7 +77,6 @@ cd queue-requestor; mvn verify; cd ..
cd queue-selector; mvn verify; cd ..
cd reattach-node; mvn verify; cd ..
cd request-reply; mvn verify; cd ..
cd rest; mvn verify; cd ..
cd scheduled-message; mvn verify; cd ..
cd security; mvn verify; cd ..
cd security-ldap; mvn verify; cd ..

View File

@ -1,191 +0,0 @@
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.apache.activemq</groupId>
<artifactId>artemis-pom</artifactId>
<version>3.0.0-SNAPSHOT</version>
</parent>
<groupId>org.apache.activemq.rest</groupId>
<artifactId>artemis-rest</artifactId>
<packaging>jar</packaging>
<name>ActiveMQ Artemis REST Interface Implementation</name>
<properties>
<activemq.basedir>${project.basedir}/..</activemq.basedir>
</properties>
<dependencies>
<!--
JBoss Logging
-->
<dependency>
<groupId>org.jboss.logging</groupId>
<artifactId>jboss-logging-processor</artifactId>
<scope>provided</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.jboss.logging</groupId>
<artifactId>jboss-logging-annotations</artifactId>
<scope>provided</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.jboss.logging</groupId>
<artifactId>jboss-logging</artifactId>
</dependency>
<dependency>
<groupId>org.jboss.logmanager</groupId>
<artifactId>jboss-logmanager</artifactId>
</dependency>
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-servlet-api</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-server</artifactId>
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-jaxrs</artifactId>
<exclusions>
<exclusion>
<groupId>org.jboss.spec.javax.ws.rs</groupId>
<artifactId>jboss-jaxrs-api_2.0_spec</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-jaxb-provider</artifactId>
<exclusions>
<exclusion>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-impl</artifactId>
</exclusion>
<exclusion>
<groupId>com.sun.xml.stream</groupId>
<artifactId>sjsxp</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-jackson2-provider</artifactId>
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>tjws</artifactId>
<scope>provided</scope>
<exclusions>
<exclusion>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>artemis-server</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>artemis-jms-server</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>artemis-jms-client</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>artemis-core-client</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>artemis-commons</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>jakarta.jms</groupId>
<artifactId>jakarta.jms-api</artifactId>
</dependency>
<dependency>
<groupId>jakarta.ws.rs</groupId>
<artifactId>jakarta.ws.rs-api</artifactId>
<version>${jakarta.ws.rs-api.version}</version>
</dependency>
<dependency>
<groupId>jakarta.xml.bind</groupId>
<artifactId>jakarta.xml.bind-api</artifactId>
<version>${jakarta.xml.bind-api.version}</version>
</dependency>
<dependency>
<groupId>org.glassfish.jaxb</groupId>
<artifactId>jaxb-runtime</artifactId>
<version>2.3.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpcore</artifactId>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>artemis-unit-test-support</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<argLine>${activemq-surefire-argline}</argLine>
<skipTests>${skipRestTests}</skipTests>
<!--includes>
<include>**/PushQueueConsumerTest.java</include>
</includes-->
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@ -1,174 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.activemq.artemis.rest;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.ext.MessageBodyReader;
import javax.ws.rs.ext.Providers;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.lang.reflect.Type;
import org.apache.activemq.artemis.api.core.client.ClientMessage;
import org.apache.activemq.artemis.rest.util.HttpMessageHelper;
import org.jboss.resteasy.core.Headers;
import org.jboss.resteasy.spi.ResteasyProviderFactory;
import org.jboss.resteasy.util.GenericType;
public class ActiveMQ {
/**
* Sets the message body to a serialized
* byte array of the object. HTTP consumers will have to provide an Accept header to marshal the object
*
* @param message
* @param object
*/
public static void setEntity(ClientMessage message, Serializable object) {
setEntity(message, object, null);
}
/**
* Sets a message property to be the Content-Type passed in. Sets the message body to a serialized
* byte array of the object.
*
* @param message
* @param object
* @param contentType HTTP Content-Type header
*/
public static void setEntity(ClientMessage message, Serializable object, String contentType) {
if (contentType != null)
message.putStringProperty(HttpHeaderProperty.CONTENT_TYPE, contentType);
byte[] data;
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream(1024);
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(object);
oos.flush();
data = baos.toByteArray();
} catch (IOException e) {
throw new RuntimeException(e);
}
message.getBodyBuffer().writeInt(data.length);
message.getBodyBuffer().writeBytes(data);
}
public static void setHttpHeader(ClientMessage message, String name, String value) {
message.putStringProperty(HttpHeaderProperty.toPropertyName(name), value);
}
/**
* Get an HTTP header value from a JMS Message
*
* @param message
* @param name
* @return the HTTP header String
*/
public static String getHttpHeader(ClientMessage message, String name) {
return message.getStringProperty(HttpHeaderProperty.toPropertyName(name));
}
/**
* Extract an object using a built-in RESTEasy JAX-RS MessageBodyReader
*
* @param message
* @param type
* @return
*/
public static <T> T getEntity(ClientMessage message, Class<T> type) {
return getEntity(message, type, null, ResteasyProviderFactory.getInstance());
}
/**
* Extract an object using a built-in RESTEasy JAX-RS MessageBodyReader
*
* @param message
* @param type
* @param factory
* @return
*/
public static <T> T getEntity(ClientMessage message, Class<T> type, ResteasyProviderFactory factory) {
return getEntity(message, type, null, factory);
}
/**
* Extract an object using a built-in RESTEasy JAX-RS MessageBodyReader
*
* @param message
* @param type
* @param factory
* @return
* @throws UnknownMediaType
* @throws UnmarshalException
*/
public static <T> T getEntity(ClientMessage message,
GenericType<T> type,
ResteasyProviderFactory factory) throws UnknownMediaType, UnmarshalException {
return getEntity(message, type.getType(), type.getGenericType(), factory);
}
public static <T> T getEntity(ClientMessage msg, Class<T> type, Type genericType, ResteasyProviderFactory factory) {
int size = msg.getBodySize();
if (size <= 0)
return null;
byte[] body = new byte[size];
msg.getBodyBuffer().readBytes(body);
String contentType = msg.getStringProperty(HttpHeaderProperty.CONTENT_TYPE);
if (contentType == null) {
throw new UnknownMediaType("Message did not have a Content-Type header cannot extract entity");
}
MediaType ct = MediaType.valueOf(contentType);
MessageBodyReader<T> reader = factory.getMessageBodyReader(type, genericType, null, ct);
if (reader == null) {
throw new UnmarshalException("Unable to find a JAX-RS reader for type " + type.getName() + " and media type " + contentType);
}
Providers current = ResteasyProviderFactory.getContextData(Providers.class);
ResteasyProviderFactory.pushContext(Providers.class, factory);
try {
return reader.readFrom(type, genericType, null, ct, new Headers<String>(), new ByteArrayInputStream(body));
} catch (IOException e) {
throw new RuntimeException(e);
} finally {
ResteasyProviderFactory.popContextData(Providers.class);
if (current != null)
ResteasyProviderFactory.pushContext(Providers.class, current);
}
}
/**
* Was this ActiveMQ Artemis message generated from a REST call?
*
* @param msg
* @return
*/
public static boolean isHttpMessage(ClientMessage msg) {
Boolean aBoolean = msg.getBooleanProperty(HttpMessageHelper.POSTED_AS_HTTP_MESSAGE);
return aBoolean != null && aBoolean.booleanValue() == true;
}
}

View File

@ -1,31 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.activemq.artemis.rest;
import org.jboss.logging.annotations.MessageBundle;
/**
* Logger Code 19
*
* each message id must be 6 digits long starting with 19, the 3rd digit should be 9
*
* so 199000 to 199999
*/
@MessageBundle(projectCode = "AMQ")
public class ActiveMQRestBundle {
}

View File

@ -1,94 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.activemq.artemis.rest;
import org.apache.activemq.artemis.api.core.ActiveMQException;
import org.apache.activemq.artemis.rest.queue.push.xml.XmlLink;
import org.jboss.logging.BasicLogger;
import org.jboss.logging.Logger;
import org.jboss.logging.annotations.Cause;
import org.jboss.logging.annotations.LogMessage;
import org.jboss.logging.annotations.Message;
import org.jboss.logging.annotations.MessageLogger;
/**
* Logger Code 19
*
* each message id must be 6 digits long starting with 19, the 3rd digit donates the level so
*
* INF0 1
* WARN 2
* DEBUG 3
* ERROR 4
* TRACE 5
* FATAL 6
*
* so an INFO message would be 191000 to 191999
*/
@MessageLogger(projectCode = "AMQ")
public interface ActiveMQRestLogger extends BasicLogger {
ActiveMQRestLogger LOGGER = Logger.getMessageLogger(ActiveMQRestLogger.class, ActiveMQRestLogger.class.getPackage().getName());
@LogMessage(level = Logger.Level.INFO)
@Message(id = 181000, value = "Loading REST push store from: {0}", format = Message.Format.MESSAGE_FORMAT)
void loadingRestStore(String path);
@LogMessage(level = Logger.Level.INFO)
@Message(id = 181001, value = "adding REST push registration: {0}", format = Message.Format.MESSAGE_FORMAT)
void addingPushRegistration(String id);
@LogMessage(level = Logger.Level.INFO)
@Message(id = 181002, value = "Push consumer started for: {0}", format = Message.Format.MESSAGE_FORMAT)
void startingPushConsumer(XmlLink link);
@LogMessage(level = Logger.Level.WARN)
@Message(id = 182000, value = "shutdown REST consumer because of timeout for: {0}", format = Message.Format.MESSAGE_FORMAT)
void shutdownRestConsumer(String id);
@LogMessage(level = Logger.Level.WARN)
@Message(id = 182001, value = "shutdown REST subscription because of timeout for: {0}", format = Message.Format.MESSAGE_FORMAT)
void shutdownRestSubscription(String id);
@LogMessage(level = Logger.Level.WARN)
@Message(id = 182002, value = "Failed to push message to {0}", format = Message.Format.MESSAGE_FORMAT)
void failedToPushMessageToUri(String uri, @Cause Exception e);
@LogMessage(level = Logger.Level.WARN)
@Message(id = 182003, value = "Failed to build Message from object", format = Message.Format.MESSAGE_FORMAT)
void failedToBuildMessageFromObject(@Cause Exception e);
@LogMessage(level = Logger.Level.WARN)
@Message(id = 182004, value = "REST configuration parameter ''{0}'' is deprecated. Use ''{1}'' instead.", format = Message.Format.MESSAGE_FORMAT)
void deprecatedConfiguration(String oldConfigParameter, String newConfigParameter);
@LogMessage(level = Logger.Level.ERROR)
@Message(id = 184000, value = "Failed to load push store {0}, it is probably corrupted", format = Message.Format.MESSAGE_FORMAT)
void errorLoadingStore(@Cause Exception e, String name);
@LogMessage(level = Logger.Level.ERROR)
@Message(id = 184001, value = "Error updating store", format = Message.Format.MESSAGE_FORMAT)
void errorUpdatingStore(@Cause Exception e);
@LogMessage(level = Logger.Level.ERROR)
@Message(id = 184002, value = "Failed to push message to {0} disabling push registration...", format = Message.Format.MESSAGE_FORMAT)
void errorPushingMessage(XmlLink link);
@LogMessage(level = Logger.Level.ERROR)
@Message(id = 184003, value = "Error deleting Subscriber queue", format = Message.Format.MESSAGE_FORMAT)
void errorDeletingSubscriberQueue(@Cause ActiveMQException e);
}

View File

@ -1,53 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.activemq.artemis.rest;
public class HttpHeaderProperty {
public static final String CONTENT_TYPE = "http_content$type";
public static final String MESSAGE_PROPERTY_DISCRIMINATOR = "message.property.";
/**
* Either strips the prefix "message.property." and returns the rest of the name or (if not starting with aforementioned prefix)
* converts an HTTP header name to a selector compatible property name. '-' character is converted to
* '$'. The return property name will also be all lower case with an "http_" prepended. For example
* "Content-Type" would be converted to "http_content$type";
*
* @param httpHeader
* @return
*/
public static String toPropertyName(String httpHeader) {
if (httpHeader.startsWith( MESSAGE_PROPERTY_DISCRIMINATOR )) {
return httpHeader.replaceAll( MESSAGE_PROPERTY_DISCRIMINATOR, "" );
} else {
httpHeader = httpHeader.replace( '-', '$' );
return "http_" + httpHeader.toLowerCase();
}
}
/**
* Converts a JMS property name to an HTTP header name.
*
* @param name
* @return null if property name isn't an HTTP header name.
*/
public static String fromPropertyName(String name) {
if (!name.startsWith("http_"))
return null;
return name.substring("http_".length()).replace('$', '-');
}
}

View File

@ -1,174 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.activemq.artemis.rest;
import javax.jms.BytesMessage;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.ObjectMessage;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.ext.MessageBodyReader;
import javax.ws.rs.ext.Providers;
import java.io.ByteArrayInputStream;
import java.lang.reflect.Type;
import org.apache.activemq.artemis.rest.util.HttpMessageHelper;
import org.jboss.resteasy.core.Headers;
import org.jboss.resteasy.spi.ResteasyProviderFactory;
import org.jboss.resteasy.util.GenericType;
public class Jms {
/**
* Set a JMS Message property to the value of an HTTP header
*
* @param message
* @param name
* @param value
*/
public static void setHttpHeader(Message message, String name, String value) {
try {
message.setStringProperty(HttpHeaderProperty.toPropertyName(name), value);
} catch (JMSException e) {
throw new RuntimeException(e);
}
}
/**
* Get an HTTP header value from a JMS Message
*
* @param message
* @param name
* @return the header or {@code null} if not present
*/
public static String getHttpHeader(Message message, String name) {
try {
return message.getStringProperty(HttpHeaderProperty.toPropertyName(name));
} catch (JMSException e) {
throw new RuntimeException(e);
}
}
/**
* Extract an object using a built-in RESTEasy JAX-RS MessageBodyReader
*
* @param message
* @param type
* @param <T>
* @return
*/
public static <T> T getEntity(Message message, Class<T> type) {
return getEntity(message, type, null, ResteasyProviderFactory.getInstance());
}
/**
* Extract an object using a built-in RESTEasy JAX-RS MessageBodyReader
*
* @param message
* @param type
* @param factory
* @param <T>
* @return
*/
public static <T> T getEntity(Message message, Class<T> type, ResteasyProviderFactory factory) {
return getEntity(message, type, null, factory);
}
/**
* Extract an object using a built-in RESTEasy JAX-RS MessageBodyReader
*
* @param message
* @param type
* @param factory
* @param <T>
* @return
* @throws UnknownMediaType
* @throws UnmarshalException
*/
public static <T> T getEntity(Message message,
GenericType<T> type,
ResteasyProviderFactory factory) throws UnknownMediaType {
return getEntity(message, type.getType(), type.getGenericType(), factory);
}
public static boolean isHttpMessage(Message message) {
try {
return message.getBooleanProperty(HttpMessageHelper.POSTED_AS_HTTP_MESSAGE);
} catch (JMSException e) {
return false;
}
}
/**
* Extract an object using a built-in RESTEasy JAX-RS MessageBodyReader
*
* @param message
* @param type
* @param genericType
* @param factory
* @param <T>
* @return
* @throws UnknownMediaType
* @throws UnmarshalException
*/
public static <T> T getEntity(Message message,
Class<T> type,
Type genericType,
ResteasyProviderFactory factory) throws UnknownMediaType {
if (!isHttpMessage(message)) {
try {
return (T) ((ObjectMessage) message).getObject();
} catch (JMSException e) {
throw new RuntimeException(e);
}
}
BytesMessage bytesMessage = (BytesMessage) message;
try {
long size = bytesMessage.getBodyLength();
if (size <= 0) {
return null;
}
byte[] body = new byte[(int) size];
bytesMessage.readBytes(body);
String contentType = message.getStringProperty(HttpHeaderProperty.CONTENT_TYPE);
if (contentType == null) {
throw new UnknownMediaType("Message did not have a Content-Type header cannot extract entity");
}
MediaType ct = MediaType.valueOf(contentType);
MessageBodyReader<T> reader = factory.getMessageBodyReader(type, genericType, null, ct);
if (reader == null) {
throw new UnmarshalException("Unable to find a JAX-RS reader for type " + type.getName() + " and media type " + contentType);
}
Providers current = ResteasyProviderFactory.getContextData(Providers.class);
ResteasyProviderFactory.pushContext(Providers.class, factory);
try {
return reader.readFrom(type, genericType, null, ct, new Headers<String>(), new ByteArrayInputStream(body));
} finally {
ResteasyProviderFactory.popContextData(Providers.class);
if (current != null)
ResteasyProviderFactory.pushContext(Providers.class, current);
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}

View File

@ -1,168 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.activemq.artemis.rest;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement(name = "rest-messaging")
public class MessageServiceConfiguration {
private int producerSessionPoolSize = 10;
private long producerTimeToLive = -1;
private int timeoutTaskInterval = 1;
private int consumerSessionTimeoutSeconds = 300;
@Deprecated
private int consumerWindowSize = -1;
private boolean defaultDurableSend = false;
private boolean dupsOk = true;
private String topicPushStoreDirectory = "topic-push-store";
private String queuePushStoreDirectory = "queue-push-store";
@Deprecated
private String inVmId = "0";
private String url = "vm://0";
private boolean useLinkHeaders = false;
private String deserializationWhiteList;
private String deserializationBlackList;
@XmlElement(name = "server-in-vm-id")
public String getInVmId() {
return inVmId;
}
public void setInVmId(String inVmId) {
ActiveMQRestLogger.LOGGER.deprecatedConfiguration("server-in-vm-id", "url");
this.inVmId = inVmId;
}
@XmlElement(name = "use-link-headers")
public boolean isUseLinkHeaders() {
return useLinkHeaders;
}
public void setUseLinkHeaders(boolean useLinkHeaders) {
this.useLinkHeaders = useLinkHeaders;
}
@XmlElement(name = "default-durable-send")
public boolean isDefaultDurableSend() {
return defaultDurableSend;
}
public void setDefaultDurableSend(boolean defaultDurableSend) {
this.defaultDurableSend = defaultDurableSend;
}
@XmlElement(name = "dups-ok")
public boolean isDupsOk() {
return dupsOk;
}
public void setDupsOk(boolean dupsOk) {
this.dupsOk = dupsOk;
}
@XmlElement(name = "topic-push-store-dir")
public String getTopicPushStoreDirectory() {
return topicPushStoreDirectory;
}
public void setTopicPushStoreDirectory(String topicPushStoreDirectory) {
this.topicPushStoreDirectory = topicPushStoreDirectory;
}
@XmlElement(name = "queue-push-store-dir")
public String getQueuePushStoreDirectory() {
return queuePushStoreDirectory;
}
public void setQueuePushStoreDirectory(String queuePushStoreDirectory) {
this.queuePushStoreDirectory = queuePushStoreDirectory;
}
@XmlElement(name = "producer-time-to-live")
public long getProducerTimeToLive() {
return producerTimeToLive;
}
public void setProducerTimeToLive(long producerTimeToLive) {
this.producerTimeToLive = producerTimeToLive;
}
@XmlElement(name = "producer-session-pool-size")
public int getProducerSessionPoolSize() {
return producerSessionPoolSize;
}
public void setProducerSessionPoolSize(int producerSessionPoolSize) {
this.producerSessionPoolSize = producerSessionPoolSize;
}
@XmlElement(name = "session-timeout-task-interval")
public int getTimeoutTaskInterval() {
return timeoutTaskInterval;
}
public void setTimeoutTaskInterval(int timeoutTaskInterval) {
this.timeoutTaskInterval = timeoutTaskInterval;
}
@XmlElement(name = "consumer-session-timeout-seconds")
public int getConsumerSessionTimeoutSeconds() {
return consumerSessionTimeoutSeconds;
}
public void setConsumerSessionTimeoutSeconds(int consumerSessionTimeoutSeconds) {
this.consumerSessionTimeoutSeconds = consumerSessionTimeoutSeconds;
}
@XmlElement(name = "consumer-window-size")
public int getConsumerWindowSize() {
return consumerWindowSize;
}
public void setConsumerWindowSize(int consumerWindowSize) {
ActiveMQRestLogger.LOGGER.deprecatedConfiguration("consumer-window-size", "url");
this.consumerWindowSize = consumerWindowSize;
}
@XmlElement(name = "url")
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getDeserializationWhiteList() {
return deserializationWhiteList;
}
public void setDeserializationWhiteList(String deserializationWhiteList) {
this.deserializationWhiteList = deserializationWhiteList;
}
public String getDeserializationBlackList() {
return deserializationBlackList;
}
public void setDeserializationBlackList(String deserializationBlackList) {
this.deserializationBlackList = deserializationBlackList;
}
}

View File

@ -1,212 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.activemq.artemis.rest;
import javax.xml.bind.JAXBContext;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.StringReader;
import java.net.URL;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import org.apache.activemq.artemis.api.core.client.ActiveMQClient;
import org.apache.activemq.artemis.api.core.client.ClientSessionFactory;
import org.apache.activemq.artemis.api.core.client.ServerLocator;
import org.apache.activemq.artemis.jms.client.ConnectionFactoryOptions;
import org.apache.activemq.artemis.rest.queue.DestinationSettings;
import org.apache.activemq.artemis.rest.queue.QueueServiceManager;
import org.apache.activemq.artemis.rest.topic.TopicServiceManager;
import org.apache.activemq.artemis.rest.util.CustomHeaderLinkStrategy;
import org.apache.activemq.artemis.rest.util.LinkHeaderLinkStrategy;
import org.apache.activemq.artemis.rest.util.LinkStrategy;
import org.apache.activemq.artemis.rest.util.TimeoutTask;
import org.apache.activemq.artemis.spi.core.naming.BindingRegistry;
import org.apache.activemq.artemis.utils.ActiveMQThreadFactory;
import org.apache.activemq.artemis.utils.XMLUtil;
public class MessageServiceManager {
private ExecutorService threadPool;
private QueueServiceManager queueManager;
private TopicServiceManager topicManager;
private TimeoutTask timeoutTask;
private int timeoutTaskInterval = 1;
protected MessageServiceConfiguration configuration = new MessageServiceConfiguration();
private boolean configSet = false;
private String configResourcePath;
protected BindingRegistry registry;
private ClientSessionFactory consumerSessionFactory;
public MessageServiceManager(ConnectionFactoryOptions jmsOptions) {
queueManager = new QueueServiceManager(jmsOptions);
topicManager = new TopicServiceManager(jmsOptions);
}
public BindingRegistry getRegistry() {
return registry;
}
public void setRegistry(BindingRegistry registry) {
this.registry = registry;
}
public int getTimeoutTaskInterval() {
return timeoutTaskInterval;
}
public void setTimeoutTaskInterval(int timeoutTaskInterval) {
this.timeoutTaskInterval = timeoutTaskInterval;
if (timeoutTask != null) {
timeoutTask.setInterval(timeoutTaskInterval);
}
}
public ExecutorService getThreadPool() {
return threadPool;
}
public void setThreadPool(ExecutorService threadPool) {
this.threadPool = threadPool;
}
public QueueServiceManager getQueueManager() {
return queueManager;
}
public TopicServiceManager getTopicManager() {
return topicManager;
}
public MessageServiceConfiguration getConfiguration() {
return configuration;
}
public String getConfigResourcePath() {
return configResourcePath;
}
public void setConfigResourcePath(String configResourcePath) {
this.configResourcePath = configResourcePath;
}
public void setConfiguration(MessageServiceConfiguration configuration) {
this.configuration = configuration;
this.configSet = true;
}
public void start() throws Exception {
if (configuration == null || !configSet) {
if (configResourcePath == null) {
configuration = new MessageServiceConfiguration();
} else {
URL url = getClass().getClassLoader().getResource(configResourcePath);
if (isOutsideOfClassloader(url)) {
url = new URL(configResourcePath);
}
JAXBContext jaxb = JAXBContext.newInstance(MessageServiceConfiguration.class);
try (Reader reader = new InputStreamReader(url.openStream())) {
String xml = XMLUtil.readerToString(reader);
xml = XMLUtil.replaceSystemPropsInString(xml);
configuration = (MessageServiceConfiguration) jaxb.createUnmarshaller().unmarshal(new StringReader(xml));
}
}
}
if (threadPool == null)
threadPool = Executors.newCachedThreadPool(ActiveMQThreadFactory.defaultThreadFactory(getClass().getName()));
timeoutTaskInterval = configuration.getTimeoutTaskInterval();
timeoutTask = new TimeoutTask(timeoutTaskInterval);
threadPool.execute(timeoutTask);
DestinationSettings defaultSettings = new DestinationSettings();
defaultSettings.setConsumerSessionTimeoutSeconds(configuration.getConsumerSessionTimeoutSeconds());
defaultSettings.setDuplicatesAllowed(configuration.isDupsOk());
defaultSettings.setDurableSend(configuration.isDefaultDurableSend());
ServerLocator consumerLocator = ActiveMQClient.createServerLocator(configuration.getUrl());
if (configuration.getConsumerWindowSize() != -1) {
consumerLocator.setConsumerWindowSize(configuration.getConsumerWindowSize());
}
ActiveMQRestLogger.LOGGER.debug("Created ServerLocator: " + consumerLocator);
consumerSessionFactory = consumerLocator.createSessionFactory();
ActiveMQRestLogger.LOGGER.debug("Created ClientSessionFactory: " + consumerSessionFactory);
ServerLocator defaultLocator = ActiveMQClient.createServerLocator(configuration.getUrl());
ClientSessionFactory sessionFactory = defaultLocator.createSessionFactory();
LinkStrategy linkStrategy;
if (configuration.isUseLinkHeaders()) {
linkStrategy = new LinkHeaderLinkStrategy();
} else {
linkStrategy = new CustomHeaderLinkStrategy();
}
queueManager.setServerLocator(defaultLocator);
queueManager.setSessionFactory(sessionFactory);
queueManager.setTimeoutTask(timeoutTask);
queueManager.setConsumerServerLocator(consumerLocator);
queueManager.setConsumerSessionFactory(consumerSessionFactory);
queueManager.setDefaultSettings(defaultSettings);
queueManager.setPushStoreFile(configuration.getQueuePushStoreDirectory());
queueManager.setProducerPoolSize(configuration.getProducerSessionPoolSize());
queueManager.setProducerTimeToLive(configuration.getProducerTimeToLive());
queueManager.setLinkStrategy(linkStrategy);
queueManager.setRegistry(registry);
topicManager.setServerLocator(defaultLocator);
topicManager.setSessionFactory(sessionFactory);
topicManager.setTimeoutTask(timeoutTask);
topicManager.setConsumerServerLocator(consumerLocator);
topicManager.setConsumerSessionFactory(consumerSessionFactory);
topicManager.setDefaultSettings(defaultSettings);
topicManager.setPushStoreFile(configuration.getTopicPushStoreDirectory());
topicManager.setProducerPoolSize(configuration.getProducerSessionPoolSize());
queueManager.setProducerTimeToLive(configuration.getProducerTimeToLive());
topicManager.setLinkStrategy(linkStrategy);
topicManager.setRegistry(registry);
queueManager.start();
topicManager.start();
}
private boolean isOutsideOfClassloader(URL url) {
return url == null;
}
public void stop() {
if (queueManager != null)
queueManager.stop();
queueManager = null;
if (topicManager != null)
topicManager.stop();
topicManager = null;
this.timeoutTask.stop();
threadPool.shutdown();
try {
threadPool.awaitTermination(5000, TimeUnit.SECONDS);
} catch (InterruptedException e) {
}
this.consumerSessionFactory.close();
}
}

View File

@ -1,26 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.activemq.artemis.rest;
public class UnknownMediaType extends RuntimeException {
private static final long serialVersionUID = -1445038845165315001L;
public UnknownMediaType(String s) {
super(s);
}
}

View File

@ -1,30 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.activemq.artemis.rest;
public class UnmarshalException extends RuntimeException {
private static final long serialVersionUID = 3932027442263719425L;
public UnmarshalException(String s) {
super(s);
}
public UnmarshalException(String s, Throwable throwable) {
super(s, throwable);
}
}

View File

@ -1,47 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.activemq.artemis.rest.integration;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import org.apache.activemq.artemis.core.server.embedded.EmbeddedActiveMQ;
public class ActiveMQBootstrapListener implements ServletContextListener {
private EmbeddedActiveMQ activeMQ;
@Override
public void contextInitialized(ServletContextEvent contextEvent) {
activeMQ = new EmbeddedActiveMQ();
try {
activeMQ.start();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
@Override
public void contextDestroyed(ServletContextEvent servletContextEvent) {
try {
if (activeMQ != null)
activeMQ.stop();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}

View File

@ -1,75 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.activemq.artemis.rest.integration;
import org.apache.activemq.artemis.core.server.embedded.EmbeddedActiveMQ;
import org.apache.activemq.artemis.jms.client.ConnectionFactoryOptions;
import org.apache.activemq.artemis.rest.MessageServiceManager;
import org.jboss.resteasy.plugins.server.tjws.TJWSEmbeddedJaxrsServer;
import org.jboss.resteasy.test.TestPortProvider;
public class EmbeddedRestActiveMQ {
private TJWSEmbeddedJaxrsServer tjws = new TJWSEmbeddedJaxrsServer();
private EmbeddedActiveMQ embeddedActiveMQ;
private MessageServiceManager manager = new MessageServiceManager(null);
public EmbeddedRestActiveMQ(ConnectionFactoryOptions jmsOptions) {
int port = TestPortProvider.getPort();
tjws.setPort(port);
tjws.setRootResourcePath("");
tjws.setSecurityDomain(null);
manager = new MessageServiceManager(jmsOptions);
initEmbeddedActiveMQ();
}
protected void initEmbeddedActiveMQ() {
embeddedActiveMQ = new EmbeddedActiveMQ();
}
public MessageServiceManager getManager() {
return manager;
}
public void start() throws Exception {
embeddedActiveMQ.start();
tjws.start();
manager.start();
tjws.getDeployment().getRegistry().addSingletonResource(manager.getQueueManager().getDestination());
tjws.getDeployment().getRegistry().addSingletonResource(manager.getTopicManager().getDestination());
}
public void stop() throws Exception {
try {
tjws.stop();
} catch (Exception e) {
}
try {
manager.stop();
} catch (Exception e) {
}
embeddedActiveMQ.stop();
}
public EmbeddedActiveMQ getEmbeddedActiveMQ() {
return embeddedActiveMQ;
}
public void setEmbeddedActiveMQ(EmbeddedActiveMQ embeddedActiveMQ) {
this.embeddedActiveMQ = embeddedActiveMQ;
}
}

View File

@ -1,42 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.activemq.artemis.rest.integration;
import org.apache.activemq.artemis.jms.client.ConnectionFactoryOptions;
import org.apache.activemq.artemis.jms.server.embedded.EmbeddedJMS;
import org.apache.activemq.artemis.spi.core.naming.BindingRegistry;
@Deprecated
public class EmbeddedRestActiveMQJMS extends EmbeddedRestActiveMQ {
public EmbeddedRestActiveMQJMS(ConnectionFactoryOptions jmsOptions) {
super(jmsOptions);
}
@Override
protected void initEmbeddedActiveMQ() {
super.setEmbeddedActiveMQ(new EmbeddedJMS());
}
public BindingRegistry getRegistry() {
return ((EmbeddedJMS) getEmbeddedActiveMQ()).getRegistry();
}
public EmbeddedJMS getEmbeddedJMS() {
return (EmbeddedJMS) getEmbeddedActiveMQ();
}
}

View File

@ -1,86 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.activemq.artemis.rest.integration;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import org.apache.activemq.artemis.jms.client.ConnectionFactoryOptions;
import org.apache.activemq.artemis.rest.MessageServiceManager;
import org.apache.activemq.artemis.utils.ObjectInputStreamWithClassLoader;
import org.jboss.resteasy.spi.Registry;
import org.jboss.resteasy.spi.ResteasyDeployment;
public class RestMessagingBootstrapListener implements ServletContextListener, ConnectionFactoryOptions {
MessageServiceManager manager;
private String deserializationBlackList;
private String deserializationWhiteList;
@Override
public void contextInitialized(ServletContextEvent contextEvent) {
ServletContext context = contextEvent.getServletContext();
ResteasyDeployment resteasyDeployment = (ResteasyDeployment) context.getAttribute(ResteasyDeployment.class.getName());
if (resteasyDeployment == null) {
throw new RuntimeException("You must install RESTEasy as a Bootstrap Listener and it must be listed before this class");
}
Registry registry = resteasyDeployment.getRegistry();
String configfile = context.getInitParameter("rest.messaging.config.file");
deserializationBlackList = context.getInitParameter(ObjectInputStreamWithClassLoader.BLACKLIST_PROPERTY);
deserializationWhiteList = context.getInitParameter(ObjectInputStreamWithClassLoader.WHITELIST_PROPERTY);
manager = new MessageServiceManager(this);
if (configfile != null) {
manager.setConfigResourcePath(configfile);
}
try {
manager.start();
registry.addSingletonResource(manager.getQueueManager().getDestination());
registry.addSingletonResource(manager.getTopicManager().getDestination());
} catch (Exception e) {
throw new RuntimeException(e);
}
}
@Override
public void contextDestroyed(ServletContextEvent servletContextEvent) {
if (manager != null) {
manager.stop();
}
}
@Override
public String getDeserializationBlackList() {
return deserializationBlackList;
}
@Override
public void setDeserializationBlackList(String blackList) {
deserializationBlackList = blackList;
}
@Override
public String getDeserializationWhiteList() {
return deserializationWhiteList;
}
@Override
public void setDeserializationWhiteList(String whiteList) {
deserializationWhiteList = whiteList;
}
}

View File

@ -1,50 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.activemq.artemis.rest.integration;
import javax.servlet.ServletContext;
import org.apache.activemq.artemis.spi.core.naming.BindingRegistry;
public class ServletContextBindingRegistry implements BindingRegistry {
private ServletContext servletContext;
public ServletContextBindingRegistry(ServletContext servletContext) {
this.servletContext = servletContext;
}
@Override
public Object lookup(String name) {
return servletContext.getAttribute(name);
}
@Override
public boolean bind(String name, Object obj) {
servletContext.setAttribute(name, obj);
return true;
}
@Override
public void unbind(String name) {
servletContext.removeAttribute(name);
}
@Override
public void close() {
}
}

View File

@ -1,239 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.activemq.artemis.rest.queue;
import javax.ws.rs.DefaultValue;
import javax.ws.rs.FormParam;
import javax.ws.rs.HeaderParam;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriBuilder;
import javax.ws.rs.core.UriInfo;
import java.net.URI;
import org.apache.activemq.artemis.api.core.ActiveMQException;
import org.apache.activemq.artemis.api.core.client.ClientConsumer;
import org.apache.activemq.artemis.api.core.client.ClientMessage;
import org.apache.activemq.artemis.api.core.client.ClientSession;
import org.apache.activemq.artemis.api.core.client.ClientSessionFactory;
import org.apache.activemq.artemis.rest.ActiveMQRestLogger;
import org.apache.activemq.artemis.rest.util.Constants;
import org.apache.activemq.artemis.rest.util.LinkStrategy;
public class AcknowledgedQueueConsumer extends QueueConsumer {
protected long counter;
protected String startup = Long.toString(System.currentTimeMillis());
protected volatile Acknowledgement ack;
public AcknowledgedQueueConsumer(ClientSessionFactory factory,
String destination,
String id,
DestinationServiceManager serviceManager,
String selector) throws ActiveMQException {
super(factory, destination, id, serviceManager, selector);
autoAck = false;
}
public synchronized Acknowledgement getAck() {
return ack;
}
@Override
@Path("acknowledge-next{index}")
@POST
public synchronized Response poll(@HeaderParam(Constants.WAIT_HEADER) @DefaultValue("0") long wait,
@PathParam("index") long index,
@Context UriInfo info) {
ActiveMQRestLogger.LOGGER.debug("Handling POST request for \"" + info.getPath() + "\"");
if (closed) {
UriBuilder builder = info.getBaseUriBuilder();
String path = info.getMatchedURIs().get(1);
builder.path(path).path("acknowledge-next");
String uri = builder.build().toString();
// redirect to another acknowledge-next
return Response.status(307).location(URI.create(uri)).build();
}
return checkIndexAndPoll(wait, info, info.getMatchedURIs().get(1), index);
}
@Override
public synchronized void shutdown() {
super.shutdown();
if (ack != null) {
ack = null;
}
}
@Path("acknowledgement/{ackToken}")
@POST
public synchronized Response acknowledge(@PathParam("ackToken") String ackToken,
@FormParam("acknowledge") boolean doAcknowledge,
@Context UriInfo uriInfo) {
ActiveMQRestLogger.LOGGER.debug("Handling POST request for \"" + uriInfo.getPath() + "\"");
ping(0);
String basePath = uriInfo.getMatchedURIs().get(1);
if (closed) {
Response.ResponseBuilder builder = Response.status(Response.Status.PRECONDITION_FAILED).entity("Could not acknowledge message, it was probably requeued from a timeout").type("text/plain");
setAcknowledgeLinks(uriInfo, basePath, builder, "-1");
return builder.build();
}
if (ack == null || !ack.getAckToken().equals(ackToken)) {
Response.ResponseBuilder builder = Response.status(Response.Status.PRECONDITION_FAILED).entity("Could not acknowledge message, it was probably requeued from a timeout or you have an old link").type("text/plain");
setAcknowledgeLinks(uriInfo, basePath, builder, "-1");
return builder.build();
}
// clear indexes as we know the client got the message and won't send a duplicate ack-next
previousIndex = -2;
lastConsumed = null;
if (ack.wasSet() && doAcknowledge != ack.isAcknowledged()) {
StringBuilder msg = new StringBuilder("Could not ");
if (doAcknowledge == false)
msg.append("un");
msg.append("acknowledge message because it has already been ");
if (doAcknowledge == true)
msg.append("un");
msg.append("acknowledged");
Response.ResponseBuilder builder = Response.status(Response.Status.PRECONDITION_FAILED).entity(msg.toString()).type("text/plain");
setAcknowledgeLinks(uriInfo, basePath, builder, "-1");
return builder.build();
}
if (ack.wasSet() && doAcknowledge == ack.isAcknowledged()) {
Response.ResponseBuilder builder = Response.noContent();
setAcknowledgeLinks(uriInfo, basePath, builder, "-1");
return builder.build();
}
if (doAcknowledge) {
try {
ack.acknowledge();
//System.out.println("Acknowledge message: " + ack.getMessage());
ack.getMessage().acknowledge();
} catch (ActiveMQException e) {
throw new RuntimeException(e);
}
} else {
ack.unacknowledge();
unacknowledge();
}
Response.ResponseBuilder builder = Response.noContent();
setAcknowledgeLinks(uriInfo, basePath, builder, "-1");
return builder.build();
}
@Override
protected ClientMessage receive(long timeoutSecs) throws Exception {
ClientMessage msg = super.receive(timeoutSecs);
return msg;
}
@Override
protected ClientMessage receiveFromConsumer(long timeoutSecs) throws Exception {
ClientMessage message = super.receiveFromConsumer(timeoutSecs);
if (message != null) {
ack = new Acknowledgement((counter++) + startup, message);
//System.out.println("---> Setting ack: " + ack.getAckToken());
}
return message;
}
protected String getAckToken() {
return ack.getAckToken();
}
protected void unacknowledge() {
// we close current session so that message is redelivered
// for temporary queues/topics, create a new session before closing old so we don't lose the temporary topic/queue
ClientConsumer old = consumer;
ClientSession oldSession = session;
try {
createSession();
} catch (Exception e) {
shutdown();
throw new RuntimeException(e);
} finally {
try {
old.close();
} catch (ActiveMQException e) {
}
try {
oldSession.close();
} catch (ActiveMQException e) {
}
}
}
protected void setAcknowledgeLinks(UriInfo uriInfo,
String basePath,
Response.ResponseBuilder builder,
String index) {
setAcknowledgeNextLink(serviceManager.getLinkStrategy(), builder, uriInfo, basePath, index);
setSessionLink(builder, uriInfo, basePath);
}
@Override
protected void setMessageResponseLinks(UriInfo info,
String basePath,
Response.ResponseBuilder builder,
String index) {
setAcknowledgementLink(builder, info, basePath);
setSessionLink(builder, info, basePath);
}
@Override
protected void setPollTimeoutLinks(UriInfo info, String basePath, Response.ResponseBuilder builder, String index) {
setAcknowledgeNextLink(serviceManager.getLinkStrategy(), builder, info, basePath, index);
setSessionLink(builder, info, basePath);
}
public void setAcknowledgementLink(Response.ResponseBuilder response, UriInfo info, String basePath) {
UriBuilder builder = info.getBaseUriBuilder();
builder.path(basePath).path("acknowledgement").path(getAckToken());
String uri = builder.build().toString();
serviceManager.getLinkStrategy().setLinkHeader(response, "acknowledgement", "acknowledgement", uri, MediaType.APPLICATION_FORM_URLENCODED);
}
public static void setAcknowledgeNextLink(LinkStrategy linkStrategy,
Response.ResponseBuilder response,
UriInfo info,
String basePath,
String index) {
if (index == null)
throw new IllegalArgumentException("index cannot be null");
UriBuilder builder = info.getBaseUriBuilder();
builder.path(basePath).path("acknowledge-next" + index);
String uri = builder.build().toString();
linkStrategy.setLinkHeader(response, "acknowledge-next", "acknowledge-next", uri, MediaType.APPLICATION_FORM_URLENCODED);
}
}

View File

@ -1,61 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.activemq.artemis.rest.queue;
import org.apache.activemq.artemis.api.core.client.ClientMessage;
public class Acknowledgement {
private final String ackToken;
private final ClientMessage message;
private boolean wasSet;
private boolean acknowledged;
public Acknowledgement(String ackToken, ClientMessage message) {
this.ackToken = ackToken;
this.message = message;
}
public String getAckToken() {
return ackToken;
}
public ClientMessage getMessage() {
return message;
}
public boolean wasSet() {
return wasSet;
}
public void acknowledge() {
if (wasSet)
throw new RuntimeException("Ack state is immutable");
wasSet = true;
acknowledged = true;
}
public void unacknowledge() {
if (wasSet)
throw new RuntimeException("Ack state is immutable");
wasSet = true;
}
public boolean isAcknowledged() {
return acknowledged;
}
}

View File

@ -1,45 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.activemq.artemis.rest.queue;
import javax.ws.rs.core.Response;
import org.apache.activemq.artemis.api.core.client.ClientMessage;
public class ConsumedHttpMessage extends ConsumedMessage {
private byte[] data;
public ConsumedHttpMessage(ClientMessage message) {
super(message);
}
@Override
public void build(Response.ResponseBuilder builder) {
buildHeaders(builder);
if (data == null) {
int size = message.getBodySize();
if (size > 0) {
data = new byte[size];
message.getBodyBuffer().readBytes(data);
} else {
data = new byte[0];
}
}
builder.entity(data);
}
}

View File

@ -1,65 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.activemq.artemis.rest.queue;
import javax.ws.rs.core.Response;
import org.apache.activemq.artemis.api.core.Message;
import org.apache.activemq.artemis.api.core.SimpleString;
import org.apache.activemq.artemis.api.core.client.ClientMessage;
import org.apache.activemq.artemis.jms.client.ConnectionFactoryOptions;
import org.apache.activemq.artemis.rest.ActiveMQRestLogger;
import org.apache.activemq.artemis.rest.HttpHeaderProperty;
public abstract class ConsumedMessage {
public static final String POSTED_AS_HTTP_MESSAGE = "postedAsHttpMessage";
protected ClientMessage message;
public ConsumedMessage(ClientMessage message) {
this.message = message;
}
public long getMessageID() {
return message.getMessageID();
}
public abstract void build(Response.ResponseBuilder builder);
protected void buildHeaders(Response.ResponseBuilder builder) {
for (SimpleString key : message.getPropertyNames()) {
String k = key.toString();
String headerName = HttpHeaderProperty.fromPropertyName(k);
if (headerName == null) {
continue;
}
builder.header(headerName, message.getStringProperty(k));
ActiveMQRestLogger.LOGGER.debug("Adding " + headerName + "=" + message.getStringProperty(k));
}
}
public static ConsumedMessage createConsumedMessage(ClientMessage message, ConnectionFactoryOptions options) {
Boolean aBoolean = message.getBooleanProperty(POSTED_AS_HTTP_MESSAGE);
if (aBoolean != null && aBoolean.booleanValue()) {
return new ConsumedHttpMessage(message);
} else if (message.getType() == Message.OBJECT_TYPE) {
return new ConsumedObjectMessage(message, options);
} else {
throw new IllegalArgumentException("ClientMessage must be an HTTP message or an Object message: " + message + " type: " + message.getType());
}
}
}

View File

@ -1,62 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.activemq.artemis.rest.queue;
import javax.ws.rs.core.Response;
import java.io.ByteArrayInputStream;
import org.apache.activemq.artemis.api.core.Message;
import org.apache.activemq.artemis.api.core.client.ClientMessage;
import org.apache.activemq.artemis.jms.client.ConnectionFactoryOptions;
import org.apache.activemq.artemis.utils.ObjectInputStreamWithClassLoader;
public class ConsumedObjectMessage extends ConsumedMessage {
protected Object readObject;
private ConnectionFactoryOptions options;
public ConsumedObjectMessage(ClientMessage message, ConnectionFactoryOptions options) {
super(message);
if (message.getType() != Message.OBJECT_TYPE)
throw new IllegalArgumentException("Client message must be an OBJECT_TYPE");
this.options = options;
}
@Override
public void build(Response.ResponseBuilder builder) {
buildHeaders(builder);
if (readObject == null) {
int size = message.getBodyBuffer().readInt();
if (size > 0) {
byte[] body = new byte[size];
message.getBodyBuffer().readBytes(body);
ByteArrayInputStream bais = new ByteArrayInputStream(body);
try (ObjectInputStreamWithClassLoader ois = new ObjectInputStreamWithClassLoader(bais)) {
if (options != null) {
ois.setWhiteList(options.getDeserializationWhiteList());
ois.setBlackList(options.getDeserializationBlackList());
}
readObject = ois.readObject();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
builder.entity(readObject);
}
}

View File

@ -1,269 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.activemq.artemis.rest.queue;
import javax.ws.rs.DELETE;
import javax.ws.rs.DefaultValue;
import javax.ws.rs.FormParam;
import javax.ws.rs.GET;
import javax.ws.rs.HEAD;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriBuilder;
import javax.ws.rs.core.UriInfo;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.atomic.AtomicLong;
import org.apache.activemq.artemis.api.core.ActiveMQException;
import org.apache.activemq.artemis.api.core.client.ClientSessionFactory;
import org.apache.activemq.artemis.rest.ActiveMQRestLogger;
import org.apache.activemq.artemis.rest.util.TimeoutTask;
public class ConsumersResource implements TimeoutTask.Callback {
protected ConcurrentMap<String, QueueConsumer> queueConsumers = new ConcurrentHashMap<>();
protected ClientSessionFactory sessionFactory;
protected String destination;
protected final String startup = Long.toString(System.currentTimeMillis());
protected AtomicLong sessionCounter = new AtomicLong(1);
protected int consumerTimeoutSeconds;
protected DestinationServiceManager serviceManager;
protected static final int ACKNOWLEDGED = 0x01;
protected static final int SELECTOR_SET = 0x02;
public DestinationServiceManager getServiceManager() {
return serviceManager;
}
public void setServiceManager(DestinationServiceManager serviceManager) {
this.serviceManager = serviceManager;
}
public ClientSessionFactory getSessionFactory() {
return sessionFactory;
}
public void setSessionFactory(ClientSessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
public String getDestination() {
return destination;
}
public void setDestination(String destination) {
this.destination = destination;
}
public int getConsumerTimeoutSeconds() {
return consumerTimeoutSeconds;
}
public void setConsumerTimeoutSeconds(int consumerTimeoutSeconds) {
this.consumerTimeoutSeconds = consumerTimeoutSeconds;
}
@Override
public boolean testTimeout(String target, boolean autoShutdown) {
QueueConsumer consumer = queueConsumers.get(target);
if (consumer == null)
return false;
if (System.currentTimeMillis() - consumer.getLastPingTime() > consumerTimeoutSeconds * 1000) {
ActiveMQRestLogger.LOGGER.shutdownRestConsumer(consumer.getId());
if (autoShutdown) {
shutdown(consumer);
}
return true;
} else {
return false;
}
}
@Override
public void shutdown(String target) {
QueueConsumer consumer = queueConsumers.get(target);
if (consumer == null)
return;
shutdown(consumer);
}
private void shutdown(QueueConsumer consumer) {
synchronized (consumer) {
consumer.shutdown();
queueConsumers.remove(consumer.getId());
}
}
public void stop() {
for (QueueConsumer consumer : queueConsumers.values()) {
consumer.shutdown();
}
}
@POST
public Response createSubscription(@FormParam("autoAck") @DefaultValue("true") boolean autoAck,
@FormParam("selector") String selector,
@Context UriInfo uriInfo) {
ActiveMQRestLogger.LOGGER.debug("Handling POST request for \"" + uriInfo.getPath() + "\"");
try {
QueueConsumer consumer = null;
int attributes = 0;
if (selector != null) {
attributes = attributes | SELECTOR_SET;
}
if (autoAck) {
consumer = createConsumer(selector);
} else {
attributes |= ACKNOWLEDGED;
consumer = createAcknowledgedConsumer(selector);
}
String attributesSegment = "attributes-" + attributes;
UriBuilder location = uriInfo.getAbsolutePathBuilder();
location.path(attributesSegment);
location.path(consumer.getId());
Response.ResponseBuilder builder = Response.created(location.build());
if (autoAck) {
QueueConsumer.setConsumeNextLink(serviceManager.getLinkStrategy(), builder, uriInfo, uriInfo.getMatchedURIs().get(0) + "/" + attributesSegment + "/" + consumer.getId(), "-1");
} else {
AcknowledgedQueueConsumer.setAcknowledgeNextLink(serviceManager.getLinkStrategy(), builder, uriInfo, uriInfo.getMatchedURIs().get(0) + "/" + attributesSegment + "/" + consumer.getId(), "-1");
}
return builder.build();
} catch (ActiveMQException e) {
throw new RuntimeException(e);
} finally {
}
}
protected void addConsumer(QueueConsumer consumer) {
queueConsumers.put(consumer.getId(), consumer);
serviceManager.getTimeoutTask().add(this, consumer.getId());
}
public QueueConsumer createConsumer(String selector) throws ActiveMQException {
String genId = sessionCounter.getAndIncrement() + "-queue-" + destination + "-" + startup;
QueueConsumer consumer = new QueueConsumer(sessionFactory, destination, genId, serviceManager, selector);
addConsumer(consumer);
return consumer;
}
public QueueConsumer createAcknowledgedConsumer(String selector) throws ActiveMQException {
String genId = sessionCounter.getAndIncrement() + "-queue-" + destination + "-" + startup;
QueueConsumer consumer = new AcknowledgedQueueConsumer(sessionFactory, destination, genId, serviceManager, selector);
addConsumer(consumer);
return consumer;
}
@Path("attributes-{attributes}/{consumer-id}")
@GET
public Response getConsumer(@PathParam("attributes") int attributes,
@PathParam("consumer-id") String consumerId,
@Context UriInfo uriInfo) throws Exception {
ActiveMQRestLogger.LOGGER.debug("Handling GET request for \"" + uriInfo.getPath() + "\"");
return headConsumer(attributes, consumerId, uriInfo);
}
@Path("attributes-{attributes}/{consumer-id}")
@HEAD
public Response headConsumer(@PathParam("attributes") int attributes,
@PathParam("consumer-id") String consumerId,
@Context UriInfo uriInfo) throws Exception {
ActiveMQRestLogger.LOGGER.debug("Handling HEAD request for \"" + uriInfo.getPath() + "\"");
QueueConsumer consumer = findConsumer(attributes, consumerId, uriInfo);
Response.ResponseBuilder builder = Response.noContent();
// we synchronize just in case a failed request is still processing
synchronized (consumer) {
if ((attributes & ACKNOWLEDGED) > 0) {
AcknowledgedQueueConsumer ackedConsumer = (AcknowledgedQueueConsumer) consumer;
Acknowledgement ack = ackedConsumer.getAck();
if (ack == null || ack.wasSet()) {
AcknowledgedQueueConsumer.setAcknowledgeNextLink(serviceManager.getLinkStrategy(), builder, uriInfo, uriInfo.getMatchedURIs().get(1) + "/attributes-" + attributes + "/" + consumer.getId(), Long.toString(consumer.getConsumeIndex()));
} else {
ackedConsumer.setAcknowledgementLink(builder, uriInfo, uriInfo.getMatchedURIs().get(1) + "/attributes-" + attributes + "/" + consumer.getId());
}
} else {
QueueConsumer.setConsumeNextLink(serviceManager.getLinkStrategy(), builder, uriInfo, uriInfo.getMatchedURIs().get(1) + "/attributes-" + attributes + "/" + consumer.getId(), Long.toString(consumer.getConsumeIndex()));
}
}
return builder.build();
}
@Path("attributes-{attributes}/{consumer-id}")
public QueueConsumer findConsumer(@PathParam("attributes") int attributes,
@PathParam("consumer-id") String consumerId,
@Context UriInfo uriInfo) throws Exception {
QueueConsumer consumer = queueConsumers.get(consumerId);
if (consumer == null) {
if ((attributes & SELECTOR_SET) > 0) {
Response.ResponseBuilder builder = Response.status(Response.Status.GONE).entity("Cannot reconnect to selector-based consumer. You must recreate the consumer session.").type("text/plain");
UriBuilder uriBuilder = uriInfo.getBaseUriBuilder();
uriBuilder.path(uriInfo.getMatchedURIs().get(1));
serviceManager.getLinkStrategy().setLinkHeader(builder, "pull-consumers", "pull-consumers", uriBuilder.build().toString(), null);
throw new WebApplicationException(builder.build());
}
if ((attributes & ACKNOWLEDGED) > 0) {
QueueConsumer tmp = new AcknowledgedQueueConsumer(sessionFactory, destination, consumerId, serviceManager, null);
consumer = addReconnectedConsumerToMap(consumerId, tmp);
} else {
QueueConsumer tmp = new QueueConsumer(sessionFactory, destination, consumerId, serviceManager, null);
consumer = addReconnectedConsumerToMap(consumerId, tmp);
}
}
return consumer;
}
private QueueConsumer addReconnectedConsumerToMap(String consumerId, QueueConsumer tmp) {
QueueConsumer consumer;
consumer = queueConsumers.putIfAbsent(consumerId, tmp);
if (consumer != null) {
tmp.shutdown();
} else {
consumer = tmp;
serviceManager.getTimeoutTask().add(this, consumer.getId());
}
return consumer;
}
@Path("attributes-{attributes}/{consumer-id}")
@DELETE
public void closeSession(@PathParam("consumer-id") String consumerId, @Context UriInfo uriInfo) {
ActiveMQRestLogger.LOGGER.debug("Handling DELETE request for \"" + uriInfo.getPath() + "\"");
QueueConsumer consumer = queueConsumers.remove(consumerId);
if (consumer == null) {
throw new WebApplicationException(Response.status(Response.Status.NOT_FOUND).entity("Failed to match a consumer to URL" + consumerId).type("text/plain").build());
}
consumer.shutdown();
}
}

View File

@ -1,48 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.activemq.artemis.rest.queue;
public class DestinationResource {
protected String destination;
protected PostMessage sender;
protected DestinationServiceManager serviceManager;
public DestinationServiceManager getServiceManager() {
return serviceManager;
}
public void setServiceManager(DestinationServiceManager serviceManager) {
this.serviceManager = serviceManager;
}
public PostMessage getSender() {
return sender;
}
public void setSender(PostMessage sender) {
this.sender = sender;
}
public String getDestination() {
return destination;
}
public void setDestination(String destination) {
this.destination = destination;
}
}

View File

@ -1,170 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.activemq.artemis.rest.queue;
import org.apache.activemq.artemis.api.core.TransportConfiguration;
import org.apache.activemq.artemis.api.core.client.ActiveMQClient;
import org.apache.activemq.artemis.api.core.client.ClientSessionFactory;
import org.apache.activemq.artemis.api.core.client.ServerLocator;
import org.apache.activemq.artemis.core.remoting.impl.invm.InVMConnectorFactory;
import org.apache.activemq.artemis.jms.client.ConnectionFactoryOptions;
import org.apache.activemq.artemis.rest.util.LinkStrategy;
import org.apache.activemq.artemis.rest.util.TimeoutTask;
import org.apache.activemq.artemis.spi.core.naming.BindingRegistry;
public abstract class DestinationServiceManager {
protected ServerLocator locator;
protected ClientSessionFactory sessionFactory;
protected ServerLocator consumerServerLocator;
protected ClientSessionFactory consumerSessionFactory;
protected boolean started;
protected String pushStoreFile;
protected DestinationSettings defaultSettings = DestinationSettings.defaultSettings;
protected TimeoutTask timeoutTask;
protected int producerPoolSize;
protected long producerTimeToLive;
protected LinkStrategy linkStrategy;
protected BindingRegistry registry;
protected ConnectionFactoryOptions jmsOptions;
public DestinationServiceManager(ConnectionFactoryOptions jmsOptions) {
this.jmsOptions = jmsOptions;
}
public BindingRegistry getRegistry() {
return registry;
}
public void setRegistry(BindingRegistry registry) {
this.registry = registry;
}
public LinkStrategy getLinkStrategy() {
return linkStrategy;
}
public void setLinkStrategy(LinkStrategy linkStrategy) {
this.linkStrategy = linkStrategy;
}
public long getProducerTimeToLive() {
return producerTimeToLive;
}
public void setProducerTimeToLive(long producerTimeToLive) {
this.producerTimeToLive = producerTimeToLive;
}
public int getProducerPoolSize() {
return producerPoolSize;
}
public void setProducerPoolSize(int producerPoolSize) {
this.producerPoolSize = producerPoolSize;
}
public ClientSessionFactory getConsumerSessionFactory() {
return consumerSessionFactory;
}
public void setConsumerSessionFactory(ClientSessionFactory consumerSessionFactory) {
this.consumerSessionFactory = consumerSessionFactory;
}
/**
* @return the consumerServerLocator
*/
public ServerLocator getConsumerServerLocator() {
return consumerServerLocator;
}
/**
* @param consumerServerLocator the consumerServerLocator to set
*/
public void setConsumerServerLocator(ServerLocator consumerServerLocator) {
this.consumerServerLocator = consumerServerLocator;
}
public TimeoutTask getTimeoutTask() {
return timeoutTask;
}
public void setTimeoutTask(TimeoutTask timeoutTask) {
this.timeoutTask = timeoutTask;
}
public DestinationSettings getDefaultSettings() {
return defaultSettings;
}
public void setDefaultSettings(DestinationSettings defaultSettings) {
this.defaultSettings = defaultSettings;
}
public ServerLocator getServerLocator() {
return this.locator;
}
public void setServerLocator(ServerLocator locator) {
this.locator = locator;
}
public ClientSessionFactory getSessionFactory() {
return sessionFactory;
}
public void setSessionFactory(ClientSessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
public String getPushStoreFile() {
return pushStoreFile;
}
public void setPushStoreFile(String pushStoreFile) {
this.pushStoreFile = pushStoreFile;
}
protected void initDefaults() {
if (locator == null) {
locator = ActiveMQClient.createServerLocatorWithoutHA(new TransportConfiguration(InVMConnectorFactory.class.getName()));
}
if (sessionFactory == null) {
try {
sessionFactory = locator.createSessionFactory();
} catch (Exception e) {
throw new RuntimeException(e.getMessage(), e);
}
}
if (consumerSessionFactory == null)
consumerSessionFactory = sessionFactory;
if (timeoutTask == null)
throw new RuntimeException("TimeoutTask is not set");
}
public abstract void start() throws Exception;
public abstract void stop();
public ConnectionFactoryOptions getJmsOptions() {
return jmsOptions;
}
}

View File

@ -1,56 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.activemq.artemis.rest.queue;
public class DestinationSettings {
protected boolean duplicatesAllowed;
private boolean durableSend;
private int consumerSessionTimeoutSeconds = 1000;
public boolean isDuplicatesAllowed() {
return duplicatesAllowed;
}
public void setDuplicatesAllowed(boolean duplicatesAllowed) {
this.duplicatesAllowed = duplicatesAllowed;
}
public int getConsumerSessionTimeoutSeconds() {
return consumerSessionTimeoutSeconds;
}
public void setConsumerSessionTimeoutSeconds(int consumerSessionTimeoutSeconds) {
this.consumerSessionTimeoutSeconds = consumerSessionTimeoutSeconds;
}
public boolean isDurableSend() {
return durableSend;
}
public void setDurableSend(boolean durableSend) {
this.durableSend = durableSend;
}
public static final DestinationSettings defaultSettings;
static {
defaultSettings = new DestinationSettings();
defaultSettings.setDuplicatesAllowed(true);
defaultSettings.setDurableSend(false);
}
}

View File

@ -1,266 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.activemq.artemis.rest.queue;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.QueryParam;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriBuilder;
import javax.ws.rs.core.UriInfo;
import java.net.URI;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;
import org.apache.activemq.artemis.api.core.ActiveMQException;
import org.apache.activemq.artemis.api.core.Message;
import org.apache.activemq.artemis.api.core.client.ClientMessage;
import org.apache.activemq.artemis.api.core.client.ClientProducer;
import org.apache.activemq.artemis.api.core.client.ClientSession;
import org.apache.activemq.artemis.api.core.client.ClientSessionFactory;
import org.apache.activemq.artemis.rest.ActiveMQRestLogger;
import org.apache.activemq.artemis.rest.util.HttpMessageHelper;
import org.apache.activemq.artemis.utils.UUID;
import org.apache.activemq.artemis.utils.UUIDGenerator;
public class PostMessage {
protected ClientSessionFactory sessionFactory;
protected String destination;
protected boolean defaultDurable = false;
protected DestinationServiceManager serviceManager;
private AtomicLong counter = new AtomicLong(1);
private final String startupTime = Long.toString(System.currentTimeMillis());
protected long producerTimeToLive;
protected ArrayBlockingQueue<Pooled> pool;
protected int poolSize = 10;
protected static class Pooled {
public ClientSession session;
public ClientProducer producer;
private Pooled(ClientSession session, ClientProducer producer) {
this.session = session;
this.producer = producer;
}
}
protected String generateDupId() {
return startupTime + Long.toString(counter.incrementAndGet());
}
public void publish(HttpHeaders headers,
byte[] body,
String dup,
boolean durable,
Long ttl,
Long expiration,
Integer priority) throws Exception {
Pooled pooled = getPooled();
try {
ClientProducer producer = pooled.producer;
ClientMessage message = createActiveMQMessage(headers, body, durable, ttl, expiration, priority, pooled.session);
message.putStringProperty(Message.HDR_DUPLICATE_DETECTION_ID.toString(), dup);
producer.send(message);
ActiveMQRestLogger.LOGGER.debug("Sent message: " + message);
pool.add(pooled);
} catch (Exception ex) {
try {
pooled.session.close();
} catch (ActiveMQException e) {
}
addPooled();
throw ex;
}
}
@PUT
@Path("{id}")
public Response putWithId(@PathParam("id") String dupId,
@QueryParam("durable") Boolean durable,
@QueryParam("ttl") Long ttl,
@QueryParam("expiration") Long expiration,
@QueryParam("priority") Integer priority,
@Context HttpHeaders headers,
@Context UriInfo uriInfo,
byte[] body) {
ActiveMQRestLogger.LOGGER.debug("Handling PUT request for \"" + uriInfo.getRequestUri() + "\"");
return internalPostWithId(dupId, durable, ttl, expiration, priority, headers, uriInfo, body);
}
@POST
@Path("{id}")
public Response postWithId(@PathParam("id") String dupId,
@QueryParam("durable") Boolean durable,
@QueryParam("ttl") Long ttl,
@QueryParam("expiration") Long expiration,
@QueryParam("priority") Integer priority,
@Context HttpHeaders headers,
@Context UriInfo uriInfo,
byte[] body) {
ActiveMQRestLogger.LOGGER.debug("Handling POST request for \"" + uriInfo.getRequestUri() + "\"");
return internalPostWithId(dupId, durable, ttl, expiration, priority, headers, uriInfo, body);
}
private Response internalPostWithId(String dupId,
Boolean durable,
Long ttl,
Long expiration,
Integer priority,
HttpHeaders headers,
UriInfo uriInfo,
byte[] body) {
String matched = uriInfo.getMatchedURIs().get(1);
UriBuilder nextBuilder = uriInfo.getBaseUriBuilder();
String nextId = generateDupId();
nextBuilder.path(matched).path(nextId);
URI next = nextBuilder.build();
boolean isDurable = defaultDurable;
if (durable != null) {
isDurable = durable.booleanValue();
}
try {
publish(headers, body, dupId, isDurable, ttl, expiration, priority);
} catch (Exception e) {
Response error = Response.serverError().entity("Problem posting message: " + e.getMessage()).type("text/plain").build();
throw new WebApplicationException(e, error);
}
Response.ResponseBuilder builder = Response.status(201);
serviceManager.getLinkStrategy().setLinkHeader(builder, "create-next", "create-next", next.toString(), "*/*");
return builder.build();
}
public long getProducerTimeToLive() {
return producerTimeToLive;
}
public void setProducerTimeToLive(long producerTimeToLive) {
this.producerTimeToLive = producerTimeToLive;
}
public DestinationServiceManager getServiceManager() {
return serviceManager;
}
public void setServiceManager(DestinationServiceManager serviceManager) {
this.serviceManager = serviceManager;
}
public ClientSessionFactory getSessionFactory() {
return sessionFactory;
}
public void setSessionFactory(ClientSessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
public String getDestination() {
return destination;
}
public void setDestination(String destination) {
this.destination = destination;
}
public boolean isDefaultDurable() {
return defaultDurable;
}
public void setDefaultDurable(boolean defaultDurable) {
this.defaultDurable = defaultDurable;
}
public int getPoolSize() {
return poolSize;
}
public void setPoolSize(int poolSize) {
this.poolSize = poolSize;
}
public void init() throws Exception {
pool = new ArrayBlockingQueue<>(poolSize);
for (int i = 0; i < poolSize; i++) {
addPooled();
}
}
protected void addPooled() throws ActiveMQException {
ClientSession session = sessionFactory.createSession();
ClientProducer producer = session.createProducer(destination);
session.start();
pool.add(new Pooled(session, producer));
}
protected Pooled getPooled() throws InterruptedException {
Pooled pooled = pool.poll(1, TimeUnit.SECONDS);
if (pooled == null) {
throw new WebApplicationException(Response.status(503).entity("Timed out waiting for available producer.").type("text/plain").build());
}
return pooled;
}
public void cleanup() {
for (Pooled pooled : pool) {
try {
pooled.session.close();
} catch (ActiveMQException e) {
throw new RuntimeException(e);
}
}
}
protected ClientMessage createActiveMQMessage(HttpHeaders headers,
byte[] body,
boolean durable,
Long ttl,
Long expiration,
Integer priority,
ClientSession session) throws Exception {
ClientMessage message = session.createMessage(Message.BYTES_TYPE, durable);
// HORNETQ-962
UUID uid = UUIDGenerator.getInstance().generateUUID();
message.setUserID(uid);
if (expiration != null) {
message.setExpiration(expiration.longValue());
} else if (ttl != null) {
message.setExpiration(System.currentTimeMillis() + ttl.longValue());
} else if (producerTimeToLive > 0) {
message.setExpiration(System.currentTimeMillis() + producerTimeToLive);
}
if (priority != null) {
byte p = priority.byteValue();
if (p >= 0 && p <= 9) {
message.setPriority(p);
}
}
HttpMessageHelper.writeHttpMessage(headers, body, message);
return message;
}
}

View File

@ -1,88 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.activemq.artemis.rest.queue;
import javax.ws.rs.POST;
import javax.ws.rs.QueryParam;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriBuilder;
import javax.ws.rs.core.UriInfo;
import java.net.URI;
import org.apache.activemq.artemis.api.core.ActiveMQException;
import org.apache.activemq.artemis.api.core.client.ClientMessage;
import org.apache.activemq.artemis.api.core.client.ClientProducer;
import org.apache.activemq.artemis.rest.ActiveMQRestLogger;
/**
* Implements simple "create" link. Returns 201 with Location of created resource as per HTTP
*/
public class PostMessageDupsOk extends PostMessage {
public void publish(HttpHeaders headers,
byte[] body,
boolean durable,
Long ttl,
Long expiration,
Integer priority) throws Exception {
Pooled pooled = getPooled();
try {
ClientProducer producer = pooled.producer;
ClientMessage message = createActiveMQMessage(headers, body, durable, ttl, expiration, priority, pooled.session);
producer.send(message);
ActiveMQRestLogger.LOGGER.debug("Sent message: " + message);
pool.add(pooled);
} catch (Exception ex) {
try {
pooled.session.close();
} catch (ActiveMQException e) {
}
addPooled();
throw ex;
}
}
@POST
public Response create(@Context HttpHeaders headers,
@QueryParam("durable") Boolean durable,
@QueryParam("ttl") Long ttl,
@QueryParam("expiration") Long expiration,
@QueryParam("priority") Integer priority,
@Context UriInfo uriInfo,
byte[] body) {
ActiveMQRestLogger.LOGGER.debug("Handling POST request for \"" + uriInfo.getRequestUri() + "\"");
try {
boolean isDurable = defaultDurable;
if (durable != null) {
isDurable = durable.booleanValue();
}
publish(headers, body, isDurable, ttl, expiration, priority);
} catch (Exception e) {
Response error = Response.serverError().entity("Problem posting message: " + e.getMessage()).type("text/plain").build();
throw new WebApplicationException(e, error);
}
Response.ResponseBuilder builder = Response.status(201);
UriBuilder nextBuilder = uriInfo.getAbsolutePathBuilder();
URI next = nextBuilder.build();
serviceManager.getLinkStrategy().setLinkHeader(builder, "create-next", "create-next", next.toString(), "*/*");
return builder.build();
}
}

View File

@ -1,40 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.activemq.artemis.rest.queue;
import javax.ws.rs.POST;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo;
import org.apache.activemq.artemis.rest.ActiveMQRestLogger;
/**
* implements reliable "create", "create-next" pattern defined by REST-* Messaging specification
*/
public class PostMessageNoDups extends PostMessage {
@POST
public Response redirectCreation(@Context UriInfo uriInfo) {
ActiveMQRestLogger.LOGGER.debug("Handling POST request for \"" + uriInfo.getPath() + "\"");
String id = generateDupId();
Response.ResponseBuilder res = Response.status(Response.Status.TEMPORARY_REDIRECT.getStatusCode());
res.location(uriInfo.getAbsolutePathBuilder().path(id).build());
return res.build();
}
}

View File

@ -1,267 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.activemq.artemis.rest.queue;
import javax.ws.rs.DefaultValue;
import javax.ws.rs.HeaderParam;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriBuilder;
import javax.ws.rs.core.UriInfo;
import java.net.URI;
import org.apache.activemq.artemis.api.core.ActiveMQException;
import org.apache.activemq.artemis.api.core.client.ClientConsumer;
import org.apache.activemq.artemis.api.core.client.ClientMessage;
import org.apache.activemq.artemis.api.core.client.ClientSession;
import org.apache.activemq.artemis.api.core.client.ClientSessionFactory;
import org.apache.activemq.artemis.jms.client.ConnectionFactoryOptions;
import org.apache.activemq.artemis.rest.ActiveMQRestLogger;
import org.apache.activemq.artemis.rest.util.Constants;
import org.apache.activemq.artemis.rest.util.LinkStrategy;
import org.apache.activemq.artemis.utils.SelectorTranslator;
/**
* Auto-acknowledged consumer
*/
public class QueueConsumer {
protected ClientSessionFactory factory;
protected ClientSession session;
protected ClientConsumer consumer;
protected String destination;
protected boolean closed;
protected String id;
protected long lastPing = System.currentTimeMillis();
protected DestinationServiceManager serviceManager;
protected boolean autoAck = true;
protected String selector;
/**
* token used to create consume-next links
*/
protected long previousIndex = -1;
protected ConsumedMessage lastConsumed;
public long getConsumeIndex() {
if (lastConsumed == null)
return -1;
return lastConsumed.getMessageID();
}
public DestinationServiceManager getServiceManager() {
return serviceManager;
}
public void setServiceManager(DestinationServiceManager serviceManager) {
this.serviceManager = serviceManager;
}
public long getLastPingTime() {
return lastPing;
}
protected void ping(long offsetSecs) {
lastPing = System.currentTimeMillis() + (offsetSecs * 1000);
}
public QueueConsumer(ClientSessionFactory factory,
String destination,
String id,
DestinationServiceManager serviceManager,
String selector) throws ActiveMQException {
this.factory = factory;
this.destination = destination;
this.id = id;
this.serviceManager = serviceManager;
this.selector = selector;
createSession();
}
public String getId() {
return id;
}
public boolean isClosed() {
return closed;
}
public synchronized void shutdown() {
if (closed)
return;
closed = true;
lastConsumed = null;
previousIndex = -2;
try {
consumer.close();
ActiveMQRestLogger.LOGGER.debug("Closed consumer: " + consumer);
} catch (Exception e) {
}
try {
session.close();
ActiveMQRestLogger.LOGGER.debug("Closed session: " + session);
} catch (Exception e) {
}
session = null;
consumer = null;
}
@Path("consume-next{index}")
@POST
public synchronized Response poll(@HeaderParam(Constants.WAIT_HEADER) @DefaultValue("0") long wait,
@PathParam("index") long index,
@Context UriInfo info) {
ActiveMQRestLogger.LOGGER.debug("Handling POST request for \"" + info.getRequestUri() + "\"");
if (closed) {
UriBuilder builder = info.getBaseUriBuilder();
builder.path(info.getMatchedURIs().get(1)).path("consume-next");
String uri = builder.build().toString();
// redirect to another consume-next
return Response.status(307).location(URI.create(uri)).build();
}
return checkIndexAndPoll(wait, info, info.getMatchedURIs().get(1), index);
}
protected Response checkIndexAndPoll(long wait, UriInfo info, String basePath, long index) {
ping(wait);
if (lastConsumed == null && index > 0) {
return Response.status(412).entity("You are using an old consume-next link and are out of sync with the JMS session on the server").type("text/plain").build();
}
if (lastConsumed != null) {
if (index == previousIndex) {
String token = Long.toString(lastConsumed.getMessageID());
return getMessageResponse(lastConsumed, info, basePath, token).build();
}
if (index != lastConsumed.getMessageID()) {
return Response.status(412).entity("You are using an old consume-next link and are out of sync with the JMS session on the server").type("text/plain").build();
}
}
try {
return pollWithIndex(wait, info, basePath, index);
} finally {
ping(0); // ping again as we don't want wait time included in timeout.
}
}
protected Response pollWithIndex(long wait, UriInfo info, String basePath, long index) {
try {
ClientMessage message = receive(wait);
if (message == null) {
Response.ResponseBuilder builder = Response.status(503).entity("Timed out waiting for message receive.").type("text/plain");
setPollTimeoutLinks(info, basePath, builder, Long.toString(index));
return builder.build();
}
previousIndex = index;
lastConsumed = ConsumedMessage.createConsumedMessage(message, this.getJmsOptions());
String token = Long.toString(lastConsumed.getMessageID());
Response response = getMessageResponse(lastConsumed, info, basePath, token).build();
if (autoAck)
message.acknowledge();
return response;
} catch (Exception e) {
Response errorResponse = Response.serverError().entity(e.getMessage()).status(Response.Status.INTERNAL_SERVER_ERROR).build();
return errorResponse;
}
}
protected void createSession() throws ActiveMQException {
session = factory.createSession(true, true, 0);
ActiveMQRestLogger.LOGGER.debug("Created session: " + session);
if (selector == null) {
consumer = session.createConsumer(destination);
} else {
consumer = session.createConsumer(destination, SelectorTranslator.convertToActiveMQFilterString(selector));
}
ActiveMQRestLogger.LOGGER.debug("Created consumer: " + consumer);
session.start();
}
protected ClientMessage receiveFromConsumer(long timeoutSecs) throws Exception {
ClientMessage m = null;
if (timeoutSecs <= 0) {
m = consumer.receive(1);
} else {
m = consumer.receive(timeoutSecs * 1000);
}
ActiveMQRestLogger.LOGGER.debug("Returning message " + m + " from consumer: " + consumer);
return m;
}
protected ClientMessage receive(long timeoutSecs) throws Exception {
return receiveFromConsumer(timeoutSecs);
}
protected void setPollTimeoutLinks(UriInfo info, String basePath, Response.ResponseBuilder builder, String index) {
setSessionLink(builder, info, basePath);
setConsumeNextLink(serviceManager.getLinkStrategy(), builder, info, basePath, index);
}
protected Response.ResponseBuilder getMessageResponse(ConsumedMessage msg,
UriInfo info,
String basePath,
String index) {
Response.ResponseBuilder responseBuilder = Response.ok();
setMessageResponseLinks(info, basePath, responseBuilder, index);
msg.build(responseBuilder);
return responseBuilder;
}
protected void setMessageResponseLinks(UriInfo info,
String basePath,
Response.ResponseBuilder responseBuilder,
String index) {
setConsumeNextLink(serviceManager.getLinkStrategy(), responseBuilder, info, basePath, index);
setSessionLink(responseBuilder, info, basePath);
}
public static void setConsumeNextLink(LinkStrategy linkStrategy,
Response.ResponseBuilder response,
UriInfo info,
String basePath,
String index) {
if (index == null)
throw new IllegalArgumentException("index cannot be null");
UriBuilder builder = info.getBaseUriBuilder();
builder.path(basePath).path("consume-next" + index);
String uri = builder.build().toString();
linkStrategy.setLinkHeader(response, "consume-next", "consume-next", uri, MediaType.APPLICATION_FORM_URLENCODED);
}
public void setSessionLink(Response.ResponseBuilder response, UriInfo info, String basePath) {
UriBuilder builder = info.getBaseUriBuilder();
builder.path(basePath);
String uri = builder.build().toString();
serviceManager.getLinkStrategy().setLinkHeader(response, "consumer", "consumer", uri, MediaType.APPLICATION_XML);
}
public ConnectionFactoryOptions getJmsOptions() {
return serviceManager.getJmsOptions();
}
}

View File

@ -1,39 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.activemq.artemis.rest.queue;
public class QueueDeployment extends DestinationSettings {
private String name;
public QueueDeployment() {
}
public QueueDeployment(String name, boolean duplicatesAllowed) {
this.name = name;
this.duplicatesAllowed = duplicatesAllowed;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}

View File

@ -1,172 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.activemq.artemis.rest.queue;
import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo;
import java.net.URI;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.apache.activemq.artemis.api.core.ActiveMQException;
import org.apache.activemq.artemis.api.core.QueueConfiguration;
import org.apache.activemq.artemis.api.core.SimpleString;
import org.apache.activemq.artemis.api.core.client.ClientSession;
import org.apache.activemq.artemis.jms.client.ActiveMQDestination;
import org.apache.activemq.artemis.jms.client.ActiveMQQueue;
import org.apache.activemq.artemis.jms.server.config.JMSQueueConfiguration;
import org.apache.activemq.artemis.jms.server.config.impl.FileJMSConfiguration;
import org.apache.activemq.artemis.rest.ActiveMQRestLogger;
import org.apache.activemq.artemis.rest.queue.push.PushConsumerResource;
import org.apache.activemq.artemis.rest.queue.push.xml.PushRegistration;
import org.apache.activemq.artemis.rest.util.Constants;
import org.w3c.dom.Document;
@Path(Constants.PATH_FOR_QUEUES)
public class QueueDestinationsResource {
private final Map<String, QueueResource> queues = new ConcurrentHashMap<>();
private final QueueServiceManager manager;
public QueueDestinationsResource(QueueServiceManager manager) {
this.manager = manager;
}
@POST
@Consumes("application/activemq.jms.queue+xml")
public Response createJmsQueue(@Context UriInfo uriInfo, Document document) {
ActiveMQRestLogger.LOGGER.debug("Handling POST request for \"" + uriInfo.getPath() + "\"");
try {
JMSQueueConfiguration queue = FileJMSConfiguration.parseQueueConfiguration(document.getDocumentElement());
ActiveMQQueue activeMQQueue = ActiveMQDestination.createQueue(queue.getName());
String queueName = activeMQQueue.getAddress();
ClientSession session = manager.getSessionFactory().createSession(false, false, false);
try {
ClientSession.QueueQuery query = session.queueQuery(new SimpleString(queueName));
if (!query.isExists()) {
if (queue.getSelector() != null) {
session.createQueue(new QueueConfiguration(queueName).setFilterString(queue.getSelector()).setDurable(queue.isDurable()));
} else {
session.createQueue(new QueueConfiguration(queueName).setDurable(queue.isDurable()));
}
} else {
throw new WebApplicationException(Response.status(412).type("text/plain").entity("Queue already exists.").build());
}
} finally {
try {
session.close();
} catch (Exception ignored) {
}
}
URI uri = uriInfo.getRequestUriBuilder().path(queueName).build();
return Response.created(uri).build();
} catch (Exception e) {
if (e instanceof WebApplicationException)
throw (WebApplicationException) e;
throw new WebApplicationException(e, Response.serverError().type("text/plain").entity("Failed to create queue.").build());
}
}
public Map<String, QueueResource> getQueues() {
return queues;
}
@Path("/{queue-name}")
public synchronized QueueResource findQueue(@PathParam("queue-name") String name) throws Exception {
QueueResource queue = queues.get(name);
if (queue == null) {
String queueName = name;
ClientSession session = manager.getSessionFactory().createSession(false, false, false);
try {
ClientSession.QueueQuery query = session.queueQuery(new SimpleString(queueName));
if (!query.isExists()) {
throw new WebApplicationException(Response.status(404).type("text/plain").entity("Queue '" + name + "' does not exist").build());
}
DestinationSettings queueSettings = manager.getDefaultSettings();
boolean defaultDurable = queueSettings.isDurableSend() || query.isDurable();
queue = createQueueResource(queueName, defaultDurable, queueSettings.getConsumerSessionTimeoutSeconds(), queueSettings.isDuplicatesAllowed());
} finally {
try {
session.close();
} catch (ActiveMQException e) {
}
}
}
return queue;
}
public QueueResource createQueueResource(String queueName,
boolean defaultDurable,
int timeoutSeconds,
boolean duplicates) throws Exception {
QueueResource queueResource = new QueueResource();
queueResource.setQueueDestinationsResource(this);
queueResource.setDestination(queueName);
queueResource.setServiceManager(manager);
ConsumersResource consumers = new ConsumersResource();
consumers.setConsumerTimeoutSeconds(timeoutSeconds);
consumers.setDestination(queueName);
consumers.setSessionFactory(manager.getConsumerSessionFactory());
consumers.setServiceManager(manager);
queueResource.setConsumers(consumers);
PushConsumerResource push = new PushConsumerResource();
push.setDestination(queueName);
push.setSessionFactory(manager.getConsumerSessionFactory());
push.setJmsOptions(manager.getJmsOptions());
queueResource.setPushConsumers(push);
PostMessage sender = null;
if (duplicates) {
sender = new PostMessageDupsOk();
} else {
sender = new PostMessageNoDups();
}
sender.setServiceManager(manager);
sender.setDefaultDurable(defaultDurable);
sender.setDestination(queueName);
sender.setSessionFactory(manager.getSessionFactory());
sender.setPoolSize(manager.getProducerPoolSize());
sender.setProducerTimeToLive(manager.getProducerTimeToLive());
sender.init();
queueResource.setSender(sender);
if (manager.getPushStore() != null) {
push.setPushStore(manager.getPushStore());
List<PushRegistration> regs = manager.getPushStore().getByDestination(queueName);
for (PushRegistration reg : regs) {
push.addRegistration(reg);
}
}
queueResource.start();
getQueues().put(queueName, queueResource);
return queueResource;
}
}

View File

@ -1,176 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.activemq.artemis.rest.queue;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.HEAD;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriBuilder;
import javax.ws.rs.core.UriInfo;
import org.apache.activemq.artemis.api.core.SimpleString;
import org.apache.activemq.artemis.api.core.client.ClientSession;
import org.apache.activemq.artemis.rest.ActiveMQRestLogger;
import org.apache.activemq.artemis.rest.queue.push.PushConsumerResource;
public class QueueResource extends DestinationResource {
protected ConsumersResource consumers;
protected PushConsumerResource pushConsumers;
private QueueDestinationsResource queueDestinationsResource;
public void start() throws Exception {
}
public void stop() {
consumers.stop();
pushConsumers.stop();
sender.cleanup();
}
@GET
@Produces("application/xml")
public Response get(@Context UriInfo uriInfo, @Context HttpServletRequest requestContext) {
ActiveMQRestLogger.LOGGER.debug("Handling GET request for \"" + destination + "\" from " + requestContext.getRemoteAddr() + ":" + requestContext.getRemotePort());
StringBuilder msg = new StringBuilder();
msg.append("<queue>").append("<name>").append(destination).append("</name>").append("<atom:link rel=\"create\" href=\"").append(createSenderLink(uriInfo)).append("\"/>").append("<atom:link rel=\"create-with-id\" href=\"").append(createSenderWithIdLink(uriInfo)).append("\"/>").append("<atom:link rel=\"pull-consumers\" href=\"").append(createConsumersLink(uriInfo)).append("\"/>").append("<atom:link rel=\"push-consumers\" href=\"").append(createPushConsumersLink(uriInfo)).append("\"/>")
.append("</queue>");
Response.ResponseBuilder builder = Response.ok(msg.toString());
setSenderLink(builder, uriInfo);
setSenderWithIdLink(builder, uriInfo);
setConsumersLink(builder, uriInfo);
setPushConsumersLink(builder, uriInfo);
return builder.build();
}
@HEAD
@Produces("application/xml")
public Response head(@Context UriInfo uriInfo) {
ActiveMQRestLogger.LOGGER.debug("Handling HEAD request for \"" + uriInfo.getRequestUri() + "\"");
Response.ResponseBuilder builder = Response.ok();
setSenderLink(builder, uriInfo);
setSenderWithIdLink(builder, uriInfo);
setConsumersLink(builder, uriInfo);
setPushConsumersLink(builder, uriInfo);
return builder.build();
}
protected void setSenderLink(Response.ResponseBuilder response, UriInfo info) {
String uri = createSenderLink(info);
serviceManager.getLinkStrategy().setLinkHeader(response, "create", "create", uri, null);
}
protected String createSenderLink(UriInfo info) {
UriBuilder builder = info.getRequestUriBuilder();
builder.path("create");
String uri = builder.build().toString();
return uri;
}
protected void setSenderWithIdLink(Response.ResponseBuilder response, UriInfo info) {
String uri = createSenderWithIdLink(info);
serviceManager.getLinkStrategy().setLinkHeader(response, "create-with-id", "create-with-id", uri, null);
}
protected String createSenderWithIdLink(UriInfo info) {
UriBuilder builder = info.getRequestUriBuilder();
builder.path("create");
String uri = builder.build().toString();
uri += "/{id}";
return uri;
}
protected void setConsumersLink(Response.ResponseBuilder response, UriInfo info) {
String uri = createConsumersLink(info);
serviceManager.getLinkStrategy().setLinkHeader(response, "pull-consumers", "pull-consumers", uri, null);
}
protected String createConsumersLink(UriInfo info) {
UriBuilder builder = info.getRequestUriBuilder();
builder.path("pull-consumers");
String uri = builder.build().toString();
return uri;
}
protected void setPushConsumersLink(Response.ResponseBuilder response, UriInfo info) {
String uri = createPushConsumersLink(info);
serviceManager.getLinkStrategy().setLinkHeader(response, "push-consumers", "push-consumers", uri, null);
}
protected String createPushConsumersLink(UriInfo info) {
UriBuilder builder = info.getRequestUriBuilder();
builder.path("push-consumers");
String uri = builder.build().toString();
return uri;
}
public void setConsumers(ConsumersResource consumers) {
this.consumers = consumers;
}
@Path("create")
public PostMessage post() throws Exception {
return sender;
}
@Path("pull-consumers")
public ConsumersResource getConsumers() {
return consumers;
}
public void setPushConsumers(PushConsumerResource pushConsumers) {
this.pushConsumers = pushConsumers;
}
@Path("push-consumers")
public PushConsumerResource getPushConsumers() {
return pushConsumers;
}
public void setQueueDestinationsResource(QueueDestinationsResource queueDestinationsResource) {
this.queueDestinationsResource = queueDestinationsResource;
}
@DELETE
public void deleteQueue(@Context UriInfo uriInfo) throws Exception {
ActiveMQRestLogger.LOGGER.debug("Handling DELETE request for \"" + uriInfo.getPath() + "\"");
queueDestinationsResource.getQueues().remove(destination);
stop();
ClientSession session = serviceManager.getSessionFactory().createSession(false, false, false);
try {
SimpleString queueName = new SimpleString(destination);
session.deleteQueue(queueName);
} finally {
try {
session.close();
} catch (Exception ignored) {
}
}
}
}

View File

@ -1,116 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.activemq.artemis.rest.queue;
import java.util.ArrayList;
import java.util.List;
import org.apache.activemq.artemis.api.core.QueueConfiguration;
import org.apache.activemq.artemis.api.core.SimpleString;
import org.apache.activemq.artemis.api.core.client.ClientSession;
import org.apache.activemq.artemis.api.core.RoutingType;
import org.apache.activemq.artemis.jms.client.ConnectionFactoryOptions;
import org.apache.activemq.artemis.rest.queue.push.FilePushStore;
import org.apache.activemq.artemis.rest.queue.push.PushStore;
public class QueueServiceManager extends DestinationServiceManager {
protected PushStore pushStore;
protected List<QueueDeployment> queues = new ArrayList<>();
protected QueueDestinationsResource destination;
public QueueServiceManager(ConnectionFactoryOptions jmsOptions) {
super(jmsOptions);
}
public List<QueueDeployment> getQueues() {
return queues;
}
public void setQueues(List<QueueDeployment> queues) {
this.queues = queues;
}
public PushStore getPushStore() {
return pushStore;
}
public void setPushStore(PushStore pushStore) {
this.pushStore = pushStore;
}
public QueueDestinationsResource getDestination() {
return destination;
}
public void setDestination(QueueDestinationsResource destination) {
this.destination = destination;
}
@Override
public void start() throws Exception {
initDefaults();
destination = new QueueDestinationsResource(this);
started = true;
if (pushStoreFile != null && pushStore == null) {
pushStore = new FilePushStore(pushStoreFile);
}
for (QueueDeployment queueDeployment : queues) {
deploy(queueDeployment);
}
}
public void deploy(QueueDeployment queueDeployment) throws Exception {
if (!started) {
throw new Exception("You must start() this class instance before deploying");
}
String queueName = queueDeployment.getName();
try (ClientSession session = sessionFactory.createSession(false, false, false)) {
ClientSession.AddressQuery query = session.addressQuery(SimpleString.toSimpleString(queueName));
if (!query.isExists()) {
session.createAddress(SimpleString.toSimpleString(queueName), RoutingType.ANYCAST, true);
session.createQueue(new QueueConfiguration(queueName).setRoutingType(RoutingType.ANYCAST).setDurable(queueDeployment.isDurableSend()));
} else {
ClientSession.QueueQuery qquery = session.queueQuery(SimpleString.toSimpleString(queueName));
if (!qquery.isExists()) {
session.createQueue(new QueueConfiguration(queueName).setRoutingType(RoutingType.ANYCAST).setDurable(queueDeployment.isDurableSend()));
}
}
}
destination.createQueueResource(queueName, queueDeployment.isDurableSend(), queueDeployment.getConsumerSessionTimeoutSeconds(), queueDeployment.isDuplicatesAllowed());
}
@Override
public void stop() {
if (started == false)
return;
for (QueueResource queue : destination.getQueues().values()) {
queue.stop();
}
try {
timeoutTask.stop();
sessionFactory.close();
} catch (Exception e) {
}
}
}

View File

@ -1,77 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.activemq.artemis.rest.queue.push;
import org.apache.activemq.artemis.api.core.client.ClientMessage;
import org.apache.activemq.artemis.rest.queue.push.xml.XmlHttpHeader;
import org.jboss.resteasy.client.ClientRequest;
import org.jboss.resteasy.client.ClientResponse;
import org.jboss.resteasy.specimpl.ResteasyUriBuilder;
import org.jboss.resteasy.spi.Link;
/**
* Forwarding to an ActiveMQ/REST-* endpoing
*/
public class ActiveMQPushStrategy extends UriTemplateStrategy {
protected boolean initialized = false;
@Override
public void start() throws Exception {
// initialize();
}
protected void initialize() throws Exception {
super.start();
initialized = true;
initAuthentication();
ClientRequest request = executor.createRequest(registration.getTarget().getHref());
for (XmlHttpHeader header : registration.getHeaders()) {
request.header(header.getName(), header.getValue());
}
ClientResponse<?> res = request.head();
if (res.getStatus() != 200) {
throw new RuntimeException("Failed to query REST destination for init information. Status: " + res.getStatus());
}
String url = (String) res.getHeaders().getFirst("msg-create-with-id");
if (url == null) {
if (res.getLinkHeader() == null) {
throw new RuntimeException("Could not find create-with-id URL");
}
Link link = res.getLinkHeader().getLinkByTitle("create-with-id");
if (link == null) {
throw new RuntimeException("Could not find create-with-id URL");
}
url = link.getHref();
}
targetUri = ResteasyUriBuilder.fromTemplate(url);
}
@Override
public boolean push(ClientMessage message) {
// we initialize lazily just in case target is in same VM
if (!initialized) {
try {
initialize();
initialized = true;
} catch (Exception e) {
throw new RuntimeException("Failed to initialize.", e);
}
}
return super.push(message);
}
}

View File

@ -1,115 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.activemq.artemis.rest.queue.push;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.activemq.artemis.rest.ActiveMQRestLogger;
import org.apache.activemq.artemis.rest.queue.push.xml.PushRegistration;
import org.apache.activemq.artemis.rest.topic.PushTopicRegistration;
public class FilePushStore implements PushStore {
protected Map<String, PushRegistration> map = new HashMap<>();
protected File dir;
protected JAXBContext ctx;
public FilePushStore(String dirname) throws Exception {
this.dir = new File(dirname);
this.ctx = JAXBContext.newInstance(PushRegistration.class, PushTopicRegistration.class);
if (this.dir.exists()) {
ActiveMQRestLogger.LOGGER.loadingRestStore(dir.getAbsolutePath());
for (File file : this.dir.listFiles()) {
if (!file.isFile())
continue;
PushRegistration reg = null;
try {
reg = (PushRegistration) ctx.createUnmarshaller().unmarshal(file);
reg.setLoadedFrom(file);
ActiveMQRestLogger.LOGGER.addingPushRegistration(reg.getId());
map.put(reg.getId(), reg);
} catch (Exception e) {
ActiveMQRestLogger.LOGGER.errorLoadingStore(e, file.getName());
}
}
}
}
public synchronized List<PushRegistration> getRegistrations() {
List<PushRegistration> list = new ArrayList<>(map.values());
return list;
}
@Override
public synchronized List<PushRegistration> getByDestination(String destination) {
List<PushRegistration> list = new ArrayList<>();
for (PushRegistration reg : map.values()) {
if (reg.getDestination().equals(destination)) {
list.add(reg);
}
}
return list;
}
@Override
public synchronized void update(PushRegistration reg) throws Exception {
if (reg.getLoadedFrom() == null)
return;
save(reg);
}
protected void save(PushRegistration reg) throws JAXBException {
Marshaller marshaller = ctx.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
marshaller.marshal(reg, (File) reg.getLoadedFrom());
}
@Override
public synchronized void add(PushRegistration reg) throws Exception {
map.put(reg.getId(), reg);
if (!this.dir.exists())
this.dir.mkdirs();
File fp = new File(dir, "reg-" + reg.getId() + ".xml");
reg.setLoadedFrom(fp);
//System.out.println("******* Saving: " + fp.getAbsolutePath());
save(reg);
}
@Override
public synchronized void remove(PushRegistration reg) throws Exception {
map.remove(reg.getId());
if (reg.getLoadedFrom() == null)
return;
File fp = (File) reg.getLoadedFrom();
fp.delete();
}
@Override
public synchronized void removeAll() throws Exception {
ArrayList<PushRegistration> copy = new ArrayList<>(map.values());
for (PushRegistration reg : copy)
remove(reg);
this.dir.delete();
}
}

View File

@ -1,140 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.activemq.artemis.rest.queue.push;
import java.util.ArrayList;
import java.util.List;
import org.apache.activemq.artemis.api.core.ActiveMQException;
import org.apache.activemq.artemis.api.core.client.ClientConsumer;
import org.apache.activemq.artemis.api.core.client.ClientSession;
import org.apache.activemq.artemis.api.core.client.ClientSessionFactory;
import org.apache.activemq.artemis.jms.client.ConnectionFactoryOptions;
import org.apache.activemq.artemis.rest.ActiveMQRestLogger;
import org.apache.activemq.artemis.rest.queue.push.xml.PushRegistration;
import org.apache.activemq.artemis.utils.SelectorTranslator;
public class PushConsumer {
protected PushRegistration registration;
protected ClientSessionFactory factory;
protected List<ClientSession> sessions;
protected List<ClientConsumer> consumers;
protected String destination;
protected String id;
protected PushStrategy strategy;
protected PushStore store;
private ConnectionFactoryOptions jmsOptions;
public PushConsumer(ClientSessionFactory factory,
String destination,
String id,
PushRegistration registration,
PushStore store,
ConnectionFactoryOptions jmsOptions) {
this.factory = factory;
this.destination = destination;
this.id = id;
this.registration = registration;
this.store = store;
this.jmsOptions = jmsOptions;
}
public PushStrategy getStrategy() {
return strategy;
}
public PushRegistration getRegistration() {
return registration;
}
public String getDestination() {
return destination;
}
public void start() throws Exception {
if (registration.getTarget().getClassName() != null) {
Class clazz = Thread.currentThread().getContextClassLoader().loadClass(registration.getTarget().getClassName());
strategy = (PushStrategy) clazz.newInstance();
} else if (registration.getTarget().getRelationship() != null) {
if (registration.getTarget().getRelationship().equals("destination")) {
strategy = new ActiveMQPushStrategy();
} else if (registration.getTarget().getRelationship().equals("template")) {
strategy = new UriTemplateStrategy();
}
}
if (strategy == null) {
strategy = new UriStrategy();
}
strategy.setRegistration(registration);
strategy.setJmsOptions(jmsOptions);
strategy.start();
sessions = new ArrayList<>();
consumers = new ArrayList<>();
for (int i = 0; i < registration.getSessionCount(); i++) {
ClientSession session = factory.createSession(false, false, 0);
ClientConsumer consumer;
if (registration.getSelector() != null) {
consumer = session.createConsumer(destination, SelectorTranslator.convertToActiveMQFilterString(registration.getSelector()));
} else {
consumer = session.createConsumer(destination);
}
consumer.setMessageHandler(new PushConsumerMessageHandler(this, session));
session.start();
ActiveMQRestLogger.LOGGER.startingPushConsumer(registration.getTarget());
consumers.add(consumer);
sessions.add(session);
}
}
public void stop() {
for (ClientSession session : sessions) {
try {
if (session != null) {
session.close();
}
} catch (ActiveMQException e) {
}
}
try {
if (strategy != null) {
strategy.stop();
}
} catch (Exception e) {
}
}
public void disableFromFailure() {
registration.setEnabled(false);
try {
if (registration.isDurable()) {
store.update(registration);
}
} catch (Exception e) {
ActiveMQRestLogger.LOGGER.errorUpdatingStore(e);
}
stop();
}
}

View File

@ -1,70 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.activemq.artemis.rest.queue.push;
import org.apache.activemq.artemis.api.core.ActiveMQException;
import org.apache.activemq.artemis.api.core.client.ClientMessage;
import org.apache.activemq.artemis.api.core.client.ClientSession;
import org.apache.activemq.artemis.api.core.client.MessageHandler;
import org.apache.activemq.artemis.rest.ActiveMQRestLogger;
public class PushConsumerMessageHandler implements MessageHandler {
private ClientSession session;
private PushConsumer pushConsumer;
PushConsumerMessageHandler(PushConsumer pushConsumer, ClientSession session) {
this.pushConsumer = pushConsumer;
this.session = session;
}
@Override
public void onMessage(ClientMessage clientMessage) {
ActiveMQRestLogger.LOGGER.debug(this + ": receiving " + clientMessage);
try {
clientMessage.acknowledge();
ActiveMQRestLogger.LOGGER.debug(this + ": acknowledged " + clientMessage);
} catch (ActiveMQException e) {
throw new RuntimeException(e.getMessage(), e);
}
ActiveMQRestLogger.LOGGER.debug(this + ": pushing " + clientMessage + " via " + pushConsumer.getStrategy());
boolean acknowledge = pushConsumer.getStrategy().push(clientMessage);
if (acknowledge) {
try {
ActiveMQRestLogger.LOGGER.debug("Acknowledging: " + clientMessage.getMessageID());
session.commit();
return;
} catch (ActiveMQException e) {
throw new RuntimeException(e);
}
} else {
try {
session.rollback();
} catch (ActiveMQException e) {
throw new RuntimeException(e.getMessage(), e);
}
if (pushConsumer.getRegistration().isDisableOnFailure()) {
ActiveMQRestLogger.LOGGER.errorPushingMessage(pushConsumer.getRegistration().getTarget());
pushConsumer.disableFromFailure();
return;
}
}
}
}

View File

@ -1,151 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.activemq.artemis.rest.queue.push;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriBuilder;
import javax.ws.rs.core.UriInfo;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicLong;
import org.apache.activemq.artemis.api.core.client.ClientSessionFactory;
import org.apache.activemq.artemis.jms.client.ConnectionFactoryOptions;
import org.apache.activemq.artemis.rest.ActiveMQRestLogger;
import org.apache.activemq.artemis.rest.queue.push.xml.PushRegistration;
public class PushConsumerResource {
protected Map<String, PushConsumer> consumers = new ConcurrentHashMap<>();
protected ClientSessionFactory sessionFactory;
protected String destination;
protected final String startup = Long.toString(System.currentTimeMillis());
protected final AtomicLong sessionCounter = new AtomicLong(1);
protected PushStore pushStore;
private ConnectionFactoryOptions jmsOptions;
public void start() {
}
public void stop() {
for (PushConsumer consumer : consumers.values()) {
consumer.stop();
}
}
public PushStore getPushStore() {
return pushStore;
}
public void setPushStore(PushStore pushStore) {
this.pushStore = pushStore;
}
public void addRegistration(PushRegistration reg) throws Exception {
if (reg.isEnabled() == false)
return;
PushConsumer consumer = new PushConsumer(sessionFactory, destination, reg.getId(), reg, pushStore, jmsOptions);
consumer.start();
consumers.put(reg.getId(), consumer);
}
@POST
@Consumes("application/xml")
public Response create(@Context UriInfo uriInfo, PushRegistration registration) {
ActiveMQRestLogger.LOGGER.debug("Handling POST request for \"" + uriInfo.getPath() + "\"");
// todo put some logic here to check for duplicates
String genId = sessionCounter.getAndIncrement() + "-" + startup;
registration.setId(genId);
registration.setDestination(destination);
PushConsumer consumer = new PushConsumer(sessionFactory, destination, genId, registration, pushStore, jmsOptions);
try {
consumer.start();
if (registration.isDurable() && pushStore != null) {
pushStore.add(registration);
}
} catch (Exception e) {
consumer.stop();
throw new WebApplicationException(e, Response.serverError().entity("Failed to start consumer.").type("text/plain").build());
}
consumers.put(genId, consumer);
UriBuilder location = uriInfo.getAbsolutePathBuilder();
location.path(genId);
return Response.created(location.build()).build();
}
@GET
@Path("{consumer-id}")
@Produces("application/xml")
public PushRegistration getConsumer(@Context UriInfo uriInfo, @PathParam("consumer-id") String consumerId) {
ActiveMQRestLogger.LOGGER.debug("Handling GET request for \"" + uriInfo.getPath() + "\"");
PushConsumer consumer = consumers.get(consumerId);
if (consumer == null) {
throw new WebApplicationException(Response.status(404).entity("Could not find consumer.").type("text/plain").build());
}
return consumer.getRegistration();
}
@DELETE
@Path("{consumer-id}")
public void deleteConsumer(@Context UriInfo uriInfo, @PathParam("consumer-id") String consumerId) {
ActiveMQRestLogger.LOGGER.debug("Handling DELETE request for \"" + uriInfo.getPath() + "\"");
PushConsumer consumer = consumers.remove(consumerId);
if (consumer == null) {
throw new WebApplicationException(Response.status(404).entity("Could not find consumer.").type("text/plain").build());
}
consumer.stop();
}
public Map<String, PushConsumer> getConsumers() {
return consumers;
}
public ClientSessionFactory getSessionFactory() {
return sessionFactory;
}
public void setSessionFactory(ClientSessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
public String getDestination() {
return destination;
}
public void setDestination(String destination) {
this.destination = destination;
}
public void setJmsOptions(ConnectionFactoryOptions jmsOptions) {
this.jmsOptions = jmsOptions;
}
}

View File

@ -1,34 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.activemq.artemis.rest.queue.push;
import java.util.List;
import org.apache.activemq.artemis.rest.queue.push.xml.PushRegistration;
public interface PushStore {
void add(PushRegistration reg) throws Exception;
void remove(PushRegistration reg) throws Exception;
List<PushRegistration> getByDestination(String destination);
void update(PushRegistration reg) throws Exception;
void removeAll() throws Exception;
}

View File

@ -1,42 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.activemq.artemis.rest.queue.push;
import org.apache.activemq.artemis.api.core.client.ClientMessage;
import org.apache.activemq.artemis.jms.client.ConnectionFactoryOptions;
import org.apache.activemq.artemis.rest.queue.push.xml.PushRegistration;
public interface PushStrategy {
/**
* Return false if unable to connect. Push consumer may be disabled if configured to do so when
* unable to connect. Throw an exception if the message sent was unaccepted by the receiver.
* ActiveMQ's retry and dead letter logic will take over from there.
*
* @param message
* @return {@code false} if unable to connect
*/
boolean push(ClientMessage message);
void setRegistration(PushRegistration reg);
void start() throws Exception;
void stop() throws Exception;
void setJmsOptions(ConnectionFactoryOptions jmsOptions);
}

View File

@ -1,220 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.activemq.artemis.rest.queue.push;
import javax.ws.rs.core.UriBuilder;
import java.io.IOException;
import org.apache.activemq.artemis.api.core.client.ClientMessage;
import org.apache.activemq.artemis.jms.client.ConnectionFactoryOptions;
import org.apache.activemq.artemis.rest.ActiveMQRestLogger;
import org.apache.activemq.artemis.rest.queue.push.xml.BasicAuth;
import org.apache.activemq.artemis.rest.queue.push.xml.PushRegistration;
import org.apache.activemq.artemis.rest.queue.push.xml.XmlHttpHeader;
import org.apache.activemq.artemis.rest.util.HttpMessageHelper;
import org.apache.http.HttpException;
import org.apache.http.HttpHost;
import org.apache.http.HttpRequest;
import org.apache.http.HttpRequestInterceptor;
import org.apache.http.auth.AuthScheme;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.AuthState;
import org.apache.http.auth.Credentials;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.client.HttpClient;
import org.apache.http.client.protocol.HttpClientContext;
import org.apache.http.impl.auth.BasicScheme;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
import org.apache.http.protocol.BasicHttpContext;
import org.apache.http.protocol.HttpContext;
import org.apache.http.protocol.HttpCoreContext;
import org.jboss.resteasy.client.ClientRequest;
import org.jboss.resteasy.client.ClientResponse;
import org.jboss.resteasy.client.core.executors.ApacheHttpClient4Executor;
import org.jboss.resteasy.specimpl.ResteasyUriBuilder;
public class UriStrategy implements PushStrategy {
ThreadSafeClientConnManager connManager = new ThreadSafeClientConnManager();
protected HttpClient client = new DefaultHttpClient(connManager);
protected BasicHttpContext localContext;
protected ApacheHttpClient4Executor executor = new ApacheHttpClient4Executor(client);
protected PushRegistration registration;
protected UriBuilder targetUri;
protected String method;
protected String contentType;
protected ConnectionFactoryOptions jmsOptions;
UriStrategy() {
connManager.setDefaultMaxPerRoute(100);
connManager.setMaxTotal(1000);
}
@Override
public void setRegistration(PushRegistration reg) {
this.registration = reg;
}
@Override
public void start() throws Exception {
initAuthentication();
method = registration.getTarget().getMethod();
if (method == null)
method = "POST";
contentType = registration.getTarget().getType();
targetUri = ResteasyUriBuilder.fromTemplate(registration.getTarget().getHref());
}
protected void initAuthentication() {
if (registration.getAuthenticationMechanism() != null) {
if (registration.getAuthenticationMechanism().getType() instanceof BasicAuth) {
BasicAuth basic = (BasicAuth) registration.getAuthenticationMechanism().getType();
UsernamePasswordCredentials creds = new UsernamePasswordCredentials(basic.getUsername(), basic.getPassword());
AuthScope authScope = new AuthScope(AuthScope.ANY);
((DefaultHttpClient) client).getCredentialsProvider().setCredentials(authScope, creds);
localContext = new BasicHttpContext();
// Generate BASIC scheme object and stick it to the local execution context
BasicScheme basicAuth = new BasicScheme();
localContext.setAttribute("preemptive-auth", basicAuth);
// Add as the first request interceptor
((DefaultHttpClient) client).addRequestInterceptor(new PreemptiveAuth(), 0);
executor.setHttpContext(localContext);
}
}
}
@Override
public void stop() {
connManager.shutdown();
}
@Override
public void setJmsOptions(ConnectionFactoryOptions jmsOptions) {
this.jmsOptions = jmsOptions;
}
@Override
public boolean push(ClientMessage message) {
ActiveMQRestLogger.LOGGER.debug("Pushing " + message);
String uri = createUri(message);
for (int i = 0; i < registration.getMaxRetries(); i++) {
long wait = registration.getRetryWaitMillis();
System.out.println("Creating request from " + uri);
ClientRequest request = executor.createRequest(uri);
request.followRedirects(false);
ActiveMQRestLogger.LOGGER.debug("Created request " + request);
for (XmlHttpHeader header : registration.getHeaders()) {
ActiveMQRestLogger.LOGGER.debug("Setting XmlHttpHeader: " + header.getName() + "=" + header.getValue());
request.header(header.getName(), header.getValue());
}
HttpMessageHelper.buildMessage(message, request, contentType, jmsOptions);
ClientResponse<?> res = null;
try {
ActiveMQRestLogger.LOGGER.debug(method + " " + uri);
res = request.httpMethod(method);
int status = res.getStatus();
ActiveMQRestLogger.LOGGER.debug("Status of push: " + status);
if (status == 503) {
String retryAfter = res.getStringHeaders().getFirst("Retry-After");
if (retryAfter != null) {
wait = Long.parseLong(retryAfter) * 1000;
}
} else if (status == 307) {
uri = res.getLocation().toString();
wait = 0;
} else if ((status >= 200 && status < 299) || status == 303 || status == 304) {
ActiveMQRestLogger.LOGGER.debug("Success");
return true;
} else if (status >= 400) {
switch (status) {
case 400: // these usually mean the message you are trying to send is crap, let dead letter logic take over
case 411:
case 412:
case 413:
case 414:
case 415:
case 416:
throw new RuntimeException("Something is wrong with the message, status returned: " + status + " for push registration of URI: " + uri);
case 401: // might as well consider these critical failures and abort. Immediately signal to disable push registration depending on config
case 402:
case 403:
case 405:
case 406:
case 407:
case 417:
case 505:
return false;
case 404: // request timeout, gone, and not found treat as a retry
case 408:
case 409:
case 410:
break;
default: // all 50x requests just retry (except 505)
break;
}
}
} catch (Exception e) {
ActiveMQRestLogger.LOGGER.failedToPushMessageToUri(uri, e);
return false;
} finally {
if (res != null)
res.releaseConnection();
}
try {
if (wait > 0)
Thread.sleep(wait);
} catch (InterruptedException e) {
throw new RuntimeException("Interrupted");
}
}
return false;
}
protected String createUri(ClientMessage message) {
String uri = targetUri.build().toString();
return uri;
}
static class PreemptiveAuth implements HttpRequestInterceptor {
@Override
public void process(final HttpRequest request, final HttpContext context) throws HttpException, IOException {
AuthState authState = (AuthState) context.getAttribute(HttpClientContext.TARGET_AUTH_STATE);
// If no auth scheme available yet, try to initialize it preemptively
if (authState.getAuthScheme() == null) {
AuthScheme authScheme = (AuthScheme) context.getAttribute("preemptive-auth");
CredentialsProvider credsProvider = (CredentialsProvider) context.getAttribute(HttpClientContext.CREDS_PROVIDER);
HttpHost targetHost = (HttpHost) context.getAttribute(HttpCoreContext.HTTP_TARGET_HOST);
if (authScheme != null) {
Credentials creds = credsProvider.getCredentials(new AuthScope(targetHost.getHostName(), targetHost.getPort()));
if (creds == null) {
throw new HttpException("No credentials for preemptive authentication");
}
authState.update(authScheme, creds);
}
}
}
}
}

View File

@ -1,29 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.activemq.artemis.rest.queue.push;
import org.apache.activemq.artemis.api.core.client.ClientMessage;
public class UriTemplateStrategy extends UriStrategy {
@Override
protected String createUri(ClientMessage message) {
String dupId = registration.getId() + "-" + message.getMessageID() + "-" + message.getTimestamp();
String uri = targetUri.build(dupId).toString();
return uri;
}
}

View File

@ -1,47 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.activemq.artemis.rest.queue.push.xml;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElementRef;
import javax.xml.bind.annotation.XmlRootElement;
import java.io.Serializable;
@XmlRootElement
@XmlAccessorType(XmlAccessType.PROPERTY)
public class Authentication implements Serializable {
private static final long serialVersionUID = -6218446923598032634L;
private AuthenticationType type;
@XmlElementRef
public AuthenticationType getType() {
return type;
}
public void setType(AuthenticationType type) {
this.type = type;
}
@Override
public String toString() {
return "Authentication{" +
"type=" + type +
'}';
}
}

View File

@ -1,26 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.activemq.artemis.rest.queue.push.xml;
import javax.xml.bind.annotation.XmlSeeAlso;
import java.io.Serializable;
@XmlSeeAlso({BasicAuth.class, DigestAuth.class})
public class AuthenticationType implements Serializable {
private static final long serialVersionUID = -4856752055689300045L;
}

View File

@ -1,53 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.activemq.artemis.rest.queue.push.xml;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
@XmlRootElement(name = "basic-auth")
@XmlType(propOrder = {"username", "password"})
public class BasicAuth extends AuthenticationType {
private static final long serialVersionUID = 2052716241089832934L;
private String username;
private String password;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@Override
public String toString() {
return "BasicAuth{" +
"username='" + username + '\'' +
", password='" + password + '\'' +
'}';
}
}

View File

@ -1,25 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.activemq.artemis.rest.queue.push.xml;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement(name = "digest")
public class DigestAuth extends BasicAuth {
private static final long serialVersionUID = 1857805131477468686L;
}

View File

@ -1,184 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.activemq.artemis.rest.queue.push.xml;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementRef;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlTransient;
import javax.xml.bind.annotation.XmlType;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
@XmlRootElement(name = "push-registration")
@XmlAccessorType(XmlAccessType.PROPERTY)
@XmlType(propOrder = {"enabled", "destination", "durable", "selector", "target", "maxRetries", "retryWaitMillis", "disableOnFailure", "authenticationMechanism", "headers", "sessionCount"})
public class PushRegistration implements Serializable {
private static final long serialVersionUID = -2749818399978544262L;
private String id;
private boolean durable;
private XmlLink target;
private Authentication authenticationMechanism;
private List<XmlHttpHeader> headers = new ArrayList<>();
private String destination;
private Object loadedFrom;
private String selector;
private long retryWaitMillis = 1000;
private boolean disableOnFailure;
private int maxRetries = 10;
private boolean enabled = true;
private int sessionCount = 1;
@XmlElement
public int getMaxRetries() {
return maxRetries;
}
public void setMaxRetries(int maxRetries) {
this.maxRetries = maxRetries;
}
@XmlElement
public long getRetryWaitMillis() {
return retryWaitMillis;
}
public void setRetryWaitMillis(long retryWaitMillis) {
this.retryWaitMillis = retryWaitMillis;
}
@XmlElement
public boolean isDisableOnFailure() {
return disableOnFailure;
}
public void setDisableOnFailure(boolean disableOnFailure) {
this.disableOnFailure = disableOnFailure;
}
@XmlElement
public boolean isEnabled() {
return enabled;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
@XmlTransient
public Object getLoadedFrom() {
return loadedFrom;
}
public void setLoadedFrom(Object loadedFrom) {
this.loadedFrom = loadedFrom;
}
@XmlAttribute
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
@XmlElement
public String getDestination() {
return destination;
}
public void setDestination(String destination) {
this.destination = destination;
}
@XmlElement
public boolean isDurable() {
return durable;
}
public void setDurable(boolean durable) {
this.durable = durable;
}
public String getSelector() {
return selector;
}
public void setSelector(String selector) {
this.selector = selector;
}
@XmlElementRef
public XmlLink getTarget() {
return target;
}
public void setTarget(XmlLink target) {
this.target = target;
}
@XmlElementRef
public Authentication getAuthenticationMechanism() {
return authenticationMechanism;
}
public void setAuthenticationMechanism(Authentication authenticationMechanism) {
this.authenticationMechanism = authenticationMechanism;
}
@XmlElementRef
public List<XmlHttpHeader> getHeaders() {
return headers;
}
public void setHeaders(List<XmlHttpHeader> headers) {
this.headers = headers;
}
@XmlElement
public int getSessionCount() {
return sessionCount;
}
public void setSessionCount(int sessionCount) {
this.sessionCount = sessionCount;
}
@Override
public String toString() {
return "PushRegistration{" +
"id='" + id + '\'' +
", durable=" + durable +
", target=" + target +
", authenticationMechanism=" + authenticationMechanism +
", headers=" + headers +
", destination='" + destination + '\'' +
", selector='" + selector + '\'' +
", retryWaitMillis=" + retryWaitMillis +
", disableOnFailure=" + disableOnFailure +
", maxRetries=" + maxRetries +
", sessionCount=" + sessionCount +
", enabled=" + enabled +
'}';
}
}

View File

@ -1,59 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.activemq.artemis.rest.queue.push.xml;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlValue;
import java.io.Serializable;
@XmlRootElement(name = "header")
@XmlAccessorType(XmlAccessType.PROPERTY)
public class XmlHttpHeader implements Serializable {
private static final long serialVersionUID = -3900391946161818601L;
private String name;
private String value;
@XmlAttribute
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@XmlValue
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
@Override
public String toString() {
return "XmlHttpHeader{" +
"name='" + name + '\'' +
", value='" + value + '\'' +
'}';
}
}

View File

@ -1,91 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.activemq.artemis.rest.queue.push.xml;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlRootElement;
import java.io.Serializable;
@XmlRootElement(name = "link")
@XmlAccessorType(XmlAccessType.PROPERTY)
public class XmlLink implements Serializable {
private static final long serialVersionUID = -6517264072911034419L;
protected String method;
protected String className;
protected String rel;
protected String type;
protected String href;
@XmlAttribute(name = "class")
public String getClassName() {
return className;
}
public void setClassName(String className) {
this.className = className;
}
@XmlAttribute
public String getMethod() {
return method;
}
public void setMethod(String method) {
this.method = method;
}
@XmlAttribute(name = "rel")
public String getRelationship() {
return rel;
}
public void setRelationship(String relationship) {
rel = relationship;
}
@XmlAttribute
public String getHref() {
return href;
}
public void setHref(String href) {
this.href = href;
}
@XmlAttribute
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
@Override
public String toString() {
return "XmlLink{" +
"className='" + className + '\'' +
", rel='" + rel + '\'' +
", href='" + href + '\'' +
", type='" + type + '\'' +
", method='" + method + '\'' +
'}';
}
}

View File

@ -1,71 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.activemq.artemis.rest.topic;
import org.apache.activemq.artemis.api.core.ActiveMQException;
import org.apache.activemq.artemis.api.core.client.ClientSessionFactory;
import org.apache.activemq.artemis.rest.queue.AcknowledgedQueueConsumer;
import org.apache.activemq.artemis.rest.queue.DestinationServiceManager;
public class AcknowledgedSubscriptionResource extends AcknowledgedQueueConsumer implements Subscription {
private boolean durable;
private long timeout;
private boolean deleteWhenIdle;
public AcknowledgedSubscriptionResource(ClientSessionFactory factory,
String destination,
String id,
DestinationServiceManager serviceManager,
String selector,
boolean durable,
Long timeout) throws ActiveMQException {
super(factory, destination, id, serviceManager, selector);
this.timeout = timeout;
this.durable = durable;
}
@Override
public boolean isDurable() {
return durable;
}
@Override
public void setDurable(boolean durable) {
this.durable = durable;
}
@Override
public long getTimeout() {
return timeout;
}
@Override
public void setTimeout(long timeout) {
this.timeout = timeout;
}
@Override
public boolean isDeleteWhenIdle() {
return deleteWhenIdle;
}
@Override
public void setDeleteWhenIdle(boolean deleteWhenIdle) {
this.deleteWhenIdle = deleteWhenIdle;
}
}

View File

@ -1,42 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.activemq.artemis.rest.topic;
import java.util.ArrayList;
import java.util.List;
import org.apache.activemq.artemis.rest.queue.push.FilePushStore;
import org.apache.activemq.artemis.rest.queue.push.xml.PushRegistration;
class FileTopicPushStore extends FilePushStore implements TopicPushStore {
FileTopicPushStore(String dirname) throws Exception {
super(dirname);
}
@Override
public synchronized List<PushTopicRegistration> getByTopic(String topic) {
List<PushTopicRegistration> list = new ArrayList<>();
for (PushRegistration reg : map.values()) {
PushTopicRegistration topicReg = (PushTopicRegistration) reg;
if (topicReg.getTopic().equals(topic)) {
list.add(topicReg);
}
}
return list;
}
}

View File

@ -1,63 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.activemq.artemis.rest.topic;
import org.apache.activemq.artemis.api.core.ActiveMQException;
import org.apache.activemq.artemis.api.core.client.ClientSession;
import org.apache.activemq.artemis.api.core.client.ClientSessionFactory;
import org.apache.activemq.artemis.jms.client.ConnectionFactoryOptions;
import org.apache.activemq.artemis.rest.ActiveMQRestLogger;
import org.apache.activemq.artemis.rest.queue.push.PushConsumer;
import org.apache.activemq.artemis.rest.queue.push.PushStore;
import org.apache.activemq.artemis.rest.queue.push.xml.PushRegistration;
public class PushSubscription extends PushConsumer {
public PushSubscription(ClientSessionFactory factory,
String destination,
String id,
PushRegistration registration,
PushStore store,
ConnectionFactoryOptions jmsOptions) {
super(factory, destination, id, registration, store, jmsOptions);
}
@Override
public void disableFromFailure() {
super.disableFromFailure();
if (registration.isDurable())
deleteSubscriberQueue();
}
protected void deleteSubscriberQueue() {
String subscriptionName = registration.getDestination();
ClientSession session = null;
try {
session = factory.createSession();
session.deleteQueue(subscriptionName);
} catch (ActiveMQException e) {
ActiveMQRestLogger.LOGGER.errorDeletingSubscriberQueue(e);
} finally {
try {
if (session != null)
session.close();
} catch (ActiveMQException e) {
}
}
}
}

View File

@ -1,213 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.activemq.artemis.rest.topic;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriBuilder;
import javax.ws.rs.core.UriInfo;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicLong;
import org.apache.activemq.artemis.api.core.ActiveMQException;
import org.apache.activemq.artemis.api.core.QueueConfiguration;
import org.apache.activemq.artemis.api.core.SimpleString;
import org.apache.activemq.artemis.api.core.client.ClientSession;
import org.apache.activemq.artemis.api.core.client.ClientSessionFactory;
import org.apache.activemq.artemis.jms.client.ConnectionFactoryOptions;
import org.apache.activemq.artemis.rest.ActiveMQRestLogger;
import org.apache.activemq.artemis.rest.queue.push.PushConsumer;
public class PushSubscriptionsResource {
protected Map<String, PushSubscription> consumers = new ConcurrentHashMap<>();
protected ClientSessionFactory sessionFactory;
protected String destination;
protected final String startup = Long.toString(System.currentTimeMillis());
protected final AtomicLong sessionCounter = new AtomicLong(1);
protected TopicPushStore pushStore;
private ConnectionFactoryOptions jmsOptions;
public PushSubscriptionsResource(ConnectionFactoryOptions jmsOptions) {
this.jmsOptions = jmsOptions;
}
public void stop() {
for (PushConsumer consumer : consumers.values()) {
consumer.stop();
if (consumer.getRegistration().isDurable() == false) {
deleteSubscriberQueue(consumer);
}
}
}
public TopicPushStore getPushStore() {
return pushStore;
}
public void setPushStore(TopicPushStore pushStore) {
this.pushStore = pushStore;
}
public ClientSession createSubscription(String subscriptionName, boolean durable) {
ClientSession session = null;
try {
session = sessionFactory.createSession();
session.createQueue(new QueueConfiguration(subscriptionName).setAddress(destination).setDurable(durable).setTemporary(!durable));
return session;
} catch (ActiveMQException e) {
throw new RuntimeException(e);
}
}
public void addRegistration(PushTopicRegistration reg) throws Exception {
if (reg.isEnabled() == false)
return;
String destination = reg.getDestination();
ClientSession session = sessionFactory.createSession(false, false, false);
ClientSession.QueueQuery query = session.queueQuery(new SimpleString(destination));
ClientSession createSession = null;
if (!query.isExists()) {
createSession = createSubscription(destination, reg.isDurable());
}
PushSubscription consumer = new PushSubscription(sessionFactory, reg.getDestination(), reg.getId(), reg, pushStore, jmsOptions);
try {
consumer.start();
} catch (Exception e) {
consumer.stop();
throw new Exception("Failed starting push subscriber for " + destination + " of push subscriber: " + reg.getTarget(), e);
} finally {
closeSession(createSession);
closeSession(session);
}
consumers.put(reg.getId(), consumer);
}
private void closeSession(ClientSession createSession) {
if (createSession != null) {
try {
createSession.close();
} catch (ActiveMQException e) {
}
}
}
@POST
public Response create(@Context UriInfo uriInfo, PushTopicRegistration registration) {
ActiveMQRestLogger.LOGGER.debug("Handling POST request for \"" + uriInfo.getPath() + "\"");
//System.out.println("PushRegistration: " + registration);
// todo put some logic here to check for duplicates
String genId = sessionCounter.getAndIncrement() + "-topic-" + destination + "-" + startup;
if (registration.getDestination() == null) {
registration.setDestination(genId);
}
registration.setId(genId);
registration.setTopic(destination);
ClientSession createSession = createSubscription(genId, registration.isDurable());
try {
PushSubscription consumer = new PushSubscription(sessionFactory, genId, genId, registration, pushStore, jmsOptions);
try {
consumer.start();
if (registration.isDurable() && pushStore != null) {
pushStore.add(registration);
}
} catch (Exception e) {
consumer.stop();
throw new WebApplicationException(e, Response.serverError().entity("Failed to start consumer.").type("text/plain").build());
}
consumers.put(genId, consumer);
UriBuilder location = uriInfo.getAbsolutePathBuilder();
location.path(genId);
return Response.created(location.build()).build();
} finally {
closeSession(createSession);
}
}
@GET
@Path("{consumer-id}")
@Produces("application/xml")
public PushTopicRegistration getConsumer(@Context UriInfo uriInfo, @PathParam("consumer-id") String consumerId) {
ActiveMQRestLogger.LOGGER.debug("Handling GET request for \"" + uriInfo.getPath() + "\"");
PushConsumer consumer = consumers.get(consumerId);
if (consumer == null) {
throw new WebApplicationException(Response.status(404).entity("Could not find consumer.").type("text/plain").build());
}
return (PushTopicRegistration) consumer.getRegistration();
}
@DELETE
@Path("{consumer-id}")
public void deleteConsumer(@Context UriInfo uriInfo, @PathParam("consumer-id") String consumerId) {
ActiveMQRestLogger.LOGGER.debug("Handling DELETE request for \"" + uriInfo.getPath() + "\"");
PushConsumer consumer = consumers.remove(consumerId);
if (consumer == null) {
throw new WebApplicationException(Response.status(404).entity("Could not find consumer.").type("text/plain").build());
}
consumer.stop();
deleteSubscriberQueue(consumer);
}
public Map<String, PushSubscription> getConsumers() {
return consumers;
}
public ClientSessionFactory getSessionFactory() {
return sessionFactory;
}
public void setSessionFactory(ClientSessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
public String getDestination() {
return destination;
}
public void setDestination(String destination) {
this.destination = destination;
}
private void deleteSubscriberQueue(PushConsumer consumer) {
String subscriptionName = consumer.getDestination();
ClientSession session = null;
try {
session = sessionFactory.createSession();
session.deleteQueue(subscriptionName);
} catch (ActiveMQException e) {
} finally {
closeSession(session);
}
}
}

View File

@ -1,43 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.activemq.artemis.rest.topic;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
import org.apache.activemq.artemis.rest.queue.push.xml.PushRegistration;
@XmlRootElement(name = "push-topic-registration")
@XmlAccessorType(XmlAccessType.PROPERTY)
@XmlType(propOrder = {"topic"})
public class PushTopicRegistration extends PushRegistration {
private static final long serialVersionUID = -2526239344680405891L;
private String topic;
@XmlElement
public String getTopic() {
return topic;
}
public void setTopic(String topic) {
this.topic = topic;
}
}

View File

@ -1,32 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.activemq.artemis.rest.topic;
public interface Subscription {
boolean isDurable();
void setDurable(boolean isDurable);
long getTimeout();
void setTimeout(long timeout);
boolean isDeleteWhenIdle();
void setDeleteWhenIdle(boolean deleteWhenIdle);
}

View File

@ -1,71 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.activemq.artemis.rest.topic;
import org.apache.activemq.artemis.api.core.ActiveMQException;
import org.apache.activemq.artemis.api.core.client.ClientSessionFactory;
import org.apache.activemq.artemis.rest.queue.DestinationServiceManager;
import org.apache.activemq.artemis.rest.queue.QueueConsumer;
public class SubscriptionResource extends QueueConsumer implements Subscription {
protected boolean durable;
protected long timeout;
private boolean deleteWhenIdle;
public SubscriptionResource(ClientSessionFactory factory,
String destination,
String id,
DestinationServiceManager serviceManager,
String selector,
boolean durable,
long timeout) throws ActiveMQException {
super(factory, destination, id, serviceManager, selector);
this.durable = durable;
this.timeout = timeout;
}
@Override
public boolean isDurable() {
return durable;
}
@Override
public void setDurable(boolean durable) {
this.durable = durable;
}
@Override
public long getTimeout() {
return timeout;
}
@Override
public void setTimeout(long timeout) {
this.timeout = timeout;
}
@Override
public boolean isDeleteWhenIdle() {
return deleteWhenIdle;
}
@Override
public void setDeleteWhenIdle(boolean deleteWhenIdle) {
this.deleteWhenIdle = deleteWhenIdle;
}
}

View File

@ -1,423 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.activemq.artemis.rest.topic;
import javax.ws.rs.DELETE;
import javax.ws.rs.DefaultValue;
import javax.ws.rs.FormParam;
import javax.ws.rs.GET;
import javax.ws.rs.HEAD;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriBuilder;
import javax.ws.rs.core.UriInfo;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.atomic.AtomicLong;
import org.apache.activemq.artemis.api.core.ActiveMQException;
import org.apache.activemq.artemis.api.core.QueueConfiguration;
import org.apache.activemq.artemis.api.core.SimpleString;
import org.apache.activemq.artemis.api.core.client.ClientSession;
import org.apache.activemq.artemis.api.core.client.ClientSessionFactory;
import org.apache.activemq.artemis.rest.ActiveMQRestLogger;
import org.apache.activemq.artemis.rest.queue.AcknowledgedQueueConsumer;
import org.apache.activemq.artemis.rest.queue.Acknowledgement;
import org.apache.activemq.artemis.rest.queue.DestinationServiceManager;
import org.apache.activemq.artemis.rest.queue.QueueConsumer;
import org.apache.activemq.artemis.rest.util.TimeoutTask;
public class SubscriptionsResource implements TimeoutTask.Callback {
protected ConcurrentMap<String, QueueConsumer> queueConsumers = new ConcurrentHashMap<>();
protected ClientSessionFactory sessionFactory;
protected String destination;
protected final String startup = Long.toString(System.currentTimeMillis());
protected AtomicLong sessionCounter = new AtomicLong(1);
protected int consumerTimeoutSeconds;
protected DestinationServiceManager serviceManager;
public DestinationServiceManager getServiceManager() {
return serviceManager;
}
public void setServiceManager(DestinationServiceManager serviceManager) {
this.serviceManager = serviceManager;
}
public int getConsumerTimeoutSeconds() {
return consumerTimeoutSeconds;
}
public void setConsumerTimeoutSeconds(int consumerTimeoutSeconds) {
this.consumerTimeoutSeconds = consumerTimeoutSeconds;
}
public ClientSessionFactory getSessionFactory() {
return sessionFactory;
}
public void setSessionFactory(ClientSessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
public String getDestination() {
return destination;
}
public void setDestination(String destination) {
this.destination = destination;
}
@Override
public boolean testTimeout(String target, boolean autoShutdown) {
QueueConsumer consumer = queueConsumers.get(target);
Subscription subscription = (Subscription) consumer;
if (consumer == null)
return false;
if (System.currentTimeMillis() - consumer.getLastPingTime() > subscription.getTimeout()) {
ActiveMQRestLogger.LOGGER.shutdownRestSubscription(consumer.getId());
if (autoShutdown) {
shutdown(consumer);
}
return true;
} else {
return false;
}
}
@Override
public void shutdown(String target) {
QueueConsumer consumer = queueConsumers.get(target);
if (consumer == null)
return;
shutdown(consumer);
}
private void shutdown(QueueConsumer consumer) {
synchronized (consumer) {
consumer.shutdown();
queueConsumers.remove(consumer.getId());
Subscription subscription = (Subscription) consumer;
if (subscription.isDeleteWhenIdle())
deleteSubscriberQueue(consumer);
}
}
public void stop() {
for (QueueConsumer consumer : queueConsumers.values()) {
consumer.shutdown();
Subscription subscription = (Subscription) consumer;
if (!subscription.isDurable()) {
deleteSubscriberQueue(consumer);
}
}
queueConsumers.clear();
}
protected String generateSubscriptionName() {
return startup + "-" + sessionCounter.getAndIncrement() + "-" + destination;
}
@POST
public Response createSubscription(@FormParam("durable") @DefaultValue("false") boolean durable,
@FormParam("autoAck") @DefaultValue("true") boolean autoAck,
@FormParam("name") String subscriptionName,
@FormParam("selector") String selector,
@FormParam("delete-when-idle") Boolean destroyWhenIdle,
@FormParam("idle-timeout") Long timeout,
@Context UriInfo uriInfo) {
ActiveMQRestLogger.LOGGER.debug("Handling POST request for \"" + uriInfo.getPath() + "\"");
if (timeout == null)
timeout = Long.valueOf((long) consumerTimeoutSeconds * 1000);
boolean deleteWhenIdle = !durable; // default is true if non-durable
if (destroyWhenIdle != null)
deleteWhenIdle = destroyWhenIdle.booleanValue();
if (subscriptionName != null) {
// see if this is a reconnect
QueueConsumer consumer = queueConsumers.get(subscriptionName);
if (consumer != null) {
boolean acked = consumer instanceof AcknowledgedSubscriptionResource;
acked = !acked;
if (acked != autoAck) {
throw new WebApplicationException(Response.status(412).entity("Consumer already exists and ack-modes don't match.").type("text/plain").build());
}
Subscription sub = (Subscription) consumer;
if (sub.isDurable() != durable) {
throw new WebApplicationException(Response.status(412).entity("Consumer already exists and durability doesn't match.").type("text/plain").build());
}
Response.ResponseBuilder builder = Response.noContent();
String pathToPullSubscriptions = uriInfo.getMatchedURIs().get(0);
if (autoAck) {
headAutoAckSubscriptionResponse(uriInfo, consumer, builder, pathToPullSubscriptions);
consumer.setSessionLink(builder, uriInfo, pathToPullSubscriptions + "/auto-ack/" + consumer.getId());
} else {
headAcknowledgedConsumerResponse(uriInfo, (AcknowledgedQueueConsumer) consumer, builder);
consumer.setSessionLink(builder, uriInfo, pathToPullSubscriptions + "/acknowledged/" + consumer.getId());
}
return builder.build();
}
} else {
subscriptionName = generateSubscriptionName();
}
ClientSession session = null;
try {
// if this is not a reconnect, create the subscription queue
if (!subscriptionExists(subscriptionName)) {
session = sessionFactory.createSession();
session.createQueue(new QueueConfiguration(subscriptionName).setAddress(destination).setDurable(durable).setTemporary(!durable));
}
QueueConsumer consumer = createConsumer(durable, autoAck, subscriptionName, selector, timeout, deleteWhenIdle);
queueConsumers.put(consumer.getId(), consumer);
serviceManager.getTimeoutTask().add(this, consumer.getId());
UriBuilder location = uriInfo.getAbsolutePathBuilder();
if (autoAck)
location.path("auto-ack");
else
location.path("acknowledged");
location.path(consumer.getId());
Response.ResponseBuilder builder = Response.created(location.build());
if (autoAck) {
QueueConsumer.setConsumeNextLink(serviceManager.getLinkStrategy(), builder, uriInfo, uriInfo.getMatchedURIs().get(0) + "/auto-ack/" + consumer.getId(), "-1");
} else {
AcknowledgedQueueConsumer.setAcknowledgeNextLink(serviceManager.getLinkStrategy(), builder, uriInfo, uriInfo.getMatchedURIs().get(0) + "/acknowledged/" + consumer.getId(), "-1");
}
return builder.build();
} catch (ActiveMQException e) {
throw new RuntimeException(e);
} finally {
if (session != null) {
try {
session.close();
} catch (ActiveMQException e) {
}
}
}
}
protected QueueConsumer createConsumer(boolean durable,
boolean autoAck,
String subscriptionName,
String selector,
long timeout,
boolean deleteWhenIdle) throws ActiveMQException {
QueueConsumer consumer;
if (autoAck) {
SubscriptionResource subscription = new SubscriptionResource(sessionFactory, subscriptionName, subscriptionName, serviceManager, selector, durable, timeout);
subscription.setDurable(durable);
subscription.setDeleteWhenIdle(deleteWhenIdle);
consumer = subscription;
} else {
AcknowledgedSubscriptionResource subscription = new AcknowledgedSubscriptionResource(sessionFactory, subscriptionName, subscriptionName, serviceManager, selector, durable, timeout);
subscription.setDurable(durable);
subscription.setDeleteWhenIdle(deleteWhenIdle);
consumer = subscription;
}
return consumer;
}
@Path("auto-ack/{consumer-id}")
@GET
public Response getAutoAckSubscription(@PathParam("consumer-id") String consumerId,
@Context UriInfo uriInfo) throws Exception {
ActiveMQRestLogger.LOGGER.debug("Handling GET request for \"" + uriInfo.getPath() + "\"");
return internalHeadAutoAckSubscription(uriInfo, consumerId);
}
@Path("auto-ack/{consumer-id}")
@HEAD
public Response headAutoAckSubscription(@PathParam("consumer-id") String consumerId,
@Context UriInfo uriInfo) throws Exception {
ActiveMQRestLogger.LOGGER.debug("Handling HEAD request for \"" + uriInfo.getPath() + "\"");
return internalHeadAutoAckSubscription(uriInfo, consumerId);
}
private Response internalHeadAutoAckSubscription(UriInfo uriInfo, String consumerId) {
QueueConsumer consumer = findAutoAckSubscription(consumerId);
Response.ResponseBuilder builder = Response.noContent();
String pathToPullSubscriptions = uriInfo.getMatchedURIs().get(1);
headAutoAckSubscriptionResponse(uriInfo, consumer, builder, pathToPullSubscriptions);
return builder.build();
}
private void headAutoAckSubscriptionResponse(UriInfo uriInfo,
QueueConsumer consumer,
Response.ResponseBuilder builder,
String pathToPullSubscriptions) {
// we synchronize just in case a failed request is still processing
synchronized (consumer) {
QueueConsumer.setConsumeNextLink(serviceManager.getLinkStrategy(), builder, uriInfo, pathToPullSubscriptions + "/acknowledged/" + consumer.getId(), Long.toString(consumer.getConsumeIndex()));
}
}
@Path("auto-ack/{subscription-id}")
public QueueConsumer findAutoAckSubscription(@PathParam("subscription-id") String subscriptionId) {
QueueConsumer consumer = queueConsumers.get(subscriptionId);
if (consumer == null) {
consumer = recreateTopicConsumer(subscriptionId, true);
}
return consumer;
}
@Path("acknowledged/{consumer-id}")
@GET
public Response getAcknowledgedConsumer(@PathParam("consumer-id") String consumerId,
@Context UriInfo uriInfo) throws Exception {
ActiveMQRestLogger.LOGGER.debug("Handling GET request for \"" + uriInfo.getPath() + "\"");
return internalHeadAcknowledgedConsumer(uriInfo, consumerId);
}
@Path("acknowledged/{consumer-id}")
@HEAD
public Response headAcknowledgedConsumer(@PathParam("consumer-id") String consumerId,
@Context UriInfo uriInfo) throws Exception {
ActiveMQRestLogger.LOGGER.debug("Handling HEAD request for \"" + uriInfo.getPath() + "\"");
return internalHeadAcknowledgedConsumer(uriInfo, consumerId);
}
private Response internalHeadAcknowledgedConsumer(UriInfo uriInfo, String consumerId) {
AcknowledgedQueueConsumer consumer = (AcknowledgedQueueConsumer) findAcknoledgeSubscription(consumerId);
Response.ResponseBuilder builder = Response.ok();
headAcknowledgedConsumerResponse(uriInfo, consumer, builder);
return builder.build();
}
private void headAcknowledgedConsumerResponse(UriInfo uriInfo,
AcknowledgedQueueConsumer consumer,
Response.ResponseBuilder builder) {
// we synchronize just in case a failed request is still processing
synchronized (consumer) {
Acknowledgement ack = consumer.getAck();
if (ack == null || ack.wasSet()) {
AcknowledgedQueueConsumer.setAcknowledgeNextLink(serviceManager.getLinkStrategy(), builder, uriInfo, uriInfo.getMatchedURIs().get(1) + "/acknowledged/" + consumer.getId(), Long.toString(consumer.getConsumeIndex()));
} else {
consumer.setAcknowledgementLink(builder, uriInfo, uriInfo.getMatchedURIs().get(1) + "/acknowledged/" + consumer.getId());
}
}
}
@Path("acknowledged/{subscription-id}")
public QueueConsumer findAcknoledgeSubscription(@PathParam("subscription-id") String subscriptionId) {
QueueConsumer consumer = queueConsumers.get(subscriptionId);
if (consumer == null) {
consumer = recreateTopicConsumer(subscriptionId, false);
}
return consumer;
}
private boolean subscriptionExists(String subscriptionId) {
ClientSession session = null;
try {
session = sessionFactory.createSession();
ClientSession.QueueQuery query = session.queueQuery(new SimpleString(subscriptionId));
return query.isExists();
} catch (ActiveMQException e) {
throw new RuntimeException(e);
} finally {
if (session != null) {
try {
session.close();
} catch (ActiveMQException e) {
}
}
}
}
private QueueConsumer recreateTopicConsumer(String subscriptionId, boolean autoAck) {
QueueConsumer consumer;
if (subscriptionExists(subscriptionId)) {
QueueConsumer tmp = null;
try {
tmp = createConsumer(true, autoAck, subscriptionId, null, consumerTimeoutSeconds * 1000L, false);
} catch (ActiveMQException e) {
throw new RuntimeException(e);
}
consumer = queueConsumers.putIfAbsent(subscriptionId, tmp);
if (consumer == null) {
consumer = tmp;
serviceManager.getTimeoutTask().add(this, subscriptionId);
} else {
tmp.shutdown();
}
} else {
throw new WebApplicationException(Response.status(405).entity("Failed to find subscriber " + subscriptionId + " you will have to reconnect").type("text/plain").build());
}
return consumer;
}
@Path("acknowledged/{subscription-id}")
@DELETE
public void deleteAckSubscription(@Context UriInfo uriInfo, @PathParam("subscription-id") String consumerId) {
ActiveMQRestLogger.LOGGER.debug("Handling DELETE request for \"" + uriInfo.getPath() + "\"");
internalDeleteSubscription(consumerId);
}
@Path("auto-ack/{subscription-id}")
@DELETE
public void deleteSubscription(@Context UriInfo uriInfo, @PathParam("subscription-id") String consumerId) {
ActiveMQRestLogger.LOGGER.debug("Handling DELETE request for \"" + uriInfo.getPath() + "\"");
internalDeleteSubscription(consumerId);
}
private void internalDeleteSubscription(String consumerId) {
QueueConsumer consumer = queueConsumers.remove(consumerId);
if (consumer == null) {
String msg = "Failed to match a subscription to URL " + consumerId;
throw new WebApplicationException(Response.status(Response.Status.NOT_FOUND).entity(msg).type("text/plain").build());
}
consumer.shutdown();
deleteSubscriberQueue(consumer);
}
private void deleteSubscriberQueue(QueueConsumer consumer) {
String subscriptionName = consumer.getId();
ClientSession session = null;
try {
session = sessionFactory.createSession();
session.deleteQueue(subscriptionName);
} catch (ActiveMQException e) {
} finally {
if (session != null) {
try {
session.close();
} catch (ActiveMQException e) {
}
}
}
}
}

View File

@ -1,40 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.activemq.artemis.rest.topic;
import org.apache.activemq.artemis.rest.queue.DestinationSettings;
public class TopicDeployment extends DestinationSettings {
private String name;
public TopicDeployment() {
}
public TopicDeployment(String name, boolean duplicatesAllowed) {
this.name = name;
this.duplicatesAllowed = duplicatesAllowed;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}

View File

@ -1,167 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.activemq.artemis.rest.topic;
import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo;
import java.net.URI;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.apache.activemq.artemis.api.core.ActiveMQException;
import org.apache.activemq.artemis.api.core.SimpleString;
import org.apache.activemq.artemis.api.core.client.ClientSession;
import org.apache.activemq.artemis.api.core.RoutingType;
import org.apache.activemq.artemis.jms.client.ActiveMQDestination;
import org.apache.activemq.artemis.jms.client.ActiveMQTopic;
import org.apache.activemq.artemis.jms.server.config.TopicConfiguration;
import org.apache.activemq.artemis.jms.server.config.impl.FileJMSConfiguration;
import org.apache.activemq.artemis.rest.ActiveMQRestLogger;
import org.apache.activemq.artemis.rest.queue.DestinationSettings;
import org.apache.activemq.artemis.rest.queue.PostMessage;
import org.apache.activemq.artemis.rest.queue.PostMessageDupsOk;
import org.apache.activemq.artemis.rest.queue.PostMessageNoDups;
import org.w3c.dom.Document;
@Path("/topics")
public class TopicDestinationsResource {
private final Map<String, TopicResource> topics = new ConcurrentHashMap<>();
private final TopicServiceManager manager;
public TopicDestinationsResource(TopicServiceManager manager) {
this.manager = manager;
}
@POST
@Consumes("application/activemq.jms.topic+xml")
public Response createJmsTopic(@Context UriInfo uriInfo, Document document) {
ActiveMQRestLogger.LOGGER.debug("Handling POST request for \"" + uriInfo.getPath() + "\"");
try {
TopicConfiguration topic = FileJMSConfiguration.parseTopicConfiguration(document.getDocumentElement());
ActiveMQTopic activeMQTopic = ActiveMQDestination.createTopic(topic.getName());
String topicName = activeMQTopic.getAddress();
ClientSession session = manager.getSessionFactory().createSession(false, false, false);
try {
ClientSession.AddressQuery query = session.addressQuery(new SimpleString(topicName));
if (!query.isExists()) {
session.createAddress(SimpleString.toSimpleString(topicName), RoutingType.MULTICAST, true);
} else {
throw new WebApplicationException(Response.status(412).type("text/plain").entity("Queue already exists.").build());
}
} finally {
try {
session.close();
} catch (Exception ignored) {
}
}
URI uri = uriInfo.getRequestUriBuilder().path(topicName).build();
return Response.created(uri).build();
} catch (Exception e) {
if (e instanceof WebApplicationException)
throw (WebApplicationException) e;
throw new WebApplicationException(e, Response.serverError().type("text/plain").entity("Failed to create queue.").build());
}
}
@Path("/{topic-name}")
public TopicResource findTopic(@PathParam("topic-name") String name) throws Exception {
TopicResource topic = topics.get(name);
if (topic == null) {
ClientSession session = manager.getSessionFactory().createSession(false, false, false);
try {
ClientSession.AddressQuery query = session.addressQuery(new SimpleString(name));
if (!query.isExists()) {
System.err.println("Topic '" + name + "' does not exist");
throw new WebApplicationException(Response.status(404).type("text/plain").entity("Topic '" + name + "' does not exist").build());
}
DestinationSettings queueSettings = manager.getDefaultSettings();
boolean defaultDurable = queueSettings.isDurableSend();
topic = createTopicResource(name, defaultDurable, queueSettings.getConsumerSessionTimeoutSeconds(), queueSettings.isDuplicatesAllowed());
} finally {
try {
session.close();
} catch (ActiveMQException e) {
}
}
}
return topic;
}
public Map<String, TopicResource> getTopics() {
return topics;
}
public TopicResource createTopicResource(String topicName,
boolean defaultDurable,
int timeoutSeconds,
boolean duplicates) throws Exception {
TopicResource topicResource = new TopicResource();
topicResource.setTopicDestinationsResource(this);
topicResource.setDestination(topicName);
topicResource.setServiceManager(manager);
SubscriptionsResource subscriptionsResource = new SubscriptionsResource();
topicResource.setSubscriptions(subscriptionsResource);
subscriptionsResource.setConsumerTimeoutSeconds(timeoutSeconds);
subscriptionsResource.setServiceManager(manager);
subscriptionsResource.setDestination(topicName);
subscriptionsResource.setSessionFactory(manager.getConsumerSessionFactory());
PushSubscriptionsResource push = new PushSubscriptionsResource(manager.getJmsOptions());
push.setDestination(topicName);
push.setSessionFactory(manager.getConsumerSessionFactory());
topicResource.setPushSubscriptions(push);
PostMessage sender = null;
if (duplicates) {
sender = new PostMessageDupsOk();
} else {
sender = new PostMessageNoDups();
}
sender.setDefaultDurable(defaultDurable);
sender.setDestination(topicName);
sender.setSessionFactory(manager.getSessionFactory());
sender.setPoolSize(manager.getProducerPoolSize());
sender.setProducerTimeToLive(manager.getProducerTimeToLive());
sender.setServiceManager(manager);
sender.init();
topicResource.setSender(sender);
if (manager.getPushStore() != null) {
push.setPushStore(manager.getPushStore());
List<PushTopicRegistration> regs = manager.getPushStore().getByTopic(topicName);
for (PushTopicRegistration reg : regs) {
push.addRegistration(reg);
}
}
getTopics().put(topicName, topicResource);
topicResource.start();
return topicResource;
}
}

View File

@ -1,26 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.activemq.artemis.rest.topic;
import java.util.List;
import org.apache.activemq.artemis.rest.queue.push.PushStore;
public interface TopicPushStore extends PushStore {
List<PushTopicRegistration> getByTopic(String topic);
}

View File

@ -1,180 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.activemq.artemis.rest.topic;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.HEAD;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriBuilder;
import javax.ws.rs.core.UriInfo;
import org.apache.activemq.artemis.api.core.SimpleString;
import org.apache.activemq.artemis.api.core.client.ClientSession;
import org.apache.activemq.artemis.rest.ActiveMQRestLogger;
import org.apache.activemq.artemis.rest.queue.DestinationResource;
import org.apache.activemq.artemis.rest.queue.PostMessage;
public class TopicResource extends DestinationResource {
protected SubscriptionsResource subscriptions;
protected PushSubscriptionsResource pushSubscriptions;
private TopicDestinationsResource topicDestinationsResource;
public void start() throws Exception {
}
public void stop() {
subscriptions.stop();
pushSubscriptions.stop();
sender.cleanup();
}
@GET
@Produces("application/xml")
public Response get(@Context UriInfo uriInfo) {
ActiveMQRestLogger.LOGGER.debug("Handling GET request for \"" + uriInfo.getPath() + "\"");
StringBuilder msg = new StringBuilder();
msg.append("<topic>").append("<name>").append(destination).append("</name>").append("<atom:link rel=\"create\" href=\"").append(createSenderLink(uriInfo)).append("\"/>").append("<atom:link rel=\"create-with-id\" href=\"").append(createSenderWithIdLink(uriInfo)).append("\"/>").append("<atom:link rel=\"pull-consumers\" href=\"").append(createSubscriptionsLink(uriInfo)).append("\"/>").append("<atom:link rel=\"push-consumers\" href=\"").append(createPushSubscriptionsLink(uriInfo)).append("\"/>")
.append("</topic>");
Response.ResponseBuilder builder = Response.ok(msg.toString());
setSenderLink(builder, uriInfo);
setSenderWithIdLink(builder, uriInfo);
setSubscriptionsLink(builder, uriInfo);
setPushSubscriptionsLink(builder, uriInfo);
return builder.build();
}
@HEAD
@Produces("application/xml")
public Response head(@Context UriInfo uriInfo) {
ActiveMQRestLogger.LOGGER.debug("Handling HEAD request for \"" + uriInfo.getPath() + "\"");
Response.ResponseBuilder builder = Response.ok();
setSenderLink(builder, uriInfo);
setSenderWithIdLink(builder, uriInfo);
setSubscriptionsLink(builder, uriInfo);
setPushSubscriptionsLink(builder, uriInfo);
return builder.build();
}
protected void setSenderLink(Response.ResponseBuilder response, UriInfo info) {
String uri = createSenderLink(info);
serviceManager.getLinkStrategy().setLinkHeader(response, "create", "create", uri, null);
}
protected String createSenderLink(UriInfo info) {
UriBuilder builder = info.getRequestUriBuilder();
builder.path("create");
String uri = builder.build().toString();
return uri;
}
protected void setSenderWithIdLink(Response.ResponseBuilder response, UriInfo info) {
String uri = createSenderWithIdLink(info);
serviceManager.getLinkStrategy().setLinkHeader(response, "create-with-id", "create-with-id", uri, null);
}
protected String createSenderWithIdLink(UriInfo info) {
UriBuilder builder = info.getRequestUriBuilder();
builder.path("create");
String uri = builder.build().toString();
uri += "/{id}";
return uri;
}
protected void setSubscriptionsLink(Response.ResponseBuilder response, UriInfo info) {
String uri = createSubscriptionsLink(info);
serviceManager.getLinkStrategy().setLinkHeader(response, "pull-subscriptions", "pull-subscriptions", uri, null);
}
protected String createSubscriptionsLink(UriInfo info) {
UriBuilder builder = info.getRequestUriBuilder();
builder.path("pull-subscriptions");
String uri = builder.build().toString();
return uri;
}
protected void setPushSubscriptionsLink(Response.ResponseBuilder response, UriInfo info) {
String uri = createPushSubscriptionsLink(info);
serviceManager.getLinkStrategy().setLinkHeader(response, "push-subscriptions", "push-subscriptions", uri, null);
}
protected String createPushSubscriptionsLink(UriInfo info) {
UriBuilder builder = info.getRequestUriBuilder();
builder.path("push-subscriptions");
String uri = builder.build().toString();
return uri;
}
public void setSubscriptions(SubscriptionsResource subscriptions) {
this.subscriptions = subscriptions;
}
@Path("create")
public PostMessage post() throws Exception {
return sender;
}
@Path("pull-subscriptions")
public SubscriptionsResource getSubscriptions() {
return subscriptions;
}
@Path("push-subscriptions")
public PushSubscriptionsResource getPushSubscriptions() {
return pushSubscriptions;
}
public void setPushSubscriptions(PushSubscriptionsResource pushSubscriptions) {
this.pushSubscriptions = pushSubscriptions;
}
@DELETE
public void deleteTopic(@Context UriInfo uriInfo) throws Exception {
ActiveMQRestLogger.LOGGER.debug("Handling DELETE request for \"" + uriInfo.getPath() + "\"");
topicDestinationsResource.getTopics().remove(destination);
try {
stop();
} catch (Exception ignored) {
}
ClientSession session = serviceManager.getSessionFactory().createSession(false, false, false);
try {
SimpleString topicName = new SimpleString(destination);
session.deleteQueue(topicName);
} finally {
try {
session.close();
} catch (Exception ignored) {
}
}
}
public void setTopicDestinationsResource(TopicDestinationsResource topicDestinationsResource) {
this.topicDestinationsResource = topicDestinationsResource;
}
}

View File

@ -1,110 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.activemq.artemis.rest.topic;
import java.util.ArrayList;
import java.util.List;
import org.apache.activemq.artemis.api.core.SimpleString;
import org.apache.activemq.artemis.api.core.client.ClientSession;
import org.apache.activemq.artemis.api.core.RoutingType;
import org.apache.activemq.artemis.jms.client.ConnectionFactoryOptions;
import org.apache.activemq.artemis.rest.queue.DestinationServiceManager;
public class TopicServiceManager extends DestinationServiceManager {
protected TopicPushStore pushStore;
protected List<TopicDeployment> topics = new ArrayList<>();
protected TopicDestinationsResource destination;
public TopicServiceManager(ConnectionFactoryOptions jmsOptions) {
super(jmsOptions);
}
public TopicPushStore getPushStore() {
return pushStore;
}
public void setPushStore(TopicPushStore pushStore) {
this.pushStore = pushStore;
}
public List<TopicDeployment> getTopics() {
return topics;
}
public void setTopics(List<TopicDeployment> topics) {
this.topics = topics;
}
public TopicDestinationsResource getDestination() {
return destination;
}
public void setDestination(TopicDestinationsResource destination) {
this.destination = destination;
}
@Override
public void start() throws Exception {
initDefaults();
started = true;
if (pushStoreFile != null && pushStore == null) {
pushStore = new FileTopicPushStore(pushStoreFile);
}
if (destination == null) {
destination = new TopicDestinationsResource(this);
}
for (TopicDeployment topic : topics) {
deploy(topic);
}
}
public void deploy(TopicDeployment topicDeployment) throws Exception {
if (!started) {
throw new Exception("You must start() this class instance before deploying");
}
String queueName = topicDeployment.getName();
boolean defaultDurable;
try (ClientSession session = sessionFactory.createSession(false, false, false)) {
defaultDurable = topicDeployment.isDurableSend();
ClientSession.AddressQuery query = session.addressQuery(new SimpleString(queueName));
if (!query.isExists())
session.createAddress(SimpleString.toSimpleString(queueName), RoutingType.MULTICAST, true);
}
destination.createTopicResource(queueName, defaultDurable, topicDeployment.getConsumerSessionTimeoutSeconds(), topicDeployment.isDuplicatesAllowed());
}
@Override
public void stop() {
if (started == false)
return;
for (TopicResource topic : destination.getTopics().values()) {
topic.stop();
}
try {
sessionFactory.close();
} catch (Exception e) {
}
}
}

View File

@ -1,23 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.activemq.artemis.rest.util;
public interface Constants {
String WAIT_HEADER = "Accept-Wait";
String PATH_FOR_QUEUES = "/queues";
}

View File

@ -1,39 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.activemq.artemis.rest.util;
import javax.ws.rs.core.Response;
public class CustomHeaderLinkStrategy implements LinkStrategy {
@Override
public void setLinkHeader(Response.ResponseBuilder builder, String title, String rel, String href, String type) {
String headerName = null;
if (title != null) {
headerName = title;
} else if (rel != null) {
headerName = rel;
} else {
throw new RuntimeException("Cannot figure out header name");
}
headerName = "msg-" + headerName;
builder.header(headerName, href);
if (type != null) {
builder.header(headerName + "-type", type);
}
}
}

View File

@ -1,127 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.activemq.artemis.rest.util;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.MultivaluedMap;
import java.io.ByteArrayInputStream;
import java.util.List;
import java.util.Map.Entry;
import org.apache.activemq.artemis.api.core.SimpleString;
import org.apache.activemq.artemis.api.core.client.ClientMessage;
import org.apache.activemq.artemis.jms.client.ConnectionFactoryOptions;
import org.apache.activemq.artemis.rest.ActiveMQRestLogger;
import org.apache.activemq.artemis.rest.HttpHeaderProperty;
import org.apache.activemq.artemis.utils.ObjectInputStreamWithClassLoader;
import org.jboss.resteasy.client.ClientRequest;
import static org.apache.activemq.artemis.rest.HttpHeaderProperty.MESSAGE_PROPERTY_DISCRIMINATOR;
public class HttpMessageHelper {
public static final String POSTED_AS_HTTP_MESSAGE = "postedAsHttpMessage";
public static boolean isTransferableHttpHeader(String key) {
String lowerKey = key.toLowerCase();
return lowerKey.toLowerCase().startsWith("content") || lowerKey.toLowerCase().equals("link");
}
public static boolean isMessageProperty( String key) {
return key.toLowerCase().startsWith( MESSAGE_PROPERTY_DISCRIMINATOR );
}
public static void buildMessage(ClientMessage message,
ClientRequest request,
String contentType,
ConnectionFactoryOptions jmsOptions) {
for (SimpleString key : message.getPropertyNames()) {
String k = key.toString();
String headerName = HttpHeaderProperty.fromPropertyName(k);
if (headerName == null || headerName.contains("content-length")) {
continue;
}
String value = message.getStringProperty(k);
request.header(headerName, value);
ActiveMQRestLogger.LOGGER.debug("Examining " + headerName + ": " + value);
// override default content type if it is set as a message property
if (headerName.equalsIgnoreCase("content-type")) {
contentType = value;
ActiveMQRestLogger.LOGGER.debug("Using contentType: " + contentType);
}
}
int size = message.getBodySize();
if (size > 0) {
Boolean aBoolean = message.getBooleanProperty(POSTED_AS_HTTP_MESSAGE);
if (aBoolean != null && aBoolean.booleanValue()) {
byte[] body = new byte[size];
message.getBodyBuffer().readBytes(body);
ActiveMQRestLogger.LOGGER.debug("Building Message from HTTP message");
request.body(contentType, body);
} else {
// assume posted as a JMS or ActiveMQ Artemis object message
size = message.getBodyBuffer().readInt();
byte[] body = new byte[size];
message.getBodyBuffer().readBytes(body);
ByteArrayInputStream bais = new ByteArrayInputStream(body);
Object obj = null;
try (ObjectInputStreamWithClassLoader ois = new ObjectInputStreamWithClassLoader(bais)) {
if (jmsOptions != null) {
ois.setBlackList(jmsOptions.getDeserializationBlackList());
ois.setWhiteList(jmsOptions.getDeserializationWhiteList());
}
obj = ois.readObject();
ActiveMQRestLogger.LOGGER.debug("**** Building Message from object: " + obj.toString());
request.body(contentType, obj);
} catch (Exception e) {
ActiveMQRestLogger.LOGGER.failedToBuildMessageFromObject(e);
throw new RuntimeException(e);
}
}
}
}
public static void writeHttpMessage(HttpHeaders headers, byte[] body, ClientMessage message) throws Exception {
MultivaluedMap<String, String> hdrs = headers.getRequestHeaders();
for (Entry<String, List<String>> entry : hdrs.entrySet()) {
String key = entry.getKey();
if (isTransferableHttpHeader(key) || isMessageProperty( key )) {
List<String> vals = entry.getValue();
String value = concatenateHeaderValue(vals);
message.putStringProperty(HttpHeaderProperty.toPropertyName(key), value);
}
}
message.putBooleanProperty(POSTED_AS_HTTP_MESSAGE, true);
message.getBodyBuffer().writeBytes(body);
}
public static String concatenateHeaderValue(List<String> vals) {
if (vals == null) {
return "";
}
StringBuilder val = new StringBuilder();
for (String v : vals) {
if (val.length() > 0) {
val.append(",");
}
val.append(v);
}
return val.toString();
}
}

View File

@ -1,55 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.activemq.artemis.rest.util;
import javax.ws.rs.core.Response;
import org.jboss.resteasy.spi.Link;
public class LinkHeaderLinkStrategy implements LinkStrategy {
/**
* @param builder
* @param title user friendly name
* @param rel could be a link
* @param href
* @param type
*/
@Override
public void setLinkHeader(Response.ResponseBuilder builder, String title, String rel, String href, String type) {
Link link = new Link(title, rel, href, type, null);
setLinkHeader(builder, link);
}
public void setLinkHeader(Response.ResponseBuilder builder, Link link) {
builder.header("Link", link);
}
/* proprietary, keep this around just in case
public static void setLinkHeader(Response.ResponseBuilder builder, String rel, String href, String type)
{
String link = "Link-Href-" + rel;
builder.header(link, href);
if (type != null)
{
String typeHeader = "Link-Type-" + rel;
builder.header(typeHeader, type);
}
}
*/
}

View File

@ -1,24 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.activemq.artemis.rest.util;
import javax.ws.rs.core.Response;
public interface LinkStrategy {
void setLinkHeader(Response.ResponseBuilder builder, String title, String rel, String href, String type);
}

View File

@ -1,161 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.activemq.artemis.rest.util;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import org.apache.activemq.artemis.rest.ActiveMQRestLogger;
public class TimeoutTask implements Runnable {
protected boolean running = true;
protected int interval = 10;
protected final Lock callbacksLock = new ReentrantLock();
protected Map<String, Callback> callbacks = new HashMap<>();
protected final Lock pendingCallbacksLock = new ReentrantLock();
protected Map<String, Callback> pendingCallbacks = new HashMap<>();
protected Thread thread;
public TimeoutTask(int interval) {
this.interval = interval;
}
public interface Callback {
boolean testTimeout(String token, boolean autoShutdown);
void shutdown(String token);
}
public synchronized void add(Callback callback, String token) {
if (callbacksLock.tryLock()) {
try {
callbacks.put(token, callback);
} finally {
callbacksLock.unlock();
}
} else {
pendingCallbacksLock.lock();
try {
pendingCallbacks.put(token, callback);
} finally {
pendingCallbacksLock.unlock();
}
}
}
public synchronized void remove(String token) {
callbacksLock.lock();
try {
callbacks.remove(token);
} finally {
callbacksLock.unlock();
}
}
public synchronized void stop() {
running = false;
if (thread != null) {
thread.interrupt();
}
}
public synchronized int getInterval() {
return interval;
}
public synchronized void setInterval(int interval) {
this.interval = interval;
}
public void start() {
thread = new Thread(this);
thread.start();
}
@Override
public void run() {
while (running) {
try {
Thread.sleep((long) interval * 1000);
} catch (InterruptedException e) {
running = false;
break;
}
// First, test all known callbacks for timeouts.
// If the timeout is true, then move it to a separate map.
Map<String, Callback> expiredCallbacks = new HashMap<>();
int liveConsumers = 0;
int deadConsumers = 0;
callbacksLock.lock();
try {
long startTime = System.currentTimeMillis();
List<String> tokens = new ArrayList<>(callbacks.size());
for (String token : callbacks.keySet()) {
tokens.add(token);
}
for (String token : tokens) {
Callback callback = callbacks.get(token);
if (callback.testTimeout(token, false)) {
deadConsumers += 1;
expiredCallbacks.put(token, callback);
callbacks.remove(token);
} else {
liveConsumers += 1;
}
}
ActiveMQRestLogger.LOGGER.debug("Finished testing callbacks for timeouts in " +
(System.currentTimeMillis() - startTime) + "ms. " +
"(Live: " + liveConsumers + ", Expired: " + deadConsumers + ")");
// Next, move any pending callback additions to the main callbacks map.
pendingCallbacksLock.lock();
try {
if (pendingCallbacks.size() > 0) {
ActiveMQRestLogger.LOGGER.debug("Found " + pendingCallbacks.size() + " callbacks to add.");
callbacks.putAll(pendingCallbacks);
pendingCallbacks.clear();
}
} finally {
pendingCallbacksLock.unlock();
}
} finally {
callbacksLock.unlock();
}
// Finally, freely shutdown all expired consumers.
if (expiredCallbacks.size() > 0) {
List<String> tokens = new ArrayList<>(expiredCallbacks.size());
for (String token : expiredCallbacks.keySet()) {
tokens.add(token);
}
for (String token : tokens) {
Callback expired = expiredCallbacks.get(token);
expired.shutdown(token);
}
}
}
}
}

View File

@ -1,119 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<xsd:schema xmlns="urn:activemq:rest" version="1.0" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
attributeFormDefault="unqualified" elementFormDefault="qualified" targetNamespace="urn:activemq:rest">
<xsd:element name="rest-messaging">
<xsd:complexType>
<xsd:all>
<xsd:element name="server-in-vm-id" type="xsd:string" minOccurs="0" maxOccurs="1">
<xsd:annotation>
<xsd:documentation>
The ActiveMQ Artemis REST implementation uses the IN-VM transport to communicate
with ActiveMQ Artemis. It uses the default server id, which is "0".
</xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:element name="use-link-headers" type="xsd:boolean" minOccurs="0" maxOccurs="1">
<xsd:annotation>
<xsd:documentation>
By default, all links (URLs) are published using custom headers.
You can instead have the ActiveMQ Artemis REST implementation publish links
using the Link Header specification instead if you desire.
</xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:element name="default-durable-send" type="xsd:boolean" minOccurs="0" maxOccurs="1">
<xsd:annotation>
<xsd:documentation>
Whether a posted message should be persisted by default if the user
does not specify a durable query parameter.
</xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:element name="dups-ok" type="xsd:boolean" minOccurs="0" maxOccurs="1">
<xsd:annotation>
<xsd:documentation>
If this is true, no duplicate detection protocol will be enforced for
message posting.
</xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:element name="topic-push-store-dir" type="xsd:string" minOccurs="0" maxOccurs="1">
<xsd:annotation>
<xsd:documentation>
This must be a relative or absolute file system path. This is a
directory where push registrations for topics are stored.
</xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:element name="queue-push-store-dir" type="xsd:string" minOccurs="0" maxOccurs="1">
<xsd:annotation>
<xsd:documentation>
This must be a relative or absolute file system path. This is a
directory where push registrations for queues are stored.
</xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:element name="producer-session-pool-size" type="xsd:int" minOccurs="0" maxOccurs="1">
<xsd:annotation>
<xsd:documentation>
The REST implementation pools ActiveMQ Artemis sessions for sending messages.
This is the size of the pool. That number of sessions will be created
at startup time.
</xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:element name="producer-time-to-live" type="xsd:long" minOccurs="0" maxOccurs="1">
<xsd:annotation>
<xsd:documentation>
Default time to live for posted messages. Default is no ttl.
</xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:element name="session-timeout-task-interval" type="xsd:int" minOccurs="0" maxOccurs="1">
<xsd:annotation>
<xsd:documentation>
Pull consumers and pull subscriptions can time out. This is the
interval the thread that checks for timed-out sessions will run at. A
value of 1 means it will run every 1 second.
</xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:element name="consumer-session-timeout-seconds" type="xsd:int" minOccurs="0" maxOccurs="1">
<xsd:annotation>
<xsd:documentation>
Timeout in seconds for pull consumers/subscriptions that remain idle
for that amount of time.
</xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:element name="consumer-window-size" type="xsd:int" minOccurs="0" maxOccurs="1">
<xsd:annotation>
<xsd:documentation>
For consumers, this config option is the same as the ActiveMQ Artemis one of the
same name. It will be used by sessions created by the ActiveMQ Artemis REST
implementation.
</xsd:documentation>
</xsd:annotation>
</xsd:element>
</xsd:all>
</xsd:complexType>
</xsd:element>
</xsd:schema>

View File

@ -1,198 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.activemq.artemis.rest.integration;
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.Destination;
import javax.jms.MessageProducer;
import javax.jms.ObjectMessage;
import javax.jms.Session;
import java.io.Serializable;
import org.apache.activemq.artemis.api.jms.ActiveMQJMSClient;
import org.apache.activemq.artemis.core.config.impl.SecurityConfiguration;
import org.apache.activemq.artemis.rest.HttpHeaderProperty;
import org.apache.activemq.artemis.rest.test.TransformTest;
import org.apache.activemq.artemis.rest.test.Util;
import org.apache.activemq.artemis.spi.core.security.ActiveMQJAASSecurityManager;
import org.apache.activemq.artemis.spi.core.security.jaas.InVMLoginModule;
import org.jboss.logging.Logger;
import org.jboss.resteasy.client.ClientRequest;
import org.jboss.resteasy.client.ClientResponse;
import org.jboss.resteasy.spi.Link;
import org.jboss.resteasy.test.TestPortProvider;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
public class EmbeddedRestActiveMQJMSTest {
private static final Logger log = Logger.getLogger(EmbeddedRestActiveMQJMSTest.class);
private static EmbeddedRestActiveMQ server;
private static ConnectionFactory factory;
private static Link consumeNext;
@BeforeClass
public static void startEmbedded() throws Exception {
server = new EmbeddedRestActiveMQ(null);
assertNotNull(server.getEmbeddedActiveMQ());
server.getManager().setConfigResourcePath("activemq-rest.xml");
SecurityConfiguration securityConfiguration = createDefaultSecurityConfiguration();
ActiveMQJAASSecurityManager securityManager = new ActiveMQJAASSecurityManager(InVMLoginModule.class.getName(), securityConfiguration);
server.getEmbeddedActiveMQ().setSecurityManager(securityManager);
server.start();
factory = ActiveMQJMSClient.createConnectionFactory("vm://0", "cf");
ClientRequest request = new ClientRequest(TestPortProvider.generateURL("/queues/exampleQueue"));
ClientResponse<?> response = request.head();
response.releaseConnection();
assertEquals(200, response.getStatus());
Link sender = response.getLinkHeader().getLinkByTitle("create");
log.debug("create: " + sender);
Link consumers = response.getLinkHeader().getLinkByTitle("pull-consumers");
log.debug("pull: " + consumers);
response = Util.setAutoAck(consumers, true);
consumeNext = response.getLinkHeader().getLinkByTitle("consume-next");
log.debug("consume-next: " + consumeNext);
}
@AfterClass
public static void stopEmbedded() throws Exception {
server.stop();
server = null;
}
@Test
public void shouldReturnStatusOK() throws Exception {
TransformTest.Order order = createTestOrder("1", "$5.00");
publish("exampleQueue", order, null);
ClientResponse<?> res = consumeNext.request().header("Accept-Wait", "2").accept("application/xml").post(String.class);
assertEquals(200, res.getStatus());
res.releaseConnection();
}
@Test
public void shouldReturnPublishedEntity() throws Exception {
TransformTest.Order order = createTestOrder("1", "$5.00");
publish("exampleQueue", order, null);
ClientResponse<?> res = consumeNext.request().header("Accept-Wait", "2").accept("application/xml").post(String.class);
TransformTest.Order order2 = res.getEntity(TransformTest.Order.class);
assertEquals(order, order2);
res.releaseConnection();
}
@Test
public void shouldReturnLink() throws Exception {
TransformTest.Order order = createTestOrder("1", "$5.00");
publish("exampleQueue", order, null);
ClientResponse<?> res = consumeNext.request().header("Accept-Wait", "2").accept("application/xml").post(String.class);
consumeNext = res.getLinkHeader().getLinkByTitle("consume-next");
res.releaseConnection();
assertNotNull(consumeNext);
}
@Test
public void shouldUseXmlAcceptHeaderToSetContentType() throws Exception {
TransformTest.Order order = createTestOrder("1", "$5.00");
publish("exampleQueue", order, null);
ClientResponse<?> res = consumeNext.request().header("Accept-Wait", "2").accept("application/xml").post(String.class);
Assert.assertTrue(res.getHeaders().getFirst("Content-Type").toString().toLowerCase().contains("application/xml"));
consumeNext = res.getLinkHeader().getLinkByTitle("consume-next");
res.releaseConnection();
assertNotNull(consumeNext);
}
@Test
public void shouldUseMessagePropertyToSetContentType() throws Exception {
TransformTest.Order order = createTestOrder("2", "$15.00");
publish("exampleQueue", order, "application/xml");
ClientResponse<?> res = consumeNext.request().header("Accept-Wait", "2").post(String.class);
Assert.assertTrue(res.getHeaders().getFirst("Content-Type").toString().toLowerCase().contains("application/xml"));
consumeNext = res.getLinkHeader().getLinkByTitle("consume-next");
res.releaseConnection();
assertNotNull(consumeNext);
}
@Test
public void shouldUseJsonAcceptHeaderToSetContentType() throws Exception {
TransformTest.Order order = createTestOrder("1", "$5.00");
publish("exampleQueue", order, null);
ClientResponse<?> res = consumeNext.request().header("Accept-Wait", "2").accept("application/json").post(String.class);
assertEquals("application/json", res.getHeaders().getFirst("Content-Type").toString().toLowerCase());
consumeNext = res.getLinkHeader().getLinkByTitle("consume-next");
res.releaseConnection();
assertNotNull(consumeNext);
}
private static SecurityConfiguration createDefaultSecurityConfiguration() {
SecurityConfiguration securityConfiguration = new SecurityConfiguration();
securityConfiguration.addUser("guest", "guest");
securityConfiguration.addRole("guest", "guest");
securityConfiguration.setDefaultUser("guest");
return securityConfiguration;
}
private TransformTest.Order createTestOrder(String name, String amount) {
TransformTest.Order order = new TransformTest.Order();
order.setName(name);
order.setAmount(amount);
return order;
}
private static void publish(String destination, Serializable object, String contentType) throws Exception {
Connection conn = factory.createConnection();
Session session = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
Destination dest = session.createQueue(destination);
try {
assertNotNull("Destination was null", dest);
MessageProducer producer = session.createProducer(dest);
ObjectMessage message = session.createObjectMessage();
if (contentType != null) {
message.setStringProperty(HttpHeaderProperty.CONTENT_TYPE, contentType);
}
message.setObject(object);
producer.send(message);
} finally {
conn.close();
}
}
}

View File

@ -1,88 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.activemq.artemis.rest.test;
import org.apache.activemq.artemis.rest.queue.QueueDeployment;
import org.apache.activemq.artemis.rest.util.Constants;
import org.jboss.logging.Logger;
import org.jboss.resteasy.client.ClientRequest;
import org.jboss.resteasy.client.ClientResponse;
import org.jboss.resteasy.spi.Link;
import org.jboss.resteasy.test.TestPortProvider;
import org.junit.Assert;
import org.junit.Test;
public class AutoAckQueueTest extends MessageTestBase {
private static final Logger log = Logger.getLogger(AutoAckQueueTest.class);
@Test
public void testSuccessFirst() throws Exception {
String testName = "testSuccessFirst";
QueueDeployment deployment = new QueueDeployment();
deployment.setDuplicatesAllowed(true);
deployment.setDurableSend(false);
deployment.setName(testName);
manager.getQueueManager().deploy(deployment);
ClientRequest request = new ClientRequest(TestPortProvider.generateURL("/queues/" + testName));
ClientResponse<?> response = request.head();
response.releaseConnection();
Assert.assertEquals(200, response.getStatus());
Link sender = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "create");
log.debug("create: " + sender);
Link consumers = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "pull-consumers");
log.debug("pull: " + consumers);
log.debug("create-with-id: " + getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "create-with-id"));
response = Util.setAutoAck(consumers, true);
Link consumeNext = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "consume-next");
log.debug("poller: " + consumeNext);
ClientResponse<?> res = sender.request().body("text/plain", Integer.toString(1)).post();
res.releaseConnection();
Assert.assertEquals(201, res.getStatus());
log.debug("create-next: " + getLinkByTitle(manager.getQueueManager().getLinkStrategy(), res, "create-next"));
res = sender.request().body("text/plain", Integer.toString(2)).post();
res.releaseConnection();
Assert.assertEquals(201, res.getStatus());
res = consumeNext.request().post(String.class);
Assert.assertEquals(200, res.getStatus());
Assert.assertEquals("1", res.getEntity(String.class));
res.releaseConnection();
Link session = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), res, "consumer");
log.debug("session: " + session);
consumeNext = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), res, "consume-next");
log.debug("consumeNext: " + consumeNext);
log.debug(consumeNext);
res = consumeNext.request().header(Constants.WAIT_HEADER, "10").post(String.class);
Assert.assertEquals(200, res.getStatus());
Assert.assertEquals("2", res.getEntity(String.class));
res.releaseConnection();
session = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), res, "consumer");
log.debug("session: " + session);
getLinkByTitle(manager.getQueueManager().getLinkStrategy(), res, "consume-next");
log.debug("consumeNext: " + consumeNext);
res = session.request().delete();
res.releaseConnection();
Assert.assertEquals(204, res.getStatus());
}
}

View File

@ -1,216 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.activemq.artemis.rest.test;
import org.apache.activemq.artemis.rest.topic.TopicDeployment;
import org.jboss.logging.Logger;
import org.jboss.resteasy.client.ClientRequest;
import org.jboss.resteasy.client.ClientResponse;
import org.jboss.resteasy.spi.Link;
import org.jboss.resteasy.test.TestPortProvider;
import org.junit.Assert;
import org.junit.Test;
public class AutoAckTopicTest extends MessageTestBase {
private static final Logger log = Logger.getLogger(AutoAckTopicTest.class);
@Test
public void testSuccessFirst() throws Exception {
String testName = "AutoAckTopicTest.testSuccessFirst";
TopicDeployment deployment = new TopicDeployment();
deployment.setDuplicatesAllowed(true);
deployment.setDurableSend(false);
deployment.setName(testName);
manager.getTopicManager().deploy(deployment);
ClientRequest request = new ClientRequest(TestPortProvider.generateURL("/topics/" + testName));
ClientResponse<?> response = request.head();
response.releaseConnection();
Assert.assertEquals(200, response.getStatus());
Link sender = getLinkByTitle(manager.getTopicManager().getLinkStrategy(), response, "create");
Link subscriptions = getLinkByTitle(manager.getTopicManager().getLinkStrategy(), response, "pull-subscriptions");
ClientResponse<?> res = subscriptions.request().post();
res.releaseConnection();
Assert.assertEquals(201, res.getStatus());
Link sub1 = res.getLocationLink();
Assert.assertNotNull(sub1);
Link consumeNext1 = getLinkByTitle(manager.getTopicManager().getLinkStrategy(), res, "consume-next");
Assert.assertNotNull(consumeNext1);
log.debug("consumeNext1: " + consumeNext1);
res = subscriptions.request().post();
res.releaseConnection();
Assert.assertEquals(201, res.getStatus());
Link sub2 = res.getLocationLink();
Assert.assertNotNull(sub2);
Link consumeNext2 = getLinkByTitle(manager.getTopicManager().getLinkStrategy(), res, "consume-next");
Assert.assertNotNull(consumeNext2);
log.debug("consumeNext2: " + consumeNext2);
res = sender.request().body("text/plain", "1").post();
res.releaseConnection();
Assert.assertEquals(201, res.getStatus());
res = sender.request().body("text/plain", "2").post();
res.releaseConnection();
Assert.assertEquals(201, res.getStatus());
res = consumeNext1.request().post(String.class);
Assert.assertEquals(200, res.getStatus());
Assert.assertEquals("1", res.getEntity(String.class));
res.releaseConnection();
consumeNext1 = getLinkByTitle(manager.getTopicManager().getLinkStrategy(), res, "consume-next");
res = consumeNext1.request().post(String.class);
Assert.assertEquals(200, res.getStatus());
Assert.assertEquals("2", res.getEntity(String.class));
res.releaseConnection();
consumeNext1 = getLinkByTitle(manager.getTopicManager().getLinkStrategy(), res, "consume-next");
res = consumeNext2.request().post(String.class);
Assert.assertEquals(200, res.getStatus());
Assert.assertEquals("1", res.getEntity(String.class));
res.releaseConnection();
consumeNext2 = getLinkByTitle(manager.getTopicManager().getLinkStrategy(), res, "consume-next");
res = consumeNext2.request().post(String.class);
Assert.assertEquals(200, res.getStatus());
Assert.assertEquals("2", res.getEntity(String.class));
res.releaseConnection();
consumeNext2 = getLinkByTitle(manager.getTopicManager().getLinkStrategy(), res, "consume-next");
Assert.assertEquals(204, sub1.request().delete().getStatus());
Assert.assertEquals(204, sub2.request().delete().getStatus());
}
@Test
public void testNewSubNotBlockedByTimeoutTask() throws Exception {
// Default config is 1s interval, 300s timeout.
// Create a topic
String testName = "AutoAckTopicTest.testNewSubNotBlockedByTimeoutTask";
TopicDeployment deployment = new TopicDeployment();
deployment.setDuplicatesAllowed(true);
deployment.setDurableSend(false);
deployment.setName(testName);
manager.getTopicManager().deploy(deployment);
// Create a consumer
ClientRequest request = new ClientRequest(TestPortProvider.generateURL("/topics/" + testName));
ClientResponse<?> response = request.head();
response.releaseConnection();
Assert.assertEquals(200, response.getStatus());
Link sender = getLinkByTitle(manager.getTopicManager().getLinkStrategy(), response, "create");
Link subscriptions = getLinkByTitle(manager.getTopicManager().getLinkStrategy(), response, "pull-subscriptions");
// Create the pull-subscription itself.
ClientResponse<?> res = subscriptions.request().post();
res.releaseConnection();
Assert.assertEquals(201, res.getStatus());
Link sub1 = res.getLocationLink();
Assert.assertNotNull(sub1);
Link consumeNext1 = getLinkByTitle(manager.getTopicManager().getLinkStrategy(), res, "consume-next");
Assert.assertNotNull(consumeNext1);
// Pull on the topic for 8s (long enoguh to guarantee the rest of the test
// will pass/fail due to the timeouttask + test operations)
AcceptWaitListener awlistener = new AcceptWaitListener(consumeNext1.getHref());
Thread t = new Thread(awlistener);
t.start();
// Wait 2 seconds to ensure a new TimeoutTask is running concurrently.
Thread.sleep(2000);
// Attempt to create a new pull-subscription. Validate that it takes no longer than 2 seconds
// (it should take like 20ms, but give it a relatively huge amount of leeway)
NewPullSubscriber nps = new NewPullSubscriber(subscriptions.getHref());
Thread npsThread = new Thread(nps);
npsThread.start();
Thread.sleep(2000);
Assert.assertTrue("NewPullSubscriber did not finish in 2 seconds!", nps.isFinished());
Assert.assertFalse("AcceptWaitListener failed to open connection!", awlistener.isFailed());
Assert.assertFalse("NewPullSubscriber failed to open new subscription!", nps.isFailed());
npsThread.interrupt();
t.interrupt();
}
private class NewPullSubscriber implements Runnable {
private final String url;
private boolean isFinished = false;
private boolean failed = false;
private NewPullSubscriber(String url) {
this.url = url;
}
public boolean isFinished() {
return isFinished;
}
public boolean isFailed() {
return failed;
}
@Override
public void run() {
try {
isFinished = false;
ClientRequest request = new ClientRequest(url);
ClientResponse<?> response = request.post();
response.releaseConnection();
log.debug("NPS response: " + response.getStatus());
Assert.assertEquals(201, response.getStatus());
isFinished = true;
} catch (Exception e) {
log.debug("Exception " + e);
failed = true;
}
}
}
private class AcceptWaitListener implements Runnable {
private final int acceptWaitTime = 8;
private String url;
private boolean isFinished = false;
private boolean failed = false;
private AcceptWaitListener(String url) {
this.url = url;
}
public boolean isFinished() {
return this.isFinished;
}
public boolean isFailed() {
return this.failed;
}
@Override
public void run() {
try {
ClientRequest req = new ClientRequest(url);
req.header("Accept-Wait", acceptWaitTime);
ClientResponse<?> response = req.post();
response.releaseConnection();
isFinished = true;
} catch (Exception e) {
failed = true;
}
}
}
}

View File

@ -1,375 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.activemq.artemis.rest.test;
import org.apache.activemq.artemis.rest.queue.QueueDeployment;
import org.apache.activemq.artemis.rest.util.Constants;
import org.apache.activemq.artemis.rest.util.CustomHeaderLinkStrategy;
import org.apache.activemq.artemis.rest.util.LinkHeaderLinkStrategy;
import org.jboss.logging.Logger;
import org.jboss.resteasy.client.ClientRequest;
import org.jboss.resteasy.client.ClientResponse;
import org.jboss.resteasy.spi.Link;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
import static org.jboss.resteasy.test.TestPortProvider.generateURL;
public class ClientAckQueueTest extends MessageTestBase {
private static final Logger log = Logger.getLogger(ClientAckQueueTest.class);
@BeforeClass
public static void setup() throws Exception {
QueueDeployment deployment1 = new QueueDeployment("testQueue", true);
manager.getQueueManager().deploy(deployment1);
}
@Test
public void testAckTimeoutX2() throws Exception {
QueueDeployment deployment = new QueueDeployment();
deployment.setConsumerSessionTimeoutSeconds(1);
deployment.setDuplicatesAllowed(true);
deployment.setDurableSend(false);
deployment.setName("testAck");
manager.getQueueManager().deploy(deployment);
manager.getQueueManager().setLinkStrategy(new LinkHeaderLinkStrategy());
testAckTimeout();
manager.getQueueManager().setLinkStrategy(new CustomHeaderLinkStrategy());
testAckTimeout();
}
private void testAckTimeout() throws Exception {
ClientRequest request = new ClientRequest(generateURL("/queues/testAck"));
ClientResponse<?> response = Util.head(request);
Link sender = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "create");
log.debug("create: " + sender);
Link consumers = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "pull-consumers");
log.debug("pull: " + consumers);
response = Util.setAutoAck(consumers, false);
Link consumeNext = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "acknowledge-next");
log.debug("poller: " + consumeNext);
{
ClientResponse<?> res = sender.request().body("text/plain", Integer.toString(1)).post();
res.releaseConnection();
Assert.assertEquals(201, res.getStatus());
res = consumeNext.request().post(String.class);
res.releaseConnection();
Assert.assertEquals(200, res.getStatus());
Link ack = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), res, "acknowledgement");
log.debug("ack: " + ack);
Assert.assertNotNull(ack);
Link session = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), res, "consumer");
log.debug("session: " + session);
consumeNext = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), res, "acknowledge-next");
log.debug("consumeNext: " + consumeNext);
// test timeout
Thread.sleep(2000);
ClientResponse ackRes = ack.request().formParameter("acknowledge", "true").post();
ackRes.releaseConnection();
Assert.assertEquals(412, ackRes.getStatus());
log.debug("**** Successfully failed ack");
consumeNext = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), ackRes, "acknowledge-next");
log.debug("consumeNext: " + consumeNext);
}
{
ClientResponse<?> res = consumeNext.request().header(Constants.WAIT_HEADER, "2").post(String.class);
res.releaseConnection();
Assert.assertEquals(200, res.getStatus());
Link ack = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), res, "acknowledgement");
log.debug("ack: " + ack);
Assert.assertNotNull(ack);
Link session = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), res, "consumer");
log.debug("session: " + session);
consumeNext = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), res, "acknowledge-next");
log.debug("consumeNext: " + consumeNext);
ClientResponse ackRes = ack.request().formParameter("acknowledge", "true").post();
if (ackRes.getStatus() != 204) {
log.debug(ackRes.getEntity(String.class));
}
ackRes.releaseConnection();
Assert.assertEquals(204, ackRes.getStatus());
Assert.assertEquals(204, session.request().delete().getStatus());
}
}
@Test
public void testSuccessFirstX2() throws Exception {
String testName = "testSuccessFirstX2";
QueueDeployment queueDeployment = new QueueDeployment(testName, true);
manager.getQueueManager().deploy(queueDeployment);
manager.getQueueManager().setLinkStrategy(new LinkHeaderLinkStrategy());
testSuccessFirst(1, testName);
manager.getQueueManager().setLinkStrategy(new CustomHeaderLinkStrategy());
testSuccessFirst(3, testName);
}
private void testSuccessFirst(int start, String queueName) throws Exception {
ClientRequest request = new ClientRequest(generateURL(Util.getUrlPath(queueName)));
ClientResponse<?> response = Util.head(request);
Link sender = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "create");
log.debug("create: " + sender);
Link consumers = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "pull-consumers");
log.debug("pull-consumers: " + consumers);
response = Util.setAutoAck(consumers, false);
Link consumeNext = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "acknowledge-next");
log.debug("acknowledge-next: " + consumeNext);
String data = Integer.toString(start);
log.debug("Sending: " + data);
ClientResponse<?> res = sender.request().body("text/plain", data).post();
res.releaseConnection();
Assert.assertEquals(201, res.getStatus());
log.debug("call acknowledge-next");
res = consumeNext.request().post(String.class);
Assert.assertEquals(200, res.getStatus());
Assert.assertEquals(Integer.toString(start++), res.getEntity());
res.releaseConnection();
Link ack = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), res, "acknowledgement");
log.debug("ack: " + ack);
Assert.assertNotNull(ack);
Link session = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), res, "consumer");
log.debug("session: " + session);
consumeNext = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), res, "acknowledge-next");
log.debug("consumeNext: " + consumeNext);
ClientResponse ackRes = ack.request().formParameter("acknowledge", "true").post();
ackRes.releaseConnection();
Assert.assertEquals(204, ackRes.getStatus());
consumeNext = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), ackRes, "acknowledge-next");
log.debug("sending next...");
String data2 = Integer.toString(start);
log.debug("Sending: " + data2);
res = sender.request().body("text/plain", data2).post();
res.releaseConnection();
Assert.assertEquals(201, res.getStatus());
log.debug(consumeNext);
res = consumeNext.request().header(Constants.WAIT_HEADER, "10").post(String.class);
Assert.assertEquals(200, res.getStatus());
Assert.assertEquals(Integer.toString(start++), res.getEntity());
res.releaseConnection();
ack = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), res, "acknowledgement");
log.debug("ack: " + ack);
Assert.assertNotNull(ack);
session = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), res, "consumer");
log.debug("session: " + session);
ackRes = ack.request().formParameter("acknowledge", "true").post();
ackRes.releaseConnection();
Assert.assertEquals(204, ackRes.getStatus());
consumeNext = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), ackRes, "acknowledge-next");
log.debug("consumeNext: " + consumeNext);
res = consumeNext.request().post(String.class);
res.releaseConnection();
log.debug(res.getStatus());
Assert.assertEquals(204, session.request().delete().getStatus());
}
@Test
public void testPullX2() throws Exception {
String testName = "testPullX2";
QueueDeployment queueDeployment = new QueueDeployment(testName, true);
manager.getQueueManager().deploy(queueDeployment);
manager.getQueueManager().setLinkStrategy(new LinkHeaderLinkStrategy());
testPull(1, testName);
manager.getQueueManager().setLinkStrategy(new CustomHeaderLinkStrategy());
testPull(4, testName);
}
private void testPull(int start, String queueName) throws Exception {
ClientRequest request = new ClientRequest(generateURL(Util.getUrlPath(queueName)));
ClientResponse<?> response = Util.head(request);
Link sender = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "create");
log.debug("create: " + sender);
Link consumers = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "pull-consumers");
log.debug("pull: " + consumers);
response = Util.setAutoAck(consumers, false);
Link consumeNext = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "acknowledge-next");
log.debug("poller: " + consumeNext);
ClientResponse<String> res = consumeNext.request().post(String.class);
res.releaseConnection();
Assert.assertEquals(503, res.getStatus());
consumeNext = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), res, "acknowledge-next");
log.debug(consumeNext);
res = sender.request().body("text/plain", Integer.toString(start)).post();
res.releaseConnection();
Assert.assertEquals(201, res.getStatus());
res = consumeNext.request().post(String.class);
Assert.assertEquals(200, res.getStatus());
Assert.assertEquals(Integer.toString(start++), res.getEntity());
res.releaseConnection();
Link ack = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), res, "acknowledgement");
log.debug("ack: " + ack);
ClientResponse ackRes = ack.request().formParameter("acknowledge", "true").post();
ackRes.releaseConnection();
Assert.assertEquals(204, ackRes.getStatus());
res = consumeNext.request().post();
res.releaseConnection();
Assert.assertEquals(503, res.getStatus());
res = sender.request().body("text/plain", Integer.toString(start)).post();
res.releaseConnection();
Assert.assertEquals(201, res.getStatus());
res = sender.request().body("text/plain", Integer.toString(start + 1)).post();
res.releaseConnection();
Assert.assertEquals(201, res.getStatus());
res = consumeNext.request().post(String.class);
Assert.assertEquals(200, res.getStatus());
Assert.assertEquals(Integer.toString(start++), res.getEntity());
res.releaseConnection();
ack = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), res, "acknowledgement");
log.debug("ack: " + ack);
ackRes = ack.request().formParameter("acknowledge", "true").post();
ackRes.releaseConnection();
Assert.assertEquals(204, ackRes.getStatus());
res = consumeNext.request().post(String.class);
Assert.assertEquals(200, res.getStatus());
Assert.assertEquals(Integer.toString(start++), res.getEntity());
res.releaseConnection();
ack = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), res, "acknowledgement");
log.debug("ack: " + ack);
ackRes = ack.request().formParameter("acknowledge", "true").post();
ackRes.releaseConnection();
Assert.assertEquals(204, ackRes.getStatus());
Link session = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), ackRes, "consumer");
res = consumeNext.request().post();
res.releaseConnection();
Assert.assertEquals(503, res.getStatus());
log.debug(session);
res = session.request().delete();
res.releaseConnection();
Assert.assertEquals(204, res.getStatus());
}
@Test
public void testReconnectX2() throws Exception {
String testName = "testReconnectX2";
QueueDeployment queueDeployment = new QueueDeployment(testName, true);
manager.getQueueManager().deploy(queueDeployment);
manager.getQueueManager().setLinkStrategy(new LinkHeaderLinkStrategy());
testReconnect(testName);
manager.getQueueManager().setLinkStrategy(new CustomHeaderLinkStrategy());
testReconnect(testName);
}
private void testReconnect(String queueName) throws Exception {
ClientRequest request = new ClientRequest(generateURL(Util.getUrlPath(queueName)));
ClientResponse<?> response = Util.head(request);
Link sender = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "create");
log.debug("create: " + sender);
Link consumers = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "pull-consumers");
log.debug("pull: " + consumers);
response = Util.setAutoAck(consumers, false);
Link consumeNext = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "acknowledge-next");
log.debug("poller: " + consumeNext);
ClientResponse<?> res = sender.request().body("text/plain", Integer.toString(1)).post();
res.releaseConnection();
Assert.assertEquals(201, res.getStatus());
res = consumeNext.request().post(String.class);
res.releaseConnection();
Assert.assertEquals(200, res.getStatus());
Link ack = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), res, "acknowledgement");
log.debug("ack: " + ack);
Assert.assertNotNull(ack);
Link session = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), res, "consumer");
log.debug("session: " + session);
consumeNext = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), res, "acknowledge-next");
log.debug("consumeNext: " + consumeNext);
ClientResponse ackRes = ack.request().formParameter("acknowledge", "true").post();
ackRes.releaseConnection();
Assert.assertEquals(204, ackRes.getStatus());
consumeNext = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), ackRes, "acknowledge-next");
log.debug("before close session consumeNext: " + consumeNext);
// test reconnect with a disconnected acknowledge-next
Assert.assertEquals(204, session.request().delete().getStatus());
res = sender.request().body("text/plain", Integer.toString(2)).post();
res.releaseConnection();
Assert.assertEquals(201, res.getStatus());
res = consumeNext.request().header(Constants.WAIT_HEADER, "10").post(String.class);
res.releaseConnection();
Assert.assertEquals(200, res.getStatus());
ack = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), res, "acknowledgement");
log.debug("ack: " + ack);
Assert.assertNotNull(ack);
ackRes = ack.request().formParameter("acknowledge", "true").post();
ackRes.releaseConnection();
Assert.assertEquals(204, ackRes.getStatus());
session = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), ackRes, "consumer");
consumeNext = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), ackRes, "acknowledge-next");
log.debug("session: " + session);
// test reconnect with disconnected acknowledge
res = sender.request().body("text/plain", Integer.toString(3)).post();
res.releaseConnection();
Assert.assertEquals(201, res.getStatus());
res = consumeNext.request().header(Constants.WAIT_HEADER, "10").post(String.class);
res.releaseConnection();
Assert.assertEquals(200, res.getStatus());
ack = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), res, "acknowledgement");
log.debug("ack: " + ack);
Assert.assertNotNull(ack);
Assert.assertEquals(204, session.request().delete().getStatus());
ackRes = ack.request().formParameter("acknowledge", "true").post();
ackRes.releaseConnection();
Assert.assertEquals(412, ackRes.getStatus());
consumeNext = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), ackRes, "acknowledge-next");
res = consumeNext.request().header(Constants.WAIT_HEADER, "10").post(String.class);
res.releaseConnection();
Assert.assertEquals(200, res.getStatus());
ack = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), res, "acknowledgement");
log.debug("ack: " + ack);
Assert.assertNotNull(ack);
ackRes = ack.request().formParameter("acknowledge", "true").post();
ackRes.releaseConnection();
Assert.assertEquals(204, ackRes.getStatus());
session = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), ackRes, "consumer");
Assert.assertEquals(204, session.request().delete().getStatus());
}
}

View File

@ -1,318 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.activemq.artemis.rest.test;
import org.apache.activemq.artemis.rest.topic.TopicDeployment;
import org.apache.activemq.artemis.rest.util.Constants;
import org.apache.activemq.artemis.rest.util.CustomHeaderLinkStrategy;
import org.apache.activemq.artemis.rest.util.LinkHeaderLinkStrategy;
import org.jboss.logging.Logger;
import org.jboss.resteasy.client.ClientRequest;
import org.jboss.resteasy.client.ClientResponse;
import org.jboss.resteasy.spi.Link;
import org.jboss.resteasy.test.TestPortProvider;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
public class ClientAckTopicTest extends MessageTestBase {
private static final Logger log = Logger.getLogger(ClientAckTopicTest.class);
@BeforeClass
public static void setup() throws Exception {
TopicDeployment deployment1 = new TopicDeployment("testQueue", true);
manager.getTopicManager().deploy(deployment1);
}
@Test
public void testAckTimeoutX2() throws Exception {
TopicDeployment deployment = new TopicDeployment();
deployment.setConsumerSessionTimeoutSeconds(1);
deployment.setDuplicatesAllowed(true);
deployment.setDurableSend(false);
deployment.setName("testAck");
manager.getTopicManager().deploy(deployment);
manager.getTopicManager().setLinkStrategy(new LinkHeaderLinkStrategy());
testAckTimeout();
manager.getTopicManager().setLinkStrategy(new CustomHeaderLinkStrategy());
testAckTimeout();
}
private void testAckTimeout() throws Exception {
ClientRequest request = new ClientRequest(TestPortProvider.generateURL("/topics/testAck"));
ClientResponse<?> response = request.head();
response.releaseConnection();
Assert.assertEquals(200, response.getStatus());
Link sender = getLinkByTitle(manager.getTopicManager().getLinkStrategy(), response, "create");
log.debug("create: " + sender);
Link subscriptions = getLinkByTitle(manager.getTopicManager().getLinkStrategy(), response, "pull-subscriptions");
response = subscriptions.request().formParameter("autoAck", "false").formParameter("durable", "true").post();
response.releaseConnection();
Assert.assertEquals(201, response.getStatus());
Link sub1 = response.getLocationLink();
Assert.assertNotNull(sub1);
Link consumeNext = getLinkByTitle(manager.getTopicManager().getLinkStrategy(), response, "acknowledge-next");
log.debug("poller: " + consumeNext);
{
ClientResponse<?> res = sender.request().body("text/plain", Integer.toString(1)).post();
res.releaseConnection();
Assert.assertEquals(201, res.getStatus());
res = consumeNext.request().post(String.class);
res.releaseConnection();
Assert.assertEquals(200, res.getStatus());
Link ack = getLinkByTitle(manager.getTopicManager().getLinkStrategy(), res, "acknowledgement");
log.debug("ack: " + ack);
Assert.assertNotNull(ack);
Link session = getLinkByTitle(manager.getTopicManager().getLinkStrategy(), res, "consumer");
log.debug("session: " + session);
consumeNext = getLinkByTitle(manager.getTopicManager().getLinkStrategy(), res, "acknowledge-next");
log.debug("consumeNext: " + consumeNext);
// test timeout
Thread.sleep(2000);
ClientResponse ackRes = ack.request().formParameter("acknowledge", "true").post();
if (ackRes.getStatus() == 500) {
log.debug("Failure: " + ackRes.getEntity(String.class));
}
ackRes.releaseConnection();
Assert.assertEquals(412, ackRes.getStatus());
log.debug("**** Successfully failed ack");
consumeNext = getLinkByTitle(manager.getTopicManager().getLinkStrategy(), ackRes, "acknowledge-next");
log.debug("consumeNext: " + consumeNext);
}
{
ClientResponse<?> res = consumeNext.request().header(Constants.WAIT_HEADER, "2").post(String.class);
res.releaseConnection();
Assert.assertEquals(200, res.getStatus());
Link ack = getLinkByTitle(manager.getTopicManager().getLinkStrategy(), res, "acknowledgement");
log.debug("ack: " + ack);
Assert.assertNotNull(ack);
consumeNext = getLinkByTitle(manager.getTopicManager().getLinkStrategy(), res, "acknowledge-next");
log.debug("consumeNext: " + consumeNext);
ClientResponse ackRes = ack.request().formParameter("acknowledge", "true").post();
if (ackRes.getStatus() != 204) {
log.debug(ackRes.getEntity(String.class));
}
ackRes.releaseConnection();
Assert.assertEquals(204, ackRes.getStatus());
}
Assert.assertEquals(204, sub1.request().delete().getStatus());
}
@Test
public void testSuccessFirst() throws Exception {
ClientRequest request = new ClientRequest(TestPortProvider.generateURL("/topics/testQueue"));
ClientResponse<?> response = request.head();
response.releaseConnection();
Assert.assertEquals(200, response.getStatus());
Link sender = getLinkByTitle(manager.getTopicManager().getLinkStrategy(), response, "create");
log.debug("create: " + sender);
Link subscriptions = getLinkByTitle(manager.getTopicManager().getLinkStrategy(), response, "pull-subscriptions");
response = subscriptions.request().formParameter("autoAck", "false").formParameter("durable", "true").post();
response.releaseConnection();
Assert.assertEquals(201, response.getStatus());
Link sub1 = response.getLocationLink();
Assert.assertNotNull(sub1);
Link consumeNext = getLinkByTitle(manager.getTopicManager().getLinkStrategy(), response, "acknowledge-next");
log.debug("poller: " + consumeNext);
ClientResponse<?> res = sender.request().body("text/plain", Integer.toString(1)).post();
res.releaseConnection();
Assert.assertEquals(201, res.getStatus());
log.debug("call ack next");
res = consumeNext.request().post(String.class);
res.releaseConnection();
Assert.assertEquals(200, res.getStatus());
Link ack = getLinkByTitle(manager.getTopicManager().getLinkStrategy(), res, "acknowledgement");
log.debug("ack: " + ack);
Assert.assertNotNull(ack);
Link session = getLinkByTitle(manager.getTopicManager().getLinkStrategy(), res, "consumer");
log.debug("session: " + session);
consumeNext = getLinkByTitle(manager.getTopicManager().getLinkStrategy(), res, "acknowledge-next");
log.debug("consumeNext: " + consumeNext);
ClientResponse ackRes = ack.request().formParameter("acknowledge", "true").post();
ackRes.releaseConnection();
Assert.assertEquals(204, ackRes.getStatus());
consumeNext = getLinkByTitle(manager.getTopicManager().getLinkStrategy(), ackRes, "acknowledge-next");
log.debug("sending next...");
res = sender.request().body("text/plain", Integer.toString(2)).post();
res.releaseConnection();
Assert.assertEquals(201, res.getStatus());
log.debug(consumeNext);
res = consumeNext.request().header(Constants.WAIT_HEADER, "10").post(String.class);
res.releaseConnection();
Assert.assertEquals(200, res.getStatus());
ack = getLinkByTitle(manager.getTopicManager().getLinkStrategy(), res, "acknowledgement");
log.debug("ack: " + ack);
Assert.assertNotNull(ack);
getLinkByTitle(manager.getTopicManager().getLinkStrategy(), res, "acknowledge-next");
log.debug("consumeNext: " + consumeNext);
ackRes = ack.request().formParameter("acknowledge", "true").post();
ackRes.releaseConnection();
Assert.assertEquals(204, ackRes.getStatus());
Assert.assertEquals(204, sub1.request().delete().getStatus());
}
@Test
public void testSuccessFirstNonDurable() throws Exception {
ClientRequest request = new ClientRequest(TestPortProvider.generateURL("/topics/testQueue"));
ClientResponse<?> response = request.head();
response.releaseConnection();
Assert.assertEquals(200, response.getStatus());
Link sender = getLinkByTitle(manager.getTopicManager().getLinkStrategy(), response, "create");
log.debug("create: " + sender);
Link subscriptions = getLinkByTitle(manager.getTopicManager().getLinkStrategy(), response, "pull-subscriptions");
response = subscriptions.request().formParameter("autoAck", "false").formParameter("durable", "false").post();
response.releaseConnection();
Assert.assertEquals(201, response.getStatus());
Link sub1 = response.getLocationLink();
Assert.assertNotNull(sub1);
Link consumeNext = getLinkByTitle(manager.getTopicManager().getLinkStrategy(), response, "acknowledge-next");
log.debug("poller: " + consumeNext);
ClientResponse<?> res = sender.request().body("text/plain", Integer.toString(1)).post();
res.releaseConnection();
Assert.assertEquals(201, res.getStatus());
log.debug("call ack next");
res = consumeNext.request().post(String.class);
res.releaseConnection();
Assert.assertEquals(200, res.getStatus());
Link ack = getLinkByTitle(manager.getTopicManager().getLinkStrategy(), res, "acknowledgement");
log.debug("ack: " + ack);
Assert.assertNotNull(ack);
Link session = getLinkByTitle(manager.getTopicManager().getLinkStrategy(), res, "consumer");
log.debug("session: " + session);
consumeNext = getLinkByTitle(manager.getTopicManager().getLinkStrategy(), res, "acknowledge-next");
log.debug("consumeNext: " + consumeNext);
ClientResponse ackRes = ack.request().formParameter("acknowledge", "true").post();
ackRes.releaseConnection();
Assert.assertEquals(204, ackRes.getStatus());
consumeNext = getLinkByTitle(manager.getTopicManager().getLinkStrategy(), ackRes, "acknowledge-next");
log.debug("sending next...");
res = sender.request().body("text/plain", Integer.toString(2)).post();
res.releaseConnection();
Assert.assertEquals(201, res.getStatus());
log.debug(consumeNext);
res = consumeNext.request().header(Constants.WAIT_HEADER, "10").post(String.class);
res.releaseConnection();
Assert.assertEquals(200, res.getStatus());
ack = getLinkByTitle(manager.getTopicManager().getLinkStrategy(), res, "acknowledgement");
log.debug("ack: " + ack);
Assert.assertNotNull(ack);
getLinkByTitle(manager.getTopicManager().getLinkStrategy(), res, "acknowledge-next");
log.debug("consumeNext: " + consumeNext);
ackRes = ack.request().formParameter("acknowledge", "true").post();
ackRes.releaseConnection();
Assert.assertEquals(204, ackRes.getStatus());
Assert.assertEquals(204, sub1.request().delete().getStatus());
}
@Test
public void testPull() throws Exception {
ClientRequest request = new ClientRequest(TestPortProvider.generateURL("/topics/testQueue"));
ClientResponse<?> response = request.head();
response.releaseConnection();
Assert.assertEquals(200, response.getStatus());
Link sender = getLinkByTitle(manager.getTopicManager().getLinkStrategy(), response, "create");
log.debug("create: " + sender);
Link subscriptions = getLinkByTitle(manager.getTopicManager().getLinkStrategy(), response, "pull-subscriptions");
response = subscriptions.request().formParameter("autoAck", "false").formParameter("durable", "true").post();
response.releaseConnection();
Assert.assertEquals(201, response.getStatus());
Link sub1 = response.getLocationLink();
Assert.assertNotNull(sub1);
Link consumeNext = getLinkByTitle(manager.getTopicManager().getLinkStrategy(), response, "acknowledge-next");
log.debug("poller: " + consumeNext);
ClientResponse<String> res = consumeNext.request().post(String.class);
res.releaseConnection();
Assert.assertEquals(503, res.getStatus());
consumeNext = getLinkByTitle(manager.getTopicManager().getLinkStrategy(), res, "acknowledge-next");
log.debug(consumeNext);
res = sender.request().body("text/plain", Integer.toString(1)).post();
res.releaseConnection();
Assert.assertEquals(201, res.getStatus());
res = consumeNext.request().post(String.class);
Assert.assertEquals(200, res.getStatus());
Assert.assertEquals(Integer.toString(1), res.getEntity());
res.releaseConnection();
Link ack = getLinkByTitle(manager.getTopicManager().getLinkStrategy(), res, "acknowledgement");
log.debug("ack: " + ack);
ClientResponse ackRes = ack.request().formParameter("acknowledge", "true").post();
ackRes.releaseConnection();
Assert.assertEquals(204, ackRes.getStatus());
res = consumeNext.request().post();
res.releaseConnection();
Assert.assertEquals(503, res.getStatus());
res = sender.request().body("text/plain", Integer.toString(2)).post();
res.releaseConnection();
Assert.assertEquals(201, res.getStatus());
res = sender.request().body("text/plain", Integer.toString(3)).post();
res.releaseConnection();
Assert.assertEquals(201, res.getStatus());
res = consumeNext.request().post(String.class);
Assert.assertEquals(200, res.getStatus());
Assert.assertEquals(Integer.toString(2), res.getEntity());
res.releaseConnection();
ack = getLinkByTitle(manager.getTopicManager().getLinkStrategy(), res, "acknowledgement");
log.debug("ack: " + ack);
ackRes = ack.request().formParameter("acknowledge", "true").post();
ackRes.releaseConnection();
Assert.assertEquals(204, ackRes.getStatus());
res = consumeNext.request().post(String.class);
Assert.assertEquals(200, res.getStatus());
Assert.assertEquals(Integer.toString(3), res.getEntity());
res.releaseConnection();
ack = getLinkByTitle(manager.getTopicManager().getLinkStrategy(), res, "acknowledgement");
log.debug("ack: " + ack);
ackRes = ack.request().formParameter("acknowledge", "true").post();
ackRes.releaseConnection();
Assert.assertEquals(204, ackRes.getStatus());
res = consumeNext.request().post();
res.releaseConnection();
Assert.assertEquals(503, res.getStatus());
log.debug(sub1);
res = sub1.request().delete();
res.releaseConnection();
Assert.assertEquals(204, res.getStatus());
}
}

View File

@ -1,179 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.activemq.artemis.rest.test;
import org.apache.activemq.artemis.rest.util.Constants;
import org.jboss.logging.Logger;
import org.jboss.resteasy.client.ClientRequest;
import org.jboss.resteasy.client.ClientResponse;
import org.jboss.resteasy.spi.Link;
import org.jboss.resteasy.test.TestPortProvider;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
public class CreateDestinationTest extends MessageTestBase {
private static final Logger log = Logger.getLogger(CreateDestinationTest.class);
@BeforeClass
public static void reg() {
server.getJaxrsServer().getDeployment().getProviderFactory().registerProvider(org.jboss.resteasy.plugins.providers.DocumentProvider.class);
}
@Test
public void testCreateQueue() throws Exception {
String queueConfig = "<queue name=\"testQueue\"><durable>true</durable></queue>";
ClientRequest create = new ClientRequest(TestPortProvider.generateURL("/queues"));
ClientResponse cRes = create.body("application/activemq.jms.queue+xml", queueConfig).post();
cRes.releaseConnection();
Assert.assertEquals(201, cRes.getStatus());
log.debug("Location: " + cRes.getLocationLink());
ClientRequest request = cRes.getLocationLink().request();
ClientResponse<?> response = request.head();
response.releaseConnection();
Assert.assertEquals(200, response.getStatus());
Link sender = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "create");
log.debug("create: " + sender);
Link consumers = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "pull-consumers");
log.debug("pull: " + consumers);
response = Util.setAutoAck(consumers, true);
Link consumeNext = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "consume-next");
log.debug("poller: " + consumeNext);
ClientResponse<?> res = sender.request().body("text/plain", Integer.toString(1)).post();
res.releaseConnection();
Assert.assertEquals(201, res.getStatus());
res = consumeNext.request().post(String.class);
Assert.assertEquals(200, res.getStatus());
Assert.assertEquals("1", res.getEntity(String.class));
res.releaseConnection();
Link session = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), res, "consumer");
log.debug("session: " + session);
consumeNext = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), res, "consume-next");
log.debug("consumeNext: " + consumeNext);
res = sender.request().body("text/plain", Integer.toString(2)).post();
res.releaseConnection();
Assert.assertEquals(201, res.getStatus());
log.debug(consumeNext);
res = consumeNext.request().header(Constants.WAIT_HEADER, "10").post(String.class);
Assert.assertEquals(200, res.getStatus());
Assert.assertEquals("2", res.getEntity(String.class));
res.releaseConnection();
session = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), res, "consumer");
log.debug("session: " + session);
getLinkByTitle(manager.getQueueManager().getLinkStrategy(), res, "consume-next");
log.debug("consumeNext: " + consumeNext);
res = session.request().delete();
res.releaseConnection();
Assert.assertEquals(204, res.getStatus());
}
@Test
public void testCreateTopic() throws Exception {
String queueConfig = "<topic name=\"testTopic\"></topic>";
ClientRequest create = new ClientRequest(TestPortProvider.generateURL("/topics"));
ClientResponse cRes = create.body("application/activemq.jms.topic+xml", queueConfig).post();
cRes.releaseConnection();
Assert.assertEquals(201, cRes.getStatus());
ClientRequest request = cRes.getLocationLink().request();
ClientResponse<?> response = request.head();
response.releaseConnection();
Assert.assertEquals(200, response.getStatus());
Link sender = getLinkByTitle(manager.getTopicManager().getLinkStrategy(), response, "create");
Link subscriptions = getLinkByTitle(manager.getTopicManager().getLinkStrategy(), response, "pull-subscriptions");
ClientResponse<?> res = subscriptions.request().post();
res.releaseConnection();
Assert.assertEquals(201, res.getStatus());
Link sub1 = res.getLocationLink();
Assert.assertNotNull(sub1);
Link consumeNext1 = getLinkByTitle(manager.getTopicManager().getLinkStrategy(), res, "consume-next");
Assert.assertNotNull(consumeNext1);
log.debug("consumeNext1: " + consumeNext1);
res = subscriptions.request().post();
res.releaseConnection();
Assert.assertEquals(201, res.getStatus());
Link sub2 = res.getLocationLink();
Assert.assertNotNull(sub2);
Link consumeNext2 = getLinkByTitle(manager.getTopicManager().getLinkStrategy(), res, "consume-next");
Assert.assertNotNull(consumeNext1);
res = sender.request().body("text/plain", Integer.toString(1)).post();
res.releaseConnection();
Assert.assertEquals(201, res.getStatus());
res = sender.request().body("text/plain", Integer.toString(2)).post();
res.releaseConnection();
Assert.assertEquals(201, res.getStatus());
res = consumeNext1.request().post(String.class);
Assert.assertEquals(200, res.getStatus());
Assert.assertEquals("1", res.getEntity(String.class));
res.releaseConnection();
consumeNext1 = getLinkByTitle(manager.getTopicManager().getLinkStrategy(), res, "consume-next");
res = consumeNext1.request().post(String.class);
Assert.assertEquals(200, res.getStatus());
Assert.assertEquals("2", res.getEntity(String.class));
res.releaseConnection();
consumeNext1 = getLinkByTitle(manager.getTopicManager().getLinkStrategy(), res, "consume-next");
res = consumeNext2.request().post(String.class);
Assert.assertEquals(200, res.getStatus());
Assert.assertEquals("1", res.getEntity(String.class));
res.releaseConnection();
consumeNext2 = getLinkByTitle(manager.getTopicManager().getLinkStrategy(), res, "consume-next");
res = consumeNext2.request().post(String.class);
Assert.assertEquals(200, res.getStatus());
Assert.assertEquals("2", res.getEntity(String.class));
res.releaseConnection();
consumeNext2 = getLinkByTitle(manager.getTopicManager().getLinkStrategy(), res, "consume-next");
res = sub1.request().delete();
res.releaseConnection();
Assert.assertEquals(204, res.getStatus());
res = sub2.request().delete();
res.releaseConnection();
Assert.assertEquals(204, res.getStatus());
}
@Test
public void testCreateQueueWithBadContentType() throws Exception {
String queueConfig = "<queue name=\"testQueue\"><durable>true</durable></queue>";
ClientRequest create = new ClientRequest(TestPortProvider.generateURL("/queues"));
ClientResponse cRes = create.body("application/x-www-form-urlencoded", queueConfig).post();
cRes.releaseConnection();
Assert.assertEquals(415, cRes.getStatus());
}
@Test
public void testCreateTopicWithBadContentType() throws Exception {
String queueConfig = "<topic name=\"testTopic\"></topic>";
ClientRequest create = new ClientRequest(TestPortProvider.generateURL("/topics"));
ClientResponse cRes = create.body("application/x-www-form-urlencoded", queueConfig).post();
cRes.releaseConnection();
Assert.assertEquals(415, cRes.getStatus());
}
}

View File

@ -1,153 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.activemq.artemis.rest.test;
import org.apache.activemq.artemis.rest.queue.QueueDeployment;
import org.apache.activemq.artemis.rest.util.Constants;
import org.jboss.logging.Logger;
import org.jboss.resteasy.client.ClientRequest;
import org.jboss.resteasy.client.ClientResponse;
import org.jboss.resteasy.spi.Link;
import org.junit.Assert;
import org.junit.Test;
import static org.jboss.resteasy.test.TestPortProvider.generateURL;
public class DupQueueTest extends MessageTestBase {
private static final Logger log = Logger.getLogger(DupQueueTest.class);
@Test
public void testDup() throws Exception {
String testName = "testDup";
QueueDeployment deployment = new QueueDeployment();
deployment.setDuplicatesAllowed(false);
deployment.setDurableSend(false);
deployment.setName(testName);
manager.getQueueManager().deploy(deployment);
ClientRequest request = new ClientRequest(generateURL("/queues/" + testName));
ClientResponse<?> response = request.head();
Assert.assertEquals(200, response.getStatus());
Link sender = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "create");
log.debug("create: " + sender);
Link consumers = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "pull-consumers");
log.debug("pull: " + consumers);
response = Util.setAutoAck(consumers, true);
Link consumeNext = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "consume-next");
log.debug("poller: " + consumeNext);
ClientResponse<?> res = sender.request().body("text/plain", Integer.toString(1)).post();
Assert.assertEquals(307, res.getStatus());
sender = res.getLocationLink();
res.releaseConnection();
log.debug("create-next: " + sender);
Assert.assertNotNull(sender);
res = sender.request().body("text/plain", Integer.toString(1)).post();
res.releaseConnection();
Assert.assertEquals(201, res.getStatus());
res = sender.request().body("text/plain", Integer.toString(1)).post();
res.releaseConnection();
Assert.assertEquals(201, res.getStatus());
sender = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), res, "create-next");
res = sender.request().body("text/plain", Integer.toString(2)).post();
res.releaseConnection();
Assert.assertEquals(201, res.getStatus());
res = consumeNext.request().post(String.class);
Assert.assertEquals(200, res.getStatus());
Assert.assertEquals("1", res.getEntity(String.class));
res.releaseConnection();
Link session = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), res, "consumer");
log.debug("session: " + session);
consumeNext = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), res, "consume-next");
log.debug("consumeNext: " + consumeNext);
res = consumeNext.request().header(Constants.WAIT_HEADER, "10").post(String.class);
Assert.assertEquals(200, res.getStatus());
res.releaseConnection();
session = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), res, "consumer");
log.debug("session: " + session);
consumeNext = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), res, "consume-next");
log.debug("consumeNext: " + consumeNext);
res = consumeNext.request().post(String.class);
res.releaseConnection();
res = session.request().delete();
res.releaseConnection();
Assert.assertEquals(204, res.getStatus());
}
@Test
public void testDupWithId() throws Exception {
String testName = "testDupWithId";
QueueDeployment deployment = new QueueDeployment();
deployment.setDuplicatesAllowed(false);
deployment.setDurableSend(false);
deployment.setName(testName);
manager.getQueueManager().deploy(deployment);
ClientRequest request = new ClientRequest(generateURL("/queues/" + testName));
ClientResponse<?> response = request.head();
response.releaseConnection();
Assert.assertEquals(200, response.getStatus());
Link sender = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "create-with-id");
log.debug("create: " + sender);
Link consumers = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "pull-consumers");
log.debug("pull: " + consumers);
response = Util.setAutoAck(consumers, true);
Link consumeNext = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "consume-next");
log.debug("poller: " + consumeNext);
ClientResponse<?> res = sender.request().pathParameter("id", "1").body("text/plain", Integer.toString(1)).post();
res.releaseConnection();
Assert.assertEquals(201, res.getStatus());
res = sender.request().body("text/plain", Integer.toString(1)).pathParameter("id", "1").post();
res.releaseConnection();
Assert.assertEquals(201, res.getStatus());
sender = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), res, "create-next");
res = sender.request().body("text/plain", Integer.toString(2)).post();
res.releaseConnection();
Assert.assertEquals(201, res.getStatus());
res = consumeNext.request().post(String.class);
Assert.assertEquals(200, res.getStatus());
Assert.assertEquals("1", res.getEntity(String.class));
res.releaseConnection();
Link session = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), res, "consumer");
log.debug("session: " + session);
consumeNext = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), res, "consume-next");
log.debug("consumeNext: " + consumeNext);
res = consumeNext.request().header(Constants.WAIT_HEADER, "10").post(String.class);
Assert.assertEquals(200, res.getStatus());
Assert.assertEquals("2", res.getEntity(String.class));
res.releaseConnection();
session = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), res, "consumer");
log.debug("session: " + session);
consumeNext = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), res, "consume-next");
log.debug("consumeNext: " + consumeNext);
res = consumeNext.request().post(String.class);
res.releaseConnection();
Assert.assertEquals(503, res.getStatus());
res = session.request().delete();
res.releaseConnection();
Assert.assertEquals(204, res.getStatus());
}
}

View File

@ -1,93 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.activemq.artemis.rest.test;
import org.apache.activemq.artemis.api.core.TransportConfiguration;
import org.apache.activemq.artemis.core.config.Configuration;
import org.apache.activemq.artemis.core.config.impl.ConfigurationImpl;
import org.apache.activemq.artemis.core.remoting.impl.invm.InVMAcceptorFactory;
import org.apache.activemq.artemis.core.server.ActiveMQServer;
import org.apache.activemq.artemis.core.server.ActiveMQServers;
import org.apache.activemq.artemis.rest.MessageServiceConfiguration;
import org.apache.activemq.artemis.rest.MessageServiceManager;
import org.jboss.logging.Logger;
import org.jboss.resteasy.plugins.server.tjws.TJWSEmbeddedJaxrsServer;
import org.jboss.resteasy.test.TestPortProvider;
public class Embedded {
private static final Logger log = Logger.getLogger(Embedded.class);
protected MessageServiceManager manager = new MessageServiceManager(null);
protected MessageServiceConfiguration config = new MessageServiceConfiguration();
protected ActiveMQServer activeMQServer;
protected TJWSEmbeddedJaxrsServer tjws = new TJWSEmbeddedJaxrsServer();
public Embedded() {
int port = TestPortProvider.getPort();
log.debug("default port is: " + port);
tjws.setPort(port);
tjws.setRootResourcePath("");
tjws.setSecurityDomain(null);
}
public MessageServiceConfiguration getConfig() {
return config;
}
public void setConfig(MessageServiceConfiguration config) {
this.config = config;
}
public ActiveMQServer getActiveMQServer() {
return activeMQServer;
}
public void setActiveMQServer(ActiveMQServer activeMQServer) {
this.activeMQServer = activeMQServer;
}
public TJWSEmbeddedJaxrsServer getJaxrsServer() {
return tjws;
}
public MessageServiceManager getManager() {
return manager;
}
public void start() throws Exception {
log.debug("\nStarting Embedded");
if (activeMQServer == null) {
Configuration configuration = new ConfigurationImpl().setPersistenceEnabled(false).setSecurityEnabled(false).addAcceptorConfiguration(new TransportConfiguration(InVMAcceptorFactory.class.getName()));
activeMQServer = ActiveMQServers.newActiveMQServer(configuration);
activeMQServer.start();
}
tjws.start();
manager.setConfiguration(config);
manager.start();
tjws.getDeployment().getRegistry().addSingletonResource(manager.getQueueManager().getDestination());
tjws.getDeployment().getRegistry().addSingletonResource(manager.getTopicManager().getDestination());
}
public void stop() throws Exception {
log.debug("\nStopping Embedded");
manager.stop();
tjws.stop();
activeMQServer.stop();
}
}

View File

@ -1,156 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.activemq.artemis.rest.test;
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.Destination;
import javax.jms.MessageProducer;
import javax.jms.ObjectMessage;
import javax.jms.Session;
import java.io.Serializable;
import org.apache.activemq.artemis.api.jms.ActiveMQJMSClient;
import org.apache.activemq.artemis.core.config.impl.SecurityConfiguration;
import org.apache.activemq.artemis.rest.HttpHeaderProperty;
import org.apache.activemq.artemis.rest.integration.EmbeddedRestActiveMQ;
import org.apache.activemq.artemis.spi.core.security.ActiveMQJAASSecurityManager;
import org.apache.activemq.artemis.spi.core.security.jaas.InVMLoginModule;
import org.jboss.logging.Logger;
import org.jboss.resteasy.client.ClientRequest;
import org.jboss.resteasy.client.ClientResponse;
import org.jboss.resteasy.spi.Link;
import org.jboss.resteasy.test.TestPortProvider;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
public class EmbeddedTest {
private static final Logger log = Logger.getLogger(EmbeddedTest.class);
public static EmbeddedRestActiveMQ server;
@BeforeClass
public static void startEmbedded() throws Exception {
server = new EmbeddedRestActiveMQ(null);
server.getManager().setConfigResourcePath("activemq-rest.xml");
SecurityConfiguration securityConfiguration = new SecurityConfiguration();
securityConfiguration.addUser("guest", "guest");
securityConfiguration.addRole("guest", "guest");
securityConfiguration.setDefaultUser("guest");
ActiveMQJAASSecurityManager securityManager = new ActiveMQJAASSecurityManager(InVMLoginModule.class.getName(), securityConfiguration);
server.getEmbeddedActiveMQ().setSecurityManager(securityManager);
server.start();
}
@AfterClass
public static void stopEmbedded() throws Exception {
server.stop();
server = null;
}
public static void publish(String destination, Serializable object, String contentType) throws Exception {
ConnectionFactory factory = ActiveMQJMSClient.createConnectionFactory("vm://0","cf");
Connection conn = factory.createConnection();
Session session = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
Destination dest = session.createQueue(destination);
try {
Assert.assertNotNull("Destination was null", dest);
MessageProducer producer = session.createProducer(dest);
ObjectMessage message = session.createObjectMessage();
if (contentType != null) {
message.setStringProperty(HttpHeaderProperty.CONTENT_TYPE, contentType);
}
message.setObject(object);
producer.send(message);
} finally {
conn.close();
}
}
@Test
public void testTransform() throws Exception {
ClientRequest request = new ClientRequest(TestPortProvider.generateURL("/queues/exampleQueue"));
ClientResponse<?> response = request.head();
response.releaseConnection();
Assert.assertEquals(200, response.getStatus());
Link sender = response.getLinkHeader().getLinkByTitle("create");
log.debug("create: " + sender);
Link consumers = response.getLinkHeader().getLinkByTitle("pull-consumers");
log.debug("pull: " + consumers);
response = Util.setAutoAck(consumers, true);
Link consumeNext = response.getLinkHeader().getLinkByTitle("consume-next");
log.debug("consume-next: " + consumeNext);
// test that Accept header is used to set content-type
{
TransformTest.Order order = new TransformTest.Order();
order.setName("1");
order.setAmount("$5.00");
publish("exampleQueue", order, null);
ClientResponse<?> res = consumeNext.request().header("Accept-Wait", "2").accept("application/xml").post(String.class);
Assert.assertEquals(200, res.getStatus());
Assert.assertTrue(res.getHeaders().getFirst("Content-Type").toString().toLowerCase().contains("application/xml"));
TransformTest.Order order2 = res.getEntity(TransformTest.Order.class);
Assert.assertEquals(order, order2);
consumeNext = res.getLinkHeader().getLinkByTitle("consume-next");
res.releaseConnection();
Assert.assertNotNull(consumeNext);
}
// test that Accept header is used to set content-type
{
TransformTest.Order order = new TransformTest.Order();
order.setName("1");
order.setAmount("$5.00");
publish("exampleQueue", order, null);
ClientResponse<?> res = consumeNext.request().header("Accept-Wait", "2").accept("application/json").post(String.class);
Assert.assertEquals(200, res.getStatus());
Assert.assertEquals("application/json", res.getHeaders().getFirst("Content-Type").toString().toLowerCase());
TransformTest.Order order2 = res.getEntity(TransformTest.Order.class);
Assert.assertEquals(order, order2);
consumeNext = res.getLinkHeader().getLinkByTitle("consume-next");
res.releaseConnection();
Assert.assertNotNull(consumeNext);
}
// test that message property is used to set content type
{
TransformTest.Order order = new TransformTest.Order();
order.setName("2");
order.setAmount("$15.00");
publish("exampleQueue", order, "application/xml");
ClientResponse<?> res = consumeNext.request().header("Accept-Wait", "2").post(String.class);
Assert.assertEquals(200, res.getStatus());
Assert.assertTrue(res.getHeaders().getFirst("Content-Type").toString().toLowerCase().contains("application/xml"));
TransformTest.Order order2 = res.getEntity(TransformTest.Order.class);
Assert.assertEquals(order, order2);
consumeNext = res.getLinkHeader().getLinkByTitle("consume-next");
res.releaseConnection();
Assert.assertNotNull(consumeNext);
}
}
}

View File

@ -1,94 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.activemq.artemis.rest.test;
import org.apache.activemq.artemis.api.core.SimpleString;
import org.apache.activemq.artemis.api.core.TransportConfiguration;
import org.apache.activemq.artemis.core.config.Configuration;
import org.apache.activemq.artemis.core.config.impl.ConfigurationImpl;
import org.apache.activemq.artemis.core.remoting.impl.invm.InVMAcceptorFactory;
import org.apache.activemq.artemis.core.server.ActiveMQServer;
import org.apache.activemq.artemis.core.server.ActiveMQServers;
import org.apache.activemq.artemis.core.settings.impl.AddressSettings;
import org.apache.activemq.artemis.rest.MessageServiceConfiguration;
import org.apache.activemq.artemis.rest.MessageServiceManager;
import org.jboss.logging.Logger;
import org.jboss.resteasy.plugins.server.tjws.TJWSEmbeddedJaxrsServer;
import org.jboss.resteasy.test.TestPortProvider;
class EmbeddedTestServer {
private static final Logger log = Logger.getLogger(EmbeddedTestServer.class);
protected MessageServiceManager manager = new MessageServiceManager(null);
protected MessageServiceConfiguration config = new MessageServiceConfiguration();
private ActiveMQServer activeMQServer;
private TJWSEmbeddedJaxrsServer tjws = new TJWSEmbeddedJaxrsServer();
EmbeddedTestServer() {
int port = TestPortProvider.getPort();
log.debug("default port is: " + port);
tjws.setPort(port);
tjws.setRootResourcePath("");
tjws.setSecurityDomain(null);
}
public MessageServiceConfiguration getConfig() {
return config;
}
public void setConfig(MessageServiceConfiguration config) {
this.config = config;
}
public ActiveMQServer getActiveMQServer() {
return activeMQServer;
}
TJWSEmbeddedJaxrsServer getJaxrsServer() {
return tjws;
}
public MessageServiceManager getManager() {
return manager;
}
public void start() throws Exception {
log.debug("\nStarting EmbeddedTestServer");
if (activeMQServer == null) {
Configuration configuration = new ConfigurationImpl().setPersistenceEnabled(false).setSecurityEnabled(false).addAcceptorConfiguration(new TransportConfiguration(InVMAcceptorFactory.class.getName()));
activeMQServer = ActiveMQServers.newActiveMQServer(configuration);
// set DLA and expiry to avoid spamming the log with warnings
activeMQServer.getAddressSettingsRepository().addMatch("#", new AddressSettings().setDeadLetterAddress(SimpleString.toSimpleString("DLA")).setExpiryAddress(SimpleString.toSimpleString("Expiry")));
activeMQServer.start();
}
tjws.start();
manager.setConfiguration(config);
manager.start();
tjws.getDeployment().getRegistry().addSingletonResource(manager.getQueueManager().getDestination());
tjws.getDeployment().getRegistry().addSingletonResource(manager.getTopicManager().getDestination());
}
public void stop() throws Exception {
log.debug("\nStopping EmbeddedTestServer");
manager.stop();
tjws.stop();
activeMQServer.stop();
}
}

View File

@ -1,134 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.activemq.artemis.rest.test;
import org.apache.activemq.artemis.api.core.QueueConfiguration;
import org.apache.activemq.artemis.api.core.SimpleString;
import org.apache.activemq.artemis.api.core.RoutingType;
import org.apache.activemq.artemis.core.server.impl.AddressInfo;
import org.jboss.logging.Logger;
import org.jboss.resteasy.client.ClientRequest;
import org.jboss.resteasy.client.ClientResponse;
import org.jboss.resteasy.spi.Link;
import org.jboss.resteasy.test.TestPortProvider;
import org.junit.Assert;
import org.junit.Test;
public class FindDestinationTest extends MessageTestBase {
private static final Logger log = Logger.getLogger(FindDestinationTest.class);
@Test
public void testFindQueue() throws Exception {
String testName = "testFindQueue";
server.getActiveMQServer().addAddressInfo(new AddressInfo(SimpleString.toSimpleString(testName), RoutingType.MULTICAST));
server.getActiveMQServer().createQueue(new QueueConfiguration(testName).setDurable(false));
ClientRequest request = new ClientRequest(TestPortProvider.generateURL("/queues/" + testName));
ClientResponse<?> response = request.head();
response.releaseConnection();
Assert.assertEquals(200, response.getStatus());
Link sender = getLinkByTitle(manager.getTopicManager().getLinkStrategy(), response, "create");
log.debug("create: " + sender);
Link consumers = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "pull-consumers");
log.debug("pull: " + consumers);
response = Util.setAutoAck(consumers, true);
Link consumeNext = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "consume-next");
log.debug("poller: " + consumeNext);
ClientResponse<?> res = sender.request().body("text/plain", Integer.toString(1)).post();
res.releaseConnection();
Assert.assertEquals(201, res.getStatus());
res = consumeNext.request().post(String.class);
Assert.assertEquals(200, res.getStatus());
Assert.assertEquals("1", res.getEntity(String.class));
res.releaseConnection();
Link session = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), res, "consumer");
log.debug("session: " + session);
Assert.assertEquals(204, session.request().delete().getStatus());
}
@Test
public void testFindTopic() throws Exception {
server.getActiveMQServer().addAddressInfo(new AddressInfo(SimpleString.toSimpleString("testTopic"), RoutingType.MULTICAST));
server.getActiveMQServer().createQueue(new QueueConfiguration("testTopic")
.setRoutingType(RoutingType.MULTICAST)
.setDurable(false));
ClientRequest request = new ClientRequest(TestPortProvider.generateURL("/topics/testTopic"));
ClientResponse<?> response = request.head();
response.releaseConnection();
Assert.assertEquals(200, response.getStatus());
Link sender = getLinkByTitle(manager.getTopicManager().getLinkStrategy(), response, "create");
Link subscriptions = getLinkByTitle(manager.getTopicManager().getLinkStrategy(), response, "pull-subscriptions");
ClientResponse<?> res = subscriptions.request().post();
Assert.assertEquals(201, res.getStatus());
Link sub1 = res.getLocationLink();
res.releaseConnection();
Assert.assertNotNull(sub1);
Link consumeNext1 = getLinkByTitle(manager.getTopicManager().getLinkStrategy(), res, "consume-next");
Assert.assertNotNull(consumeNext1);
log.debug("consumeNext1: " + consumeNext1);
res = subscriptions.request().post();
Assert.assertEquals(201, res.getStatus());
Link sub2 = res.getLocationLink();
res.releaseConnection();
Assert.assertNotNull(sub2);
Link consumeNext2 = getLinkByTitle(manager.getTopicManager().getLinkStrategy(), res, "consume-next");
Assert.assertNotNull(consumeNext1);
res = sender.request().body("text/plain", Integer.toString(1)).post();
res.releaseConnection();
Assert.assertEquals(201, res.getStatus());
res = sender.request().body("text/plain", Integer.toString(2)).post();
res.releaseConnection();
Assert.assertEquals(201, res.getStatus());
res = consumeNext1.request().post(String.class);
Assert.assertEquals(200, res.getStatus());
Assert.assertEquals("1", res.getEntity(String.class));
res.releaseConnection();
consumeNext1 = getLinkByTitle(manager.getTopicManager().getLinkStrategy(), res, "consume-next");
res = consumeNext1.request().post(String.class);
Assert.assertEquals(200, res.getStatus());
Assert.assertEquals("2", res.getEntity(String.class));
res.releaseConnection();
res = consumeNext2.request().post(String.class);
Assert.assertEquals(200, res.getStatus());
Assert.assertEquals("1", res.getEntity(String.class));
res.releaseConnection();
consumeNext2 = getLinkByTitle(manager.getTopicManager().getLinkStrategy(), res, "consume-next");
res = consumeNext2.request().post(String.class);
Assert.assertEquals(200, res.getStatus());
Assert.assertEquals("2", res.getEntity(String.class));
res.releaseConnection();
res = sub1.request().delete();
res.releaseConnection();
Assert.assertEquals(204, res.getStatus());
res = sub2.request().delete();
res.releaseConnection();
Assert.assertEquals(204, res.getStatus());
}
}

View File

@ -1,274 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.activemq.artemis.rest.test;
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.Destination;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageListener;
import javax.jms.MessageProducer;
import javax.jms.ObjectMessage;
import javax.jms.Session;
import javax.xml.bind.annotation.XmlRootElement;
import java.io.Serializable;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import org.apache.activemq.artemis.jms.client.ActiveMQDestination;
import org.apache.activemq.artemis.jms.client.ActiveMQJMSConnectionFactory;
import org.apache.activemq.artemis.rest.HttpHeaderProperty;
import org.apache.activemq.artemis.rest.Jms;
import org.apache.activemq.artemis.rest.queue.QueueDeployment;
import org.jboss.logging.Logger;
import org.jboss.resteasy.client.ClientRequest;
import org.jboss.resteasy.client.ClientResponse;
import org.jboss.resteasy.spi.Link;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
import static org.jboss.resteasy.test.TestPortProvider.generateURL;
public class JMSTest extends MessageTestBase {
private static final Logger log = Logger.getLogger(JMSTest.class);
public static ConnectionFactory connectionFactory;
@BeforeClass
public static void setup() throws Exception {
connectionFactory = new ActiveMQJMSConnectionFactory(manager.getQueueManager().getServerLocator());
}
@XmlRootElement
public static class Order implements Serializable {
private static final long serialVersionUID = 1397854679589606480L;
private String name;
private String amount;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAmount() {
return amount;
}
public void setAmount(String amount) {
this.amount = amount;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
Order order = (Order) o;
if (!amount.equals(order.amount)) {
return false;
}
if (!name.equals(order.name)) {
return false;
}
return true;
}
@Override
public int hashCode() {
int result = name.hashCode();
result = 31 * result + amount.hashCode();
return result;
}
}
public static Destination createDestination(String dest) {
ActiveMQDestination destination = (ActiveMQDestination) ActiveMQDestination.fromPrefixedName(dest);
log.debug("SimpleAddress: " + destination.getSimpleAddress());
return destination;
}
public static void publish(String dest, Serializable object, String contentType) throws Exception {
Connection conn = connectionFactory.createConnection();
try {
Session session = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
Destination destination = createDestination(dest);
MessageProducer producer = session.createProducer(destination);
ObjectMessage message = session.createObjectMessage();
if (contentType != null) {
message.setStringProperty(HttpHeaderProperty.CONTENT_TYPE, contentType);
}
message.setObject(object);
producer.send(message);
} finally {
conn.close();
}
}
public static class Listener implements MessageListener {
public static Order order;
public static String messageID = null;
public static CountDownLatch latch = new CountDownLatch(1);
@Override
public void onMessage(Message message) {
try {
order = Jms.getEntity(message, Order.class);
messageID = message.getJMSMessageID();
} catch (Exception e) {
e.printStackTrace();
}
latch.countDown();
}
}
@Test
public void testJmsConsumer() throws Exception {
String queueName = "testQueue2";
String prefixedQueueName = ActiveMQDestination.createQueueAddressFromName(queueName).toString();
log.debug("Queue name: " + prefixedQueueName);
QueueDeployment deployment = new QueueDeployment();
deployment.setDuplicatesAllowed(true);
deployment.setDurableSend(false);
deployment.setName(queueName);
manager.getQueueManager().deploy(deployment);
Connection conn = connectionFactory.createConnection();
try {
Session session = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
Destination destination = createDestination(prefixedQueueName);
MessageConsumer consumer = session.createConsumer(destination);
consumer.setMessageListener(new Listener());
conn.start();
ClientRequest request = new ClientRequest(generateURL(Util.getUrlPath(queueName)));
ClientResponse<?> response = request.head();
response.releaseConnection();
Assert.assertEquals(200, response.getStatus());
Link sender = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "create");
log.debug("create: " + sender);
Link consumeNext = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "consume-next");
log.debug("consume-next: " + consumeNext);
// test that Accept header is used to set content-type
{
Order order = new Order();
order.setName("1");
order.setAmount("$5.00");
response = sender.request().body("application/xml", order).post();
response.releaseConnection();
Assert.assertEquals(201, response.getStatus());
Listener.latch.await(1, TimeUnit.SECONDS);
Assert.assertNotNull(Listener.order);
Assert.assertEquals(order, Listener.order);
Assert.assertNotNull(Listener.messageID);
}
} finally {
conn.close();
}
}
@Test
public void testJmsProducer() throws Exception {
String queueName = "testQueue";
String prefixedQueueName = ActiveMQDestination.createQueueAddressFromName(queueName).toString();
log.debug("Queue name: " + prefixedQueueName);
QueueDeployment deployment = new QueueDeployment();
deployment.setDuplicatesAllowed(true);
deployment.setDurableSend(false);
deployment.setName(queueName);
manager.getQueueManager().deploy(deployment);
ClientRequest request = new ClientRequest(generateURL(Util.getUrlPath(queueName)));
ClientResponse<?> response = request.head();
response.releaseConnection();
Assert.assertEquals(200, response.getStatus());
Link sender = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "create");
log.debug("create: " + sender);
Link consumers = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "pull-consumers");
log.debug("pull: " + consumers);
response = Util.setAutoAck(consumers, true);
Link consumeNext = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "consume-next");
log.debug("consume-next: " + consumeNext);
// test that Accept header is used to set content-type
{
Order order = new Order();
order.setName("1");
order.setAmount("$5.00");
publish(prefixedQueueName, order, null);
ClientResponse<?> res = consumeNext.request().header("Accept-Wait", "2").accept("application/xml").post(String.class);
Assert.assertEquals(200, res.getStatus());
Assert.assertTrue(res.getHeaders().getFirst("Content-Type").toString().toLowerCase().contains("application/xml"));
Order order2 = res.getEntity(Order.class);
res.releaseConnection();
Assert.assertEquals(order, order2);
consumeNext = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), res, "consume-next");
Assert.assertNotNull(consumeNext);
}
// test that Accept header is used to set content-type
{
Order order = new Order();
order.setName("1");
order.setAmount("$5.00");
publish(prefixedQueueName, order, null);
ClientResponse<?> res = consumeNext.request().header("Accept-Wait", "2").accept("application/json").post(String.class);
Assert.assertEquals(200, res.getStatus());
Assert.assertEquals("application/json", res.getHeaders().getFirst("Content-Type").toString().toLowerCase());
Order order2 = res.getEntity(Order.class);
res.releaseConnection();
Assert.assertEquals(order, order2);
consumeNext = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), res, "consume-next");
Assert.assertNotNull(consumeNext);
}
// test that message property is used to set content type
{
Order order = new Order();
order.setName("2");
order.setAmount("$15.00");
publish(prefixedQueueName, order, "application/xml");
ClientResponse<?> res = consumeNext.request().header("Accept-Wait", "2").post(String.class);
Assert.assertEquals(200, res.getStatus());
Assert.assertTrue(res.getHeaders().getFirst("Content-Type").toString().toLowerCase().contains("application/xml"));
Order order2 = res.getEntity(Order.class);
res.releaseConnection();
Assert.assertEquals(order, order2);
consumeNext = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), res, "consume-next");
Assert.assertNotNull(consumeNext);
}
}
}

View File

@ -1,103 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.activemq.artemis.rest.test;
import org.apache.activemq.artemis.api.core.SimpleString;
import org.apache.activemq.artemis.api.core.client.ClientMessage;
import org.apache.activemq.artemis.api.core.client.ClientSession;
import org.apache.activemq.artemis.api.core.client.MessageHandler;
import org.apache.activemq.artemis.rest.HttpHeaderProperty;
import org.apache.activemq.artemis.rest.queue.QueueDeployment;
import org.jboss.logging.Logger;
import org.jboss.resteasy.client.ClientRequest;
import org.jboss.resteasy.client.ClientResponse;
import org.jboss.resteasy.spi.Link;
import org.junit.Assert;
import org.junit.Test;
import java.util.Set;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import static org.apache.activemq.artemis.rest.util.HttpMessageHelper.POSTED_AS_HTTP_MESSAGE;
import static org.hamcrest.CoreMatchers.hasItem;
import static org.hamcrest.CoreMatchers.not;
import static org.jboss.resteasy.test.TestPortProvider.generateURL;
public class MessagePropertiesTest extends MessageTestBase {
private static final Logger log = Logger.getLogger(MessagePropertiesTest.class);
public static class Listener implements MessageHandler {
public static CountDownLatch latch = new CountDownLatch(1);
public static Set< SimpleString > propertyNames;
@Override
public void onMessage(ClientMessage clientMessage) {
try {
propertyNames = clientMessage.getPropertyNames();
} catch (Exception e) {
e.printStackTrace();
}
latch.countDown();
}
}
@Test
public void testJmsProperties() throws Exception {
QueueDeployment deployment = new QueueDeployment();
deployment.setDuplicatesAllowed(true);
deployment.setDurableSend(false);
final String queueName = "testQueue";
deployment.setName(queueName);
manager.getQueueManager().deploy(deployment);
ClientSession session = manager.getQueueManager().getSessionFactory().createSession();
try {
session.createConsumer(queueName).setMessageHandler(new Listener());
session.start();
ClientRequest request = new ClientRequest(generateURL(Util.getUrlPath(queueName)));
ClientResponse<?> response = request.head();
response.releaseConnection();
Assert.assertEquals(200, response.getStatus());
Link sender = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "create");
log.debug("create: " + sender);
{
response = sender.request().body("text/plain", "val")
.header( "dummyHeader", "DummyValue" )
.header( HttpHeaderProperty.MESSAGE_PROPERTY_DISCRIMINATOR + "property1", "val" )
.post();
response.releaseConnection();
Assert.assertEquals(201, response.getStatus());
Listener.latch.await( 2, TimeUnit.SECONDS);
Assert.assertEquals(4, Listener.propertyNames.size());
Assert.assertThat( Listener.propertyNames, hasItem( new SimpleString( "http_content$type" ) ) );
Assert.assertThat( Listener.propertyNames, hasItem( new SimpleString( "http_content$length" ) ) );
Assert.assertThat( Listener.propertyNames, hasItem( new SimpleString( POSTED_AS_HTTP_MESSAGE ) ) );
Assert.assertThat( Listener.propertyNames, hasItem( new SimpleString( "property1" ) ) );
Assert.assertThat( Listener.propertyNames, not(hasItem( new SimpleString( "dummyHeader" )) ) );
}
} finally {
session.close();
}
}
}

View File

@ -1,79 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.activemq.artemis.rest.test;
import java.lang.reflect.Field;
import org.apache.activemq.artemis.rest.MessageServiceManager;
import org.apache.activemq.artemis.rest.util.LinkHeaderLinkStrategy;
import org.apache.activemq.artemis.rest.util.LinkStrategy;
import org.jboss.resteasy.client.ClientExecutor;
import org.jboss.resteasy.client.ClientResponse;
import org.jboss.resteasy.client.core.BaseClientResponse;
import org.jboss.resteasy.spi.Link;
import org.junit.AfterClass;
import org.junit.BeforeClass;
public class MessageTestBase {
public static EmbeddedTestServer server;
public static MessageServiceManager manager;
private static Field executorField;
static {
try {
executorField = BaseClientResponse.class.getDeclaredField("executor");
} catch (NoSuchFieldException e) {
throw new RuntimeException(e);
}
executorField.setAccessible(true);
}
@BeforeClass
public static void setupActiveMQServerAndManager() throws Exception {
server = new EmbeddedTestServer();
server.start();
manager = server.getManager();
}
@AfterClass
public static void shutdownActiveMQServerAndManager() throws Exception {
manager = null;
server.stop();
server = null;
}
public static Link getLinkByTitle(LinkStrategy strategy, ClientResponse response, String title) {
if (strategy instanceof LinkHeaderLinkStrategy) {
return response.getLinkHeader().getLinkByTitle(title);
} else {
String headerName = "msg-" + title;
String href = (String) response.getHeaders().getFirst(headerName);
if (href == null)
return null;
//log.debug(headerName + ": " + href);
Link l = new Link(title, null, href, null, null);
try {
l.setExecutor((ClientExecutor) executorField.get(response));
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
return l;
}
}
}

View File

@ -1,203 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.activemq.artemis.rest.test;
import org.apache.activemq.artemis.api.core.TransportConfiguration;
import org.apache.activemq.artemis.core.config.Configuration;
import org.apache.activemq.artemis.core.config.impl.ConfigurationImpl;
import org.apache.activemq.artemis.core.remoting.impl.invm.InVMAcceptorFactory;
import org.apache.activemq.artemis.core.server.ActiveMQServer;
import org.apache.activemq.artemis.core.server.ActiveMQServers;
import org.apache.activemq.artemis.rest.MessageServiceManager;
import org.apache.activemq.artemis.rest.queue.QueueDeployment;
import org.apache.activemq.artemis.rest.queue.push.xml.PushRegistration;
import org.apache.activemq.artemis.rest.queue.push.xml.XmlLink;
import org.jboss.logging.Logger;
import org.jboss.resteasy.client.ClientRequest;
import org.jboss.resteasy.client.ClientResponse;
import org.jboss.resteasy.spi.Link;
import org.jboss.resteasy.spi.ResteasyDeployment;
import org.jboss.resteasy.test.EmbeddedContainer;
import org.junit.Assert;
import org.junit.Test;
import static org.jboss.resteasy.test.TestPortProvider.generateURL;
/**
* Test durable queue push consumers
*/
public class PersistentPushQueueConsumerTest {
private static final Logger log = Logger.getLogger(PersistentPushQueueConsumerTest.class);
public static MessageServiceManager manager;
protected static ResteasyDeployment deployment;
public static ActiveMQServer activeMQServer;
public static void startup() throws Exception {
Configuration configuration = new ConfigurationImpl().setPersistenceEnabled(false).setSecurityEnabled(false).addAcceptorConfiguration(new TransportConfiguration(InVMAcceptorFactory.class.getName()));
activeMQServer = ActiveMQServers.newActiveMQServer(configuration);
activeMQServer.start();
deployment = EmbeddedContainer.start();
manager = new MessageServiceManager(null);
manager.start();
deployment.getRegistry().addSingletonResource(manager.getQueueManager().getDestination());
deployment.getRegistry().addSingletonResource(manager.getTopicManager().getDestination());
}
public static void shutdown() throws Exception {
manager.stop();
manager = null;
EmbeddedContainer.stop();
deployment = null;
activeMQServer.stop();
activeMQServer = null;
}
@Test
public void testBridge() throws Exception {
try {
startup();
String testName = "testBridge";
deployBridgeQueues(testName);
ClientRequest request = new ClientRequest(generateURL("/queues/" + testName));
ClientResponse<?> response = request.head();
response.releaseConnection();
Assert.assertEquals(200, response.getStatus());
Link sender = MessageTestBase.getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "create");
log.debug("create: " + sender);
Link pushSubscriptions = MessageTestBase.getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "push-consumers");
log.debug("push subscriptions: " + pushSubscriptions);
request = new ClientRequest(generateURL("/queues/" + testName + "forwardQueue"));
response = request.head();
response.releaseConnection();
Assert.assertEquals(200, response.getStatus());
Link consumers = MessageTestBase.getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "pull-consumers");
log.debug("pull: " + consumers);
response = Util.setAutoAck(consumers, true);
Link consumeNext = MessageTestBase.getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "consume-next");
log.debug("poller: " + consumeNext);
PushRegistration reg = new PushRegistration();
reg.setDurable(true);
reg.setDisableOnFailure(true);
XmlLink target = new XmlLink();
target.setHref(generateURL("/queues/" + testName + "forwardQueue"));
target.setRelationship("destination");
reg.setTarget(target);
response = pushSubscriptions.request().body("application/xml", reg).post();
response.releaseConnection();
Assert.assertEquals(201, response.getStatus());
shutdown();
startup();
deployBridgeQueues(testName);
ClientResponse<?> res = sender.request().body("text/plain", Integer.toString(1)).post();
res.releaseConnection();
Assert.assertEquals(201, res.getStatus());
res = consumeNext.request().header("Accept-Wait", "2").post(String.class);
Assert.assertEquals(200, res.getStatus());
Assert.assertEquals("1", res.getEntity(String.class));
res.releaseConnection();
Link session = MessageTestBase.getLinkByTitle(manager.getQueueManager().getLinkStrategy(), res, "consumer");
res = session.request().delete();
res.releaseConnection();
Assert.assertEquals(204, res.getStatus());
manager.getQueueManager().getPushStore().removeAll();
} finally {
shutdown();
}
}
private void deployBridgeQueues(String testName) throws Exception {
QueueDeployment deployment = new QueueDeployment();
deployment.setDuplicatesAllowed(true);
deployment.setDurableSend(false);
deployment.setName(testName);
manager.getQueueManager().deploy(deployment);
QueueDeployment deployment2 = new QueueDeployment();
deployment2.setDuplicatesAllowed(true);
deployment2.setDurableSend(false);
deployment2.setName(testName + "forwardQueue");
manager.getQueueManager().deploy(deployment2);
}
@Test
public void testFailure() throws Exception {
try {
startup();
String testName = "testFailure";
QueueDeployment deployment = new QueueDeployment();
deployment.setDuplicatesAllowed(true);
deployment.setDurableSend(false);
deployment.setName(testName);
manager.getQueueManager().deploy(deployment);
ClientRequest request = new ClientRequest(generateURL("/queues/" + testName));
ClientResponse<?> response = request.head();
response.releaseConnection();
Assert.assertEquals(200, response.getStatus());
Link sender = MessageTestBase.getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "create");
log.debug("create: " + sender);
Link pushSubscriptions = MessageTestBase.getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "push-consumers");
log.debug("push subscriptions: " + pushSubscriptions);
PushRegistration reg = new PushRegistration();
reg.setDurable(true);
XmlLink target = new XmlLink();
target.setHref("http://localhost:3333/error");
target.setRelationship("uri");
reg.setTarget(target);
reg.setDisableOnFailure(true);
reg.setMaxRetries(3);
reg.setRetryWaitMillis(10);
response = pushSubscriptions.request().body("application/xml", reg).post();
Assert.assertEquals(201, response.getStatus());
Link pushSubscription = response.getLocationLink();
response.releaseConnection();
ClientResponse<?> res = sender.request().body("text/plain", Integer.toString(1)).post();
res.releaseConnection();
Assert.assertEquals(201, res.getStatus());
Thread.sleep(5000);
response = pushSubscription.request().get();
PushRegistration reg2 = response.getEntity(PushRegistration.class);
Assert.assertEquals(reg.isDurable(), reg2.isDurable());
Assert.assertEquals(reg.getTarget().getHref(), reg2.getTarget().getHref());
Assert.assertFalse(reg2.isEnabled()); // make sure the failure disables the PushRegistration
response.releaseConnection();
manager.getQueueManager().getPushStore().removeAll();
} finally {
shutdown();
}
}
}

View File

@ -1,239 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.activemq.artemis.rest.test;
import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import org.apache.activemq.artemis.api.core.SimpleString;
import org.apache.activemq.artemis.api.core.TransportConfiguration;
import org.apache.activemq.artemis.api.core.client.ClientSession;
import org.apache.activemq.artemis.core.config.Configuration;
import org.apache.activemq.artemis.core.config.impl.ConfigurationImpl;
import org.apache.activemq.artemis.core.remoting.impl.invm.InVMAcceptorFactory;
import org.apache.activemq.artemis.core.server.ActiveMQServer;
import org.apache.activemq.artemis.core.server.ActiveMQServers;
import org.apache.activemq.artemis.rest.MessageServiceManager;
import org.apache.activemq.artemis.rest.queue.push.xml.XmlLink;
import org.apache.activemq.artemis.rest.topic.PushTopicRegistration;
import org.apache.activemq.artemis.rest.topic.TopicDeployment;
import org.jboss.logging.Logger;
import org.jboss.resteasy.client.ClientRequest;
import org.jboss.resteasy.client.ClientResponse;
import org.jboss.resteasy.spi.Link;
import org.jboss.resteasy.spi.ResteasyDeployment;
import org.jboss.resteasy.test.EmbeddedContainer;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
import static org.jboss.resteasy.test.TestPortProvider.generateURL;
/**
* Test durable queue push consumers
*/
public class PersistentPushTopicConsumerTest {
private static final Logger log = Logger.getLogger(PersistentPushTopicConsumerTest.class);
public static ActiveMQServer server;
public static MessageServiceManager manager;
protected static ResteasyDeployment deployment;
@BeforeClass
public static void setup() throws Exception {
Configuration configuration = new ConfigurationImpl().setPersistenceEnabled(false).setSecurityEnabled(false).addAcceptorConfiguration(new TransportConfiguration(InVMAcceptorFactory.class.getName()));
server = ActiveMQServers.newActiveMQServer(configuration);
server.start();
}
@AfterClass
public static void cleanup() throws Exception {
server.stop();
server = null;
}
public static void startup() throws Exception {
deployment = EmbeddedContainer.start();
manager = new MessageServiceManager(null);
manager.start();
deployment.getRegistry().addSingletonResource(manager.getQueueManager().getDestination());
deployment.getRegistry().addSingletonResource(manager.getTopicManager().getDestination());
deployment.getRegistry().addPerRequestResource(Receiver.class);
}
public static void shutdown() throws Exception {
manager.stop();
manager = null;
EmbeddedContainer.stop();
deployment = null;
}
@Test
public void testFailure() throws Exception {
try {
String testName = "testFailure";
startup();
deployTopic(testName);
ClientRequest request = new ClientRequest(generateURL("/topics/" + testName));
ClientResponse<?> response = request.head();
response.releaseConnection();
Assert.assertEquals(200, response.getStatus());
Link sender = MessageTestBase.getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "create");
log.debug("create: " + sender);
Link pushSubscriptions = MessageTestBase.getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "push-subscriptions");
log.debug("push subscriptions: " + pushSubscriptions);
PushTopicRegistration reg = new PushTopicRegistration();
reg.setDurable(true);
XmlLink target = new XmlLink();
target.setHref("http://localhost:3333/error");
target.setRelationship("uri");
reg.setTarget(target);
reg.setDisableOnFailure(true);
reg.setMaxRetries(3);
reg.setRetryWaitMillis(10);
response = pushSubscriptions.request().body("application/xml", reg).post();
Assert.assertEquals(201, response.getStatus());
Link pushSubscription = response.getLocationLink();
response.releaseConnection();
ClientResponse<?> res = sender.request().body("text/plain", Integer.toString(1)).post();
res.releaseConnection();
Assert.assertEquals(201, res.getStatus());
Thread.sleep(5000);
response = pushSubscription.request().get();
PushTopicRegistration reg2 = response.getEntity(PushTopicRegistration.class);
response.releaseConnection();
Assert.assertEquals(reg.isDurable(), reg2.isDurable());
Assert.assertEquals(reg.getTarget().getHref(), reg2.getTarget().getHref());
Assert.assertFalse(reg2.isEnabled());
response.releaseConnection();
String destination = reg2.getDestination();
ClientSession session = manager.getQueueManager().getSessionFactory().createSession(false, false, false);
ClientSession.QueueQuery query = session.queueQuery(new SimpleString(destination));
Assert.assertFalse(query.isExists());
manager.getQueueManager().getPushStore().removeAll();
} finally {
shutdown();
}
}
@Test
public void testSuccessFirst() throws Exception {
try {
String testName = "testSuccessFirst";
startup();
deployTopic(testName);
ClientRequest request = new ClientRequest(generateURL("/topics/" + testName));
ClientResponse<?> response = request.head();
response.releaseConnection();
Assert.assertEquals(200, response.getStatus());
Link sender = MessageTestBase.getLinkByTitle(manager.getTopicManager().getLinkStrategy(), response, "create");
log.debug("create: " + sender);
Link pushSubscriptions = MessageTestBase.getLinkByTitle(manager.getTopicManager().getLinkStrategy(), response, "push-subscriptions");
log.debug("push subscriptions: " + pushSubscriptions);
String sub1 = generateURL("/subscribers/1");
String sub2 = generateURL("/subscribers/2");
PushTopicRegistration reg = new PushTopicRegistration();
reg.setDurable(true);
XmlLink target = new XmlLink();
target.setHref(sub1);
reg.setTarget(target);
response = pushSubscriptions.request().body("application/xml", reg).post();
response.releaseConnection();
Assert.assertEquals(201, response.getStatus());
reg = new PushTopicRegistration();
reg.setDurable(true);
target = new XmlLink();
target.setHref(sub2);
reg.setTarget(target);
response = pushSubscriptions.request().body("application/xml", reg).post();
response.releaseConnection();
Assert.assertEquals(201, response.getStatus());
shutdown();
startup();
deployTopic(testName);
ClientResponse<?> res = sender.request().body("text/plain", Integer.toString(1)).post();
res.releaseConnection();
Assert.assertEquals(201, res.getStatus());
Receiver.latch.await(1, TimeUnit.SECONDS);
Assert.assertEquals("1", Receiver.subscriber1);
Assert.assertEquals("1", Receiver.subscriber2);
manager.getTopicManager().getPushStore().removeAll();
} finally {
shutdown();
}
}
@Path("/subscribers")
public static class Receiver {
public static String subscriber1;
public static String subscriber2;
public static CountDownLatch latch = new CountDownLatch(2);
@Path("1")
@POST
@Consumes("text/plain")
public void postOne(String msg) {
log.debug("in subscribers 1!!!!!!!!!! " + msg);
subscriber1 = msg;
latch.countDown();
}
@Path("2")
@POST
@Consumes("text/plain")
public void postTwo(String msg) {
log.debug("in subscribers 2!!!!!!!!!! " + msg);
subscriber2 = msg;
latch.countDown();
}
}
private void deployTopic(String topicName) throws Exception {
TopicDeployment deployment = new TopicDeployment();
deployment.setDuplicatesAllowed(true);
deployment.setDurableSend(false);
deployment.setName(topicName);
manager.getTopicManager().deploy(deployment);
}
}

View File

@ -1,335 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.activemq.artemis.rest.test;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import java.util.concurrent.atomic.AtomicInteger;
import org.apache.activemq.artemis.rest.queue.QueueDeployment;
import org.apache.activemq.artemis.rest.queue.push.ActiveMQPushStrategy;
import org.apache.activemq.artemis.rest.queue.push.xml.PushRegistration;
import org.apache.activemq.artemis.rest.queue.push.xml.XmlLink;
import org.apache.activemq.artemis.rest.util.Constants;
import org.jboss.logging.Logger;
import org.jboss.resteasy.client.ClientRequest;
import org.jboss.resteasy.client.ClientResponse;
import org.jboss.resteasy.spi.Link;
import org.junit.Assert;
import org.junit.Test;
import static org.jboss.resteasy.test.TestPortProvider.generateURL;
public class PushQueueConsumerTest extends MessageTestBase {
private static final Logger log = Logger.getLogger(PushQueueConsumerTest.class);
enum PushRegistrationType {
CLASS, BRIDGE, URI, TEMPLATE
}
@Test
public void testBridge() throws Exception {
Link destinationForConsumption = null;
ClientResponse consumerResponse = null;
Link pushSubscription = null;
String messageContent = "1";
try {
// The name of the queue used for the test should match the name of the test
String queue = "testBridge";
String queueToPushTo = "pushedFrom-" + queue;
log.debug("\n" + queue);
deployQueue(queue);
deployQueue(queueToPushTo);
ClientResponse queueResponse = Util.head(new ClientRequest(generateURL(Util.getUrlPath(queue))));
Link destination = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), queueResponse, "create");
Link pushSubscriptions = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), queueResponse, "push-consumers");
ClientResponse queueToPushToResponse = Util.head(new ClientRequest(generateURL(Util.getUrlPath(queueToPushTo))));
ClientResponse autoAckResponse = setAutoAck(queueToPushToResponse, true);
destinationForConsumption = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), autoAckResponse, "consume-next");
pushSubscription = createPushRegistration(queueToPushTo, pushSubscriptions, PushRegistrationType.BRIDGE);
sendMessage(destination, messageContent);
consumerResponse = consume(destinationForConsumption, messageContent);
} finally {
cleanupConsumer(consumerResponse);
cleanupSubscription(pushSubscription);
}
}
private void cleanupSubscription(Link pushSubscription) throws Exception {
if (pushSubscription != null) {
ClientResponse<?> response = pushSubscription.request().delete();
response.releaseConnection();
Assert.assertEquals(204, response.getStatus());
}
}
@Test
public void testClass() throws Exception {
Link destinationForConsumption = null;
ClientResponse consumerResponse = null;
Link pushSubscription = null;
String messageContent = "1";
try {
// The name of the queue used for the test should match the name of the test
String queue = "testClass";
String queueToPushTo = "pushedFrom-" + queue;
log.debug("\n" + queue);
deployQueue(queue);
deployQueue(queueToPushTo);
ClientResponse queueResponse = Util.head(new ClientRequest(generateURL(Util.getUrlPath(queue))));
Link destinationForSend = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), queueResponse, "create");
Link pushSubscriptions = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), queueResponse, "push-consumers");
ClientResponse queueToPushToResponse = Util.head(new ClientRequest(generateURL(Util.getUrlPath(queueToPushTo))));
ClientResponse autoAckResponse = setAutoAck(queueToPushToResponse, true);
destinationForConsumption = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), autoAckResponse, "consume-next");
pushSubscription = createPushRegistration(queueToPushTo, pushSubscriptions, PushRegistrationType.CLASS);
sendMessage(destinationForSend, messageContent);
consumerResponse = consume(destinationForConsumption, messageContent);
} finally {
cleanupConsumer(consumerResponse);
cleanupSubscription(pushSubscription);
}
}
@Test
public void testTemplate() throws Exception {
Link destinationForConsumption = null;
ClientResponse consumerResponse = null;
Link pushSubscription = null;
String messageContent = "1";
try {
// The name of the queue used for the test should match the name of the test
String queue = "testTemplate";
String queueToPushTo = "pushedFrom-" + queue;
log.debug("\n" + queue);
deployQueue(queue);
deployQueue(queueToPushTo);
ClientResponse queueResponse = Util.head(new ClientRequest(generateURL(Util.getUrlPath(queue))));
Link destinationForSend = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), queueResponse, "create");
Link pushSubscriptions = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), queueResponse, "push-consumers");
ClientResponse queueToPushToResponse = Util.head(new ClientRequest(generateURL(Util.getUrlPath(queueToPushTo))));
Link consumers = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), queueToPushToResponse, "pull-consumers");
Link createWithId = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), queueToPushToResponse, "create-with-id");
ClientResponse autoAckResponse = Util.setAutoAck(consumers, true);
destinationForConsumption = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), autoAckResponse, "consume-next");
pushSubscription = createPushRegistration(createWithId.getHref(), pushSubscriptions, PushRegistrationType.TEMPLATE);
sendMessage(destinationForSend, messageContent);
consumerResponse = consume(destinationForConsumption, messageContent);
} finally {
cleanupConsumer(consumerResponse);
cleanupSubscription(pushSubscription);
}
}
@Path("/my")
public static class MyResource {
public static String got_it;
@PUT
public void put(String str) {
got_it = str;
}
}
@Path("/myConcurrent")
public static class MyConcurrentResource {
public static AtomicInteger concurrentInvocations = new AtomicInteger();
public static AtomicInteger maxConcurrentInvocations = new AtomicInteger();
@PUT
public void put(String str) {
concurrentInvocations.getAndIncrement();
if (concurrentInvocations.get() > maxConcurrentInvocations.get()) {
maxConcurrentInvocations.set(concurrentInvocations.get());
}
try {
// sleep here so the concurrent invocations can stack up
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
concurrentInvocations.getAndDecrement();
}
}
@Test
public void testUri() throws Exception {
Link pushSubscription = null;
String messageContent = "1";
try {
// The name of the queue used for the test should match the name of the test
String queue = "testUri";
String queueToPushTo = "pushedFrom-" + queue;
log.debug("\n" + queue);
deployQueue(queue);
deployQueue(queueToPushTo);
server.getJaxrsServer().getDeployment().getRegistry().addPerRequestResource(MyResource.class);
ClientResponse queueResponse = Util.head(new ClientRequest(generateURL(Util.getUrlPath(queue))));
Link destinationForSend = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), queueResponse, "create");
Link pushSubscriptions = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), queueResponse, "push-consumers");
pushSubscription = createPushRegistration(generateURL("/my"), pushSubscriptions, PushRegistrationType.URI);
sendMessage(destinationForSend, messageContent);
Thread.sleep(100);
Assert.assertEquals(messageContent, MyResource.got_it);
} finally {
cleanupSubscription(pushSubscription);
}
}
@Test
public void testUriWithMultipleSessions() throws Exception {
Link pushSubscription = null;
String messageContent = "1";
final int CONCURRENT = 10;
try {
// The name of the queue used for the test should match the name of the test
String queue = "testUriWithMultipleSessions";
String queueToPushTo = "pushedFrom-" + queue;
log.debug("\n" + queue);
deployQueue(queue);
deployQueue(queueToPushTo);
server.getJaxrsServer().getDeployment().getRegistry().addPerRequestResource(MyConcurrentResource.class);
ClientResponse queueResponse = Util.head(new ClientRequest(generateURL(Util.getUrlPath(queue))));
Link destinationForSend = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), queueResponse, "create");
Link pushSubscriptions = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), queueResponse, "push-consumers");
pushSubscription = createPushRegistration(generateURL("/myConcurrent"), pushSubscriptions, PushRegistrationType.URI, CONCURRENT);
for (int i = 0; i < CONCURRENT; i++) {
sendMessage(destinationForSend, messageContent);
}
// wait until all the invocations have completed
while (MyConcurrentResource.concurrentInvocations.get() > 0) {
Thread.sleep(100);
}
Assert.assertEquals(CONCURRENT, MyConcurrentResource.maxConcurrentInvocations.get());
} finally {
cleanupSubscription(pushSubscription);
}
}
private void deployQueue(String queueName) throws Exception {
QueueDeployment deployment = new QueueDeployment();
deployment.setDuplicatesAllowed(true);
deployment.setDurableSend(false);
deployment.setName(queueName);
manager.getQueueManager().deploy(deployment);
}
private ClientResponse consume(Link destination, String expectedContent) throws Exception {
ClientResponse response;
response = destination.request().header(Constants.WAIT_HEADER, "1").post(String.class);
Assert.assertEquals(200, response.getStatus());
Assert.assertEquals(expectedContent, response.getEntity(String.class));
response.releaseConnection();
return response;
}
private void sendMessage(Link sender, String content) throws Exception {
ClientResponse sendMessageResponse = sender.request().body("text/plain", content).post();
sendMessageResponse.releaseConnection();
Assert.assertEquals(201, sendMessageResponse.getStatus());
}
private ClientResponse setAutoAck(ClientResponse response, boolean ack) throws Exception {
Link pullConsumers = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "pull-consumers");
ClientResponse autoAckResponse = pullConsumers.request().formParameter("autoAck", Boolean.toString(ack)).post();
autoAckResponse.releaseConnection();
Assert.assertEquals(201, autoAckResponse.getStatus());
return autoAckResponse;
}
private void cleanupConsumer(ClientResponse consumerResponse) throws Exception {
if (consumerResponse != null) {
Link consumer = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), consumerResponse, "consumer");
ClientResponse<?> response = consumer.request().delete();
response.releaseConnection();
Assert.assertEquals(204, response.getStatus());
}
}
private Link createPushRegistration(String queueToPushTo,
Link pushSubscriptions,
PushRegistrationType pushRegistrationType) throws Exception {
return createPushRegistration(queueToPushTo, pushSubscriptions, pushRegistrationType, 1);
}
private Link createPushRegistration(String queueToPushTo,
Link pushSubscriptions,
PushRegistrationType pushRegistrationType,
int sessionCount) throws Exception {
PushRegistration reg = new PushRegistration();
reg.setDurable(false);
XmlLink target = new XmlLink();
if (pushRegistrationType == PushRegistrationType.CLASS) {
target.setHref(generateURL(Util.getUrlPath(queueToPushTo)));
target.setClassName(ActiveMQPushStrategy.class.getName());
} else if (pushRegistrationType == PushRegistrationType.BRIDGE) {
target.setHref(generateURL(Util.getUrlPath(queueToPushTo)));
target.setRelationship("destination");
} else if (pushRegistrationType == PushRegistrationType.TEMPLATE) {
target.setHref(queueToPushTo);
target.setRelationship("template");
} else if (pushRegistrationType == PushRegistrationType.URI) {
target.setMethod("put");
target.setHref(queueToPushTo);
}
reg.setTarget(target);
reg.setSessionCount(sessionCount);
ClientResponse pushRegistrationResponse = pushSubscriptions.request().body("application/xml", reg).post();
pushRegistrationResponse.releaseConnection();
Assert.assertEquals(201, pushRegistrationResponse.getStatus());
Link pushSubscription = pushRegistrationResponse.getLocationLink();
return pushSubscription;
}
}

View File

@ -1,362 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.activemq.artemis.rest.test;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import java.util.concurrent.atomic.AtomicInteger;
import org.apache.activemq.artemis.rest.queue.QueueDeployment;
import org.apache.activemq.artemis.rest.queue.push.ActiveMQPushStrategy;
import org.apache.activemq.artemis.rest.queue.push.xml.XmlLink;
import org.apache.activemq.artemis.rest.topic.PushTopicRegistration;
import org.apache.activemq.artemis.rest.topic.TopicDeployment;
import org.jboss.logging.Logger;
import org.jboss.resteasy.client.ClientRequest;
import org.jboss.resteasy.client.ClientResponse;
import org.jboss.resteasy.spi.Link;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
import static org.jboss.resteasy.test.TestPortProvider.generateURL;
public class PushTopicConsumerTest extends MessageTestBase {
private static final Logger log = Logger.getLogger(PushTopicConsumerTest.class);
@BeforeClass
public static void setup() throws Exception {
// TopicDeployment deployment = new TopicDeployment();
// deployment.setDuplicatesAllowed(true);
// deployment.setDurableSend(false);
// deployment.setName("testTopic");
// manager.getTopicManager().deploy(deployment);
// QueueDeployment deployment2 = new QueueDeployment();
// deployment2.setDuplicatesAllowed(true);
// deployment2.setDurableSend(false);
// deployment2.setName("forwardQueue");
// manager.getQueueManager().deploy(deployment2);
}
@Test
public void testBridge() throws Exception {
TopicDeployment deployment = new TopicDeployment();
deployment.setDuplicatesAllowed(true);
deployment.setDurableSend(false);
deployment.setName("testBridge");
manager.getTopicManager().deploy(deployment);
QueueDeployment deployment2 = new QueueDeployment();
deployment2.setDuplicatesAllowed(true);
deployment2.setDurableSend(false);
deployment2.setName("testBridgeForwardQueue");
manager.getQueueManager().deploy(deployment2);
ClientRequest request = new ClientRequest(generateURL("/topics/testBridge"));
ClientResponse<?> response = request.head();
response.releaseConnection();
Assert.assertEquals(200, response.getStatus());
Link sender = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "create");
log.debug("create: " + sender);
Link pushSubscriptions = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "push-subscriptions");
log.debug("push subscriptions: " + pushSubscriptions);
request = new ClientRequest(generateURL("/queues/testBridgeForwardQueue"));
response = request.head();
response.releaseConnection();
Assert.assertEquals(200, response.getStatus());
Link consumers = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "pull-consumers");
response = Util.setAutoAck(consumers, true);
Link consumeNext = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "consume-next");
PushTopicRegistration reg = new PushTopicRegistration();
reg.setDurable(false);
XmlLink target = new XmlLink();
target.setHref(generateURL("/queues/testBridgeForwardQueue"));
target.setRelationship("destination");
reg.setTarget(target);
response = pushSubscriptions.request().body("application/xml", reg).post();
response.releaseConnection();
Assert.assertEquals(201, response.getStatus());
Link pushSubscription = response.getLocationLink();
response = sender.request().body("text/plain", Integer.toString(1)).post();
response.releaseConnection();
Assert.assertEquals(201, response.getStatus());
response = consumeNext.request().header("Accept-Wait", "1").post(String.class);
Assert.assertEquals(200, response.getStatus());
Assert.assertEquals("1", response.getEntity(String.class));
response.releaseConnection();
Link session = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "consumer");
response = session.request().delete();
response.releaseConnection();
Assert.assertEquals(204, response.getStatus());
response = pushSubscription.request().delete();
response.releaseConnection();
Assert.assertEquals(204, response.getStatus());
}
@Test
public void testClass() throws Exception {
TopicDeployment deployment = new TopicDeployment();
deployment.setDuplicatesAllowed(true);
deployment.setDurableSend(false);
deployment.setName("testClass");
manager.getTopicManager().deploy(deployment);
QueueDeployment deployment2 = new QueueDeployment();
deployment2.setDuplicatesAllowed(true);
deployment2.setDurableSend(false);
deployment2.setName("testClassForwardQueue");
manager.getQueueManager().deploy(deployment2);
ClientRequest request = new ClientRequest(generateURL("/topics/testClass"));
ClientResponse<?> response = request.head();
response.releaseConnection();
Assert.assertEquals(200, response.getStatus());
Link sender = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "create");
log.debug("create: " + sender);
Link pushSubscriptions = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "push-subscriptions");
log.debug("push subscriptions: " + pushSubscriptions);
request = new ClientRequest(generateURL("/queues/testClassForwardQueue"));
response = request.head();
response.releaseConnection();
Assert.assertEquals(200, response.getStatus());
Link consumers = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "pull-consumers");
response = Util.setAutoAck(consumers, true);
Link consumeNext = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "consume-next");
PushTopicRegistration reg = new PushTopicRegistration();
reg.setDurable(false);
XmlLink target = new XmlLink();
target.setHref(generateURL("/queues/testClassForwardQueue"));
target.setClassName(ActiveMQPushStrategy.class.getName());
reg.setTarget(target);
response = pushSubscriptions.request().body("application/xml", reg).post();
Assert.assertEquals(201, response.getStatus());
Link pushSubscription = response.getLocationLink();
response.releaseConnection();
response = sender.request().body("text/plain", Integer.toString(1)).post();
response.releaseConnection();
Assert.assertEquals(201, response.getStatus());
response = consumeNext.request().header("Accept-Wait", "1").post(String.class);
Assert.assertEquals(200, response.getStatus());
Assert.assertEquals("1", response.getEntity(String.class));
response.releaseConnection();
Link session = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "consumer");
response = session.request().delete();
response.releaseConnection();
Assert.assertEquals(204, response.getStatus());
response = pushSubscription.request().delete();
response.releaseConnection();
Assert.assertEquals(204, response.getStatus());
}
@Test
public void testTemplate() throws Exception {
TopicDeployment deployment = new TopicDeployment();
deployment.setDuplicatesAllowed(true);
deployment.setDurableSend(false);
deployment.setName("testTemplate");
manager.getTopicManager().deploy(deployment);
QueueDeployment deployment2 = new QueueDeployment();
deployment2.setDuplicatesAllowed(true);
deployment2.setDurableSend(false);
deployment2.setName("testTemplateForwardQueue");
manager.getQueueManager().deploy(deployment2);
ClientRequest request = new ClientRequest(generateURL("/topics/testTemplate"));
ClientResponse<?> response = request.head();
response.releaseConnection();
Assert.assertEquals(200, response.getStatus());
Link sender = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "create");
log.debug("create: " + sender);
Link pushSubscriptions = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "push-subscriptions");
log.debug("push subscriptions: " + pushSubscriptions);
request = new ClientRequest(generateURL("/queues/testTemplateForwardQueue"));
response = request.head();
response.releaseConnection();
Assert.assertEquals(200, response.getStatus());
Link consumers = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "pull-consumers");
Link createWithId = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "create-with-id");
response = Util.setAutoAck(consumers, true);
Link consumeNext = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "consume-next");
PushTopicRegistration reg = new PushTopicRegistration();
reg.setDurable(false);
XmlLink target = new XmlLink();
target.setRelationship("template");
target.setHref(createWithId.getHref());
reg.setTarget(target);
response = pushSubscriptions.request().body("application/xml", reg).post();
Assert.assertEquals(201, response.getStatus());
Link pushSubscription = response.getLocationLink();
response.releaseConnection();
response = sender.request().body("text/plain", Integer.toString(1)).post();
response.releaseConnection();
Assert.assertEquals(201, response.getStatus());
response = consumeNext.request().header("Accept-Wait", "1").post(String.class);
Assert.assertEquals(200, response.getStatus());
Assert.assertEquals("1", response.getEntity(String.class));
response.releaseConnection();
Link session = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "consumer");
response = session.request().delete();
response.releaseConnection();
Assert.assertEquals(204, response.getStatus());
response = pushSubscription.request().delete();
response.releaseConnection();
Assert.assertEquals(204, response.getStatus());
}
@Path("/my")
public static class MyResource {
public static String gotit;
@PUT
public void put(String str) {
gotit = str;
}
}
@Path("/myConcurrent")
public static class MyConcurrentResource {
public static AtomicInteger concurrentInvocations = new AtomicInteger();
public static AtomicInteger maxConcurrentInvocations = new AtomicInteger();
@PUT
public void put(String str) {
concurrentInvocations.getAndIncrement();
if (concurrentInvocations.get() > maxConcurrentInvocations.get()) {
maxConcurrentInvocations.set(concurrentInvocations.get());
}
try {
// sleep here so the concurrent invocations can stack up
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
concurrentInvocations.getAndDecrement();
}
}
@Test
public void testUri() throws Exception {
TopicDeployment deployment = new TopicDeployment();
deployment.setDuplicatesAllowed(true);
deployment.setDurableSend(false);
deployment.setName("testUri");
manager.getTopicManager().deploy(deployment);
ClientRequest request = new ClientRequest(generateURL("/topics/testUri"));
server.getJaxrsServer().getDeployment().getRegistry().addPerRequestResource(MyResource.class);
ClientResponse<?> response = request.head();
response.releaseConnection();
Assert.assertEquals(200, response.getStatus());
Link sender = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "create");
log.debug("create: " + sender);
Link pushSubscriptions = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "push-subscriptions");
log.debug("push subscriptions: " + pushSubscriptions);
PushTopicRegistration reg = new PushTopicRegistration();
reg.setDurable(false);
XmlLink target = new XmlLink();
target.setMethod("put");
target.setHref(generateURL("/my"));
reg.setTarget(target);
response = pushSubscriptions.request().body("application/xml", reg).post();
Assert.assertEquals(201, response.getStatus());
Link pushSubscription = response.getLocationLink();
response.releaseConnection();
response = sender.request().body("text/plain", Integer.toString(1)).post();
response.releaseConnection();
Assert.assertEquals(201, response.getStatus());
Thread.sleep(100);
Assert.assertEquals("1", MyResource.gotit);
response = pushSubscription.request().delete();
response.releaseConnection();
Assert.assertEquals(204, response.getStatus());
}
@Test
public void testUriWithMultipleSessions() throws Exception {
final int CONCURRENT = 10;
TopicDeployment deployment = new TopicDeployment();
deployment.setDuplicatesAllowed(true);
deployment.setDurableSend(false);
deployment.setName("testUriWithMultipleSessions");
manager.getTopicManager().deploy(deployment);
ClientRequest request = new ClientRequest(generateURL("/topics/testUriWithMultipleSessions"));
server.getJaxrsServer().getDeployment().getRegistry().addPerRequestResource(MyConcurrentResource.class);
ClientResponse<?> response = request.head();
response.releaseConnection();
Assert.assertEquals(200, response.getStatus());
Link sender = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "create");
log.debug("create: " + sender);
Link pushSubscriptions = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "push-subscriptions");
log.debug("push subscriptions: " + pushSubscriptions);
PushTopicRegistration reg = new PushTopicRegistration();
reg.setDurable(false);
XmlLink target = new XmlLink();
target.setMethod("put");
target.setHref(generateURL("/myConcurrent"));
reg.setTarget(target);
reg.setSessionCount(CONCURRENT);
response = pushSubscriptions.request().body("application/xml", reg).post();
Assert.assertEquals(201, response.getStatus());
Link pushSubscription = response.getLocationLink();
response.releaseConnection();
for (int i = 0; i < CONCURRENT; i++) {
response = sender.request().body("text/plain", Integer.toString(1)).post();
response.releaseConnection();
Assert.assertEquals(201, response.getStatus());
}
// wait until all the invocations have completed
while (MyConcurrentResource.concurrentInvocations.get() > 0) {
Thread.sleep(100);
}
Assert.assertEquals(CONCURRENT, MyConcurrentResource.maxConcurrentInvocations.get());
response = pushSubscription.request().delete();
response.releaseConnection();
Assert.assertEquals(204, response.getStatus());
}
}

View File

@ -1,157 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.activemq.artemis.rest.test;
import java.util.HashMap;
import org.apache.activemq.artemis.api.core.Message;
import org.apache.activemq.artemis.api.core.QueueConfiguration;
import org.apache.activemq.artemis.api.core.SimpleString;
import org.apache.activemq.artemis.api.core.TransportConfiguration;
import org.apache.activemq.artemis.api.core.client.ClientConsumer;
import org.apache.activemq.artemis.api.core.client.ClientMessage;
import org.apache.activemq.artemis.api.core.client.ClientProducer;
import org.apache.activemq.artemis.api.core.client.ClientSession;
import org.apache.activemq.artemis.api.core.client.ClientSessionFactory;
import org.apache.activemq.artemis.api.core.client.ServerLocator;
import org.apache.activemq.artemis.core.client.impl.ServerLocatorImpl;
import org.apache.activemq.artemis.core.config.Configuration;
import org.apache.activemq.artemis.core.config.impl.ConfigurationImpl;
import org.apache.activemq.artemis.core.remoting.impl.invm.InVMAcceptorFactory;
import org.apache.activemq.artemis.core.remoting.impl.invm.InVMConnectorFactory;
import org.apache.activemq.artemis.core.server.ActiveMQServer;
import org.apache.activemq.artemis.core.server.ActiveMQServers;
import org.apache.activemq.artemis.api.core.RoutingType;
import org.apache.activemq.artemis.core.server.impl.AddressInfo;
import org.jboss.logging.Logger;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
/**
* Play with ActiveMQ
*/
public class RawAckTest {
private static final Logger log = Logger.getLogger(RawAckTest.class);
protected static ActiveMQServer activeMQServer;
static ServerLocator serverLocator;
static ClientSessionFactory sessionFactory;
static ClientSessionFactory consumerSessionFactory;
static ClientProducer producer;
static ClientSession session;
@BeforeClass
public static void setup() throws Exception {
Configuration configuration = new ConfigurationImpl().setPersistenceEnabled(false).setSecurityEnabled(false).addAcceptorConfiguration(new TransportConfiguration(InVMAcceptorFactory.class.getName()));
activeMQServer = ActiveMQServers.newActiveMQServer(configuration);
activeMQServer.start();
HashMap<String, Object> transportConfig = new HashMap<>();
serverLocator = new ServerLocatorImpl(false, new TransportConfiguration(InVMConnectorFactory.class.getName(), transportConfig));
sessionFactory = serverLocator.createSessionFactory();
consumerSessionFactory = serverLocator.createSessionFactory();
SimpleString addr = SimpleString.toSimpleString("testQueue");
activeMQServer.addAddressInfo(new AddressInfo(addr, RoutingType.MULTICAST));
activeMQServer.createQueue(new QueueConfiguration(addr).setDurable(false));
session = sessionFactory.createSession(true, true);
producer = session.createProducer(addr);
session.start();
}
@AfterClass
public static void shutdown() throws Exception {
serverLocator.close();
activeMQServer.stop();
}
static boolean passed = false;
private static class MyThread extends Thread {
final ClientConsumer consumer;
private MyThread(ClientConsumer consumer) {
this.consumer = consumer;
}
@Override
public void run() {
try {
ClientMessage message = consumer.receiveImmediate();
int size = message.getBodyBuffer().readInt();
byte[] bytes = new byte[size];
message.getBodyBuffer().readBytes(bytes);
String str = new String(bytes);
log.debug(str);
message.acknowledge();
message = consumer.receive(1);
if (message != null) {
System.err.println("Not expecting another message: type=" + message.getType());
throw new RuntimeException("Failed, receive extra message");
}
Assert.assertNull(message);
passed = true;
} catch (Exception e) {
e.printStackTrace();
}
}
}
@Test
public void testAck() throws Exception {
ClientMessage message;
message = session.createMessage(Message.OBJECT_TYPE, false);
message.getBodyBuffer().writeInt("hello".getBytes().length);
message.getBodyBuffer().writeBytes("hello".getBytes());
producer.send(message);
Thread.sleep(100);
ClientSession sessionConsumer = sessionFactory.createSession(true, true);
ClientConsumer consumer = sessionConsumer.createConsumer("testQueue");
sessionConsumer.start();
MyThread t = new MyThread(consumer);
t.start();
t.join();
Assert.assertTrue(passed);
passed = false;
message = session.createMessage(false);
message.getBodyBuffer().writeInt("hello2".getBytes().length);
message.getBodyBuffer().writeBytes("hello2".getBytes());
producer.send(message);
Thread.sleep(100);
t = new MyThread(consumer);
t.start();
t.join();
Assert.assertTrue(passed);
}
}

View File

@ -1,562 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.activemq.artemis.rest.test;
import org.apache.activemq.artemis.rest.queue.QueueDeployment;
import org.apache.activemq.artemis.rest.util.Constants;
import org.jboss.logging.Logger;
import org.jboss.resteasy.client.ClientRequest;
import org.jboss.resteasy.client.ClientResponse;
import org.jboss.resteasy.spi.Link;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
import static org.jboss.resteasy.test.TestPortProvider.generateURL;
/**
* repost on same consume-next
* repost on old consume-next
* repost on same consume-next with timeouts
* repost on same ack-next
* repost successful ack
* repost successful unack
* repost ack after unack
* repost unack after ack
* post on old ack-next
* post on old ack-next after an ack
* ack with an old ack link
*/
public class RepostingQueueTest extends MessageTestBase {
private static final Logger log = Logger.getLogger(RepostingQueueTest.class);
@BeforeClass
public static void setup() throws Exception {
QueueDeployment deployment1 = new QueueDeployment("testQueue", true);
manager.getQueueManager().deploy(deployment1);
}
@Test
public void testPostOnSameConsumeNext() throws Exception {
ClientRequest request = new ClientRequest(generateURL("/queues/testQueue"));
ClientResponse<?> response = request.head();
response.releaseConnection();
Assert.assertEquals(200, response.getStatus());
Link sender = MessageTestBase.getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "create");
log.debug("create: " + sender);
Link consumers = MessageTestBase.getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "pull-consumers");
log.debug("pull: " + consumers);
response = Util.setAutoAck(consumers, true);
Link consumeNext = MessageTestBase.getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "consume-next");
log.debug("resource consume-next: " + consumeNext);
response = sender.request().body("text/plain", Integer.toString(1)).post();
response.releaseConnection();
Assert.assertEquals(201, response.getStatus());
response = consumeNext.request().post(String.class);
Assert.assertEquals(200, response.getStatus());
Assert.assertEquals("1", response.getEntity(String.class));
response.releaseConnection();
Link session = MessageTestBase.getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "consumer");
log.debug("session: " + session);
consumeNext = MessageTestBase.getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "consume-next");
log.debug("session 1st consumeNext: " + consumeNext);
response = sender.request().body("text/plain", Integer.toString(2)).post();
response.releaseConnection();
Assert.assertEquals(201, response.getStatus());
response = consumeNext.request().header(Constants.WAIT_HEADER, "10").post(String.class);
Assert.assertEquals(200, response.getStatus());
Assert.assertEquals("2", response.getEntity(String.class));
response.releaseConnection();
response = consumeNext.request().header(Constants.WAIT_HEADER, "10").post(String.class);
Assert.assertEquals(200, response.getStatus());
Assert.assertEquals("2", response.getEntity(String.class));
response.releaseConnection();
response = consumeNext.request().header(Constants.WAIT_HEADER, "10").post(String.class);
Assert.assertEquals(200, response.getStatus());
Assert.assertEquals("2", response.getEntity(String.class));
response.releaseConnection();
response = consumeNext.request().header(Constants.WAIT_HEADER, "10").post(String.class);
Assert.assertEquals(200, response.getStatus());
Assert.assertEquals("2", response.getEntity(String.class));
response.releaseConnection();
session = MessageTestBase.getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "consumer");
log.debug("session: " + session);
consumeNext = MessageTestBase.getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "consume-next");
log.debug("session 2nd consumeNext: " + consumeNext);
response = sender.request().body("text/plain", Integer.toString(3)).post();
response.releaseConnection();
Assert.assertEquals(201, response.getStatus());
response = consumeNext.request().header(Constants.WAIT_HEADER, "10").post(String.class);
Assert.assertEquals(200, response.getStatus());
Assert.assertEquals("3", response.getEntity(String.class));
response.releaseConnection();
response = session.request().delete();
response.releaseConnection();
Assert.assertEquals(204, response.getStatus());
}
@Test
public void testPostOnOldConsumeNext() throws Exception {
ClientRequest request = new ClientRequest(generateURL("/queues/testQueue"));
ClientResponse<?> response = request.head();
response.releaseConnection();
Assert.assertEquals(200, response.getStatus());
Link sender = MessageTestBase.getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "create");
log.debug("create: " + sender);
Link consumers = MessageTestBase.getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "pull-consumers");
log.debug("pull: " + consumers);
response = Util.setAutoAck(consumers, true);
Link consumeNext = MessageTestBase.getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "consume-next");
log.debug("resource consume-next: " + consumeNext);
response = sender.request().body("text/plain", Integer.toString(1)).post();
response.releaseConnection();
Assert.assertEquals(201, response.getStatus());
response = consumeNext.request().header(Constants.WAIT_HEADER, "1").post(String.class);
Assert.assertEquals(200, response.getStatus());
Assert.assertEquals("1", response.getEntity(String.class));
response.releaseConnection();
Link session = MessageTestBase.getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "consumer");
log.debug("session: " + session);
consumeNext = MessageTestBase.getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "consume-next");
Link firstConsumeNext = consumeNext;
log.debug("session 1st consumeNext: " + consumeNext);
response = sender.request().body("text/plain", Integer.toString(2)).post();
response.releaseConnection();
Assert.assertEquals(201, response.getStatus());
response = consumeNext.request().header(Constants.WAIT_HEADER, "10").post(String.class);
Assert.assertEquals(200, response.getStatus());
Assert.assertEquals("2", response.getEntity(String.class));
response.releaseConnection();
session = MessageTestBase.getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "consumer");
log.debug("session: " + session);
consumeNext = MessageTestBase.getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "consume-next");
log.debug("session 2nd consumeNext: " + consumeNext);
response = sender.request().body("text/plain", Integer.toString(3)).post();
response.releaseConnection();
Assert.assertEquals(201, response.getStatus());
response = consumeNext.request().header(Constants.WAIT_HEADER, "10").post(String.class);
Assert.assertEquals(200, response.getStatus());
Assert.assertEquals("3", response.getEntity(String.class));
response.releaseConnection();
response = firstConsumeNext.request().header(Constants.WAIT_HEADER, "10").post(String.class);
Assert.assertEquals(412, response.getStatus());
log.debug(response.getEntity(String.class));
response.releaseConnection();
response = session.request().delete();
response.releaseConnection();
Assert.assertEquals(204, response.getStatus());
}
@Test
public void testPostOnSameConsumeNextWithTimeout() throws Exception {
ClientRequest request = new ClientRequest(generateURL("/queues/testQueue"));
ClientResponse<?> response = request.head();
response.releaseConnection();
Assert.assertEquals(200, response.getStatus());
Link sender = MessageTestBase.getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "create");
log.debug("create: " + sender);
Link consumers = MessageTestBase.getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "pull-consumers");
log.debug("pull: " + consumers);
response = Util.setAutoAck(consumers, true);
Link consumeNext = MessageTestBase.getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "consume-next");
log.debug("resource consume-next: " + consumeNext);
response = sender.request().body("text/plain", Integer.toString(1)).post();
response.releaseConnection();
Assert.assertEquals(201, response.getStatus());
response = consumeNext.request().header(Constants.WAIT_HEADER, "1").post(String.class);
Assert.assertEquals(200, response.getStatus());
Assert.assertEquals("1", response.getEntity(String.class));
response.releaseConnection();
Link session = MessageTestBase.getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "consumer");
log.debug("session: " + session);
consumeNext = MessageTestBase.getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "consume-next");
log.debug("session 1st consumeNext: " + consumeNext);
// test timeout here
response = consumeNext.request().post(String.class);
response.releaseConnection();
Assert.assertEquals(503, response.getStatus());
session = MessageTestBase.getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "consumer");
log.debug("session: " + session);
consumeNext = MessageTestBase.getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "consume-next");
log.debug("session 2nd consumeNext: " + consumeNext);
response = sender.request().body("text/plain", Integer.toString(3)).post();
response.releaseConnection();
Assert.assertEquals(201, response.getStatus());
response = consumeNext.request().header(Constants.WAIT_HEADER, "10").post(String.class);
Assert.assertEquals(200, response.getStatus());
Assert.assertEquals("3", response.getEntity(String.class));
response.releaseConnection();
response = session.request().delete();
response.releaseConnection();
Assert.assertEquals(204, response.getStatus());
}
@Test
public void testPostOnSameAcknowledgeNextAndAck() throws Exception {
ClientRequest request = new ClientRequest(generateURL("/queues/testQueue"));
ClientResponse<?> response = request.head();
response.releaseConnection();
Assert.assertEquals(200, response.getStatus());
Link sender = MessageTestBase.getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "create");
log.debug("create: " + sender);
Link consumers = MessageTestBase.getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "pull-consumers");
log.debug("pull: " + consumers);
response = Util.setAutoAck(consumers, false);
Link consumeNext = MessageTestBase.getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "acknowledge-next");
log.debug("resource acknowledge-next: " + consumeNext);
response = sender.request().body("text/plain", Integer.toString(1)).post();
response.releaseConnection();
Assert.assertEquals(201, response.getStatus());
response = consumeNext.request().header(Constants.WAIT_HEADER, "3").post(String.class);
Assert.assertEquals(200, response.getStatus());
Assert.assertEquals("1", response.getEntity(String.class));
response.releaseConnection();
Link session = MessageTestBase.getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "consumer");
log.debug("session: " + session);
Link ack = MessageTestBase.getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "acknowledgement");
log.debug("ack: " + ack);
response = ack.request().formParameter("acknowledge", "true").post();
response.releaseConnection();
Assert.assertEquals(204, response.getStatus());
response = ack.request().formParameter("acknowledge", "true").post();
response.releaseConnection();
Assert.assertEquals(204, response.getStatus());
response = ack.request().formParameter("acknowledge", "true").post();
response.releaseConnection();
Assert.assertEquals(204, response.getStatus());
consumeNext = MessageTestBase.getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "acknowledge-next");
log.debug("session 1st acknowledge-next: " + consumeNext);
response = sender.request().body("text/plain", Integer.toString(2)).post();
response.releaseConnection();
Assert.assertEquals(201, response.getStatus());
response = consumeNext.request().header(Constants.WAIT_HEADER, "10").post(String.class);
Assert.assertEquals(200, response.getStatus());
Assert.assertEquals("2", response.getEntity(String.class));
response.releaseConnection();
response = consumeNext.request().header(Constants.WAIT_HEADER, "10").post(String.class);
Assert.assertEquals(200, response.getStatus());
Assert.assertEquals("2", response.getEntity(String.class));
response.releaseConnection();
response = consumeNext.request().header(Constants.WAIT_HEADER, "10").post(String.class);
Assert.assertEquals(200, response.getStatus());
Assert.assertEquals("2", response.getEntity(String.class));
response.releaseConnection();
response = consumeNext.request().header(Constants.WAIT_HEADER, "10").post(String.class);
Assert.assertEquals(200, response.getStatus());
Assert.assertEquals("2", response.getEntity(String.class));
response.releaseConnection();
ack = MessageTestBase.getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "acknowledgement");
log.debug("ack: " + ack);
response = ack.request().formParameter("acknowledge", "true").post();
response.releaseConnection();
Assert.assertEquals(204, response.getStatus());
response = session.request().delete();
response.releaseConnection();
Assert.assertEquals(204, response.getStatus());
}
@Test
public void testRepostSuccessfulUnacknowledge() throws Exception {
ClientRequest request = new ClientRequest(generateURL("/queues/testQueue"));
ClientResponse<?> response = request.head();
response.releaseConnection();
Assert.assertEquals(200, response.getStatus());
Link sender = MessageTestBase.getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "create");
log.debug("create: " + sender);
Link consumers = MessageTestBase.getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "pull-consumers");
log.debug("pull: " + consumers);
response = Util.setAutoAck(consumers, false);
Link consumeNext = MessageTestBase.getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "acknowledge-next");
log.debug("resource acknowledge-next: " + consumeNext);
response = sender.request().body("text/plain", Integer.toString(1)).post();
response.releaseConnection();
Assert.assertEquals(201, response.getStatus());
response = consumeNext.request().header(Constants.WAIT_HEADER, "1").post(String.class);
Assert.assertEquals(200, response.getStatus());
Assert.assertEquals("1", response.getEntity(String.class));
response.releaseConnection();
Link session = MessageTestBase.getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "consumer");
log.debug("session: " + session);
Link ack = MessageTestBase.getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "acknowledgement");
log.debug("ack: " + ack);
response = ack.request().formParameter("acknowledge", "false").post();
response.releaseConnection();
Assert.assertEquals(204, response.getStatus());
response = ack.request().formParameter("acknowledge", "false").post();
response.releaseConnection();
Assert.assertEquals(204, response.getStatus());
response = ack.request().formParameter("acknowledge", "false").post();
response.releaseConnection();
Assert.assertEquals(204, response.getStatus());
consumeNext = MessageTestBase.getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "acknowledge-next");
log.debug("session 1st acknowledge-next: " + consumeNext);
response = consumeNext.request().header(Constants.WAIT_HEADER, "10").post(String.class);
Assert.assertEquals(200, response.getStatus());
Assert.assertEquals("1", response.getEntity(String.class));
response.releaseConnection();
response = consumeNext.request().header(Constants.WAIT_HEADER, "10").post(String.class);
Assert.assertEquals(200, response.getStatus());
Assert.assertEquals("1", response.getEntity(String.class));
response.releaseConnection();
response = consumeNext.request().header(Constants.WAIT_HEADER, "10").post(String.class);
Assert.assertEquals(200, response.getStatus());
Assert.assertEquals("1", response.getEntity(String.class));
response.releaseConnection();
response = consumeNext.request().header(Constants.WAIT_HEADER, "10").post(String.class);
Assert.assertEquals(200, response.getStatus());
Assert.assertEquals("1", response.getEntity(String.class));
response.releaseConnection();
ack = MessageTestBase.getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "acknowledgement");
log.debug("ack: " + ack);
response = ack.request().formParameter("acknowledge", "true").post();
response.releaseConnection();
Assert.assertEquals(204, response.getStatus());
response = session.request().delete();
response.releaseConnection();
Assert.assertEquals(204, response.getStatus());
}
@Test
public void testRepostAckAfterUnacknowledge() throws Exception {
ClientRequest request = new ClientRequest(generateURL("/queues/testQueue"));
ClientResponse<?> response = request.head();
response.releaseConnection();
Assert.assertEquals(200, response.getStatus());
Link sender = MessageTestBase.getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "create");
log.debug("create: " + sender);
Link consumers = MessageTestBase.getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "pull-consumers");
log.debug("pull: " + consumers);
response = Util.setAutoAck(consumers, false);
Link consumeNext = MessageTestBase.getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "acknowledge-next");
log.debug("resource acknowledge-next: " + consumeNext);
response = sender.request().body("text/plain", Integer.toString(1)).post();
response.releaseConnection();
Assert.assertEquals(201, response.getStatus());
response = consumeNext.request().header(Constants.WAIT_HEADER, "1").post(String.class);
Assert.assertEquals(200, response.getStatus());
Assert.assertEquals("1", response.getEntity(String.class));
response.releaseConnection();
Link session = MessageTestBase.getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "consumer");
log.debug("session: " + session);
Link ack = MessageTestBase.getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "acknowledgement");
log.debug("ack: " + ack);
response = ack.request().formParameter("acknowledge", "false").post();
response.releaseConnection();
Assert.assertEquals(204, response.getStatus());
response = ack.request().formParameter("acknowledge", "true").post();
Assert.assertEquals(412, response.getStatus());
log.debug(response.getEntity(String.class));
response.releaseConnection();
consumeNext = MessageTestBase.getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "acknowledge-next");
log.debug("session 1st acknowledge-next: " + consumeNext);
response = consumeNext.request().header(Constants.WAIT_HEADER, "10").post(String.class);
Assert.assertEquals(200, response.getStatus());
Assert.assertEquals("1", response.getEntity(String.class));
response.releaseConnection();
response = consumeNext.request().header(Constants.WAIT_HEADER, "10").post(String.class);
Assert.assertEquals(200, response.getStatus());
Assert.assertEquals("1", response.getEntity(String.class));
response.releaseConnection();
response = consumeNext.request().header(Constants.WAIT_HEADER, "10").post(String.class);
Assert.assertEquals(200, response.getStatus());
Assert.assertEquals("1", response.getEntity(String.class));
response.releaseConnection();
response = consumeNext.request().header(Constants.WAIT_HEADER, "10").post(String.class);
Assert.assertEquals(200, response.getStatus());
Assert.assertEquals("1", response.getEntity(String.class));
response.releaseConnection();
ack = MessageTestBase.getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "acknowledgement");
log.debug("ack: " + ack);
response = ack.request().formParameter("acknowledge", "true").post();
response.releaseConnection();
Assert.assertEquals(204, response.getStatus());
response = session.request().delete();
response.releaseConnection();
Assert.assertEquals(204, response.getStatus());
}
@Test
public void testRepostUnAckAfterAcknowledge() throws Exception {
ClientRequest request = new ClientRequest(generateURL("/queues/testQueue"));
ClientResponse<?> response = request.head();
response.releaseConnection();
Assert.assertEquals(200, response.getStatus());
Link sender = MessageTestBase.getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "create");
log.debug("create: " + sender);
Link consumers = MessageTestBase.getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "pull-consumers");
log.debug("pull: " + consumers);
response = Util.setAutoAck(consumers, false);
Link consumeNext = MessageTestBase.getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "acknowledge-next");
log.debug("resource acknowledge-next: " + consumeNext);
response = sender.request().body("text/plain", Integer.toString(1)).post();
response.releaseConnection();
Assert.assertEquals(201, response.getStatus());
response = consumeNext.request().header(Constants.WAIT_HEADER, "3").post(String.class);
Assert.assertEquals(200, response.getStatus());
Assert.assertEquals("1", response.getEntity(String.class));
response.releaseConnection();
Link session = MessageTestBase.getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "consumer");
log.debug("session: " + session);
Link ack = MessageTestBase.getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "acknowledgement");
log.debug("ack: " + ack);
response = ack.request().formParameter("acknowledge", "true").post();
response.releaseConnection();
Assert.assertEquals(204, response.getStatus());
response = ack.request().formParameter("acknowledge", "false").post();
Assert.assertEquals(412, response.getStatus());
log.debug(response.getEntity(String.class));
response.releaseConnection();
consumeNext = MessageTestBase.getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "acknowledge-next");
log.debug("session 1st acknowledge-next: " + consumeNext);
response = sender.request().body("text/plain", Integer.toString(2)).post();
response.releaseConnection();
Assert.assertEquals(201, response.getStatus());
response = consumeNext.request().header(Constants.WAIT_HEADER, "10").post(String.class);
Assert.assertEquals(200, response.getStatus());
Assert.assertEquals("2", response.getEntity(String.class));
response.releaseConnection();
response = consumeNext.request().header(Constants.WAIT_HEADER, "10").post(String.class);
Assert.assertEquals(200, response.getStatus());
Assert.assertEquals("2", response.getEntity(String.class));
response.releaseConnection();
response = consumeNext.request().header(Constants.WAIT_HEADER, "10").post(String.class);
Assert.assertEquals(200, response.getStatus());
Assert.assertEquals("2", response.getEntity(String.class));
response.releaseConnection();
response = consumeNext.request().header(Constants.WAIT_HEADER, "10").post(String.class);
Assert.assertEquals(200, response.getStatus());
Assert.assertEquals("2", response.getEntity(String.class));
response.releaseConnection();
ack = MessageTestBase.getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "acknowledgement");
log.debug("ack: " + ack);
response = ack.request().formParameter("acknowledge", "true").post();
response.releaseConnection();
Assert.assertEquals(204, response.getStatus());
response = session.request().delete();
response.releaseConnection();
Assert.assertEquals(204, response.getStatus());
}
@Test
public void testPostOnOldAcknowledgeNextAndAck() throws Exception {
ClientRequest request = new ClientRequest(generateURL("/queues/testQueue"));
ClientResponse<?> response = request.head();
response.releaseConnection();
Assert.assertEquals(200, response.getStatus());
Link sender = MessageTestBase.getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "create");
log.debug("create: " + sender);
Link consumers = MessageTestBase.getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "pull-consumers");
log.debug("pull: " + consumers);
response = Util.setAutoAck(consumers, false);
Link consumeNext = MessageTestBase.getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "acknowledge-next");
log.debug("resource acknowledge-next: " + consumeNext);
response = sender.request().body("text/plain", Integer.toString(1)).post();
response.releaseConnection();
Assert.assertEquals(201, response.getStatus());
response = consumeNext.request().header(Constants.WAIT_HEADER, "3").post(String.class);
Assert.assertEquals(200, response.getStatus());
Assert.assertEquals("1", response.getEntity(String.class));
response.releaseConnection();
Link session = MessageTestBase.getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "consumer");
log.debug("session: " + session);
Link ack = MessageTestBase.getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "acknowledgement");
Link oldAck = ack;
log.debug("ack: " + ack);
response = ack.request().formParameter("acknowledge", "true").post();
response.releaseConnection();
Assert.assertEquals(204, response.getStatus());
consumeNext = MessageTestBase.getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "acknowledge-next");
log.debug("session 1st acknowledge-next: " + consumeNext);
response = sender.request().body("text/plain", Integer.toString(2)).post();
response.releaseConnection();
Assert.assertEquals(201, response.getStatus());
response = consumeNext.request().header(Constants.WAIT_HEADER, "10").post(String.class);
response.releaseConnection();
Assert.assertEquals(200, response.getStatus());
ack = MessageTestBase.getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "acknowledgement");
log.debug("ack: " + ack);
response = oldAck.request().formParameter("acknowledge", "true").post();
Assert.assertEquals(412, response.getStatus());
log.debug(response.getEntity(String.class));
response.releaseConnection();
response = ack.request().formParameter("acknowledge", "true").post();
response.releaseConnection();
Assert.assertEquals(204, response.getStatus());
consumeNext = MessageTestBase.getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "acknowledge-next");
response = consumeNext.request().post(String.class);
response.releaseConnection();
Assert.assertEquals(503, response.getStatus());
response = session.request().delete();
response.releaseConnection();
Assert.assertEquals(204, response.getStatus());
}
}

View File

@ -1,690 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.activemq.artemis.rest.test;
import org.apache.activemq.artemis.rest.topic.TopicDeployment;
import org.apache.activemq.artemis.rest.util.Constants;
import org.jboss.logging.Logger;
import org.jboss.resteasy.client.ClientRequest;
import org.jboss.resteasy.client.ClientResponse;
import org.jboss.resteasy.spi.Link;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
import static org.jboss.resteasy.test.TestPortProvider.generateURL;
/**
* repost on same consume-next
* repost on old consume-next
* repost on same consume-next with timeouts
* repost on same ack-next
* repost successful ack
* repost successful unack
* repost ack after unack
* repost unack after ack
* post on old ack-next
* post on old ack-next after an ack
* ack with an old ack link
*/
public class RepostingTopicTest extends MessageTestBase {
private static final Logger log = Logger.getLogger(RepostingTopicTest.class);
@BeforeClass
public static void setup() throws Exception {
TopicDeployment deployment1 = new TopicDeployment("testTopic", true);
manager.getTopicManager().deploy(deployment1);
}
@Test
public void testReconnectOnNamedSubscriber() throws Exception {
ClientRequest request = new ClientRequest(generateURL("/topics/testTopic"));
ClientResponse<?> response = request.head();
response.releaseConnection();
Assert.assertEquals(200, response.getStatus());
Link sender = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "create");
log.debug("create: " + sender);
Link consumers = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "pull-subscriptions");
log.debug("pull: " + consumers);
response = consumers.request().formParameter("name", "bill").post();
response.releaseConnection();
response = sender.request().body("text/plain", Integer.toString(1)).post();
response.releaseConnection();
Assert.assertEquals(201, response.getStatus());
response = sender.request().body("text/plain", Integer.toString(2)).post();
response.releaseConnection();
Assert.assertEquals(201, response.getStatus());
// recreate subscription a second time as named. Should pick up old one.
response = consumers.request().formParameter("name", "bill").post();
response.releaseConnection();
Link consumeNext = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "consume-next");
log.debug("resource consume-next: " + consumeNext);
response = consumeNext.request().post(String.class);
Assert.assertEquals(200, response.getStatus());
Assert.assertEquals("1", response.getEntity(String.class));
response.releaseConnection();
consumeNext = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "consume-next");
response = consumeNext.request().header("Accept-Wait", "2").post(String.class);
Assert.assertEquals(200, response.getStatus());
Assert.assertEquals("2", response.getEntity(String.class));
response.releaseConnection();
Link session = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "consumer");
response = session.request().delete();
response.releaseConnection();
Assert.assertEquals(204, response.getStatus());
}
@Test
public void testRestartOnDurableNamedSubscriber() throws Exception {
ClientRequest request = new ClientRequest(generateURL("/topics/testTopic"));
ClientResponse<?> response = request.head();
response.releaseConnection();
Assert.assertEquals(200, response.getStatus());
Link sender = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "create");
log.debug("create: " + sender);
Link consumers = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "pull-subscriptions");
log.debug("pull: " + consumers);
response = consumers.request().formParameter("name", "bill").formParameter("durable", "true").post();
response.releaseConnection();
response = sender.request().body("text/plain", Integer.toString(1)).post();
response.releaseConnection();
Assert.assertEquals(201, response.getStatus());
response = sender.request().body("text/plain", Integer.toString(2)).post();
response.releaseConnection();
Assert.assertEquals(201, response.getStatus());
manager.getTopicManager().getDestination().findTopic("testTopic").getSubscriptions().stop();
// recreate subscription a second time as named. Should pick up old one.
response = consumers.request().formParameter("name", "bill").formParameter("durable", "true").post();
response.releaseConnection();
Link consumeNext = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "consume-next");
log.debug("resource consume-next: " + consumeNext);
response = consumeNext.request().header("Accept-Wait", "2").post(String.class);
Assert.assertEquals(200, response.getStatus());
Assert.assertEquals("1", response.getEntity(String.class));
response.releaseConnection();
consumeNext = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "consume-next");
response = consumeNext.request().header("Accept-Wait", "2").post(String.class);
Assert.assertEquals(200, response.getStatus());
Assert.assertEquals("2", response.getEntity(String.class));
response.releaseConnection();
Link session = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "consumer");
response = session.request().delete();
response.releaseConnection();
Assert.assertEquals(204, response.getStatus());
}
@Test
public void testRestartOnNonDurableNamedSubscriber() throws Exception {
ClientRequest request = new ClientRequest(generateURL("/topics/testTopic"));
ClientResponse<?> response = request.head();
response.releaseConnection();
Assert.assertEquals(200, response.getStatus());
Link sender = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "create");
log.debug("create: " + sender);
Link consumers = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "pull-subscriptions");
log.debug("pull: " + consumers);
response = consumers.request().formParameter("name", "bill").post();
response.releaseConnection();
response = sender.request().body("text/plain", Integer.toString(1)).post();
response.releaseConnection();
Assert.assertEquals(201, response.getStatus());
response = sender.request().body("text/plain", Integer.toString(2)).post();
response.releaseConnection();
Assert.assertEquals(201, response.getStatus());
manager.getTopicManager().getDestination().findTopic("testTopic").getSubscriptions().stop();
// recreate subscription a second time as named. Should pick up old one.
response = consumers.request().formParameter("name", "bill").post();
response.releaseConnection();
Link consumeNext = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "consume-next");
log.debug("resource consume-next: " + consumeNext);
response = consumeNext.request().header("Accept-Wait", "2").post(String.class);
response.releaseConnection();
Assert.assertEquals(503, response.getStatus());
Link session = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "consumer");
response = session.request().delete();
response.releaseConnection();
Assert.assertEquals(204, response.getStatus());
}
@Test
public void testPostOnSameConsumeNext() throws Exception {
ClientRequest request = new ClientRequest(generateURL("/topics/testTopic"));
ClientResponse<?> response = request.head();
response.releaseConnection();
Assert.assertEquals(200, response.getStatus());
Link sender = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "create");
log.debug("create: " + sender);
Link consumers = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "pull-subscriptions");
log.debug("pull: " + consumers);
response = Util.setAutoAck(consumers, true);
Link consumeNext = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "consume-next");
log.debug("resource consume-next: " + consumeNext);
response = sender.request().body("text/plain", Integer.toString(1)).post();
response.releaseConnection();
Assert.assertEquals(201, response.getStatus());
response = consumeNext.request().post(String.class);
Assert.assertEquals(200, response.getStatus());
Assert.assertEquals("1", response.getEntity(String.class));
response.releaseConnection();
Link session = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "consumer");
log.debug("session: " + session);
consumeNext = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "consume-next");
log.debug("session 1st consumeNext: " + consumeNext);
response = sender.request().body("text/plain", Integer.toString(2)).post();
response.releaseConnection();
Assert.assertEquals(201, response.getStatus());
response = consumeNext.request().header(Constants.WAIT_HEADER, "10").post(String.class);
Assert.assertEquals(200, response.getStatus());
Assert.assertEquals("2", response.getEntity(String.class));
response.releaseConnection();
response = consumeNext.request().header(Constants.WAIT_HEADER, "10").post(String.class);
Assert.assertEquals(200, response.getStatus());
Assert.assertEquals("2", response.getEntity(String.class));
response.releaseConnection();
response = consumeNext.request().header(Constants.WAIT_HEADER, "10").post(String.class);
Assert.assertEquals(200, response.getStatus());
Assert.assertEquals("2", response.getEntity(String.class));
response.releaseConnection();
response = consumeNext.request().header(Constants.WAIT_HEADER, "10").post(String.class);
Assert.assertEquals(200, response.getStatus());
Assert.assertEquals("2", response.getEntity(String.class));
response.releaseConnection();
session = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "consumer");
log.debug("session: " + session);
consumeNext = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "consume-next");
log.debug("session 2nd consumeNext: " + consumeNext);
response = sender.request().body("text/plain", Integer.toString(3)).post();
response.releaseConnection();
Assert.assertEquals(201, response.getStatus());
response = consumeNext.request().header(Constants.WAIT_HEADER, "10").post(String.class);
Assert.assertEquals(200, response.getStatus());
Assert.assertEquals("3", response.getEntity(String.class));
response.releaseConnection();
response = session.request().delete();
response.releaseConnection();
Assert.assertEquals(204, response.getStatus());
}
@Test
public void testPostOnOldConsumeNext() throws Exception {
ClientRequest request = new ClientRequest(generateURL("/topics/testTopic"));
ClientResponse<?> response = request.head();
response.releaseConnection();
Assert.assertEquals(200, response.getStatus());
Link sender = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "create");
log.debug("create: " + sender);
Link consumers = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "pull-subscriptions");
log.debug("pull: " + consumers);
response = Util.setAutoAck(consumers, true);
Link consumeNext = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "consume-next");
log.debug("resource consume-next: " + consumeNext);
response = sender.request().body("text/plain", Integer.toString(1)).post();
response.releaseConnection();
Assert.assertEquals(201, response.getStatus());
response = consumeNext.request().post(String.class);
Assert.assertEquals(200, response.getStatus());
Assert.assertEquals("1", response.getEntity(String.class));
response.releaseConnection();
Link session = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "consumer");
log.debug("session: " + session);
consumeNext = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "consume-next");
Link firstConsumeNext = consumeNext;
log.debug("session 1st consumeNext: " + consumeNext);
response = sender.request().body("text/plain", Integer.toString(2)).post();
response.releaseConnection();
Assert.assertEquals(201, response.getStatus());
response = consumeNext.request().header(Constants.WAIT_HEADER, "10").post(String.class);
Assert.assertEquals(200, response.getStatus());
Assert.assertEquals("2", response.getEntity(String.class));
response.releaseConnection();
session = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "consumer");
log.debug("session: " + session);
consumeNext = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "consume-next");
log.debug("session 2nd consumeNext: " + consumeNext);
response = sender.request().body("text/plain", Integer.toString(3)).post();
response.releaseConnection();
Assert.assertEquals(201, response.getStatus());
response = consumeNext.request().header(Constants.WAIT_HEADER, "10").post(String.class);
Assert.assertEquals(200, response.getStatus());
Assert.assertEquals("3", response.getEntity(String.class));
response.releaseConnection();
response = firstConsumeNext.request().header(Constants.WAIT_HEADER, "10").post(String.class);
Assert.assertEquals(412, response.getStatus());
log.debug(response.getEntity(String.class));
response.releaseConnection();
response = session.request().delete();
response.releaseConnection();
Assert.assertEquals(204, response.getStatus());
}
@Test
public void testPostOnSameConsumeNextWithTimeout() throws Exception {
ClientRequest request = new ClientRequest(generateURL("/topics/testTopic"));
ClientResponse<?> response = request.head();
response.releaseConnection();
Assert.assertEquals(200, response.getStatus());
Link sender = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "create");
log.debug("create: " + sender);
Link consumers = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "pull-subscriptions");
log.debug("pull: " + consumers);
response = Util.setAutoAck(consumers, true);
Link consumeNext = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "consume-next");
log.debug("resource consume-next: " + consumeNext);
response = sender.request().body("text/plain", Integer.toString(1)).post();
response.releaseConnection();
Assert.assertEquals(201, response.getStatus());
response = consumeNext.request().post(String.class);
Assert.assertEquals(200, response.getStatus());
Assert.assertEquals("1", response.getEntity(String.class));
response.releaseConnection();
Link session = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "consumer");
log.debug("session: " + session);
consumeNext = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "consume-next");
log.debug("session 1st consumeNext: " + consumeNext);
// test timeout here
response = consumeNext.request().post(String.class);
response.releaseConnection();
Assert.assertEquals(503, response.getStatus());
session = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "consumer");
log.debug("session: " + session);
consumeNext = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "consume-next");
log.debug("session 2nd consumeNext: " + consumeNext);
response = sender.request().body("text/plain", Integer.toString(3)).post();
response.releaseConnection();
Assert.assertEquals(201, response.getStatus());
response = consumeNext.request().header(Constants.WAIT_HEADER, "10").post(String.class);
Assert.assertEquals(200, response.getStatus());
Assert.assertEquals("3", response.getEntity(String.class));
response.releaseConnection();
response = session.request().delete();
response.releaseConnection();
Assert.assertEquals(204, response.getStatus());
}
@Test
public void testPostOnSameAcknowledgeNextAndAck() throws Exception {
ClientRequest request = new ClientRequest(generateURL("/topics/testTopic"));
ClientResponse<?> response = request.head();
response.releaseConnection();
Assert.assertEquals(200, response.getStatus());
Link sender = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "create");
log.debug("create: " + sender);
Link consumers = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "pull-subscriptions");
log.debug("pull: " + consumers);
response = Util.setAutoAck(consumers, false);
Link consumeNext = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "acknowledge-next");
log.debug("resource acknowledge-next: " + consumeNext);
response = sender.request().body("text/plain", Integer.toString(1)).post();
response.releaseConnection();
Assert.assertEquals(201, response.getStatus());
response = consumeNext.request().post(String.class);
Assert.assertEquals(200, response.getStatus());
Assert.assertEquals("1", response.getEntity(String.class));
response.releaseConnection();
Link session = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "consumer");
log.debug("session: " + session);
Link ack = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "acknowledgement");
log.debug("ack: " + ack);
response = ack.request().formParameter("acknowledge", "true").post();
response.releaseConnection();
Assert.assertEquals(204, response.getStatus());
response = ack.request().formParameter("acknowledge", "true").post();
response.releaseConnection();
Assert.assertEquals(204, response.getStatus());
response = ack.request().formParameter("acknowledge", "true").post();
response.releaseConnection();
Assert.assertEquals(204, response.getStatus());
consumeNext = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "acknowledge-next");
log.debug("session 1st acknowledge-next: " + consumeNext);
response = sender.request().body("text/plain", Integer.toString(2)).post();
response.releaseConnection();
Assert.assertEquals(201, response.getStatus());
response = consumeNext.request().header(Constants.WAIT_HEADER, "10").post(String.class);
Assert.assertEquals(200, response.getStatus());
Assert.assertEquals("2", response.getEntity(String.class));
response.releaseConnection();
response = consumeNext.request().header(Constants.WAIT_HEADER, "10").post(String.class);
Assert.assertEquals(200, response.getStatus());
Assert.assertEquals("2", response.getEntity(String.class));
response.releaseConnection();
response = consumeNext.request().header(Constants.WAIT_HEADER, "10").post(String.class);
Assert.assertEquals(200, response.getStatus());
Assert.assertEquals("2", response.getEntity(String.class));
response.releaseConnection();
response = consumeNext.request().header(Constants.WAIT_HEADER, "10").post(String.class);
Assert.assertEquals(200, response.getStatus());
Assert.assertEquals("2", response.getEntity(String.class));
response.releaseConnection();
ack = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "acknowledgement");
log.debug("ack: " + ack);
response = ack.request().formParameter("acknowledge", "true").post();
response.releaseConnection();
Assert.assertEquals(204, response.getStatus());
response = session.request().delete();
response.releaseConnection();
Assert.assertEquals(204, response.getStatus());
}
@Test
public void testRepostSuccessfulUnacknowledge() throws Exception {
ClientRequest request = new ClientRequest(generateURL("/topics/testTopic"));
ClientResponse<?> response = request.head();
response.releaseConnection();
Assert.assertEquals(200, response.getStatus());
Link sender = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "create");
log.debug("create: " + sender);
Link consumers = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "pull-subscriptions");
log.debug("pull: " + consumers);
response = Util.setAutoAck(consumers, false);
Link consumeNext = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "acknowledge-next");
log.debug("resource acknowledge-next: " + consumeNext);
response = sender.request().body("text/plain", Integer.toString(1)).post();
response.releaseConnection();
Assert.assertEquals(201, response.getStatus());
response = consumeNext.request().post(String.class);
Assert.assertEquals(200, response.getStatus());
Assert.assertEquals("1", response.getEntity(String.class));
response.releaseConnection();
Link session = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "consumer");
log.debug("session: " + session);
Link ack = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "acknowledgement");
log.debug("ack: " + ack);
response = ack.request().formParameter("acknowledge", "false").post();
response.releaseConnection();
Assert.assertEquals(204, response.getStatus());
response = ack.request().formParameter("acknowledge", "false").post();
response.releaseConnection();
Assert.assertEquals(204, response.getStatus());
response = ack.request().formParameter("acknowledge", "false").post();
response.releaseConnection();
Assert.assertEquals(204, response.getStatus());
consumeNext = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "acknowledge-next");
log.debug("session 1st acknowledge-next: " + consumeNext);
response = consumeNext.request().header(Constants.WAIT_HEADER, "10").post(String.class);
Assert.assertEquals(200, response.getStatus());
Assert.assertEquals("1", response.getEntity(String.class));
response.releaseConnection();
response = consumeNext.request().header(Constants.WAIT_HEADER, "10").post(String.class);
Assert.assertEquals(200, response.getStatus());
Assert.assertEquals("1", response.getEntity(String.class));
response.releaseConnection();
response = consumeNext.request().header(Constants.WAIT_HEADER, "10").post(String.class);
Assert.assertEquals(200, response.getStatus());
Assert.assertEquals("1", response.getEntity(String.class));
response.releaseConnection();
response = consumeNext.request().header(Constants.WAIT_HEADER, "10").post(String.class);
Assert.assertEquals(200, response.getStatus());
Assert.assertEquals("1", response.getEntity(String.class));
response.releaseConnection();
ack = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "acknowledgement");
log.debug("ack: " + ack);
response = ack.request().formParameter("acknowledge", "true").post();
response.releaseConnection();
Assert.assertEquals(204, response.getStatus());
response = session.request().delete();
response.releaseConnection();
Assert.assertEquals(204, response.getStatus());
}
@Test
public void testRepostAckAfterUnacknowledge() throws Exception {
ClientRequest request = new ClientRequest(generateURL("/topics/testTopic"));
ClientResponse<?> response = request.head();
response.releaseConnection();
Assert.assertEquals(200, response.getStatus());
Link sender = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "create");
log.debug("create: " + sender);
Link consumers = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "pull-subscriptions");
log.debug("pull: " + consumers);
response = Util.setAutoAck(consumers, false);
Link consumeNext = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "acknowledge-next");
log.debug("resource acknowledge-next: " + consumeNext);
response = sender.request().body("text/plain", Integer.toString(1)).post();
response.releaseConnection();
Assert.assertEquals(201, response.getStatus());
response = consumeNext.request().post(String.class);
Assert.assertEquals(200, response.getStatus());
Assert.assertEquals("1", response.getEntity(String.class));
response.releaseConnection();
Link session = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "consumer");
log.debug("session: " + session);
Link ack = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "acknowledgement");
log.debug("ack: " + ack);
response = ack.request().formParameter("acknowledge", "false").post();
response.releaseConnection();
Assert.assertEquals(204, response.getStatus());
response = ack.request().formParameter("acknowledge", "true").post();
Assert.assertEquals(412, response.getStatus());
log.debug(response.getEntity(String.class));
response.releaseConnection();
consumeNext = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "acknowledge-next");
log.debug("session 1st acknowledge-next: " + consumeNext);
response = consumeNext.request().header(Constants.WAIT_HEADER, "10").post(String.class);
Assert.assertEquals(200, response.getStatus());
Assert.assertEquals("1", response.getEntity(String.class));
response.releaseConnection();
response = consumeNext.request().header(Constants.WAIT_HEADER, "10").post(String.class);
Assert.assertEquals(200, response.getStatus());
Assert.assertEquals("1", response.getEntity(String.class));
response.releaseConnection();
response = consumeNext.request().header(Constants.WAIT_HEADER, "10").post(String.class);
Assert.assertEquals(200, response.getStatus());
Assert.assertEquals("1", response.getEntity(String.class));
response.releaseConnection();
response = consumeNext.request().header(Constants.WAIT_HEADER, "10").post(String.class);
Assert.assertEquals(200, response.getStatus());
Assert.assertEquals("1", response.getEntity(String.class));
response.releaseConnection();
ack = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "acknowledgement");
log.debug("ack: " + ack);
response = ack.request().formParameter("acknowledge", "true").post();
response.releaseConnection();
Assert.assertEquals(204, response.getStatus());
response = session.request().delete();
response.releaseConnection();
Assert.assertEquals(204, response.getStatus());
}
@Test
public void testRepostUnAckAfterAcknowledge() throws Exception {
ClientRequest request = new ClientRequest(generateURL("/topics/testTopic"));
ClientResponse<?> response = request.head();
response.releaseConnection();
Assert.assertEquals(200, response.getStatus());
Link sender = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "create");
log.debug("create: " + sender);
Link consumers = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "pull-subscriptions");
log.debug("pull: " + consumers);
response = Util.setAutoAck(consumers, false);
Link consumeNext = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "acknowledge-next");
log.debug("resource acknowledge-next: " + consumeNext);
response = sender.request().body("text/plain", Integer.toString(1)).post();
response.releaseConnection();
Assert.assertEquals(201, response.getStatus());
response = consumeNext.request().post(String.class);
Assert.assertEquals(200, response.getStatus());
Assert.assertEquals("1", response.getEntity(String.class));
response.releaseConnection();
Link session = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "consumer");
log.debug("session: " + session);
Link ack = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "acknowledgement");
log.debug("ack: " + ack);
response = ack.request().formParameter("acknowledge", "true").post();
response.releaseConnection();
Assert.assertEquals(204, response.getStatus());
response = ack.request().formParameter("acknowledge", "false").post();
Assert.assertEquals(412, response.getStatus());
log.debug(response.getEntity(String.class));
response.releaseConnection();
consumeNext = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "acknowledge-next");
log.debug("session 1st acknowledge-next: " + consumeNext);
response = sender.request().body("text/plain", Integer.toString(2)).post();
response.releaseConnection();
Assert.assertEquals(201, response.getStatus());
response = consumeNext.request().header(Constants.WAIT_HEADER, "10").post(String.class);
Assert.assertEquals(200, response.getStatus());
Assert.assertEquals("2", response.getEntity(String.class));
response.releaseConnection();
response = consumeNext.request().header(Constants.WAIT_HEADER, "10").post(String.class);
Assert.assertEquals(200, response.getStatus());
Assert.assertEquals("2", response.getEntity(String.class));
response.releaseConnection();
response = consumeNext.request().header(Constants.WAIT_HEADER, "10").post(String.class);
Assert.assertEquals(200, response.getStatus());
Assert.assertEquals("2", response.getEntity(String.class));
response.releaseConnection();
response = consumeNext.request().header(Constants.WAIT_HEADER, "10").post(String.class);
Assert.assertEquals(200, response.getStatus());
Assert.assertEquals("2", response.getEntity(String.class));
response.releaseConnection();
ack = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "acknowledgement");
log.debug("ack: " + ack);
response = ack.request().formParameter("acknowledge", "true").post();
response.releaseConnection();
Assert.assertEquals(204, response.getStatus());
response = session.request().delete();
response.releaseConnection();
Assert.assertEquals(204, response.getStatus());
}
@Test
public void testPostOnOldAcknowledgeNextAndAck() throws Exception {
ClientRequest request = new ClientRequest(generateURL("/topics/testTopic"));
ClientResponse<?> response = request.head();
response.releaseConnection();
Assert.assertEquals(200, response.getStatus());
Link sender = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "create");
log.debug("create: " + sender);
Link consumers = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "pull-subscriptions");
log.debug("pull: " + consumers);
response = Util.setAutoAck(consumers, false);
Link consumeNext = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "acknowledge-next");
log.debug("resource acknowledge-next: " + consumeNext);
response = sender.request().body("text/plain", Integer.toString(1)).post();
response.releaseConnection();
Assert.assertEquals(201, response.getStatus());
response = consumeNext.request().header(Constants.WAIT_HEADER, "1").post(String.class);
Assert.assertEquals(200, response.getStatus());
Assert.assertEquals("1", response.getEntity(String.class));
response.releaseConnection();
Link session = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "consumer");
log.debug("session: " + session);
Link ack = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "acknowledgement");
Link oldAck = ack;
log.debug("ack: " + ack);
response = ack.request().formParameter("acknowledge", "true").post();
response.releaseConnection();
Assert.assertEquals(204, response.getStatus());
consumeNext = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "acknowledge-next");
log.debug("session 1st acknowledge-next: " + consumeNext);
Link firstConsumeNext = consumeNext;
response = sender.request().body("text/plain", Integer.toString(2)).post();
response.releaseConnection();
Assert.assertEquals(201, response.getStatus());
response = consumeNext.request().header(Constants.WAIT_HEADER, "10").post(String.class);
response.releaseConnection();
Assert.assertEquals(200, response.getStatus());
ack = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "acknowledgement");
log.debug("ack: " + ack);
response = oldAck.request().formParameter("acknowledge", "true").post();
Assert.assertEquals(412, response.getStatus());
log.debug(response.getEntity(String.class));
response.releaseConnection();
consumeNext = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "acknowledge-next");
response = ack.request().formParameter("acknowledge", "true").post();
response.releaseConnection();
Assert.assertEquals(204, response.getStatus());
consumeNext = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "acknowledge-next");
response = consumeNext.request().post(String.class);
response.releaseConnection();
Assert.assertEquals(503, response.getStatus());
response = session.request().delete();
response.releaseConnection();
Assert.assertEquals(204, response.getStatus());
}
}

View File

@ -1,71 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.activemq.artemis.rest.test;
import org.apache.activemq.artemis.rest.queue.QueueDeployment;
import org.jboss.logging.Logger;
import org.jboss.resteasy.client.ClientRequest;
import org.jboss.resteasy.client.ClientResponse;
import org.jboss.resteasy.spi.Link;
import org.junit.Assert;
import org.junit.Test;
import static org.jboss.resteasy.test.TestPortProvider.generateURL;
public class RoundtripTimeTest extends MessageTestBase {
private static final Logger log = Logger.getLogger(RoundtripTimeTest.class);
@Test
public void testSuccessFirst() throws Exception {
QueueDeployment deployment = new QueueDeployment();
deployment.setDuplicatesAllowed(true);
deployment.setDurableSend(false);
deployment.setName("testQueue");
manager.getQueueManager().deploy(deployment);
ClientRequest request = new ClientRequest(generateURL("/queues/testQueue"));
ClientResponse<?> response = request.head();
response.releaseConnection();
Assert.assertEquals(200, response.getStatus());
Link sender = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "create");
log.debug("create: " + sender);
Link consumers = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "pull-consumers");
log.debug("pull: " + consumers);
response = Util.setAutoAck(consumers, true);
Link consumeNext = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "consume-next");
log.debug("consume-next: " + consumeNext);
long start = System.currentTimeMillis();
int num = 100;
for (int i = 0; i < num; i++) {
response = sender.request().body("text/plain", Integer.toString(i + 1)).post();
response.releaseConnection();
}
long end = System.currentTimeMillis() - start;
log.debug(num + " iterations took " + end + "ms");
for (int i = 0; i < num; i++) {
response = consumeNext.request().post(String.class);
consumeNext = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "consume-next");
Assert.assertEquals(200, response.getStatus());
Assert.assertEquals(Integer.toString(i + 1), response.getEntity(String.class));
response.releaseConnection();
}
}
}

View File

@ -1,303 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.activemq.artemis.rest.test;
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.Destination;
import javax.jms.MessageProducer;
import javax.jms.ObjectMessage;
import javax.jms.Session;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.xml.bind.annotation.XmlRootElement;
import java.io.Serializable;
import org.apache.activemq.artemis.jms.client.ActiveMQDestination;
import org.apache.activemq.artemis.jms.client.ActiveMQJMSConnectionFactory;
import org.apache.activemq.artemis.rest.HttpHeaderProperty;
import org.apache.activemq.artemis.rest.queue.push.xml.XmlLink;
import org.apache.activemq.artemis.rest.topic.PushTopicRegistration;
import org.apache.activemq.artemis.rest.topic.TopicDeployment;
import org.apache.activemq.artemis.utils.Wait;
import org.jboss.logging.Logger;
import org.jboss.resteasy.client.ClientRequest;
import org.jboss.resteasy.client.ClientResponse;
import org.jboss.resteasy.spi.Link;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
import static org.jboss.resteasy.test.TestPortProvider.generateURL;
public class SelectorTest extends MessageTestBase {
private static final Logger log = Logger.getLogger(SelectorTest.class);
public static ConnectionFactory connectionFactory;
public static String topicName = "testTopic";
public static String prefixedTopicName = ActiveMQDestination.createTopicAddressFromName(topicName).toString();
@BeforeClass
public static void setup() throws Exception {
connectionFactory = new ActiveMQJMSConnectionFactory(manager.getQueueManager().getServerLocator());
log.debug("Queue name: " + prefixedTopicName);
TopicDeployment deployment = new TopicDeployment();
deployment.setDuplicatesAllowed(true);
deployment.setDurableSend(false);
deployment.setName(topicName);
manager.getTopicManager().deploy(deployment);
}
@XmlRootElement
public static class Order implements Serializable {
private static final long serialVersionUID = 482698090549294508L;
private String name;
private String amount;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAmount() {
return amount;
}
public void setAmount(String amount) {
this.amount = amount;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
Order order = (Order) o;
if (!amount.equals(order.amount)) {
return false;
}
if (!name.equals(order.name)) {
return false;
}
return true;
}
@Override
public String toString() {
return "Order{" +
"name='" + name + '\'' +
'}';
}
@Override
public int hashCode() {
int result = name.hashCode();
result = 31 * result + amount.hashCode();
return result;
}
}
public static Destination createDestination(String dest) {
ActiveMQDestination destination = (ActiveMQDestination) ActiveMQDestination.fromPrefixedName(dest);
log.debug("SimpleAddress: " + destination.getSimpleAddress());
return destination;
}
public static void publish(String dest, Serializable object, String contentType, String tag) throws Exception {
Connection conn = connectionFactory.createConnection();
try {
Session session = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
Destination destination = createDestination(dest);
MessageProducer producer = session.createProducer(destination);
ObjectMessage message = session.createObjectMessage();
if (contentType != null) {
message.setStringProperty(HttpHeaderProperty.CONTENT_TYPE, contentType);
}
if (tag != null) {
message.setStringProperty("MyTag", tag);
}
message.setObject(object);
producer.send(message);
} finally {
conn.close();
}
}
@Path("/push")
public static class PushReceiver {
public static Order oneOrder;
public static Order twoOrder;
@POST
@Path("one")
public void one(Order order) {
oneOrder = order;
}
@POST
@Path("two")
public void two(Order order) {
twoOrder = order;
}
}
@Test
public void testPush() throws Exception {
server.getJaxrsServer().getDeployment().getRegistry().addPerRequestResource(PushReceiver.class);
ClientRequest request = new ClientRequest(generateURL("/topics/" + topicName));
ClientResponse<?> response = request.head();
response.releaseConnection();
Assert.assertEquals(200, response.getStatus());
Link consumers = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "push-subscriptions");
log.debug("push: " + consumers);
PushTopicRegistration oneReg = new PushTopicRegistration();
oneReg.setDurable(false);
XmlLink target = new XmlLink();
target.setMethod("post");
target.setHref(generateURL("/push/one"));
target.setType("application/xml");
oneReg.setTarget(target);
oneReg.setSelector("MyTag = '1'");
response = consumers.request().body("application/xml", oneReg).post();
response.releaseConnection();
Link oneSubscription = response.getLocationLink();
PushTopicRegistration twoReg = new PushTopicRegistration();
twoReg.setDurable(false);
target = new XmlLink();
target.setMethod("post");
target.setHref(generateURL("/push/two"));
target.setType("application/xml");
twoReg.setTarget(target);
twoReg.setSelector("MyTag = '2'");
response = consumers.request().body("application/xml", twoReg).post();
response.releaseConnection();
Link twoSubscription = response.getLocationLink();
Order order = new Order();
order.setName("1");
order.setAmount("$5.00");
publish(prefixedTopicName, order, null, "1");
Wait.assertEquals(order, () -> PushReceiver.oneOrder);
order.setName("2");
publish(prefixedTopicName, order, null, "2");
Wait.assertEquals(order, () -> PushReceiver.twoOrder);
order.setName("3");
publish(prefixedTopicName, order, null, "2");
Wait.assertEquals(order, () -> PushReceiver.twoOrder);
order.setName("4");
publish(prefixedTopicName, order, null, "1");
Wait.assertEquals(order, () -> PushReceiver.oneOrder);
order.setName("5");
publish(prefixedTopicName, order, null, "1");
Wait.assertEquals(order, () -> PushReceiver.oneOrder);
order.setName("6");
publish(prefixedTopicName, order, null, "1");
Wait.assertEquals(order, () -> PushReceiver.oneOrder);
response = oneSubscription.request().delete();
response.releaseConnection();
response = twoSubscription.request().delete();
response.releaseConnection();
}
@Test
public void testPull() throws Exception {
ClientRequest request = new ClientRequest(generateURL("/topics/" + topicName));
ClientResponse<?> response = request.head();
response.releaseConnection();
Assert.assertEquals(200, response.getStatus());
Link consumers = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "pull-subscriptions");
log.debug("pull: " + consumers);
response = consumers.request().formParameter("autoAck", "true").formParameter("selector", "MyTag = '1'").post();
response.releaseConnection();
Link consumeOne = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "consume-next");
log.debug("consumeOne: " + consumeOne);
response = consumers.request().formParameter("autoAck", "true").formParameter("selector", "MyTag = '2'").post();
response.releaseConnection();
Link consumeTwo = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "consume-next");
log.debug("consumeTwo: " + consumeTwo);
// test that Accept header is used to set content-type
{
Order order = new Order();
order.setName("1");
order.setAmount("$5.00");
publish(prefixedTopicName, order, null, "1");
order.setName("2");
publish(prefixedTopicName, order, null, "2");
order.setName("3");
publish(prefixedTopicName, order, null, "2");
order.setName("4");
publish(prefixedTopicName, order, null, "1");
order.setName("5");
publish(prefixedTopicName, order, null, "1");
order.setName("6");
publish(prefixedTopicName, order, null, "1");
{
order.setName("1");
consumeOne = consumeOrder(order, consumeOne);
order.setName("2");
consumeTwo = consumeOrder(order, consumeTwo);
order.setName("3");
consumeTwo = consumeOrder(order, consumeTwo);
order.setName("4");
consumeOne = consumeOrder(order, consumeOne);
order.setName("5");
consumeOne = consumeOrder(order, consumeOne);
order.setName("6");
consumeOne = consumeOrder(order, consumeOne);
}
}
}
private Link consumeOrder(Order order, Link consumeNext) throws Exception {
ClientResponse<?> response = consumeNext.request().header("Accept-Wait", "4").accept("application/xml").post(String.class);
Assert.assertEquals(200, response.getStatus());
Assert.assertTrue(response.getHeaders().getFirst("Content-Type").toString().toLowerCase().contains("application/xml"));
Order order2 = response.getEntity(Order.class);
Assert.assertEquals(order, order2);
consumeNext = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "consume-next");
Assert.assertNotNull(consumeNext);
response.releaseConnection();
return consumeNext;
}
}

View File

@ -1,308 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.activemq.artemis.rest.test;
import org.apache.activemq.artemis.rest.queue.QueueDeployment;
import org.apache.activemq.artemis.rest.topic.TopicDeployment;
import org.apache.activemq.artemis.rest.util.Constants;
import org.jboss.logging.Logger;
import org.jboss.resteasy.client.ClientRequest;
import org.jboss.resteasy.client.ClientResponse;
import org.jboss.resteasy.spi.Link;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
import static org.jboss.resteasy.test.TestPortProvider.generateURL;
public class SessionTest extends MessageTestBase {
private static final Logger log = Logger.getLogger(SessionTest.class);
@BeforeClass
public static void setup() throws Exception {
QueueDeployment deployment1 = new QueueDeployment("testQueue", true);
manager.getQueueManager().deploy(deployment1);
TopicDeployment deployment = new TopicDeployment();
deployment.setConsumerSessionTimeoutSeconds(1);
deployment.setDuplicatesAllowed(true);
deployment.setDurableSend(false);
deployment.setName("testTopic");
manager.getTopicManager().deploy(deployment);
}
@Test
public void testRestartFromAutoAckSession() throws Exception {
ClientRequest request = new ClientRequest(generateURL("/queues/testQueue"));
ClientResponse<?> response = request.head();
response.releaseConnection();
Assert.assertEquals(200, response.getStatus());
Link sender = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "create");
log.debug("create: " + sender);
Link consumers = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "pull-consumers");
log.debug("pull: " + consumers);
response = Util.setAutoAck(consumers, true);
Link session = response.getLocationLink();
response = session.request().head();
response.releaseConnection();
Link consumeNext = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "consume-next");
log.debug("consume-next: " + consumeNext);
response = sender.request().body("text/plain", Integer.toString(1)).post();
response.releaseConnection();
Assert.assertEquals(201, response.getStatus());
response = consumeNext.request().post(String.class);
Assert.assertEquals(200, response.getStatus());
Assert.assertEquals("1", response.getEntity(String.class));
response.releaseConnection();
response = session.request().get();
consumeNext = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "consume-next");
response = sender.request().body("text/plain", Integer.toString(2)).post();
response.releaseConnection();
Assert.assertEquals(201, response.getStatus());
response = consumeNext.request().post(String.class);
Assert.assertEquals(200, response.getStatus());
Assert.assertEquals("2", response.getEntity(String.class));
response.releaseConnection();
response = session.request().head();
consumeNext = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "consume-next");
response = sender.request().body("text/plain", Integer.toString(3)).post();
response.releaseConnection();
Assert.assertEquals(201, response.getStatus());
response = consumeNext.request().post(String.class);
Assert.assertEquals(200, response.getStatus());
Assert.assertEquals("3", response.getEntity(String.class));
response.releaseConnection();
response = session.request().delete();
response.releaseConnection();
Assert.assertEquals(204, response.getStatus());
}
@Test
public void testTopicRestartFromAutoAckSession() throws Exception {
ClientRequest request = new ClientRequest(generateURL("/topics/testTopic"));
ClientResponse<?> response = request.head();
response.releaseConnection();
Assert.assertEquals(200, response.getStatus());
Link sender = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "create");
log.debug("create: " + sender);
Link consumers = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "pull-subscriptions");
log.debug("pull: " + consumers);
response = Util.setAutoAck(consumers, true);
Link session = response.getLocationLink();
response = session.request().head();
response.releaseConnection();
Link consumeNext = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "consume-next");
log.debug("consume-next: " + consumeNext);
response = sender.request().body("text/plain", Integer.toString(1)).post();
response.releaseConnection();
Assert.assertEquals(201, response.getStatus());
response = consumeNext.request().post(String.class);
Assert.assertEquals(200, response.getStatus());
Assert.assertEquals("1", response.getEntity(String.class));
response.releaseConnection();
response = session.request().get();
response.releaseConnection();
consumeNext = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "consume-next");
response = sender.request().body("text/plain", Integer.toString(2)).post();
response.releaseConnection();
Assert.assertEquals(201, response.getStatus());
response = consumeNext.request().post(String.class);
Assert.assertEquals(200, response.getStatus());
Assert.assertEquals("2", response.getEntity(String.class));
response.releaseConnection();
response = session.request().head();
response.releaseConnection();
consumeNext = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "consume-next");
response = sender.request().body("text/plain", Integer.toString(3)).post();
response.releaseConnection();
Assert.assertEquals(201, response.getStatus());
response = consumeNext.request().post(String.class);
Assert.assertEquals(200, response.getStatus());
Assert.assertEquals("3", response.getEntity(String.class));
response.releaseConnection();
response = session.request().delete();
response.releaseConnection();
Assert.assertEquals(204, response.getStatus());
}
@Test
public void testRestartFromAckSession() throws Exception {
ClientRequest request = new ClientRequest(generateURL("/queues/testQueue"));
ClientResponse<?> response = request.head();
response.releaseConnection();
Assert.assertEquals(200, response.getStatus());
Link sender = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "create");
log.debug("create: " + sender);
Link consumers = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "pull-consumers");
log.debug("pull: " + consumers);
response = Util.setAutoAck(consumers, false);
Link session = response.getLocationLink();
response = session.request().head();
response.releaseConnection();
Link consumeNext = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "acknowledge-next");
log.debug("consume-next: " + consumeNext);
Link ack = null;
response = sender.request().body("text/plain", Integer.toString(1)).post();
response.releaseConnection();
Assert.assertEquals(201, response.getStatus());
// consume
response = consumeNext.request().header(Constants.WAIT_HEADER, "3").post(String.class);
Assert.assertEquals(200, response.getStatus());
Assert.assertEquals("1", response.getEntity(String.class));
response.releaseConnection();
response = session.request().get();
response.releaseConnection();
consumeNext = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "acknowledge-next");
Assert.assertNull(consumeNext);
ack = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "acknowledgement");
Assert.assertNotNull(ack);
// acknowledge
response = ack.request().formParameter("acknowledge", "true").post();
response.releaseConnection();
response = session.request().head();
response.releaseConnection();
consumeNext = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "acknowledge-next");
Assert.assertNotNull(consumeNext);
ack = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "acknowledgement");
Assert.assertNull(ack);
response = sender.request().body("text/plain", Integer.toString(2)).post();
response.releaseConnection();
Assert.assertEquals(201, response.getStatus());
// consume
response = consumeNext.request().header(Constants.WAIT_HEADER, "1").post(String.class);
Assert.assertEquals(200, response.getStatus());
Assert.assertEquals("2", response.getEntity(String.class));
response.releaseConnection();
response = session.request().get();
response.releaseConnection();
consumeNext = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "acknowledge-next");
Assert.assertNull(consumeNext);
ack = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "acknowledgement");
Assert.assertNotNull(ack);
// acknowledge
response = ack.request().formParameter("acknowledge", "true").post();
response.releaseConnection();
response = session.request().head();
response.releaseConnection();
consumeNext = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "acknowledge-next");
Assert.assertNotNull(consumeNext);
ack = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "acknowledgement");
Assert.assertNull(ack);
response = session.request().delete();
response.releaseConnection();
Assert.assertEquals(204, response.getStatus());
}
@Test
public void testTopicRestartFromAckSession() throws Exception {
ClientRequest request = new ClientRequest(generateURL("/topics/testTopic"));
ClientResponse<?> response = request.head();
response.releaseConnection();
Assert.assertEquals(200, response.getStatus());
Link sender = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "create");
log.debug("create: " + sender);
Link consumers = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "pull-subscriptions");
log.debug("pull: " + consumers);
response = Util.setAutoAck(consumers, false);
Link session = response.getLocationLink();
response = session.request().head();
response.releaseConnection();
Link consumeNext = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "acknowledge-next");
log.debug("consume-next: " + consumeNext);
Link ack = null;
response = sender.request().body("text/plain", Integer.toString(1)).post();
response.releaseConnection();
Assert.assertEquals(201, response.getStatus());
// consume
response = consumeNext.request().header(Constants.WAIT_HEADER, "1").post(String.class);
Assert.assertEquals(200, response.getStatus());
Assert.assertEquals("1", response.getEntity(String.class));
response.releaseConnection();
response = session.request().get();
response.releaseConnection();
consumeNext = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "acknowledge-next");
Assert.assertNull(consumeNext);
ack = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "acknowledgement");
Assert.assertNotNull(ack);
// acknowledge
response = ack.request().formParameter("acknowledge", "true").post();
response.releaseConnection();
response = session.request().head();
response.releaseConnection();
consumeNext = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "acknowledge-next");
Assert.assertNotNull(consumeNext);
ack = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "acknowledgement");
Assert.assertNull(ack);
response = sender.request().body("text/plain", Integer.toString(2)).post();
response.releaseConnection();
Assert.assertEquals(201, response.getStatus());
// consume
response = consumeNext.request().header(Constants.WAIT_HEADER, "1").post(String.class);
Assert.assertEquals(200, response.getStatus());
Assert.assertEquals("2", response.getEntity(String.class));
response.releaseConnection();
response = session.request().get();
response.releaseConnection();
consumeNext = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "acknowledge-next");
Assert.assertNull(consumeNext);
ack = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "acknowledgement");
Assert.assertNotNull(ack);
// acknowledge
response = ack.request().formParameter("acknowledge", "true").post();
response.releaseConnection();
response = session.request().head();
response.releaseConnection();
consumeNext = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "acknowledge-next");
Assert.assertNotNull(consumeNext);
ack = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "acknowledgement");
Assert.assertNull(ack);
response = session.request().delete();
response.releaseConnection();
Assert.assertEquals(204, response.getStatus());
}
}

View File

@ -1,247 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.activemq.artemis.rest.test;
import javax.xml.bind.annotation.XmlRootElement;
import java.io.Serializable;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import org.apache.activemq.artemis.api.core.Message;
import org.apache.activemq.artemis.api.core.client.ClientMessage;
import org.apache.activemq.artemis.api.core.client.ClientProducer;
import org.apache.activemq.artemis.api.core.client.ClientSession;
import org.apache.activemq.artemis.api.core.client.MessageHandler;
import org.apache.activemq.artemis.rest.ActiveMQ;
import org.apache.activemq.artemis.rest.queue.QueueDeployment;
import org.jboss.logging.Logger;
import org.jboss.resteasy.client.ClientRequest;
import org.jboss.resteasy.client.ClientResponse;
import org.jboss.resteasy.spi.Link;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
import static org.jboss.resteasy.test.TestPortProvider.generateURL;
public class TransformTest extends MessageTestBase {
private static final Logger log = Logger.getLogger(TransformTest.class);
@BeforeClass
public static void setup() throws Exception {
QueueDeployment deployment = new QueueDeployment();
deployment.setDuplicatesAllowed(true);
deployment.setDurableSend(false);
deployment.setName("testQueue");
manager.getQueueManager().deploy(deployment);
}
@XmlRootElement
public static class Order implements Serializable {
private static final long serialVersionUID = 2510412973800601968L;
private String name;
private String amount;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAmount() {
return amount;
}
public void setAmount(String amount) {
this.amount = amount;
}
@Override
public boolean equals(Object o) {
if (this == o)
return true;
if (o == null || getClass() != o.getClass())
return false;
Order order = (Order) o;
if (!amount.equals(order.amount))
return false;
if (!name.equals(order.name))
return false;
return true;
}
@Override
public int hashCode() {
int result = name.hashCode();
result = 31 * result + amount.hashCode();
return result;
}
}
public static void publish(String destination, Serializable object, String contentType) throws Exception {
ClientSession session = manager.getQueueManager().getSessionFactory().createSession();
try {
ClientProducer producer = session.createProducer(destination);
ClientMessage message = session.createMessage(Message.OBJECT_TYPE, false);
if (contentType == null) {
ActiveMQ.setEntity(message, object);
} else
ActiveMQ.setEntity(message, object, contentType);
producer.send(message);
session.start();
} finally {
session.close();
}
}
@Test
public void testTransform() throws Exception {
ClientRequest request = new ClientRequest(generateURL("/queues/testQueue"));
ClientResponse<?> response = request.head();
response.releaseConnection();
Assert.assertEquals(200, response.getStatus());
Link sender = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "create");
log.debug("create: " + sender);
Link consumers = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "pull-consumers");
log.debug("pull: " + consumers);
response = Util.setAutoAck(consumers, true);
Link consumeNext = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "consume-next");
log.debug("consume-next: " + consumeNext);
// test that Accept header is used to set content-type
{
Order order = new Order();
order.setName("1");
order.setAmount("$5.00");
publish("testQueue", order, null);
response = consumeNext.request().accept("application/xml").post(String.class);
Assert.assertEquals(200, response.getStatus());
Assert.assertTrue(response.getHeaders().getFirst("Content-Type").toString().toLowerCase().contains("application/xml"));
Order order2 = response.getEntity(Order.class);
response.releaseConnection();
Assert.assertEquals(order, order2);
consumeNext = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "consume-next");
Assert.assertNotNull(consumeNext);
}
// test that Accept header is used to set content-type
{
Order order = new Order();
order.setName("1");
order.setAmount("$5.00");
publish("testQueue", order, null);
response = consumeNext.request().accept("application/json").post(String.class);
Assert.assertEquals(200, response.getStatus());
Assert.assertEquals("application/json", response.getHeaders().getFirst("Content-Type").toString().toLowerCase());
Order order2 = response.getEntity(Order.class);
response.releaseConnection();
Assert.assertEquals(order, order2);
consumeNext = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "consume-next");
Assert.assertNotNull(consumeNext);
}
// test that message property is used to set content type
{
Order order = new Order();
order.setName("2");
order.setAmount("$15.00");
publish("testQueue", order, "application/xml");
response = consumeNext.request().post(String.class);
Assert.assertEquals(200, response.getStatus());
Assert.assertTrue(response.getHeaders().getFirst("Content-Type").toString().toLowerCase().contains("application/xml"));
Order order2 = response.getEntity(Order.class);
response.releaseConnection();
Assert.assertEquals(order, order2);
consumeNext = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "consume-next");
Assert.assertNotNull(consumeNext);
}
}
public static class Listener implements MessageHandler {
public static Order order;
public static CountDownLatch latch = new CountDownLatch(1);
@Override
public void onMessage(ClientMessage clientMessage) {
log.debug("onMessage!");
try {
order = ActiveMQ.getEntity(clientMessage, Order.class);
} catch (Exception e) {
e.printStackTrace();
}
latch.countDown();
}
}
@Test
public void testJmsConsumer() throws Exception {
QueueDeployment deployment = new QueueDeployment();
deployment.setDuplicatesAllowed(true);
deployment.setDurableSend(false);
final String queueName = "testJmsConsumer";
deployment.setName(queueName);
manager.getQueueManager().deploy(deployment);
ClientSession session = manager.getQueueManager().getSessionFactory().createSession();
try {
session.createConsumer(queueName).setMessageHandler(new Listener());
session.start();
ClientRequest request = new ClientRequest(generateURL(Util.getUrlPath(queueName)));
ClientResponse<?> response = request.head();
response.releaseConnection();
Assert.assertEquals(200, response.getStatus());
Link sender = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "create");
log.debug("create: " + sender);
Link consumers = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "pull-consumers");
log.debug("pull: " + consumers);
response = Util.setAutoAck(consumers, true);
Link consumeNext = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "consume-next");
log.debug("consume-next: " + consumeNext);
// test that Accept header is used to set content-type
{
Order order = new Order();
order.setName("1");
order.setAmount("$5.00");
response = sender.request().body("application/xml", order).post();
response.releaseConnection();
Assert.assertEquals(201, response.getStatus());
Listener.latch.await(2, TimeUnit.SECONDS);
Assert.assertNotNull(Listener.order);
Assert.assertEquals(order, Listener.order);
}
} finally {
session.close();
}
}
}

View File

@ -1,49 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.activemq.artemis.rest.test;
import org.apache.activemq.artemis.rest.util.Constants;
import org.jboss.resteasy.client.ClientRequest;
import org.jboss.resteasy.client.ClientResponse;
import org.jboss.resteasy.spi.Link;
import org.junit.Assert;
public final class Util {
private Util() {
// Utility class
}
static ClientResponse head(ClientRequest request) throws Exception {
ClientResponse<?> response = request.head();
response.releaseConnection();
Assert.assertEquals(200, response.getStatus());
return response;
}
static String getUrlPath(String queueName) {
return Constants.PATH_FOR_QUEUES + "/" + queueName;
}
public static ClientResponse setAutoAck(Link link, boolean ack) throws Exception {
ClientResponse response;
response = link.request().formParameter("autoAck", Boolean.toString(ack)).post();
response.releaseConnection();
Assert.assertEquals(201, response.getStatus());
return response;
}
}

View File

@ -1,47 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.activemq.artemis.rest.test;
import javax.xml.bind.JAXBContext;
import java.io.StringReader;
import org.apache.activemq.artemis.rest.queue.push.xml.PushRegistration;
import org.jboss.logging.Logger;
import org.junit.Test;
public class XmlTest {
private static final Logger log = Logger.getLogger(XmlTest.class);
@Test
public void testPush() throws Exception {
String xml = "<push-registration id=\"111\">\n" +
" <destination>bar</destination>\n" +
" <durable>true</durable>\n" +
" <session-count>10</session-count>\n" +
" <link rel=\"template\" href=\"http://somewhere.com/resources/{id}/messages\" method=\"PUT\"/>\n" +
" <authentication>\n" +
" <basic-auth><username>guest</username><password>geheim</password></basic-auth>" +
" </authentication>\n" +
" <header name=\"foo\">bar</header>" +
"</push-registration>";
JAXBContext ctx = JAXBContext.newInstance(PushRegistration.class);
PushRegistration reg = (PushRegistration) ctx.createUnmarshaller().unmarshal(new StringReader(xml));
log.debug(reg);
}
}

View File

@ -1,691 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.activemq.artemis.rest.topic;
import org.apache.activemq.artemis.rest.test.MessageTestBase;
import org.apache.activemq.artemis.rest.test.Util;
import org.apache.activemq.artemis.rest.util.Constants;
import org.jboss.logging.Logger;
import org.jboss.resteasy.client.ClientRequest;
import org.jboss.resteasy.client.ClientResponse;
import org.jboss.resteasy.spi.Link;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
import static org.jboss.resteasy.test.TestPortProvider.generateURL;
/**
* repost on same consume-next
* repost on old consume-next
* repost on same consume-next with timeouts
* repost on same ack-next
* repost successful ack
* repost successful unack
* repost ack after unack
* repost unack after ack
* post on old ack-next
* post on old ack-next after an ack
* ack with an old ack link
*/
public class RepostingTopicTest extends MessageTestBase {
private static final Logger log = Logger.getLogger(RepostingTopicTest.class);
@BeforeClass
public static void setup() throws Exception {
TopicDeployment deployment1 = new TopicDeployment("testTopic", true);
manager.getTopicManager().deploy(deployment1);
}
@Test
public void testReconnectOnNamedSubscriber() throws Exception {
ClientRequest request = new ClientRequest(generateURL("/topics/testTopic"));
ClientResponse<?> response = request.head();
response.releaseConnection();
Assert.assertEquals(200, response.getStatus());
Link sender = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "create");
log.debug("create: " + sender);
Link consumers = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "pull-subscriptions");
log.debug("pull: " + consumers);
response = consumers.request().formParameter("name", "bill").post();
response.releaseConnection();
response = sender.request().body("text/plain", Integer.toString(1)).post();
response.releaseConnection();
Assert.assertEquals(201, response.getStatus());
response = sender.request().body("text/plain", Integer.toString(2)).post();
response.releaseConnection();
Assert.assertEquals(201, response.getStatus());
// recreate subscription a second time as named. Should pick up old one.
response = consumers.request().formParameter("name", "bill").post();
response.releaseConnection();
Link consumeNext = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "consume-next");
log.debug("resource consume-next: " + consumeNext);
response = consumeNext.request().post(String.class);
Assert.assertEquals(200, response.getStatus());
Assert.assertEquals("1", response.getEntity(String.class));
response.releaseConnection();
consumeNext = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "consume-next");
response = consumeNext.request().header("Accept-Wait", "2").post(String.class);
Assert.assertEquals(200, response.getStatus());
Assert.assertEquals("2", response.getEntity(String.class));
response.releaseConnection();
Link session = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "consumer");
response = session.request().delete();
response.releaseConnection();
Assert.assertEquals(204, response.getStatus());
}
@Test
public void testRestartOnDurableNamedSubscriber() throws Exception {
ClientRequest request = new ClientRequest(generateURL("/topics/testTopic"));
ClientResponse<?> response = request.head();
response.releaseConnection();
Assert.assertEquals(200, response.getStatus());
Link sender = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "create");
log.debug("create: " + sender);
Link consumers = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "pull-subscriptions");
log.debug("pull: " + consumers);
response = consumers.request().formParameter("name", "bill").formParameter("durable", "true").post();
response.releaseConnection();
response = sender.request().body("text/plain", Integer.toString(1)).post();
response.releaseConnection();
Assert.assertEquals(201, response.getStatus());
response = sender.request().body("text/plain", Integer.toString(2)).post();
response.releaseConnection();
Assert.assertEquals(201, response.getStatus());
manager.getTopicManager().getDestination().findTopic("testTopic").getSubscriptions().stop();
// recreate subscription a second time as named. Should pick up old one.
response = consumers.request().formParameter("name", "bill").formParameter("durable", "true").post();
response.releaseConnection();
Link consumeNext = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "consume-next");
log.debug("resource consume-next: " + consumeNext);
response = consumeNext.request().header("Accept-Wait", "2").post(String.class);
Assert.assertEquals(200, response.getStatus());
Assert.assertEquals("1", response.getEntity(String.class));
response.releaseConnection();
consumeNext = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "consume-next");
response = consumeNext.request().header("Accept-Wait", "2").post(String.class);
Assert.assertEquals(200, response.getStatus());
Assert.assertEquals("2", response.getEntity(String.class));
response.releaseConnection();
Link session = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "consumer");
response = session.request().delete();
response.releaseConnection();
Assert.assertEquals(204, response.getStatus());
}
@Test
public void testRestartOnNonDurableNamedSubscriber() throws Exception {
ClientRequest request = new ClientRequest(generateURL("/topics/testTopic"));
ClientResponse<?> response = request.head();
response.releaseConnection();
Assert.assertEquals(200, response.getStatus());
Link sender = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "create");
log.debug("create: " + sender);
Link consumers = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "pull-subscriptions");
log.debug("pull: " + consumers);
response = consumers.request().formParameter("name", "bill").post();
response.releaseConnection();
response = sender.request().body("text/plain", Integer.toString(1)).post();
response.releaseConnection();
Assert.assertEquals(201, response.getStatus());
response = sender.request().body("text/plain", Integer.toString(2)).post();
response.releaseConnection();
Assert.assertEquals(201, response.getStatus());
manager.getTopicManager().getDestination().findTopic("testTopic").getSubscriptions().stop();
// recreate subscription a second time as named. Should pick up old one.
response = consumers.request().formParameter("name", "bill").post();
response.releaseConnection();
Link consumeNext = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "consume-next");
log.debug("resource consume-next: " + consumeNext);
response = consumeNext.request().header("Accept-Wait", "2").post(String.class);
response.releaseConnection();
Assert.assertEquals(503, response.getStatus());
Link session = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "consumer");
response = session.request().delete();
response.releaseConnection();
Assert.assertEquals(204, response.getStatus());
}
@Test
public void testPostOnSameConsumeNext() throws Exception {
ClientRequest request = new ClientRequest(generateURL("/topics/testTopic"));
ClientResponse<?> response = request.head();
response.releaseConnection();
Assert.assertEquals(200, response.getStatus());
Link sender = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "create");
log.debug("create: " + sender);
Link consumers = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "pull-subscriptions");
log.debug("pull: " + consumers);
response = Util.setAutoAck(consumers, true);
Link consumeNext = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "consume-next");
log.debug("resource consume-next: " + consumeNext);
response = sender.request().body("text/plain", Integer.toString(1)).post();
response.releaseConnection();
Assert.assertEquals(201, response.getStatus());
response = consumeNext.request().post(String.class);
Assert.assertEquals(200, response.getStatus());
Assert.assertEquals("1", response.getEntity(String.class));
response.releaseConnection();
Link session = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "consumer");
log.debug("session: " + session);
consumeNext = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "consume-next");
log.debug("session 1st consumeNext: " + consumeNext);
response = sender.request().body("text/plain", Integer.toString(2)).post();
response.releaseConnection();
Assert.assertEquals(201, response.getStatus());
response = consumeNext.request().header(Constants.WAIT_HEADER, "10").post(String.class);
Assert.assertEquals(200, response.getStatus());
Assert.assertEquals("2", response.getEntity(String.class));
response.releaseConnection();
response = consumeNext.request().header(Constants.WAIT_HEADER, "10").post(String.class);
Assert.assertEquals(200, response.getStatus());
Assert.assertEquals("2", response.getEntity(String.class));
response.releaseConnection();
response = consumeNext.request().header(Constants.WAIT_HEADER, "10").post(String.class);
Assert.assertEquals(200, response.getStatus());
Assert.assertEquals("2", response.getEntity(String.class));
response.releaseConnection();
response = consumeNext.request().header(Constants.WAIT_HEADER, "10").post(String.class);
Assert.assertEquals(200, response.getStatus());
Assert.assertEquals("2", response.getEntity(String.class));
response.releaseConnection();
session = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "consumer");
log.debug("session: " + session);
consumeNext = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "consume-next");
log.debug("session 2nd consumeNext: " + consumeNext);
response = sender.request().body("text/plain", Integer.toString(3)).post();
response.releaseConnection();
Assert.assertEquals(201, response.getStatus());
response = consumeNext.request().header(Constants.WAIT_HEADER, "10").post(String.class);
Assert.assertEquals(200, response.getStatus());
Assert.assertEquals("3", response.getEntity(String.class));
response.releaseConnection();
response = session.request().delete();
response.releaseConnection();
Assert.assertEquals(204, response.getStatus());
}
@Test
public void testPostOnOldConsumeNext() throws Exception {
ClientRequest request = new ClientRequest(generateURL("/topics/testTopic"));
ClientResponse<?> response = request.head();
response.releaseConnection();
Assert.assertEquals(200, response.getStatus());
Link sender = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "create");
log.debug("create: " + sender);
Link consumers = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "pull-subscriptions");
log.debug("pull: " + consumers);
response = Util.setAutoAck(consumers, true);
Link consumeNext = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "consume-next");
log.debug("resource consume-next: " + consumeNext);
response = sender.request().body("text/plain", Integer.toString(1)).post();
response.releaseConnection();
Assert.assertEquals(201, response.getStatus());
response = consumeNext.request().post(String.class);
Assert.assertEquals(200, response.getStatus());
Assert.assertEquals("1", response.getEntity(String.class));
response.releaseConnection();
Link session = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "consumer");
log.debug("session: " + session);
consumeNext = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "consume-next");
Link firstConsumeNext = consumeNext;
log.debug("session 1st consumeNext: " + consumeNext);
response = sender.request().body("text/plain", Integer.toString(2)).post();
response.releaseConnection();
Assert.assertEquals(201, response.getStatus());
response = consumeNext.request().header(Constants.WAIT_HEADER, "10").post(String.class);
Assert.assertEquals(200, response.getStatus());
Assert.assertEquals("2", response.getEntity(String.class));
response.releaseConnection();
session = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "consumer");
log.debug("session: " + session);
consumeNext = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "consume-next");
log.debug("session 2nd consumeNext: " + consumeNext);
response = sender.request().body("text/plain", Integer.toString(3)).post();
response.releaseConnection();
Assert.assertEquals(201, response.getStatus());
response = consumeNext.request().header(Constants.WAIT_HEADER, "10").post(String.class);
Assert.assertEquals(200, response.getStatus());
Assert.assertEquals("3", response.getEntity(String.class));
response.releaseConnection();
response = firstConsumeNext.request().header(Constants.WAIT_HEADER, "10").post(String.class);
Assert.assertEquals(412, response.getStatus());
log.debug(response.getEntity(String.class));
response.releaseConnection();
response = session.request().delete();
response.releaseConnection();
Assert.assertEquals(204, response.getStatus());
}
@Test
public void testPostOnSameConsumeNextWithTimeout() throws Exception {
ClientRequest request = new ClientRequest(generateURL("/topics/testTopic"));
ClientResponse<?> response = request.head();
response.releaseConnection();
Assert.assertEquals(200, response.getStatus());
Link sender = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "create");
log.debug("create: " + sender);
Link consumers = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "pull-subscriptions");
log.debug("pull: " + consumers);
response = Util.setAutoAck(consumers, true);
Link consumeNext = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "consume-next");
log.debug("resource consume-next: " + consumeNext);
response = sender.request().body("text/plain", Integer.toString(1)).post();
response.releaseConnection();
Assert.assertEquals(201, response.getStatus());
response = consumeNext.request().post(String.class);
Assert.assertEquals(200, response.getStatus());
Assert.assertEquals("1", response.getEntity(String.class));
response.releaseConnection();
Link session = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "consumer");
log.debug("session: " + session);
consumeNext = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "consume-next");
log.debug("session 1st consumeNext: " + consumeNext);
// test timeout here
response = consumeNext.request().post(String.class);
response.releaseConnection();
Assert.assertEquals(503, response.getStatus());
session = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "consumer");
log.debug("session: " + session);
consumeNext = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "consume-next");
log.debug("session 2nd consumeNext: " + consumeNext);
response = sender.request().body("text/plain", Integer.toString(3)).post();
response.releaseConnection();
Assert.assertEquals(201, response.getStatus());
response = consumeNext.request().header(Constants.WAIT_HEADER, "10").post(String.class);
Assert.assertEquals(200, response.getStatus());
Assert.assertEquals("3", response.getEntity(String.class));
response.releaseConnection();
response = session.request().delete();
response.releaseConnection();
Assert.assertEquals(204, response.getStatus());
}
@Test
public void testPostOnSameAcknowledgeNextAndAck() throws Exception {
ClientRequest request = new ClientRequest(generateURL("/topics/testTopic"));
ClientResponse<?> response = request.head();
response.releaseConnection();
Assert.assertEquals(200, response.getStatus());
Link sender = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "create");
log.debug("create: " + sender);
Link consumers = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "pull-subscriptions");
log.debug("pull: " + consumers);
response = Util.setAutoAck(consumers, false);
Link consumeNext = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "acknowledge-next");
log.debug("resource acknowledge-next: " + consumeNext);
response = sender.request().body("text/plain", Integer.toString(1)).post();
response.releaseConnection();
Assert.assertEquals(201, response.getStatus());
response = consumeNext.request().post(String.class);
Assert.assertEquals(200, response.getStatus());
Assert.assertEquals("1", response.getEntity(String.class));
response.releaseConnection();
Link session = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "consumer");
log.debug("session: " + session);
Link ack = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "acknowledgement");
log.debug("ack: " + ack);
response = ack.request().formParameter("acknowledge", "true").post();
response.releaseConnection();
Assert.assertEquals(204, response.getStatus());
response = ack.request().formParameter("acknowledge", "true").post();
response.releaseConnection();
Assert.assertEquals(204, response.getStatus());
response = ack.request().formParameter("acknowledge", "true").post();
response.releaseConnection();
Assert.assertEquals(204, response.getStatus());
consumeNext = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "acknowledge-next");
log.debug("session 1st acknowledge-next: " + consumeNext);
response = sender.request().body("text/plain", Integer.toString(2)).post();
response.releaseConnection();
Assert.assertEquals(201, response.getStatus());
response = consumeNext.request().header(Constants.WAIT_HEADER, "10").post(String.class);
Assert.assertEquals(200, response.getStatus());
Assert.assertEquals("2", response.getEntity(String.class));
response.releaseConnection();
response = consumeNext.request().header(Constants.WAIT_HEADER, "10").post(String.class);
Assert.assertEquals(200, response.getStatus());
Assert.assertEquals("2", response.getEntity(String.class));
response.releaseConnection();
response = consumeNext.request().header(Constants.WAIT_HEADER, "10").post(String.class);
Assert.assertEquals(200, response.getStatus());
Assert.assertEquals("2", response.getEntity(String.class));
response.releaseConnection();
response = consumeNext.request().header(Constants.WAIT_HEADER, "10").post(String.class);
Assert.assertEquals(200, response.getStatus());
Assert.assertEquals("2", response.getEntity(String.class));
response.releaseConnection();
ack = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "acknowledgement");
log.debug("ack: " + ack);
response = ack.request().formParameter("acknowledge", "true").post();
response.releaseConnection();
Assert.assertEquals(204, response.getStatus());
response = session.request().delete();
response.releaseConnection();
Assert.assertEquals(204, response.getStatus());
}
@Test
public void testRepostSuccessfulUnacknowledge() throws Exception {
ClientRequest request = new ClientRequest(generateURL("/topics/testTopic"));
ClientResponse<?> response = request.head();
response.releaseConnection();
Assert.assertEquals(200, response.getStatus());
Link sender = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "create");
log.debug("create: " + sender);
Link consumers = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "pull-subscriptions");
log.debug("pull: " + consumers);
response = Util.setAutoAck(consumers, false);
Link consumeNext = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "acknowledge-next");
log.debug("resource acknowledge-next: " + consumeNext);
response = sender.request().body("text/plain", Integer.toString(1)).post();
response.releaseConnection();
Assert.assertEquals(201, response.getStatus());
response = consumeNext.request().post(String.class);
Assert.assertEquals(200, response.getStatus());
Assert.assertEquals("1", response.getEntity(String.class));
response.releaseConnection();
Link session = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "consumer");
log.debug("session: " + session);
Link ack = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "acknowledgement");
log.debug("ack: " + ack);
response = ack.request().formParameter("acknowledge", "false").post();
response.releaseConnection();
Assert.assertEquals(204, response.getStatus());
response = ack.request().formParameter("acknowledge", "false").post();
response.releaseConnection();
Assert.assertEquals(204, response.getStatus());
response = ack.request().formParameter("acknowledge", "false").post();
response.releaseConnection();
Assert.assertEquals(204, response.getStatus());
consumeNext = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "acknowledge-next");
log.debug("session 1st acknowledge-next: " + consumeNext);
response = consumeNext.request().header(Constants.WAIT_HEADER, "10").post(String.class);
Assert.assertEquals(200, response.getStatus());
Assert.assertEquals("1", response.getEntity(String.class));
response.releaseConnection();
response = consumeNext.request().header(Constants.WAIT_HEADER, "10").post(String.class);
Assert.assertEquals(200, response.getStatus());
Assert.assertEquals("1", response.getEntity(String.class));
response.releaseConnection();
response = consumeNext.request().header(Constants.WAIT_HEADER, "10").post(String.class);
Assert.assertEquals(200, response.getStatus());
Assert.assertEquals("1", response.getEntity(String.class));
response.releaseConnection();
response = consumeNext.request().header(Constants.WAIT_HEADER, "10").post(String.class);
Assert.assertEquals(200, response.getStatus());
Assert.assertEquals("1", response.getEntity(String.class));
response.releaseConnection();
ack = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "acknowledgement");
log.debug("ack: " + ack);
response = ack.request().formParameter("acknowledge", "true").post();
response.releaseConnection();
Assert.assertEquals(204, response.getStatus());
response = session.request().delete();
response.releaseConnection();
Assert.assertEquals(204, response.getStatus());
}
@Test
public void testRepostAckAfterUnacknowledge() throws Exception {
ClientRequest request = new ClientRequest(generateURL("/topics/testTopic"));
ClientResponse<?> response = request.head();
response.releaseConnection();
Assert.assertEquals(200, response.getStatus());
Link sender = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "create");
log.debug("create: " + sender);
Link consumers = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "pull-subscriptions");
log.debug("pull: " + consumers);
response = Util.setAutoAck(consumers, false);
Link consumeNext = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "acknowledge-next");
log.debug("resource acknowledge-next: " + consumeNext);
response = sender.request().body("text/plain", Integer.toString(1)).post();
response.releaseConnection();
Assert.assertEquals(201, response.getStatus());
response = consumeNext.request().post(String.class);
Assert.assertEquals(200, response.getStatus());
Assert.assertEquals("1", response.getEntity(String.class));
response.releaseConnection();
Link session = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "consumer");
log.debug("session: " + session);
Link ack = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "acknowledgement");
log.debug("ack: " + ack);
response = ack.request().formParameter("acknowledge", "false").post();
response.releaseConnection();
Assert.assertEquals(204, response.getStatus());
response = ack.request().formParameter("acknowledge", "true").post();
Assert.assertEquals(412, response.getStatus());
log.debug(response.getEntity(String.class));
response.releaseConnection();
consumeNext = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "acknowledge-next");
log.debug("session 1st acknowledge-next: " + consumeNext);
response = consumeNext.request().header(Constants.WAIT_HEADER, "10").post(String.class);
Assert.assertEquals(200, response.getStatus());
Assert.assertEquals("1", response.getEntity(String.class));
response.releaseConnection();
response = consumeNext.request().header(Constants.WAIT_HEADER, "10").post(String.class);
Assert.assertEquals(200, response.getStatus());
Assert.assertEquals("1", response.getEntity(String.class));
response.releaseConnection();
response = consumeNext.request().header(Constants.WAIT_HEADER, "10").post(String.class);
Assert.assertEquals(200, response.getStatus());
Assert.assertEquals("1", response.getEntity(String.class));
response.releaseConnection();
response = consumeNext.request().header(Constants.WAIT_HEADER, "10").post(String.class);
Assert.assertEquals(200, response.getStatus());
Assert.assertEquals("1", response.getEntity(String.class));
response.releaseConnection();
ack = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "acknowledgement");
log.debug("ack: " + ack);
response = ack.request().formParameter("acknowledge", "true").post();
response.releaseConnection();
Assert.assertEquals(204, response.getStatus());
response = session.request().delete();
response.releaseConnection();
Assert.assertEquals(204, response.getStatus());
}
@Test
public void testRepostUnAckAfterAcknowledge() throws Exception {
ClientRequest request = new ClientRequest(generateURL("/topics/testTopic"));
ClientResponse<?> response = request.head();
response.releaseConnection();
Assert.assertEquals(200, response.getStatus());
Link sender = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "create");
log.debug("create: " + sender);
Link consumers = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "pull-subscriptions");
log.debug("pull: " + consumers);
response = Util.setAutoAck(consumers, false);
Link consumeNext = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "acknowledge-next");
log.debug("resource acknowledge-next: " + consumeNext);
response = sender.request().body("text/plain", Integer.toString(1)).post();
response.releaseConnection();
Assert.assertEquals(201, response.getStatus());
response = consumeNext.request().post(String.class);
Assert.assertEquals(200, response.getStatus());
Assert.assertEquals("1", response.getEntity(String.class));
response.releaseConnection();
Link session = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "consumer");
log.debug("session: " + session);
Link ack = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "acknowledgement");
log.debug("ack: " + ack);
response = ack.request().formParameter("acknowledge", "true").post();
response.releaseConnection();
Assert.assertEquals(204, response.getStatus());
response = ack.request().formParameter("acknowledge", "false").post();
Assert.assertEquals(412, response.getStatus());
log.debug(response.getEntity(String.class));
response.releaseConnection();
consumeNext = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "acknowledge-next");
log.debug("session 1st acknowledge-next: " + consumeNext);
response = sender.request().body("text/plain", Integer.toString(2)).post();
response.releaseConnection();
Assert.assertEquals(201, response.getStatus());
response = consumeNext.request().header(Constants.WAIT_HEADER, "10").post(String.class);
Assert.assertEquals(200, response.getStatus());
Assert.assertEquals("2", response.getEntity(String.class));
response.releaseConnection();
response = consumeNext.request().header(Constants.WAIT_HEADER, "10").post(String.class);
Assert.assertEquals(200, response.getStatus());
Assert.assertEquals("2", response.getEntity(String.class));
response.releaseConnection();
response = consumeNext.request().header(Constants.WAIT_HEADER, "10").post(String.class);
Assert.assertEquals(200, response.getStatus());
Assert.assertEquals("2", response.getEntity(String.class));
response.releaseConnection();
response = consumeNext.request().header(Constants.WAIT_HEADER, "10").post(String.class);
Assert.assertEquals(200, response.getStatus());
Assert.assertEquals("2", response.getEntity(String.class));
response.releaseConnection();
ack = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "acknowledgement");
log.debug("ack: " + ack);
response = ack.request().formParameter("acknowledge", "true").post();
response.releaseConnection();
Assert.assertEquals(204, response.getStatus());
response = session.request().delete();
response.releaseConnection();
Assert.assertEquals(204, response.getStatus());
}
@Test
public void testPostOnOldAcknowledgeNextAndAck() throws Exception {
ClientRequest request = new ClientRequest(generateURL("/topics/testTopic"));
ClientResponse<?> response = request.head();
response.releaseConnection();
Assert.assertEquals(200, response.getStatus());
Link sender = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "create");
log.debug("create: " + sender);
Link consumers = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "pull-subscriptions");
log.debug("pull: " + consumers);
response = Util.setAutoAck(consumers, false);
Link consumeNext = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "acknowledge-next");
log.debug("resource acknowledge-next: " + consumeNext);
response = sender.request().body("text/plain", Integer.toString(1)).post();
response.releaseConnection();
Assert.assertEquals(201, response.getStatus());
response = consumeNext.request().header(Constants.WAIT_HEADER, "1").post(String.class);
Assert.assertEquals(200, response.getStatus());
Assert.assertEquals("1", response.getEntity(String.class));
response.releaseConnection();
Link session = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "consumer");
log.debug("session: " + session);
Link ack = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "acknowledgement");
Link oldAck = ack;
log.debug("ack: " + ack);
response = ack.request().formParameter("acknowledge", "true").post();
response.releaseConnection();
Assert.assertEquals(204, response.getStatus());
consumeNext = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "acknowledge-next");
log.debug("session 1st acknowledge-next: " + consumeNext);
Link firstConsumeNext = consumeNext;
response = sender.request().body("text/plain", Integer.toString(2)).post();
response.releaseConnection();
Assert.assertEquals(201, response.getStatus());
response = consumeNext.request().header(Constants.WAIT_HEADER, "10").post(String.class);
response.releaseConnection();
Assert.assertEquals(200, response.getStatus());
ack = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "acknowledgement");
log.debug("ack: " + ack);
response = oldAck.request().formParameter("acknowledge", "true").post();
Assert.assertEquals(412, response.getStatus());
log.debug(response.getEntity(String.class));
response.releaseConnection();
consumeNext = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "acknowledge-next");
response = ack.request().formParameter("acknowledge", "true").post();
response.releaseConnection();
Assert.assertEquals(204, response.getStatus());
consumeNext = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "acknowledge-next");
response = consumeNext.request().post(String.class);
response.releaseConnection();
Assert.assertEquals(503, response.getStatus());
response = session.request().delete();
response.releaseConnection();
Assert.assertEquals(204, response.getStatus());
}
}

View File

@ -1,19 +0,0 @@
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<rest-messaging>
<use-link-headers>true</use-link-headers>
</rest-messaging>

View File

@ -1,49 +0,0 @@
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<configuration xmlns="urn:activemq" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:activemq /schema/artemis-server.xsd">
<core xmlns="urn:activemq:core">
<persistence-enabled>false</persistence-enabled>
<acceptors>
<acceptor name="in-vm">vm://0</acceptor>
</acceptors>
<!-- Other config -->
<security-settings>
<!--security for example queue-->
<security-setting match="exampleQueue">
<permission type="createDurableQueue" roles="guest"/>
<permission type="deleteDurableQueue" roles="guest"/>
<permission type="createNonDurableQueue" roles="guest"/>
<permission type="deleteNonDurableQueue" roles="guest"/>
<permission type="consume" roles="guest"/>
<permission type="send" roles="guest"/>
</security-setting>
</security-settings>
<addresses>
<address name="exampleQueue">
<anycast>
<queue name="exampleQueue"/>
</anycast>
</address>
</addresses>
</core>
</configuration>

Some files were not shown because too many files have changed in this diff Show More