Git Product home page Git Product logo

spring-amqp's Introduction

Spring AMQP Join the chat at https://gitter.im/spring-projects/spring-amqp

This project provides support for using Spring and Java with AMQP 0.9.1, and in particular RabbitMQ.

Code of Conduct

Please see our Code of conduct.

Reporting Security Vulnerabilities

Please see our Security policy.

Checking out and Building

To check out the project from GitHub and build from source using Gradle, do the following:

git clone git://github.com/SpringSource/spring-amqp.git
cd spring-amqp
./gradlew build

If you encounter out of memory errors during the build, increase available heap and permgen for Gradle:

GRADLE_OPTS='-XX:MaxPermSize=1024m -Xmx1024m'

To build and install jars into your local Maven cache:

./gradlew install

To build api Javadoc (results will be in build/api):

./gradlew api

To build reference documentation (results will be in build/reference):

./gradlew reference

To build complete distribution including -dist, -docs, and -schema zip files (results will be in build/distributions)

./gradlew dist

To analyze and gather metrics using Sonar:

./gradlew clean build sonar

(Please make sure that you have Sonar running, e.g. on localhost port 9000)

Using Eclipse

To generate Eclipse metadata (.classpath and .project files), do the following:

./gradlew eclipse

Once complete, you may then import the projects into Eclipse as usual:

File -> Import -> Existing projects into workspace

Browse to the 'spring-amqp' root directory. All projects should import free of errors.

Using SpringSource Tool Suite™ (STS)

Using the STS Gradle Support, you can directly import Gradle projects, without having to generate Eclipse metadata first (since STS 2.7.M1). Please make sure you have the Gradle STS Extension installed - Please see the installation instructions for details.

  1. Select File -> Import -> Gradle Project
  2. Browse to the Spring AMQP Root Folder
  3. Click on Build Model
  4. Select the projects you want to import
  5. Press Finish

Using IntelliJ IDEA

To generate IDEA metadata (.iml and .ipr files), do the following:

./gradlew idea

Distribution Contents

If you downloaded the full Spring AMQP distribution or if you created the distribution using ./gradlew dist, you will see the following directory structure:

├── README.md
├── apache-license.txt
├── docs
│	├── api
│	└── reference
├── epl-license.txt
├── libs
├── notice.txt
└── schema
    └── rabbit

The binary JARs and the source code are available in the libs. The reference manual and javadocs are located in the docs directory.

Changelog

Lists of issues addressed per release can be found in JIRA.

Additional Resources

Contributing to Spring AMQP

Here are some ways for you to get involved in the community:

  • Get involved with the Spring community on the Spring Community Forums. Please help out on the forum by responding to questions and joining the debate.
  • Create JIRA tickets for bugs and new features and comment and vote on the ones that you are interested in.
  • Github is for social coding: if you want to write code, we encourage contributions through pull requests from forks of this repository. If you want to contribute code this way, please reference a JIRA ticket as well covering the specific issue you are addressing.
  • Watch for upcoming articles on Spring by subscribing to springframework.org

Before we accept a non-trivial patch or pull request we will need you to sign the contributor's agreement. Signing the contributor's agreement does not grant anyone commit rights to the main repository, but it does mean that we can accept your contributions, and you will get an author credit if we do. Active contributors might be asked to join the core team, and given the ability to merge pull requests.

Code Conventions and Housekeeping

None of these is essential for a pull request, but they will all help. They can also be added after the original pull request but before a merge.

  • Use the Spring Framework code format conventions (import eclipse-code-formatter.xml from the root of the project if you are using Eclipse).
  • Make sure all new .java files to have a simple Javadoc class comment with at least an @author tag identifying you, and preferably at least a paragraph on what the class is for.
  • Add the ASF license header comment to all new .java files (copy from existing files in the project)
  • Add yourself as an @author to the .java files that you modify substantially (more than cosmetic changes).
  • Add some Javadocs and, if you change the namespace, some XSD doc elements.
  • A few unit tests would help a lot as well - someone has to do it.
  • If no-one else is using your branch, please rebase it against the current main (or other target branch in the main project).

License

Spring AMQP is released under the terms of the Apache Software License Version 2.0 (see LICENSE.txt).

spring-amqp's People

Contributors

garyrussell avatar dsyer avatar artembilan avatar spring-builds avatar markfisher avatar ghillert avatar olegz avatar cbeams avatar panchenko avatar Buzzardo avatar nristock avatar acogoluegnes avatar wilkinsona avatar LeonardoFerreiraa avatar neetkee avatar jbrisbin avatar snicoll avatar cppwfs avatar jamescarr avatar spring-operator avatar dreis2211 avatar zysaaa avatar mhewedy avatar bjmi avatar mjaggard avatar ryl avatar rwanderc avatar yannbolliger avatar tbcs avatar 0xflotus avatar

Stargazers

Smriti Kumari avatar  avatar Doogie Min avatar  avatar hadron avatar ray.ao avatar JinChang avatar giquieu avatar zacks avatar  avatar  avatar  avatar Pappu Kumar avatar Martin Jinoch avatar  avatar Gabriele Santomaggio avatar Mujahed Alaqqad avatar Alex avatar majd avatar  avatar Victor Alves avatar Jay avatar Bram avatar XingRay avatar gavinpan avatar Timothy Spann avatar Leonardo Ferreira avatar Dennis Gao avatar August avatar 键盘上的猫 avatar  avatar Nicolás Pazos avatar Michael Strelchenko avatar Marcello Muscara avatar  avatar  avatar  avatar cnScarb avatar 정문경 avatar whnhn avatar SummerLeone avatar 原俊杰 avatar  avatar James Dube avatar  avatar  avatar Andrii Maliuta avatar 素喂 avatar 疯狂的茶几 avatar Jonas avatar 一如年少模样 avatar dengsd avatar  avatar Garry avatar Phuoc Le avatar Eddie Cho avatar  avatar  avatar  avatar Mo'ath Alshorman avatar raed avatar Liu Zhiling avatar xuandanh avatar QU, Tong avatar  avatar SUN avatar  avatar Yoana Chung avatar  avatar cqj avatar  avatar Gilbert.ho avatar Denis avatar Nikheel avatar  avatar  avatar GardenLee avatar Jeremy Gan avatar Guilherme Bisconcini avatar  avatar Brendon Miranda avatar J avatar gold_river avatar bank avatar Nico Coetzee avatar  avatar Slobodan Lazarevski avatar 叶盛青 avatar Felipe Marcondes Pena avatar 林秦浩 avatar  avatar loumzy avatar  avatar gaoxinfu avatar 飘扬的红领巾 avatar Majnun Abdurahmanov avatar  avatar  avatar Rostov avatar cuizhanming avatar

Watchers

Wayne Lund avatar davidwei_001 avatar Jeremiah Strauss avatar Matt Stockton avatar Alex Panchenko avatar william avatar Gary Russell avatar Arnaud Cogoluègnes avatar Leon avatar Frank avatar James Cloos avatar LeiWang avatar Artem Bilan avatar 王华 avatar  avatar lispmind avatar  avatar jingtu avatar Hefei Li avatar Raynor avatar Philip Lourandos avatar Yann ROBERT avatar  avatar 张伟 avatar Wander Costa avatar  avatar jianhui-xu avatar liuliu avatar  avatar Yuriy Eremin avatar javacodecreeks avatar Scorpioacc avatar Bugs avatar workwyz avatar  avatar Dengguang Pang avatar  avatar linshimiao avatar  avatar caocao485 avatar  avatar George avatar lusong avatar xianren avatar bruce avatar  avatar 张大川 avatar  avatar Nitin Reddy avatar Rostov avatar  avatar Majnun Abdurahmanov avatar  avatar  avatar  avatar  avatar  avatar

spring-amqp's Issues

No way to specify return type with rabbit template

In my tests I use RabitTemplate. Today I've met following issue:
My @RabbitListener annotated function return some pretty complex generic type: ResponseWrapper<SomeAnotherClassHere<OfFirst, AndSecond>>.
But when I try to invoke something like following:

  ResponseWrapper<SomeAnotherClassHere<OfFirst, AndSecond>> resp = (ResponseWrapper<SomeAnotherClassHere<OfFirst, AndSecond>>) rabbitTemplate.convertSendAndRecieve("queueName", requestDTO);

in debug I can see that real type of resp is smth like ResponseWrapper<LinkedHashMap<String,?>>.
And, of course, my tests doesn't work because of LinkedHashMap cannot be cast to SomeAnotherClassHere .

The only workaround I've found is to read response as object, then serialize it to String with jackson and then deserialize it back to desired class, which looks pretty good.

Is it possible to make versions of convertSendAndRecieve, which support TypeReference (i.e. as RestTemplate)?

Unacked messages when using SimpleMessageListenerContainer

Hello,

We are experiencing an issue with SimpleMessageListenerContainer. Sometimes we have messages that stay unacked until we restart our service or we kill the connection via RabbitMQ console.

It happens rarely. I got the thread dump and heap dump of a service when it contains unacked messages. From the thread dump I cannot see anything blocked:

AMQP Connection 127.0.0.1:5672" Id=274746 in RUNNABLE (running in native)
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.socketRead(SocketInputStream.java:116)
at java.net.SocketInputStream.read(SocketInputStream.java:170)
at java.net.SocketInputStream.read(SocketInputStream.java:141)
at java.io.BufferedInputStream.fill(BufferedInputStream.java:246)
at java.io.BufferedInputStream.read(BufferedInputStream.java:265)
  - locked [email protected]
at java.io.DataInputStream.readUnsignedByte(DataInputStream.java:288)
at com.rabbitmq.client.impl.Frame.readFrom(Frame.java:91)
at com.rabbitmq.client.impl.SocketFrameHandler.readFrame(SocketFrameHandler.java:164)
  - locked [email protected]
at com.rabbitmq.client.impl.AMQConnection$MainLoop.run(AMQConnection.java:571)
at java.lang.Thread.run(Thread.java:745)

and

pool-2-thread-28084" Id=274747 in TIMED_WAITING on lock=java.u[email protected]1c4066eb
at sun.misc.Unsafe.park(Native Method)
at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:215)
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:2078)
at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:1093)
at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:809)
at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1067)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1127)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)

And in the heap dump I can see that the BlockingQueueConsumer containing the queue (of type LinkedBlockingQueue) is not referenced by any SimpleMessageListenerContainer as it should be as all our RabbitMQ listeners are configured to use it.

From the SimpleMessageListenerContainer code I saw that it may remove idle consumers. My question is: do you have any idea why it could remove it and not cancel the messages it contains?

RabbitMQ 3.6.4, Erlang 19.1
Spring amqp:spring-rabbit:1.7.3.RELEASE
com.rabbit:amqp-client:4.0.2

here is how we create the factory:

 SimpleRabbitListenerContainerFactory factory = new   SimpleRabbitListenerContainerFactory();
        factory.setConnectionFactory(connectionFactory);
        factory.setConcurrentConsumers(min);
        factory.setMaxConcurrentConsumers(max);
        factory.setAcknowledgeMode(AUTO);
        factory.setDefaultRequeueRejected(false);
        factory.setMessageConverter(jacksonMessageConverter);
        // Add an incoming message logging interceptor
        factory.setAdviceChain(
                messageLoggingInterceptor,
                RetryInterceptorBuilder
                        .stateless()
                        .retryPolicy(new NeverRetryPolicy())
                        .recoverer(messageRecoverer)             // to republish failed messages in a dlq
                        .build(),
                rabbitConsumerExceptionLoggingInterceptor
        );
        return factory;

and the connection factory:

com.rabbitmq.client.ConnectionFactory clientFactory = new com.rabbitmq.client.ConnectionFactory();
            if (this.useSsl) {
                clientFactory.useSslProtocol();
            }
            connectionFactory = new CachingConnectionFactory(clientFactory);
            connectionFactory.setUsername(this.username);
            connectionFactory.setPassword(this.password);
            connectionFactory.setAddresses(this.url);
            connectionFactory.setCacheMode(CacheMode.CONNECTION);
            connectionFactory.setChannelCacheSize(this.maximumChannelsPerConnection);
            connectionFactory.setChannelCheckoutTimeout(this.channelCheckoutTimeout);
            connectionFactory.setConnectionCacheSize(this.maxConnections);

I can provide you with a sample if it looks too messy here but anyway it is difficult to reproduce. The only correlation we saw is that it happens sometimes on queues that idle since some time, that is, no messages during few hours

Thank you

ListenerExecutionFailedException.getFailedMessage() is always null

It is my understanding that ErrorHandler and FatalExceptionStrategy are supposed to have access to the Message via the ListenerExecutionFailedException.

However, nothing ever appears to fill it in.
I would expect MessagingMessageListenerAdapter.invokeHandler to be passing it in the exception constructors.

The spring boot context identify the AsyncRabbitTemplate bean as RabbitTemplate bean

I have used spring-boot-starter-amqp 1.4.2 RELEASE, the imported spring-amqp and spring-rabbit library is 1.6.5 RELEASE.

But when I create a bean having type org.springframework.amqp.rabbit.AsyncRabbitTemplate
@bean(name="rabbitTemplate")
public AsyncRabbitTemplate getRabbitTemplate()
{
AsyncRabbitTemplate rabbitTemplate =
new AsyncRabbitTemplate(getConnectionFactory(),
"sendExchange",
"sendMessage",
"replyQueue");
rabbitTemplate.setReceiveTimeout(60000);
rabbitTemplate.setAutoStartup(true);
return rabbitTemplate;
}
The connectionFactory I used is a CachingConnectionFactory bean.

But when I get the "rabbitTemplate" bean from application context
AsyncRabbitTemplate rabbitTemplate =
(AsyncRabbitTemplate) ApplicationContextUtil.getBean("rabbitTemplate");
I found the retrieved bean is the bean having org.springframework.amqp.rabbit.RabbitTemplate.
There is no inheritance relationship between RabbitTemplate and AsyncRabbitTemplate class, why the
spring container identify the created AsyncRabbitTemplate bean as RabbitTemplate bean?

No consumer failed event in case of Error

SimpleMessageListenerContainer does not emit an event in case of catching an Error:
https://github.com/spring-projects/spring-amqp/blob/master/spring-rabbit/src/main/java/org/springframework/amqp/rabbit/listener/SimpleMessageListenerContainer.java#L1060

On one hand it makes sense as in case of errors it might be hard to recover or even handle such an event. On the other hand my observation was that an OutOfMemory error caused shutdown of the consumer but my service kept running and would be able to handle the event.

Documentation is slightly misleading here:
"The containers publish application events whenever a listener (consumer) experiences a failure of some kind"

My questions are:

  1. Would it make sense to emit an event in case of an Error?
  2. If not, is there a way to get the list of active/failed consumers? I could use that to expose some health checks and metrics.

Send message on close

I want to send message by using RabbitTemplate inside method close of my singleton AutoCloseable bean, but when I call rabbitTemplate.convertAndSend I got an exception:

 Exception: java.lang.IllegalStateException: The ApplicationContext is closed and the ConnectionFactory can no longer create connections.

Why CachingConnectionFactory not stopped in destroy method?

log4j2 appender issues

soft version:
spring-rabbit:1.7.1.RELEASE,
log4j2 : 2.8.2
slf4j : 1.7.7

log4j2 config:
`

<appenders>
    <console name="console" target="SYSTEM_OUT">
        <PatternLayout pattern="[%d{HH:mm:ss:SSS}] [%p] - %l - %m%n"/>
    </console>
    <!--<Kafka name="Kafka" topic="log-test">-->
        <!--<PatternLayout pattern="%date %message"/>-->
        <!--<Property name="bootstrap.servers">192.168.3.166:9090,192.168.3.166:9091,192.168.3.166:9092</Property>-->
    <!--</Kafka>-->
    <RabbitMQ name="rabbitmq_logdata_tojson"
              host="${sys:rabbitmq_host}"
              port="${sys:rabbitmq_port}"
              user="${sys:rabbitmq_user}"
              password="${sys:rabbitmq_password}"
              virtualHost="/"
              exchange="${sys:rabbitmq_exchange}"
              exchangeType="${sys:rabbitmq_exchangeType}"
              declareExchange="true"
              durable="true"
              autoDelete="false"
              applicationId="${sys:rabbitmq_qname_4logdata.json}"
              routingKeyPattern="${sys:rabbitmq_qname_4logdata.json}"
              contentType="text/plain"
              contentEncoding="${sys:log4j2_charset}"
              generateId="false"
              deliveryMode="NON_PERSISTENT"
              charset="${sys:log4j2_charset}"
              senderPoolSize="1" maxSenderRetries="5">
    </RabbitMQ>

    <!--flume appender的配置,此处采用Avro类型 -->
    <!--<Flume name="flume_logdata_in" compress="false" type="Avro" >-->
        <!--<Agent host="192.168.2.111" port="4444"/>-->
    <!--</Flume>-->

</appenders>

<loggers>

    <logger name="${sys:rabbitmq_qname_4logdata.json}" level="info">
        <appender-ref ref="rabbitmq_logdata_tojson"/>
    </logger>

    <!-- 测试数据使用 -->
    <!--<logger name="${sys:rabbitmq_qname_4logdata}" level="info">-->
        <!--<appender-ref ref="rabbitmq_logdata_tobyte"/>-->
    <!--</logger>-->

    <root level="debug">
        <appender-ref ref="console"/>
        <!--<appender-ref ref="Kafka"/>-->
    </root>
</loggers>

`

java code:
private static final Logger writeQueueLog= LoggerFactory.getLogger(System.getProperty("rabbitmq_qname_4logdata.json")); writeQueueLog.info(jsonObject.toString());

the System.properties

rabbitmq_qname_4logdata.json=user.behavior.countmessage.queue rabbitmq_qname_4logdata=user.behavior.logdatainfo.queue

when i user AMQPAppender to send message to rabbitmq, always has some other logger message.

I had debug APQPAppender source code, when method "append" has been called, all of the events is need, but the Sender is running,always has some events from other logger.

then, I changed queue to String like this : private final LinkedBlockingQueue<String> eventsStrs = new LinkedBlockingQueue<String>();, and add data in method append(),
I see all the value is right, bug value from events have some wrong message.

i have no idea about it, can you help me?

Wrong documentation for delayed message

In the chapter of Reference Manual said:

properties.setXDelay(15000);

when this method doesn't exists.

The correct method is (setDelay):

/**

  • Set the x-delay header.
  • @param delay the delay.
  • @SInCE 1.6
    */
    public void setDelay(Integer delay) {
    if (delay == null || delay < 0) {
    this.headers.remove(X_DELAY);
    }
    else {
    this.headers.put(X_DELAY, delay);
    }
    }

Ability to configure auto-startup on a per @RabbitListener basis

This is a request for an Enhancement:

I brought this up via spring-boot spring-projects/spring-boot#10437 and it was suggested to move it here.

@RabbitListener's are configured to auto start by default. It's possible to disable auto-start but it's an all-or-nothing change via the Spring Boot property: spring.rabbitmq.listener.auto-startup=false.

The ability to configure on a per @RabbitListener basis whether or not it auto-starts would be a useful feature (perhaps via an attribute (e.g. autostartup=false)

The only reasonably-clean (not really) way I could come up with was to configure a custom containerFactory="rabbitContainerFactory" on the @RabbitListener with an implementation like this:

@Bean
RabbitListenerContainerFactory<SimpleMessageListenerContainer> rabbitContainerFactory(ConnectionFactory rabbitConnectionFactory)
{
    SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory()
    {
        @Override
        protected void initializeContainer(final SimpleMessageListenerContainer instance)
        {
            super.initializeContainer(instance);
            instance.setAutoStartup(false);
        }
    };

    factory.setConnectionFactory(rabbitConnectionFactory);
    return factory;
}

Add possibility to setup and use ExceptionHandler

As of now Spring MVC supports concept of GlobalExceptionHandler, which allows to create custom handler for any exception (and Exception class itself). In opposite spring AMQP project doesn't allow to return setup any exception handler and I must setup exception handling globally.

Typically there is 3 types of situations which involve exception handling:

  1. Potentially recoverable error. I should throw exception and message will be redelivered to me
  2. Exception in sender's logics. I should return exception to him (reply_to header or @SendTo annotation).
  3. Exception in handler's logics. Exception should be reported and message should not be redelievered.

Spring AMQP helps us to solve 1 and 3, but there is no common way to solve 2.
I propose to implement one of following:

  1. Implement something like ExceptionHandler from Spring MVC.
  2. Handle throws keyword and return thrown exceptions to sender

It would be very cool if you could implement this!

Extending Jackson2JsonMessageConverter

I want to register a new module into the object mapper present in Jackson2JsonMessageConverter, but the documentation suggests two ways of doing it:

  • One is to configure the ObjectMapper and inject into Jackson2JsonMessageConverter. The documentation in the setJsonObjectMapper suggest an alternative which is to extend the class and override the method initializeJsonObjectMapper

  • The issue with extending the Jackson2JsonMessageConverter is the lack of access to the ObjectMapper in the parent class, ending up like this:

public class JacksonMessageConverter extends Jackson2JsonMessageConverter {
    @Override
    protected void initializeJsonObjectMapper() {
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.registerModule(new GuavaModule());
        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        this.setJsonObjectMapper(objectMapper);
    }
}

So we still have to inject the ObjectMapper, besides overriding the method, it doesn't really look like an alternative.

Changing the ObjectMapper visibility to protected (or a getter) would give us the alternative.

Clarify intended uses for AsyncRabbitTemplate.

I'm trying to better understand the cases for using the AsyncRabbitTemplate. The docs mention that the sendAndRecieve will not block. After reviewing the details of the implementation, it seems the send call does block, but the receive will not block. Does that sound right?

My initial interpretation was that both send and receive would be async. Would you have any recommendation on doing that? Maybe using @Async?

Low Delivery Rate for Rabbit

I was testing performance of Rabbit clients in Java. With Spring AMQP I was able to get Delivery Rate as 800 msgs/s. I was using testing for a 1 consumer on a single node.
At the same time I was able to get even 6000 msgs/s while using official Rabbit client.

Spring AMQP code: https://gist.github.com/dmydlarz/635c961ceca42befba89161d3399a75d
Rabbit official client code: https://gist.github.com/dmydlarz/f2ea5f4fe7ea88cfafb3862353bdbd4e

Settings for Spring AMQP where:

spring.rabbitmq.listener.max-concurrency: 1
spring.rabbitmq.listener.concurrency: 1
spring.rabbitmq.listener.simple.prefetch: 100
spring.rabbitmq.listener.simple.transaction-size: 100

This is delivery rate I got while running on Spring:
image

And this is what I get running on official client:
image

Similar numbers (as in Spring AMQP) where received by @softwaremill team in their tests descirbed in blogpost: https://softwaremill.com/mqperf/#rabbitmq. They got ~680 msgs/second.


Question is: why Spring is not able to get same numbers as official client.

What is more I was able to get ~6k rate with official Rabbit Java Perf Tool. So it should be achievable.

image

It was run as:

bin/runjava com.rabbitmq.perf.PerfTest -s 1024 -x 1  -y 1 -z 180 -u "rabbitqos_poc" -t "topic" f persistent

(1024B payload, 1 producer, 1 consumer, 180 seconds, persistent queue)

More on that: https://www.rabbitmq.com/blog/2012/04/17/rabbitmq-performance-measurements-part-1/

Cannot access receivedUserId through header annotation.

@RabbitHandler
private void onMessage(MyObject myObject,
        Message message,
        @Header(name = AmqpHeaders.RECEIVED_USER_ID, required = false) String userId) {
    // message.messageProperties.receivedUserId = "guest"
    // userId = null
}

Unknown channel number

I use rabbitmq as a message queue ,and i use Spring amqp which is a easy way to send and receive messages. but i meet this problem when i send message to fanout exchange :

2017-06-29 07:37:50.840 ERROR 1 --- [o-1234-exec-153] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.amqp.AmqpIOException: java.io.IOException] with root cause
com.rabbitmq.client.impl.UnknownChannelException: Unknown channel number 75
at com.rabbitmq.client.impl.ChannelManager.getChannel(ChannelManager.java:80) ~[amqp-client-3.5.7.jar!/:na]
at com.rabbitmq.client.impl.AMQConnection$MainLoop.run(AMQConnection.java:554) ~[amqp-client-3.5.7.jar!/:na]
at java.lang.Thread.run(Thread.java:745) [na:1.7.0_95]
This is when I use loadrunner test 50 concurrent problems will appear ,i build 5 fanout exchange,and every fanout exchange binds 10 queues ,each time a message is sent to a random exchange .When 10 concurrent time will also be the problem , but after a minute later . I used a total of two computer tests, one installed rabbimq, another send message.
i use this send message :
rabbitTemplate.convertAndSend(deptid, deptid, message);

This problem bothers me for a long time, and any help is very grateful.

Not support binding a queue to a custom Exchange whth Annotation

When binding a queue to the rabbitmq_lvc exchange,

@RabbitListener(
            bindings = @QueueBinding(
                    value = @Queue(),
                    exchange = @Exchange(
                            value = "lvc",
                            type = "'x-lvc'",//ExchangeTypes.TOPIC,
                            durable = "true"
                    ),
                    key="test"
            )
    )

An exception will be thrown.

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'myBean' defined in file [D:\git\gs-messaging-rabbitmq\complete\target\classes\hello\MyBean.class]: Initialization of bean failed; nested exception is org.springframework.beans.factory.BeanInitializationException: Unexpected exchange type: 'x-lvc'
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:564) ~[spring-beans-4.3.7.RELEASE.jar:4.3.7.RELEASE]
	.................................
Caused by: org.springframework.beans.factory.BeanInitializationException: Unexpected exchange type: 'x-lvc'
	at org.springframework.amqp.rabbit.annotation.RabbitListenerAnnotationBeanPostProcessor.declareExchangeAndBinding(RabbitListenerAnnotationBeanPostProcessor.java:598) ~[spring-rabbit-1.7.1.RELEASE.jar:na]

RabbitListenerAnnotationBeanPostProcessor.java

Cannot set another host name BrokerRunning

It's hard to set another hostname for the BrokerRunning rule.
For the connection factory it's possible to use a static block.

    @ClassRule
    public static BrokerRunning brokerRunning = BrokerRunning.isRunning();
    static {
        brokerRunning.setHostName("abc");
    }

but the host name for the management client is hardcoded

Client client = new Client("http://localhost:15672/api/", "guest", "guest");

Expose deBatchingEnabled to SimpleRabbitListenerContainerFactory

It's currently not possible to control how debatching is handled from the instances that are created by a SimpleRabbitListenerContainerFactory (without overriding it).

Please expose deBatchingEnabled as a property on the factory to be able to control debatching on the instance created.

AmqpAppender always have some message in queue

I found a problem, but i have no idea about it.

my producer send 4000 messages to mq,

I debug the AmqpAppender queue, always have some messages in it .

Then I put more messages to mq, the appender queue will increase, can not decrease.

How to rollback other txManagers on rabbit exception

When running Rabbit in HA failover, if the failover happens (thus the connections gets closed) the message currently being processed is correctly returned to the queue.
However, in our case there is some DB saving going while processing the message and I can't get that to rollback, this then results in the updates to the DB being done again as the message is reprocessed. (and in our case this results in an error as the message should be unique).

As per the documentation I've configured channelTransacted and transactionManager for the SimpleRabbitListenerContainerFactory as follows:

 @Bean
    public SimpleRabbitListenerContainerFactory rabbitListenerContainerFactory(ConnectionFactory connectionFactory,
    PlatformTransactionManager transactionManager) {
        SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
        factory.setTransactionManager(transactionManager);
        factory.setChannelTransacted(true);
        factory.setConnectionFactory(connectionFactory);
        return factory;
    }

Transaction management has been enabled:

@SpringBootApplication
@EnableJpaRepositories
@EntityScan
@EnableTransactionManagement
public class MyFabulousApp {
    // ... main and stuff
}

The processing code can be as simple as:

   @RabbitListener(queues = "foo")
   @Transactional
   public void process(Bar message) {
       barRepository.save(message);
   }

This seem to guard against instances in where the database goes down, and then the Rabbit transaction is rollbacked and the message is rejected. But not when the Rabbit goes down, then the transaction to the database does not seem to receive a rollback call.

We're using Spring AMQP through Spring Boot 1.5.9

How to close Connection from org.springframework.amqp.rabbit.connection.CachingConnectionFactory

Hello,

I'm using spring-amqp with spring-rabbit in a batch. I used <rabbit:connection-factory ... /> in my context in order to declare my ConnectionFactory and all the rest.

When my application is on the way to end, a connection remain active and blocks the process to finish. I read the .close() has not effect on this connection factory and I would like to know what should I do in order to gracefully end it ?

Thx

How to use vcap Rabbitmq jms queue and Redis service in spring boot application

Hi Garry,

I am new to vcap services on pivotal. I have to bind redis and rabbit mq services using vcap.
This is the below link in which I am working right now
link1: http://stackoverflow.com/questions/43305346/how-to-give-manual-acknowledge-using-jmstemplate-and-delete-message-from-rabbitm
After consuming messages from rabbitmq jms queue I am processing and storing it in redis as hmset.
In below link the entire details are given .
The question that I have is
(http://stackoverflow.com/questions/43936022/use-pivotal-cloud-foundry-redis-and-rabbitmq-service-using-as-vcap-service-in-sp)
In this url the vcap config is mentioned I am trying to use it but I am not able to get the specific dependencies for
@bean
RabbitConnectionFactory rabbitFactory() {
return connectionFactory().rabbitConnectionFactory("rabbit-servicename");
}

Have u any other solution for this .
Thanks.

Regards,
Abhijeet.

RabbitMq management Rest Api connection issue with client using non public certificates

Creating a RabbitManagementTemplate instance there is no way to add trusted certificates or to change the http client. The underlying class Client creates a rest template instance without any option to configure trusted certificates. The HttpClientBuilder used to create the HttpComponentsClientHttpRequestFactory used by the RestTemplate doesn't call useSystemProperties() method so default properties like javax.net.ssl.trustStore doesn't work too.

Is there a way I messed by now I couldn't see a way to trust the server certificate with the RabbitManagementTemplate.

Expose Network Recovery Interval and Automatic Connection Recovery in RabbitConnectionFactoryBean

I opened an issue in Spring Boot to expose networkRecoveryInterval and automaticRecovery as part of the RabbitAutoConfiguration. @philwebb agreed that it would be a nice capability to have. However, before this can be done those properties need to be exposed on the RabbitConnectionFactoryBean.

Can I submit a PR to expose these properties on the RabbitConnectionFactoryBean?

Issue:

spring-projects/spring-boot#5031

Class not found exception

Hi Guys,

I build a jar by myself and i am sure i am do nothing, just run the gradle build and gradle install command,
then i get the new jar file, but when i use the jar file in my app, i get an error like below:

`Caused by: java.lang.NoClassDefFoundError: org/springframework/amqp/support/converter/SmartMessageConverter
at java.lang.Class.getDeclaredMethods0(Native Method)
at java.lang.Class.privateGetDeclaredMethods(Class.java:2701)
at java.lang.Class.getDeclaredMethods(Class.java:1975)
at org.springframework.util.ReflectionUtils.getDeclaredMethods(ReflectionUtils.java:613)
at org.springframework.util.ReflectionUtils.doWithLocalMethods(ReflectionUtils.java:489)
at org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor.buildPersistenceMetadata(PersistenceAnnotationBeanPostProcessor.java:431)
at org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor.findPersistenceMetadata(PersistenceAnnotationBeanPostProcessor.java:397)
... 72 common frames omitted
Caused by: java.lang.ClassNotFoundException: org.springframework.amqp.support.converter.SmartMessageConverter
at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:335)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
... 79 common frames omitted

`

could you please help me look at this?

Rabbit SSL connection error RabbitConnectionFactoryBean

In case if we use RabbitConnectionFactoryBean with
useSSL=true
&&sslPropertiesLocation == null && keyStore == null &&trustStore == null
&& keyStorePassphrase == null && this.trustStorePassphrase == null

it makes a call to amqp-rabbit-connectionfactory

if (this.sslAlgorithmSet) {
				this.connectionFactory.useSslProtocol(this.sslAlgorithm);
			}
			else {
				this.connectionFactory.useSslProtocol();
			}

but that code internally uses a NullTrustManager; meaning it doesn't do the server certificate validation. The spring documentation also mentions this.
I did raise an issue with rabbit-mq maintainers Issue but it didn't go anywhere.

My suggestion is that we should avoid using
this.connectionFactory.useSslProtocol(this.sslAlgorithm);
or
this.connectionFactory.useSslProtocol();

instead delegate to Java's default trustStore mechanism
the rabbit-amqp library is susceptible for man-in-middle attacks; I believe we should provide more safer defaults.

should I make a PR? I think this should work !!

public void useDefaultTrustStoreMechanism(){
  		SSLContext c = SSLContext.getInstance(this.sslAlgorithm);
        c.init(null, new TrustManager[] {  getDefaultTrustManager(this.sslAlgorithm, (KeyStore)null }, null);
        useSslProtocol(c);
	
}


public static X509TrustManager getDefaultTrustManager(String algorithm, KeyStore keystore) {

      TrustManagerFactory factory;
      X509TrustManager x509TrustManager = null;

      try {
          factory = TrustManagerFactory.getInstance(algorithm);
          factory.init(keystore);
          for (TrustManager trustManager : factory.getTrustManagers()) {

              if (trustManager instanceof X509TrustManager) {
                   x509TrustManager = (X509TrustManager)trustManager;
                  break;
              }
          }

      } catch (NoSuchAlgorithmException  e) {
          e.printStackTrace();
      }catch ( KeyStoreException e){
          e.printStackTrace();
      }

      return x509TrustManager;

}

RabbitConnectionFactory should support JKS for SSL Keystore

this is more of a feature request than a bug...

Currently, "PKCS12" is the only supported type for the keystore, even though JKS is used for the truststore. It would be nice if the type was configurable, as JKS is a common format to use for Java Applications and it is somewhat inconvenient to have to convert to P12 just to use a secure rabbit connection.

I know I can easily override the class to implement this myself, I just thought it would be convenient if this was supported natively by a property similar to how keystore path and password are treated.

DirectMessageListenerContainer does not restart consumers after a lost connection has been recovered

So we've been playing around with version spring-amqp/-rabbit 2.0.0 M5 and have a weird issue with DirectMessageListenerContainers.

We use a CachingConnectionFactory with all values at their defaults. The DirectMessageListenerContainers also have everything on default except missingQueuesFatal set to false.

To test connection and consumer recovery, we stop the RabbitMQ server (sends connection close because of shutdown). All DirectMessageListenerContainer (DMLC) detect the lost connection properly. However, once the server comes back up, there's always one DMLC which does not restart its consumers.

I've been debugging a little:
It looks like the first DMLC to run the monitor task calls DirectMessageListenerContainer#doConsumeFromQueue from the consumer monitor task and still gets a connection object in DirectMessageListenerContainer.java#L553 form the connection factory. This raises an Exception in DirectMessageListenerContainer#L567 when creating a channel. This exception is caught in the monitor thread DirectMessageListenerContainer.java#L416 which just logs an error. However, the consumer which failed to start is not added back to the list of consumersToRestart.

Let me know if you're having trouble reproducing this issue; I'll try to create a minimal example application then.

EDIT: Logs at https://gist.github.com/Monofraps/152a6d95d63252c4eae62f310a84c50a

correlation id missing when trying to communicate between different rabbitmq rpc library

I am using spring amqp for my service written in Java, and my colleague created a service using nodejs and he is using amqplib-rpc. The problem is when I tried to request from spring amqp to amqplib-rpc it raise an error that "reply() cannot reply to a message without 'correlationId'". It said that spring amqp automatically creates a correlationid. In fact, its ok when I use spring amqp to spring amqp request

SHOULD raise exception when durable, exclusive queue (spring-amqp/spring-rabbit)

Hello there,

Thanks for spring-amqp/spring-rabbit for to easy using RabbitMQ, but I got a question.

The question is,
Why didn't raise a Exception when declare a queue with durable: true and exclusive: true.

in RabbitMQ AMQP-0-9-1-ERRATA

30 durable vs exclusive

The spec does not define what happens if a client tries to declare a queue which is both durable and exclusive. RabbitMQ will treat a request to declare such a queue as a request for an exclusive transient queue.

According to above paragraph
Although it will request with durable: true and exclusive: true, RabbitMQ will change to non-durable exclusive queue.

Queue queueForTest1 = new Queue("QUEUE_NAME", true, true, false);
Queue queueForTest2 = new Queue("QUEUE_NAME", true, false, false);
rabbitAdmin.declareQueue(queueForTest1);
rabbitAdmin.declareQueue(queueForTest2);
Channel shutdown: channel error; protocol method: #method<channel.close>(reply-code=406, reply-text=PRECONDITION_FAILED - inequivalent arg 'durable' for queue 'QUEUE_NAME' in vhost '/': received 'true' but current is 'false', class-id=50, method-id=10)

and I certainly checked this situation via above my test code.

So I suggest.
It'd better that will raise a exception by spring-amqp/spring-rabbit, to prevent this situation which is declaring with durable: true and exclusive: true.

Delivery mode lost when using RepublishMessageRecoverer

Hi,

When using RepublishMessageRecoverer, delivery mode of the new message seems to be NON_PERSISTENT by default. When RabbitMQ broker restart, all messages get lost.
I've tried to override the RepublishMessageRecoverer by adding message.getMessageProperties().setDeliveryMode(MessageDeliveryMode.PERSISTENT), and messages are now persistent.

Is it possible to add an option to choose delivery mode of the republished messages ?

Thanks

Correlation Id spring apmq 1.7.x

Hello this code look weird SimpleAmqpHeaderMapper.toHeaders

	@SuppressWarnings("deprecation")
			byte[] correlationId = amqpMessageProperties.getCorrelationId();
			if (correlationId != null && correlationId.length > 0) {
				headers.put(AmqpHeaders.CORRELATION_ID, correlationId);
			}
			String correlationIdString = amqpMessageProperties.getCorrelationIdString();
			if (StringUtils.hasText(correlationIdString)) {
				headers.put(AmqpHeaders.CORRELATION_ID, correlationId);
			}

second why is not there something like

if (StringUtils.hasText(correlationIdString)) {
				headers.put(AmqpHeaders.CORRELATION_ID, correlationIdString);
			}

Possible memory leak during DirectMessageListenerContainer start phase if no RabbitMQ server is available

During DirectMessageListenerContainer startup, a loop continuously tries to start consumers for each registered queue name.

for (String queue : queueNames) {
    consumeFromQueue(queue);
}

consumeFromQueue will internally invoke doConsumeFromQueue if there's no active listener for the given queue. However, doConsumeFromQueue will append an entry to consumersToRestart every time it fails to start a consumer. During the whole start phase the this.consumersMonitor is acquired (Thread.sleep does not unlock monitor objects). This results in the consumer monitor task to block at synchronized (this.consumersMonitor) until the container has started (i.e. a consumer for every queue has been created without error). Since the monitor task is blocked, the following code to clean the list of consumers to restart is not cleared resulting in consumersToRestart growing until either the container starts up or the JVM crashes due to OOM errors.

synchronized (this.consumersMonitor) {
	List<SimpleConsumer> restartableConsumers = new ArrayList<>(this.consumersToRestart);
	this.consumersToRestart.clear();
[...]
}

spring-rabbit-1.0.xsd

line 254 <xsd:attribute name="durable" use="optional" type="xsd:string " default="true">

SimpleMessageListenerContainer not stopped

When testing SimpleMessageListenerContainer (4 parallel consumers per listener container), I noticed that if i call stop() when rabbitmq is down (stopped rabbit service), then when rabbitmq is back again (started rabbit service), container is actually not 100% stopped and somehow reconnects itself - it still has 2 or 3 consumers out of this 4 reconnected.

Situation is always different - sometimes it is stopped, sometimes 2 reconnect, sometimes even all 4 reconnect.

Headers are not set when used with MessageBuilder APIs

I have a application where I am using both JMS and AMQP (Rabbit) with configurations and am using JAXB object and using spring-integration chain to publish the object message. Similar configuration works fine with JMS but not for AMQP. Looks like it's a bug, can someone please take a quick look at it and suggest if am doing anything wrong.

I am using spring-integration-amqp-4.2.6.RELEASE.jar (which has transitive dependency on spring-amqp-1.5.2.RELEASE.jar & amqp-client-3.5.6.jar )

Sample Code To Publish the Message

MessageBuilder<?> messageBuilder = MessageBuilder.withPayload(event)
					.setHeader("destinationName", destinationName)
					.setHeader("deliveryMode", (deliveryMode==2 ? Boolean.TRUE : Boolean.FALSE))
					.setHeader("sessionAcknowledge", sessionAcknowledge)
					.setPriority(proprity);
			
			// RoutingKey is applicable only for RabbitMQ
			if(routingKey!=null && !routingKey.isEmpty()){
				messageBuilder.setHeader("routingKeyName", routingKey);
			}
                        // set other bunch of custom application headers in a Map<String, String> (msgHeaders)
			if(msgHeaders!=null && !msgHeaders.isEmpty()){
				messageBuilder.copyHeaders(msgHeaders);
			}
			
			Message<?> message = messageBuilder .build();
         MessageChannel messageChannel = applicationContext.getBean("objMessageChannel", MessageChannel.class);
    messageChannel.send(message, timeoutInMilliSecs);

Configuration for publishing the message with AMQP

	<int:channel id="objMessageChannel" />

	<int:chain id="publisherObjectMessageChannel" input-channel="objMessageChannel">
		<int-xml:marshalling-transformer id="objectToXMLTransformer" marshaller="messagePublisherMarshaller" 
			result-type="StringResult" result-transformer="resultToStringTransformer">
		</int-xml:marshalling-transformer>
		<int:service-activator method="sendMessage" ref="messagePublisherServiceActivator" />
		<int:header-enricher>
			<int:header name="custom-static-header" value="custom-static-header-value" />
		</int:header-enricher>
		<int-amqp:outbound-channel-adapter amqp-template="rabbitTemplate" 
			default-delivery-mode="${message.publisher.amqp.delivery.mode:${default.message.publisher.amqp.delivery.mode}}"
			exchange-name-expression="headers['destinationName']" routing-key-expression="headers['routingKeyName']"  />
	</int:chain>

Configuration for publishing the message with JMS

	<int:chain id="publisherObjectMessageChannel" input-channel="objMessageChannel">
		<int-xml:marshalling-transformer id="objectToXMLTransformer" marshaller="messagePublisherMarshaller" 
			result-type="StringResult" result-transformer="resultToStringTransformer">
		</int-xml:marshalling-transformer>
		<int:service-activator method="sendMessage" ref="messagePublisherServiceActivator" />
                <int:header-enricher>
			<int:header name="custom-static-header" value="custom-static-header-value" />
		</int:header-enricher>
		<int-jms:outbound-channel-adapter connection-factory="publisherConnectionFactory" 
			destination-expression="headers['destinationName']" explicit-qos-enabled="true" pub-sub-domain="false"
			session-transacted="${message.publisher.jms.session.transactional:${default.message.publisher.jms.session.transactional}}" 
			delivery-persistent="#{${message.publisher.jms.delivery.mode:${default.message.publisher.jms.delivery.mode}} == 2 ? true : false}" />
	</int:chain>

When I looked at the org.springframework.integration.amqp.outbound.AmqpOutboundEndpoint.send() method looks like it's passing only the body in case of RabbitTemplate and when it uses headerMapper it simply keeps amqp standard headers and ignore everything else. Either configuration should be allowed for extention with headerMapper or it should pass Message object directly to convertAndSend rather than message.getPayload().

	private void send(String exchangeName, String routingKey,
			final Message<?> requestMessage, CorrelationData correlationData) {
		if (this.amqpTemplate instanceof RabbitTemplate) {
			((RabbitTemplate) this.amqpTemplate).convertAndSend(exchangeName, routingKey, requestMessage.getPayload(),
					new MessagePostProcessor() {
						@Override
						public org.springframework.amqp.core.Message postProcessMessage(
								org.springframework.amqp.core.Message message) throws AmqpException {
							headerMapper.fromHeadersToRequest(requestMessage.getHeaders(),
									message.getMessageProperties());
							checkDeliveryMode(requestMessage, message.getMessageProperties());
							return message;
						}
					},
					correlationData);
		}
		else {
			this.amqpTemplate.convertAndSend(exchangeName, routingKey, requestMessage.getPayload(),
					new MessagePostProcessor() {
						@Override
						public org.springframework.amqp.core.Message postProcessMessage(
								org.springframework.amqp.core.Message message) throws AmqpException {
							headerMapper.fromHeadersToRequest(requestMessage.getHeaders(),
									message.getMessageProperties());
							return message;
						}
					});
		}
	}

auto delete exchange disappears after creation

hello,

I have a following problem. During listener recovery (after connection to RabbiMQ is restored) RabbitAdmin recreates exchanges, queues and bindings. According to logs, exchange and queues are created successfully, however it fails when RabbitAdmin tries to bind first queue to that exchange. The reason for the failure was missing exchange which was created during this initialization process. In RabbitMQ management web console I could see that all queues were created. The exchange was missing, and also the bindings were not there. The only situation I encounter following problems is after listener recovery due to the connection problem between app and RabbitMQ. According to RabbitMQ docs https://www.rabbitmq.com/amqp-0-9-1-reference.html#exchange.declare.auto-delete auto delete exchange is removed after all queues have finished using it. Additionally server should allow client to create queues and bind to them before it considers the exchange to be removed. The initialization process didn't take longer then 300 millisecond so I assume it's not the case. Please have a look at enclosed logs

2017-07-06 20:41:04.723  INFO 7645 --- [InCUContainer-9] o.s.a.r.c.CachingConnectionFactory       : Created new connection: [email protected] [delegate=amqp://[email protected]:5672/, localPort= 59800]
2017-07-06 20:41:04.723 DEBUG 7645 --- [InCUContainer-9] o.s.amqp.rabbit.core.RabbitAdmin         : Initializing declarations
2017-07-06 20:41:04.723  INFO 7645 --- [InCUContainer-9] o.s.amqp.rabbit.core.RabbitAdmin         : Auto-declaring a non-durable or auto-delete Exchange (hsm.in.queue.direct) durable:false, auto-delete:true. It will be deleted by the broker if it shuts down, and can be redeclared by closing and reopening the connection.
2017-07-06 20:41:04.723  INFO 7645 --- [InCUContainer-9] o.s.amqp.rabbit.core.RabbitAdmin         : Auto-declaring a non-durable, auto-delete, or exclusive Queue (hsm1.sk.in.queue) durable:false, auto-delete:true, exclusive:false. It will be redeclared if the broker stops and is restarted while the connection factory is alive, but all messages will be lost.
2017-07-06 20:41:04.723  INFO 7645 --- [InCUContainer-9] o.s.amqp.rabbit.core.RabbitAdmin         : Auto-declaring a non-durable, auto-delete, or exclusive Queue (hsm1.gk.in.queue) durable:false, auto-delete:true, exclusive:false. It will be redeclared if the broker stops and is restarted while the connection factory is alive, but all messages will be lost.
2017-07-06 20:41:04.724  INFO 7645 --- [InCUContainer-9] o.s.amqp.rabbit.core.RabbitAdmin         : Auto-declaring a non-durable, auto-delete, or exclusive Queue (hsm1.rk.in.queue) durable:false, auto-delete:true, exclusive:false. It will be redeclared if the broker stops and is restarted while the connection factory is alive, but all messages will be lost.
2017-07-06 20:41:04.724  INFO 7645 --- [InCUContainer-9] o.s.amqp.rabbit.core.RabbitAdmin         : Auto-declaring a non-durable, auto-delete, or exclusive Queue (hsm1.cp.in.queue) durable:false, auto-delete:true, exclusive:false. It will be redeclared if the broker stops and is restarted while the connection factory is alive, but all messages will be lost.
2017-07-06 20:41:04.724  INFO 7645 --- [InCUContainer-9] o.s.amqp.rabbit.core.RabbitAdmin         : Auto-declaring a non-durable, auto-delete, or exclusive Queue (hsm1.cu.in.queue) durable:false, auto-delete:true, exclusive:false. It will be redeclared if the broker stops and is restarted while the connection factory is alive, but all messages will be lost.
2017-07-06 20:41:04.724  INFO 7645 --- [InCUContainer-9] o.s.amqp.rabbit.core.RabbitAdmin         : Auto-declaring a non-durable, auto-delete, or exclusive Queue (hsm1.rp.in.queue) durable:false, auto-delete:true, exclusive:false. It will be redeclared if the broker stops and is restarted while the connection factory is alive, but all messages will be lost.
2017-07-06 20:41:04.724  INFO 7645 --- [InCUContainer-9] o.s.amqp.rabbit.core.RabbitAdmin         : Auto-declaring a non-durable, auto-delete, or exclusive Queue (hsm1.is.in.queue) durable:false, auto-delete:true, exclusive:false. It will be redeclared if the broker stops and is restarted while the connection factory is alive, but all messages will be lost.
2017-07-06 20:41:04.724  INFO 7645 --- [InCUContainer-9] o.s.amqp.rabbit.core.RabbitAdmin         : Auto-declaring a non-durable, auto-delete, or exclusive Queue (hsm1.gs.in.queue) durable:false, auto-delete:true, exclusive:false. It will be redeclared if the broker stops and is restarted while the connection factory is alive, but all messages will be lost.
2017-07-06 20:41:04.724  INFO 7645 --- [InCUContainer-9] o.s.amqp.rabbit.core.RabbitAdmin         : Auto-declaring a non-durable, auto-delete, or exclusive Queue (hsm1.gp.in.queue) durable:false, auto-delete:true, exclusive:false. It will be redeclared if the broker stops and is restarted while the connection factory is alive, but all messages will be lost.
2017-07-06 20:41:04.724  INFO 7645 --- [InCUContainer-9] o.s.amqp.rabbit.core.RabbitAdmin         : Auto-declaring a non-durable, auto-delete, or exclusive Queue (hsm1.ac.in.queue) durable:false, auto-delete:true, exclusive:false. It will be redeclared if the broker stops and is restarted while the connection factory is alive, but all messages will be lost.
2017-07-06 20:41:04.724  INFO 7645 --- [InCUContainer-9] o.s.amqp.rabbit.core.RabbitAdmin         : Auto-declaring a non-durable, auto-delete, or exclusive Queue (hsm1.rs.in.queue) durable:false, auto-delete:true, exclusive:false. It will be redeclared if the broker stops and is restarted while the connection factory is alive, but all messages will be lost.
2017-07-06 20:41:04.724 TRACE 7645 --- [InCUContainer-9] o.s.a.r.c.CachingConnectionFactory       : Cached Rabbit Channel: PublisherCallbackChannelImpl: AMQChannel(amqp://[email protected]:5672/,84), conn: [email protected] Shared Rabbit Connection: [email protected] [delegate=amqp://[email protected]:5672/, localPort= 59800] retrieved from cache
2017-07-06 20:41:04.724 TRACE 7645 --- [InCUContainer-9] o.s.a.r.s.PublisherCallbackChannelImpl   : AMQChannel(amqp://[email protected]:5672/,84) is already closed
2017-07-06 20:41:04.725 DEBUG 7645 --- [InCUContainer-9] o.s.a.r.s.PublisherCallbackChannelImpl   : PendingConfirms cleared
2017-07-06 20:41:04.728 DEBUG 7645 --- [InCUContainer-9] o.s.a.r.c.CachingConnectionFactory       : Creating cached Rabbit Channel from PublisherCallbackChannelImpl: AMQChannel(amqp://[email protected]:5672/,1)
2017-07-06 20:41:04.728 DEBUG 7645 --- [InCUContainer-9] o.s.a.r.s.PublisherCallbackChannelImpl   : Added listener [email protected]
2017-07-06 20:41:04.728 DEBUG 7645 --- [InCUContainer-9] o.s.amqp.rabbit.core.RabbitTemplate      : Added pubsub channel: Cached Rabbit Channel: PublisherCallbackChannelImpl: AMQChannel(amqp://[email protected]:5672/,1), conn: [email protected] Shared Rabbit Connection: [email protected] [delegate=amqp://[email protected]:5672/, localPort= 59800] to map, size now 1
2017-07-06 20:41:04.728 DEBUG 7645 --- [InCUContainer-9] o.s.amqp.rabbit.core.RabbitTemplate      : Executing callback on RabbitMQ Channel: Cached Rabbit Channel: PublisherCallbackChannelImpl: AMQChannel(amqp://[email protected]:5672/,1), conn: [email protected] Shared Rabbit Connection: [email protected] [delegate=amqp://[email protected]:5672/, localPort= 59800]
2017-07-06 20:41:04.728 DEBUG 7645 --- [InCUContainer-9] o.s.amqp.rabbit.core.RabbitAdmin         : declaring Exchange 'hsm.in.queue.direct'
2017-07-06 20:41:04.730 DEBUG 7645 --- [InCUContainer-9] o.s.amqp.rabbit.core.RabbitAdmin         : declaring Queue 'hsm1.sk.in.queue.dlx'
2017-07-06 20:41:04.731 DEBUG 7645 --- [InCUContainer-9] o.s.amqp.rabbit.core.RabbitAdmin         : Queue with name that starts with 'amq.' cannot be declared.
2017-07-06 20:41:04.731 DEBUG 7645 --- [InCUContainer-9] o.s.amqp.rabbit.core.RabbitAdmin         : declaring Queue 'hsm1.gk.in.queue.dlx'
2017-07-06 20:41:04.732 DEBUG 7645 --- [InCUContainer-9] o.s.amqp.rabbit.core.RabbitAdmin         : Queue with name that starts with 'amq.' cannot be declared.
2017-07-06 20:41:04.732 DEBUG 7645 --- [InCUContainer-9] o.s.amqp.rabbit.core.RabbitAdmin         : declaring Queue 'hsm1.rk.in.queue.dlx'
2017-07-06 20:41:04.734 DEBUG 7645 --- [InCUContainer-9] o.s.amqp.rabbit.core.RabbitAdmin         : Queue with name that starts with 'amq.' cannot be declared.
2017-07-06 20:41:04.734 DEBUG 7645 --- [InCUContainer-9] o.s.amqp.rabbit.core.RabbitAdmin         : declaring Queue 'hsm1.cp.in.queue.dlx'
2017-07-06 20:41:04.735 DEBUG 7645 --- [InCUContainer-9] o.s.amqp.rabbit.core.RabbitAdmin         : Queue with name that starts with 'amq.' cannot be declared.
2017-07-06 20:41:04.735 DEBUG 7645 --- [InCUContainer-9] o.s.amqp.rabbit.core.RabbitAdmin         : declaring Queue 'hsm1.cu.in.queue.dlx'
2017-07-06 20:41:04.736 DEBUG 7645 --- [InCUContainer-9] o.s.amqp.rabbit.core.RabbitAdmin         : Queue with name that starts with 'amq.' cannot be declared.
2017-07-06 20:41:04.736 DEBUG 7645 --- [InCUContainer-9] o.s.amqp.rabbit.core.RabbitAdmin         : declaring Queue 'hsm1.rp.in.queue.dlx'
2017-07-06 20:41:04.737 DEBUG 7645 --- [InCUContainer-9] o.s.amqp.rabbit.core.RabbitAdmin         : Queue with name that starts with 'amq.' cannot be declared.
2017-07-06 20:41:04.737 DEBUG 7645 --- [InCUContainer-9] o.s.amqp.rabbit.core.RabbitAdmin         : declaring Queue 'hsm1.is.in.queue.dlx'
2017-07-06 20:41:04.739 DEBUG 7645 --- [InCUContainer-9] o.s.amqp.rabbit.core.RabbitAdmin         : Queue with name that starts with 'amq.' cannot be declared.
2017-07-06 20:41:04.739 DEBUG 7645 --- [InCUContainer-9] o.s.amqp.rabbit.core.RabbitAdmin         : declaring Queue 'hsm1.gs.in.queue.dlx'
2017-07-06 20:41:04.740 DEBUG 7645 --- [InCUContainer-9] o.s.amqp.rabbit.core.RabbitAdmin         : Queue with name that starts with 'amq.' cannot be declared.
2017-07-06 20:41:04.740 DEBUG 7645 --- [InCUContainer-9] o.s.amqp.rabbit.core.RabbitAdmin         : declaring Queue 'hsm1.gp.in.queue.dlx'
2017-07-06 20:41:04.741 DEBUG 7645 --- [InCUContainer-9] o.s.amqp.rabbit.core.RabbitAdmin         : Queue with name that starts with 'amq.' cannot be declared.
2017-07-06 20:41:04.741 DEBUG 7645 --- [InCUContainer-9] o.s.amqp.rabbit.core.RabbitAdmin         : declaring Queue 'hsm1.ac.in.queue.dlx'
2017-07-06 20:41:04.742 DEBUG 7645 --- [InCUContainer-9] o.s.amqp.rabbit.core.RabbitAdmin         : Queue with name that starts with 'amq.' cannot be declared.
2017-07-06 20:41:04.742 DEBUG 7645 --- [InCUContainer-9] o.s.amqp.rabbit.core.RabbitAdmin         : declaring Queue 'hsm1.rs.in.queue.dlx'
2017-07-06 20:41:04.743 DEBUG 7645 --- [InCUContainer-9] o.s.amqp.rabbit.core.RabbitAdmin         : Queue with name that starts with 'amq.' cannot be declared.
2017-07-06 20:41:04.743 DEBUG 7645 --- [InCUContainer-9] o.s.amqp.rabbit.core.RabbitAdmin         : declaring Queue 'hsm1.sk.in.queue'
2017-07-06 20:41:04.746 DEBUG 7645 --- [InCUContainer-9] o.s.amqp.rabbit.core.RabbitAdmin         : Queue with name that starts with 'amq.' cannot be declared.
2017-07-06 20:41:04.746 DEBUG 7645 --- [InCUContainer-9] o.s.amqp.rabbit.core.RabbitAdmin         : declaring Queue 'hsm1.gk.in.queue'
2017-07-06 20:41:04.748 DEBUG 7645 --- [InCUContainer-9] o.s.amqp.rabbit.core.RabbitAdmin         : Queue with name that starts with 'amq.' cannot be declared.
2017-07-06 20:41:04.748 DEBUG 7645 --- [InCUContainer-9] o.s.amqp.rabbit.core.RabbitAdmin         : declaring Queue 'hsm1.rk.in.queue'
2017-07-06 20:41:04.756 DEBUG 7645 --- [InCUContainer-9] o.s.amqp.rabbit.core.RabbitAdmin         : Queue with name that starts with 'amq.' cannot be declared.
2017-07-06 20:41:04.757 DEBUG 7645 --- [InCUContainer-9] o.s.amqp.rabbit.core.RabbitAdmin         : declaring Queue 'hsm1.cp.in.queue'
2017-07-06 20:41:04.760 DEBUG 7645 --- [InCUContainer-9] o.s.amqp.rabbit.core.RabbitAdmin         : Queue with name that starts with 'amq.' cannot be declared.
2017-07-06 20:41:04.760 DEBUG 7645 --- [InCUContainer-9] o.s.amqp.rabbit.core.RabbitAdmin         : declaring Queue 'hsm1.cu.in.queue'
2017-07-06 20:41:04.768 DEBUG 7645 --- [InCUContainer-9] o.s.amqp.rabbit.core.RabbitAdmin         : Queue with name that starts with 'amq.' cannot be declared.
2017-07-06 20:41:04.768 DEBUG 7645 --- [InCUContainer-9] o.s.amqp.rabbit.core.RabbitAdmin         : declaring Queue 'hsm1.rp.in.queue'
2017-07-06 20:41:04.771 DEBUG 7645 --- [InCUContainer-9] o.s.amqp.rabbit.core.RabbitAdmin         : Queue with name that starts with 'amq.' cannot be declared.
2017-07-06 20:41:04.771 DEBUG 7645 --- [InCUContainer-9] o.s.amqp.rabbit.core.RabbitAdmin         : declaring Queue 'hsm1.is.in.queue'
2017-07-06 20:41:04.774 DEBUG 7645 --- [InCUContainer-9] o.s.amqp.rabbit.core.RabbitAdmin         : Queue with name that starts with 'amq.' cannot be declared.
2017-07-06 20:41:04.774 DEBUG 7645 --- [InCUContainer-9] o.s.amqp.rabbit.core.RabbitAdmin         : declaring Queue 'hsm1.gs.in.queue'
2017-07-06 20:41:04.777 DEBUG 7645 --- [InCUContainer-9] o.s.amqp.rabbit.core.RabbitAdmin         : Queue with name that starts with 'amq.' cannot be declared.
2017-07-06 20:41:04.777 DEBUG 7645 --- [InCUContainer-9] o.s.amqp.rabbit.core.RabbitAdmin         : declaring Queue 'hsm1.gp.in.queue'
2017-07-06 20:41:04.780 DEBUG 7645 --- [InCUContainer-9] o.s.amqp.rabbit.core.RabbitAdmin         : Queue with name that starts with 'amq.' cannot be declared.
2017-07-06 20:41:04.780 DEBUG 7645 --- [InCUContainer-9] o.s.amqp.rabbit.core.RabbitAdmin         : declaring Queue 'hsm1.ac.in.queue'
2017-07-06 20:41:04.783 DEBUG 7645 --- [InCUContainer-9] o.s.amqp.rabbit.core.RabbitAdmin         : Queue with name that starts with 'amq.' cannot be declared.
2017-07-06 20:41:04.783 DEBUG 7645 --- [InCUContainer-9] o.s.amqp.rabbit.core.RabbitAdmin         : declaring Queue 'hsm1.rs.in.queue'
2017-07-06 20:41:04.790 DEBUG 7645 --- [InCUContainer-9] o.s.amqp.rabbit.core.RabbitAdmin         : Queue with name that starts with 'amq.' cannot be declared.
2017-07-06 20:41:04.790 DEBUG 7645 --- [InCUContainer-9] o.s.amqp.rabbit.core.RabbitAdmin         : Binding destination [hsm1.sk.in.queue (QUEUE)] to exchange [hsm.in.queue.direct] with routing key [1.sk]
2017-07-06 20:41:04.833 DEBUG 7645 --- [.104.5.184:5672] o.s.amqp.rabbit.core.RabbitTemplate      : Removed pubsub channel: PublisherCallbackChannelImpl: AMQChannel(amqp://[email protected]:5672/,1) from map, size now 0
2017-07-06 20:41:04.833 DEBUG 7645 --- [.104.5.184:5672] o.s.a.r.s.PublisherCallbackChannelImpl   : PendingConfirms cleared
2017-07-06 20:41:04.833 ERROR 7645 --- [.104.5.184:5672] o.s.a.r.c.CachingConnectionFactory       : Channel shutdown: channel error; protocol method: #method<channel.close>(reply-code=404, reply-text=NOT_FOUND - no exchange 'hsm.in.queue.direct' in vhost '/', class-id=50, method-id=20)
2017-07-06 20:41:04.834 DEBUG 7645 --- [InCUContainer-9] o.s.a.r.c.CachingConnectionFactory       : Detected closed channel on exception.  Re-initializing: PublisherCallbackChannelImpl: AMQChannel(amqp://[email protected]:5672/,1)
2017-07-06 20:41:04.837 TRACE 7645 --- [InCUContainer-9] o.s.a.r.c.CachingConnectionFactory       : Returning cached Channel: PublisherCallbackChannelImpl: AMQChannel(amqp://[email protected]:5672/,1)
2017-07-06 20:41:04.837 DEBUG 7645 --- [InCUContainer-9] o.s.a.r.l.SimpleMessageListenerContainer : Recovering consumer in 5000 ms.
2017-07-06 20:41:09.841  WARN 7645 --- [InCUContainer-9] o.s.a.r.l.SimpleMessageListenerContainer : Consumer raised exception, processing can restart if the connection factory supports it
org.springframework.amqp.AmqpIOException: java.io.IOException
	at org.springframework.amqp.rabbit.support.RabbitExceptionTranslator.convertRabbitAccessException(RabbitExceptionTranslator.java:71)
	at org.springframework.amqp.rabbit.connection.RabbitAccessor.convertRabbitAccessException(RabbitAccessor.java:113)
	at org.springframework.amqp.rabbit.core.RabbitTemplate.doExecute(RabbitTemplate.java:1462)
	at org.springframework.amqp.rabbit.core.RabbitTemplate.execute(RabbitTemplate.java:1412)
	at org.springframework.amqp.rabbit.core.RabbitTemplate.execute(RabbitTemplate.java:1388)
	at org.springframework.amqp.rabbit.core.RabbitAdmin.initialize(RabbitAdmin.java:500)
	at org.springframework.amqp.rabbit.core.RabbitAdmin$11.onCreate(RabbitAdmin.java:419)
	at org.springframework.amqp.rabbit.connection.CompositeConnectionListener.onCreate(CompositeConnectionListener.java:33)
	at org.springframework.amqp.rabbit.connection.CachingConnectionFactory.createConnection(CachingConnectionFactory.java:553)
	at org.springframework.amqp.rabbit.connection.ConnectionFactoryUtils$1.createConnection(ConnectionFactoryUtils.java:90)
	at org.springframework.amqp.rabbit.connection.ConnectionFactoryUtils.doGetTransactionalResourceHolder(ConnectionFactoryUtils.java:140)
	at org.springframework.amqp.rabbit.connection.ConnectionFactoryUtils.getTransactionalResourceHolder(ConnectionFactoryUtils.java:76)
	at org.springframework.amqp.rabbit.listener.BlockingQueueConsumer.start(BlockingQueueConsumer.java:496)
	at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer$AsyncMessageProcessingConsumer.run(SimpleMessageListenerContainer.java:1331)
	at java.lang.Thread.run(Thread.java:745)
Caused by: java.io.IOException: null
	at com.rabbitmq.client.impl.AMQChannel.wrap(AMQChannel.java:105)
	at com.rabbitmq.client.impl.AMQChannel.wrap(AMQChannel.java:101)
	at com.rabbitmq.client.impl.AMQChannel.exnWrappingRpc(AMQChannel.java:123)
	at com.rabbitmq.client.impl.ChannelN.queueBind(ChannelN.java:944)
	at com.rabbitmq.client.impl.ChannelN.queueBind(ChannelN.java:60)
	at org.springframework.amqp.rabbit.support.PublisherCallbackChannelImpl.queueBind(PublisherCallbackChannelImpl.java:383)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.springframework.amqp.rabbit.connection.CachingConnectionFactory$CachedChannelInvocationHandler.invoke(CachingConnectionFactory.java:917)
	at com.sun.proxy.$Proxy64.queueBind(Unknown Source)
	at org.springframework.amqp.rabbit.core.RabbitAdmin.declareBindings(RabbitAdmin.java:613)
	at org.springframework.amqp.rabbit.core.RabbitAdmin.access$300(RabbitAdmin.java:66)
	at org.springframework.amqp.rabbit.core.RabbitAdmin$12.doInRabbit(RabbitAdmin.java:505)
	at org.springframework.amqp.rabbit.core.RabbitTemplate.doExecute(RabbitTemplate.java:1456)
	... 12 common frames omitted
Caused by: com.rabbitmq.client.ShutdownSignalException: channel error; protocol method: #method<channel.close>(reply-code=404, reply-text=NOT_FOUND - no exchange 'hsm.in.queue.direct' in vhost '/', class-id=50, method-id=20)
	at com.rabbitmq.utility.ValueOrException.getValue(ValueOrException.java:66)
	at com.rabbitmq.utility.BlockingValueOrException.uninterruptibleGetValue(BlockingValueOrException.java:32)
	at com.rabbitmq.client.impl.AMQChannel$BlockingRpcContinuation.getReply(AMQChannel.java:360)
	at com.rabbitmq.client.impl.AMQChannel.privateRpc(AMQChannel.java:225)
	at com.rabbitmq.client.impl.AMQChannel.exnWrappingRpc(AMQChannel.java:117)
	... 25 common frames omitted
Caused by: com.rabbitmq.client.ShutdownSignalException: channel error; protocol method: #method<channel.close>(reply-code=404, reply-text=NOT_FOUND - no exchange 'hsm.in.queue.direct' in vhost '/', class-id=50, method-id=20)
	at com.rabbitmq.client.impl.ChannelN.asyncShutdown(ChannelN.java:483)
	at com.rabbitmq.client.impl.ChannelN.processAsync(ChannelN.java:320)
	at com.rabbitmq.client.impl.AMQChannel.handleCompleteInboundCommand(AMQChannel.java:143)
	at com.rabbitmq.client.impl.AMQChannel.handleFrame(AMQChannel.java:90)
	at com.rabbitmq.client.impl.AMQConnection$MainLoop.run(AMQConnection.java:559)
	... 1 common frames omitted
2017-07-06 20:41:09.842  INFO 7645 --- [InCUContainer-9] o.s.a.r.l.SimpleMessageListenerContainer : Restarting Consumer: tags=[{}], channel=null, acknowledgeMode=AUTO local queue size=0

Can you please guide me how to trace and resolve the issue. Thank you

RabbitListenerEndpointRegistry.isRunning violates the Lifecycle contract.

Hello,

We are dealing with problem because RabbitListenerEndpointRegistry.isRunning returns true if any of registered MessageListenerContainer is started.

In case when RabbitListenerEndpointRegistry contains started and not started containers then method isRunning returns true and method start is not called, so not started containers don't start.

It's possible to fix this problem.
Thanks,

I found a bug in class RabbitManagementTemplate

Hey guys, I found a bug in class RabbitManagementTemplate, column 194, method deleteExchange(Exchange exchange). This method should call this.rabbitClient.deleteExchange(DEFAULT_VHOST, exchange.getName()) but it does this.rabbitClient.deleteQueue(DEFAULT_VHOST, exchange.getName()). I found it for calling deleteExchange(Exchange exchange) but it did not make any effectiveness.

Unexpected exchange type: headers

Hi!

When I try to bind queue to headers exchange through annotation @RabbitListener -> bindings -> @QueueBinding, I receive exception: Unexpected exchange type: headers

I inspect class RabbitListenerAnnotationBeanPostProcessor and found next code:

if (exchangeType.equals(ExchangeTypes.DIRECT)) {
    exchange = new DirectExchange(exchangeName,
            resolveExpressionAsBoolean(bindingExchange.durable()),
            resolveExpressionAsBoolean(bindingExchange.autoDelete()));
    actualBinding = new Binding(queueName, DestinationType.QUEUE, exchangeName, resolvedKey, null);
}
else if (exchangeType.equals(ExchangeTypes.FANOUT)) {
    exchange = new FanoutExchange(exchangeName,
            resolveExpressionAsBoolean(bindingExchange.durable()),
            resolveExpressionAsBoolean(bindingExchange.autoDelete()));
    actualBinding = new Binding(queueName, DestinationType.QUEUE, exchangeName, "", null);
}
else if (exchangeType.equals(ExchangeTypes.TOPIC)) {
    exchange = new TopicExchange(exchangeName,
            resolveExpressionAsBoolean(bindingExchange.durable()),
            resolveExpressionAsBoolean(bindingExchange.autoDelete()));
    actualBinding = new Binding(queueName, DestinationType.QUEUE, exchangeName, resolvedKey, null);
}
else {
    throw new BeanInitializationException("Unexpected exchange type: " + exchangeType);
}

i.e. binding to headers exchange not supported in annotation @RabbitListener.
Why?

MessagePostProcessor doesn't expose CorrelationData

The Javadoc for CorrelationData.setId says:

One use case, however, is when it needs to be set in a MessagePostProcessor after a CorrelationData with a 'null' correlation id has been passed into a RabbitTemplate.

I have exactly that use case. However, there doesn't appear to be any way for a MessagePostProcessor to actually do this. Presumably there was supposed to be some kind of public CorrelationData postProcessCorrelationData(CorrelationData data, Message message) API?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.