Application error when creating simple web service using Spring Boot - web-services

I am getting below error when creating a simple web service that returns "hello" string
Whitelabel Error Page This application has no explicit mapping for
/error, so you are seeing this as a fallback.
My webservice endpoint:
#WebService
public class HelloWs {
#WebMethod
public String hello() {
return "hello";
}
}
My configuration class:
#Configuration
public class WebServiceConfig {
#Autowired
private Bus bus;
#Bean
public Endpoint endpoint() {
Endpoint endpoint = new EndpointImpl(bus, new HelloWs());
endpoint.publish("/hello");
return endpoint;
}
}
My pom.xml dependencies:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-spring-boot-starter-jaxws</artifactId>
<version>3.2.7</version>
</dependency>
</dependencies>
My project structure:

If you are using mvn spring-boot:run then cxf web services are host at /services/*, Thus at url http://localhost:8080/services you will find list of the cxf endpoints, in your case it will be only one. And you get wsdl at location http://localhost:8080/services/hello?wsdl
If you are deploying to any app server add context path before services.

Related

I have a problem with using AWS secrets manager with Spring Boot app to get AWS RDS credentials

this is my pom.xml dependencie that I'm using:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.amazonaws.secretsmanager</groupId>
<artifactId>aws-secretsmanager-jdbc</artifactId>
<version>${aws-secretsmanager-jdbc.version}</version>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
</dependency>
</dependencies>
<properties>
<aws-secretsmanager-jdbc.version>1.0.5</aws-secretsmanager-jdbc.version>
</properties>
this is my application.properties:
spring.datasource.driver-classname=com.amazonaws.secretsmanager.sql.AWSSecretsManagerPostgreSQLDriver
spring.jpa.database-platform=org.hibernate.dialect.PostgreSQLDialect
spring.datasource.url=jdbc-secretsmanager:postgresql://postgres-db.cjqt4bf02oy9.ap-northeast-2.rds.amazonaws.com:5432/postgres-db
spring.datasource.username=dev/dbCreds/demo
unfortunately I got this error:
com.amazonaws.services.secretsmanager.model.ResourceNotFoundException: Secrets Manager can't find the specified secret. (Service: AWSSecretsManager; Status Code: 400; Error Code: ResourceNotFoundException; Request ID: 6571600b-61bc-4889-ad74-f41c678bfd89; Proxy: null)
BTW I was following this article: Spring Boot Externalized Database Configuration with AWS Secrets Manager
I have searched around but couldn't find any solution.

Unable to override uri-endpoint-override override-endpoint options for STS

Our goal is to no longer access AWS endpoints via a custom proxy but to access them via VPC endpoints from AWS. To make this work in our secured network we use our own VPC endpoints which we configure with the option: uri-endpoint-override (string) and override-endpoint (boolean). Now the problem is that the options are not used at all and the application always uses the default endpoints which have no access in our network. Because of this the STS component can't execute a HTTP request.
And in the console the following error message appears:
Unable to execute HTTP request: Connect to sts.eu-central-1.amazonaws.com:443 [sts.eu-central-1.amazonaws.com/54.239.54.207] failed: Connect timed out, ContainerCredentialsProvider(): Cannot fetch credentials from container - neither AWS_CONTAINER_CREDENTIALS_FULL_URI or AWS_CONTAINER_CREDENTIALS_RELATIVE_URI environment variables are set
As taken from the error message, the default endpoint sts.eu-central-1.amazonaws.com:443 is used.
This is how our application.properties looks in which the options are set:
camel.component.aws2-sts.override-endpoint=true
camel.component.aws2-sts.uri-endpoint-override=https://vpce-???-???.sts.eu central1.vpce.amazonaws.com
We are using the following versions:
Apache Camel 3.14.2
Spring Boot 2.5.10
Dependencies
<properties>
<java.version>14</java.version>
<camel.version>3.14.2</camel.version>
<spring-boot.version>2.5.10</spring-boot.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.camel.springboot</groupId>
<artifactId>camel-aws2-s3-starter</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.camel.springboot</groupId>
<artifactId>camel-aws2-sts-starter</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-jetty</artifactId>
<version>${camel.version}</version>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-json-validator</artifactId>
<version>${camel.version}</version>
</dependency>
</dependencies>
Info
With ticket CAMEL-16171 , Camel added the usage of uri-endpoint-override and override-endpoint options attributes for all AWS components among others for STS.
Do you have any idea why the options are not overwritten? Thanks a lot for your help!

https not working as expected on swisscom CloudFoundry

I have a very simple spring boot application which as one controller:
#RestController
public class HomeController {
#GetMapping(path = "/")
public String getHome() {
return "Hello world";
}
}
and the following security configuration to enforce https:
#Configuration
public class SslWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
// require https!
http.requiresChannel().anyRequest().requiresSecure();
}
}
the application.properties looks like this:
server.tomcat.remote-ip-header=x-forwarded-for
server.tomcat.protocol-header=x-forwarded-proto
the maven dependencies are:
<dependencies>
<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>
</dependencies>
The manifest.mf looks like this:
applications:
- name: jt-demo
memory: 1G
instances: 1
path: ./target/demo.jar
buildpacks:
- https://github.com/cloudfoundry/java-buildpack#v4.17.2
env:
JAVA_OPTS: -Djava.security.egd=file:///dev/urandom
JBP_CONFIG_OPEN_JDK_JRE: '{jre: { version: 11.+ }}'
I install the app on two different cloudfoundry providers (pivotal and swisscom) via this command: cf push jt-demo -f manifest.yml
when I run this app on https://run.pivotal.io, and access it via https it works as expected and the browser shows me the expected "Hello world". But when I run it on the swisscom developer application cloud (https://developer.swisscom.com), then I get ERR_TOO_MANY_REDIRECTS (to many 302).
It seems the two cloudfoundry environments are not handling HTTPS the same way.
I know pivotal runs the cf api version 2.138.0 and swisscom has 2.136.0 - but I don't expect this to be the reason.
How can I fix the app/configuration for swisscom dev?
I finally found the answer to my problem here Spring Boot HTTPS redirect loop after Swisscom Application Cloud update
https://docs.developer.swisscom.com/devguide-sc/buildpacks/java/caveats.html
it's a bit unexpected to have to configure server.tomcat.internal-proxies for swisscom...

AWS Beanstalk: Cannot determine embedded database driver class

I have a spring boot application which runs just fine on my local instance (through Intellij) but while deploying on AWS BEanstalk, the application throws the following error (sorry about the formatting. This is how spring generated the exception):
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfig
uration$JdbcTemplateConfiguration': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationExcept
ion: Could not autowire field: private javax.sql.DataSource org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration$JdbcTemplateConfigur
ation.dataSource; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSource' defined in cla
ss path resource [org/springframework/boot/autoconfigure/jdbc/DataSourceAutoConfiguration$NonEmbeddedConfiguration.class]: Bean instantiation via factor
y method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [javax.sql.DataSource]: Factory method
'dataSource' threw exception; nested exception is org.springframework.boot.autoconfigure.jdbc.DataSourceProperties$DataSourceBeanCreationException: Cann
ot 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 "aws" are currently active).
pom.xml
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-rest</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-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk-dynamodb</artifactId>
<version>1.10.56</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<configuration>
<archive>
<manifest>
<mainClass>com.my.app.path.MyApplication</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
</plugins>
</build>
application.properties
spring.profiles.active=aws
dynamodb.tablename=my_dynamodb_table
application-aws.properties
spring.profiles.active=aws
The application uses a table in dynamodb. Could this be because I might need to set permissions in AWS to allow beanstalk to talk to dynamodb? If so, please let me know how to do that.
My EC2 instance is tomcat8 type.
Found the solution to my question on this post. See the answer by #user672009.
Just add this to your pom.
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>1.3.156</version>
</dependency>

Spring boot deploy external tomcat

I'm using spring boot with a simple hello world controller. I would like to deploy it to external tomcat server. I've noticed that web.xml file is missing. I expected to see this file inside web-inf directory.
When running spring boot internally (with the internal tomcat of spring boot, it works. But I would like to deploy my app to external tomcat server.
After deploying the war file to external tomcat server, I can see the hello world in the available services list, but I can't use the hello world service - I get 404 error message instead.
I'm using maven, Jdk 1.8, IntelliJ
This is my pom.xml:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.springframework</groupId>
<artifactId>gs-spring-boot</artifactId>
<version>0.1.0</version>
<packaging>war</packaging>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.3.1.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-plugin-api</artifactId>
<version>3.3.9</version>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
<version>1.9.2.RELEASE</version>
</dependency>
</dependencies>
<properties>
<java.version>1.8</java.version>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>2.6</version>
<configuration>
<attachClasses>true</attachClasses>
</configuration>
</plugin>
</plugins>
</build>
</project>
This is my Application class:
import java.util.Arrays;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.context.web.SpringBootServletInitializer;
import org.springframework.context.ApplicationContext;
#SpringBootApplication
public class Application extends SpringBootServletInitializer {
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(Application.class);
}
public static void main(String[] args) {
ApplicationContext ctx = SpringApplication.run(Application.class, args);
System.out.println("Let's inspect the beans provided by Spring Boot:");
String[] beanNames = ctx.getBeanDefinitionNames();
Arrays.sort(beanNames);
for (String beanName : beanNames) {
System.out.println(beanName);
}
}
}
What is the right way to deploy the hello world app to external tomcat service?
When deploying on tomcat, there should be a context path added by the container and that have to be included as first element path in your URL. Check tomcat startup logs to get the context path and retry calling the service as indicated.
If Spring boot app on external Tomcat is deployed successfully and no error are thrown, it is reachable not through localhost:8080/ but localhost:8080/your-deployed-war-file-name.
You can add finalName to your pom.xml to avoid adding versions to built war filename - Maven : How to avoid version appended to a war file in Maven?:
<build>
<finalName>${project.artifactId}</finalName>
</build>