Error finding bean when using Watson spring-boot-starter - spring-boot

I followed the steps in https://github.com/watson-developer-cloud/spring-boot-starter to try an call the Watson Conversation(Assistant) service in a Spring boot application, however I am getting this error:
*************************** APPLICATION FAILED TO START
Description:
Field service in application.ConverseApiBinding required a bean of
type 'com.ibm.watson.developer_cloud.conversation.v1.Conversation'
that could not be found.
Action:
Consider defining a bean of type
'com.ibm.watson.developer_cloud.conversation.v1.Conversation' in your
configuration.
Is there thing else I need to do apart from adding dependencies (I used maven) and
#Autowired
protected Conversation service;
The service url and credentials are provided in the VCAP_SERVICES environment variable.

You need to have something in your application properties file to signal that the conversation bean should be created. Normally this would be the service credentials.
In the case where the service credentials come from VCAP_SERVICES, you can simply specify
watson.conversation.enabled=true
in your application properties file. That should trigger the creation of the bean.

Related

How to launch spring boot application with cloud-bus via custom auto-configuration?

Some time ago I found out that my spring-boot application had been launching slowly via #EnableAutoConfiguration. Then I decided to create custom configuration to speed up a process. I tried to #Import all needed configurations and I faced with issue of unknown beans:
Description:
Parameter 0 of method streamBusBridge in org.springframework.cloud.bus.BusStreamAutoConfiguration required a bean of type 'org.springframework.cloud.stream.function.StreamBridge' that could not be found.
Action:
Consider defining a bean of type 'org.springframework.cloud.stream.function.StreamBridge' in your configuration.
It seems that I've already used all cloud-bus configurations:
PathServiceMatcherAutoConfiguration.class,
BindingsEndpointAutoConfiguration.class,
BusAutoConfiguration.class,
BindingServiceConfiguration.class,
BindersHealthIndicatorAutoConfiguration.class,
ChannelsEndpointAutoConfiguration.class,
BusRefreshAutoConfiguration.class,
FunctionConfiguration.class,
BusStreamAutoConfiguration.class,
BusJacksonAutoConfiguration.class
What should I add to launch my application via custom auto-configuration?
Spring-boot: v2.6.6
Spring-cloud-bus: v3.1.2
Java: 17

How to configure a non-AgroalDataSource within Quarkus and Panache

Apache ShardingSphere provides the ShardingSphereDataSource to encapsulate the routing mechanisme. So, if we inject a ShardingSphereDataSource into a EntityManager, we can easily persist our data and route to the planned destination via EntityManager#persist method.
I don't know my understanding is correct or not, Does Panache seems to only accept AgroalDataSource?
I refer to this project to produce a ShardingSphereDataSource bean, and use following code snippet to inspect whether the ShardingSphereDataSource is produced successfully.
CDI.current().getBeanManager().getBeans(DataSource.class).forEach(bean -> {
log.info("DataSource Bean name:{}, beanClass:{}", bean.getName(), bean.getBeanClass());
});
The result shows I have a ShardingSphereDataSource named defaultDs in the CDI context.
DataSource Bean name:defaultDs, beanClass:class org.apache.shardingsphere.driver.jdbc.core.datasource.ShardingSphereDataSource
Next, I config a persistent unit and refer to this datasource.
quarkus.hibernate-orm.datasource=defaultDs
quarkus.hibernate-orm.packages=x.y.x.domain
I get the error message.
Caused by: io.quarkus.runtime.configuration.ConfigurationException: The datasource 'defaultDs' is not configured but the persistence unit '<default>' uses it. To solve this, configure datasource 'defaultDs'. Refer to https://quarkus.io/guides/datasource for guidance.
So, how do we configure a non-AgroalDataSource within Quarkus and Panache?

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.

Accessing JNDI Datasource using Container Managed Authentication Alias in Websphere (Spring + Ibatis/Mybatis)

I am using WebSphere 8.5.5.18.
As of now I'm using Component-Managed Authentication Alias for my DataSource. But I want to use Container-Managed instead. When I just change the Security settings in Data Sources → Security settings I am getting error in logs. It is unable to fetch records.
Exception Stacktrace:
Check the SQL Statement (preparation failed).
--- Cause: java.sql.SQLException: [jcc][t4][10205][11234][3.72.54] Null userid is not supported. ERRORCODE=-4461, SQLSTATE=42815 DSRA0010E: SQL State = 42815, Error Code = -4,461
at org.springframework.jdbc.support.SQLStateSQLExceptionTranslator.doTranslate(SQLStateSQLExceptionTranslator.java:97)
at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:72)
at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:80)
at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:80)
at org.springframework.orm.ibatis.SqlMapClientTemplate.execute(SqlMapClientTemplate.java:212)
at org.springframework.orm.ibatis.SqlMapClientTemplate.queryForObject(SqlMapClientTemplate.java:271)
Basically the database is not being accessed properly when settings are changed from Component-Managed Authentication to Container-Managed Authentication alias.
When I run with Component-Managed Authentication, its working fine.
Does changing security setting to Container Managed Authentication alias, require some other/additional setting/changes? Or do I need to change my underlying Spring ibatis code to make it work?
Any help on configuring/implementing Container-Managed Authentication Alias in websphere would be appreciated.
Container-managed authentication applies when your code (or any third party code that executes upon its behalf) looks up the data source with a resource reference that specifies the resource authentication as container or leaves resource authentication unspecified, in which case it defaults to container.
Component-managed authentication applies when your code (or any third party code that executes upon its behalf) looks up the data source without a resource reference, or uses a resource reference that specifies the resource authentication as application.
Here are some examples of resource references that use container authentication:
// resource injection can be used on a web component (servlet) or ejb component
#Resource(name = "java:comp/env/jdbc/ds1ref", lookup = "jdbc/ds1", authenticationType = Resource.AuthenticationType.CONTAINER)
DataSource ds1;
#Resource(name = "java:comp/env/jdbc/ds2ref", lookup = "jdbc/ds2")
DataSource ds2;
...
// code that looks up one of the above resource references
DataSource ds = InitialContext.doLookup("java:comp/env/jdbc/ds1ref");
Here is an example of a resource reference defined within a web.xml deployment descriptor:
<resource-ref>
<res-ref-name>java:comp/env/jdbc/ds3ref</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
<lookup-name>jdbc/ds3</lookup-name>
</resource-ref>
If third party code, such as Spring, is looking up a data source on your behalf and you would like it to use container authentication, you will need to define a resource reference with container managed authentication, such as shown above in the examples, and supply its resource reference name to the third party software in place of however you are doing so currently. If you are unsure where this is done, it might help to search for occurrences of the configured JNDI name of the WebSphere data source within the application.

What is the required configuration steps to have a Spring Boot application send simple e-mails via AWS SES?

I have been fighting with this for several hours today. I started with the documentation at http://cloud.spring.io/spring-cloud-aws/spring-cloud-aws.html#_sending_mails which doesn't really say a lot about the specific steps. It just says that the developer can include a Bean XML and then autowire MailSender. I have tried that as well as many variants and have not been able to get it to work using spring-cloud-aws. I finally resorted to directly including aws-java-sdk-ses and manually configuring the class.
Here is a simple project demonstrating what I've tried:
https://github.com/deinspanjer/aws-ses-test
This project compiles, but when I run it I get:
Parameter 0 of constructor in com.example.awssestest.AwsSesTestApplication required a bean of type 'org.springframework.mail.MailSender' that could not be found.
- Bean method 'mailSender' not loaded because #ConditionalOnClass did not find required class 'javax.mail.internet.MimeMessage'
- Bean method 'simpleMailSender' not loaded because #ConditionalOnClass did not find required class 'com.amazonaws.services.simpleemail.AmazonSimpleEmailService'
- Bean method 'javaMailSender' not loaded because #ConditionalOnClass did not find required class 'com.amazonaws.services.simpleemail.AmazonSimpleEmailService'
If I try adding javax-mail ( https://github.com/deinspanjer/aws-ses-test/tree/try-with-javax-mail-api ) then the error changes to:
Parameter 0 of constructor in com.example.awssestest.AwsSesTestApplication required a bean of type 'org.springframework.mail.MailSender' that could not be found.
- Bean method 'mailSender' not loaded because AnyNestedCondition 0 matched 2 did not; NestedCondition on MailSenderAutoConfiguration.MailSenderCondition.JndiNameProperty #ConditionalOnProperty (spring.mail.jndi-name) did not find property 'jndi-name'; NestedCondition on MailSenderAutoConfiguration.MailSenderCondition.HostProperty #ConditionalOnProperty (spring.mail.host) did not find property 'host'
- Bean method 'simpleMailSender' not loaded because #ConditionalOnClass did not find required class 'com.amazonaws.services.simpleemail.AmazonSimpleEmailService'
- Bean method 'javaMailSender' not loaded because #ConditionalOnClass did not find required class 'com.amazonaws.services.simpleemail.AmazonSimpleEmailService'
If instead, I try explicitly adding a dependency on aws-java-sdk-ses ( https://github.com/deinspanjer/aws-ses-test/tree/try-with-aws-java-sdk-ses ), I get this error instead:
Parameter 0 of constructor in com.example.awssestest.AwsSesTestApplication required a bean of type 'org.springframework.mail.MailSender' that could not be found.
- Bean method 'mailSender' not loaded because #ConditionalOnClass did not find required class 'javax.mail.internet.MimeMessage'
- Bean method 'javaMailSender' in 'MailSenderAutoConfiguration' not loaded because #ConditionalOnClass did not find required class 'javax.mail.Session'
- Bean method 'simpleMailSender' in 'MailSenderAutoConfiguration' not loaded because #ConditionalOnMissingClass found unwanted class 'org.springframework.cloud.aws.mail.simplemail.SimpleEmailServiceJavaMailSender'
For this error, I tried adding a #Qualifier("simpleMailSender") annotation to the #Autowired, but it did not help.
I hope someone might be able to steer me in the right direction.
You may try below steps to fix your issue. I tried these changes in the forked repo from you and it works for me.
Add dependency "com.amazonaws:aws-java-sdk-ses" in pom.xml file.
Create an auto configuration class to configure the mail sender bean. Below is example. The AWSCredentialsProvider is configured and provided by spring-cloud-starter-aws out-of-the-box.
.
#Configuration
public class SimpleMailAutoConfig {
#Bean
public AmazonSimpleEmailService amazonSimpleEmailService(AWSCredentialsProvider credentialsProvider) {
return AmazonSimpleEmailServiceClientBuilder.standard()
.withCredentials(credentialsProvider)
// Replace US_WEST_2 with the AWS Region you're using for
// Amazon SES.
.withRegion(Regions.US_WEST_2).build();
}
#Bean
public MailSender mailSender(AmazonSimpleEmailService ses) {
return new SimpleEmailServiceMailSender(ses);
}
}
3. Use spring API to send mail using the configured mail sender.
Hope it helps.
Edit:
If you need to use JavaMailSender instead of MailSender (for instance when you want to send attachments), simply configure SimpleEmailServiceJavaMailSender instead of SimpleEmailServiceMailSender.
Like this:
#Bean
public JavaMailSender mailSender(AmazonSimpleEmailService ses) {
return new SimpleEmailServiceJavaMailSender(ses);
}
I used AWS SES in a Spring Boot web project some time ago, but I haven't used Spring Cloud AWS to integrate my application with the mail service.
Instead I simply included spring-boot-starter-mail among the project dependencies (pom.xml):
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
Then I set SMTP server parameters in my application.properties. In my case I used these properties:
spring.mail.host=email-smtp.eu-west-1.amazonaws.com
spring.mail.port=465
spring.mail.protocol=smtps
spring.mail.smtps.auth=true
spring.mail.smtp.ssl.enable=true
spring.mail.username=<my-user>
spring.mail.password=<my-password>
Note: server host and port may vary.
Spring Boot will create a default JavaMailSender instance, configuring it with the previos parametes. You can use this object to send emails...
Probably this in not the best approach to AWS SES integration with a Spring Boot application, but it works fine for me.
Add AWS-Java-sdk to your project
Setup AWS credentials (Keys) on your machine
Create SendEmailRequest
SendEmailRequest#.sendEmail(request)
p.s. You don't need any JavaMail here. You can wrap it to beans in Spring in any desired way.
you can do it through Application.properties also. Make Sure that You are not in the sandbox in AWS SES.
Verify your E-mail Adress or Domain for sending Email through SES.Go to SES DashBoard and select "Email Addresses".(For testing, you can Send a Demo email From SES DashBoard--> Email Addresses --> Send a Test email).
Create 'Access Key Id' and 'Secret access key'.(Without this keys You cannot send mail. You will get 535-Error).
3.Now put the keys in your application.properties. As Shown below
`spring.mail.host=email-smtp.us-east-1.amazonaws.com(Your Hosting region)
spring.mail.username=<Access Key Id>
spring.mail.password=<Secret access key>`
If you are using MimeMessage then set the Sending mail ID as given below:
MimeMessageHelper helper = new MimeMessageHelper(message);
helper.setFrom("yourmailID#yourDomain.com");
Hope It helps.
Just to add something to #davioooh answer,if anybody is using smtp interface of aws instead of aws sdk api,--
If you are using Port 465,then use protocol as smtps
But,If you are using Port 25,587,then you use protocol as smtp
It is mandatory.
If you are not using SMTPS while using port 465,then you will get exception in your springboot application.(Because,while using Port 465 client has to initiate the TLS while transferring the mail,so you have to mention SMTPS in your application.properties file.
Similarly,you are not required to use SMTPS while using Port 25,587 because in this case server first responds to the client that it is tls enabled or not,then the client initiates a tls encryption.So,you only have to use SMTP in case of Port 25,587.

Resources