Commit d308c727 authored by Scott Frederick's avatar Scott Frederick

Support Boot 2.0

parent 963d307f
buildscript { buildscript {
ext { ext {
springBootVersion = '1.5.4.RELEASE' springBootVersion = '2.0.0.BUILD-SNAPSHOT'
springCloudConnectorsVersion = '1.2.4.RELEASE' springCloudConnectorsVersion = '2.0.0.BUILD-SNAPSHOT'
} }
repositories { repositories {
jcenter() jcenter()
mavenCentral() mavenCentral()
maven { url "https://repo.spring.io/plugins-release" } maven { url "https://repo.spring.io/plugins-release" }
maven { url "https://repo.spring.io/plugins-snapshot" }
} }
dependencies { dependencies {
...@@ -21,6 +22,7 @@ apply plugin: 'eclipse-wtp' ...@@ -21,6 +22,7 @@ apply plugin: 'eclipse-wtp'
apply plugin: 'idea' apply plugin: 'idea'
apply plugin: 'org.springframework.boot' apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'
version = '1.0' version = '1.0'
...@@ -29,6 +31,8 @@ targetCompatibility = 1.8 ...@@ -29,6 +31,8 @@ targetCompatibility = 1.8
repositories { repositories {
mavenCentral() mavenCentral()
mavenLocal()
maven { url "https://repo.spring.io/libs-snapshot" }
} }
dependencies { dependencies {
...@@ -45,7 +49,7 @@ dependencies { ...@@ -45,7 +49,7 @@ dependencies {
compile "org.springframework.cloud:spring-cloud-cloudfoundry-connector:${springCloudConnectorsVersion}" compile "org.springframework.cloud:spring-cloud-cloudfoundry-connector:${springCloudConnectorsVersion}"
// JPA Persistence // JPA Persistence
compile "commons-dbcp:commons-dbcp" compile "org.apache.commons:commons-dbcp2"
runtime "com.h2database:h2" runtime "com.h2database:h2"
runtime "mysql:mysql-connector-java" runtime "mysql:mysql-connector-java"
runtime "org.postgresql:postgresql" runtime "org.postgresql:postgresql"
......
...@@ -3,5 +3,5 @@ applications: ...@@ -3,5 +3,5 @@ applications:
- name: spring-music - name: spring-music
memory: 1G memory: 1G
random-route: true random-route: true
path: build/libs/spring-music.jar path: build/libs/spring-music-1.0.jar
package org.cloudfoundry.samples.music; package org.cloudfoundry.samples.music;
import org.cloudfoundry.samples.music.config.SpringApplicationContextInitializer; import org.cloudfoundry.samples.music.config.SpringApplicationContextInitializer;
import org.cloudfoundry.samples.music.repositories.AlbumRepositoryPopulator;
import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.support.SpringBootServletInitializer;
@SpringBootApplication @SpringBootApplication
public class Application extends SpringBootServletInitializer { public class Application {
public static void main(String[] args) { public static void main(String[] args) {
new SpringApplicationBuilder(Application.class). new SpringApplicationBuilder(Application.class)
initializers(new SpringApplicationContextInitializer()) .initializers(new SpringApplicationContextInitializer())
.listeners(new AlbumRepositoryPopulator())
.application() .application()
.run(args); .run(args);
} }
} }
\ No newline at end of file
...@@ -17,6 +17,7 @@ import org.springframework.context.ConfigurableApplicationContext; ...@@ -17,6 +17,7 @@ import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.env.ConfigurableEnvironment; import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
import javax.validation.constraints.NotNull;
import java.util.*; import java.util.*;
public class SpringApplicationContextInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> { public class SpringApplicationContextInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {
...@@ -26,7 +27,7 @@ public class SpringApplicationContextInitializer implements ApplicationContextIn ...@@ -26,7 +27,7 @@ public class SpringApplicationContextInitializer implements ApplicationContextIn
private static final Map<Class<? extends ServiceInfo>, String> serviceTypeToProfileName = new HashMap<>(); private static final Map<Class<? extends ServiceInfo>, String> serviceTypeToProfileName = new HashMap<>();
private static final List<String> validLocalProfiles = Arrays.asList("mysql", "postgres", "mongodb", "redis"); private static final List<String> validLocalProfiles = Arrays.asList("mysql", "postgres", "mongodb", "redis");
public static final String IN_MEMORY_PROFILE = "in-memory"; private static final String IN_MEMORY_PROFILE = "in-memory";
static { static {
serviceTypeToProfileName.put(MongoServiceInfo.class, "mongodb"); serviceTypeToProfileName.put(MongoServiceInfo.class, "mongodb");
...@@ -56,7 +57,7 @@ public class SpringApplicationContextInitializer implements ApplicationContextIn ...@@ -56,7 +57,7 @@ public class SpringApplicationContextInitializer implements ApplicationContextIn
} }
} }
public String[] getCloudProfile(Cloud cloud) { private String[] getCloudProfile(Cloud cloud) {
if (cloud == null) { if (cloud == null) {
return null; return null;
} }
......
package org.cloudfoundry.samples.music.config.data; package org.cloudfoundry.samples.music.config.data;
import org.apache.commons.dbcp.BasicDataSource; import org.apache.commons.dbcp2.BasicDataSource;
import javax.sql.DataSource; import javax.sql.DataSource;
......
package org.cloudfoundry.samples.music.domain; package org.cloudfoundry.samples.music.domain;
import org.hibernate.HibernateException; import org.hibernate.HibernateException;
import org.hibernate.engine.spi.SessionImplementor; import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.id.IdentifierGenerator; import org.hibernate.id.IdentifierGenerator;
import java.io.Serializable; import java.io.Serializable;
...@@ -9,7 +9,7 @@ import java.util.UUID; ...@@ -9,7 +9,7 @@ import java.util.UUID;
public class RandomIdGenerator implements IdentifierGenerator { public class RandomIdGenerator implements IdentifierGenerator {
@Override @Override
public Serializable generate(SessionImplementor session, Object object) throws HibernateException { public Serializable generate(SharedSessionContractImplementor session, Object object) throws HibernateException {
return generateId(); return generateId();
} }
......
...@@ -3,27 +3,20 @@ package org.cloudfoundry.samples.music.repositories; ...@@ -3,27 +3,20 @@ package org.cloudfoundry.samples.music.repositories;
import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import org.cloudfoundry.samples.music.domain.Album; import org.cloudfoundry.samples.music.domain.Album;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactoryUtils; import org.springframework.beans.factory.BeanFactoryUtils;
import org.springframework.context.ApplicationContext; import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ApplicationListener; import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.core.io.ClassPathResource; import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource; import org.springframework.core.io.Resource;
import org.springframework.data.repository.CrudRepository; import org.springframework.data.repository.CrudRepository;
import org.springframework.data.repository.init.Jackson2ResourceReader; import org.springframework.data.repository.init.Jackson2ResourceReader;
import org.springframework.stereotype.Component;
import java.util.Collection; import java.util.Collection;
@Component public class AlbumRepositoryPopulator implements ApplicationListener<ApplicationReadyEvent> {
public class AlbumRepositoryPopulator implements ApplicationListener<ContextRefreshedEvent>, ApplicationContextAware {
private final Jackson2ResourceReader resourceReader; private final Jackson2ResourceReader resourceReader;
private final Resource sourceData; private final Resource sourceData;
private ApplicationContext applicationContext;
public AlbumRepositoryPopulator() { public AlbumRepositoryPopulator() {
ObjectMapper mapper = new ObjectMapper(); ObjectMapper mapper = new ObjectMapper();
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
...@@ -32,25 +25,17 @@ public class AlbumRepositoryPopulator implements ApplicationListener<ContextRefr ...@@ -32,25 +25,17 @@ public class AlbumRepositoryPopulator implements ApplicationListener<ContextRefr
} }
@Override @Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { public void onApplicationEvent(ApplicationReadyEvent event) {
this.applicationContext = applicationContext; CrudRepository albumRepository =
} BeanFactoryUtils.beanOfTypeIncludingAncestors(event.getApplicationContext(), CrudRepository.class);
@Override
public void onApplicationEvent(ContextRefreshedEvent event) {
if (event.getApplicationContext().equals(applicationContext)) {
CrudRepository albumRepository =
BeanFactoryUtils.beanOfTypeIncludingAncestors(applicationContext, CrudRepository.class);
if (albumRepository != null && albumRepository.count() == 0) { if (albumRepository != null && albumRepository.count() == 0) {
populate(albumRepository); populate(albumRepository);
}
} }
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public void populate(CrudRepository repository) { private void populate(CrudRepository repository) {
Object entity = getEntityFromResource(sourceData); Object entity = getEntityFromResource(sourceData);
if (entity instanceof Collection) { if (entity instanceof Collection) {
......
...@@ -8,6 +8,7 @@ import org.springframework.data.repository.CrudRepository; ...@@ -8,6 +8,7 @@ import org.springframework.data.repository.CrudRepository;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Optional;
import java.util.Set; import java.util.Set;
public class RedisAlbumRepository implements CrudRepository<Album, String> { public class RedisAlbumRepository implements CrudRepository<Album, String> {
...@@ -33,7 +34,7 @@ public class RedisAlbumRepository implements CrudRepository<Album, String> { ...@@ -33,7 +34,7 @@ public class RedisAlbumRepository implements CrudRepository<Album, String> {
} }
@Override @Override
public <S extends Album> Iterable<S> save(Iterable<S> albums) { public <S extends Album> Iterable<S> saveAll(Iterable<S> albums) {
List<S> result = new ArrayList<>(); List<S> result = new ArrayList<>();
for (S entity : albums) { for (S entity : albums) {
...@@ -45,12 +46,12 @@ public class RedisAlbumRepository implements CrudRepository<Album, String> { ...@@ -45,12 +46,12 @@ public class RedisAlbumRepository implements CrudRepository<Album, String> {
} }
@Override @Override
public Album findOne(String id) { public Optional<Album> findById(String id) {
return hashOps.get(ALBUMS_KEY, id); return Optional.of(hashOps.get(ALBUMS_KEY, id));
} }
@Override @Override
public boolean exists(String id) { public boolean existsById(String id) {
return hashOps.hasKey(ALBUMS_KEY, id); return hashOps.hasKey(ALBUMS_KEY, id);
} }
...@@ -60,7 +61,7 @@ public class RedisAlbumRepository implements CrudRepository<Album, String> { ...@@ -60,7 +61,7 @@ public class RedisAlbumRepository implements CrudRepository<Album, String> {
} }
@Override @Override
public Iterable<Album> findAll(Iterable<String> ids) { public Iterable<Album> findAllById(Iterable<String> ids) {
return hashOps.multiGet(ALBUMS_KEY, convertIterableToList(ids)); return hashOps.multiGet(ALBUMS_KEY, convertIterableToList(ids));
} }
...@@ -70,7 +71,7 @@ public class RedisAlbumRepository implements CrudRepository<Album, String> { ...@@ -70,7 +71,7 @@ public class RedisAlbumRepository implements CrudRepository<Album, String> {
} }
@Override @Override
public void delete(String id) { public void deleteById(String id) {
hashOps.delete(ALBUMS_KEY, id); hashOps.delete(ALBUMS_KEY, id);
} }
...@@ -80,7 +81,7 @@ public class RedisAlbumRepository implements CrudRepository<Album, String> { ...@@ -80,7 +81,7 @@ public class RedisAlbumRepository implements CrudRepository<Album, String> {
} }
@Override @Override
public void delete(Iterable<? extends Album> albums) { public void deleteAll(Iterable<? extends Album> albums) {
for (Album album : albums) { for (Album album : albums) {
delete(album); delete(album);
} }
...@@ -90,7 +91,7 @@ public class RedisAlbumRepository implements CrudRepository<Album, String> { ...@@ -90,7 +91,7 @@ public class RedisAlbumRepository implements CrudRepository<Album, String> {
public void deleteAll() { public void deleteAll() {
Set<String> ids = hashOps.keys(ALBUMS_KEY); Set<String> ids = hashOps.keys(ALBUMS_KEY);
for (String id : ids) { for (String id : ids) {
delete(id); deleteById(id);
} }
} }
......
...@@ -40,12 +40,12 @@ public class AlbumController { ...@@ -40,12 +40,12 @@ public class AlbumController {
@RequestMapping(value = "/{id}", method = RequestMethod.GET) @RequestMapping(value = "/{id}", method = RequestMethod.GET)
public Album getById(@PathVariable String id) { public Album getById(@PathVariable String id) {
logger.info("Getting album " + id); logger.info("Getting album " + id);
return repository.findOne(id); return repository.findById(id).orElse(null);
} }
@RequestMapping(value = "/{id}", method = RequestMethod.DELETE) @RequestMapping(value = "/{id}", method = RequestMethod.DELETE)
public void deleteById(@PathVariable String id) { public void deleteById(@PathVariable String id) {
logger.info("Deleting album " + id); logger.info("Deleting album " + id);
repository.delete(id); repository.deleteById(id);
} }
} }
\ No newline at end of file
---
spring: spring:
jpa: jpa:
generate-ddl: true generate-ddl: true
# turn off the security on the actuator end points as this is a demo app
management: management:
security: endpoints:
enabled: false web:
\ No newline at end of file exposure:
include: "*"
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment