Change package names zero->boot

* actuator -> boot-ops
* cli -> boot-cli
* launcher -> boot-load
* autoconfig -> boot-config
* bootstrap -> boot-strap
* starters -> boot-up

[#54095231] [bs-253] Refactor Zero->Boot
This commit is contained in:
Dave Syer
2013-07-26 11:50:02 +01:00
parent b2873fbc2d
commit 2098e23fca
609 changed files with 1686 additions and 1626 deletions

View File

@@ -0,0 +1,48 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot</artifactId>
<version>0.5.0.BUILD-SNAPSHOT</version>
</parent>
<artifactId>spring-boot-samples</artifactId>
<packaging>pom</packaging>
<properties>
<main.basedir>${basedir}/..</main.basedir>
</properties>
<modules>
<module>spring-boot-sample-ops</module>
<module>spring-boot-sample-ops-ui</module>
<module>spring-boot-sample-batch</module>
<module>spring-boot-sample-data-jpa</module>
<module>spring-boot-sample-integration</module>
<module>spring-boot-sample-jetty</module>
<module>spring-boot-sample-profile</module>
<module>spring-boot-sample-simple</module>
<module>spring-boot-sample-tomcat</module>
<module>spring-boot-sample-traditional</module>
<module>spring-boot-sample-web-ui</module>
<module>spring-boot-sample-xml</module>
</modules>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>${project.groupId}</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${project.version}</version>
<extensions>true</extensions>
<executions>
<execution>
<goals>
<goal>package</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>

View File

@@ -0,0 +1,30 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-samples</artifactId>
<version>0.5.0.BUILD-SNAPSHOT</version>
</parent>
<artifactId>spring-boot-sample-batch</artifactId>
<packaging>jar</packaging>
<properties>
<main.basedir>${basedir}/../..</main.basedir>
</properties>
<dependencies>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>spring-boot-up-batch</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>${project.groupId}</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>

View File

@@ -0,0 +1,74 @@
/*
* Copyright 2012-2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.sample.batch;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.StepContribution;
import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
import org.springframework.batch.core.scope.context.ChunkContext;
import org.springframework.batch.core.step.tasklet.Tasklet;
import org.springframework.batch.repeat.RepeatStatus;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.config.EnableAutoConfiguration;
import org.springframework.boot.strap.SpringApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration
@EnableAutoConfiguration
@ComponentScan
@EnableBatchProcessing
public class SampleBatchApplication {
@Autowired
private JobBuilderFactory jobs;
@Autowired
private StepBuilderFactory steps;
@Bean
protected Tasklet tasklet() {
return new Tasklet() {
@Override
public RepeatStatus execute(StepContribution contribution,
ChunkContext context) {
return RepeatStatus.FINISHED;
}
};
}
@Bean
public Job job() throws Exception {
return this.jobs.get("job").start(step1()).build();
}
@Bean
protected Step step1() throws Exception {
return this.steps.get("step1").tasklet(tasklet()).build();
}
public static void main(String[] args) throws Exception {
// System.exit is common for Batch applications since the exit code can be used to
// drive a workflow
System.exit(SpringApplication.exit(SpringApplication.run(
SampleBatchApplication.class, args)));
}
}

View File

@@ -0,0 +1,65 @@
/*
* Copyright 2012-2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.sample.batch;
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.springframework.boot.sample.batch.SampleBatchApplication;
import org.springframework.boot.strap.SpringApplication;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
public class SampleBatchApplicationTests {
private PrintStream savedOutput;
private PrintStream savedErr;
private ByteArrayOutputStream output;
@Before
public void init() {
this.savedOutput = System.out;
this.savedErr = System.err;
this.output = new ByteArrayOutputStream();
System.setOut(new PrintStream(this.output));
System.setErr(new PrintStream(this.output));
}
@After
public void after() {
System.setOut(this.savedOutput);
System.setErr(this.savedErr);
}
private String getOutput() {
return this.output.toString();
}
@Test
public void testDefaultSettings() throws Exception {
assertEquals(0, SpringApplication.exit(SpringApplication
.run(SampleBatchApplication.class)));
String output = getOutput();
assertTrue("Wrong output: " + output,
output.contains("completed with the following parameters"));
}
}

View File

@@ -0,0 +1,41 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-samples</artifactId>
<version>0.5.0.BUILD-SNAPSHOT</version>
</parent>
<artifactId>spring-boot-sample-data-jpa</artifactId>
<packaging>jar</packaging>
<properties>
<main.basedir>${basedir}/../..</main.basedir>
</properties>
<dependencies>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>spring-boot-up-data-jpa</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>spring-boot-up-web</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.hsqldb</groupId>
<artifactId>hsqldb</artifactId>
<scope>runtime</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>${project.groupId}</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<extensions>true</extensions>
</plugin>
</plugins>
</build>
</project>

View File

@@ -0,0 +1,33 @@
/*
* Copyright 2012-2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.sample.data.jpa;
import org.springframework.boot.config.EnableAutoConfiguration;
import org.springframework.boot.strap.SpringApplication;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration
@ComponentScan
@EnableAutoConfiguration
public class SampleDataJpaApplication {
public static void main(String[] args) throws Exception {
SpringApplication.run(SampleDataJpaApplication.class, args);
}
}

View File

@@ -0,0 +1,76 @@
/*
* Copyright 2012-2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.sample.data.jpa.domain;
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
@Entity
public class City implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue
private Long id;
@Column(nullable = false)
private String name;
@Column(nullable = false)
private String state;
@Column(nullable = false)
private String country;
@Column(nullable = false)
private String map;
protected City() {
}
public City(String name, String country) {
super();
this.name = name;
this.country = country;
}
public String getName() {
return this.name;
}
public String getState() {
return this.state;
}
public String getCountry() {
return this.country;
}
public String getMap() {
return this.map;
}
@Override
public String toString() {
return getName() + "," + getState() + "," + getCountry();
}
}

View File

@@ -0,0 +1,81 @@
/*
* Copyright 2012-2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.sample.data.jpa.domain;
import java.io.Serializable;
import java.util.Set;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import org.hibernate.annotations.NaturalId;
@Entity
public class Hotel implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue
private Long id;
@ManyToOne(optional = false)
@NaturalId
private City city;
@Column(nullable = false)
@NaturalId
private String name;
@Column(nullable = false)
private String address;
@Column(nullable = false)
private String zip;
@OneToMany(fetch = FetchType.LAZY, mappedBy = "hotel")
private Set<Review> reviews;
protected Hotel() {
}
public Hotel(City city, String name) {
this.city = city;
this.name = name;
}
public City getCity() {
return this.city;
}
public String getName() {
return this.name;
}
public String getAddress() {
return this.address;
}
public String getZip() {
return this.zip;
}
}

View File

@@ -0,0 +1,63 @@
/*
* Copyright 2012-2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.sample.data.jpa.domain;
import java.io.Serializable;
import java.math.BigDecimal;
import java.math.MathContext;
import java.math.RoundingMode;
public class HotelSummary implements Serializable {
private static final long serialVersionUID = 1L;
private static final MathContext MATH_CONTEXT = new MathContext(2,
RoundingMode.HALF_UP);
private City city;
private String name;
private Double averageRating;
private Integer averageRatingRounded;
public HotelSummary(City city, String name, Double averageRating) {
this.city = city;
this.name = name;
this.averageRating = averageRating == null ? null : new BigDecimal(averageRating,
MATH_CONTEXT).doubleValue();
this.averageRatingRounded = averageRating == null ? null : (int) Math
.round(averageRating);
}
public City getCity() {
return this.city;
}
public String getName() {
return this.name;
}
public Double getAverageRating() {
return this.averageRating;
}
public Integer getAverageRatingRounded() {
return this.averageRatingRounded;
}
}

View File

@@ -0,0 +1,21 @@
/*
* Copyright 2012-2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.sample.data.jpa.domain;
public enum Rating {
TERRIBLE, POOR, AVERAGE, GOOD, EXCELLENT,
}

View File

@@ -0,0 +1,41 @@
/*
* Copyright 2012-2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.sample.data.jpa.domain;
import java.io.Serializable;
public class RatingCount implements Serializable {
private static final long serialVersionUID = 1L;
private Rating rating;
private long count;
public RatingCount(Rating rating, long count) {
this.rating = rating;
this.count = count;
}
public Rating getRating() {
return this.rating;
}
public long getCount() {
return this.count;
}
}

View File

@@ -0,0 +1,129 @@
/*
* Copyright 2012-2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.sample.data.jpa.domain;
import java.io.Serializable;
import java.util.Date;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import org.springframework.util.Assert;
@Entity
public class Review implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue
private Long id;
@ManyToOne(optional = false)
private Hotel hotel;
@Column(nullable = false)
private int index;
@Column(nullable = false)
@Enumerated(EnumType.ORDINAL)
private Rating rating;
@Column(nullable = false)
@Temporal(TemporalType.DATE)
private Date checkInDate;
@Column(nullable = false)
@Enumerated(EnumType.ORDINAL)
private TripType tripType;
@Column(nullable = false)
private String title;
@Column(nullable = false, length = 5000)
private String details;
protected Review() {
}
public Review(Hotel hotel, int index, ReviewDetails details) {
Assert.notNull(hotel, "Hotel must not be null");
Assert.notNull(details, "Details must not be null");
this.hotel = hotel;
this.index = index;
this.rating = details.getRating();
this.checkInDate = details.getCheckInDate();
this.tripType = details.getTripType();
this.title = details.getTitle();
this.details = details.getDetails();
}
public Hotel getHotel() {
return this.hotel;
}
public int getIndex() {
return this.index;
}
public Rating getRating() {
return this.rating;
}
public void setRating(Rating rating) {
this.rating = rating;
}
public Date getCheckInDate() {
return this.checkInDate;
}
public void setCheckInDate(Date checkInDate) {
this.checkInDate = checkInDate;
}
public TripType getTripType() {
return this.tripType;
}
public void setTripType(TripType tripType) {
this.tripType = tripType;
}
public String getTitle() {
return this.title;
}
public void setTitle(String title) {
this.title = title;
}
public String getDetails() {
return this.details;
}
public void setDetails(String details) {
this.details = details;
}
}

View File

@@ -0,0 +1,86 @@
/*
* Copyright 2012-2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.sample.data.jpa.domain;
import java.io.Serializable;
import java.util.Date;
//FIXME Hibernate bug HHH-5792 prevents this being embedded
public class ReviewDetails implements Serializable {
private static final long serialVersionUID = 1L;
private Rating rating;
private Date checkInDate;
private TripType tripType;
private String title;
private String details;
public ReviewDetails() {
}
@Deprecated
public ReviewDetails(String title, Rating rating) {
this.title = title;
this.rating = rating;
}
public Rating getRating() {
return this.rating;
}
public void setRating(Rating rating) {
this.rating = rating;
}
public Date getCheckInDate() {
return this.checkInDate;
}
public void setCheckInDate(Date checkInDate) {
this.checkInDate = checkInDate;
}
public TripType getTripType() {
return this.tripType;
}
public void setTripType(TripType tripType) {
this.tripType = tripType;
}
public String getTitle() {
return this.title;
}
public void setTitle(String title) {
this.title = title;
}
public String getDetails() {
return this.details;
}
public void setDetails(String details) {
this.details = details;
}
}

View File

@@ -0,0 +1,21 @@
/*
* Copyright 2012-2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.sample.data.jpa.domain;
public enum TripType {
BUSINESS, COUPLES, FAMILY, FRIENDS, SOLO
}

View File

@@ -0,0 +1,33 @@
/*
* Copyright 2012-2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.sample.data.jpa.domain.repository;
import org.springframework.boot.sample.data.jpa.domain.City;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.repository.Repository;
public interface CityRepository extends Repository<City, Long> {
Page<City> findAll(Pageable pageable);
Page<City> findByNameLikeAndCountryLikeAllIgnoringCase(String name, String country,
Pageable pageable);
City findByNameAndCountryAllIgnoringCase(String name, String country);
}

View File

@@ -0,0 +1,27 @@
/*
* Copyright 2012-2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.sample.data.jpa.domain.repository;
import org.springframework.boot.sample.data.jpa.domain.City;
import org.springframework.boot.sample.data.jpa.domain.Hotel;
import org.springframework.data.repository.Repository;
public interface HotelRepository extends Repository<Hotel, Long> {
Hotel findByCityAndName(City city, String name);
}

View File

@@ -0,0 +1,106 @@
/*
* Copyright 2012-2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.sample.data.jpa.domain.repository;
import java.util.List;
import java.util.Locale;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import org.springframework.boot.sample.data.jpa.domain.City;
import org.springframework.boot.sample.data.jpa.domain.Hotel;
import org.springframework.boot.sample.data.jpa.domain.HotelSummary;
import org.springframework.boot.sample.data.jpa.domain.RatingCount;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Order;
import org.springframework.stereotype.Repository;
@Repository
public class HotelSummaryRepository {
private static final String AVERAGE_REVIEW_FUNCTION = "avg(r.rating)";
private static final String FIND_BY_CITY_QUERY = "select new "
+ HotelSummary.class.getName() + "(h.city, h.name, "
+ AVERAGE_REVIEW_FUNCTION
+ ") from Hotel h left outer join h.reviews r where h.city = ?1 group by h";
private static final String FIND_BY_CITY_COUNT_QUERY = "select count(h) from Hotel h where h.city = ?1";
private static final String FIND_RATING_COUNTS_QUERY = "select new "
+ RatingCount.class.getName() + "(r.rating, count(r)) "
+ "from Review r where r.hotel = ?1 group by r.rating order by r.rating DESC";
private EntityManager entityManager;
public Page<HotelSummary> findByCity(City city, Pageable pageable) {
StringBuilder queryString = new StringBuilder(FIND_BY_CITY_QUERY);
applySorting(queryString, pageable == null ? null : pageable.getSort());
Query query = this.entityManager.createQuery(queryString.toString());
query.setParameter(1, city);
query.setFirstResult(pageable.getOffset());
query.setMaxResults(pageable.getPageSize());
Query countQuery = this.entityManager.createQuery(FIND_BY_CITY_COUNT_QUERY);
countQuery.setParameter(1, city);
@SuppressWarnings("unchecked")
List<HotelSummary> content = query.getResultList();
Long total = (Long) countQuery.getSingleResult();
return new PageImpl<HotelSummary>(content, pageable, total);
}
@SuppressWarnings("unchecked")
public List<RatingCount> findRatingCounts(Hotel hotel) {
Query query = this.entityManager.createQuery(FIND_RATING_COUNTS_QUERY);
query.setParameter(1, hotel);
return query.getResultList();
}
private void applySorting(StringBuilder query, Sort sort) {
if (sort != null) {
query.append(" order by");
for (Order order : sort) {
String aliasedProperty = getAliasedProperty(order.getProperty());
query.append(String.format(" %s %s,", aliasedProperty, order
.getDirection().name().toLowerCase(Locale.US)));
}
query.deleteCharAt(query.length() - 1);
}
}
private String getAliasedProperty(String property) {
if (property.equals("averageRating")) {
return AVERAGE_REVIEW_FUNCTION;
}
return "h." + property;
}
@PersistenceContext
public void setEntityManager(EntityManager entityManager) {
this.entityManager = entityManager;
}
}

View File

@@ -0,0 +1,31 @@
/*
* Copyright 2012-2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.sample.data.jpa.domain.repository;
import org.springframework.boot.sample.data.jpa.domain.Hotel;
import org.springframework.boot.sample.data.jpa.domain.Review;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.repository.Repository;
public interface ReviewRepository extends Repository<Review, Long> {
Page<Review> findByHotel(Hotel hotel, Pageable pageable);
Review findByHotelAndIndex(Hotel hotel, int index);
}

View File

@@ -0,0 +1,44 @@
/*
* Copyright 2012-2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.sample.data.jpa.service;
import java.io.Serializable;
import org.springframework.util.Assert;
public class CitySearchCriteria implements Serializable {
private static final long serialVersionUID = 1L;
private String name;
public CitySearchCriteria() {
}
public CitySearchCriteria(String name) {
Assert.notNull(name, "Name must not be null");
this.name = name;
}
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
}

View File

@@ -0,0 +1,32 @@
/*
* Copyright 2012-2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.sample.data.jpa.service;
import org.springframework.boot.sample.data.jpa.domain.City;
import org.springframework.boot.sample.data.jpa.domain.HotelSummary;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
public interface CityService {
Page<City> findCities(CitySearchCriteria criteria, Pageable pageable);
City getCity(String name, String country);
Page<HotelSummary> getHotels(City city, Pageable pageable);
}

View File

@@ -0,0 +1,38 @@
/*
* Copyright 2012-2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.sample.data.jpa.service;
import org.springframework.boot.sample.data.jpa.domain.City;
import org.springframework.boot.sample.data.jpa.domain.Hotel;
import org.springframework.boot.sample.data.jpa.domain.Review;
import org.springframework.boot.sample.data.jpa.domain.ReviewDetails;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
public interface HotelService {
Hotel getHotel(City city, String name);
Page<Review> getReviews(Hotel hotel, Pageable pageable);
Review getReview(Hotel hotel, int index);
Review addReview(Hotel hotel, ReviewDetails details);
ReviewsSummary getReviewSummary(Hotel hotel);
}

View File

@@ -0,0 +1,25 @@
/*
* Copyright 2012-2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.sample.data.jpa.service;
import org.springframework.boot.sample.data.jpa.domain.Rating;
public interface ReviewsSummary {
public long getNumberOfReviewsWithRating(Rating rating);
}

View File

@@ -0,0 +1,84 @@
/*
* Copyright 2012-2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.sample.data.jpa.service.impl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.sample.data.jpa.domain.City;
import org.springframework.boot.sample.data.jpa.domain.HotelSummary;
import org.springframework.boot.sample.data.jpa.domain.repository.CityRepository;
import org.springframework.boot.sample.data.jpa.domain.repository.HotelSummaryRepository;
import org.springframework.boot.sample.data.jpa.service.CitySearchCriteria;
import org.springframework.boot.sample.data.jpa.service.CityService;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
@Component("cityService")
@Transactional
public class CityServiceImpl implements CityService {
// FIXME deal with null repository return values
private CityRepository cityRepository;
private HotelSummaryRepository hotelSummaryRepository;
@Override
public Page<City> findCities(CitySearchCriteria criteria, Pageable pageable) {
Assert.notNull(criteria, "Criteria must not be null");
String name = criteria.getName();
if (!StringUtils.hasLength(name)) {
return this.cityRepository.findAll(null);
}
String country = "";
int splitPos = name.lastIndexOf(",");
if (splitPos >= 0) {
country = name.substring(splitPos + 1);
name = name.substring(0, splitPos);
}
name = "%" + name.trim() + "%";
country = "%" + country.trim() + "%";
return this.cityRepository.findByNameLikeAndCountryLikeAllIgnoringCase(name,
country, pageable);
}
@Override
public City getCity(String name, String country) {
Assert.notNull(name, "Name must not be null");
Assert.notNull(country, "Country must not be null");
return this.cityRepository.findByNameAndCountryAllIgnoringCase(name, country);
}
@Override
public Page<HotelSummary> getHotels(City city, Pageable pageable) {
Assert.notNull(city, "City must not be null");
return this.hotelSummaryRepository.findByCity(city, pageable);
}
@Autowired
public void setCityRepository(CityRepository cityRepository) {
this.cityRepository = cityRepository;
}
@Autowired
public void setHotelSummaryRepository(HotelSummaryRepository hotelSummaryRepository) {
this.hotelSummaryRepository = hotelSummaryRepository;
}
}

View File

@@ -0,0 +1,118 @@
/*
* Copyright 2012-2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.sample.data.jpa.service.impl;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.sample.data.jpa.domain.City;
import org.springframework.boot.sample.data.jpa.domain.Hotel;
import org.springframework.boot.sample.data.jpa.domain.Rating;
import org.springframework.boot.sample.data.jpa.domain.RatingCount;
import org.springframework.boot.sample.data.jpa.domain.Review;
import org.springframework.boot.sample.data.jpa.domain.ReviewDetails;
import org.springframework.boot.sample.data.jpa.domain.repository.HotelRepository;
import org.springframework.boot.sample.data.jpa.domain.repository.HotelSummaryRepository;
import org.springframework.boot.sample.data.jpa.domain.repository.ReviewRepository;
import org.springframework.boot.sample.data.jpa.service.HotelService;
import org.springframework.boot.sample.data.jpa.service.ReviewsSummary;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
@Component("hotelService")
@Transactional
public class HotelServiceImpl implements HotelService {
// FIXME deal with null repository return values
private HotelRepository hotelRepository;
private HotelSummaryRepository hotelSummaryRepository;
private ReviewRepository reviewRepository;
@Override
public Hotel getHotel(City city, String name) {
Assert.notNull(city, "City must not be null");
Assert.hasLength(name, "Name must not be empty");
return this.hotelRepository.findByCityAndName(city, name);
}
@Override
public Page<Review> getReviews(Hotel hotel, Pageable pageable) {
Assert.notNull(hotel, "Hotel must not be null");
return this.reviewRepository.findByHotel(hotel, pageable);
}
@Override
public Review getReview(Hotel hotel, int reviewNumber) {
Assert.notNull(hotel, "Hotel must not be null");
return this.reviewRepository.findByHotelAndIndex(hotel, reviewNumber);
}
@Override
public Review addReview(Hotel hotel, ReviewDetails details) {
// FIXME
System.out.println(details.getTitle());
return new Review(hotel, 1, details);
}
@Override
public ReviewsSummary getReviewSummary(Hotel hotel) {
List<RatingCount> ratingCounts = this.hotelSummaryRepository
.findRatingCounts(hotel);
return new ReviewsSummaryImpl(ratingCounts);
}
@Autowired
public void setHotelRepository(HotelRepository hotelRepository) {
this.hotelRepository = hotelRepository;
}
@Autowired
public void setHotelSummaryRepository(HotelSummaryRepository hotelSummaryRepository) {
this.hotelSummaryRepository = hotelSummaryRepository;
}
@Autowired
public void setReviewRepository(ReviewRepository reviewRepository) {
this.reviewRepository = reviewRepository;
}
private static class ReviewsSummaryImpl implements ReviewsSummary {
private Map<Rating, Long> ratingCount;
public ReviewsSummaryImpl(List<RatingCount> ratingCounts) {
this.ratingCount = new HashMap<Rating, Long>();
for (RatingCount ratingCount : ratingCounts) {
this.ratingCount.put(ratingCount.getRating(), ratingCount.getCount());
}
}
@Override
public long getNumberOfReviewsWithRating(Rating rating) {
Long count = this.ratingCount.get(rating);
return count == null ? 0 : count;
}
}
}

View File

@@ -0,0 +1,36 @@
/*
* Copyright 2012-2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.sample.data.jpa.web;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.sample.data.jpa.service.CityService;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class SampleController {
@Autowired
private CityService cityService;
@RequestMapping("/")
@ResponseBody
public String helloWorld() {
return this.cityService.getCity("Bath", "UK").getName();
}
}

View File

@@ -0,0 +1 @@
spring.jpa.ddl_auto: create-drop

View File

@@ -0,0 +1,186 @@
--
-- Sample dataset containing a number of Hotels in various Cities across the world. The reviews are entirely fictional :)
--
-- =================================================================================================
-- AUSTRALIA
-- Brisbane
insert into City(country,name,state,map) values ('Australia', 'Brisbane', 'Queensland', '-27.470933,153.023502')
insert into Hotel(city_id,name,address,zip) values (1,'Conrad Treasury Place', 'William & George Streets', '4001')
-- Melbourne
insert into City(country,name,state,map) values ('Australia', 'Melbourne', 'Victoria', '-37.813187,144.96298')
insert into Hotel(city_id,name,address,zip) values (2,'The Langham','1 Southgate Ave, Southbank', '3006')
insert into Review(hotel_id,index,checkInDate,rating,tripType,title,details) values (2,0,'2005-05-10',2,4,'Pretty average','I stayed in 2005, the hotel was nice enough but nothing special.')
insert into Review(hotel_id,index,checkInDate,rating,tripType,title,details) values (2,1,'2006-01-12',4,2,'Bright hotel with big rooms','This hotel has a fantastic lovely big windows. The room we stayed in had lots of space. Recommended.')
insert into Review(hotel_id,index,checkInDate,rating,tripType,title,details) values (2,2,'2006-05-25',3,1,'Pretty good','I liked this hotel and would stay again.')
insert into Review(hotel_id,index,checkInDate,rating,tripType,title,details) values (2,3,'2009-01-20',3,2,'Nice clean rooms','The rooms are maintained to a high standard and very clean, the bathroom was spotless!!')
-- Sydney
insert into City(country,name,state,map) values ('Australia', 'Sydney', 'New South Wales', '-33.868901,151.207091')
insert into Hotel(city_id,name,address,zip) values (3,'Swissotel', '68 Market Street', '2000')
-- =================================================================================================
-- CANADA
-- Montreal
insert into City(country,name,state,map) values ('Canada', 'Montreal', 'Quebec', '45.508889,-73.554167')
insert into Hotel(city_id,name,address,zip) values (4,'Ritz Carlton', '1228 Sherbrooke St','H3G1H6')
-- =================================================================================================
-- ISRAEL
-- Tel Aviv
insert into City(country,name,state,map) values ('Israel', 'Tel Aviv', '', '32.066157,34.777821')
insert into Hotel(city_id,name,address,zip) values (5,'Hilton Tel Aviv', 'Independence Park', '63405')
-- =================================================================================================
-- JAPAN
-- Tokyo
insert into City(country,name,state,map) values ('Japan', 'Tokyo', '', '35.689488,139.691706')
insert into Hotel(city_id,name,address,zip) values (6,'InterContinental Tokyo Bay', 'Takeshiba Pier', '105')
-- =================================================================================================
-- SPAIN
-- Barcelona
insert into City(country,name,state,map) values ('Spain', 'Barcelona', 'Catalunya', '41.387917,2.169919')
insert into Hotel(city_id,name,address,zip) values (7,'Hilton Diagonal Mar', 'Passeig del Taulat 262-264', '08019')
-- =================================================================================================
-- SWITZERLAND
-- Neuchatel
insert into City(country,name,state,map) values ('Switzerland', 'Neuchatel', '', '46.992979,6.931933')
insert into Hotel(city_id,name,address,zip) values (8,'Hotel Beaulac', ' Esplanade Leopold-Robert 2', '2000')
-- =================================================================================================
-- UNITED KINGDOM
-- Bath
insert into City(country,name,state,map) values ('UK', 'Bath', 'Somerset', '51.381428,-2.357454')
insert into Hotel(city_id,name,address,zip) values (9,'The Bath Priory Hotel', 'Weston Road', 'BA1 2XT')
insert into Review(hotel_id,index,checkInDate,rating,tripType,title,details) values (9,0,'2000-01-23',4,1,'A lovely hotel','We stayed here after a wedding and it was fantastic. Recommend to all.')
insert into Review(hotel_id,index,checkInDate,rating,tripType,title,details) values (9,1,'2000-08-04',3,1,'Very special','A very special hotel with lovely staff.')
insert into Review(hotel_id,index,checkInDate,rating,tripType,title,details) values (9,2,'2001-01-01',2,4,'Nice but too hot','Stayed during the summer heat wave (exceptional for England!) and the room was very hot. Still recommended.')
insert into Review(hotel_id,index,checkInDate,rating,tripType,title,details) values (9,3,'2002-01-20',3,1,'Big rooms and a great view','Considering how central this hotel is the rooms are a very good size.')
insert into Review(hotel_id,index,checkInDate,rating,tripType,title,details) values (9,4,'2002-11-03',2,1,'Good but pricey','A nice hotel but be prepared to pay over the odds for your stay.')
insert into Review(hotel_id,index,checkInDate,rating,tripType,title,details) values (9,5,'2003-09-18',4,1,'Fantastic place','Just lovely.')
insert into Review(hotel_id,index,checkInDate,rating,tripType,title,details) values (9,6,'2004-03-21',4,3,'A very special place','I stayed here in 2004 and found it to be very relaxing, a nice pool and good gym is cherry on the cake.')
insert into Review(hotel_id,index,checkInDate,rating,tripType,title,details) values (9,7,'2004-04-10',0,0,'Terrible','I complained after I was told I could not check out after 11pm. Ridiculous!!!')
insert into Review(hotel_id,index,checkInDate,rating,tripType,title,details) values (9,8,'2004-12-20',4,4,'A perfect location','Central location makes this a perfect hotel. Be warned though, it''s not cheap.')
insert into Review(hotel_id,index,checkInDate,rating,tripType,title,details) values (9,9,'2005-04-19',3,2,'Expensive but worth it','Dig deep into your pockets and enjoy this lovely City and fantastic hotel.')
insert into Review(hotel_id,index,checkInDate,rating,tripType,title,details) values (9,10,'2005-05-21',4,1,'The best hotel in the area','Top hotel in the area, would not stay anywhere else.')
insert into Review(hotel_id,index,checkInDate,rating,tripType,title,details) values (9,11,'2005-11-17',4,2,'Lovely hotel, fantastic grounds','The garden upkeep run into thousands (perhaps explaining why the rooms are so much) but so lovely and relaxing.')
insert into Review(hotel_id,index,checkInDate,rating,tripType,title,details) values (9,12,'2006-01-04',3,4,'Gorgeous Top Quality Hotel','Top draw stuff.')
insert into Review(hotel_id,index,checkInDate,rating,tripType,title,details) values (9,13,'2006-01-21',4,1,'Fabulous Hotel and Restaurant','The food at this hotel is second to none, try the peppered steak!')
insert into Review(hotel_id,index,checkInDate,rating,tripType,title,details) values (9,14,'2006-01-29',4,4,'Feels like home','A lovely home away from home.')
insert into Review(hotel_id,index,checkInDate,rating,tripType,title,details) values (9,15,'2006-03-21',1,1,'Far too expensive','Overpriced, Overpriced, Overpriced!!')
insert into Review(hotel_id,index,checkInDate,rating,tripType,title,details) values (9,16,'2006-05-10',4,1,'Excellent Hotel, Wonderful Staff','The staff went out of their way to help us after we missed our last train home, organising a Taxi back to Newport even after we had checked out.')
insert into Review(hotel_id,index,checkInDate,rating,tripType,title,details) values (9,17,'2007-09-11',3,2,'The perfect retreat','If you want a relaxing stay, this is the place.')
insert into Review(hotel_id,index,checkInDate,rating,tripType,title,details) values (9,18,'2008-06-01',3,3,'Lovely stay, fantastic staff','As other reviews have noted, the staff in this hotel really are the best in Bath.')
insert into Review(hotel_id,index,checkInDate,rating,tripType,title,details) values (9,19,'2009-05-14',4,2,'Can''t Wait to go back','We will stay again for sure.')
insert into Review(hotel_id,index,checkInDate,rating,tripType,title,details) values (9,20,'2010-04-26',4,1,'Amazing Hotel','We won a trip here after entering a competition. Not sure we would pay the full price but such a wonderful place.')
insert into Review(hotel_id,index,checkInDate,rating,tripType,title,details) values (9,21,'2010-10-26',2,2,'Dissapointed','The pool was closed, the chief was ill, the staff were rude my wallet is bruised!')
insert into Hotel(city_id,name,address,zip) values (9,'Bath Travelodge', 'Rossiter Road, Widcombe Basin', 'BA2 4JP')
insert into Review(hotel_id,index,checkInDate,rating,tripType,title,details) values (10,0,'2002-08-21',0,2,'Terrible hotel','One of the worst hotels that I have ever stayed in.')
insert into Review(hotel_id,index,checkInDate,rating,tripType,title,details) values (10,1,'2003-01-28',0,0,'Rude and unpleasant staff','The staff refused to help me with any aspect of my stay, I will not stay here again.')
insert into Review(hotel_id,index,checkInDate,rating,tripType,title,details) values (10,2,'2004-06-17',1,0,'Below par','Don''t stay here!!')
insert into Review(hotel_id,index,checkInDate,rating,tripType,title,details) values (10,3,'2005-07-12',0,1,'Small and Unpleasant','The room was far too small and felt unclean. Not recommended.')
insert into Review(hotel_id,index,checkInDate,rating,tripType,title,details) values (10,4,'2006-01-07',1,4,'Cheap if you are not fussy','This hotel has some rough edges but I challenge you to find somewhere cheaper.')
insert into Review(hotel_id,index,checkInDate,rating,tripType,title,details) values (10,5,'2006-01-13',0,2,'Terrible','Just terrible!')
insert into Review(hotel_id,index,checkInDate,rating,tripType,title,details) values (10,6,'2006-03-25',0,0,'Smelly and dirty room','My room smelt of damp and I found the socks of the previous occupant under my bed.')
insert into Review(hotel_id,index,checkInDate,rating,tripType,title,details) values (10,7,'2006-04-09',0,4,'Grim','Grim. I would try elsewhere before staying here.')
insert into Review(hotel_id,index,checkInDate,rating,tripType,title,details) values (10,8,'2006-08-01',1,3,'Very Noisy','Building work during the day and a disco at night. Good grief!')
insert into Review(hotel_id,index,checkInDate,rating,tripType,title,details) values (10,9,'2009-01-03',1,4,'Tired and falling down','This hotel is in serious need of refurbishment, the windows are rotting, the paintwork is tired and the carpets are from the 1970s.')
insert into Review(hotel_id,index,checkInDate,rating,tripType,title,details) values (10,10,'2009-07-20',0,0,'Not suitable for human habitation','I would not put my dog up in this hotel.')
insert into Review(hotel_id,index,checkInDate,rating,tripType,title,details) values (10,11,'2010-05-20',1,0,'Conveient for the railway','Average place but useful if you need to commute')
insert into Review(hotel_id,index,checkInDate,rating,tripType,title,details) values (10,12,'2010-01-22',2,2,'Not as bad as the reviews','Some of the reviews seem a bit harsh, it''s not too bad for the price.')
insert into Review(hotel_id,index,checkInDate,rating,tripType,title,details) values (10,13,'2011-01-10',3,1,'Reburished and nice','Looks like this hotel has had a major facelift. If you have stayed before 2011 perhaps it''s time to give this hotel another try. Very good value for money and pretty nice.')
-- London
insert into City(country,name,state,map) values ('UK', 'London', '', '51.500152,-0.126236')
insert into Hotel(city_id,name,address,zip) values (10,'Melia White House', 'Albany Street','NW1 3UP')
-- Southampton
insert into City(country,name,state,map) values ('UK', 'Southampton', 'Hampshire', '50.902571,-1.397238')
insert into Hotel(city_id,name,address,zip) values (11,'Chilworth Manor', 'The Cottage, Southampton Business Park', 'SO16 7JF')
-- =================================================================================================
-- USA
-- Atlanta
insert into City(country,name,state,map) values ('USA', 'Atlanta', 'GA', '33.748995,-84.387982')
insert into Hotel(city_id,name,address,zip) values (12,'Marriott Courtyard', 'Tower Place, Buckhead', '30305')
insert into Review(hotel_id,index,checkInDate,rating,tripType,title,details) values (13,0,'2009-01-20',3,0,'Better than most','Most other hotels is this area are a bit ropey, this one is actually pretty good.')
insert into Hotel(city_id,name,address,zip) values (12,'Ritz Carlton', 'Peachtree Rd, Buckhead','30326')
insert into Hotel(city_id,name,address,zip) values (12,'Doubletree', 'Tower Place, Buckhead', '30305')
insert into Review(hotel_id,index,checkInDate,rating,tripType,title,details) values (15,0,'2006-01-12',2,3,'No fuss hotel','Cheap, no fuss hotel. Good if you are travelling on business and just need a place to stay.')
insert into Review(hotel_id,index,checkInDate,rating,tripType,title,details) values (15,1,'2009-01-20',2,2,'Nice area but small rooms','The area felt nice and safe but the rooms are a little on the small side')
-- Chicago
insert into City(country,name,state,map) values ('USA', 'Chicago', 'IL', '41.878114,-87.629798')
insert into Hotel(city_id,name,address,zip) values (13,'Hotel Allegro', '171 West Randolph Street', '60601')
insert into Review(hotel_id,index,checkInDate,rating,tripType,title,details) values (16,0,'2009-12-15',3,2,'Cheap and Recommended','Good value for money, can''t really fault it.')
-- Eau Claire
insert into City(country,name,state,map) values ('USA', 'Eau Claire', 'WI', '44.811349,-91.498494')
insert into Hotel(city_id,name,address,zip) values (14, 'Sea Horse Inn', '2106 N Clairemont Ave', '54703')
insert into Hotel(city_id,name,address,zip) values (14, 'Super 8 Eau Claire Campus Area', '1151 W Macarthur Ave', '54701')
-- Hollywood
insert into City(country,name,state,map) values ('USA', 'Hollywood', 'FL', '26.011201,-80.14949')
insert into Hotel(city_id,name,address,zip) values (15, 'Westin Diplomat', '3555 S. Ocean Drive','33019')
insert into Review(hotel_id,index,checkInDate,rating,tripType,title,details) values (19,0,'2006-01-11',0,0,'Avoid','The hotel has a very bad reputation. I would avoid it if I were you.')
-- Miami
insert into City(country,name,state,map) values ('USA', 'Miami', 'FL', '25.788969,-80.226439')
insert into Hotel(city_id,name,address,zip) values (16,'Conrad Miami', '1395 Brickell Ave', '33131')
insert into Review(hotel_id,index,checkInDate,rating,tripType,title,details) values (20,0,'2010-01-09',3,2,'Close to the local attractions','Fantastic access to all the local attractions mean you won''t mind the small rooms.')
insert into Review(hotel_id,index,checkInDate,rating,tripType,title,details) values (20,1,'2010-09-10',2,2,'Good value and friendly','Not expensive and very welcoming staff. I would stay again.')
-- Melbourne
insert into City(country,name,state,map) values ('USA', 'Melbourne', 'FL', '28.083627,-80.608109')
insert into Hotel(city_id,name,address,zip) values (17,'Radisson Suite Hotel Oceanfront', '3101 North Hwy', '32903')
insert into Review(hotel_id,index,checkInDate,rating,tripType,title,details) values (21,0,'2005-06-15',3,3,'A very nice hotel','I can''t fault this hotel and I have stayed here many times. Always friendly staff and lovely atmosphere.')
insert into Review(hotel_id,index,checkInDate,rating,tripType,title,details) values (21,1,'2006-01-20',2,4,'Comfortable and good value','To complaints at all.')
insert into Review(hotel_id,index,checkInDate,rating,tripType,title,details) values (21,2,'2007-08-21',3,1,'Above average','Better than a lot of hotels in the area and not too pricey.')
-- New York
insert into City(country,name,state,map) values ('USA', 'New York', 'NY', '40.714353,-74.005973')
insert into Hotel(city_id,name,address,zip) values (18, 'W Union Hotel', 'Union Square, Manhattan', '10011')
insert into Review(hotel_id,index,checkInDate,rating,tripType,title,details) values (22,0,'2002-01-19',0,1,'Too noisy, too small','The city never sleeps and neither will you if you say here. The rooms are small and the sound insulation is poor!')
insert into Review(hotel_id,index,checkInDate,rating,tripType,title,details) values (22,1,'2004-03-10',1,4,'Overpriced','Far too much money for such a tiny room!')
insert into Review(hotel_id,index,checkInDate,rating,tripType,title,details) values (22,2,'2007-04-11',2,0,'So so, nothing special','Not brilliant but not too bad either.')
insert into Hotel(city_id,name,address,zip) values (18, 'W Lexington Hotel', 'Lexington Ave, Manhattan', '10011')
insert into Review(hotel_id,index,checkInDate,rating,tripType,title,details) values (23,0,'2004-07-21',3,2,'Excellent location','So close to the heart of the city. Recommended.')
insert into Review(hotel_id,index,checkInDate,rating,tripType,title,details) values (23,1,'2006-05-20',3,1,'Very nice','I can''t fault this hotel, clean, good location and nice staff.')
insert into Hotel(city_id,name,address,zip) values (18, '70 Park Avenue Hotel', '70 Park Avenue', '10011')
insert into Review(hotel_id,index,checkInDate,rating,tripType,title,details) values (24,0,'2003-11-10',4,1,'Great!!','I own this hotel and I think it is pretty darn good.')
-- Palm Bay
insert into City(country,name,state,map) values ('USA', 'Palm Bay', 'FL', '28.034462,-80.588665')
insert into Hotel(city_id,name,address,zip) values (19,'Jameson Inn', '890 Palm Bay Rd NE', '32905')
insert into Review(hotel_id,index,checkInDate,rating,tripType,title,details) values (25,0,'2005-10-20',3,2,'Fantastical','This is the BEST hotel in Palm Bay, not complaints at all.')
insert into Review(hotel_id,index,checkInDate,rating,tripType,title,details) values (25,1,'2006-01-12',4,1,'Top marks','I rate this hotel 5 stars, the best in the area by miles.')
-- San Francisco
insert into City(country,name,state,map) values ('USA', 'San Francisco', 'CA', '37.77493,-122.419415')
insert into Hotel(city_id,name,address,zip) values (20, 'Marriot Downtown', '55 Fourth Street', '94103')
insert into Review(hotel_id,index,checkInDate,rating,tripType,title,details) values (26,0,'2006-07-02',2,3,'Could be better','I stayed in late 2006 with work, the room was very small and the restaurant does not stay open very late.')
insert into Review(hotel_id,index,checkInDate,rating,tripType,title,details) values (26,1,'2008-07-01',1,4,'Brrrr cold!','My room was freezing cold, I would not recommend this place.')
insert into Review(hotel_id,index,checkInDate,rating,tripType,title,details) values (26,2,'2009-01-05',3,2,'Nice for money','You can''t really go wrong here for the money. There may be better places to stay but not for this price.')
-- Washington
insert into City(country,name,state,map) values ('USA', 'Washington', 'DC', '38.895112,-77.036366')
insert into Hotel(city_id,name,address,zip) values (21, 'Hotel Rouge', '1315 16th Street NW', '20036')
insert into Review(hotel_id,index,checkInDate,rating,tripType,title,details) values (27,0,'2000-01-29',0,2,'Never again','I will never ever stay here again!! They wanted extra cash to get fresh batteries for the TV remote')
insert into Review(hotel_id,index,checkInDate,rating,tripType,title,details) values (27,1,'2006-02-20',0,0,'Avoid','This place is the pits, they charged us twice for a single night stay. I only got refunded after contacting my credit card company.')

View File

@@ -0,0 +1,88 @@
/*
* Copyright 2012-2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.sample.data.jpa;
import java.io.IOException;
import java.util.concurrent.Callable;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import org.springframework.boot.sample.data.jpa.SampleDataJpaApplication;
import org.springframework.boot.strap.SpringApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.web.client.DefaultResponseErrorHandler;
import org.springframework.web.client.RestTemplate;
import static org.junit.Assert.assertEquals;
/**
* Basic integration tests for service demo application.
*
* @author Dave Syer
*/
public class SampleDataJpaApplicationTests {
private static ConfigurableApplicationContext context;
@BeforeClass
public static void start() throws Exception {
Future<ConfigurableApplicationContext> future = Executors
.newSingleThreadExecutor().submit(
new Callable<ConfigurableApplicationContext>() {
@Override
public ConfigurableApplicationContext call() throws Exception {
return (ConfigurableApplicationContext) SpringApplication
.run(SampleDataJpaApplication.class);
}
});
context = future.get(10, TimeUnit.SECONDS);
}
@AfterClass
public static void stop() {
if (context != null) {
context.close();
}
}
@Test
public void testHome() throws Exception {
ResponseEntity<String> entity = getRestTemplate().getForEntity(
"http://localhost:8080", String.class);
assertEquals(HttpStatus.OK, entity.getStatusCode());
assertEquals("Bath", entity.getBody());
}
private RestTemplate getRestTemplate() {
RestTemplate restTemplate = new RestTemplate();
restTemplate.setErrorHandler(new DefaultResponseErrorHandler() {
@Override
public void handleError(ClientHttpResponse response) throws IOException {
}
});
return restTemplate;
}
}

View File

@@ -0,0 +1,30 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-samples</artifactId>
<version>0.5.0.BUILD-SNAPSHOT</version>
</parent>
<artifactId>spring-boot-sample-integration</artifactId>
<packaging>jar</packaging>
<properties>
<main.basedir>${basedir}/../..</main.basedir>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-up-integration</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>${project.groupId}</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>

View File

@@ -0,0 +1,32 @@
/*
* Copyright 2012-2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.sample.integration;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class HelloWorldService {
@Autowired
private ServiceProperties configuration;
public String getHelloMessage(String name) {
return this.configuration.getGreeting() + " " + name;
}
}

View File

@@ -0,0 +1,41 @@
/*
* Copyright 2012-2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.sample.integration;
import java.io.File;
import java.io.FileInputStream;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.integration.annotation.MessageEndpoint;
import org.springframework.integration.annotation.ServiceActivator;
import org.springframework.util.StreamUtils;
@MessageEndpoint
public class SampleEndpoint {
@Autowired
private HelloWorldService helloWorldService;
@ServiceActivator
public String hello(File input) throws Exception {
FileInputStream in = new FileInputStream(input);
String name = new String(StreamUtils.copyToByteArray(in));
in.close();
return this.helloWorldService.getHelloMessage(name);
}
}

View File

@@ -0,0 +1,37 @@
/*
* Copyright 2012-2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.sample.integration;
import org.springframework.boot.config.EnableAutoConfiguration;
import org.springframework.boot.strap.SpringApplication;
import org.springframework.boot.strap.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ImportResource;
@Configuration
@EnableAutoConfiguration
@EnableConfigurationProperties(ServiceProperties.class)
@ComponentScan
@ImportResource("integration-context.xml")
public class SampleIntegrationApplication {
public static void main(String[] args) throws Exception {
SpringApplication.run(SampleIntegrationApplication.class, args);
}
}

View File

@@ -0,0 +1,34 @@
/*
* Copyright 2012-2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.sample.integration;
import org.springframework.boot.strap.context.properties.ConfigurationProperties;
@ConfigurationProperties(name = "service", ignoreUnknownFields = false)
public class ServiceProperties {
private String greeting = "Hello";
public String getGreeting() {
return this.greeting;
}
public void setGreeting(String greeting) {
this.greeting = greeting;
}
}

View File

@@ -0,0 +1,2 @@
logging.file: /tmp/logs/app.log
service.greeting: Hello

View File

@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:int="http://www.springframework.org/schema/integration"
xmlns:int-file="http://www.springframework.org/schema/integration/file"
xsi:schemaLocation="http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd
http://www.springframework.org/schema/integration/file http://www.springframework.org/schema/integration/file/spring-integration-file.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<int-file:inbound-channel-adapter channel="input" directory="target/input" filename-pattern="*">
<int:poller fixed-rate="500"/>
</int-file:inbound-channel-adapter>
<int:service-activator input-channel="input" ref="sampleEndpoint" output-channel="output"/>
<int:channel id="output"/>
<int-file:outbound-channel-adapter channel="output" directory="target/output"/>
</beans>

View File

@@ -0,0 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<property name="LOG_PATTERN" value="[%d{yyyy-MM-dd HH:mm:ss.SSS}] - ${PID:-????} %5p [%t] --- %c{1}: %m%n"/>
<property name="LOG_FILE" value="${LOG_FILE:-${LOG_PATH:-/tmp/}spring.log}"/>
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>${LOG_PATTERN}</pattern>
</encoder>
</appender>
<appender name="FILE"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<encoder>
<pattern>${LOG_PATTERN}</pattern>
</encoder>
<file>${LOG_FILE}</file>
<rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
<fileNamePattern>${LOG_FILE}.%i</fileNamePattern>
</rollingPolicy>
<triggeringPolicy
class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
<MaxFileSize>10MB</MaxFileSize>
</triggeringPolicy>
</appender>
<logger name="org.springframework.integration.file" level="DEBUG" />
<root level="INFO">
<appender-ref ref="CONSOLE" />
<appender-ref ref="FILE" />
</root>
</configuration>

View File

@@ -0,0 +1,89 @@
/*
* Copyright 2012-2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.sample.integration.consumer;
import java.util.concurrent.Callable;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import org.springframework.boot.sample.integration.SampleIntegrationApplication;
import org.springframework.boot.sample.integration.producer.ProducerApplication;
import org.springframework.boot.strap.SpringApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.ResourcePatternUtils;
import org.springframework.util.StreamUtils;
import static org.junit.Assert.assertTrue;
/**
* Basic integration tests for service demo application.
*
* @author Dave Syer
*/
public class SampleIntegrationApplicationTests {
private static ConfigurableApplicationContext context;
@BeforeClass
public static void start() throws Exception {
context = (ConfigurableApplicationContext) SpringApplication
.run(SampleIntegrationApplication.class);
}
@AfterClass
public static void stop() {
if (context != null) {
context.close();
}
}
@Test
public void testVanillaExchange() throws Exception {
SpringApplication.run(ProducerApplication.class, "World");
String output = getOutput();
assertTrue("Wrong output: " + output, output.contains("Hello World"));
}
private String getOutput() throws Exception {
Future<String> future = Executors.newSingleThreadExecutor().submit(
new Callable<String>() {
@Override
public String call() throws Exception {
Resource[] resources = new Resource[0];
while (resources.length == 0) {
Thread.sleep(200);
resources = ResourcePatternUtils.getResourcePatternResolver(
new DefaultResourceLoader()).getResources(
"file:target/output/**");
}
StringBuilder builder = new StringBuilder();
for (Resource resource : resources) {
builder.append(new String(StreamUtils
.copyToByteArray(resource.getInputStream())));
}
return builder.toString();
}
});
return future.get(10, TimeUnit.SECONDS);
}
}

View File

@@ -0,0 +1,47 @@
/*
* Copyright 2012-2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.sample.integration.producer;
import java.io.File;
import java.io.FileOutputStream;
import org.springframework.boot.strap.CommandLineRunner;
import org.springframework.boot.strap.SpringApplication;
import org.springframework.context.annotation.Configuration;
@Configuration
public class ProducerApplication implements CommandLineRunner {
@Override
public void run(String... args) throws Exception {
new File("target/input").mkdirs();
if (args.length > 0) {
FileOutputStream stream = new FileOutputStream("target/input/data"
+ System.currentTimeMillis() + ".txt");
for (String arg : args) {
stream.write(arg.getBytes());
}
stream.flush();
stream.close();
}
}
public static void main(String[] args) throws Exception {
SpringApplication.run(ProducerApplication.class, args);
}
}

View File

@@ -0,0 +1,39 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-samples</artifactId>
<version>0.5.0.BUILD-SNAPSHOT</version>
</parent>
<artifactId>spring-boot-sample-jetty</artifactId>
<packaging>jar</packaging>
<properties>
<main.basedir>${basedir}/../..</main.basedir>
</properties>
<dependencies>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>spring-boot-up</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>spring-boot-up-jetty</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>${project.groupId}</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>

View File

@@ -0,0 +1,33 @@
/*
* Copyright 2012-2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.sample.jetty;
import org.springframework.boot.config.EnableAutoConfiguration;
import org.springframework.boot.strap.SpringApplication;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration
@EnableAutoConfiguration
@ComponentScan
public class SampleJettyApplication {
public static void main(String[] args) throws Exception {
SpringApplication.run(SampleJettyApplication.class, args);
}
}

View File

@@ -0,0 +1,32 @@
/*
* Copyright 2012-2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.sample.jetty.service;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component
public class HelloWorldService {
@Value("${name:World}")
private String name;
public String getHelloMessage() {
return "Hello " + this.name;
}
}

View File

@@ -0,0 +1,36 @@
/*
* Copyright 2012-2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.sample.jetty.web;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.sample.jetty.service.HelloWorldService;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class SampleController {
@Autowired
private HelloWorldService helloWorldService;
@RequestMapping("/")
@ResponseBody
public String helloWorld() {
return this.helloWorldService.getHelloMessage();
}
}

View File

@@ -0,0 +1,88 @@
/*
* Copyright 2012-2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.sample.jetty;
import java.io.IOException;
import java.util.concurrent.Callable;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import org.springframework.boot.sample.jetty.SampleJettyApplication;
import org.springframework.boot.strap.SpringApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.web.client.DefaultResponseErrorHandler;
import org.springframework.web.client.RestTemplate;
import static org.junit.Assert.assertEquals;
/**
* Basic integration tests for demo application.
*
* @author Dave Syer
*/
public class SampleJettyApplicationTests {
private static ConfigurableApplicationContext context;
@BeforeClass
public static void start() throws Exception {
Future<ConfigurableApplicationContext> future = Executors
.newSingleThreadExecutor().submit(
new Callable<ConfigurableApplicationContext>() {
@Override
public ConfigurableApplicationContext call() throws Exception {
return (ConfigurableApplicationContext) SpringApplication
.run(SampleJettyApplication.class);
}
});
context = future.get(10, TimeUnit.SECONDS);
}
@AfterClass
public static void stop() {
if (context != null) {
context.close();
}
}
@Test
public void testHome() throws Exception {
ResponseEntity<String> entity = getRestTemplate().getForEntity(
"http://localhost:8080", String.class);
assertEquals(HttpStatus.OK, entity.getStatusCode());
assertEquals("Hello World", entity.getBody());
}
private RestTemplate getRestTemplate() {
RestTemplate restTemplate = new RestTemplate();
restTemplate.setErrorHandler(new DefaultResponseErrorHandler() {
@Override
public void handleError(ClientHttpResponse response) throws IOException {
}
});
return restTemplate;
}
}

View File

@@ -0,0 +1,47 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-samples</artifactId>
<version>0.5.0.BUILD-SNAPSHOT</version>
</parent>
<artifactId>spring-boot-sample-ops-ui</artifactId>
<packaging>jar</packaging>
<properties>
<main.basedir>${basedir}/../..</main.basedir>
</properties>
<dependencies>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>spring-boot-up-ops</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>spring-boot-up-web</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
</dependency>
<dependency>
<groupId>org.thymeleaf</groupId>
<artifactId>thymeleaf-spring3</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>${project.groupId}</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>

View File

@@ -0,0 +1,54 @@
/*
* Copyright 2012-2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.sample.ops.ui;
import java.util.Date;
import java.util.Map;
import org.springframework.boot.config.EnableAutoConfiguration;
import org.springframework.boot.ops.properties.SecurityProperties;
import org.springframework.boot.strap.SpringApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@EnableAutoConfiguration
@ComponentScan
@Controller
public class SampleActuatorUiApplication {
@RequestMapping("/")
public String home(Map<String, Object> model) {
model.put("message", "Hello World");
model.put("title", "Hello Home");
model.put("date", new Date());
return "home";
}
public static void main(String[] args) throws Exception {
SpringApplication.run(SampleActuatorUiApplication.class, args);
}
@Bean
public SecurityProperties securityProperties() {
SecurityProperties security = new SecurityProperties();
security.getBasic().setPath(""); // empty
return security;
}
}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,31 @@
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>Error</title>
<link rel="stylesheet" th:href="@{/resources/css/bootstrap.min.css}"
href="../../resources/css/bootstrap.min.css" />
</head>
<body>
<div class="container">
<div class="navbar">
<div class="navbar-inner">
<a class="brand" href="http://www.thymeleaf.org"> Thymeleaf -
Plain </a>
<ul class="nav">
<li><a th:href="@{/}" href="home.html"> Home </a></li>
</ul>
</div>
</div>
<h1 th:text="${title}">Title</h1>
<div id="created" th:text="${#dates.format(timestamp)}">July 11,
2012 2:17:16 PM CDT</div>
<div>
There was an unexpected error (type=<span th:text="${error}">Bad</span>, status=<span th:text="${status}">500</span>).
</div>
<div th:text="${message}">Fake content</div>
<div>
Please contact the operator with the above information.
</div>
</div>
</body>
</html>

View File

@@ -0,0 +1,25 @@
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title th:text="${title}">Title</title>
<link rel="stylesheet" th:href="@{/resources/css/bootstrap.min.css}"
href="../../resources/css/bootstrap.min.css" />
</head>
<body>
<div class="container">
<div class="navbar">
<div class="navbar-inner">
<a class="brand" href="http://www.thymeleaf.org"> Thymeleaf -
Plain </a>
<ul class="nav">
<li><a th:href="@{/}" href="home.html"> Home </a></li>
</ul>
</div>
</div>
<h1 th:text="${title}">Title</h1>
<div th:text="${message}">Fake content</div>
<div id="created" th:text="${#dates.format(date)}">July 11,
2012 2:17:16 PM CDT</div>
</div>
</body>
</html>

View File

@@ -0,0 +1,113 @@
/*
* Copyright 2012-2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.sample.ops.ui;
import java.io.IOException;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Ignore;
import org.junit.Test;
import org.springframework.boot.sample.ops.ui.SampleActuatorUiApplication;
import org.springframework.boot.strap.SpringApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.web.client.DefaultResponseErrorHandler;
import org.springframework.web.client.RestTemplate;
import static org.junit.Assert.assertEquals;
/**
* Integration tests for separate management and main service ports.
*
* @author Dave Syer
*/
public class SampleActuatorUiApplicationPortTests {
private static ConfigurableApplicationContext context;
private static int port = 9010;
private static int managementPort = 9011;
@BeforeClass
public static void start() throws Exception {
final String[] args = new String[] { "--server.port=" + port,
"--management.port=" + managementPort, "--management.address=127.0.0.1" };
Future<ConfigurableApplicationContext> future = Executors
.newSingleThreadExecutor().submit(
new Callable<ConfigurableApplicationContext>() {
@Override
public ConfigurableApplicationContext call() throws Exception {
return (ConfigurableApplicationContext) SpringApplication
.run(SampleActuatorUiApplication.class, args);
}
});
context = future.get(10, TimeUnit.SECONDS);
}
@AfterClass
public static void stop() {
if (context != null) {
context.close();
}
}
@Test
public void testHome() throws Exception {
ResponseEntity<String> entity = getRestTemplate().getForEntity(
"http://localhost:" + port, String.class);
assertEquals(HttpStatus.OK, entity.getStatusCode());
}
@Test
@Ignore
public void testMetrics() throws Exception {
// FIXME broken since error page is not rendered
@SuppressWarnings("rawtypes")
ResponseEntity<Map> entity = getRestTemplate().getForEntity(
"http://localhost:" + managementPort + "/metrics", Map.class);
assertEquals(HttpStatus.UNAUTHORIZED, entity.getStatusCode());
}
@Test
public void testHealth() throws Exception {
ResponseEntity<String> entity = getRestTemplate().getForEntity(
"http://localhost:" + managementPort + "/health", String.class);
assertEquals(HttpStatus.OK, entity.getStatusCode());
assertEquals("ok", entity.getBody());
}
private RestTemplate getRestTemplate() {
RestTemplate restTemplate = new RestTemplate();
restTemplate.setErrorHandler(new DefaultResponseErrorHandler() {
@Override
public void handleError(ClientHttpResponse response) throws IOException {
}
});
return restTemplate;
}
}

View File

@@ -0,0 +1,129 @@
/*
* Copyright 2012-2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.sample.ops.ui;
import java.io.IOException;
import java.util.Arrays;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import org.springframework.boot.sample.ops.ui.SampleActuatorUiApplication;
import org.springframework.boot.strap.SpringApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.web.client.DefaultResponseErrorHandler;
import org.springframework.web.client.RestTemplate;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
/**
* Basic integration tests for demo application.
*
* @author Dave Syer
*/
public class SampleActuatorUiApplicationTests {
private static ConfigurableApplicationContext context;
@BeforeClass
public static void start() throws Exception {
Future<ConfigurableApplicationContext> future = Executors
.newSingleThreadExecutor().submit(
new Callable<ConfigurableApplicationContext>() {
@Override
public ConfigurableApplicationContext call() throws Exception {
return (ConfigurableApplicationContext) SpringApplication
.run(SampleActuatorUiApplication.class);
}
});
context = future.get(30, TimeUnit.SECONDS);
}
@AfterClass
public static void stop() {
if (context != null) {
context.close();
}
}
@Test
public void testHome() throws Exception {
HttpHeaders headers = new HttpHeaders();
headers.setAccept(Arrays.asList(MediaType.TEXT_HTML));
ResponseEntity<String> entity = getRestTemplate().exchange(
"http://localhost:8080", HttpMethod.GET, new HttpEntity<Void>(headers),
String.class);
assertEquals(HttpStatus.OK, entity.getStatusCode());
assertTrue("Wrong body (title doesn't match):\n" + entity.getBody(), entity
.getBody().contains("<title>Hello"));
}
@Test
public void testCss() throws Exception {
ResponseEntity<String> entity = getRestTemplate().getForEntity(
"http://localhost:8080/css/bootstrap.min.css", String.class);
assertEquals(HttpStatus.OK, entity.getStatusCode());
assertTrue("Wrong body:\n" + entity.getBody(), entity.getBody().contains("body"));
}
@Test
public void testMetrics() throws Exception {
@SuppressWarnings("rawtypes")
ResponseEntity<Map> entity = getRestTemplate().getForEntity(
"http://localhost:8080/metrics", Map.class);
assertEquals(HttpStatus.UNAUTHORIZED, entity.getStatusCode());
}
@Test
public void testError() throws Exception {
HttpHeaders headers = new HttpHeaders();
headers.setAccept(Arrays.asList(MediaType.TEXT_HTML));
ResponseEntity<String> entity = getRestTemplate().exchange(
"http://localhost:8080/error", HttpMethod.GET,
new HttpEntity<Void>(headers), String.class);
assertEquals(HttpStatus.OK, entity.getStatusCode());
assertTrue("Wrong body:\n" + entity.getBody(), entity.getBody()
.contains("<html>"));
assertTrue("Wrong body:\n" + entity.getBody(), entity.getBody()
.contains("<body>"));
}
private RestTemplate getRestTemplate() {
RestTemplate restTemplate = new RestTemplate();
restTemplate.setErrorHandler(new DefaultResponseErrorHandler() {
@Override
public void handleError(ClientHttpResponse response) throws IOException {
}
});
return restTemplate;
}
}

View File

@@ -0,0 +1,130 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-samples</artifactId>
<version>0.5.0.BUILD-SNAPSHOT</version>
</parent>
<artifactId>spring-boot-sample-ops</artifactId>
<packaging>jar</packaging>
<properties>
<main.basedir>${basedir}/../..</main.basedir>
</properties>
<dependencies>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>spring-boot-up-ops</artifactId>
<version>${project.version}</version>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-up-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>${project.groupId}</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>tomcat</id>
<activation>
<activeByDefault>false</activeByDefault>
</activation>
<dependencies>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-core</artifactId>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-logging-juli</artifactId>
</dependency>
</dependencies>
</profile>
<profile>
<id>jetty</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<dependencies>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-webapp</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-jsp</artifactId>
</dependency>
</dependencies>
</profile>
<profile>
<id>juli</id>
<activation>
<activeByDefault>false</activeByDefault>
</activation>
<dependencies>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-jdk14</artifactId>
</dependency>
</dependencies>
</profile>
<profile>
<id>log4j</id>
<activation>
<activeByDefault>false</activeByDefault>
</activation>
<dependencies>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
</dependency>
</dependencies>
</profile>
<profile>
<id>logback</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<dependencies>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
</dependency>
</dependencies>
</profile>
</profiles>
</project>

View File

@@ -0,0 +1,32 @@
/*
* Copyright 2012-2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.sample.ops;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class HelloWorldService {
@Autowired
private ServiceProperties configuration;
public String getHelloMessage() {
return "Hello " + this.configuration.getName();
}
}

View File

@@ -0,0 +1,35 @@
/*
* Copyright 2012-2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.sample.ops;
import org.springframework.boot.config.EnableAutoConfiguration;
import org.springframework.boot.strap.SpringApplication;
import org.springframework.boot.strap.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration
@EnableAutoConfiguration
@EnableConfigurationProperties
@ComponentScan
public class SampleActuatorApplication {
public static void main(String[] args) throws Exception {
SpringApplication.run(SampleActuatorApplication.class, args);
}
}

View File

@@ -0,0 +1,45 @@
/*
* Copyright 2012-2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.sample.ops;
import java.util.Collections;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class SampleController {
@Autowired
private HelloWorldService helloWorldService;
@RequestMapping("/")
@ResponseBody
public Map<String, String> helloWorld() {
return Collections.singletonMap("message",
this.helloWorldService.getHelloMessage());
}
@RequestMapping("/foo")
@ResponseBody
public String foo() {
throw new IllegalArgumentException("Server error");
}
}

View File

@@ -0,0 +1,36 @@
/*
* Copyright 2012-2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.sample.ops;
import org.springframework.boot.strap.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
@ConfigurationProperties(name = "service", ignoreUnknownFields = false)
@Component
public class ServiceProperties {
private String name = "World";
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
}

View File

@@ -0,0 +1,9 @@
logging.file: /tmp/logs/app.log
management.port: 8080
management.address: 127.0.0.1
management.allow_shutdown: true
server.port: 8080
server.tomcat.basedir: target/tomcat
server.tomcat.access_log_pattern: %h %t "%r" %s %b
security.require_ssl: false
service.name: Phil

View File

@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<property name="CONSOLE_LOG_PATTERN" value="%d{yyyy-MM-dd HH:mm:ss.SSS} %5p ${PID:- } [%t] --- %-40.40logger{39} : %m%n%wex"/>
<conversionRule conversionWord="wex" converterClass="org.springframework.boot.strap.logging.logback.WhitespaceThrowableProxyConverter" />
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>${CONSOLE_LOG_PATTERN}</pattern>
</encoder>
</appender>
<root level="INFO">
<appender-ref ref="CONSOLE" />
</root>
<!-- logger name="org.springframework" level="DEBUG"/ -->
</configuration>

View File

@@ -0,0 +1,128 @@
/*
* Copyright 2012-2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.sample.ops;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import org.junit.After;
import org.junit.Test;
import org.springframework.boot.sample.ops.SampleActuatorApplication;
import org.springframework.boot.strap.SpringApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.http.HttpRequest;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.http.client.ClientHttpRequestExecution;
import org.springframework.http.client.ClientHttpRequestInterceptor;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.http.client.InterceptingClientHttpRequestFactory;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.security.crypto.codec.Base64;
import org.springframework.web.client.DefaultResponseErrorHandler;
import org.springframework.web.client.RestTemplate;
import static org.junit.Assert.assertEquals;
/**
* Integration tests for endpoints configuration.
*
* @author Dave Syer
*/
public class EndpointsPropertiesSampleActuatorApplicationTests {
private ConfigurableApplicationContext context;
private void start(final Class<?> configuration, final String... args)
throws Exception {
Future<ConfigurableApplicationContext> future = Executors
.newSingleThreadExecutor().submit(
new Callable<ConfigurableApplicationContext>() {
@Override
public ConfigurableApplicationContext call() throws Exception {
return (ConfigurableApplicationContext) SpringApplication
.run(configuration, args);
}
});
this.context = future.get(10, TimeUnit.SECONDS);
}
@After
public void stop() {
if (this.context != null) {
this.context.close();
}
}
@Test
public void testCustomErrorPath() throws Exception {
start(SampleActuatorApplication.class, "--error.path=/oops");
testError();
}
private void testError() {
@SuppressWarnings("rawtypes")
ResponseEntity<Map> entity = getRestTemplate("user", "password").getForEntity(
"http://localhost:8080/oops", Map.class);
assertEquals(HttpStatus.OK, entity.getStatusCode());
@SuppressWarnings("unchecked")
Map<String, Object> body = entity.getBody();
assertEquals("None", body.get("error"));
assertEquals(999, body.get("status"));
}
private RestTemplate getRestTemplate(final String username, final String password) {
List<ClientHttpRequestInterceptor> interceptors = new ArrayList<ClientHttpRequestInterceptor>();
if (username != null) {
interceptors.add(new ClientHttpRequestInterceptor() {
@Override
public ClientHttpResponse intercept(HttpRequest request, byte[] body,
ClientHttpRequestExecution execution) throws IOException {
request.getHeaders().add(
"Authorization",
"Basic "
+ new String(Base64
.encode((username + ":" + password)
.getBytes())));
return execution.execute(request, body);
}
});
}
RestTemplate restTemplate = new RestTemplate(
new InterceptingClientHttpRequestFactory(
new SimpleClientHttpRequestFactory(), interceptors));
restTemplate.setErrorHandler(new DefaultResponseErrorHandler() {
@Override
public void handleError(ClientHttpResponse response) throws IOException {
}
});
return restTemplate;
}
}

View File

@@ -0,0 +1,167 @@
/*
* Copyright 2012-2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.sample.ops;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Ignore;
import org.junit.Test;
import org.springframework.boot.sample.ops.SampleActuatorApplication;
import org.springframework.boot.strap.SpringApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.http.HttpRequest;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.http.client.ClientHttpRequestExecution;
import org.springframework.http.client.ClientHttpRequestInterceptor;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.http.client.InterceptingClientHttpRequestFactory;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.security.crypto.codec.Base64;
import org.springframework.web.client.DefaultResponseErrorHandler;
import org.springframework.web.client.RestTemplate;
import static org.junit.Assert.assertEquals;
/**
* Integration tests for separate management and main service ports.
*
* @author Dave Syer
*/
public class ManagementAddressSampleActuatorApplicationTests {
private static ConfigurableApplicationContext context;
private static int port = 9010;
private static int managementPort = 9011;
@BeforeClass
public static void start() throws Exception {
final String[] args = new String[] { "--server.port=" + port,
"--management.port=" + managementPort };
Future<ConfigurableApplicationContext> future = Executors
.newSingleThreadExecutor().submit(
new Callable<ConfigurableApplicationContext>() {
@Override
public ConfigurableApplicationContext call() throws Exception {
return (ConfigurableApplicationContext) SpringApplication
.run(SampleActuatorApplication.class, args);
}
});
context = future.get(30, TimeUnit.SECONDS);
}
@AfterClass
public static void stop() {
if (context != null) {
context.close();
}
}
@Test
public void testHome() throws Exception {
@SuppressWarnings("rawtypes")
ResponseEntity<Map> entity = getRestTemplate("user", "password").getForEntity(
"http://localhost:" + port, Map.class);
assertEquals(HttpStatus.OK, entity.getStatusCode());
@SuppressWarnings("unchecked")
Map<String, Object> body = entity.getBody();
assertEquals("Hello Phil", body.get("message"));
}
@Test
@Ignore
public void testMetrics() throws Exception {
// FIXME broken because error page is no longer exposed on management port
testHome(); // makes sure some requests have been made
@SuppressWarnings("rawtypes")
ResponseEntity<Map> entity = getRestTemplate().getForEntity(
"http://localhost:" + managementPort + "/metrics", Map.class);
assertEquals(HttpStatus.UNAUTHORIZED, entity.getStatusCode());
}
@Test
@Ignore
public void testHealth() throws Exception {
// FIXME broken because error page is no longer exposed on management port
ResponseEntity<String> entity = getRestTemplate().getForEntity(
"http://localhost:" + managementPort + "/health", String.class);
assertEquals(HttpStatus.OK, entity.getStatusCode());
assertEquals("ok", entity.getBody());
}
@Test
@Ignore
public void testErrorPage() throws Exception {
// FIXME broken because error page is no longer exposed on management port
@SuppressWarnings("rawtypes")
ResponseEntity<Map> entity = getRestTemplate().getForEntity(
"http://localhost:" + managementPort + "/error", Map.class);
assertEquals(HttpStatus.OK, entity.getStatusCode());
@SuppressWarnings("unchecked")
Map<String, Object> body = entity.getBody();
assertEquals(999, body.get("status"));
}
private RestTemplate getRestTemplate() {
return getRestTemplate(null, null);
}
private RestTemplate getRestTemplate(final String username, final String password) {
List<ClientHttpRequestInterceptor> interceptors = new ArrayList<ClientHttpRequestInterceptor>();
if (username != null) {
interceptors.add(new ClientHttpRequestInterceptor() {
@Override
public ClientHttpResponse intercept(HttpRequest request, byte[] body,
ClientHttpRequestExecution execution) throws IOException {
request.getHeaders().add(
"Authorization",
"Basic "
+ new String(Base64
.encode((username + ":" + password)
.getBytes())));
return execution.execute(request, body);
}
});
}
RestTemplate restTemplate = new RestTemplate(
new InterceptingClientHttpRequestFactory(
new SimpleClientHttpRequestFactory(), interceptors));
restTemplate.setErrorHandler(new DefaultResponseErrorHandler() {
@Override
public void handleError(ClientHttpResponse response) throws IOException {
}
});
return restTemplate;
}
}

View File

@@ -0,0 +1,103 @@
/*
* Copyright 2012-2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.sample.ops;
import java.io.IOException;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import org.springframework.boot.sample.ops.SampleActuatorApplication;
import org.springframework.boot.strap.SpringApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.web.client.DefaultResponseErrorHandler;
import org.springframework.web.client.RestTemplate;
import static org.junit.Assert.assertEquals;
/**
* Integration tests for separate management and main service ports.
*
* @author Dave Syer
*/
public class ManagementSampleActuatorApplicationTests {
private static ConfigurableApplicationContext context;
private static int port = 9010;
private static int managementPort = 9011;
@BeforeClass
public static void start() throws Exception {
final String[] args = new String[] { "--server.port=" + port,
"--management.port=" + managementPort, "--management.address=127.0.0.1" };
Future<ConfigurableApplicationContext> future = Executors
.newSingleThreadExecutor().submit(
new Callable<ConfigurableApplicationContext>() {
@Override
public ConfigurableApplicationContext call() throws Exception {
return (ConfigurableApplicationContext) SpringApplication
.run(SampleActuatorApplication.class, args);
}
});
context = future.get(30, TimeUnit.SECONDS);
}
@AfterClass
public static void stop() {
if (context != null) {
context.close();
}
}
@Test
public void testHome() throws Exception {
@SuppressWarnings("rawtypes")
ResponseEntity<Map> entity = getRestTemplate().getForEntity(
"http://localhost:" + port, Map.class);
assertEquals(HttpStatus.UNAUTHORIZED, entity.getStatusCode());
}
@Test
public void testHealth() throws Exception {
ResponseEntity<String> entity = getRestTemplate().getForEntity(
"http://localhost:" + managementPort + "/health", String.class);
assertEquals(HttpStatus.OK, entity.getStatusCode());
assertEquals("ok", entity.getBody());
}
private RestTemplate getRestTemplate() {
RestTemplate restTemplate = new RestTemplate();
restTemplate.setErrorHandler(new DefaultResponseErrorHandler() {
@Override
public void handleError(ClientHttpResponse response) throws IOException {
}
});
return restTemplate;
}
}

View File

@@ -0,0 +1,136 @@
/*
* Copyright 2012-2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.sample.ops;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import org.springframework.boot.sample.ops.SampleActuatorApplication;
import org.springframework.boot.strap.SpringApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.http.HttpRequest;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.http.client.ClientHttpRequestExecution;
import org.springframework.http.client.ClientHttpRequestInterceptor;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.http.client.InterceptingClientHttpRequestFactory;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.security.crypto.codec.Base64;
import org.springframework.web.client.DefaultResponseErrorHandler;
import org.springframework.web.client.ResourceAccessException;
import org.springframework.web.client.RestTemplate;
import static org.junit.Assert.assertEquals;
/**
* Integration tests for switching off management endpoints.
*
* @author Dave Syer
*/
public class NoManagementSampleActuatorApplicationTests {
private static ConfigurableApplicationContext context;
private static int managementPort = 0;
@BeforeClass
public static void start() throws Exception {
final String[] args = new String[] { "--management.port=" + managementPort };
Future<ConfigurableApplicationContext> future = Executors
.newSingleThreadExecutor().submit(
new Callable<ConfigurableApplicationContext>() {
@Override
public ConfigurableApplicationContext call() throws Exception {
return (ConfigurableApplicationContext) SpringApplication
.run(SampleActuatorApplication.class, args);
}
});
context = future.get(10, TimeUnit.SECONDS);
}
@AfterClass
public static void stop() {
if (context != null) {
context.close();
}
}
@Test
public void testHome() throws Exception {
@SuppressWarnings("rawtypes")
ResponseEntity<Map> entity = getRestTemplate("user", "password").getForEntity(
"http://localhost:8080", Map.class);
assertEquals(HttpStatus.OK, entity.getStatusCode());
@SuppressWarnings("unchecked")
Map<String, Object> body = entity.getBody();
assertEquals("Hello Phil", body.get("message"));
}
@Test(expected = ResourceAccessException.class)
public void testMetricsNotAvailable() throws Exception {
testHome(); // makes sure some requests have been made
@SuppressWarnings("rawtypes")
ResponseEntity<Map> entity = getRestTemplate("user", "password").getForEntity(
"http://localhost:" + managementPort + "/metrics", Map.class);
assertEquals(HttpStatus.NOT_FOUND, entity.getStatusCode());
}
private RestTemplate getRestTemplate(final String username, final String password) {
List<ClientHttpRequestInterceptor> interceptors = new ArrayList<ClientHttpRequestInterceptor>();
if (username != null) {
interceptors.add(new ClientHttpRequestInterceptor() {
@Override
public ClientHttpResponse intercept(HttpRequest request, byte[] body,
ClientHttpRequestExecution execution) throws IOException {
request.getHeaders().add(
"Authorization",
"Basic "
+ new String(Base64
.encode((username + ":" + password)
.getBytes())));
return execution.execute(request, body);
}
});
}
RestTemplate restTemplate = new RestTemplate(
new InterceptingClientHttpRequestFactory(
new SimpleClientHttpRequestFactory(), interceptors));
restTemplate.setErrorHandler(new DefaultResponseErrorHandler() {
@Override
public void handleError(ClientHttpResponse response) throws IOException {
}
});
return restTemplate;
}
}

View File

@@ -0,0 +1,208 @@
/*
* Copyright 2012-2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.sample.ops;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import org.springframework.boot.sample.ops.SampleActuatorApplication;
import org.springframework.boot.strap.SpringApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.http.HttpRequest;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.http.client.ClientHttpRequestExecution;
import org.springframework.http.client.ClientHttpRequestInterceptor;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.http.client.InterceptingClientHttpRequestFactory;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.security.crypto.codec.Base64;
import org.springframework.web.client.DefaultResponseErrorHandler;
import org.springframework.web.client.RestTemplate;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
/**
* Basic integration tests for service demo application.
*
* @author Dave Syer
*/
public class SampleActuatorApplicationTests {
private static ConfigurableApplicationContext context;
@BeforeClass
public static void start() throws Exception {
Future<ConfigurableApplicationContext> future = Executors
.newSingleThreadExecutor().submit(
new Callable<ConfigurableApplicationContext>() {
@Override
public ConfigurableApplicationContext call() throws Exception {
return (ConfigurableApplicationContext) SpringApplication
.run(SampleActuatorApplication.class);
}
});
context = future.get(30, TimeUnit.SECONDS);
}
@AfterClass
public static void stop() {
if (context != null) {
context.close();
}
}
@Test
public void testHomeIsSecure() throws Exception {
@SuppressWarnings("rawtypes")
ResponseEntity<Map> entity = getRestTemplate().getForEntity(
"http://localhost:8080", Map.class);
assertEquals(HttpStatus.UNAUTHORIZED, entity.getStatusCode());
@SuppressWarnings("unchecked")
Map<String, Object> body = entity.getBody();
assertEquals("Wrong body: " + body, "Unauthorized", body.get("error"));
assertFalse(entity.getHeaders().containsKey("Set-Cookie"));
}
@Test
public void testHome() throws Exception {
@SuppressWarnings("rawtypes")
ResponseEntity<Map> entity = getRestTemplate("user", "password").getForEntity(
"http://localhost:8080", Map.class);
assertEquals(HttpStatus.OK, entity.getStatusCode());
@SuppressWarnings("unchecked")
Map<String, Object> body = entity.getBody();
assertEquals("Hello Phil", body.get("message"));
}
@Test
public void testMetrics() throws Exception {
testHome(); // makes sure some requests have been made
@SuppressWarnings("rawtypes")
ResponseEntity<Map> entity = getRestTemplate("user", "password").getForEntity(
"http://localhost:8080/metrics", Map.class);
assertEquals(HttpStatus.OK, entity.getStatusCode());
@SuppressWarnings("unchecked")
Map<String, Object> body = entity.getBody();
assertTrue("Wrong body: " + body, body.containsKey("counter.status.200.root"));
}
@Test
public void testEnv() throws Exception {
@SuppressWarnings("rawtypes")
ResponseEntity<Map> entity = getRestTemplate("user", "password").getForEntity(
"http://localhost:8080/env", Map.class);
assertEquals(HttpStatus.OK, entity.getStatusCode());
@SuppressWarnings("unchecked")
Map<String, Object> body = entity.getBody();
assertTrue("Wrong body: " + body, body.containsKey("systemProperties"));
}
@Test
public void testHealth() throws Exception {
ResponseEntity<String> entity = getRestTemplate().getForEntity(
"http://localhost:8080/health", String.class);
assertEquals(HttpStatus.OK, entity.getStatusCode());
assertEquals("ok", entity.getBody());
}
@Test
public void testErrorPage() throws Exception {
@SuppressWarnings("rawtypes")
ResponseEntity<Map> entity = getRestTemplate("user", "password").getForEntity(
"http://localhost:8080/foo", Map.class);
assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, entity.getStatusCode());
@SuppressWarnings("unchecked")
Map<String, Object> body = entity.getBody();
assertEquals(500, body.get("status"));
}
@Test
public void testErrorPageDirectAccess() throws Exception {
@SuppressWarnings("rawtypes")
ResponseEntity<Map> entity = getRestTemplate().getForEntity(
"http://localhost:8080/error", Map.class);
assertEquals(HttpStatus.OK, entity.getStatusCode());
@SuppressWarnings("unchecked")
Map<String, Object> body = entity.getBody();
assertEquals("None", body.get("error"));
assertEquals(999, body.get("status"));
}
@Test
public void testBeans() throws Exception {
@SuppressWarnings("rawtypes")
ResponseEntity<List> entity = getRestTemplate("user", "password").getForEntity(
"http://localhost:8080/beans", List.class);
assertEquals(HttpStatus.OK, entity.getStatusCode());
assertEquals(1, entity.getBody().size());
@SuppressWarnings("unchecked")
Map<String, Object> body = (Map<String, Object>) entity.getBody().get(0);
assertTrue("Wrong body: " + body,
((String) body.get("context")).startsWith("application"));
}
private RestTemplate getRestTemplate() {
return getRestTemplate(null, null);
}
private RestTemplate getRestTemplate(final String username, final String password) {
List<ClientHttpRequestInterceptor> interceptors = new ArrayList<ClientHttpRequestInterceptor>();
if (username != null) {
interceptors.add(new ClientHttpRequestInterceptor() {
@Override
public ClientHttpResponse intercept(HttpRequest request, byte[] body,
ClientHttpRequestExecution execution) throws IOException {
request.getHeaders().add(
"Authorization",
"Basic "
+ new String(Base64
.encode((username + ":" + password)
.getBytes())));
return execution.execute(request, body);
}
});
}
RestTemplate restTemplate = new RestTemplate(
new InterceptingClientHttpRequestFactory(
new SimpleClientHttpRequestFactory(), interceptors));
restTemplate.setErrorHandler(new DefaultResponseErrorHandler() {
@Override
public void handleError(ClientHttpResponse response) throws IOException {
}
});
return restTemplate;
}
}

View File

@@ -0,0 +1,136 @@
/*
* Copyright 2012-2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.sample.ops;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import org.springframework.boot.sample.ops.SampleActuatorApplication;
import org.springframework.boot.strap.SpringApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.http.HttpRequest;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.http.client.ClientHttpRequestExecution;
import org.springframework.http.client.ClientHttpRequestInterceptor;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.http.client.InterceptingClientHttpRequestFactory;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.security.crypto.codec.Base64;
import org.springframework.web.client.DefaultResponseErrorHandler;
import org.springframework.web.client.RestTemplate;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
/**
* Integration tests for separate management and main service ports.
*
* @author Dave Syer
*/
public class ShutdownSampleActuatorApplicationTests {
private static ConfigurableApplicationContext context;
@BeforeClass
public static void start() throws Exception {
Future<ConfigurableApplicationContext> future = Executors
.newSingleThreadExecutor().submit(
new Callable<ConfigurableApplicationContext>() {
@Override
public ConfigurableApplicationContext call() throws Exception {
return (ConfigurableApplicationContext) SpringApplication
.run(SampleActuatorApplication.class);
}
});
context = future.get(10, TimeUnit.SECONDS);
}
@AfterClass
public static void stop() {
if (context != null) {
context.close();
}
}
@Test
public void testHome() throws Exception {
@SuppressWarnings("rawtypes")
ResponseEntity<Map> entity = getRestTemplate("user", "password").getForEntity(
"http://localhost:8080", Map.class);
assertEquals(HttpStatus.OK, entity.getStatusCode());
@SuppressWarnings("unchecked")
Map<String, Object> body = entity.getBody();
assertEquals("Hello Phil", body.get("message"));
}
@Test
public void testShutdown() throws Exception {
@SuppressWarnings("rawtypes")
ResponseEntity<Map> entity = getRestTemplate("user", "password").postForEntity(
"http://localhost:8080/shutdown", null, Map.class);
assertEquals(HttpStatus.OK, entity.getStatusCode());
@SuppressWarnings("unchecked")
Map<String, Object> body = entity.getBody();
assertTrue("Wrong body: " + body,
((String) body.get("message")).contains("Shutting down"));
}
private RestTemplate getRestTemplate(final String username, final String password) {
List<ClientHttpRequestInterceptor> interceptors = new ArrayList<ClientHttpRequestInterceptor>();
if (username != null) {
interceptors.add(new ClientHttpRequestInterceptor() {
@Override
public ClientHttpResponse intercept(HttpRequest request, byte[] body,
ClientHttpRequestExecution execution) throws IOException {
request.getHeaders().add(
"Authorization",
"Basic "
+ new String(Base64
.encode((username + ":" + password)
.getBytes())));
return execution.execute(request, body);
}
});
}
RestTemplate restTemplate = new RestTemplate(
new InterceptingClientHttpRequestFactory(
new SimpleClientHttpRequestFactory(), interceptors));
restTemplate.setErrorHandler(new DefaultResponseErrorHandler() {
@Override
public void handleError(ClientHttpResponse response) throws IOException {
}
});
return restTemplate;
}
}

View File

@@ -0,0 +1,96 @@
/*
* Copyright 2012-2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.sample.ops;
import java.io.IOException;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import org.springframework.boot.sample.ops.SampleActuatorApplication;
import org.springframework.boot.strap.SpringApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.web.client.DefaultResponseErrorHandler;
import org.springframework.web.client.RestTemplate;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
/**
* Integration tests for unsecured service endpoints (even with Spring Security on
* classpath).
*
* @author Dave Syer
*/
public class UnsecureSampleActuatorApplicationTests {
private static ConfigurableApplicationContext context;
@BeforeClass
public static void start() throws Exception {
Future<ConfigurableApplicationContext> future = Executors
.newSingleThreadExecutor().submit(
new Callable<ConfigurableApplicationContext>() {
@Override
public ConfigurableApplicationContext call() throws Exception {
return (ConfigurableApplicationContext) SpringApplication
.run(SampleActuatorApplication.class,
"--security.basic.enabled=false");
}
});
context = future.get(10, TimeUnit.SECONDS);
}
@AfterClass
public static void stop() {
if (context != null) {
context.close();
}
}
@Test
public void testHome() throws Exception {
@SuppressWarnings("rawtypes")
ResponseEntity<Map> entity = getRestTemplate().getForEntity(
"http://localhost:8080", Map.class);
assertEquals(HttpStatus.OK, entity.getStatusCode());
@SuppressWarnings("unchecked")
Map<String, Object> body = entity.getBody();
assertEquals("Hello Phil", body.get("message"));
assertFalse(entity.getHeaders().containsKey("Set-Cookie"));
}
private RestTemplate getRestTemplate() {
RestTemplate restTemplate = new RestTemplate();
restTemplate.setErrorHandler(new DefaultResponseErrorHandler() {
@Override
public void handleError(ClientHttpResponse response) throws IOException {
}
});
return restTemplate;
}
}

View File

@@ -0,0 +1,5 @@
@Grab("org.springframework.boot:spring-boot-up-ops:0.5.0.BUILD-SNAPSHOT")
@Grab("org.springframework.boot:spring-boot-up-web:0.5.0.BUILD-SNAPSHOT")
@ComponentScan("org.springframework.boot.sample.service")
class Start {
}

View File

@@ -0,0 +1,35 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-samples</artifactId>
<version>0.5.0.BUILD-SNAPSHOT</version>
</parent>
<artifactId>spring-boot-sample-profile</artifactId>
<packaging>jar</packaging>
<properties>
<main.basedir>${basedir}/../..</main.basedir>
</properties>
<dependencies>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>spring-boot-up</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.yaml</groupId>
<artifactId>snakeyaml</artifactId>
<scope>runtime</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>${project.groupId}</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>

View File

@@ -0,0 +1,47 @@
/*
* Copyright 2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.sample.profile;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.config.EnableAutoConfiguration;
import org.springframework.boot.sample.profile.service.MessageService;
import org.springframework.boot.strap.CommandLineRunner;
import org.springframework.boot.strap.SpringApplication;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration
@EnableAutoConfiguration
@ComponentScan
public class SampleProfileApplication implements CommandLineRunner {
// Simple example shows how a command line spring application can execute an
// injected bean service. Also demonstrates how you can use @Value to inject
// command line args ('--name=whatever') or application properties
@Autowired
private MessageService helloWorldService;
@Override
public void run(String... args) {
System.out.println(this.helloWorldService.getMessage());
}
public static void main(String[] args) throws Exception {
SpringApplication.run(SampleProfileApplication.class, args);
}
}

View File

@@ -0,0 +1,35 @@
/*
* Copyright 2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.sample.profile.service;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Profile;
import org.springframework.stereotype.Component;
@Component
@Profile("goodbye")
public class GoodbyeWorldService implements MessageService {
@Value("${name:World}")
private String name;
@Override
public String getMessage() {
return "Goodbye " + this.name;
}
}

View File

@@ -0,0 +1,35 @@
/*
* Copyright 2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.sample.profile.service;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Profile;
import org.springframework.stereotype.Component;
@Component
@Profile({ "hello", "default" })
public class HelloWorldService implements MessageService {
@Value("${name:World}")
private String name;
@Override
public String getMessage() {
return "Hello " + this.name;
}
}

View File

@@ -0,0 +1,26 @@
/*
* Copyright 2012-2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.sample.profile.service;
/**
* @author Dave Syer
*/
public interface MessageService {
String getMessage();
}

View File

@@ -0,0 +1,7 @@
name: Phil
---
spring:
profiles: goodbye,dev
name: Everyone

View File

@@ -0,0 +1,91 @@
/*
* Copyright 2012-2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.sample.profile;
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.springframework.boot.sample.profile.SampleProfileApplication;
import static org.junit.Assert.assertTrue;
public class SampleProfileApplicationTests {
private static PrintStream savedOutput;
private static ByteArrayOutputStream output;
private String profiles;
@BeforeClass
public static void init() {
savedOutput = System.out;
output = new ByteArrayOutputStream();
System.setOut(new PrintStream(output));
}
@Before
public void before() {
this.profiles = System.getProperty("spring.profiles.active");
}
@After
public void after() {
if (this.profiles != null) {
System.setProperty("spring.profiles.active", this.profiles);
}
else {
System.clearProperty("spring.profiles.active");
}
}
@AfterClass
public static void clear() {
System.setOut(savedOutput);
}
private static String getOutput() {
return output.toString();
}
@Test
public void testDefaultProfile() throws Exception {
SampleProfileApplication.main(new String[0]);
String output = getOutput();
assertTrue("Wrong output: " + output, output.contains("Hello Phil"));
}
@Test
public void testGoodbyeProfile() throws Exception {
System.setProperty("spring.profiles.active", "goodbye");
SampleProfileApplication.main(new String[0]);
String output = getOutput();
assertTrue("Wrong output: " + output, output.contains("Goodbye Everyone"));
}
@Test
public void testGoodbyeProfileFromCommandline() throws Exception {
SampleProfileApplication
.main(new String[] { "--spring.profiles.active=goodbye" });
String output = getOutput();
assertTrue("Wrong output: " + output, output.contains("Goodbye Everyone"));
}
}

View File

@@ -0,0 +1,30 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-samples</artifactId>
<version>0.5.0.BUILD-SNAPSHOT</version>
</parent>
<artifactId>spring-boot-sample-simple</artifactId>
<packaging>jar</packaging>
<properties>
<main.basedir>${basedir}/../..</main.basedir>
</properties>
<dependencies>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>spring-boot-up</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>${project.groupId}</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>

View File

@@ -0,0 +1,47 @@
/*
* Copyright 2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.sample.simple;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.config.EnableAutoConfiguration;
import org.springframework.boot.sample.simple.service.HelloWorldService;
import org.springframework.boot.strap.CommandLineRunner;
import org.springframework.boot.strap.SpringApplication;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration
@EnableAutoConfiguration
@ComponentScan
public class SampleSimpleApplication implements CommandLineRunner {
// Simple example shows how a command line spring application can execute an
// injected bean service. Also demonstrates how you can use @Value to inject
// command line args ('--name=whatever') or application properties
@Autowired
private HelloWorldService helloWorldService;
@Override
public void run(String... args) {
System.out.println(this.helloWorldService.getHelloMessage());
}
public static void main(String[] args) throws Exception {
SpringApplication.run(SampleSimpleApplication.class, args);
}
}

View File

@@ -0,0 +1,32 @@
/*
* Copyright 2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.sample.simple.service;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component
public class HelloWorldService {
@Value("${name:World}")
private String name;
public String getHelloMessage() {
return "Hello " + this.name;
}
}

View File

@@ -0,0 +1,80 @@
/*
* Copyright 2012-2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.sample.simple;
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.springframework.boot.sample.simple.SampleSimpleApplication;
import static org.junit.Assert.assertTrue;
/**
* Tests for {@link SampleSimpleApplication}.
*
* @author Dave Syer
* @author Phillip Webb
*/
public class SampleSimpleApplicationTests {
private PrintStream savedOutput;
private ByteArrayOutputStream output;
private String profiles;
@Before
public void init() {
this.savedOutput = System.out;
this.output = new ByteArrayOutputStream();
System.setOut(new PrintStream(this.output));
this.profiles = System.getProperty("spring.profiles.active");
}
@After
public void after() {
if (this.profiles != null) {
System.setProperty("spring.profiles.active", this.profiles);
}
else {
System.clearProperty("spring.profiles.active");
}
System.setOut(this.savedOutput);
}
private String getOutput() {
return this.output.toString();
}
@Test
public void testDefaultSettings() throws Exception {
SampleSimpleApplication.main(new String[0]);
String output = getOutput();
assertTrue("Wrong output: " + output, output.contains("Hello Phil"));
}
@Test
public void testCommandLineOverrides() throws Exception {
SampleSimpleApplication.main(new String[] { "--name=Gordon" });
String output = getOutput();
assertTrue("Wrong output: " + output, output.contains("Hello Gordon"));
}
}

View File

@@ -0,0 +1,39 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-samples</artifactId>
<version>0.5.0.BUILD-SNAPSHOT</version>
</parent>
<artifactId>spring-boot-sample-tomcat</artifactId>
<packaging>jar</packaging>
<properties>
<main.basedir>${basedir}/../..</main.basedir>
</properties>
<dependencies>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>spring-boot-up</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>spring-boot-up-tomcat</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>${project.groupId}</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>

View File

@@ -0,0 +1,33 @@
/*
* Copyright 2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.sample.tomcat;
import org.springframework.boot.config.EnableAutoConfiguration;
import org.springframework.boot.strap.SpringApplication;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration
@EnableAutoConfiguration
@ComponentScan
public class SampleTomcatApplication {
public static void main(String[] args) throws Exception {
SpringApplication.run(SampleTomcatApplication.class, args);
}
}

View File

@@ -0,0 +1,32 @@
/*
* Copyright 2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.sample.tomcat.service;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component
public class HelloWorldService {
@Value("${name:World}")
private String name;
public String getHelloMessage() {
return "Hello " + this.name;
}
}

View File

@@ -0,0 +1,36 @@
/*
* Copyright 2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.sample.tomcat.web;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.sample.tomcat.service.HelloWorldService;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class SampleController {
@Autowired
private HelloWorldService helloWorldService;
@RequestMapping("/")
@ResponseBody
public String helloWorld() {
return this.helloWorldService.getHelloMessage();
}
}

View File

@@ -0,0 +1,108 @@
/*
* Copyright 2012-2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.sample.tomcat;
import java.io.IOException;
import java.util.concurrent.Callable;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import org.springframework.boot.config.PropertyPlaceholderAutoConfiguration;
import org.springframework.boot.config.web.EmbeddedServletContainerAutoConfiguration;
import org.springframework.boot.config.web.WebMvcAutoConfiguration;
import org.springframework.boot.sample.tomcat.SampleTomcatApplication;
import org.springframework.boot.sample.tomcat.service.HelloWorldService;
import org.springframework.boot.sample.tomcat.web.SampleController;
import org.springframework.boot.strap.SpringApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.web.client.DefaultResponseErrorHandler;
import org.springframework.web.client.RestTemplate;
import static org.junit.Assert.assertEquals;
/**
* Basic integration tests for demo application.
*
* @author Dave Syer
*/
public class NonAutoConfigurationSampleTomcatApplicationTests {
private static ConfigurableApplicationContext context;
@Configuration
@Import({ EmbeddedServletContainerAutoConfiguration.class,
WebMvcAutoConfiguration.class, PropertyPlaceholderAutoConfiguration.class })
@ComponentScan(basePackageClasses = { SampleController.class, HelloWorldService.class })
public static class NonAutoConfigurationSampleTomcatApplication {
public static void main(String[] args) throws Exception {
SpringApplication.run(SampleTomcatApplication.class, args);
}
}
@BeforeClass
public static void start() throws Exception {
Future<ConfigurableApplicationContext> future = Executors
.newSingleThreadExecutor().submit(
new Callable<ConfigurableApplicationContext>() {
@Override
public ConfigurableApplicationContext call() throws Exception {
return (ConfigurableApplicationContext) SpringApplication
.run(NonAutoConfigurationSampleTomcatApplication.class);
}
});
context = future.get(10, TimeUnit.SECONDS);
}
@AfterClass
public static void stop() {
if (context != null) {
context.close();
}
}
@Test
public void testHome() throws Exception {
ResponseEntity<String> entity = getRestTemplate().getForEntity(
"http://localhost:8080", String.class);
assertEquals(HttpStatus.OK, entity.getStatusCode());
assertEquals("Hello World", entity.getBody());
}
private RestTemplate getRestTemplate() {
RestTemplate restTemplate = new RestTemplate();
restTemplate.setErrorHandler(new DefaultResponseErrorHandler() {
@Override
public void handleError(ClientHttpResponse response) throws IOException {
}
});
return restTemplate;
}
}

View File

@@ -0,0 +1,88 @@
/*
* Copyright 2012-2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.sample.tomcat;
import java.io.IOException;
import java.util.concurrent.Callable;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import org.springframework.boot.sample.tomcat.SampleTomcatApplication;
import org.springframework.boot.strap.SpringApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.web.client.DefaultResponseErrorHandler;
import org.springframework.web.client.RestTemplate;
import static org.junit.Assert.assertEquals;
/**
* Basic integration tests for demo application.
*
* @author Dave Syer
*/
public class SampleTomcatApplicationTests {
private static ConfigurableApplicationContext context;
@BeforeClass
public static void start() throws Exception {
Future<ConfigurableApplicationContext> future = Executors
.newSingleThreadExecutor().submit(
new Callable<ConfigurableApplicationContext>() {
@Override
public ConfigurableApplicationContext call() throws Exception {
return (ConfigurableApplicationContext) SpringApplication
.run(SampleTomcatApplication.class);
}
});
context = future.get(10, TimeUnit.SECONDS);
}
@AfterClass
public static void stop() {
if (context != null) {
context.close();
}
}
@Test
public void testHome() throws Exception {
ResponseEntity<String> entity = getRestTemplate().getForEntity(
"http://localhost:8080", String.class);
assertEquals(HttpStatus.OK, entity.getStatusCode());
assertEquals("Hello World", entity.getBody());
}
private RestTemplate getRestTemplate() {
RestTemplate restTemplate = new RestTemplate();
restTemplate.setErrorHandler(new DefaultResponseErrorHandler() {
@Override
public void handleError(ClientHttpResponse response) throws IOException {
}
});
return restTemplate;
}
}

View File

@@ -0,0 +1 @@
/target

View File

@@ -0,0 +1,47 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-samples</artifactId>
<version>0.5.0.BUILD-SNAPSHOT</version>
</parent>
<artifactId>spring-boot-sample-traditional</artifactId>
<packaging>war</packaging>
<properties>
<main.basedir>${basedir}/../..</main.basedir>
<m2eclipse.wtp.contextRoot>/</m2eclipse.wtp.contextRoot>
</properties>
<dependencies>
<!-- Compile -->
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>spring-boot-up</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
</dependency>
<!-- Provided (for embedded war support) -->
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>spring-boot-up-tomcat</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>${project.groupId}</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>

View File

@@ -0,0 +1,33 @@
/*
* Copyright 2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.sample.traditional;
import org.springframework.boot.config.EnableAutoConfiguration;
import org.springframework.boot.strap.SpringApplication;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration
@EnableAutoConfiguration
@ComponentScan
public class SampleTraditionalApplication {
public static void main(String[] args) throws Exception {
SpringApplication.run(SampleTraditionalApplication.class, args);
}
}

View File

@@ -0,0 +1,56 @@
/*
* Copyright 2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.sample.traditional.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.DispatcherServlet;
import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
@EnableWebMvc
@ComponentScan
@Configuration
public class WebConfig extends WebMvcConfigurerAdapter {
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/").setViewName("home");
}
@Bean
public InternalResourceViewResolver viewResolver() {
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
viewResolver.setPrefix("/WEB-INF/views/");
viewResolver.setSuffix(".jsp");
return viewResolver;
}
@Bean
public DispatcherServlet dispatcherServlet() {
return new DispatcherServlet();
}
@Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
}

View File

@@ -0,0 +1,7 @@
log4j.rootCategory=INFO, stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - <%m>%n
log4j.category.org.springframework.web=DEBUG

View File

@@ -0,0 +1,11 @@
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Home</title>
</head>
<body>
<h1>Home</h1>
</body>
</html>

View File

@@ -0,0 +1,31 @@
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<servlet>
<servlet-name>appServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextClass</param-name>
<param-value>org.springframework.web.context.support.AnnotationConfigWebApplicationContext</param-value>
</init-param>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>org.springframework.issues.config</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>appServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<!-- Disables Servlet Container welcome file handling. Needed for compatibility
with Servlet 3.0 and Tomcat 7.0 -->
<welcome-file-list>
<welcome-file></welcome-file>
</welcome-file-list>
</web-app>

View File

@@ -0,0 +1,6 @@
<html>
<body>
<h1>Hello</h1>
Hello World!
</body>
</html>

View File

@@ -0,0 +1,101 @@
/*
* Copyright 2012-2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.sample.traditional;
import java.io.IOException;
import java.util.concurrent.Callable;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import org.springframework.boot.sample.traditional.SampleTraditionalApplication;
import org.springframework.boot.strap.SpringApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.web.client.DefaultResponseErrorHandler;
import org.springframework.web.client.RestTemplate;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
/**
* Basic integration tests for demo application.
*
* @author Dave Syer
*/
public class SampleTraditionalApplicationTests {
private static ConfigurableApplicationContext context;
@BeforeClass
public static void start() throws Exception {
Future<ConfigurableApplicationContext> future = Executors
.newSingleThreadExecutor().submit(
new Callable<ConfigurableApplicationContext>() {
@Override
public ConfigurableApplicationContext call() throws Exception {
return (ConfigurableApplicationContext) SpringApplication
.run(SampleTraditionalApplication.class);
}
});
context = future.get(30, TimeUnit.SECONDS);
}
@AfterClass
public static void stop() {
if (context != null) {
context.close();
}
}
@Test
public void testHomeJsp() throws Exception {
ResponseEntity<String> entity = getRestTemplate().getForEntity(
"http://localhost:8080", String.class);
assertEquals(HttpStatus.OK, entity.getStatusCode());
String body = entity.getBody();
assertTrue("Wrong body:\n" + body, body.contains("<html>"));
assertTrue("Wrong body:\n" + body, body.contains("<h1>Home</h1>"));
}
@Test
public void testStaticPage() throws Exception {
ResponseEntity<String> entity = getRestTemplate().getForEntity(
"http://localhost:8080/index.html", String.class);
assertEquals(HttpStatus.OK, entity.getStatusCode());
String body = entity.getBody();
assertTrue("Wrong body:\n" + body, body.contains("<html>"));
assertTrue("Wrong body:\n" + body, body.contains("<h1>Hello</h1>"));
}
private RestTemplate getRestTemplate() {
RestTemplate restTemplate = new RestTemplate();
restTemplate.setErrorHandler(new DefaultResponseErrorHandler() {
@Override
public void handleError(ClientHttpResponse response) throws IOException {
}
});
return restTemplate;
}
}

View File

@@ -0,0 +1,7 @@
log4j.rootCategory=INFO, stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - <%m>%n
log4j.category.org.springframework.web=DEBUG

View File

@@ -0,0 +1,42 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-samples</artifactId>
<version>0.5.0.BUILD-SNAPSHOT</version>
</parent>
<artifactId>spring-boot-sample-web-ui</artifactId>
<packaging>jar</packaging>
<properties>
<main.basedir>${basedir}/../..</main.basedir>
</properties>
<dependencies>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>spring-boot-up-web</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.thymeleaf</groupId>
<artifactId>thymeleaf-spring3</artifactId>
</dependency>
<dependency>
<groupId>nz.net.ultraq.thymeleaf</groupId>
<artifactId>thymeleaf-layout-dialect</artifactId>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>${project.groupId}</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>

View File

@@ -0,0 +1,52 @@
/*
* Copyright 2012-2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.sample.ui;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.atomic.AtomicLong;
/**
* @author Dave Syer
*/
public class InMemoryMessageRespository implements MessageRepository {
private static AtomicLong counter = new AtomicLong();
private ConcurrentMap<Long, Message> messages = new ConcurrentHashMap<Long, Message>();
@Override
public Iterable<Message> findAll() {
return this.messages.values();
}
@Override
public Message save(Message message) {
Long id = message.getId();
if (id == null) {
id = counter.incrementAndGet();
message.setId(id);
}
this.messages.put(id, message);
return message;
}
@Override
public Message findMessage(Long id) {
return this.messages.get(id);
}
}

View File

@@ -0,0 +1,66 @@
/*
* Copyright 2012 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*/
package org.springframework.boot.sample.ui;
import java.util.Calendar;
import org.hibernate.validator.constraints.NotEmpty;
/**
* @author Rob Winch
*/
public class Message {
private Long id;
@NotEmpty(message = "Message is required.")
private String text;
@NotEmpty(message = "Summary is required.")
private String summary;
private Calendar created = Calendar.getInstance();
public Long getId() {
return this.id;
}
public void setId(Long id) {
this.id = id;
}
public Calendar getCreated() {
return this.created;
}
public void setCreated(Calendar created) {
this.created = created;
}
public String getText() {
return this.text;
}
public void setText(String text) {
this.text = text;
}
public String getSummary() {
return this.summary;
}
public void setSummary(String summary) {
this.summary = summary;
}
}

View File

@@ -0,0 +1,27 @@
/*
* Copyright 2012 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*/
package org.springframework.boot.sample.ui;
/**
* @author Rob Winch
*/
public interface MessageRepository {
Iterable<Message> findAll();
Message save(Message message);
Message findMessage(Long id);
}

View File

@@ -0,0 +1,50 @@
/*
* Copyright 2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.sample.ui;
import org.springframework.boot.config.EnableAutoConfiguration;
import org.springframework.boot.strap.SpringApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.convert.converter.Converter;
@Configuration
@EnableAutoConfiguration
@ComponentScan
public class SampleWebUiApplication {
@Bean
public MessageRepository messageRepository() {
return new InMemoryMessageRespository();
}
@Bean
public Converter<String, Message> messageConverter() {
return new Converter<String, Message>() {
@Override
public Message convert(String id) {
return messageRepository().findMessage(Long.valueOf(id));
}
};
}
public static void main(String[] args) throws Exception {
SpringApplication.run(SampleWebUiApplication.class, args);
}
}

View File

@@ -0,0 +1,69 @@
/*
* Copyright 2012 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*/
package org.springframework.boot.sample.ui.mvc;
import javax.validation.Valid;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.sample.ui.Message;
import org.springframework.boot.sample.ui.MessageRepository;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
/**
* @author Rob Winch
*/
@Controller
@RequestMapping("/")
public class MessageController {
private MessageRepository messageRepository;
@Autowired
public MessageController(MessageRepository messageRepository) {
this.messageRepository = messageRepository;
}
@RequestMapping
public ModelAndView list() {
Iterable<Message> messages = this.messageRepository.findAll();
return new ModelAndView("messages/list", "messages", messages);
}
@RequestMapping("{id}")
public ModelAndView view(@PathVariable("id") Message message) {
return new ModelAndView("messages/view", "message", message);
}
@RequestMapping(params = "form", method = RequestMethod.GET)
public String createForm(@ModelAttribute Message message) {
return "messages/form";
}
@RequestMapping(method = RequestMethod.POST)
public ModelAndView create(@Valid Message message, BindingResult result,
RedirectAttributes redirect) {
if (result.hasErrors()) {
return new ModelAndView("messages/form", "formErrors", result.getAllErrors());
}
message = this.messageRepository.save(message);
redirect.addFlashAttribute("globalMessage", "Successfully created a new message");
return new ModelAndView("redirect:/{message.id}", "message.id", message.getId());
}
}

Some files were not shown because too many files have changed in this diff Show More