I am just getting into spring-cloud-config and I'm working on this basic project. I would like to know if it is possible and how to rewrite this client to not use Spring Boot.
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
#EnableAutoConfiguration
#ComponentScan
#RestController
#RefreshScope
public class ClientApp {
#Value("${bar:World!}")
String bar;
#RequestMapping("/")
String hello() {
return "Hello " + bar + "!";
}
public static void main(String[] args) {
SpringApplication.run(ClientApp.class, args);
}
}
The reason for this is that we are thinking of using spring-cloud-config in our spring batch web service, but we use the old spring with xmls, not spring boot. I couldn't find any documentation related to this.
Related
The project is being migrated from a mix of spring and jersey to full spring boot webflux
The actual error message is:
Type org.glassfish.jersey.servlet.ServletContainer not present
Problem is I don't know why the test is trying to spawn this context, and debugging is extremely hard.
The test declaration is:
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.web.server.LocalServerPort;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.springframework.test.web.reactive.server.WebTestClient;
import org.springframework.web.reactive.function.client.ExchangeStrategies;
import org.springframework.web.reactive.function.client.WebClient;
#ExtendWith(SpringExtension.class)
#SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
#AutoConfigureWebTestClient
#TestPropertySource(properties = {"opentracing.sample-rate=1"})
class ReactiveControllerIT {
#LocalServerPort
int port;
#Autowired
private WebTestClient webClient;
And the application class
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.data.neo4j.repository.config.EnableReactiveNeo4jRepositories;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
#SpringBootApplication
#EnableScheduling
#EnableReactiveNeo4jRepositories
#EnableGlobalMethodSecurity(prePostEnabled = true, proxyTargetClass = true)
public class SeoGraphApplication {
public static void main(String[] args) {
SpringApplication.run(SeoGraphApplication.class, args);
}
}
Even with empty test methods I don't reach the actual method.
Any thoughts?
Thanks,
Omer.
Found it, after many hours of debugging.
this method was the key to the solution:
private WebApplicationType deduceWebApplicationType() {
if (ClassUtils.isPresent(REACTIVE_WEB_ENVIRONMENT_CLASS, null)
&& !ClassUtils.isPresent(MVC_WEB_ENVIRONMENT_CLASS, null)
&& !ClassUtils.isPresent(JERSEY_WEB_ENVIRONMENT_CLASS, null)) {
return WebApplicationType.REACTIVE;
}
for (String className : WEB_ENVIRONMENT_CLASSES) {
if (!ClassUtils.isPresent(className, null)) {
return WebApplicationType.NONE;
}
}
return WebApplicationType.SERVLET;
}
The if regarding the Jersey web environment resulted in true, which eventually made this method return servlet type.
The source of it was usage of error types library in my company which for some odd reason depends on jersey-server and when found, results in a servlet context initialization.
I contacted the authors about it, and worst part is that excluding the server dependency had no effect on the functionality.
Thanks to anyone who spent time on this one.
I was trying my hands on netflix zuul api gateway technology. I was able to route my urls using application.properties file. But I was not able to do the same with third party configuration using ZuulProperties. This is a requirement. How can I do this. I tried below code:
config class code
package com.example.springbootzuulgatwayproxy;
import java.util.HashMap;
import java.util.Map;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.cloud.netflix.zuul.filters.ZuulProperties;
import org.springframework.cloud.netflix.zuul.filters.ZuulProperties.ZuulRoute;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
#Configuration
public class AppConfig {
#Primary
#Bean(name = "zuulConfigProperties")
#RefreshScope
#ConfigurationProperties("zuul")
public ZuulProperties zuulProperties() {
ZuulProperties.ZuulRoute route = new ZuulProperties.ZuulRoute("http://localhost:8090");// ZuulRoute is static inner class of ZuulProperties
Map<String,ZuulRoute> map = new HashMap<String,ZuulRoute>();
map.put("zuul.routes.employee.url", route);
ZuulProperties props = new ZuulProperties();
props.setRoutes(map);
return props;
}
}
here I am expecting that ZuulProperties will load the zuul.route property from inside my config class.. am I going wrong? As I had said, I could have done this easily using applicatin.properties. But this the requirement where I am stuck. To be frank, I want those properties to be loaded from database. But then I came across this piece of code, it was looking promising. But I am not able to do with this.
main class
package com.example.springbootzuulgatwayproxy;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import com.example.springbootzuulgatwayproxy.filters.ErrorFilter;
import com.example.springbootzuulgatwayproxy.filters.PostFilter;
import com.example.springbootzuulgatwayproxy.filters.PreFilter;
import com.example.springbootzuulgatwayproxy.filters.RouteFilter;
#ComponentScan
#SpringBootApplication
#EnableZuulProxy
public class SpringBootZuulgatwayproxyApplication {
public static void main(String[] args) {
SpringApplication.run(SpringBootZuulgatwayproxyApplication.class, args);
}
#Bean
public PreFilter preFilter() {
return new PreFilter();
}
#Bean
public PostFilter postFilter() {
return new PostFilter();
}
#Bean
public ErrorFilter errorFilter() {
return new ErrorFilter();
}
#Bean
public RouteFilter routeFilter() {
return new RouteFilter();
}
}
when I hit http://localhost:8080/employee/getEmployeeDetails/{employee_name} url, postman gives me 404 not found error.
I have a running Spring web project (A) with outside Tomcat, and now, I want to move to Spring cloud, that need to support (A), and while I run as Spring boot web project with outside Tomcat, the applicationContext.xml loads twice.
Code as below:
package com.pa.openapi.gateway.core;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.data.jpa.JpaRepositoriesAutoConfiguration;
import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.support.SpringBootServletInitializer;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
#EnableWebMvc
#SpringBootApplication(exclude = {DataSourceAutoConfiguration.class,
HibernateJpaAutoConfiguration.class, JpaRepositoriesAutoConfiguration.class })
#EnableDiscoveryClient
public class Application extends SpringBootServletInitializer {
public static void main(String[] args) {
System.out.println("*********************Application***************************************");
SpringApplication.run(Application.class, args);
}
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
return builder.sources(this.getClass());
}
}
package com.pa.openapi.gateway.core;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ImportResource;
#Configuration
#ImportResource("classpath*:applicationContext.xml")
public class ConfigurationClass { }
Tomcat as apache-tomcat-8.0.24
If you have any question, please let me know.
I have a Spring Boot project using Jersey as my REST service and using AngularJS for my front end development. While I run it without using any controller and go to index.html (which is in resource/static/index.html) it works fine. When I add a controller it renders gives the string "index.html" as an output. Spring Boot Configuration:
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
#SpringBootApplication
#ComponentScan(basePackages = {"com.cst.interfaces","com.cst.configuration","com.cst.application","com.cst.application.implmentation"})
#EnableAutoConfiguration
public class ApplicationConfiguration {
public static void main(String args[]) throws Exception{
SpringApplication.run(ApplicationConfiguration.class, args);
}
public ServletRegistrationBean jerseyServlet(){
ServletRegistrationBean register = new ServletRegistrationBean(new ServletContainer(),"/*");
register.addInitParameter(ServletProperties.JAXRS_APPLICATION_CLASS, JerseyInitalize.class.getName());
return register;
}
}
JerseyConfiguration:
import org.glassfish.jersey.server.ResourceConfig;
import org.springframework.stereotype.Component;
#Component
public class JerseyInitalize extends ResourceConfig{
public JerseyInitalize(){
super();
this.packages("com.cst.interfaces");
}
}
Controller Class:
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import org.springframework.web.bind.annotation.RestController;
#RestController
#Path("/home")
public class HomeResource {
#GET
#Produces("application/json")
public String getString(){
return "index.html";
}
}
This is because you annotated your controller with #RestController, which is a shorthand for #Controller with #ResponseBody. The latter annotation instructs the controller to render the output as-is directly into the response.
Use #Controller for controllers that are not RESTful instead.
I'm coding a Spring server and I am using Retrofit to make the api calls.
I have the next interface for the Retrofit client:
import retrofit.http.Body;
import retrofit.http.GET;
import retrofit.http.POST;
public interface AuthSvcApi {
public static final String AUTHENTICATION_PATH = "/authToken";
#POST(AUTHENTICATION_PATH)
public boolean loginUser(#Body String accessToken);
}
Then my controller is:
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import com.purposes.client.AuthSvcApi;
#Controller
public class AuthSvc{
#RequestMapping(value=AuthSvcApi.AUTHENTICATION_PATH, method = RequestMethod.POST)
public #ResponseBody boolean loginUser(#RequestBody String accessToken) {
CheckAccessToken checkAccessToken = new CheckFacebookAccessToken();
checkAccessToken.checkToken(accessToken);
return false;
}
}
The method isn't finished, but it should work. And the application class is:
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
//Tell Spring to automatically inject any dependencies that are marked in
//our classes with #Autowired
#EnableAutoConfiguration
//Tell Spring to turn on WebMVC (e.g., it should enable the DispatcherServlet
//so that requests can be routed to our Controllers)
#EnableWebMvc
//Tell Spring to go and scan our controller package (and all sub packages) to
//find any Controllers or other components that are part of our applciation.
//Any class in this package that is annotated with #Controller is going to be
//automatically discovered and connected to the DispatcherServlet.
#ComponentScan
//Tell Spring that this object represents a Configuration for the
//application
#Configuration
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
I don't know why this doesn't work fine, but I am going crazy because the response is:
No mapping found for HTTP request with URI [/authToken] in DispatcherServlet with name 'dispatcherServlet'
Looks like you need to include AuthSvcApi.AUTHENTICATION_PATH
to this line:
.setEndpoint(SERVER).build()
Like this:
.setEndpoint(SERVER + AuthSvcApi.AUTHENTICATION_PATH).build()
Well, I found the solution, the problem was that the annotation #ComponentScan didn't find the package where the controller was. I resolve the problem indicating to the annotation the package where the controller is.
#ComponentScan(basePackages={"com.purposes.controllers"})