Spring Cloud Contract producer cannot send message - spring

I'm trying to incorporate Spring Cloud Contract into an existing project. I've had some success with REST but I'm struggling to set up the messaging side.
Thus far I've set up a contract on the producer, which does produce a test in target/generated-test-sources/contracts. I've also set up a base class for the test.
I can't get past this error:
2017-09-08 17:10:51.759 ERROR - --[]- [ main] o.s.c.c.v.m.stream.StreamStubMessages : Exception took place while trying to resolve the destination. Will assume the name [invites]
org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.springframework.cloud.stream.config.ChannelBindingServiceProperties' available
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:353)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:340)
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1093)
at org.springframework.cloud.contract.verifier.messaging.stream.StreamStubMessages.resolvedDestination(StreamStubMessages.java:86)
at org.springframework.cloud.contract.verifier.messaging.stream.StreamStubMessages.receive(StreamStubMessages.java:73)
at org.springframework.cloud.contract.verifier.messaging.stream.StreamStubMessages.receive(StreamStubMessages.java:110)
at org.springframework.cloud.contract.verifier.messaging.stream.StreamStubMessages.receive(StreamStubMessages.java:36)
at org.springframework.cloud.contract.verifier.messaging.internal.ContractVerifierMessaging.receive(ContractVerifierMessaging.java:40)
at org.springframework.cloud.contract.verifier.tests.email.MessagingTest.validate_invitedContract(MessagingTest.java:27)
and later
2017-09-08 17:10:51.759 ERROR - --[]- [ main] o.s.c.c.v.m.stream.StreamStubMessages : Exception occurred while trying to read a message from a channel with name [invites]
org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'invites' available
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanDefinition(DefaultListableBeanFactory.java:687)
at org.springframework.beans.factory.support.AbstractBeanFactory.getMergedLocalBeanDefinition(AbstractBeanFactory.java:1207)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:284)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202)
My application.yml file under src/test/resources:
spring:
cloud:
stream:
bindings:
output:
content-type: application/json
destination: invites
I have the following dependencies:
`
<!-- Spring Cloud Contract Deps -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-stream</artifactId>
<version>1.2.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-contract-verifier</artifactId>
<version>1.1.3.RELEASE</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-stream-test-support</artifactId>
<version>1.2.2.RELEASE</version>
<scope>test</scope>
</dependency>
<!-- END SCC Deps -->`
I've combed through the docs, watched Marcin's talk and looked through the samples for Spring Cloud Contract but I'm stuck. Any help would be greatly appreciated.

First issue:
Please use the release train. In the release train, we know that there are no invalid dependencies.
Second issue:
You don't have the #EnableBinding(Source.class) annotation. That's why Stream doesn't know how to bind to the output channel.
If you go to the Spring Cloud Contract samples you'll notice this line on the main application class (https://github.com/spring-cloud-samples/spring-cloud-contract-samples/blob/master/producer/src/main/java/com/example/ProducerApplication.java#L9). After I've added this line to your code, the context started but the tests failed cause the message wasn't sent.

Related

Spring Cloud Kafka Stream Multibinder BeanCreationException: Error creating bean with name 'kafkaStreamsFunctionProcessorInvoker'

I am trying to create a spring boot application using spring cloud kafka stream which reads input from kafka cluster 1 and send it to kafka cluster 2 using single kafkastream application.
I am getting following exception during startup.
***************************
APPLICATION FAILED TO START
***************************
Description:
A component required a bean named 'sessionBrokers-KafkaStreamsBinderConfigurationProperties' that could not be found.
Action:
Consider defining a bean named 'sessionBrokers-KafkaStreamsBinderConfigurationProperties' in your configuration.
My configuration is as below
spring.cloud.function.definition=itemConsumedStream
#Input Configuration
spring.cloud.stream.bindings.itemConsumedStream-in-0.binder=sessionBrokers
spring.cloud.stream.bindings.itemConsumedStream-in-0.destination=${session.event.data.input.topic}
spring.cloud.stream.kafka.bindings.itemConsumedStream-in-0.consumer.configuration.key.deserializer=org.apache.kafka.common.serialization.StringSerializer
spring.cloud.stream.kafka.bindings.itemConsumedStream-in-0.consumer.configuration.value.deserializer=in.custom.JsonNodeDeserializer
#Output Configuration
spring.cloud.stream.bindings.itemConsumedStream-out-0.binder=searchBrokers
spring.cloud.stream.bindings.itemConsumedStream-out-0.destination=${itemConsumed.events.output.topic}
spring.cloud.stream.kafka.bindings.itemConsumedStream-out-0.producer.configuration.key.serializer=org.apache.kafka.common.serialization.StringSerializer
spring.cloud.stream.kafka.bindings.itemConsumedStream-out-0.producer.configuration.value.serializer=in.custom.JsonSerializer
#Input Binder Configurations
spring.cloud.stream.binders.sessionBrokers.type=kafka
spring.cloud.stream.binders.sessionBrokers.environment.spring.cloud.stream.kafka.streams.binder.brokers=${session.event.data.input.kafka.brokers}
#Output Binder Configurations
spring.cloud.stream.binders.searchBrokers.type=kafka
spring.cloud.stream.binders.searchBrokers.environment.spring.cloud.stream.kafka.binder.brokers=${search.kafka.brokers}
pom dependencies are
spring boot version
2.7.1
spring cloud version
2021.0.0
<dependency>
<groupId>org.apache.kafka</groupId>
<artifactId>kafka-streams</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-stream</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-stream-binder-kafka-streams</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-stream-binder-kafka</artifactId>
</dependency>
This is working if I use single binder ie
spring.cloud.stream.kafka.streams.binder.brokers=${session.event.data.input.kafka.brokers}
instead of multiple binders

Spring boot fails to start when add Kubernetes dependencies "The bean 'kubernetesPodUtils', defined in class path resource"

I trying to add Kubernetes to my project to use Service name rather than localhost. I added the below dependencies :
#AutoConfigureAfter
#EnableEurekaClient
#EnableFeignClients
#EnableDiscoveryClient
<!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-kubernetes-client-all -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-kubernetes-client-all</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-kubernetes-config</artifactId>
<version>1.1.10.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-kubernetes</artifactId>
<version>1.1.10.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-kubernetes-discovery</artifactId>
<version>2.1.3</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-kubernetes-core</artifactId>
<version>1.1.10.RELEASE</version>
</dependency>
<!-- MicroServices -->
But I got the below error :
***************************
APPLICATION FAILED TO START
***************************
Description:
The bean 'kubernetesPodUtils', defined in class path resource [org/springframework/cloud/kubernetes/KubernetesAutoConfiguration.class], could not be registered. A bean with that name has already been defined in class path resource [org/springframework/cloud/kubernetes/client/KubernetesClientAutoConfiguration.class] and overriding is disabled.
Action:
Consider renaming one of the beans or enabling overriding by setting spring.main.allow-bean-definition-overriding=true
2022-06-14 12:28:08.696 ERROR 1 --- [ main] o.s.b.d.LoggingFailureAnalysisReporter :
***************************
APPLICATION FAILED TO START
***************************
Description:
The bean 'kubernetesPodUtils', defined in class path resource [org/springframework/cloud/kubernetes/KubernetesAutoConfiguration.class], could not be registered. A bean with that name has already been defined in class path resource [org/springframework/cloud/kubernetes/client/KubernetesClientAutoConfiguration.class] and overriding is disabled.
Action:
Consider renaming one of the beans or enabling overriding by setting spring.main.allow-bean-definition-overriding=true
Looks like KubernetesAutoConfiguration is going to be defined in multiple dependencies. Based on your need, try to identify the dependencies which are required. In your pom file you have spring-cloud-starter-kubernetes-client-all alongwith individual dependecies too.
https://docs.spring.io/spring-cloud-kubernetes/docs/current/reference/html/#starters

Spring cloud stream multi binder - Error KStreamBinderConfiguration required a single bean, but 2 were found

I have a use case where a single kafka stream processing MS will have a processor and a consumer which will consume the processor output message. Similar to below sample in github
https://github.com/spring-cloud/spring-cloud-stream-samples/tree/master/kafka-streams-samples/kafka-streams-message-channel
while executing the above sample I getting following error
***************************
APPLICATION FAILED TO START
***************************
Description:
Parameter 0 of method provisioningProvider in org.springframework.cloud.stream.binder.kafka.streams.KStreamBinderConfiguration required a single bean, but 2 were found:
- kafkaBinderConfigurationProperties: defined by method 'kafkaBinderConfigurationProperties' in org.springframework.cloud.stream.binder.kafka.streams.MutliBinderPropertiesConfiguration
- binderConfigurationProperties: defined by method 'binderConfigurationProperties' in class path resource [org/springframework/cloud/stream/binder/kafka/streams/KafkaStreamsBinderSupportAutoConfiguration.class]
Action:
Consider marking one of the beans as #Primary, updating the consumer to accept multiple beans, or using #Qualifier to identify the bean that should be consumed
This error occurred for me while I was using #SpringBootApplication and #EnableBinding( Processor.class ) outside of the class that was running my project, in conjunction with both of the dependencies below.
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-stream-binder-kafka</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-stream-binder-kafka-streams</artifactId>
</dependency>
Both of these dependencies provide a configuration for provisioningProvider, so to resolve the issue, we must specify which configuration to use.
In your application.yml file, set a default binder to resolve this issue.
spring:
cloud:
stream:
kafka:
binder:
brokers: localhost
defaultBrokerPort: 9092
bindings:
output:
binder: name-of-target-binder
destination: sample-topic
defaultBinder: name-of-target-binder
The documentation here, Section 7.4 Multiple Binders on the Classpath, provides further insight into this issue.
This seems to be some kind of screw-up from the side of Spring Cloud.
This cryptic thread proposed downgrading the dependencies (org.springframework.cloud:spring-cloud-stream-binder-kafka-streams and org.springframework.cloud:spring-cloud-stream for me) from 3.0.1.RELEASE to 3.0.0.RELEASE.
This was indeed the fix for my version of this problem, and I guess it is for you, too.
I had a similar issue, and I fixed it by adding in my pom:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

Testing Neo4j with Spring Boot and embedded driver

Problem
I build an application using a Neo4j database. I like to test some custom Cypher queries using Spring Boot's #DataNeo4jTest annotation (see also Spring Boot Test - Neo4j), but I run in either one of the following problems:
The test tries to connect to a Neo4j instance using the BOLT driver.
The test fails to load the embedded driver.
Details
My dependencies are managed with Maven following the Spring Data Neo4j Reference Documentation. Section 10.3.1 of the SDN documentation explains:
By default, SDN will use the BOLT driver to connect to Neo4j and you don’t need to declare it as a separate dependency in your pom. If you want to use the embedded or HTTP drivers in your production application, you must add the following dependencies as well. (This dependency on the embedded driver is not required if you only want to use the embedded driver for testing. See the section on Testing below for more information).
Therefore, the relevant parts of my pom.xml are:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi=...>
...
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.0.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
...
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-neo4j</artifactId>
</dependency>
<dependency>
<groupId>org.neo4j.test</groupId>
<artifactId>neo4j-harness</artifactId>
<version>3.3.4</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
...
</project>
My main/resources/application.yml is:
spring:
data:
neo4j:
uri: bolt://localhost
username: <username>
password: <password>
My test/resources/application.yml is:
spring.data.neo4j.uri: file:///neo4j.db
Without the test/resources/application.yml I get the following exception, which I assume is caused by using the BOLT driver:
org.springframework.transaction.CannotCreateTransactionException: Could not open Neo4j Session for transaction;
nested exception is org.neo4j.driver.v1.exceptions.AuthenticationException: The client is unauthorized due to authentication failure.
With the test/resources/application.yml I get the following exception:
java.lang.IllegalStateException: Failed to load ApplicationContext
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'neo4jAuditionBeanFactoryPostProcessor': Unsatisfied dependency expressed through constructor parameter 0;
nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sessionFactory' defined in class path resource [org/springframework/boot/autoconfigure/data/neo4j/Neo4jDataAutoConfiguration.class]: Bean instantiation via factory method failed;
nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.neo4j.ogm.session.SessionFactory]: Factory method 'sessionFactory' threw exception;
nested exception is org.neo4j.ogm.exception.core.ConfigurationException: Could not load driver class org.neo4j.ogm.drivers.embedded.driver.EmbeddedDriver
Questions
Are there any dependencies missing?
Is the configuration wrong?
Does anyone have a link to a working example using the Spring Boot annotation #DataNeo4jTest?
Any suggestion is welcome.
I have found a solution to my problem. It seems as if the BOLT driver is used as default for testing as well - which is confusing given the Spring Data Neo4j (SDN) documentation. Finally, the pom.xml of the GitHub project movies-java-spring-data-neo4j helped me. I added the following test dependency to my pom.xml:
<dependency>
<groupId>org.neo4j</groupId>
<artifactId>neo4j-ogm-embedded-driver</artifactId>
<version>${neo4j-ogm.version}</version>
<scope>test</scope>
</dependency>
I kept the test/resources/application.yml but removed the line:
spring.data.neo4j.uri: file:///neo4j.db
Now, the test context starts with the embedded driver, and creates a temporary database file like file:/C:/Users/Me/AppData/Local/Temp/neo4j.db6943517458205762238/, which is awesome. I can get a clean database instance for every test method.
I hope this answer will help others, who have the same problem. I'm happy to provide more details if necessary.
#DataNeo4JTest works great with Spring Boot 2.x.
Example Test:
#RunWith(SpringRunner.class)
#DataNeo4jTest
public class WidgetRepositoryTest {
#Autowired
private WidgetRepository repository;
private Widget widget;
#Before
public void setUp() {
widget = WidgetTestData.builder().build();
}
#Test
public void itShouldSaveAndRetrieve() {
final Widget saved = repository.save(widget);
assertThat(saved.getId()).isNotNull();
assertThat(saved.getName()).isEqualTo(widget.getName());
final Optional<Widget> found = repository.findById(saved.getId());
assertThat(found).hasValueSatisfying(w-> {
assertThat(w.getId()).isEqualTo(saved.getId());
assertThat(w.getName()).isEqualTo(saved.getName());
});
}
}
The Neo4J-related dependencies in my Maven POM:
<dependency>
<groupId>org.neo4j.test</groupId>
<artifactId>neo4j-harness</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.neo4j</groupId>
<artifactId>neo4j-ogm-embedded-driver</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-neo4j</artifactId>
</dependency>

Spring boot failing to start with Spring Cloud AWS Core dependency

I am writing a spring boot app that accesses stuff from an s3 bucket, but I get a NoClassDefFoundError when I use the starter spring-cloud-starter-aws dependency from the spring initializer.
Am I missing some other dependency here?
Below are my dependencies.
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-aws</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-cassandra</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-integration</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
I also defined the dependencyManagement block for spring-cloud-dependencies and use Edgware.SR1 as my spring-cloud-version.
My app fails with the following error when starting up.
2018-01-24 12:20:25.642 INFO 1980 --- [ main] utoConfigurationReportLoggingInitializer :
Error starting ApplicationContext. To display the auto-configuration report re-run your application with 'debug' enabled.
2018-01-24 12:20:25.666 ERROR 1980 --- [ main] o.s.boot.SpringApplication : Application startup failed
org.springframework.beans.factory.BeanDefinitionStoreException: Failed to process import candidates for configuration class [com.art.productattribution.consumerintegration.ConsumerIntegrationApplication]; nested exception is java.lang.NoClassDefFoundError: com/amazonaws/AmazonClientException
at org.springframework.context.annotation.ConfigurationClassParser.processImports(ConfigurationClassParser.java:616) ~[spring-context-4.3.13.RELEASE.jar:4.3.13.RELEASE]
Not sure what am I missing here? Please let me know if you need any more details with this. The version of spring boot I am using is 1.5.9.RELEASE
The correct dependency is the spring-cloud-aws-context. Add the following in your pom file (version 1.2.2 as of Nov 22, 2017):
<!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-aws-context -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-aws-context</artifactId>
<version>1.2.2.RELEASE</version>
</dependency>
Below are the Spring Cloud AWS modules:
Spring Cloud AWS Core is the core module of Spring Cloud AWS providing basic services for security and configuration setup. Developers will not use this module directly but rather through other modules. The core module provides support for cloud based environment configurations providing direct access to the instance based EC2 metadata and the overall application stack specific CloudFormation metadata.
Spring Cloud AWS Context delivers access to the Simple Storage Service via the Spring resource loader abstraction. Moreover developers can send e-mails using the Simple E-Mail Service and the Spring mail abstraction. Further the developers can introduce declarative caching using the Spring caching support and the ElastiCache caching service.
Spring Cloud AWS JDBC provides automatic datasource lookup and configuration for the Relational Database Service which can be used with JDBC or any other support data access technology by Spring.
Spring Cloud AWS Messaging enables developers to receive and send messages with the Simple Queueing Service for point-to-point communication. Publish-subscribe messaging is supported with the integration of the Simple Notification Service.
Ref: http://cloud.spring.io/spring-cloud-aws/spring-cloud-aws.html#_using_amazon_web_services
It seems com.amazonaws.AmazonClientException is not found in the classpath. I think you can add the following dependency in your POM.xml file to solve this issue.
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-aws-core</artifactId>
<version>1.2.2.RELEASE</version>
</dependency>
You need to include dependency mentioned by #alltej. Also you need to add below property in application.properties file if you are running on local.
cloud.aws.stack.auto=false

Resources