ConnectionClosedException while using Elastic RestHighLevelClient bulk request - elasticsearch

I am using the following code for RestHighLevelClient in Elastic Search.
val credentialsProvider = new BasicCredentialsProvider
credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(conf.value.getString("elkUserName"), conf.value.getString("elkPassword")))
val builder = RestClient.builder(new HttpHost(conf.value.getString("elkIp"), Integer.valueOf(conf.value.getString("elkPort"))))
.setRequestConfigCallback(new RestClientBuilder.RequestConfigCallback() {
//set timeout
override def customizeRequestConfig(requestConfigBuilder: RequestConfig.Builder): RequestConfig.Builder = requestConfigBuilder.setConnectTimeout(Integer.valueOf(conf.value.getString("elkWriteTimeOut"))).setSocketTimeout(Integer.valueOf(conf.value.getString("elkWriteTimeOut")))
}).setHttpClientConfigCallback(new HttpClientConfigCallback() {
override def customizeHttpClient(httpClientBuilder: HttpAsyncClientBuilder): HttpAsyncClientBuilder = {
httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider)
}
})
client = new RestHighLevelClient(builder)
val requestBuilder = RequestOptions.DEFAULT.toBuilder
requestBuilder.setHttpAsyncResponseConsumerFactory(
new HttpAsyncResponseConsumerFactory.HeapBufferedResponseConsumerFactory(1024 * 1024 * 1024))
var request = new BulkRequest()
request.setRefreshPolicy("wait_for")
var sizeOfRequest = 1 L
newListOfMap.foreach {
vals =>
val newMap = vals.asJava
request.add(new IndexRequest(indexName).source(newMap))
}
client.bulk(request, requestBuilder.build)
But I am getting the following Exception
java.lang.NoSuchMethodError:
org.apache.http.ConnectionClosedException: method <init>()V not found
at org.apache.http.nio.protocol.HttpAsyncRequestExecutor.endOfInput(HttpAsyncRequestExecutor.java:356)
at org.apache.http.impl.nio.DefaultNHttpClientConnection.consumeInput(DefaultNHttpClientConnection.java:261)
at org.apache.http.impl.nio.client.InternalIODispatch.onInputReady(InternalIODispatch.java:81)
at org.apache.http.impl.nio.client.InternalIODispatch.onInputReady(InternalIODispatch.java:39)
at org.apache.http.impl.nio.reactor.AbstractIODispatch.inputReady(AbstractIODispatch.java:114)
at org.apache.http.impl.nio.reactor.BaseIOReactor.readable(BaseIOReactor.java:162)
at org.apache.http.impl.nio.reactor.AbstractIOReactor.processEvent(AbstractIOReactor.java:337)
at org.apache.http.impl.nio.reactor.AbstractIOReactor.processEvents(AbstractIOReactor.java:315)
at org.apache.http.impl.nio.reactor.AbstractIOReactor.execute(AbstractIOReactor.java:276)
at org.apache.http.impl.nio.reactor.BaseIOReactor.execute(BaseIOReactor.java:104)
at org.apache.http.impl.nio.reactor.AbstractMultiworkerIOReactor$Worker.run(AbstractMultiworkerIOReactor.java:591)
at java.lang.Thread.run(Thread.java:748)
org.apache.http.ConnectionClosedException: Connection closed
unexpectedly at org.elasticsearch.client.RestClient.extractAndWrapCause(RestClient.java:778)
at org.elasticsearch.client.RestClient.performRequest(RestClient.java:218)
at org.elasticsearch.client.RestClient.performRequest(RestClient.java:205)
at org.elasticsearch.client.RestHighLevelClient.internalPerformRequest(RestHighLevelClient.java:1454)
at org.elasticsearch.client.RestHighLevelClient.performRequest(RestHighLevelClient.java:1424)
at org.elasticsearch.client.RestHighLevelClient.performRequestAndParseEntity(RestHighLevelClient.java:1394)
at org.elasticsearch.client.RestHighLevelClient.bulk(RestHighLevelClient.java:492)
at Utils.ELKUtil$.postDataToELK(ELKUtil.scala:59)
NOTE: The above code is working for smaller size of request but getting above error while posting bigger size of request. Please suggest.

If your project is using both httpcore and httpcore-nio dependencies, ensure that both of their versions are either simultaneously <= 4.4.10 or > 4.4.10.
The suggestion by Harshit is partially what caused this issue in my case. On closer inspection of the logs, it is evident that HttpAsyncRequestExecutor is calling a default constructor called ConnectionClosedException, however, this default constructor does not exist in the destination
The HttpAsyncRequestExecutor is a class of httpcore-nio package. ConnectionClosedException is a class of the httpcore package. This issue starts occurring after v4.4.10, beyond which point the ConnectionClosedException class has a default constructor included which HttpAsyncRequestExecutor calls. For versions <= 4.4.10, the default constructor is not present, however, it is called with a parameter in HttpAsyncRequestExecutor. Thus the versions for both libraries should be either above or below v4.4.10 when being used together.

we had a similar issue and the fix we that the service has httpcore-4.4.3 where as the elastic client requires httpcore-4.4.12. So we updated all HTTP dependencies to map the version needed for elastic-rest-high-level-client
https://mvnrepository.com/artifact/org.elasticsearch.client/elasticsearch-rest-client/7.5.2

Related

hapi-fhir ResourceVersionConflictException for Update resource

I am using hapi-fhir sdk in Android. I got ResourceVersionConflictException for Patient update. From api doc
Represents an HTTP 409 Conflict response. This exception should be
thrown in methods which accept a version (e.g. Update, Delete) when
the operation fails because of a version conflict as specified in the
FHIR specification.
how is version conflict happening here. I am just updating Given name and calling client.update()
Here is my sample code;
Patient read:
val patient = client.read()
.resource(Patient::class.java)
.withId(id)
.encodedJson()
.execute()
Update:
val newName = .....
val humanName = if (patient.name == null){
patient.addName()
}else{
if (patient.name.isEmpty()){ patient.addName() } else patient.name[0]
}
// updating given name
if (humanName.given.isEmpty()){
humanName.addGiven(newName)
}else{
humanName.given[0].value = newName
}
// update api call
client.update()
.resource(patient)
.encodedJson()
.execute()
I am getting ResourceVersionConflictException for this update call. I am missing something. How can i update patient?
Thanks in advance.

java.lang.IllegalStateException: block()/blockFirst()/blockLast() are blocking, which is not supported in thread reactor-http-kqueue-4

Im getting an error with the blocking operation in Spring Webflux. I retrieve a Mono of list of Address documents and im using this Mono list of address documents to form the street address(withStreet)as shown below :
Mono<List<Address>> docs = getAddress(id, name);
AddressResponse addrResponse = new AddressResponse.Builder().
withStreet(docs.map(doc -> doc.stream().
map(StreetAddress::map).
collect(Collectors.toList())).block()).
build();
map method :
public static StreetAddress map(Address addr) {
return new Builder().
withId(addr.getId()).
withStreet(addr.getStreetAddress()).
build();
}
When i execute the above code, it throws a "block()/blockFirst()/blockLast() are blocking, which is not supported in thread reactor-http-nio-2". Could you please suggest how to fix. i want to retrieve AddressResponse without blocking it. This response will be further used in the code in Response Entity as shown below :
return Mono.just(ResponseEntity
.status(HttpStatus.OK)
.body(addrResponse)));
The problem is you try to mix reactive and imperative code.
Instead, just map it in the reactive pipeline:
Mono<AddressResponse> response = docs.map(addresses->{
return new AddressResponse.Builder()
.withStreet(addresses -> addresses.stream()
.map(StreetAddress::map)
.collect(Collectors.toList()))
.build();
})
Then you can return it as is, or map it into a Mono> type, apply the same method then above.

Spring Traverson follow relative path ignores baseUri

I'm trying to use Traverson in my Spring Boot application to consume an external HAL-api. While doing so I get the exception org.apache.http.ProtocolException: Target host is not specified on the first hop, i.e. Traverson calls my baseUri without problems and with set target host, but seems to "forget" the host on the first hop.
And this is the code calling it:
override fun doStuff() {
// baseUri gets injected by class and is of form "https://my.host.com"
val startUri = UriComponentsBuilder.fromUriString(baseUri)
// If dms is declared as first hop, Traverson would call baseUri before first hop which returns a html website and results in an error -> dms has to be part of Traverson baseUri
.pathSegment("dms")
.build()
.toUri();
val authHeader = HttpHeaders()
// bearerToken gets injected by class and is not relevant for the problem
authHeader.set(HttpHeaders.AUTHORIZATION, bearerToken)
val restTemplate = RestTemplateBuilder()
.rootUri(baseUri)
.defaultHeader(HttpHeaders.AUTHORIZATION, bearerToken)
.build()
// httpRequestFactory gets injected by class and is used to configure SSL, should not matter for the problem
restTemplate.requestFactory = httpRequestFactory
val repoId: String = Traverson(startUri, MediaTypes.HAL_JSON)
.setRestOperations(restTemplate)
.follow("$._links.allrepos.href")
.withHeaders(authHeader)
.toObject("$.repositories[0].id")
log.debug("Repo id is $repoId")
}
This is the return of the Traverson baseUri (https://my.host.com/dms):
{
_links: {
allrepos: {
href: "/dms/r"
}
}
}
When executing this code, Traverson get's the link I'm searching for ("/dms/r") but when trying to follow it, it executes a call to "/dms/r" instead of "https://my.host.com/dms/r".
Am I missing something?
Every bit of help is very much appreciated!
EDIT 1:
It is possible to achieve my goal with following code. But if I have to resort to this option, I would instead use restTemplate directly without url discovery, since Traverson is just too inconvenient to use in this case.
val allReposLink = Traverson(startUri, MediaTypes.HAL_JSON)
.setRestOperations(restTemplate)
.follow("$._links.allrepos.href")
.withHeaders(headers)
.asLink()
.href
val allReposUri = UriComponentsBuilder.fromUriString(baseUri)
.pathSegment(allReposLink)
.build()
.toUri()
val repoId = Traverson(allReposUri, MediaTypes.HAL_JSON)
.setRestOperations(restTemplate)
.follow("$.repositories[0].id")
.withHeaders(headers)
.asLink()
.href
It should be possible to do it like this:
// DOES NOT WORK
val repoId: String = Traverson(startUri, MediaTypes.HAL_JSON)
.setRestOperations(restTemplate)
.follow("allrepos")
.withHeaders(headers)
.toObject("$.repositories[0].id")

Getting an err status 500 connecting reactmongo to mlabs

SOLUTION in the bottom
i'm trying to connect my reactive spring webflux project to mongodb via mlabs. But from the api and documentation i don't know which method is causing my problem. I set up two methods to work with my mlab db but don't know which should I stick to.
Method 1 > in the application properties set up my mlab uri
spring.data.mongodb.uri=mongodb://<fernando>:<password>#ds261277.mlab.com:61277/cont-api?AuthMechanism=SCRAM-SHA-1
i've tried lower case, with & ampersand instead of question mark and adding
spring.data.mongodb.database=mycollection
Result: My code runs but when i make any request(get, post, etc) i get an error, adding or removing the "?AuthMechanism=SCRAM-SHA-1" doesn't make a difference
ERROR 2423 --- [ntLoopGroup-2-2] a.w.r.e.AbstractErrorWebExceptionHandler : [eb675923] 500 Server Error for HTTP POST "/content/v1/cont/"
org.springframework.data.mongodb.UncategorizedMongoDbException: Exception authenticating MongoCredential{mechanism=SCRAM-SHA-1, userName='<fernando>', source='cont-api', password=<hidden>, mechanismProperties={}}; nested exception is com.mongodb.MongoSecurityException: Exception authenticating MongoCredential{mechanism=SCRAM-SHA-1, userName='<fernando>', source='cont-api', password=<hidden>, mechanismProperties={}}
Method 2 > create a dataConfig like so, but when i run, i get an error of trying to connect to local mongodb
#Configuration
public class DataConfig {
private static final String DATABASE_NAME = "hospitals";
private static final String DATABA_URL = "mongodb://<fernando>:<password>#ds261277.mlab.com:61277/cont-api";
MongoClient mongoClient = MongoClients.create(new ConnectionString(DATABA_URL));
MongoDatabase database = mongoClient.getDatabase(DATABASE_NAME);
// #Bean
// public ReactiveMongoDatabaseFactory mongoDatabaseFactory(MongoClient mongoClient){
// return new SimpleReactiveMongoDatabaseFactory(mongoClient, DATABASE_NAME);
// }
//
// #Bean
// public ReactiveMongoOperations reactiveMongoTemplate(ReactiveMongoDatabaseFactory database){
// return new ReactiveMongoTemplate(database);
// }
}
Results:
[localhost:27017] org.mongodb.driver.cluster : Exception in monitor thread while connecting to server localhost:27017
com.mongodb.MongoSocketOpenException: Exception opening socket
any help would be great, thanks in advance
UPDATE & SOLUTION :
So i scrapped method two and stuck to method one, i just had to remove the angle brackets from the mlab uri so instead of it's now //fernando:password ...
So heads up to anyone using mlab, completely forgot to remove the angle brackets < >
Before:
spring.data.mongodb.uri=mongodb://<fernando>:<password>#ds261277.mlab.com:61277/cont-api
After: without < > around the user and password
spring.data.mongodb.uri=mongodb://fernando:password#ds261277.mlab.com:61277/cont-api

FaultException when using ExecuteTransactionRequest (CRM 2015)

I'm doing a bit of a technical investigation into the ExecuteTransactionRequest. It's not something I've ever used before so I knocked up a very quick experiment just to see how it works. However, when sending off the request the OrganizationService is throwing back a FaultException (below). What I believe is happening is that my version of CRM doesn't support that OrganizationRequest. Although I'm pretty sure I have the right assemblies and version.
Can anyone please shed some light on what I'm missing?
CRM Deployment Version: 7.0.1.129
Organization Version: 7.0.2.53
Microsoft.Xrm Assembly Version: 7.0.0.0 (Also happened with 8.0.0.0)
An unhandled exception of type 'System.ServiceModel.FaultException'
occurred in Microsoft.Xrm.Sdk.dll
Additional information: The formatter threw an exception while trying
to deserialize the message: There was an error while trying to
deserialize parameter
http://schemas.microsoft.com/xrm/2011/Contracts/Services:request. The
InnerException message was 'Error in line 1 position 451. Element
'http://schemas.microsoft.com/xrm/2011/Contracts/Services:request'
contains data from a type that maps to the name
'http://schemas.microsoft.com/xrm/2011/Contracts:ExecuteTransactionRequest'.
The deserializer has no knowledge of any type that maps to this name.
Consider changing the implementation of the ResolveName method on your
DataContractResolver to return a non-null value for name
'ExecuteTransactionRequest' and namespace
'http://schemas.microsoft.com/xrm/2011/Contracts'.'. Please see
InnerException for more details.
CrmConnection connection = CrmConnection.Parse(GetCrmConnectionString("unmanaged"));
IOrganizationService orgService = new OrganizationService(connection);
ExecuteTransactionRequest transactionRequest = new ExecuteTransactionRequest()
{
ReturnResponses = true,
Requests = new OrganizationRequestCollection()
};
Entity newContact = new Entity("contact");
newContact["firstname"] = "Stack";
newContact["lastname"] = "Overflow";
CreateRequest createRequest = new CreateRequest()
{
Target = newContact
};
transactionRequest.Requests.Add(createRequest);
ExecuteTransactionResponse transactionResponse = (ExecuteTransactionResponse)orgService.Execute(transactionRequest);
Update
Quick look at your code, looked like it was because of the CreateRequest not being added to the collection. After your comments and double checking the crm organization version, you are on CRM 2015 (not on update 1). ExecuteTransactionRequest is only supported by CRM 2015 update 1 (version 7.1.XXX) and up (version 8.0.XXX) organizations. So unfortunately, your query won't work until at least the 2015 update is applied to the organization.
You did not add your create request to the ExecuteTransactionRequest - Requests collection. An empty request collection is causing the exceptions most likely.
ExecuteTransactionRequest transactionRequest = new ExecuteTransactionRequest()
{
ReturnResponses = true,
Requests = new OrganizationRequestCollection()
};
Entity newContact = new Entity("contact");
newContact["firstname"] = "Stack";
newContact["lastname"] = "Overflow";
CreateRequest createRequest = new CreateRequest()
{
Target = newContact
};
transactionRequest.Requests.Add(createRequest); //missing
ExecuteTransactionResponse transactionResponse = (ExecuteTransactionResponse)orgService.Execute(transactionRequest);

Resources