Spring Solr connection with Zookeeper using jaas.conf - spring-boot

I am migrating an existing java project to Spring Boot. It connects to Solr via Zookeeper.
It is throwing following error on startup.
org.apache.zookeeper.KeeperException$NoAuthException: KeeperErrorCode = NoAuth for /clusterstate.json
This following configuration works on local, but on other environments Zookeeper requires some authentication (jaas.conf). How do I pass the jaas.conf to Spring Boot such that it can initialize SolrClient correctly?
#Configuration
#EnableSolrRepositories(basePackages = "com.search", multicoreSupport = true)
public class SolrConfig {
#Value("${spring.data.solr.zk-host}")
private String zkHost;
#Bean
public SolrClient solrClient() {
return new CloudSolrClient(zkHost);
}
#Bean
public SolrTemplate solrTemplate(SolrClient solrClient) throws Exception {
return new SolrTemplate(solrClient);
}
}
jaas.conf
Client {
org.apache.zookeeper.server.auth.DigestLoginModule required
username="some_username"
password="some_password";
};
I tried passing credentials as environment properties of zkDigestUsername and zkDigestPassword. In this case there was no exception during Spring Boot startup, but subsequent inserts/reads to Solr is not working.
Any help would be appreciated. Thanks much!

I was able to fix the issue by providing jaas config using the following JVM parameter.
-Djava.security.auth.login.config=/etc/zookeeper/conf/jaas.conf

Related

Programmatic RedissonClient in Spring boot project

I am trying to implement Hibernate second level caching in a Spring boot project using Redisson.
I have followed this blog as a reference
https://pavankjadda.medium.com/implement-hibernate-2nd-level-cache-with-redis-spring-boot-and-spring-data-jpa-7cdbf5632883
Also i am trying to initialize the RedissionClient programmatically and not through declaratively /through a config file
Created a spring bean to be initialized which should create the RedissonClient instance.
#Configuration
#Lazy(value = false)
public class RedissonConfig {
#Bean
public RedissonClient redissionClient() {
Config config = new Config();
config.useSingleServer().setAddress("redis://127.0.0.1:6379");
return Redisson.create(config);
}
}
However this bean is never intialized and i get the following error while application startup.
Caused by: org.hibernate.cache.CacheException: Unable to locate Redisson configuration
at org.redisson.hibernate.RedissonRegionFactory.createRedissonClient(RedissonRegionFactory.java:107) ~[redisson-hibernate-53-3.12.1.jar:3.12.1]
at org.redisson.hibernate.RedissonRegionFactory.prepareForUse(RedissonRegionFactory.java:83) ~[redisson-hibernate-53-3.12.1.jar:3.12.1]
It seems Spring boot Hibernate still trying to load the Redisson config through a config file.
is it possible to load the Redission config in spring boot programmatically ?
Best Regards,
Saurav
I just did exactly this, here is how:
you need a custom RegionFactory that is similar to the JndiRedissonRegionFactory but gets its RedissonClient injected somehow.
an instance of this Class, fully configured, is put into the hibernate-properties map. Hibernates internal code is flexible: if the value of hibernate.cache.region.factory_class is a string it is treated as a FQDN. If it is an instance of Class<?>, it will be instantiated. If it is an Object, it will be used.
Spring offers a rather simple way to customize hibernate properties with a bean:
#AutoConfiguration(after = RedissonAutoConfiguration.class, before = JpaAutoConfiguration.class)
#ConditionalOnProperty("spring.jpa.properties.hibernate.cache.use_second_level_cache")
public class HibernateCacheAutoConfiguration {
#Bean
public HibernatePropertiesCustomizer setRegionFactory(RedissonClient redisson) {
return hibernateProperties -> hibernateProperties.put(AvailableSettings.CACHE_REGION_FACTORY, new SpringBootRedissonRegionFactory(redisson));
}
}
My RegionFactory is really simple:
#AllArgsConstructor
public class SpringBootRedissonRegionFactory extends RedissonRegionFactory {
private RedissonClient redissonClient;
#Override
protected RedissonClient createRedissonClient(Map properties) {
return redissonClient;
}
#Override
protected void releaseFromUse() {
}
}
I used the redisson-starter to get a RedissonClient, hence the reference to RedissonAutoConfiguration, but you could just create an instance by hand.
It is possible, but then you need to provide a custom implementation of RegionFactory to Hibernate, which can extends RedissonRegionFactory but uses your own client instance.

How to config max-delivery-attempts for Spring Boot with Embedded ActiveMQ Artemis?

I would like to config the max-delivery-attempts of dead letter as described in the manual.
I tried Spring Boot with embedded ActiveMQ Artemis JMS server, but cannot figure out how to set max-delivery-attempts value.
After debugging the Configuration instance I finally find the method. Here's the code:
#Configuration
public class RedeliveryConfiguration implements ArtemisConfigurationCustomizer {
#Override
public void customize(org.apache.activemq.artemis.core.config.Configuration configuration) {
Map<String, AddressSettings> addressesSettings = configuration.getAddressesSettings();
// # is the catch all address or default address
addressesSettings.get("#").setMaxDeliveryAttempts(2);
}
}

Spring Cloud Config Client connecting to RabbitMQ

I have been trying to set up a Spring Cloud Config Server/Client. I have been following a few different examples (1, 2). I have the client and server set up correctly and can successfully query localhost:8888/localhost:8080 to see the values in JSON format.
My question is whether Spring Boot will automatically detect these properties provided by Spring Cloud Config Server. For now I am just attempting to connect to a RabbitMQ instance on startup but have had no success despite not having any errors. It does not connect to Rabbit or create the queues/exchanges.
It works when I have an application.properties file locally with the following properties but I wish to get these setting through Spring Cloud Config from a GitHub repository.
spring.rabbitmq.host=178.61.47.---
spring.rabbitmq.port=5672
spring.rabbitmq.username=mqtt
spring.rabbitmq.password=mqtt
I have looked through the questions here/issues on GitHub but can't see anything relating to this.
Code for client class is below:
#EnableAutoConfiguration
#ComponentScan
#SpringBootApplication
public class ConfigRabbitApplication {
final static String queueName = "arduino-weather-queue";
#Autowired
RabbitTemplate rabbitTemplate;
#Bean
Queue queue() {
return new Queue(queueName, true);
}
#Bean
Binding binding(Queue queue, TopicExchange exchange) {
return BindingBuilder.bind(queue).to(exchange).with("arduino-weather");
}
#Bean
TopicExchange exchange() {
return new TopicExchange("arduino-iot-exchange", true, false);
}
public static void main(String[] args) {
SpringApplication.run(ConfigRabbitApplication.class, args);
}
}
No, spring boot client is not aware that you want to fetch configuration from config-server. That is probably loaded when specific class in on a classpath, thats why you have to add org.springframework.cloud:spring-cloud-starter-config dependency. Its well described here: http://cloud.spring.io/spring-cloud-config/spring-cloud-config.html#_client_side_usage
In case config-server is not on localhost:8888 you will also have to add:
spring.cloud.config.uri: http://myconfigserver.com
to your bootstrap.yml file ( its same as application.yml, just loaded earlier ).

spring boot multiple mongodb datasource

We are using spring boot and we have multiple mongodbs within the system. We are able to configure "one" mongodb in application.properties files, as per the spring boot documents. Now we have a need to write to multiple mongodbs. How can we configure this?
Hope someone can help and any code examples would be helpful.
Thanks
GM
Use multiple #Bean methods, where you create and configure your datasources, and specify the bean name to distinguish them.
Example:
#Bean("primary")
public Mongo primaryMongo() throws UnknownHostException {
Mongo mongo = new Mongo();
// configure the client ...
return mongo;
}
#Bean("secondary")
public Mongo secondaryMongo() throws UnknownHostException {
Mongo mongo = new Mongo();
// configure the client ...
return mongo;
}
When you want to access the datasource, use the #Qualifier annotation on the field to specify the datasource with the bean name:
#Autowired
#Qualifier("primary")
private Mongo mongo;

connect mongohq or mongolab using spring framework

i try to connect to mongohq using spring. i got some information from heroku but while connecting with that code MongoURI class are deprecated .
I used spring-data-mongodb version 1.2.0.RELEASE. and mongo-java-driver - 2.11.0
can any one tell how to connect to mongohq or mongolab using spring
Hear is the code..
#Configuration
public class SpringConfig {
#Bean
public DB getDb() throws UnknownHostException, MongoException {
String uri="mongodb://user:password#id.mongolab.com:53178/db";
MongoClientURI mongoClientURI=new MongoClientURI(uri);
MongoClient mongoClient=new MongoClient(mongoClientURI);
DB db=mongoClient.getDB(mongoClientURI.getDatabase());
db.authenticate(mongoClientURI.getUsername(),mongoClientURI.getPassword());
return db;
}
}
As you can read in the MongoURI documentation
public class MongoURI
extends Object
Represents a URI which can be used to create a Mongo instance. The URI describes the hosts to be used and options.
This class has been superseded by MongoClientURI, and may be deprecated in a future release.
So MongoClientURI is your answer
If you use mongodb with Spring Data Mongodb you can use a configuration as described in http://docs.spring.io/spring-data/data-mongo/docs/1.4.1.RELEASE/reference/html/mongo.core.html#mongo.mongo-db-factory-java
It will finally look like :
#Configuration
public class MongoHQConfiguration {
public #Bean MongoDbFactory mongoDbFactory() throws MongoException, UnknownHostException {
return new SimpleMongoDbFactory(new MongoURI(System.getenv("MONGOHQ_URL")));
}
public #Bean MongoTemplate mongoTemplate() throws Exception {
return new MongoTemplate(mongoDbFactory());
}
}
If you are using Spring Boot, the class "MongoProperties" is just waiting for an external configuration:
With "heroku config" you can see properties already defined - there will be a "MONGOLAB_URI" if MongoLab was added to your application.
Just define: heroku config:set spring.data.mongodb.uri=< MONGOLAB_URI >. Done.

Resources