Configure a db2 datasource with Thorntail / Wildfly Swarm - db2

Has anyone managed to configure a db2 datasource with Thorntail / Wildfly Swarm?
As far as I understand: As soon as I pull in the datasources fraction, the db2 driver should be autodetected according to documentation (https://docs.thorntail.io/2.3.0.Final/#auto-detecting-jdbc-drivers_thorntail).
So the only thing I should have to do is reference "ibmdb2" as the driver-name in my datasource, right?
pom.xml (using Thorntail 2.3.0.Final)
<dependency>
<groupId>io.thorntail</groupId>
<artifactId>datasources</artifactId>
</dependency>
<dependency>
<groupId>com.ibm.db2</groupId>
<artifactId>db2jcc_license_cu</artifactId>
<version>10.1</version>
</dependency>
<dependency>
<groupId>com.ibm.db2</groupId>
<artifactId>db2jcc4</artifactId>
<version>4.22.29</version>
</dependency>
project-defauls.yml
swarm:
context:
path: /
datasources:
data-sources:
MYDS:
driver-name: ibmdb2
connection-url: jdbc:db2://host:port/schema
user-name: user
password: password
Currently I get the following error on startup:
2019-05-02 09:07:52,747 INFO [org.wildfly.swarm.datasources] (main) THORN1003: Auto-detected JDBC driver for ibmdb2
2019-05-02 09:07:57,660 ERROR [org.jboss.as.controller.management-operation] (ServerService Thread Pool -- 16) WFLYCTL0013: Operation ("add") failed - address: ([
("subsystem" => "datasources"),
("jdbc-driver" => "ibmdb2")
]) - failure description: "WFLYJCA0114: Failed to load datasource class: com.ibm.db2.jdbc.DB2XADataSource"

You found a bug in the JDBC driver autodetection code. The driver was (probably) autodetected, but it was wrongly configured. Specifically, this line of code sets the XA datasource class name to com.ibm.db2.jdbc.DB2XADataSource, which doesn't exist. (That's actually what your error message says, but I also confirmed it by looking into the JDBC driver JAR.) The correct class name is com.ibm.db2.jcc.DB2XADataSource. I filed THORN-2398 and submitted a PR with a fix.
I'm not sure if there's a simple workaround, because JDBC driver autodetection is performed after all configuration is applied. Perhaps the following hack might work. Define a new JDBC driver in project-defaults.yml like this:
thorntail:
datasources:
jdbc-drivers:
mydb2:
driver-module-name: com.ibm.db2jcc
driver-xa-datasource-class-name: com.ibm.db2.jcc.DB2XADataSource
But keep everything else intact. That means there will be 2 JDBC drivers for DB2, one autodetected (which will create the com.ibm.db2jcc module), and the second one you create that will piggyback on the infrastructure created by the first. If that works, just change driver-name: ibmdb2 in your data source to driver-name: mydb2.
If this doesn't work, you'll have to move off of JDBC driver autodetection for now, until the issue is fixed.

Related

Getting Error when trying to connect AWS Aurora Postgre cluster from spring boot app

I am trying to connect to AWS Aurora (Postgre) cluster from spring boot app using following properties
spring.datasource.driver.class.name = org.postgre.jdbc.Driver
spring.datasource.url=jdbc:postgresql://a2-xxxxx.cluster-xxxxxxxxxx.us-east-1.rds.amazonaws.com:5432
spring.datasource.username=username
spring.datasource.password=password
but I am getting following error -
*Caused by: java.lang.RuntimeException: Driver org.postgresql.Driver claims to not accept jdbcUrl, jdbc:postgresql://a2-xxxxx.cluster-xxxxxxxxxx.us-east-1.rds.amazonaws.com:5432
at com.zaxxer.hikari.util.DriverDataSource.<init>(DriverDataSource.java:110) ~[HikariCP-4.0.3.jar:na]
at com.zaxxer.hikari.pool.PoolBase.initializeDataSource(PoolBase.java:331) ~[HikariCP-4.0.3.jar:na]
at com.zaxxer.hikari.pool.PoolBase.<init>(PoolBase.java:114) ~[HikariCP-4.0.3.jar:na]*
Following are my maven pom.xml contents -
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
</dependency>
You should read the jdbc documentation.
If the host is specified, the url needs a / at the end. If the database you are connecting to has a different name than the user, you also have to put the name of the database after the /. Even if they are the same, it's a good idea to include the db name because that default behavior is a bit confusing.

Quarkus devservices not starting config free postgres db

I just wanted to try dev services for spinning up a config free postgres in docker as I read at https://quarkus.io/guides/datasource#dev-services-configuration-free-databases
Generated a quarkus project https://code.quarkus.io/ with dependency quarkus-jdbc-postgresql
and application.properties looks like
quarkus.datasource.devservices.enabled=true
quarkus.datasource.db-kind=postgresql
quarkus.datasource.devservices.port=5432
Starting quarkus does NOT spin up postgres, instead I get a warning that quarkus does not understand its own properties, see Quarkus Log
2022-03-09 23:11:14,433 WARN [io.qua.config] (Quarkus Main Thread) Unrecognized configuration key "quarkus.datasource.devservices.enabled" was provided; it will be ignored; verify that the dependency extension for this configuration is set or that you did not make a typo
2022-03-09 23:11:14,433 WARN [io.qua.config] (Quarkus Main Thread) Unrecognized configuration key "quarkus.datasource.devservices.port" was provided; it will be ignored; verify that the dependency extension for this configuration is set or that you did not make a typo
2022-03-09 23:11:14,433 WARN [io.qua.config] (Quarkus Main Thread) Unrecognized configuration key "quarkus.datasource.db-kind" was provided; it will be ignored; verify that the dependency extension for this configuration is set or that you did not make a typo
2022-03-09 23:11:14,936 INFO [io.quarkus] (Quarkus Main Thread) quarkus-resteasy-postgres 1.0.0-SNAPSHOT on JVM (powered by Quarkus 2.7.4.Final) started in 2.182s. Listening on: http://localhost:8080
2022-03-09 23:11:14,937 INFO [io.quarkus] (Quarkus Main Thread) Profile dev activated. Live Coding activated.
2022-03-09 23:11:14,937 INFO [io.quarkus] (Quarkus Main Thread) Installed features: [cdi, jdbc-postgresql, resteasy, smallrye-context-propagation, vertx]
Any idea what is going on here?
Project here: https://github.com/syr/quarkus-resteasy-postgres
According to your warning message, there's one extension missing for this configuration:
2022-03-09 23:11:14,433 WARN [io.qua.config] (Quarkus Main Thread) Unrecognized configuration key "quarkus.datasource.db-kind" was provided; it will be ignored; verify that the dependency extension for this configuration is set or that you did not make a typo
You can solve your problem adding one of these dependencies to your project (on your pom.xml):
Pool your database connections (included in Hibernate ORM)
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-agroal</artifactId>
</dependency>
or
Hibernate ORM
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-hibernate-orm</artifactId>
</dependency>

Dynamic destination in Spring Cloud Stream from Azure Event Hub to Kafka

I'm trying to use Spring Cloud Stream to process messages sent to an Azure Event Hub instance. Those messages should be routed to a tenant-specific topic determined at runtime, based on message content, on a Kafka cluster. For development purposes, I'm running Kafka locally via Docker.
I've done some research about bindings not known at configuration time and have found that dynamic destination resolution might be exactly what I need for this scenario.
However, the only way to get my solution working is to use StreamBridge. I would rather use the dynamic destination header spring.cloud.stream.sendto.destination, in that way the processor could be written as a Function<> instead of a Consumer<> (it is not properly a sink). The main concern about this approach is that, since the final solution will be deployed with Spring Data Flow, I'm afraid I will have troubles configuring the streams if using StreamBridge.
Moving on to the code, this is the processor function, I stripped away the unrelated parts
private static final String OUTPUT_DESTINATION_TEMPLATE = "%s.gateway-report";
private static final String STREAM_DESTINATION_HEADER = "spring.cloud.stream.sendto.destination";
private static final String TENANT_ID_HEADER = "tenant-id";
#Bean
public Function<Message<String>, Message<String>>
routeMessageToTenantDestination(TenantGatewayDeviceService gatewayDeviceService) {
return msg -> {
final String tenantId = "test";
final String destination = String.format(OUTPUT_DESTINATION_TEMPLATE, tenantId);
return MessageBuilder.withPayload(msg.getPayload())
.setHeader(STREAM_DESTINATION_HEADER, destination)
.setHeader(TENANT_ID_HEADER, tenantId)
.build();
};
}
and this is my application.yml
spring:
cloud:
stream:
bindings:
routeMessageToTenantDestination-in-0:
binder: kafka-evthub
destination: gateway-report
group: report-processor
dynamic-destinations:
binders:
kafka-ioc:
type: kafka
environment:
spring.cloud.stream.kafka.binder:
brokers: localhost:29092
kafka-evthub:
type: kafka
environment:
spring.cloud.stream.kafka.binder:
brokers: xxxxxxxxxxx.servicebus.windows.net:9093
configuration:
sasl:
jaas:
config: org.apache.kafka.common.security.plain.PlainLoginModule required username="$ConnectionString" password="Endpoint=sb://xxxxxxxxxxx.servicebus.windows.net/;SharedAccessKeyName=*******;SharedAccessKey=********";
mechanism: PLAIN
security.protocol: SASL_SSL
default-binder: kafka-ioc
My relevant dependencies in pom.xml
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-stream</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-stream-binder-kafka</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.kafka</groupId>
<artifactId>spring-kafka</artifactId>
</dependency>
This is the exception I get each time the function fires
2022-01-20 10:56:18.848 ERROR 2258917 --- [container-0-C-1] o.s.integration.handler.LoggingHandler : org.springframework.messaging.MessageHandlingException: error occurred in message handler [... stripped away ...]
at org.springframework.integration.support.utils.IntegrationUtils.wrapInHandlingExceptionIfNecessary(IntegrationUtils.java:191)
at org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:65)
at org.springframework.integration.dispatcher.AbstractDispatcher.tryOptimizedDispatch(AbstractDispatcher.java:115)
at org.springframework.integration.dispatcher.UnicastingDispatcher.doDispatch(UnicastingDispatcher.java:133)
at org.springframework.integration.dispatcher.UnicastingDispatcher.dispatch(UnicastingDispatcher.java:106)
at org.springframework.integration.channel.AbstractSubscribableChannel.doSend(AbstractSubscribableChannel.java:72)
at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:317)
at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:272)
at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:187)
at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:166)
at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:47)
at org.springframework.messaging.core.AbstractMessageSendingTemplate.send(AbstractMessageSendingTemplate.java:109)
at org.springframework.integration.endpoint.MessageProducerSupport.sendMessage(MessageProducerSupport.java:208)
at org.springframework.integration.kafka.inbound.KafkaMessageDrivenChannelAdapter.sendMessageIfAny(KafkaMessageDrivenChannelAdapter.java:385)
at org.springframework.integration.kafka.inbound.KafkaMessageDrivenChannelAdapter.access$300(KafkaMessageDrivenChannelAdapter.java:79)
at org.springframework.integration.kafka.inbound.KafkaMessageDrivenChannelAdapter$IntegrationRecordMessageListener.onMessage(KafkaMessageDrivenChannelAdapter.java:442)
at org.springframework.integration.kafka.inbound.KafkaMessageDrivenChannelAdapter$IntegrationRecordMessageListener.onMessage(KafkaMessageDrivenChannelAdapter.java:416)
at org.springframework.kafka.listener.adapter.RetryingMessageListenerAdapter.lambda$onMessage$0(RetryingMessageListenerAdapter.java:125)
at org.springframework.retry.support.RetryTemplate.doExecute(RetryTemplate.java:329)
at org.springframework.retry.support.RetryTemplate.execute(RetryTemplate.java:255)
at org.springframework.kafka.listener.adapter.RetryingMessageListenerAdapter.onMessage(RetryingMessageListenerAdapter.java:119)
at org.springframework.kafka.listener.adapter.RetryingMessageListenerAdapter.onMessage(RetryingMessageListenerAdapter.java:42)
at org.springframework.kafka.listener.KafkaMessageListenerContainer$ListenerConsumer.doInvokeOnMessage(KafkaMessageListenerContainer.java:2588)
at org.springframework.kafka.listener.KafkaMessageListenerContainer$ListenerConsumer.invokeOnMessage(KafkaMessageListenerContainer.java:2569)
at org.springframework.kafka.listener.KafkaMessageListenerContainer$ListenerConsumer.doInvokeRecordListener(KafkaMessageListenerContainer.java:2483)
at org.springframework.kafka.listener.KafkaMessageListenerContainer$ListenerConsumer.doInvokeWithRecords(KafkaMessageListenerContainer.java:2405)
at org.springframework.kafka.listener.KafkaMessageListenerContainer$ListenerConsumer.invokeRecordListener(KafkaMessageListenerContainer.java:2284)
at org.springframework.kafka.listener.KafkaMessageListenerContainer$ListenerConsumer.invokeListener(KafkaMessageListenerContainer.java:1958)
at org.springframework.kafka.listener.KafkaMessageListenerContainer$ListenerConsumer.invokeIfHaveRecords(KafkaMessageListenerContainer.java:1353)
at org.springframework.kafka.listener.KafkaMessageListenerContainer$ListenerConsumer.pollAndInvoke(KafkaMessageListenerContainer.java:1344)
at org.springframework.kafka.listener.KafkaMessageListenerContainer$ListenerConsumer.run(KafkaMessageListenerContainer.java:1236)
at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
at java.base/java.lang.Thread.run(Thread.java:829)
Caused by: java.lang.NullPointerException
at org.springframework.cloud.stream.function.StreamBridge.resolveDestination(StreamBridge.java:276)
at org.springframework.cloud.stream.function.FunctionConfiguration$FunctionToDestinationBinder$1.doSendMessage(FunctionConfiguration.java:604)
at org.springframework.cloud.stream.function.FunctionConfiguration$FunctionToDestinationBinder$1.handleMessageInternal(FunctionConfiguration.java:597)
at org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:56)
... 32 more
I've tried different things, f.i. manually creating the destination topic, configuring an explicit destination binding with the same name assigned to the header (not a definitive solution, just for testing), but I keep getting this exception. I've also tried to provide a NewDestinationBindingCallback<> and I can see from printing a log that the framework enters the method, but nevertheless I keep getting the same error.
This happens also with the other approach for integrating Spring Cloud Stream with Event Hubs, namely the library azure-spring-cloud-stream-binder-eventhubs.
As I said previously, I've found a workaround in relying to StreamBridge, but this solution seems less desirable to me and I would like to understand what I'm missing.
EDIT: I made a small step forward and managed to make it work by downgrading spring boot starter version from 2.6.2 to 2.4.4
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.4</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
and setting
<properties>
<spring-cloud.version>2020.0.2</spring-cloud.version>
</properties>
instead of 2021.0.0 in pom.xml, as found in the sample provided by sobychacko. However, it seems like a regression, or something is missing in my configuration to make this work with the most recent version?
Not sure what exactly is causing the issues you have. I just created a basic sample app demonstrating the sendto.destination header and verified that the app works as expected. It is a multi-binder application with two Kafka clusters connected. The function will consume from the first cluster and then using the sendto header, produce the output to the second cluster. Compare the code/config in this sample with your app and see what is missing.
I see references to StreamBridge in the stacktrace you shared. However, when using the sendto.destination header, it shouldn't go through StreamBridge.

Spring Cloud Config Server not registering as client to Spring Boot Admin

I have Spring Cloud config server and trying to register it to Spring Boot admin. In my pom.xml file I have
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-client</artifactId>
<version>2.1.6</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
<version>2.1.3.Release</version>
</dependency>
I have several other services registering, so I know I have all my URL and settings correct. But I am not seeing is the registering log in the config server logs.
Found the answer after running the config server in debug mode.
SpringBootAdminClientAutoConfiguration:
Did not match:
- Spring Boot Client is disabled, because 'spring.boot.admin.client.url' is empty. (SpringBootAdminClientEnabledCondition)
Matched:
- #ConditionalOnWebApplication (required) found 'session' scope (OnWebApplicationCondition)
SpringBootAdminClientCloudFoundryAutoConfiguration:
Did not match:
- Spring Boot Client is disabled, because 'spring.boot.admin.client.url' is empty. (SpringBootAdminClientEnabledCondition)
Matched:
- #ConditionalOnWebApplication (required) found 'session' scope (OnWebApplicationCondition)
Since the config server doesn't read from the config server git repo the client URL was not set.
Adding --spring.boot.admin.client.url=<url> to the startup fixed it.

Spring Boot MVC application with Postgresql deployment failed in Heroku

I have a Spring Boot MVC project. It works fine with h2 database and also fine in local postgre database with following application.properties configuration
spring.datasource.url=myUrl
spring.datasource.username=myUsername
spring.datasource.password=myPassword
But when I am trying to deploy it in Heroku it is getting this following error:
Caused by: org.hibernate.HibernateException: Access to
DialectResolutionInfo cannot be null when 'hibernate.dialect' not set
If I use this configuration
spring.jpa.database-platform=org.hibernate.dialect.PostgreSQLDialect
spring.datasource.driverClassName=org.postgresql.Driver
spring.datasource.url=herokuPostgreSqlDbUrl
spring.datasource.username=herokuUsername
spring.datasource.password=mherokuPassword
I am getting this when try to run my project from STS and failed deployment.
Caused by: java.sql.SQLException: Driver:org.postgresql.Driver#17a3dff6
returned null for URL:myUrl
My pom is :
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>9.4-1206-jdbc42</version>
</dependency>
Can any body help ?
You need a proper JDBC url. See: https://springframework.guru/configuring-spring-boot-for-postgresql/