Issue connecting pub/sub from PCF - spring-boot

I'm trying to connect google Pub/Sub from PCF environment(Spring boot app). The app is successfully loaded the credentials from credentials.json file and it printed Project ID. but it is printing below error after started.
c.g.a.oauth2.ComputeEngineCredentials : Failed to detect whether we are running on Google Compute Engine.
ERROR 13 --- [nio-8080-exec-4] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is java.lang.IllegalStateException: Expected the service InnerService [FAILED] to be RUNNING, but the service has FAILED] with root cause
java.io.IOException: The Application Default Credentials are not available. They are available if running in Google Compute Engine. Otherwise, the environment variable GOOGLE_APPLICATION_CREDENTIALS must be defined pointing to a file defining the credentials. See https://developers.google.com/accounts/docs/application-default-credentials for more information.
Here is the code which I'm using and I'm invoking this method from a sample rest controller.
public static void subscribeAsyncExample(String projectId, String subscriptionId) {
ProjectSubscriptionName subscriptionName =
ProjectSubscriptionName.of(projectId, subscriptionId);
System.out.println("Processing messages...");
MessageReceiver receiver =
(message, consumer) -> {
System.out.println("Id : " + message.getMessageId());
System.out.println("Data : " + message.getData().toStringUtf8());
consumer.ack();
};
Subscriber subscriber = null;
try {
subscriber = Subscriber.newBuilder(subscriptionName, receiver).build();
subscriber.startAsync().awaitRunning();
subscriber.awaitTerminated();
} finally {
if (subscriber != null) {
subscriber.stopAsync();
}
}
}
pom.xml
Spring boot: 2.3.2.RELEASE
spring-cloud-gcp.version: 1.1.3.RELEASE
`
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-gcp-starter-pubsub</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.google.cloud</groupId>
<artifactId>google-cloud-pubsub</artifactId>
</dependency>
<dependency>
<groupId>com.google.cloud</groupId>
<artifactId>google-cloud-storage</artifactId>
</dependency>
`
Log:
The default project ID is *******
Default credentials provider for service account *****-client-account#*******.gserviceaccount.com
Scopes in use by default credentials: [https://www.googleapis.com/auth/pubsub, https://www.googleapis.com/auth/trace.append, https://www.googleapis.com/auth/spanner.admin, https://www.googleapis.com/auth/cloudruntimeconfig, https://www.googleapis.com/auth/sqlservice.admin, https://www.googleapis.com/auth/devstorage.read_only, https://www.googleapis.com/auth/devstorage.read_write, https://www.googleapis.com/auth/cloud-platform, https://www.googleapis.com/auth/spanner.data, https://www.googleapis.com/auth/datastore, https://www.googleapis.com/auth/cloud-vision]

Related

Access token not propagated in Spring Boot 2.7

We use Spring Boot with an OIDC integration to provide authentication and authorization to our users.
Our application acts as Client in the OIDC code flow, calling downstream Resource servers through Http requests to serve user requests.
To have the Client pass the access token of the authenticated user to Resource servers we use the ServletOAuth2AuthorizedClientExchangeFilterFunction and apply that to the org.springframework.web.reactive.function.client.WebClient handling downstream requests.
We recently upgraded from Spring Boot 2.6.7 to 2.7.3 and discovered that the Authentication header containing the access token is no
longer added to outgoing requests, if those requests are scheduled on a thread other than the one serving the original request:
public class MyController {
public Mono<ProductSearchResult> searchByName(SearchProductsQuery query) {
List<String> sortOrder = new ArrayList<>();
System.out.println("--OUTER: " + Thread.currentThread().getName());
return resourceServere.searchByName(query)
.doOnNext(searchResponse -> sortOrder.addAll(searchResponse.getIds()))
.flatMap(searchResponse -> Mono.zip(
getSomething(searchResponse.getIds()),
getSomethingElse(searchResponse.getIds()),
Mono.just(searchResponse.pagination())))
.map(tuple3 -> SearchResultMapper.map(tuple3.getT1(), tuple3.getT2(), tuple3.getT3()));
}
private Mono<List<String>> getSomething(List<String> ids) {
System.out.println("--INNER: " + Thread.currentThread().getName());
if (ids.isEmpty()) {
return Mono.just(new ArrayList<>());
}
return otherResourceServerClient.getStuff(ids);
}
}
Which prints
--OUTER: http-nio-8080-exec-6
--INNER: reactor-http-nio-3
Debugging ServletOAuth2AuthorizedClientExchangeFilterFunction we discovered that the request in the http-nio-thread has the Authentication:
Debugger stopped in ServletOAuth2AuthorizedClientExchangeFilterFunction
whereas the request in the reactor-http thread does not:
Debugger stopped in ServletOAuth2AuthorizedClientExchangeFilterFunction
I can certainly provide more information about our setup, I'm just a bit uncertain what would be relevant.
For starters though, we depend on both spring-starter-webflux and spring-boot-starter-web, as well as on spring-boot-starter-security
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
Curious to hear if anyone has experienced the same issue?

Why does java Spring return no such method exception for aws sdk while initializing the awsS3Client

I'm trying to upload dynamic objects into the s3 bucket in my web application.
But struggling with no such method error during initializing the AWS3Client.
Initially, the input is a multipart image saving it into a local machine and then using it for uploading it into the s3 bucket.
During uploading the No such method exception occurs as shown in the first image.
Exception snapshot during client initialization
Also, specified the amazon dependency used into pom in the second picture.
pom-Amazon_dependency
following is the code used for initiating s3client into the application.
Map<String, String> s3Credentials = ((FSRepositoryServiceImpl) fsRepositoryService).getS3Credentials();
AmazonS3 s3 = AmazonS3ClientBuilder.standard().withRegion(Regions.AP_SOUTH_1).withCredentials(
new AWSStaticCredentialsProvider(new BasicAWSCredentials(s3Credentials.get("accessKeyId"),
s3Credentials.get("secretAccessKey"))))
.build();
Here are some more details about the issue
Pom dependency
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.4.3</version>
</dependency>
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-core-asl</artifactId>
<version>1.9.13</version>
</dependency>
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
<version>1.9.13</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.13.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.amazonaws/aws-java-sdk-s3 -->
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk-s3</artifactId>
<version>1.12.150</version>
</dependency>
Code to upload object into s3 bucket:
//Save temporary document in file format for uploading to s3
Map<String, String> s3ObjectDetails = fsRepositoryService.saveTempDocumentforS3Reference(
basePatientDocumentsRepoPath, docContents, ext, originalImgFileName);
//Credentials for aws account
Map<String, String> s3Credentials = ((FSRepositoryServiceImpl) fsRepositoryService).getS3Credentials();
AmazonS3 s3 = AmazonS3ClientBuilder.standard().withRegion(Regions.AP_SOUTH_1).withCredentials(
new AWSStaticCredentialsProvider(new BasicAWSCredentials(s3Credentials.get(<accessKeyId>),
s3Credentials.get(<secretAccessKey>))))
.build();
//bucket details on the aws cloud
Map<String, String> bucketDetails = ((FSRepositoryServiceImpl) fsRepositoryService).getBucketDetails(
/* used this for dynamic key name for bucket */s3ObjectDetails.get(<document Name>));
String uploadingPath = bucketDetails.get(<filePath>) + "/" + patientId + "/";
uploadingPath = uploadingPath.replace("//", "/");
String fileToUpload = s3ObjectDetails.get(<Pathofthedocument>);
PutObjectRequest objectRequest = new PutObjectRequest(bucketDetails.get(bucket),
uploadingPath + bucketDetails.get(<key>), <fileToUpload>);
ObjectMetadata metadata = new ObjectMetadata();
metadata.setContentType("plain/text");
metadata.addUserMetadata(<key Name>, bucketDetails.get(key));
objectRequest.setMetadata(metadata);
PutObjectResult uploadImagetoS3 = s3.putObject(objectRequest);
Error statement:
02:54,190 INFO :
Saving Doc 5f5ab725-0403-4554-b62c-674130c9a8f2-1643628704942 under: /data/ihealwell/patients/ImagePrescription/20808/
Jan 31, 2022 5:07:27 PM org.apache.catalina.core.StandardWrapperValve invoke
SEVERE: Servlet.service() for servlet [api-dispatcher] in context with path [/IHW] threw exception [Handler processing failed; nested exception is java.lang.NoSuchMethodError: com.fasterxml.jackson.databind.ObjectMapper.enable([Lcom/fasterxml/jackson/core/JsonParser$Feature;)Lcom/fasterxml/jackson/databind/ObjectMapper;] with root cause
java.lang.NoSuchMethodError: com.fasterxml.jackson.databind.ObjectMapper.enable([Lcom/fasterxml/jackson/core/JsonParser$Feature;)Lcom/fasterxml/jackson/databind/ObjectMapper;
at com.amazonaws.partitions.PartitionsLoader.(PartitionsLoader.java:54)
at com.amazonaws.regions.RegionMetadataFactory.create(RegionMetadataFactory.java:30)
at com.amazonaws.regions.RegionUtils.initialize(RegionUtils.java:64)
at com.amazonaws.regions.RegionUtils.getRegionMetadata(RegionUtils.java:52)
at com.amazonaws.regions.RegionUtils.getRegion(RegionUtils.java:106)
at com.amazonaws.client.builder.AwsClientBuilder.getRegionObject(AwsClientBuilder.java:256)
at com.amazonaws.client.builder.AwsClientBuilder.withRegion(AwsClientBuilder.java:245)
at com.amazonaws.client.builder.AwsClientBuilder.withRegion(AwsClientBuilder.java:232)
at com.indohealth.ihealwell.web.rest.controller.PatientResourceController.saveOnS3Resource(PatientResourceController.java:1932)
at com.indohealth.ihealwell.web.rest.controller.PatientResourceController.saveDocumentOnGlobalResource(PatientResourceController.java:1891)
at com.indohealth.ihealwell.web.rest.controller.DocumentResourceController.updateDocumentbyPatient(DocumentResourceController.java:288)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)

Configure HTTPS in Spring Boot Apache Camel REST API with keystore having multiple certs using camel-jetty component

I am trying to configure https in my apache camel Spring Boot REST application (using apache-camel v3.11.1, springboot v2.5.3) with keystore having multiple certificates.
Problem:
Application run failed
org.apache.camel.RuntimeCamelException: java.lang.IllegalStateException: KeyStores with multiple certificates are not supported on the base class org.eclipse.jetty.util.ssl.SslContextFactory. (Use org.eclipse.jetty.util.ssl.SslContextFactory$Server or org.eclipse.jetty.util.ssl.SslContextFactory$Client instead)
at org.apache.camel.RuntimeCamelException.wrapRuntimeCamelException(RuntimeCamelException.java:51) ~[camel-api-3.11.1.jar:3.11.1]
Project setup:
pom.xml: (dependencies only, to show that I am not using spring-boot-web-starter)
..
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.apache.camel.springboot</groupId>
<artifactId>camel-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.apache.camel.springboot</groupId>
<artifactId>camel-jetty-starter</artifactId>
</dependency>
..
..<!-- all other required dependencies are in place-->
..
</dependencies>
..
application.properties
#camel.component.jetty.keystore=keystore-with-one-certificate.jks # WORKS
camel.component.jetty.keystore=keystore-with-multiple-certificates.jks # DOESN'T WORK
camel.component.jetty.ssl-key-password=password
camel.component.jetty.ssl-password=password
Rest Route:
restConfiguration()
.component("jetty")
.scheme("https")
.port("8080");
rest()
.path("/api")
.get("/{name}")
..
..
.to("direct:x");
Looked at answers in the below posts, but still not able to resolve the exception that I get,
https://stackoverflow.com/a/60598953/6363894,
https://stackoverflow.com/a/55499113/6363894
I know that exception clearly states to use org.eclipse.jetty.util.ssl.SslContextFactory$Server, but I don't understand how/where to use SslContextFactory.Server object.
SslContextFactory.Server sslContextFactory = new SslContextFactory.Server();
sslContextFactory.setKeyStoreResource(findKeyStorePath());
sslContextFactory.setKeyStorePassword("password");
sslContextFactory.setKeyManagerPassword("password");
sslContextFactory.setNeedClientAuth(true);
Also I've created a bean for sslContextParameters and added that to restConfiguration as below, this time application runs successfully but then when I test, SSL handshake fails.
restConfiguration()
.component("jetty")
.endpointProperty("sslContextParameters", "#sslContextParameters")
.scheme("https")
.port("8080");
#Bean(name = "sslContextParameters")
public SSLContextParameters setSSLContextParameters() {
KeyStoreParameters ksp = new KeyStoreParameters();
ksp.setResource("keystore-with-multiple-certificates.jks");
ksp.setPassword("password");
KeyManagersParameters kmp = new KeyManagersParameters();
kmp.setKeyStore(ksp);
kmp.setKeyPassword("password");
SSLContextServerParameters scsp = new SSLContextServerParameters();
scsp.setClientAuthentication("REQUIRE");
SSLContextParameters scp = new SSLContextParameters();
scp.setServerParameters(scsp);
scp.setKeyManagers(kmp);
return scp;
}
Any help on how to configure SslContextFactory.Server object with the restConfigurations() or any other way I can achieve this? I'll update the post, if any more details are required.

Spring - Websockets - JSR-356

I implemented websockets into my application. I copied the configuration and dependencies from jHipster generated app, but I am getting the following errors:
java.lang.IllegalArgumentException: No 'javax.websocket.server.ServerContainer' ServletContext attribute. Are you running in a Servlet container that supports JSR-356?
and
org.apache.catalina.connector.ClientAbortException: java.io.IOException: An established connection was aborted by the software in your host machine
I believe these errors are the reason for the socket connection not being consistent and the therefore the client is not able to send and/or receive any messages.
I searched for a solution but other post didn't help (ie. adding glassfish dependencies).
These are my ws dependencies:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-messaging</artifactId>
</dependency>
Do I need to include some other dependencies or is the problem elsewhere?
I found a solution here.
I added these 2 beans:
#Bean
public TomcatServletWebServerFactory tomcatContainerFactory() {
TomcatServletWebServerFactory factory = new TomcatServletWebServerFactory();;
factory.setTomcatContextCustomizers(Collections.singletonList(tomcatContextCustomizer()));
return factory;
}
#Bean
public TomcatContextCustomizer tomcatContextCustomizer() {
return new TomcatContextCustomizer() {
#Override
public void customize(Context context) {
context.addServletContainerInitializer(new WsSci(), null);
}
};
}

HikariCP with Spring boot autoconfiguration & Spring Data

I am trying to use spring boot(1.4.3.RELEASE) autoconfoguration. This is a multi module project.
parent project
|---pom.xml -> This is a parent pom.
|---repository(Spring Data)
|---pom.xml
|---src
|---web
|---pom.xml
|---src
My application.properties,
# Dialer Data Access
spring.datasource.hikari.connection-test-query=SELECT 1 FROM DUAL
spring.datasource.hikari.minimum-idle=5
spring.datasource.hikari.maximum-pool-size=10
spring.datasource.hikari.pool-name=cc_dialer
spring.datasource.hikari.driver-class-name=com.mariadb.jdbc.Driver
spring.datasource.hikari.url=jdbc:mysql://localhost:3306/dialer
spring.datasource.hikari.username=root
spring.datasource.hikari.password=root
spring.datasource.hikari.type com.zaxxer.hikari.HikariDataSource
web module Application.java,
#SpringBootApplication(exclude = { VelocityAutoConfiguration.class }, scanBasePackages =
{ "com.test.dbrepo.repository" })
#EnableScheduling
public class DialerApplication {
Web pom.xml,
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
Repository application,
#SpringBootApplication(scanBasePackages = { "com.cc.dialer.dbrepo" })
public class DialerDBServiceApplication {
Repository pom.xml,
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/com.zaxxer/HikariCP -->
<dependency>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
<!-- <version>2.5.1</version>-->
</dependency>
<!-- https://mvnrepository.com/artifact/org.mariadb.jdbc/mariadb-java-client -->
<dependency>
<groupId>org.mariadb.jdbc</groupId>
<artifactId>mariadb-java-client</artifactId>
<!-- <version>1.5.7</version>-->
</dependency>
I am trying to use Spring boot autoconfiguration, but getting the below error.
2017-01-17 14:57:59.903 [main] WARN o.s.b.c.e.AnnotationConfigEmbeddedWebApplicationContext - Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration': Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSource' defined in class path resource [org/springframework/boot/autoconfigure/jdbc/DataSourceConfiguration$Tomcat.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.apache.tomcat.jdbc.pool.DataSource]: Factory method 'dataSource' threw exception; nested exception is org.springframework.boot.autoconfigure.jdbc.DataSourceProperties$DataSourceBeanCreationException: Cannot determine embedded database driver class for database type NONE. If you want an embedded database please put a supported one on the classpath. If you have database settings to be loaded from a particular profile you may need to active it (the profiles "dev" are currently active).
2017-01-17 14:57:59.905 [main] INFO o.a.catalina.core.StandardService - Stopping service Tomcat
2017-01-17 14:57:59.911 [main] WARN o.s.boot.SpringApplication - Error handling failed (Error creating bean with name 'delegatingApplicationListener' defined in class path resource [org/springframework/security/config/annotation/web/configuration/WebSecurityConfiguration.class]: BeanPostProcessor before instantiation of bean failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration': Initialization of bean failed; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'org.springframework.context.annotation.ConfigurationClassPostProcessor.importRegistry' available)
2017-01-17 14:57:59.914 [main] ERROR o.s.b.d.LoggingFailureAnalysisReporter -
***************************
APPLICATION FAILED TO START
***************************
Description:
Cannot determine embedded database driver class for database type NONE
You can use something like below in your property file configuration.
spring.datasource.url=jdbc:mysql://localhost/test
spring.datasource.username=<user>
spring.datasource.password=<password>
spring.datasource.driver-class-name=<driver classname>
spring.datasource.type=com.zaxxer.hikari.HikariDataSource
spring.datasource.hikari.maximum-pool-size=50
spring.datasource.hikari.idle-timeout=1000
spring.datasource.hikari.pool-name=blah

Resources