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.
Related
I know this question has been posted before, but I couldn't resolve it from that post. I get the error that "SpringApplicationConfiguration cannot be resolved to a type" in the following code:
package com.caveofprogramming.tests;
import static org.junit.Assert.assertNotNull;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.SpringBootConfiguration;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import com.caveofprogramming.App;
#RunWith(SpringJUnit4ClassRunner.class)
#SpringApplicationConfiguration(App.class)
#WebAppConfiguration
public class StatusTest {
#Test
public void testDummy() {
long value = 7l;
assertNotNull("Value should not be null", value);
}
}
This has the following dependency in the pom.xml file:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<version>2.1.9.RELEASE</version><!--$NO-MVN-MAN-VER$-->
</dependency>
What can I do to get rid of this error but not cause any other issues? Thanks.
Here below is App.java:
package com.caveofprogramming;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
import org.springframework.context.annotation.Bean;
import org.springframework.web.servlet.view.UrlBasedViewResolver;
import org.springframework.web.servlet.view.tiles3.TilesConfigurer;
import org.springframework.web.servlet.view.tiles3.TilesView;
#SpringBootApplication
public class App extends SpringBootServletInitializer {
public static void main(String[] args) {
SpringApplication.run(App.class, args);
}
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder
application) {
return application.sources(App.class);
}
#Bean
public TilesConfigurer tilesConfigurer() {
TilesConfigurer tilesConfigurer = new TilesConfigurer();
String[] defs = {"/WEB-INF/tiles.xml"};
tilesConfigurer.setDefinitions(defs);
return tilesConfigurer;
}
#Bean
public UrlBasedViewResolver tilesViewResolver() {
UrlBasedViewResolver tilesViewResolver = new UrlBasedViewResolver();
tilesViewResolver.setViewClass(TilesView.class);
return tilesViewResolver;
}
}
I believe a configuration like this will get you going
#RunWith(SpringRunner.class)
#ComponentScan(basePackages = {"com.caveofprogramming"})
#SpringBootTest
#AutoConfigureMockMvc
I assume there's a lot more to your test (or there intends to be) than what you've listed. If you're truly going to just make a simple test like this, run with the Mockito runner, and you don't need the rest of that nonsense.
#RunWith(MockitoJUnitRunner.class)
Note that this assumes you're attempting to perform a test of your controllers, based on the fact that you have annotated your test with #WebAppConfiguration
This is the error which i am getting:
Description:
Field andiRepository in com.service.datafetcher.AllAndisDataFetcher required a bean of type 'com.repositories.AndiRepository' 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.repositories.AndiRepository' in your configuration.
This is the data fetcher file which is requiring a bean:
import com.models.Andi;
import com.repositories.AndiRepository;
import graphql.schema.DataFetcher;
import graphql.schema.DataFetchingEnvironment;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.List;
#Component
public class AllAndisDataFetcher implements DataFetcher<List<Andi>> {
#Autowired
AndiRepository andiRepository;
#Override
public List<Andi> get(DataFetchingEnvironment dataFetchingEnvironment) throws Exception {
return andiRepository.findAll();
}
}
this is the main method which resides in "com".
package com;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
#SpringBootApplication
#ComponentScan("com.repositories")//to scan repository files
#EntityScan("com.models")
#EnableJpaRepositories("com.repositories.AndiRepository")
public class DynamoDBApplication {
public static void main(String[] args) {
SpringApplication.run(DynamoDBApplication.class, args);
}
}
The models, repositories, service, packages are inside the main com package.
This is the repository file:
package com.repositories;
import com.andiskillsmaxmodels.Andi;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;
#Repository
public interface AndiRepository extends CrudRepository<Andi, Integer> {
}
Thank you
Correct your package names. They're all over the place. You have imported classes from different packages it seems. Make sure that AndiRepository is in the com.repositories package. And Andi class in your com.models package. After correcting these mistakes do the following.
Remove #ComponentScan("com.repositories"). You don't need this, since #SpringBootApplicationautomatically does it for you.
And replace #SpringBootApplication with #SpringBootApplication(scanBasePackages = "com")
I spent a while trying to figure out spring boot neo4j in java. What I want is something like this
import org.neo4j.driver.v1.AuthTokens;
import org.neo4j.driver.v1.Driver;
import org.neo4j.driver.v1.GraphDatabase;
import org.neo4j.driver.v1.Record;
import org.neo4j.driver.v1.Session;
import org.neo4j.driver.v1.StatementResult;
import org.neo4j.driver.v1.Transaction;
import org.neo4j.driver.v1.Value;
public class adding {
static Driver driver;
public static void main(String args[]) throws JSONException {
StatementResult result;
driver = GraphDatabase.driver("bolt://localhost:7687", AuthTokens.basic("neo4j","password"));
Session session = driver.session();
result = session.run("CREATE (a:Person {name: bob} return a.name");
}
}
So this works an all however I'm looking to query with spring boot.
I followed this guide https://spring.io/guides/gs/accessing-data-neo4j/
and was left pretty confused. I'm not sure how I can immitate the above create process with spring boot . Is there like a query command?
package com.example.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
#SpringBootApplication
public class SpringGraphNeo4jApplication {
public static void main(String[] args) {
SpringApplication.run(SpringGraphNeo4jApplication.class, args);
}
}
The demo has this file and runs on a port.... I don't understand
Add #EnableNeo4jRepositories in you SpringGraphNeo4jApplication class
In case you want to use your own queries , use #query annotation on repository
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.data.neo4j.repository.config.EnableNeo4jRepositories;
#SpringBootApplication
#EnableNeo4jRepositories
public class SpringGraphNeo4jApplication {
private final static Logger log = LoggerFactory.getLogger(SpringGraphNeo4jApplication.class);
public static void main(String[] args) throws Exception {
SpringApplication.run(SpringGraphNeo4jApplication.class, args);
}
}
I'm working on Spring over Hibernate project an i'm only in the beginning.
I'm tryng to hav a SpringBootApplication which writes to MsSql some LogEntries objects.
I have some different packages:
here is the classes:
LogEntryFacadeImpl.class :
package com.tradingSystem.dataAccess;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.tradingSystem.entity.LogEntry;
#Service
public class LogEntryFacadeImpl implements LogEntryFacade{
#Autowired
private LogEntryDAO logEntryDao;
#Transactional
#Override
public Long addLogEntry(LogEntry log) {
return this.logEntryDao.save(log).getId();
}
#Override
public LogEntry getLogEntry(Long logId) {
return this.logEntryDao.findOne(logId);
}
}
LogEntryDAO.class:
package com.tradingSystem.dataAccess;
import org.springframework.data.jpa.repository.JpaRepository;
import com.tradingSystem.entity.LogEntry;
public interface LogEntryDAO extends JpaRepository<LogEntry, Long> {
}
and I use this class as tester:
TestApplication.class:
package com.testings;
import java.util.Date;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
import com.tradingSystem.dataAccess.LogEntryFacade;
import com.tradingSystem.entity.LogEntry;
#SpringBootApplication
#ComponentScan({"com.tradingSystem" })
public class TestApplication implements CommandLineRunner{
#Autowired
private LogEntryFacade logEntryFacade;
public static void main(String[] args) {
SpringApplication.run(TestApplication.class, args);
}
#Override
public void run(String... args) throws Exception {
LogEntry log = new LogEntry(552266, "Testing of log entry save",
new Date(System.currentTimeMillis()),
new Date(System.currentTimeMillis()));
System.err.println(log);
Long id = logEntryFacade.addLogEntry(log);
LogEntry log2 = logEntryFacade.getLogEntry(id);
System.err.println(log2);
}
}
wher i run this as application i get this message in console:
APPLICATION FAILED TO START
Description:
Field logEntryDao in com.tradingSystem.dataAccess.LogEntryFacadeImpl required a bean of type 'com.tradingSystem.dataAccess.LogEntryDAO' that could not be found.
Action:
Consider defining a bean of type 'com.tradingSystem.dataAccess.LogEntryDAO' in your configuration.
I put the #ComponentScan({"com.tradingSystem" }) annotation in the tester as you can see. however, still get this message.
(when I didnt use any packages separation, everything works fine...)
Please help me solve this
Thanks
You should add #Repository annotation above your Repository interface.
Optionally you can add it like #Repository(value="logEntryRepository")
the default scan path is package of #SpringBootApplication class, so you must declare three scan path, but it's seems like that you missing two scan config, you need add
#EnableJpaRepositories(basePackages = "com.tradingSystem.dataAccess")
#EntityScan(basePackages = "com.tradingSystem.entity")
#ComponentScan(basePackages = "com.tradingSystem.dataAccess")
to the TestApplication class
I have been trying to add spring validators to a spring-data-rest project.
I followed along and setup the "getting started" application via this link: http://spring.io/guides/gs/accessing-data-rest/
...and now I am trying to add a custom PeopleValidator by following the documents here:
http://docs.spring.io/spring-data/rest/docs/2.1.0.RELEASE/reference/html/validation-chapter.html
My custom PeopleValidator looks like
package hello;
import org.springframework.validation.Errors;
import org.springframework.validation.Validator;
public class PeopleValidator implements Validator {
#Override
public boolean supports(Class<?> clazz) {
return true;
}
#Override
public void validate(Object target, Errors errors) {
errors.reject("DIE");
}
}
...and my Application.java class now looks like this
package hello;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.data.rest.webmvc.config.RepositoryRestMvcConfiguration;
#Configuration
#EnableJpaRepositories
#Import(RepositoryRestMvcConfiguration.class)
#EnableAutoConfiguration
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
#Bean
public PeopleValidator beforeCreatePeopleValidator() {
return new PeopleValidator();
}
}
I would expect that POSTing to the http://localhost:8080/people URL would result in an error of some kind since the PeopleValidator is rejecting everything. However, no error is thrown, and the validator is never called.
I have also tried manually setting up the validator as shown in section 5.1 of the spring-data-rest documentation.
What am I missing?
So it appears that the before/after "save" events only fire on PUT and PATCH. When POSTing, the before/after "create" events fire.
I tried it the manual way again using the configureValidatingRepositoryEventListener override and it worked. I'm not sure what I'm doing differently at work than here at home. I'll have to look tomorrow.
I sure would love to hear if others have suggestions on why it wouldn't work.
For the record, here is what the new Application.java class looks like.
package hello;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.data.rest.core.event.ValidatingRepositoryEventListener;
import org.springframework.data.rest.webmvc.config.RepositoryRestMvcConfiguration;
#Configuration
#EnableJpaRepositories
#Import(RepositoryRestMvcConfiguration.class)
#EnableAutoConfiguration
public class Application extends RepositoryRestMvcConfiguration {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
#Override
protected void configureValidatingRepositoryEventListener(ValidatingRepositoryEventListener validatingListener) {
validatingListener.addValidator("beforeCreate", new PeopleValidator());
}
}
Looks like the feature is currently not implemented (2.3.0), unluckily there are no constants for the event names otherwise the solution below would not be that fragile.
The Configuration adds all properly named Validator beans to ValidatingRepositoryEventListener using the right event.
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.ListableBeanFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.rest.core.event.ValidatingRepositoryEventListener;
import org.springframework.validation.Validator;
#Configuration
public class ValidatorRegistrar implements InitializingBean {
private static final List<String> EVENTS;
static {
List<String> events = new ArrayList<String>();
events.add("beforeCreate");
events.add("afterCreate");
events.add("beforeSave");
events.add("afterSave");
events.add("beforeLinkSave");
events.add("afterLinkSave");
events.add("beforeDelete");
events.add("afterDelete");
EVENTS = Collections.unmodifiableList(events);
}
#Autowired
ListableBeanFactory beanFactory;
#Autowired
ValidatingRepositoryEventListener validatingRepositoryEventListener;
#Override
public void afterPropertiesSet() throws Exception {
Map<String, Validator> validators = beanFactory.getBeansOfType(Validator.class);
for (Map.Entry<String, Validator> entry : validators.entrySet()) {
EVENTS.stream().filter(p -> entry.getKey().startsWith(p)).findFirst()
.ifPresent(p -> validatingRepositoryEventListener.addValidator(p, entry.getValue()));
}
}
}
A bit of a stab in the dark - I've not used spring-data-rest. However, after having a read of the tutorial you're following, I think the problem is that you need a PersonValidator not a PeopleValidator. Rename everything accordingly:
PersonValidator
package hello;
import org.springframework.validation.Errors;
import org.springframework.validation.Validator;
public class PersonValidator implements Validator {
#Override
public boolean supports(Class<?> clazz) {
return true;
}
#Override
public void validate(Object target, Errors errors) {
errors.reject("DIE");
}
}
Application
package hello;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.data.rest.webmvc.config.RepositoryRestMvcConfiguration;
#Configuration
#EnableJpaRepositories
#Import(RepositoryRestMvcConfiguration.class)
#EnableAutoConfiguration
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
#Bean
public PersonValidator beforeCreatePersonValidator() {
return new PersonValidator();
}
}
Another way of doing it is to use annotated handlers as specified here
http://docs.spring.io/spring-data/rest/docs/2.1.0.RELEASE/reference/html/events-chapter.html#d5e443
Here is an example of how to use annotated handlers:
import gr.bytecode.restapp.model.Agent;
import org.springframework.data.rest.core.annotation.HandleBeforeCreate;
import org.springframework.data.rest.core.annotation.HandleBeforeSave;
import org.springframework.data.rest.core.annotation.RepositoryEventHandler;
import org.springframework.stereotype.Component;
#Component
#RepositoryEventHandler(Agent.class)
public class AgentEventHandler {
public static final String NEW_NAME = "**modified**";
#HandleBeforeCreate
public void handleBeforeCreates(Agent agent) {
agent.setName(NEW_NAME);
}
#HandleBeforeSave
public void handleBeforeSave(Agent agent) {
agent.setName(NEW_NAME + "..update");
}
}
Example is from github edited for brevity.