All Projects → 4finance → Micro Infra Spring

4finance / Micro Infra Spring

Licence: apache-2.0
Repository containing default microservice infrastructure set up using Spring configuration

Programming Languages

groovy
2714 projects

Build Status Coverage Status Download Stack Overflow Gitter

micro-infra-spring

Sets up the whole Spring infrastructure stack that will turn your microservice into a beauty.

Check out the wiki to have a deeper insight into the project.

Versioning

Currently we have two lines of versions.

Version greater than 2.0.0

This version is in the "master" branch and it contains micro-infra-spring integrated with Spring Cloud. We want to tightly couple micro-infra-spring with Spring Cloud thus this branch will be developed. All the new features will be also developed for this branch.

This version is backwards compatible - you can use both the old (microservice.json) and the new (Spring Cloud Zookeeper approach). To enable the new approach you have to provide the springCloud profile.

Versions smaller than 2.0.0

All versions smaller than 2.0.0 are related to the micro-infra-spring version that does not contain Spring Cloud integration (other than the micro-infra-config module). The code containing that version is present in the "legacy" branch. This branch in general will not be maintained. If someone wants a feature to be present here he first needs to develop it in the "master" branch and then backport it to the "legacy" branch. The "legacy" branch in general will not be maintained if it won't be essential.

TROUBLESHOOTING SPRING CLOUD INTEGRATION

Check boot-microservice for an example of a working application

Check spring-cloud-zookeeper documentation on how to register your application with properties in Zookeeper

My application doesn't seem to use SpringCloud capabilities

Ensure that you have ALSO passed the springCloud profile. For example:

./gradlew bootRun -Dspring.profiles.active=prod,springCloud -DAPP_ENV=prod -DCONFIG_FOLDER=/properties -Dserver.port=9090 -Dspring.application.name=foo

Wrong version of spring boot

Issue

You may find issues like NoClassDefFoundError or ArrayStoreException. That most likely means that you have different versions of Spring on your classpath.

Example of an exception:

Exception in thread "main" java.lang.NoClassDefFoundError: org/springframework/boot/context/config/ConfigFileEnvironmentPostProcessor
	at org.springframework.cloud.config.server.NativeEnvironmentRepository.findOne(NativeEnvironmentRepository.java:99)
	at com.ofg.infrastructure.property.FileSystemLocator.locate(FileSystemLocator.java:41)
	at org.springframework.cloud.bootstrap.config.PropertySourceBootstrapConfiguration.initialize(PropertySourceBootstrapConfiguration.java:80)
	at org.springframework.boot.SpringApplication.applyInitializers(SpringApplication.java:567)
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:303)
	at pl.uservices.dojrzewatr.Application.main(Application.java:18)
Caused by: java.lang.ClassNotFoundException: org.springframework.boot.context.config.ConfigFileEnvironmentPostProcessor
	at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
	at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
	... 6 more

Workaround

Enforce Spring and Spring Boot library versions

configurations {
    all {
        resolutionStrategy {
            eachDependency { DependencyResolveDetails details ->
                if (details.requested.group == 'org.springframework.boot') { details.useVersion '1.3.0.RC1' }
                if (details.requested.group == 'org.springframework') { details.useVersion '4.2.2.RELEASE' }
            }
        }
    }
}

ClientHttpRequestFactory duplicated beans

Issue

With Ribbon coming in you have another ClientHttpRequestFactory. If you autowire one in your codebase you'll get the following exception:

Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: org.springframework.http.client.ClientHttpRequestFactory pl.uservices.dojrzewatr.brewing.BrewConfiguration.clientHttpRequestFactory; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [org.springframework.http.client.ClientHttpRequestFactory] is defined: expected single matching bean but found 2: requestFactory,ribbonClientHttpRequestFactory
	at org.springrk.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:571) ~[spring-beans-4.2.2.RELEASE.jar:4.2.2.RELEASE]
	at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88) ~[spring-beans-4.2.2.RELEASE.jar:4.2.2.RELEASE]
	at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:331) ~[spring-beans-4.2.2.RELEASE.jar:4.2.2.RELEASE]
	... 38 common frames omitted
Caused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [org.springframework.http.client.ClientHttpRequestFactory] is defined: expected single matching bean but found 2: requestFactory,ribbonClientHttpRequestFactory
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1126) ~[spring-beans-4.2.2.RELEASE.jar:4.2.2.RELEASE]
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1014) ~[spring-beans-4.2.2.RELEASE.jar:4.2.2.RELEASE]
	at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:543) ~[spring-beans-4.2.2.RELEASE.jar:4.2.2.RELEASE]
	... 40 common frames omitted

Workaround

Pass the @Qualifier("requestFactory") to get one from micro-infra

@Autowired @Qualifier("requestFactory") ClientHttpRequestFactory clientHttpRequestFactory;

ServiceConfigurationResolver missing

Issue

If you're using springCloud profile you might get the following exception

Unsatisfied dependency expressed through ... of type [com.ofg.infrastructure.discovery.ServiceConfigurationResolver]: : 
No qualifying bean of type [com.ofg.infrastructure.discovery.ServiceConfigurationResolver] found for dependency: 
expected at least 1 bean which qualifies as autowire candidate for this dependency. 
Dependency annotations: {}; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: 
No qualifying bean of type [com.ofg.infrastructure.discovery.ServiceConfigurationResolver] found for dependency: 
expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}

Workaround:

You have legacy code that requires JSON representation whereas right now you have to use the ZookeeperDependencies class. Together with ZookeeperDiscoveryProperties to retrieve the realm.

I want to use the old functionality of micro-infra but it blows up with Spring Cloud stuff

Ensure that you have a bootstrap.yaml file on your classpath that deregisters everything related to Spring Cloud. For example:

spring.cloud.zookeeper.enabled: false
spring.cloud.zookeeper.discovery.enabled: false
ribbon.zookeeper.enabled: false
spring.autoconfigure.exclude: org.springframework.cloud.client.loadbalancer.LoadBalancerAutoConfiguration

Trying to connect to Zipkin

You might have such an exception when trying to boot up the application:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'spanCollector' defined in class path resource [org/springframework/cloud/sleuth/zipkin/ZipkinAutoConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.github.kristofa.brave.zipkin.ZipkinSpanCollector]: Factory method 'spanCollector' threw exception; nested exception is java.lang.IllegalStateException: org.apache.thrift.transport.TTransportException: java.net.ConnectException: Connection refused

That means that your application is trying to connect to Zipkin server and fails to do so. This will happen when you start your app in prod profile.

Workaround

There are two approaches:

  • set spring.zipkin.enabled to false in bootstrap.yaml
  • set APP_ENV to a value that contains test or stage or rbt

Rationale:

We want to connect to Zipkin only if one has the production profile turned on and he has deployed his application to the production environment. One can override this functionality by setting the tracing.properties.enabled to false. Check out com.ofg.infrastructure.tracing.TracingPropertiesEnabler for more infromation.

Your .yaml properties file is not taken into account

You might find out that your .yaml file doesn't override .properties files. This is caused by way spring-boot is processing directories when looking for properties. For now there is no solution for this issue.

Missing org.springframework.web.client.RestTemplate

If you getting

NoSuchBeanDefinitionException: No qualifying bean of type [org.springframework.web.client.RestTemplate]

That means that you don't have any RestTemplate instance in your context

Workaround

Add to your bootstrap.properites/.yml file this line:

spring.cloud.zookeeper.dependency.resttemplate.enabled: false
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].