ArangoDB own converters - spring-data

How can I add my own ArangoDB configuration converter.
An example of a converter.
public class HTMLConverter {
private static final boolean HTML_DESCRIPTION_IS_PRESENT = ClassUtils.isPresent("com.b.k.api.domain.extend.HTML", null);
public static Collection<Converter<?, ?>> getConvertersToRegister() {
if (!HTML_DESCRIPTION_IS_PRESENT) {
return Collections.emptySet();
}
final List<Converter<?, ?>> converters = new ArrayList<>();
converters.add(HtmlToStringConverter.INSTANCE);
converters.add(StringToHtmlConverter.INSTANCE);
return converters;
}
public enum HtmlToStringConverter implements Converter<HTML, String> {
INSTANCE;
#Override
public String convert(final HTML source) {
return source == null ? null : source.getXml();
}
}
public enum StringToHtmlConverter implements Converter<String, HTML> {
INSTANCE;
#Override
public HTML convert(final String source) {
return source == null ? null : new HTML(source);
}
}
}
The reproduction of my converters looks like this:
public class BKArangoCustomConverters extends CustomConversions {
private static final StoreConversions STORE_CONVERSIONS;
static {
final Collection<Converter<?, ?>> converters = new ArrayList<>();
converters.addAll(XMLConverter.getConvertersToRegister());
converters.addAll(HTMLConverter.getConvertersToRegister());
STORE_CONVERSIONS = StoreConversions.of(SimpleTypeHolder.DEFAULT, converters);
}
protected BKArangoCustomConverters(Collection<?> converters) {
super(converters);
}
}
I am asked how can I add new converters to the ArangoDB configuration using the builder "com.arangodb.ArangoDB.Builder" in the extension class "com.arangodb.springframework.config.AbstractArangoConfiguration".

You have to override the method customConversions() from AbstractArangoConfiguration in your configuration class and add your converters there.
public CustomConversions customConversions() {
Collection<Converter<?, ?>> converters = new ArrayList<>();
converters.addAll(XMLConverter.getConvertersToRegister());
converters.addAll(HTMLConverter.getConvertersToRegister());
return new ArangoCustomConversions(converters);
}
or you replace the ArangoCustomConversions with our own clasn class BKArangoCustomConverters.
public CustomConversions customConversions() {
return new BKArangoCustomConverters(Collections.emptyList());
}

Related

Configuration for Mvc testing

guys. I have spring MVC project and I want to test CoursesController, but can not find out how to do it.
Do I need to make separated configuration class for tests?
Before springMvc I used separated configuration class for test with embedded database.
I'd appreciate all the help I can get.
CoursesController class:
#Controller
#RequestMapping("/courses")
public class CoursesController {
private final CourseService courseService;
#Autowired
public CoursesController(CourseService courseService) {
this.courseService = courseService;
}
#GetMapping()
public String index(Model model, #RequestParam("page") Optional<Integer> page,
#RequestParam("size") Optional<Integer> size) throws ServiceException {
int currentPage = page.orElse(1);
int pageSize = size.orElse(10);
Page<Course> coursePage = courseService.findPaginated(PageRequest.of(currentPage - 1, pageSize));
model.addAttribute("coursePage", coursePage);
int totalPages = coursePage.getTotalPages();
if (totalPages > 0) {
List<Integer> pageNumbers = IntStream.rangeClosed(1, totalPages).boxed().collect(Collectors.toList());
model.addAttribute("pageNumbers", pageNumbers);
}
return "courses/index";
}
}
Configuration class:
#Configuration
#ComponentScan("com.university")
#PropertySource("classpath:/application.properties")
#EnableWebMvc
public class Config implements WebMvcConfigurer {
#Autowired
private Environment env;
private final ApplicationContext applicationContext;
#Autowired
public Config(ApplicationContext applicationContext) {
this.applicationContext = applicationContext;
}
#Bean
public HikariDataSource dataSource() {
return (HikariDataSource) DataSourceBuilder.create().type(HikariDataSource.class)
.url(env.getProperty("spring.datasource.url"))
.driverClassName(env.getProperty("spring.datasource.driverClassName"))
.username(env.getProperty("spring.datasource.username"))
.password(env.getProperty("spring.datasource.password")).build();
}
#Bean
public JdbcTemplate jdbcTemplate() {
return new JdbcTemplate(dataSource());
}
#Bean
public SpringResourceTemplateResolver templateResolver() {
SpringResourceTemplateResolver templateResolver = new SpringResourceTemplateResolver();
templateResolver.setApplicationContext(applicationContext);
templateResolver.setPrefix("/WEB-INF/views/");
templateResolver.setSuffix(".html");
return templateResolver;
}
#Bean
public SpringTemplateEngine templateEngine() {
SpringTemplateEngine templateEngine = new SpringTemplateEngine();
templateEngine.setTemplateResolver(templateResolver());
templateEngine.setEnableSpringELCompiler(true);
return templateEngine;
}
#Override
public void configureViewResolvers(ViewResolverRegistry registry) {
ThymeleafViewResolver resolver = new ThymeleafViewResolver();
resolver.setTemplateEngine(templateEngine());
registry.viewResolver(resolver);
}
#Bean
public SessionLocaleResolver localeResolver() {
SessionLocaleResolver localeResolver = new SessionLocaleResolver();
localeResolver.setDefaultLocale(Locale.ENGLISH);
return localeResolver;
}
}
I did separate configuration class for tests with H2 database.

Spring Boot - Bean named entityManagerFactory

I am trying to make a simple Spring Boot application generated with jHipster to get from a postgresql a list of articles from a postreSQL database and display it using a rest controller, but when i run it i get
***************************
APPLICATION FAILED TO START
***************************
Description:
Parameter 0 of constructor in org.adi.security.DomainUserDetailsService required a bean named 'entityManagerFactory' that could not be found.
Action:
Consider defining a bean named 'entityManagerFactory' in your configuration.
But the thing is that that `DomainUserDetailsService is something generated by jhipster which stopped working after i added my classes. So i will write below my classes:
Article Entity:
package org.adi.domain;
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
#Entity
#Table(name="articles")
public class Article implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
#Column(name="article_id")
private int articleId;
#Column(name="title")
private String title;
#Column(name="category")
private String category;
public int getArticleId() {
return articleId;
}
public void setArticleId(int articleId) {
this.articleId = articleId;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getCategory() {
return category;
}
public void setCategory(String category) {
this.category = category;
}
}
ArticleDAO (Repository):
#Transactional
#Repository
public class ArticleDAO implements IArticleDAO {
#PersistenceContext
private EntityManager entityManager;
#Override
public Article getArticleById(int articleId) {
return entityManager.find(Article.class, articleId);
}
#SuppressWarnings("unchecked")
#Override
public List<Article> getAllArticles() {
String hql = "FROM Article as atcl ORDER BY atcl.articleId DESC";
return (List<Article>) entityManager.createQuery(hql).getResultList();
}
#Override
public void createArticle(Article article) {
entityManager.persist(article);
}
#Override
public void updateArticle(Article article) {
Article artcl = getArticleById(article.getArticleId());
artcl.setTitle(article.getTitle());
artcl.setCategory(article.getCategory());
entityManager.flush();
}
#Override
public void deleteArticle(int articleId) {
entityManager.remove(getArticleById(articleId));
}
#Override
public boolean articleExists(String title, String category) {
String hql = "FROM Article as atcl WHERE atcl.title = ? and atcl.category = ?";
int count = entityManager.createQuery(hql).setParameter(1, title)
.setParameter(2, category).getResultList().size();
return count > 0 ? true : false;
}
}
ArticleService:
#Service
public class ArticleService implements IArticleService {
#Autowired
private IArticleDAO articleDAO;
#Override
public Article getArticleById(int articleId) {
Article obj = articleDAO.getArticleById(articleId);
return obj;
}
#Override
public List<Article> getAllArticles(){
return articleDAO.getAllArticles();
}
#Override
public synchronized boolean createArticle(Article article){
if (articleDAO.articleExists(article.getTitle(), article.getCategory())) {
return false;
} else {
articleDAO.createArticle(article);
return true;
}
}
#Override
public void updateArticle(Article article) {
articleDAO.updateArticle(article);
}
#Override
public void deleteArticle(int articleId) {
articleDAO.deleteArticle(articleId);
}
}
and finally my REST controller:
#Controller
#RequestMapping("user")
#CrossOrigin(origins = {"http://localhost:4200"})
public class ArticleController {
#Autowired
private IArticleService articleService;
#GetMapping("article")
public ResponseEntity<Article> getArticleById(#RequestParam("id") String id) {
Article article = articleService.getArticleById(Integer.parseInt(id));
return new ResponseEntity<Article>(article, HttpStatus.OK);
}
#GetMapping("all-articles")
public ResponseEntity<List<Article>> getAllArticles() {
List<Article> list = articleService.getAllArticles();
return new ResponseEntity<List<Article>>(list, HttpStatus.OK);
}
#PostMapping("article")
public ResponseEntity<Void> createArticle(#RequestBody Article article, UriComponentsBuilder builder) {
boolean flag = articleService.createArticle(article);
if (flag == false) {
return new ResponseEntity<Void>(HttpStatus.CONFLICT);
}
HttpHeaders headers = new HttpHeaders();
headers.setLocation(builder.path("/article?id={id}").buildAndExpand(article.getArticleId()).toUri());
return new ResponseEntity<Void>(headers, HttpStatus.CREATED);
}
#PutMapping("article")
public ResponseEntity<Article> updateArticle(#RequestBody Article article) {
articleService.updateArticle(article);
return new ResponseEntity<Article>(article, HttpStatus.OK);
}
#DeleteMapping("article")
public ResponseEntity<Void> deleteArticle(#RequestParam("id") String id) {
articleService.deleteArticle(Integer.parseInt(id));
return new ResponseEntity<Void>(HttpStatus.NO_CONTENT);
}
}
Did you create a Persistence Unit?
[Reference]=> https://docs.oracle.com/cd/E19798-01/821-1841/bnbrj/index.html
Once you already have the persistence-unit's tag defined you are able to create your entity manager like this:
private final String PERSISTENCE_UNIT_NAME = "PUName";
private EntityManagerFactory eMFactory = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT_NAME);
EntityManager entityManager=eMFactory.createEntityManager();

Save LocaTime via SpringData to MongoDB

I try to save a LocalTime (joda) field to the MongoDB with SpringData using spring-boot-starter-parent (org.springframework.boot 1.2.3.RELEASE) and get a StackOverflowError.
The StackOverflowError is in BeanWrapper in the method
public <S> S getProperty(PersistentProperty<?> property, Class<? extends S> type)
Stacktrace:
http-nio-8080-exec-2#5509 daemon, prio=5, in group 'main', status: 'RUNNING'
at org.springframework.data.mapping.model.BeanWrapper.getProperty(BeanWrapper.java:120)
at org.springframework.data.mapping.model.BeanWrapper.getProperty(BeanWrapper.java:100)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter$3.doWithPersistentProperty(MappingMongoConverter.java:419)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter$3.doWithPersistentProperty(MappingMongoConverter.java:412)
at org.springframework.data.mapping.model.BasicPersistentEntity.doWithProperties(BasicPersistentEntity.java:307)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.writeInternal(MappingMongoConverter.java:412)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.writePropertyInternal(MappingMongoConverter.java:511)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter$3.doWithPersistentProperty(MappingMongoConverter.java:424)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter$3.doWithPersistentProperty(MappingMongoConverter.java:412)
at org.springframework.data.mapping.model.BasicPersistentEntity.doWithProperties(BasicPersistentEntity.java:307)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.writeInternal(MappingMongoConverter.java:412)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.writePropertyInternal(MappingMongoConverter.java:511)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter$3.doWithPersistentProperty(MappingMongoConverter.java:424)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter$3.doWithPersistentProperty(MappingMongoConverter.java:412)
at org.springframework.data.mapping.model.BasicPersistentEntity.doWithProperties(BasicPersistentEntity.java:307)...
Adding these two Converters to the CustomConversions fix the problem.
#Configuration
public class MongoConfiguration extends AbstractMongoConfiguration {
#Override
protected String getDatabaseName() {
return "databasename";
}
#Override
public Mongo mongo() throws Exception {
return new MongoClient("localhost");
}
#Override
public CustomConversions customConversions() {
List<Converter<?, ?>> converters = new ArrayList<>();
converters.add(new LocalTimeToStringConverter());
converters.add(new StringToLocalTimeConverter());
return new CustomConversions(converters);
}
}
public class LocalTimeToStringConverter implements Converter<LocalTime, String> {
#Override
public String convert(LocalTime localTime) {
return localTime.toString();
}
}
public class StringToLocalTimeConverter implements Converter<String, LocalTime> {
#Override
public LocalTime convert(String s) {
return LocalTime.parse(s);
}
}

Map that extends TreeMap deserialized as empty map on client

I need to pass a map with a custom field to client.
just TreeMap works fine, but not descendants of TreeMap. If I change TreeMap to HashMap, it also works fine.
GWT 2.5.1
public class MyMap extends TreeMap<String, String> {
public String s;
public MyMap() {
}
public MyMap(String s) {
this.s = s;
}
}
public class GreetingServiceImpl extends RemoteServiceServlet implements GreetingService {
#Override
public Map<String, String> testSelfMap() {
Map<String, String> c = new MyMap("abc");
c.put("k", "v");
return c;
}
}
#RemoteServiceRelativePath("greet")
public interface GreetingService extends RemoteService {
Map<String, String> testSelfMap();
}
public interface GreetingServiceAsync {
void testSelfMap(AsyncCallback<Map<String, String>> async);
}
public class HW implements EntryPoint {
GreetingServiceAsync serv = GWT.create(GreetingService.class);
public void onModuleLoad() {
serv.testSelfMap(new AsyncCallback<Map<String, String>>() {
#Override
public void onSuccess(Map<String, String> result) {
System.out.println(result.get("k"));
}
#Override
public void onFailure(Throwable caught) {
caught.printStackTrace();
}
});
}
}

Junit to test restful service

I have written a junit to test my rest service offline.The junit for my restful controller extends AbstractControllerTestSupport which is used to create the dispatcherservletinstance.
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(loader=MockWebContextLoader.class, locations={"/rest-servlet- test.xml"})
public abstract class AbstractControllerTestSupport extends TestCase {
private static DispatcherServlet dispatcherServlet;
....
public static DispatcherServlet getServletInstance() {
if(null == dispatcherServlet) {
dispatcherServlet = new DispatcherServlet() {
protected WebApplicationContext createWebApplicationContext(WebApplicationContext parent) {
return MockWebContextLoader.getInstance();
}
};
System.out.println("dispatcher:"+dispatcherServlet.getContextConfigLocation()+":"+dispatcherServlet.getWebApplicationContext());
try {
dispatcherServlet.init(new MockServletConfig());
} catch (ServletException se) {
System.out.println("Exception"+se.getMessage());
}
}
return dispatcherServlet;
}
Following is my loader class.
public class MockWebContextLoader extends AbstractContextLoader {
public static final ServletContext SERVLET_CONTEXT = new MockServletContext(
"/mHealthAPIs", new FileSystemResourceLoader());
private final static GenericWebApplicationContext webContext = new GenericWebApplicationContext();
protected BeanDefinitionReader createBeanDefinitionReader(
final GenericApplicationContext context) {
return new XmlBeanDefinitionReader(context);
}
public final ConfigurableApplicationContext loadContext(
final String... locations) throws Exception {
SERVLET_CONTEXT.setAttribute(
WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE,
webContext);
webContext.setServletContext(SERVLET_CONTEXT);
createBeanDefinitionReader(webContext).loadBeanDefinitions(locations);
AnnotationConfigUtils.registerAnnotationConfigProcessors(webContext);
webContext.refresh();
webContext.registerShutdownHook();
return webContext;
}
public static WebApplicationContext getInstance() {
return webContext;
}
protected String getResourceSuffix() {
return "-context.xml";
}
the test runs fine with spring version 3.0 .However if I shift to spring 3.2.x it gives me following error "The type MockWebContextLoader must implement the inherited abstract method SmartContextLoader.loadContext(MergedContextConfiguration)" .This is because in 3.2.2 "AbstractContextLoader" implements "SmartContextLoader" .
Can you provide me with the work around?
Got the solution:I changed the MockWebContextLoader class as follows.
public class MockWebContextLoader extends AbstractContextLoader {
public static final ServletContext SERVLET_CONTEXT = new MockServletContext(
"/mHealthAPIs", new FileSystemResourceLoader());
private final static GenericWebApplicationContext webContext = new GenericWebApplicationContext();
protected BeanDefinitionReader createBeanDefinitionReader(
final GenericApplicationContext context) {
return new XmlBeanDefinitionReader(context);
}
#Override
public ApplicationContext loadContext(MergedContextConfiguration arg0)
throws Exception {
SERVLET_CONTEXT.setAttribute(
WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE,
webContext);
webContext.setServletContext(SERVLET_CONTEXT);
createBeanDefinitionReader(webContext).loadBeanDefinitions(
arg0.getLocations());
AnnotationConfigUtils.registerAnnotationConfigProcessors(webContext);
webContext.refresh();
webContext.registerShutdownHook();
return webContext;
}
public static WebApplicationContext getInstance() {
return webContext;
}
protected String getResourceSuffix() {
return "-context.xml";
}
public final ConfigurableApplicationContext loadContext(
final String... locations) throws Exception {
return null;
}
}