Show a static HTML page while the Spring context initializes - spring

Spring Boot 2.3.7, Embedded Jetty, JSP and WAR packaging. I want to show my some static HTML page while spring context initializes. It should be visible when application starts and before spring context refreshed. I tried to use this manual as example https://www.nurkiewicz.com/2015/09/displaying-progress-of-spring.html but this doesn't work.
I need to start embedded jetty directly when jetty is initialized. But spring boot starts embedded jetty only when context refreshed.
How should I do this?

I created a Jetty warpper warmup class:
public final class WarmupServer {
private final String contextPath;
private final String displayName;
private final DefaultApplicationArguments arguments;
private final String[] welcomeFiles;
private final Resource baseResource;
private Server server;
public WarmupServer(String contextPath,
String displayName,
Resource baseResource,
String[] welcomeFiles,
String... runArgs) {
this.contextPath = StringUtils.defaultIfBlank(contextPath, "/");
this.displayName = StringUtils.defaultIfBlank(displayName, "Warmup");
this.baseResource = ObjectUtils.defaultIfNull(baseResource, Resource.newClassPathResource("/static"));
this.welcomeFiles = ArrayUtils.isEmpty(welcomeFiles) ? new String[]{"html/warmup.html"} : welcomeFiles;
this.arguments = new DefaultApplicationArguments(ArrayUtils.nullToEmpty(runArgs));
}
public Server start() throws Exception {
if (server != null && server.isStarted()) {
throw new IllegalStateException("Server already started");
}
server = new Server();
server.setHandler(buildServletHandler());
final String configPath = parseArg(OPT_CONFIG);
if (StringUtils.isBlank(configPath)) {
throw new RuntimeException(OPT_CONFIG + " argument is not set");
}
final Config config = ConfigUtils.parseFile(new File(configPath), DEFAULT_CONFIG_FILE_NAME);
configureHttpConnector(config);
configureHttpsConnector(config);
server.start();
return server;
}
public void registerWarmupServerStopLifecycle(ConfigurableApplicationContext context) {
context.getBeanFactory()
.registerSingleton(WarmupStopLifecycle.class.getSimpleName(), new WarmupStopLifecycle(server));
}
private ServletContextHandler buildServletHandler() {
final ServletContextHandler handler = new ServletContextHandler(ServletContextHandler.SESSIONS);
handler.addServlet(DefaultServlet.class, "/");
handler.setDisplayName(displayName);
handler.setContextPath(contextPath);
handler.setWelcomeFiles(welcomeFiles);
handler.setBaseResource(baseResource);
return handler;
}
private void configureHttpConnector(Config config) {
final int httpPort = NumberUtils.toInt(parseArg(OPT_HTTP_PORT), config.getInt(OPT_HTTP_PORT));
final ServerConnector connector = new ServerConnector(server);
connector.setPort(httpPort);
server.addConnector(connector);
}
private void configureHttpsConnector(Config config) {
final int httpsPort = NumberUtils.toInt(
parseArg(OPT_HTTPS_PORT), config.getInt(OPT_HTTPS_PORT));
final String keyStorePath = StringUtils.defaultIfBlank(
parseArg(OPT_KEYSTORE_FILE), config.getString(OPT_KEYSTORE_FILE));
final boolean sslEnabled = StringUtils.isNotBlank(keyStorePath)
&& Files.isReadable(Paths.get(keyStorePath));
if (sslEnabled) {
final HttpConfiguration configuration = new HttpConfiguration();
configuration.setSecurePort(httpsPort);
configuration.setSecureScheme(HTTPS_SCHEME);
final ServerConnector httpsConnector = new HttpsConnector()
.createConnector(server, configuration, config.getConfig(JETTY_HTTPS_CONFIG), httpsPort);
server.addConnector(httpsConnector);
}
}
private String parseArg(String optionName) {
final List<String> values = arguments.getOptionValues(optionName);
return CollectionUtils.isEmpty(values) ? StringUtils.EMPTY : values.get(0);
}
public static WarmupServer start(String contextPath,
String displayName,
Resource baseResource,
String[] welcomeFiles,
String... runArgs) throws Exception {
final WarmupServer server = new WarmupServer(contextPath, displayName, baseResource, welcomeFiles, runArgs);
server.start();
return server;
}
}
This wrapper parses command line arguments and creates a Jetty handler and HTTP and (or) HTTPS connectors by using provided command line arguments.
And the simple Spring's Lifecycle implementation class:
#RequiredArgsConstructor
class WarmupStopLifecycle implements SmartLifecycle {
private static final Logger logger = LogManager.getFormatterLogger();
private final Server warmupServer;
private volatile boolean isRunning;
#Override
public void start() {
try {
warmupServer.stop();
isRunning = true;
} catch (Exception e) {
logger.error("Failed to stop warmup server", e);
throw new RuntimeException("Failed to stop warmup server", e);
}
}
#Override
public void stop() {
}
#Override
public boolean isRunning() {
return isRunning;
}
/**
* Returns phase of this lifecycle.
* A phase MUST be before the Spring web server starts.
* See {#code org.springframework.boot.web.servlet.context.WebServerStartStopLifecycle} phase.
*/
#Override
public int getPhase() {
return Integer.MAX_VALUE - 2;
}
}
So usage of this:
#SpringBootApplication
public class SpringApplication {
public static void main(String[] args) throws Exception {
final WarmupServer warmupServer = WarmupServer.start(
"/my_context_path", "My Warmup server handler", args);
new SpringApplicationBuilder()
.sources(SpringApplication.class)
.initializers(warmupServer::registerWarmupServerStopLifecycle)
.run(args);
}
}
WarmupServer starts immediately after the application runs and will be stopped before starting the Spring's web server.

Related

defaultServlet cant find index.html

i implemented a servlet container, Ioc without any dependency.
and when i try to forward to static/resource i set this request to go DefaultServlet.
public class DefaultServlet extends HttpServlet {
for processing about all the static resouces under resource folder
(index.html)
but the path of request response with 'file not exists' in this Default
how can get path of static resource?
this is my code
there are no settings about servlet, and ioc
private void selfInitialize(ServletContext servletContext) {
ServletRegistration.Dynamic gServlet = servletContext.addServlet(GCI_SERVLET_NAME,new DefaultServlet());
gServlet.setLoadOnStartup(1);
gServlet.addMapping("/");
// ServletRegistration.Dynamic servletRegistration = servletContext.addServlet(DISPATCHER_SERVLET_NAME, new DispatcherServlet());
// servletRegistration.setLoadOnStartup(2);
// servletRegistration.addMapping("/");
FilterRegistration.Dynamic filterRegistration = servletContext.addFilter("encodingFilter", new CharacterEncodingFilter());
filterRegistration.addMappingForUrlPatterns(null, false, "/*");
}
this is my ioc container, and not implements ResourceLoader
public class ApplicationContext implements BeanFactory {
private static ApplicationContext context = new ApplicationContext();
private static final Logger log = LoggerFactory.getLogger(ApplicationContext.class);
private static Map<String, CustomBeanDefinition> beanDefinitions;
CustomBeanDefinitionGenerator generator;
private Set<Class<?>> requiredBeans;
BeanScanner scan;
private ApplicationContext() {};
public void initialize(String basePackage) {
log.debug("star to scan : {}", basePackage);
scan = new BeanScanner(basePackage);
requiredBeans = scan.getTypesWith(Controller.class, Service.class, Component.class);
generator = new CustomBeanDefinitionGenerator(requiredBeans);
generator.instantiate();
generator.registerBean();
beanDefinitions = generator.getBeanDefinitions();
}
public static ApplicationContext getInstance(){
if(context != null){
return context;
}
return new ApplicationContext();
}
public static Map<String, CustomBeanDefinition> getAllBeanDefinitions() {
return beanDefinitions;
}
public static Set<Object> getAllBeans() {
return beanDefinitions
.values()
.stream()
.map(CustomBeanDefinition::getBean)
.collect(Collectors.toSet());
}
#Override
public Object getBean(Class<?> clazz) {
String beanName = createBeanName(clazz);
return getBean(beanName);
}
public Object getBean(String beanName) {
return beanDefinitions.get(beanName).getBean();
}
}
in this code of DefaultServlet.
resource.exist() return false

My junit test is not #Autowiring. What am I missing

I am trying to unit test my Spring Boot project in Eclipse. The problem I am having is that my #Autowire s are being ignored.
#SpringBootTest
public class ValidateRepositoryTest {
private static final String CREATE_TBLVALIDATE_SQL_SCRIPT = "scripts/create/validate.sql";
private static final String DROP_TBLVALIDATE_SQL_SCRIPT = "scripts/drop/validate.sql";
private static final Logger logger = Logger.getLogger(ValidateRepositoryTest.class);
#Autowired
private JdbcTemplate jdbc;
#Before
public void before() throws SQLException {
if (jdbc == null) {
logger.fatal("jdbc == null in ValidateRepositoryTest.before()");
return;
}
ScriptUtils.executeSqlScript(jdbc.getDataSource().getConnection(), new ClassPathResource(CREATE_TBLVALIDATE_SQL_SCRIPT));
}
#After
public void after() throws SQLException {
if (jdbc == null) {
logger.fatal("jdbc == null in ValidateRepositoryTest.before()");
return;
}
ScriptUtils.executeSqlScript(jdbc.getDataSource().getConnection(), new ClassPathResource(DROP_TBLVALIDATE_SQL_SCRIPT));
}
#Autowired
ValidateRepository validateRepository;
#Test
public void testFindByKeyCode() {
if (jdbc == null) {
logger.fatal("validateRepository == null in ValidateRepositoryTest.testFindByKeyCode()");
return;
}
String documentTypeKeyCode = Validate.DOCUMENT_TYPE_CLAIMS_APPROVAL;
String sendMethodKeyCode = Validate.DOCUMENT_SEND_METHOD_EMAIL;
Validate validate = validateRepository.findByKeyCode(documentTypeKeyCode);
assertEquals("Shortage Claims Approval POD", validate.getDescription());
}
}
The output.
[INFO] Running com.kable.newsstand.batch.shortage_claim_auto_accept.entities.validate.test.ValidateRepositoryTest
09:40:51.029 [main] ERROR com.kable.newsstand.batch.shortage_claim_auto_accept.entities.validate.test.ValidateRepositoryTest - jdbc == null in ValidateRepositoryTest.before()
09:40:51.036 [main] ERROR com.kable.newsstand.batch.shortage_claim_auto_accept.entities.validate.test.ValidateRepositoryTest - validateRepository == null in ValidateRepositoryTest.testFindByKeyCode()
09:40:51.036 [main] ERROR com.kable.newsstand.batch.shortage_claim_auto_accept.entities.validate.test.ValidateRepositoryTest - jdbc == null in ValidateRepositoryTest.after()
I think it might have something to do with not having #RunWith(SpringRunner.class) at the top, but if I include this, it tries to run my main application, which throws exceptions because instance variables aren't populated from the environment:
#SpringBootApplication
public class ShortageClaimAutoAccept implements CommandLineRunner {
private static final Logger logger = Logger.getLogger(ShortageClaimAutoAccept.class);
private static String cognosUser;
private static String cognosPassword;
private static String smtpHost;
private static String ftpServer;
private static String ftpUserName;
private static String ftpPassword;
private static String ftpPath;
private static Mailer mailer;
private static FtpRelativePathUsage ftp;
#Autowired
JdbcTemplate jdbcTemplate;
#Autowired
ClaimRepository claimRepository;
#Autowired
ClaimDetailRepository claimDetailRepository;
#Autowired
DocumentControlRepository documentControlRepository;
#Autowired
DocumentReportRepository documentReportRepository;
#Autowired
ValidateRepository validateRepository;
private void startClaimAutoAcceptApp() {
if (smtpHost == null) {
throw new IllegalStateException("smtp host is null");
}
if (cognosUser == null) {
throw new IllegalStateException("cognos user is null");
}
if (cognosPassword == null) {
throw new IllegalStateException("cognos password is null");
}
if (ftpServer == null) {
throw new IllegalStateException("ftp host is null");
}
if (ftpUserName == null) {
throw new IllegalStateException("ftp user is null");
}
if (ftpPassword == null) {
throw new IllegalStateException("ftp password is null");
}
if (ftpPath == null) {
throw new IllegalStateException("ftp server base path is null");
}
acceptClaimDetailsAndCloseClaims();
emailPODClaims();
}
public static void main(String[] args) {
try {
final Properties props = ApplicationPropertiesProvider.getProperties();
smtpHost = props.getProperty("SYS_SMTP_HOST");
cognosUser = props.getProperty("REPORT_RUNNER_USER");
cognosPassword = props.getProperty("REPORT_RUNNER_PWD");
ftpServer = props.getProperty("FTP_I_CLAIMSPOD_HOST");
ftpUserName = props.getProperty("FTP_I_CLAIMSPOD_USRID");
ftpPassword = props.getProperty("FTP_I_CLAIMSPOD_PWD");
ftpPath = props.getProperty("FTP_I_CLAIMS_BASE_PATH");
mailer = new Mailer(smtpHost, "");
FtpSite ftpSite = new FtpSite(ftpServer, ftpUserName, ftpPassword, ftpPath);
ftp = new FtpRelativePathUsage(ftpSite);
SpringApplication.run(ShortageClaimAutoAccept.class, args);
} catch (IllegalStateException ex) {
logger.fatal(ex);
} catch (Exception ex) {
logger.fatal("Uncaught exception in the process: \n", ex);
}
}
#Override
public void run(String... arg0) throws Exception {
startClaimAutoAcceptApp();
}
}
I'm not sure why it tries to run this, when all I am doing is testing.
You are missing two things here:
A runner
#RunWith(SpringRunner.class)
The component classes to use for loading an ApplicationContext. Can also
be specified using #ContextConfiguration(classes=...). If no
explicit classes are defined the test will look for nested Configuration
classes, before falling back to a SpringBootConfiguration search.
#SpringBootTest(classes = ShortageClaimAutoAccept.class)

connection timeout is not working for TomcatEmbeddedServletContainerFactory in spring boot

i have tried lowering the connection timeout from 60000 to just 100 millseconds to see whether it is breaking or not. But it is working fine even if the response time is more than 2000 millseconds .
Mine is springboot project,please let me know what is the way to test this connection timeout or let me know if i'm doing anything wrong???
#Component("tomcat")
public class TomcatServer {
private static final Logger LOGGER = LogManager.getLogger(TomcatServer.class);
#Value("${server.connection.timeout:60000}")
private int connectionTimeout;
#Value("${server.connection.keepalive.timeout:60000}")
private int keepAliveTimeout;
#Value("${server.connection.keepalive.count:100}")
private int maxKeepAliveRequests;
#Bean
public TomcatEmbeddedServletContainerFactory tomcatFactory(#Autowired final ContextResource primaryDS) {
final TomcatEmbeddedServletContainerFactory tcFactory = new TomcatEmbeddedServletContainerFactory() {
#Override
protected TomcatEmbeddedServletContainer getTomcatEmbeddedServletContainer(
final Tomcat tomcat) {
tomcat.enableNaming();
return super.getTomcatEmbeddedServletContainer(tomcat);
}
#Override
protected void postProcessContext(final Context context) {
context.getNamingResources().addResource(primaryDS);
}
};
tcFactory.addConnectorCustomizers(connector -> {
final Http11NioProtocol proto = (Http11NioProtocol) connector.getProtocolHandler();
LOGGER.info("connectionTimeout=" + connectionTimeout);
LOGGER.info("keepAliveTimeout=" + keepAliveTimeout);
LOGGER.info("maxKeepAliveRequests=" + maxKeepAliveRequests);
proto.setConnectionTimeout(connectionTimeout);
proto.setKeepAliveTimeout(keepAliveTimeout);
proto.setMaxKeepAliveRequests(maxKeepAliveRequests);
});
return tcFactory;
}
}```

Spring Cloud Canary Deployment

I have a spring cloud micro service with Zuul running on docker.
Requirement:
I want to create canary deployment with specific requirement as we will have x clients and I want to canary test with y specific clients (using email or username).
Can I configure the gateway to route requests to the new version of the micro-service for these y clients?
So you can do that via configuration or dynamic routing but i think first idom is not good for generic part every client you have to define it again and again but second one is more good
#Component
public class PostFilter extends ZuulFilter {
private static final String REQUEST_PATH = "/special-customer-product-request-url";
private static final String TARGET_SERVICE = "special-customer-service";
private static final String HTTP_METHOD = "POST or GET";
private final DiscoveryClient discoveryClient;
public PostOrdersFilter(DiscoveryClient discoveryClient) {
this.discoveryClient = discoveryClient;
}
#Override
public String filterType() {
return "route";
}
#Override
public int filterOrder() {
return 0;
}
#Override
public boolean shouldFilter() {
RequestContext context = RequestContext.getCurrentContext();
HttpServletRequest request = context.getRequest();
String method = request.getMethod();
String requestURI = request.getRequestURI();
return HTTP_METHOD.equalsIgnoreCase(method) && requestURI.startsWith(REQUEST_PATH);
}
#Override
public Object run() {
RequestContext context = RequestContext.getCurrentContext();
List<ServiceInstance> instances = discoveryClient.getInstances(TARGET_SERVICE);
try {
if (instances != null && instances.size() > 0) {
context.setRouteHost(instances.get(0).getUri().toURL());
} else {
throw new IllegalStateException("Target service instance not found!");
}
} catch (Exception e) {
throw new IllegalArgumentException("Couldn't get service URL!", e);
}
return null;
}
}

Loading a custom ApplicationContextInitializer in AWS Lambda Spring boot

How to loada custom ApplicationContextInitializer to in spring boot AWS Lambda?
I have an aws lambda application using spring boot, I would like to write an ApplicationContextInitializer for decrypting database passwords. I have the following code that works while running it as a spring boot application locally, but when I deploy it to the AWS console as a lambda it doesn't work.
Here is my code
1. applications.properties
spring.datasource.url=url
spring.datasource.username=testuser
CIPHER.spring.datasource.password=encryptedpassword
The following code is the ApplicationContextInitializer, assuming password is Base64 encoded for testing only (In the actual case it will be encrypted by AWM KMS). The idea here is if the key is starting with 'CIPHER.' (as in CIPHER.spring.datasource.password)I assume it's value needs to be decrypted and another key value pair with actual, key (here spring.datasource.password) and its decrypted value will be added at context initialization.
will be like spring.datasource.password=decrypted password
#Component
public class DecryptedPropertyContextInitializer
implements ApplicationContextInitializer<ConfigurableApplicationContext> {
private static final String CIPHER = "CIPHER.";
#Override
public void initialize(ConfigurableApplicationContext applicationContext) {
ConfigurableEnvironment environment = applicationContext.getEnvironment();
for (PropertySource<?> propertySource : environment.getPropertySources()) {
Map<String, Object> propertyOverrides = new LinkedHashMap<>();
decodePasswords(propertySource, propertyOverrides);
if (!propertyOverrides.isEmpty()) {
PropertySource<?> decodedProperties = new MapPropertySource("decoded "+ propertySource.getName(), propertyOverrides);
environment.getPropertySources().addBefore(propertySource.getName(), decodedProperties);
}
}
}
private void decodePasswords(PropertySource<?> source, Map<String, Object> propertyOverrides) {
if (source instanceof EnumerablePropertySource) {
EnumerablePropertySource<?> enumerablePropertySource = (EnumerablePropertySource<?>) source;
for (String key : enumerablePropertySource.getPropertyNames()) {
Object rawValue = source.getProperty(key);
if (rawValue instanceof String && key.startsWith(CIPHER)) {
String cipherRemovedKey = key.substring(CIPHER.length());
String decodedValue = decode((String) rawValue);
propertyOverrides.put(cipherRemovedKey, decodedValue);
}
}
}
}
public String decode(String encodedString) {
byte[] valueDecoded = org.apache.commons.codec.binary.Base64.decodeBase64(encodedString);
return new String(valueDecoded);
}
Here is the Spring boot initializer
#SpringBootApplication
#ComponentScan(basePackages = "com.amazonaws.serverless.sample.springboot.controller")
public class Application extends SpringBootServletInitializer {
#Bean
public HandlerMapping handlerMapping() {
return new RequestMappingHandlerMapping();
}
#Bean
public HandlerAdapter handlerAdapter() {
return new RequestMappingHandlerAdapter();
}
#Bean
public HandlerExceptionResolver handlerExceptionResolver() {
return new HandlerExceptionResolver() {
#Override
public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
return null;
}
};
}
//loading the initializer here
public static void main(String[] args) {
SpringApplication application=new SpringApplication(Application.class);
application.addInitializers(new DecryptedPropertyContextInitializer());
application.run(args);
}
This is working when run as a spring boot appliaction, But when it deployed as a lambda into AWS the main() method in my SpringBootServletInitializer will never be called by lambda. Here is my Lambda handler.
public class StreamLambdaHandler implements RequestStreamHandler {
private static Logger LOGGER = LoggerFactory.getLogger(StreamLambdaHandler.class);
private static SpringBootLambdaContainerHandler<AwsProxyRequest, AwsProxyResponse> handler;
static {
try {
handler = SpringBootLambdaContainerHandler.getAwsProxyHandler(Application.class);
handler.onStartup(servletContext -> {
FilterRegistration.Dynamic registration = servletContext.addFilter("CognitoIdentityFilter", CognitoIdentityFilter.class);
registration.addMappingForUrlPatterns(EnumSet.of(DispatcherType.REQUEST), true, "/*");
});
} catch (ContainerInitializationException e) {
e.printStackTrace();
throw new RuntimeException("Could not initialize Spring Boot application", e);
}
}
#Override
public void handleRequest(InputStream inputStream, OutputStream outputStream, Context context)
throws IOException {
handler.proxyStream(inputStream, outputStream, context);
outputStream.close();
}
}
What change is to be made in the code to load the ApplicationContextInitializer by Lambda? Any help will be highly appreciated.
I was able to nail it in the following way.
First changed the property value with place holder with a prefix, where the prefix denotes the values need to be decrypted, ex.
spring.datasource.password=${MY_PREFIX_placeHolder}
aws lambda environment variable name should match to the placeholder
('MY_PREFIX_placeHolder') and it value is encrypted using AWS KMS (This sample is base64 decoding).
create an ApplicationContextInitializer which will decrypt the property value
public class DecryptedPropertyContextInitializer
implements ApplicationContextInitializer<ConfigurableApplicationContext> {
private static final String CIPHER = "MY_PREFIX_";
#Override
public void initialize(ConfigurableApplicationContext applicationContext) {
ConfigurableEnvironment environment = applicationContext.getEnvironment();
for (PropertySource<?> propertySource : environment.getPropertySources()) {
Map<String, Object> propertyOverrides = new LinkedHashMap<>();
decodePasswords(propertySource, propertyOverrides);
if (!propertyOverrides.isEmpty()) {
PropertySource<?> decodedProperties = new MapPropertySource("decoded "+ propertySource.getName(), propertyOverrides);
environment.getPropertySources().addBefore(propertySource.getName(), decodedProperties);
}
}
}
private void decodePasswords(PropertySource<?> source, Map<String, Object> propertyOverrides) {
if (source instanceof EnumerablePropertySource) {
EnumerablePropertySource<?> enumerablePropertySource = (EnumerablePropertySource<?>) source;
for (String key : enumerablePropertySource.getPropertyNames()) {
Object rawValue = source.getProperty(key);
if (rawValue instanceof String && key.startsWith(CIPHER)) {
String decodedValue = decode((String) rawValue);
propertyOverrides.put(key, decodedValue);
}
}
}
}
public String decode(String encodedString) {
byte[] valueDecoded = org.apache.commons.codec.binary.Base64.decodeBase64(encodedString);
return new String(valueDecoded);
}
}
The above code will decrypt all the values with prefix MY_PREFIX_ and add them at the top of the property source.
As the spring boot is deployed into aws lambda, lambda will not invoke the main() function, so if the ApplicationContextInitializer is initialized in main() it is not going to work. In order to make it work need to override createSpringApplicationBuilder() method of SpringBootServletInitializer, so SpringBootServletInitializer will be like
#SpringBootApplication
#ComponentScan(basePackages = "com.amazonaws.serverless.sample.springboot.controller")
public class Application extends SpringBootServletInitializer {
#Bean
public HandlerMapping handlerMapping() {
return new RequestMappingHandlerMapping();
}
#Bean
public HandlerAdapter handlerAdapter() {
return new RequestMappingHandlerAdapter();
}
#Bean
public HandlerExceptionResolver handlerExceptionResolver() {
return new HandlerExceptionResolver() {
#Override
public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
return null;
}
};
}
#Override
protected SpringApplicationBuilder createSpringApplicationBuilder() {
SpringApplicationBuilder builder = new SpringApplicationBuilder();
builder.initializers(new DecryptedPropertyContextInitializer());
return builder;
}
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
No need to make any changes for the lambdahandler.

Resources