Created RestHighLevelClient for Elasticsearch won't use SSL - spring-boot

I am trying to connect to an existing Elasticsearch instance. The instance is set up and working fine, which I can confirm by accessing it through the browser under https://localhost:9200. I am using Spring Data Elasticsearch version 4.1.2 and I am following the official instructions from https://docs.spring.io/spring-data/elasticsearch/docs/current/reference/html/#elasticsearch.clients.rest.
Unfortunately, when starting the application, the initial health checks of the elasticsearch instance fail, because the code is trying to use http instead of https:
o.s.w.r.f.client.ExchangeFunctions : [377e90b0] HTTP HEAD http://localhost:9200/
Therefore I added the ".usingSsl()" to the ClientConfiguration, but it does not seem to have any effect and I just don't understand why. The "funny" thing is, if I implement the reactive client as described here (https://docs.spring.io/spring-data/elasticsearch/docs/current/reference/html/#elasticsearch.clients.reactive), https suddenly works and the applications starts perfectly fine. However, I want to use the regular high level client.
Can you help me change the configuration in a way so that it finally makes use of https instead of http?
#Configuration
class ElasticsearchClientConfig: AbstractElasticsearchConfiguration() {
#Bean
override fun elasticsearchClient(): RestHighLevelClient {
val clientConfiguration = ClientConfiguration.builder()
.connectedTo("localhost:9200")
.usingSsl()
.build();
return RestClients.create(clientConfiguration).rest();
}
}

Related

Setting couchbase query timeout doesn't works

I am trying to customize the timeout settings for my couchbase Spring Boot client. I am using spring-boot-starter-data-couchbase in my project. Specifically what I want to do is, when it's taking too long for the couchbase to respond(may be say because of some network partition or any other reason). I just want to send some default response to my client. I followed this answer and am also using AbstractCouchbaseConfiguration to configure the timeout but it is just not working.
Below is the overridden method from my configuration class.
#Override
protected CouchbaseEnvironment getEnvironment() {
DefaultCouchbaseEnvironment.builder()
.connectTimeout(TimeUnit.SECONDS.toMillis(2))
.maxRequestLifetime(TimeUnit.SECONDS.toMillis(2))
.socketConnectTimeout(1000).queryTimeout(TimeUnit.SECONDS.toMillis(2));
return super.getEnvironment();
}
Can someone please help me with this?

ElasticsearchJestHealthIndicator : Health check failed when using Jest in spring boot

I'm using Jest at enter link description here in my spring boot application.
Then I created the client with the example code :
JestClientFactory factory = new JestClientFactory();
factory.setHttpClientConfig(new HttpClientConfig
.Builder("http://myhost:9200")
.multiThreaded(true)
JestClient client = factory.getObject();
Everything is fine. I can use this client to do all the queries I want. Happy till now.
Then the problem, when the application starts up, ElasticsearchJestHealthIndicator class is auto-initialized. But the problem is I don't know where to set the config that it will need, so it uses the default value as http://localhost:9200, which leads me to this problem:
WARN [on(2)-127.0.0.1] s.b.a.h.ElasticsearchJestHealthIndicator : Health check failed
io.searchbox.client.config.exception.CouldNotConnectException: Could not connect to http://localhost:9200
at io.searchbox.client.http.JestHttpClient.execute(JestHttpClient.java:70)
at io.searchbox.client.http.JestHttpClient.execute(JestHttpClient.java:60)
Can someone show me how to properly config it , or turn it off ?
A quick search in the reference documentation shows that Spring Boot will configure for you a JestClient (you can just inject it anywhere you need), and that the following configuration properties apply:
spring.elasticsearch.jest.uris=http://search.example.com:9200
spring.elasticsearch.jest.read-timeout=10000
spring.elasticsearch.jest.username=user
spring.elasticsearch.jest.password=secret
See here for more on this.
The Jest client has been deprecated as well, since both Elasticsearch and Spring Data Elasticsearch provide official support for REST clients.
See https://docs.spring.io/spring-boot/docs/current/reference/html/spring-boot-features.html#boot-features-elasticsearch

Routing - Spring Boot Web App & AWS Application Load Balancer

I have a Spring Boot web app with the usual routings:
#GetMapping("/account")
public String search(#RequestParam(value="search"...
I've now deployed this behind an AWS Application Load Balancer, where I have used path based routing to target my app.
I've configured /admin/* on the Load Balancer to forward to my app, which works fine.
The issue though is that my app is now seeing /admin/account, rather than the /account it is expecting.
AWS says:
Note that the path pattern is used to route requests but does not
alter them. For example, if a rule has a path pattern of /img/*, the
rule would forward a request for /img/picture.jpg to the specified
target group as a request for /img/picture.jpg.
Is there any tidy way around this? Or do I have to resort to something like this:
#GetMapping("*/account")
I don't think that functionality exists in AWS Applicxation loadbalancer -- check this out stackoverflow.com/questions/39317685
Quoting the relevant part here
you can use a reverse proxy on your server and do something like this
(this is Nginx configuration):
server {
listen 80 default_server;
location /secured/ {
proxy_pass http://localhost:{service_port}/;
}
}
This will strip the /admin part and proxy everything else to your
service. Just be sure to have the trailing / after the service port.
The only thing I can think of doing (besides web server url rewrites or a reverse proxy like Zuul) is to do the url rewrites within your app.
An easy way to do that is using UrlRewriteFilter
#Bean
public FilterRegistrationBean urlRewriteFilter() {
FilterRegistrationBean filterRegistration = new FilterRegistrationBean();
filterRegistration.setFilter(new UrlRewriteFilter());
// You probably want to set the order very low so it fires before
// other filters, especially if you're using Spring Security
filterRegistration.setOrder(Integer.MIN_VALUE);
filterRegistration.setUrlPatterns(Collections.singletonList("/*"));
Map<String, String> initParams = new HashMap<>();
initParams.put("confPath", "url_rewrite.xml");
filterRegistration.setInitParameters(initParams);
return filterRegistration;
}
The maven coordinates for the filter:
<dependency>
<groupId>org.tuckey</groupId>
<artifactId>urlrewritefilter</artifactId>
<version>4.0.3</version>
</dependency>
A configuration file example can be found here: http://cdn.rawgit.com/paultuckey/urlrewritefilter/master/src/doc/manual/4.0/urlrewrite.xml

How to configure Spring Boot with elasticsearch 5.2.1?

I am trying to connect my Spring Boot application to local elasticsearch 5.2.1 instance. When i use "org.springframework.boot:spring-boot-starter-data-elasticsearch" dependency, i face with "Received message from unsupported version: [2.0.0] minimal compatible version is: [5.0.0]". I think this is due to elasticsearch version is 2.4.4 in starter dependency. So to solve this error, i edit pom.xml properties by adding elasticsearch.version>5.2.1/elasticsearch.version> line. But this time i get
"java.lang.NoSuchMethodError: org.elasticsearch.client.transport.TransportClient.builder()"
To overcome this issue, i create custom config class like below:
#Configuration
public class ElasticsearchConfiguration {
#Bean
public Client client() throws UnknownHostException {
TransportClient client = new PreBuiltTransportClient(Settings.EMPTY)
.addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("localhost"), 9300));
return client;
}
#Bean
public ElasticsearchTemplate elasticsearchTemplate() throws UnknownHostException {
return new ElasticsearchTemplate(client());
}
}
This time i get apache.logging.log4j exceptions (check here) so i add necessary dependencies.
Finally i get below error and stucked there. Could anyone help me out with this?
nested exception is java.lang.NoClassDefFoundError:org/elasticsearch/action/count/CountRequestBuilder
The github page of spring-data-elasticsearch shows that it currently supports elasticsearch only up to version 2.4.0.
For now you have 3 options:
Wait and hope
checkout the pull request
checkout the dev branch 5.0.x-prep
You need to use Spring Boot 2. Check out my spring-boot-elasticsearch-5.x example.
You can use elasticsearch java api to create transport client instead of using spring-data-elasticsearch.
I tried the same and getting that error too for CountRequestBuilder, reason is that CountRequestBuilder class is deprecated and removed now from 5.x elastic search versions, that class is replaced by SearchRequestBuilder but unfortunately spring-data-elasticsearch don't provide this even in the latest release of its jar and that CountRequestBuilder is used in ElasticSearchTemplate.
I am also looking out for some solution. I will post if able to resolve.

How do I configure reactor-netty to use SSL?

I am trying to get familiar with Spring's Project Reactor (https://projectreactor.io/) and have built a small application to make REST calls to another service over SSL. I cannot find any way to configure the org.springframework.web.client.reactive.WebClient to make requests over SSL. There seems to be no documentation about this. I am using reactor-core 3.0.0.RC1 and reactor-netty 0.5.0.M3, and Spring Framework 5.0.0.M1. Does anyone know how to configure reactor-netty with SSL support?
Update 2017-01-04:
This was corrected in the 5.0.0.M4 release of Spring Framework with this patch.
Original Answer:
I discovered that the solution is to create a new ClientHttpConnector implementation that respects SSL.
public class ReactorClientHttpsAwareConnector implements ClientHttpConnector {
#Override
public Mono<ClientHttpResponse> connect(HttpMethod method, URI uri,
Function<? super ClientHttpRequest, Mono<Void>> requestCallback) {
return reactor.ipc.netty.http.HttpClient.create()
.request(io.netty.handler.codec.http.HttpMethod.valueOf(method.name()),
uri.toString(),
httpClientRequest -> requestCallback
.apply(new ReactorClientHttpRequest(method, uri, httpClientRequest)))
.cast(HttpInbound.class)
.otherwise(HttpException.class, exc -> Mono.just(exc.getChannel()))
.map(ReactorClientHttpResponse::new);
}
}
HttpClient.create() is required to make the client SSL-aware.

Resources