JHipster with elasticsearch on cloudfoundry - spring-boot

Has anyone successfully used elasticsearch (searchly) through the Pivotal Web Services market place for a Jhipster generated application? I have correctly bound the searchly service to my application, but keep getting the following error:
Failed to instantiate [org.elasticsearch.client.Client]: Factory method 'elasticsearchClient' threw exception; nested exception is java.lang.IllegalStateException: java.lang.NumberFormatException: For input string: "//gopivotal:<redacted>#dori-us-east-1.searchly.com"
My jhipster production profile is as follows:
data:
elasticsearch:
cluster-name:
cluster-nodes: ${vcap.searchly.credentials.uri}
Any help appreciated.

cluster-nodes is actually used behind the scenes by TransportClientFactoryBean and it can't parse the username:password bit. It doesn't feel right to paste the URI of the service in the "cluster-nodes" property but I couldn't find anything else to configure it.
Can you please create an issue in the Spring Data ElasticSearch tracker?
In the meantime, I suggest to use Jest, you can create your own client easily from PWS as follows:
public JestClient jestClient(String url) {
HttpClientConfig clientConfig = new HttpClientConfig
.Builder(String url)
.readTimeout(6000)
.multiThreaded(true)
.build();
JestClientFactory factory = new JestClientFactory();
factory.setHttpClientConfig(clientConfig);
return factory.getObject();
}
And pass the property (as you did in your description) to that method.

Related

IllegalStateException: Unable to create a ConnectionFactory for

When I tried with non-reactive approach as below, am able to get connection without any issues.
spring.datasource.url=jdbc:sqlserver://AAAAA1011.na.app.corp\\bbbb;databaseName=mydb;integratedSecurity=true;authenticationScheme=JavaKerberos
But when I tried with Reactive R2dbc with MsSql server approach as below, then am facing exceptions, below is the code:
#Bean
#Override
public ConnectionFactory connectionFactory() {
ConnectionFactory connectionFactory = ConnectionFactories.get(ConnectionFactoryOptions.builder()
.option(ConnectionFactoryOptions.DRIVER, "mssql")
.option(ConnectionFactoryOptions.HOST, "AAAAA1011.na.app.corp/bbbb")
.option(ConnectionFactoryOptions.DATABASE, "mydb")
.option(ConnectionFactoryOptions.USER, "NA\\user")
.option(Option.valueOf("integratedSecurity"), true)
.option(Option.valueOf("authenticationScheme"), "JavaKerberos")
.build());
return connectionFactory;
}`
Excception stacktrace:
org.springframework.beans.BeanInstantiationException: Failed to instantiate [io.r2dbc.spi.ConnectionFactory]: Factory method 'connectionFactory' threw exception; nested exception is java.lang.IllegalStateException: Unable to create a ConnectionFactory for 'ConnectionFactoryOptions{options={database=mydb, host=AAAAA1011.na.app.corp/bbbb, driver=mssql, authenticationScheme=JavaKerberos, integratedSecurity=true, user=NA\user}}'. Available drivers: [ pool, sqlserver ]
at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:658) ~[spring-beans-5.3.23.jar:5.3.23]
And I found this link too: https://github.com/r2dbc/r2dbc-mssql/issues/101 , mentioning that r2dbc doesnt support Kerberos seems, but that was written on 2019, its been 3 yrs now, not sure whether above works or not.
If anyone aware of above issue, can you Please help me out..
From the exception info, the connection issue is caused by the driver settings.
Available drivers: [ pool, sqlserver ]
Try to change .option(ConnectionFactoryOptions.DRIVER, "mssql") to the following:
.option(ConnectionFactoryOptions.DRIVER, "sqlserver")
I know little about Kerberos support in R2dbc/MSSQL, please update yourself according to the official docs.

Error setting custom trust store for Eureka Discovery client by overriding DiscoveryClient.DiscoveryClientOptionalArgs

I am upgrading a spring-boot project from an old version (2.2.9.RELEASE + Spring Cloud HOXTON.SR12) to v2.6.1 + Spring Cloud 2021.0.0
The issue I am currently hitting is with Trust Store enabled Eureka clients. In my old version, all eureka registering applications would use
import org.springframework.cloud.client.discovery.EnableDiscoveryClient; and be tagged with
#EnableDiscoveryClient
To use a custom trust store, I'd then include the following beans in a configuration class:
#Bean
public DiscoveryClient.DiscoveryClientOptionalArgs getTrustStoredEurekaClient(SSLContext sslContext) {
DiscoveryClient.DiscoveryClientOptionalArgs args = new DiscoveryClient.DiscoveryClientOptionalArgs();
args.setSSLContext(sslContext);
return args;
}
#Bean
public SSLContext sslContext() throws Exception {
return new SSLContextBuilder().loadTrustMaterial(new File(trustStore).toURI().toURL(), trustStorePassword.toCharArray()).build();
}
using import com.netflix.discovery.DiscoveryClient;
Following the upgrade, any microservice which attempts to use this custom truststore will not start, with the error thrown below:
*************************** APPLICATION FAILED TO START
Description:
Field optionalArgs in
org.springframework.cloud.netflix.eureka.EurekaClientAutoConfiguration$RefreshableEurekaClientConfiguration
required a bean of type
'com.netflix.discovery.AbstractDiscoveryClientOptionalArgs' that could
not be found.
The injection point has the following annotations:
#org.springframework.beans.factory.annotation.Autowired(required=true)
Action:
Consider defining a bean of type
'com.netflix.discovery.AbstractDiscoveryClientOptionalArgs' in your
configuration.
It doesn't seem to matter if I try to autowrire in a separate bean of type DiscoveryClientOptionalArgs and set the context to this, and I am currently unable to resolve this.
I could solve this by setting the following in the gateway's application.properties:
eureka.client.tls.enabled=true
eureka.client.tls.key-store=file:<path-to-key-store>
eureka.client.tls.key-store-password=<password>
eureka.client.tls.keyStoreType=PKCS12
eureka.client.tls.keyPassword=<password>
eureka.client.tls.trust-store=file:<path-to-trust-store>
eureka.client.tls.trust-store-password=<password>
What's not clear to me is why a keystore in addition to the truststore needs to be set (as above, it was only necessary to configure a trust store for the SSL context of the DiscoveryClient override for the previous versions using Zuul), which suggests I haven't fully understood what's actually happening here.

No suitable default RequestUpgradeStrategy found in a new generated jhipster application

I'm working on Jhipster micro-services project, all works fine and good until i a
websocket spring-websocket
into the gateway application in my JDL file, now when I run the project I always get a failure
Failed to instantiate [org.springframework.web.servlet.HandlerMapping]: Factory method 'stompWebSocketHandlerMapping' threw exception; nested exception is java.lang.IllegalStateException: No suitable default RequestUpgradeStrategy found
the application I'am use is right of the box generated from jhipster generator 7.0.0
the JDL I use is :
application {
config {
baseName usergateway,
packageName fr.teamsyst.trade4talent.usergateway,
applicationType gateway,
authenticationType jwt,
databaseType mongodb,
devDatabaseType mongodb,
prodDatabaseType mongodb,
serviceDiscoveryType eureka,
testFrameworks [protractor],
nativeLanguage fr,
languages [fr, en],
jhiPrefix t4t,
websocket spring-websocket,
}
entities *
}
Add spring-boot-starter-tomcat dependency to pom.xml
Add spring.main.web-application-type: reactive to application.yml

Deploying Spring Integration to WebSphere ND 8.5.5

I am looking for some guidance on deploying a simple Spring Integration application to WebSphere. The overall scope of the application is quite simple - it reads from a RabbitMQ endpoint, transforms any messages received to a specific xml format, and then posts the message to a JMS endpoint in WAS.
Initially, I built the application as a JAR. I was able to get it to work well enough with SSL turned off on the IIOP endpoints in WAS, but despite hours of debugging I never could get it to communicate properly with WAS over SSL. The initial handshake and communication with the bootstrap port was successful, but the SIB endpoint rejected the exact same certificate chain with the usual PKIX chaining error, and no amount of certificate importing made any difference.
So I elected to work out deploying the application as a web app into WAS itself, which would have been the end goal anyways. This caused a number of issues that i've had to work through:
I have not gotten properties to work in the normal Spring fashion. I assume that in this context Spring needs to be explicitly told where to look, but i've sidestepped this with hardcoding for now. Perhaps using #Resource annotations would be the way to do this in this context?
Various jar versioning issues, which i've mostly worked out by setting the application classloader as PARENT_LAST, and judiciously removing things that seemed redundant.
Oddly I did have to add some jars related to Parameter validation which don't seem to have been present in my original maven build.
Needing to set some values in the web.xml in order for spring to location configuration beans, specifically setting init-param with contextClass (org.springframework.web.context.support.AnnotationConfigWebApplicationContext) and contextConfigLocation set to a list of the objects that would normally be loaded via the #Configuration annotation.
May or may not be necessary but I did move from Maven to IID in order to hopefully avoid versioning issues with IBM related jars.
Now I would like to know if there are other items generally needed to be done to deploy Spring (especially Spring Integration) to WAS, and whether the above seems like enough.
In addition, I have an issue with the actual JMS connection to WAS. I have tried to use the UserCredentialsConnectionFactoryAdapter, and was successful with this with Spring standalone. However when deployed in WAS, an exception is thrown:
Caused by: java.lang.ClassCastException: com.ibm.ws.sib.api.jms.impl.JmsManagedQueueConnectionFactoryImpl incompatible with javax.jms.ConnectionFactory
I believe this is thrown when the setTargetConnectionFactory method is called, since if I use the connection factory without the UserCredentialsConnectionFactoryAdapter, it works fine, except the connection by "anonymous" is rejected by the bus:
[03/03/21 15:23:32:934 EST] 0000016c SibMessage W [BPM.WorkflowServer.Bus:Node1.server1-BPM.WorkflowServer.Bus] CWSII0212W: The bus BPM.WorkflowServer.Bus denied an anonymous user access to the bus.
If you want to see the code, this works fine (but doesn't authenticate):
#Bean
public ConnectionFactory jmsConnectionFactory() throws NamingException {
ConnectionFactory connectionFactory = null;
Context ctx = null;
Properties p = new Properties();
p.put(Context.INITIAL_CONTEXT_FACTORY, "com.ibm.websphere.naming.WsnInitialContextFactory");
p.put(Context.PROVIDER_URL, providerUrl);
p.put(Context.SECURITY_AUTHENTICATION,"simple");
p.put(Context.SECURITY_PRINCIPAL,jmsUsername);
p.put(Context.SECURITY_CREDENTIALS,jmsPassword);
ctx = new InitialContext(p);
if (null != ctx)
System.out.println("Got naming context");
connectionFactory = (QueueConnectionFactory) ctx.lookup("javax.jms.QueueConnectionFactory");
if (null != connectionFactory)
System.out.println("Got connection factory");
return connectionFactory;
}
Whereas this throws the class cast exception:
#Bean
public UserCredentialsConnectionFactoryAdapter jmsConnectionFactory() throws NamingException {
ConnectionFactory connectionFactory = null;
Context ctx = null;
Properties p = new Properties();
p.put(Context.INITIAL_CONTEXT_FACTORY, "com.ibm.websphere.naming.WsnInitialContextFactory");
p.put(Context.PROVIDER_URL, providerUrl);
p.put(Context.SECURITY_AUTHENTICATION,"simple");
p.put(Context.SECURITY_PRINCIPAL,jmsUsername);
p.put(Context.SECURITY_CREDENTIALS,jmsPassword);
ctx = new InitialContext(p);
if (null != ctx)
System.out.println("Got naming context");
connectionFactory = (ConnectionFactory) ctx.lookup("javax.jms.QueueConnectionFactory");
if (null != connectionFactory)
System.out.println("Got connection factory");
UserCredentialsConnectionFactoryAdapter adapter = new UserCredentialsConnectionFactoryAdapter();
adapter.setTargetConnectionFactory(connectionFactory);
adapter.setUsername(jmsUsername);
adapter.setPassword(jmsPassword);
return adapter;
// return connectionFactory;
}
Note: the credentials set in the Context properties seem to have no effect.
I am using this connection factory with Spring Integration Java DSL:
.handle(Jms.outboundAdapter(jmsConfig.jmsConnectionFactory())
.destination(jmsDestination))
I understand from WebSphere documentation that supplying credentials happens on the ConnectionFactory.getConnection() call. So I wonder whether there is any hook in the DSL where I could override the getConnection so as to provide parameters and avoid the class cast exception that I am seeing.
Alternately I am considering just explicitly calling jms template methods to send the message using a lambda in the handler and creating the connection manually.
So, finally what I would like to ask for is:
Any overall guidance on deploying a Spring application to WebSphere traditional
What may be causing the class cast exception
ps, I have placed all of the spring, et al jars in a shared library. This is the contents:
c:/IBM/IID/sharedlibs/spring/accessors-smart-1.2.jar
c:/IBM/IID/sharedlibs/spring/amqp-client-5.10.0.jar
c:/IBM/IID/sharedlibs/spring/android-json-0.0.20131108.vaadin1.jar
c:/IBM/IID/sharedlibs/spring/apiguardian-api-1.1.0.jar
c:/IBM/IID/sharedlibs/spring/asm-5.0.4.jar
c:/IBM/IID/sharedlibs/spring/assertj-core-3.18.1.jar
c:/IBM/IID/sharedlibs/spring/byte-buddy-1.10.19.jar
c:/IBM/IID/sharedlibs/spring/byte-buddy-agent-1.10.19.jar
c:/IBM/IID/sharedlibs/spring/hamcrest-2.2.jar
c:/IBM/IID/sharedlibs/spring/hamcrest-core-2.2.jar
c:/IBM/IID/sharedlibs/spring/hamcrest-library-2.2.jar
c:/IBM/IID/sharedlibs/spring/http-client-3.8.0.RELEASE.jar
c:/IBM/IID/sharedlibs/spring/jackson-annotations-2.11.4.jar
c:/IBM/IID/sharedlibs/spring/jackson-core-2.11.4.jar
c:/IBM/IID/sharedlibs/spring/jackson-databind-2.11.4.jar
c:/IBM/IID/sharedlibs/spring/jackson-dataformat-xml-2.11.4.jar
c:/IBM/IID/sharedlibs/spring/jackson-datatype-jdk8-2.11.4.jar
c:/IBM/IID/sharedlibs/spring/jackson-datatype-jsr310-2.11.4.jar
c:/IBM/IID/sharedlibs/spring/jackson-module-jaxb-annotations-2.11.4.jar
c:/IBM/IID/sharedlibs/spring/jackson-module-parameter-names-2.11.4.jar
c:/IBM/IID/sharedlibs/spring/jakarta.activation-api-1.2.2.jar
c:/IBM/IID/sharedlibs/spring/jakarta.annotation-api-1.3.5.jar
c:/IBM/IID/sharedlibs/spring/jakarta.el-3.0.3.jar
c:/IBM/IID/sharedlibs/spring/json-path-2.4.0.jar
c:/IBM/IID/sharedlibs/spring/json-smart-2.3.jar
c:/IBM/IID/sharedlibs/spring/jsonassert-1.5.0.jar
c:/IBM/IID/sharedlibs/spring/objenesis-3.1.jar
c:/IBM/IID/sharedlibs/spring/reactive-streams-1.0.3.jar
c:/IBM/IID/sharedlibs/spring/reactor-core-3.4.2.jar
c:/IBM/IID/sharedlibs/spring/snakeyaml-1.27.jar
c:/IBM/IID/sharedlibs/spring/spring-amqp-2.3.4.jar
c:/IBM/IID/sharedlibs/spring/spring-aop-5.3.3.jar
c:/IBM/IID/sharedlibs/spring/spring-beans-5.3.3.jar
c:/IBM/IID/sharedlibs/spring/spring-boot-2.4.2.jar
c:/IBM/IID/sharedlibs/spring/spring-boot-autoconfigure-2.4.2.jar
c:/IBM/IID/sharedlibs/spring/spring-boot-starter-2.4.2.jar
c:/IBM/IID/sharedlibs/spring/spring-boot-starter-amqp-2.4.2.jar
c:/IBM/IID/sharedlibs/spring/spring-boot-starter-json-2.4.2.jar
c:/IBM/IID/sharedlibs/spring/spring-boot-starter-logging-2.4.2.jar
c:/IBM/IID/sharedlibs/spring/spring-boot-starter-web-2.4.2.jar
c:/IBM/IID/sharedlibs/spring/spring-context-5.3.3.jar
c:/IBM/IID/sharedlibs/spring/spring-core-5.3.3.jar
c:/IBM/IID/sharedlibs/spring/spring-expression-5.3.3.jar
c:/IBM/IID/sharedlibs/spring/spring-integration-amqp-5.4.3.jar
c:/IBM/IID/sharedlibs/spring/spring-integration-core-5.4.3.jar
c:/IBM/IID/sharedlibs/spring/spring-integration-jms-5.4.3.jar
c:/IBM/IID/sharedlibs/spring/spring-integration-xml-5.4.3.jar
c:/IBM/IID/sharedlibs/spring/spring-jcl-5.3.3.jar
c:/IBM/IID/sharedlibs/spring/spring-jms-5.3.3.jar
c:/IBM/IID/sharedlibs/spring/spring-messaging-5.3.3.jar
c:/IBM/IID/sharedlibs/spring/spring-oxm-5.3.3.jar
c:/IBM/IID/sharedlibs/spring/spring-rabbit-2.3.4.jar
c:/IBM/IID/sharedlibs/spring/spring-rabbit-junit-2.3.4.jar
c:/IBM/IID/sharedlibs/spring/spring-retry-1.3.1.jar
c:/IBM/IID/sharedlibs/spring/spring-tx-5.3.3.jar
c:/IBM/IID/sharedlibs/spring/spring-web-5.3.3.jar
c:/IBM/IID/sharedlibs/spring/spring-webmvc-5.3.3.jar
c:/IBM/IID/sharedlibs/spring/spring-xml-3.0.10.RELEASE.jar
c:/IBM/IID/sharedlibs/spring/stax2-api-4.2.1.jar
c:/IBM/IID/sharedlibs/spring/woodstox-core-6.2.4.jar
c:/IBM/IID/sharedlibs/spring/xmlunit-core-2.7.0.jar
c:/IBM/IID/sharedlibs/spring/slf4j-api-1.7.30.jar
c:/IBM/IID/sharedlibs/spring/jakarta.validation-api-2.0.2.jar
c:/IBM/IID/sharedlibs/spring/hibernate-validator-6.1.7.Final.jar
c:/IBM/IID/sharedlibs/spring/jboss-logging-3.4.1.Final.jar
c:/IBM/IID/sharedlibs/spring/classmate-1.5.1.jar
c:/IBM/IID/sharedlibs/spring/javax.jms-api-2.0.1.jar
UPDATE
So what I finally realized is that:
WAS 8.5.5 is using J2EE v6, which means JMS 1.1
Spring JMS is using JMS 2.0
When I switched to using the UserCredentialsConnectionFactoryAdapter, this tries to use the JmsContext interface which is part of JMS 2.0 classes, and not provided by the WAS jee container, so this was the reason for the class cast exception.
What I did was to do the JMS sending manually instead of using any spring integration gateway. A better solution might be to create my own adapter that extends connection factory and uses credentials in the connect method, but this works well enough for now:
.handle( m -> {
try {
jmsConfig.sendMessage( m.getPayload().toString() );
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} )
JmsConfig being a bean that manages the connection.

Using JaxWsProxyFactoryBean and Spring how do I make an HTTPS connection through a proxy?

I am trying to use JaxWsProxyFactoryBean to connect to a TLS1.2 https service using spring boot and java config through a proxy. I have been unable to find any samples, or information about how to configure this. Im using wsdl2java to build all of the objects that eventually get returned from JaxWsProxyFactoryBean. Any help would be greatly appreciated. What I currently have:
private <T> T cxfClient(String address, String user, String pass, Class<T> serviceClass) {
JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();
factory.setAddress(address);
factory.setUsername(user);
factory.setPassword(pass);
return factory.create(serviceClass);
}
and
#Bean
public Client client() {
Client client = ClientProxy.getClient(lexisNexisClient());
HTTPConduit http = (HTTPConduit) client.getConduit();
http.getClient().setProxyServer("myproxy");
http.getClient().setProxyServerPort(myport);
http.getProxyAuthorization().setUserName("myuser");
http.getProxyAuthorization().setPassword("mypass");
return client;
}
I am currently getting an error:
Caused by: java.lang.NoSuchMethodError: org.apache.cxf.configuration.jsse.TLSClientParameters.getSslContext()Ljavax/net/ssl/SSLContext
Any help would be greatly appreciated.
Thanks,
Brian
Issue ended up being a dependency problem with CXF versions. Apparently the Ljavax/net/ssl/SSLContext means there is a dependency version conflict.
Thanks,
Brian

Resources