From 40ee80de277881a2d5884e39b01de1a5dc18497e Mon Sep 17 00:00:00 2001 From: Tushar Mane Date: Thu, 22 Feb 2018 10:52:01 -0800 Subject: [PATCH 01/13] dummy checkin --- ci/migrateDatabase.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/ci/migrateDatabase.yml b/ci/migrateDatabase.yml index b2af8c5ef..551ca12de 100644 --- a/ci/migrateDatabase.yml +++ b/ci/migrateDatabase.yml @@ -9,6 +9,7 @@ image_resource: inputs: - name: pal-tracker # - name: version +# - git:test #outputs: # - name: build-output From 6e7f2e8efe93016ba6849cfa6b2a5dc142c10f3a Mon Sep 17 00:00:00 2001 From: Tushar Mane Date: Thu, 22 Feb 2018 11:02:40 -0800 Subject: [PATCH 02/13] test --- ci/migrateDatabase.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci/migrateDatabase.yml b/ci/migrateDatabase.yml index 551ca12de..9f1fdace2 100644 --- a/ci/migrateDatabase.yml +++ b/ci/migrateDatabase.yml @@ -9,7 +9,7 @@ image_resource: inputs: - name: pal-tracker # - name: version -# - git:test + #outputs: # - name: build-output From a654eac3f6bc8baa2ba21f67b02289f579070c4d Mon Sep 17 00:00:00 2001 From: Tyson Gern Date: Wed, 26 Jul 2017 11:45:04 -0600 Subject: [PATCH 03/13] Add tests for JDBC lab --- .../tracker/JdbcTimeEntryRepositoryTest.java | 159 ++++++++++++++++++ 1 file changed, 159 insertions(+) create mode 100644 src/test/java/test/pivotal/pal/tracker/JdbcTimeEntryRepositoryTest.java diff --git a/src/test/java/test/pivotal/pal/tracker/JdbcTimeEntryRepositoryTest.java b/src/test/java/test/pivotal/pal/tracker/JdbcTimeEntryRepositoryTest.java new file mode 100644 index 000000000..e1eac20fc --- /dev/null +++ b/src/test/java/test/pivotal/pal/tracker/JdbcTimeEntryRepositoryTest.java @@ -0,0 +1,159 @@ +package test.pivotal.pal.tracker; + + +import com.mysql.cj.jdbc.MysqlDataSource; +import io.pivotal.pal.tracker.JdbcTimeEntryRepository; +import io.pivotal.pal.tracker.TimeEntry; +import io.pivotal.pal.tracker.TimeEntryRepository; +import org.junit.Before; +import org.junit.Test; +import org.springframework.jdbc.core.JdbcTemplate; + +import java.sql.Date; +import java.time.LocalDate; +import java.util.List; +import java.util.Map; +import java.util.TimeZone; + +import static org.assertj.core.api.Assertions.assertThat; + +public class JdbcTimeEntryRepositoryTest { + private TimeEntryRepository subject; + private JdbcTemplate jdbcTemplate; + + @Before + public void setUp() throws Exception { + MysqlDataSource dataSource = new MysqlDataSource(); + dataSource.setUrl(System.getenv("SPRING_DATASOURCE_URL")); + + subject = new JdbcTimeEntryRepository(dataSource); + + jdbcTemplate = new JdbcTemplate(dataSource); + jdbcTemplate.execute("DELETE FROM time_entries"); + + TimeZone.setDefault(TimeZone.getTimeZone("UTC")); + } + + @Test + public void createInsertsATimeEntryRecord() throws Exception { + TimeEntry newTimeEntry = new TimeEntry(123, 321, LocalDate.parse("2017-01-09"), 8); + TimeEntry entry = subject.create(newTimeEntry); + + Map foundEntry = jdbcTemplate.queryForMap("Select * from time_entries where id = ?", entry.getId()); + + assertThat(foundEntry.get("id")).isEqualTo(entry.getId()); + assertThat(foundEntry.get("project_id")).isEqualTo(123L); + assertThat(foundEntry.get("user_id")).isEqualTo(321L); + assertThat(((Date)foundEntry.get("date")).toLocalDate()).isEqualTo(LocalDate.parse("2017-01-09")); + assertThat(foundEntry.get("hours")).isEqualTo(8); + } + + @Test + public void createReturnsTheCreatedTimeEntry() throws Exception { + TimeEntry newTimeEntry = new TimeEntry(123, 321, LocalDate.parse("2017-01-09"), 8); + TimeEntry entry = subject.create(newTimeEntry); + + assertThat(entry.getId()).isNotNull(); + assertThat(entry.getProjectId()).isEqualTo(123); + assertThat(entry.getUserId()).isEqualTo(321); + assertThat(entry.getDate()).isEqualTo(LocalDate.parse("2017-01-09")); + assertThat(entry.getHours()).isEqualTo(8); + } + + @Test + public void findFindsATimeEntry() throws Exception { + jdbcTemplate.execute( + "INSERT INTO time_entries (id, project_id, user_id, date, hours) " + + "VALUES (999, 123, 321, '2017-01-09', 8)" + ); + + TimeEntry timeEntry = subject.find(999L); + + assertThat(timeEntry.getId()).isEqualTo(999L); + assertThat(timeEntry.getProjectId()).isEqualTo(123L); + assertThat(timeEntry.getUserId()).isEqualTo(321L); + assertThat(timeEntry.getDate()).isEqualTo(LocalDate.parse("2017-01-09")); + assertThat(timeEntry.getHours()).isEqualTo(8); + } + + @Test + public void findReturnsNullWhenNotFound() throws Exception { + TimeEntry timeEntry = subject.find(999L); + + assertThat(timeEntry).isNull(); + } + + @Test + public void listFindsAllTimeEntries() throws Exception { + jdbcTemplate.execute( + "INSERT INTO time_entries (id, project_id, user_id, date, hours) " + + "VALUES (999, 123, 321, '2017-01-09', 8), (888, 456, 678, '2017-01-08', 9)" + ); + + List timeEntries = subject.list(); + assertThat(timeEntries.size()).isEqualTo(2); + + TimeEntry timeEntry = timeEntries.get(0); + assertThat(timeEntry.getId()).isEqualTo(888L); + assertThat(timeEntry.getProjectId()).isEqualTo(456L); + assertThat(timeEntry.getUserId()).isEqualTo(678L); + assertThat(timeEntry.getDate()).isEqualTo(LocalDate.parse("2017-01-08")); + assertThat(timeEntry.getHours()).isEqualTo(9); + + timeEntry = timeEntries.get(1); + assertThat(timeEntry.getId()).isEqualTo(999L); + assertThat(timeEntry.getProjectId()).isEqualTo(123L); + assertThat(timeEntry.getUserId()).isEqualTo(321L); + assertThat(timeEntry.getDate()).isEqualTo(LocalDate.parse("2017-01-09")); + assertThat(timeEntry.getHours()).isEqualTo(8); + } + + @Test + public void updateReturnsTheUpdatedRecord() throws Exception { + jdbcTemplate.execute( + "INSERT INTO time_entries (id, project_id, user_id, date, hours) " + + "VALUES (1000, 123, 321, '2017-01-09', 8)"); + + TimeEntry timeEntryUpdates = new TimeEntry(456, 987, LocalDate.parse("2017-01-10"), 10); + + TimeEntry updatedTimeEntry = subject.update(1000L, timeEntryUpdates); + + assertThat(updatedTimeEntry.getId()).isEqualTo(1000L); + assertThat(updatedTimeEntry.getProjectId()).isEqualTo(456L); + assertThat(updatedTimeEntry.getUserId()).isEqualTo(987L); + assertThat(updatedTimeEntry.getDate()).isEqualTo(LocalDate.parse("2017-01-10")); + assertThat(updatedTimeEntry.getHours()).isEqualTo(10); + } + + @Test + public void updateUpdatesTheRecord() throws Exception { + jdbcTemplate.execute( + "INSERT INTO time_entries (id, project_id, user_id, date, hours) " + + "VALUES (1000, 123, 321, '2017-01-09', 8)"); + + TimeEntry updatedTimeEntry = new TimeEntry(456, 322, LocalDate.parse("2017-01-10"), 10); + + TimeEntry timeEntry = subject.update(1000L, updatedTimeEntry); + + Map foundEntry = jdbcTemplate.queryForMap("Select * from time_entries where id = ?", timeEntry.getId()); + + assertThat(foundEntry.get("id")).isEqualTo(timeEntry.getId()); + assertThat(foundEntry.get("project_id")).isEqualTo(456L); + assertThat(foundEntry.get("user_id")).isEqualTo(322L); + assertThat(((Date)foundEntry.get("date")).toLocalDate()).isEqualTo(LocalDate.parse("2017-01-10")); + assertThat(foundEntry.get("hours")).isEqualTo(10); + } + + @Test + public void deleteRemovesTheRecord() throws Exception { + jdbcTemplate.execute( + "INSERT INTO time_entries (id, project_id, user_id, date, hours) " + + "VALUES (999, 123, 321, '2017-01-09', 8)" + ); + + subject.delete(999L); + + Map foundEntry = jdbcTemplate.queryForMap("Select count(*) count from time_entries where id = ?", 999); + assertThat(foundEntry.get("count")).isEqualTo(0L); + } +} From 3040769186b9512d1059dbde4778818027d2f631 Mon Sep 17 00:00:00 2001 From: Tushar Mane Date: Thu, 22 Feb 2018 13:45:36 -0800 Subject: [PATCH 04/13] jdbc repo details added --- build.gradle | 30 ++++++- .../tracker/InMemoryTimeEntryRepository.java | 13 ++- .../pal/tracker/JdbcTimeEntryRepository.java | 88 +++++++++++++++++++ .../pal/tracker/PalTrackerApplication.java | 12 ++- .../pal/tracker/TimeEntryRepository.java | 17 ++-- .../pal/trackerapi/TimeEntryApiTest.java | 17 +++- 6 files changed, 148 insertions(+), 29 deletions(-) create mode 100644 src/main/java/io/pivotal/pal/tracker/JdbcTimeEntryRepository.java diff --git a/build.gradle b/build.gradle index fdc6a55b7..4563f9acc 100644 --- a/build.gradle +++ b/build.gradle @@ -1,6 +1,9 @@ +import org.flywaydb.gradle.task.FlywayMigrateTask + plugins { - id 'java' - id 'org.springframework.boot' version '1.5.10.RELEASE' + id "java" + id "org.springframework.boot" version "1.5.4.RELEASE" + id "org.flywaydb.flyway" version "4.2.0" } repositories { @@ -9,14 +12,33 @@ repositories { dependencies { compile("org.springframework.boot:spring-boot-starter-web") - testCompile("org.springframework.boot:spring-boot-starter-test") compile("com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.9.1") + compile("org.springframework.boot:spring-boot-starter-jdbc") + + compile("mysql:mysql-connector-java:6.0.6") + + testCompile("org.springframework.boot:spring-boot-starter-test") } +def developmentDbUrl = "jdbc:mysql://localhost:3306/tracker_dev?user=tracker&useSSL=false&useTimezone=true&serverTimezone=UTC&useLegacyDatetimeCode=false" bootRun.environment([ "WELCOME_MESSAGE": "hello", + "SPRING_DATASOURCE_URL": developmentDbUrl, ]) +def testDbUrl = "jdbc:mysql://localhost:3306/tracker_test?user=tracker&useSSL=false&useTimezone=true&serverTimezone=UTC&useLegacyDatetimeCode=false" test.environment([ "WELCOME_MESSAGE": "Hello from test", -]) \ No newline at end of file + "SPRING_DATASOURCE_URL": testDbUrl, +]) + +flyway { + url = developmentDbUrl + user = "tracker" + password = "" + locations = ["filesystem:databases/tracker/migrations"] +} + +task testMigrate(type: FlywayMigrateTask) { + url = testDbUrl +} \ No newline at end of file diff --git a/src/main/java/io/pivotal/pal/tracker/InMemoryTimeEntryRepository.java b/src/main/java/io/pivotal/pal/tracker/InMemoryTimeEntryRepository.java index 72db871dc..07785c3e0 100644 --- a/src/main/java/io/pivotal/pal/tracker/InMemoryTimeEntryRepository.java +++ b/src/main/java/io/pivotal/pal/tracker/InMemoryTimeEntryRepository.java @@ -5,7 +5,6 @@ import java.util.List; public class InMemoryTimeEntryRepository implements TimeEntryRepository { - private HashMap timeEntries = new HashMap<>(); @Override @@ -16,24 +15,24 @@ public TimeEntry create(TimeEntry timeEntry) { } @Override - public TimeEntry find(long id) { + public TimeEntry find(Long id) { return timeEntries.get(id); } @Override public List list() { - return new ArrayList(timeEntries.values()); + return new ArrayList<>(timeEntries.values()); } @Override - public TimeEntry update(long id, TimeEntry timeEntry) { - timeEntry.setId(id); + public TimeEntry update(Long id, TimeEntry timeEntry) { timeEntries.replace(id, timeEntry); + timeEntry.setId(id); return timeEntry; } @Override - public void delete(long id) { + public void delete(Long id) { timeEntries.remove(id); } -} +} \ No newline at end of file diff --git a/src/main/java/io/pivotal/pal/tracker/JdbcTimeEntryRepository.java b/src/main/java/io/pivotal/pal/tracker/JdbcTimeEntryRepository.java new file mode 100644 index 000000000..72173dd4f --- /dev/null +++ b/src/main/java/io/pivotal/pal/tracker/JdbcTimeEntryRepository.java @@ -0,0 +1,88 @@ +package io.pivotal.pal.tracker; + +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.core.ResultSetExtractor; +import org.springframework.jdbc.core.RowMapper; +import org.springframework.jdbc.support.GeneratedKeyHolder; +import org.springframework.jdbc.support.KeyHolder; + +import javax.sql.DataSource; +import java.sql.Date; +import java.sql.PreparedStatement; +import java.util.List; + +import static java.sql.Statement.RETURN_GENERATED_KEYS; + +public class JdbcTimeEntryRepository implements TimeEntryRepository { + + private final JdbcTemplate jdbcTemplate; + + public JdbcTimeEntryRepository(DataSource dataSource) { + this.jdbcTemplate = new JdbcTemplate(dataSource); + } + + @Override + public TimeEntry create(TimeEntry timeEntry) { + KeyHolder generatedKeyHolder = new GeneratedKeyHolder(); + + jdbcTemplate.update(connection -> { + PreparedStatement statement = connection.prepareStatement( + "INSERT INTO time_entries (project_id, user_id, date, hours) " + + "VALUES (?, ?, ?, ?)", + RETURN_GENERATED_KEYS + ); + + statement.setLong(1, timeEntry.getProjectId()); + statement.setLong(2, timeEntry.getUserId()); + statement.setDate(3, Date.valueOf(timeEntry.getDate())); + statement.setInt(4, timeEntry.getHours()); + + return statement; + }, generatedKeyHolder); + + return find(generatedKeyHolder.getKey().longValue()); + } + + @Override + public TimeEntry find(Long id) { + return jdbcTemplate.query( + "SELECT id, project_id, user_id, date, hours FROM time_entries WHERE id = ?", + new Object[]{id}, + extractor); + } + + @Override + public List list() { + return jdbcTemplate.query("SELECT id, project_id, user_id, date, hours FROM time_entries", mapper); + } + + @Override + public TimeEntry update(Long id, TimeEntry timeEntry) { + jdbcTemplate.update("UPDATE time_entries " + + "SET project_id = ?, user_id = ?, date = ?, hours = ? " + + "WHERE id = ?", + timeEntry.getProjectId(), + timeEntry.getUserId(), + Date.valueOf(timeEntry.getDate()), + timeEntry.getHours(), + id); + + return find(id); + } + + @Override + public void delete(Long id) { + jdbcTemplate.update("DELETE FROM time_entries WHERE id = ?", id); + } + + private final RowMapper mapper = (rs, rowNum) -> new TimeEntry( + rs.getLong("id"), + rs.getLong("project_id"), + rs.getLong("user_id"), + rs.getDate("date").toLocalDate(), + rs.getInt("hours") + ); + + private final ResultSetExtractor extractor = + (rs) -> rs.next() ? mapper.mapRow(rs, 1) : null; +} diff --git a/src/main/java/io/pivotal/pal/tracker/PalTrackerApplication.java b/src/main/java/io/pivotal/pal/tracker/PalTrackerApplication.java index 3cd26e2a5..22884d4f4 100644 --- a/src/main/java/io/pivotal/pal/tracker/PalTrackerApplication.java +++ b/src/main/java/io/pivotal/pal/tracker/PalTrackerApplication.java @@ -9,16 +9,21 @@ import org.springframework.context.annotation.Bean; import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder; +import javax.sql.DataSource; +import java.util.TimeZone; + @SpringBootApplication public class PalTrackerApplication { public static void main(String[] args) { + // Make sure the application runs as UTC + TimeZone.setDefault(TimeZone.getTimeZone("UTC")); SpringApplication.run(PalTrackerApplication.class, args); } @Bean - TimeEntryRepository timeEntryRepository() { - return new InMemoryTimeEntryRepository(); + TimeEntryRepository timeEntryRepository(DataSource dataSource) { + return new JdbcTimeEntryRepository(dataSource); } @Bean @@ -29,5 +34,4 @@ public ObjectMapper jsonObjectMapper() { .modules(new JavaTimeModule()) .build(); } - -} +} \ No newline at end of file diff --git a/src/main/java/io/pivotal/pal/tracker/TimeEntryRepository.java b/src/main/java/io/pivotal/pal/tracker/TimeEntryRepository.java index c2ff55d14..866097db4 100644 --- a/src/main/java/io/pivotal/pal/tracker/TimeEntryRepository.java +++ b/src/main/java/io/pivotal/pal/tracker/TimeEntryRepository.java @@ -1,18 +1,11 @@ package io.pivotal.pal.tracker; -import org.springframework.http.ResponseEntity; - import java.util.List; public interface TimeEntryRepository { - - TimeEntry create(TimeEntry any); - - TimeEntry find(long l); - + TimeEntry create(TimeEntry timeEntry); + TimeEntry find(Long id); List list(); - - TimeEntry update(long eq, TimeEntry any); - - void delete(long l); -} + TimeEntry update(Long id, TimeEntry timeEntry); + void delete(Long id); +} \ No newline at end of file diff --git a/src/test/java/test/pivotal/pal/trackerapi/TimeEntryApiTest.java b/src/test/java/test/pivotal/pal/trackerapi/TimeEntryApiTest.java index 91e271b45..df213a69d 100644 --- a/src/test/java/test/pivotal/pal/trackerapi/TimeEntryApiTest.java +++ b/src/test/java/test/pivotal/pal/trackerapi/TimeEntryApiTest.java @@ -1,8 +1,9 @@ package test.pivotal.pal.trackerapi; - import com.jayway.jsonpath.DocumentContext; +import com.mysql.cj.jdbc.MysqlDataSource; import io.pivotal.pal.tracker.PalTrackerApplication; import io.pivotal.pal.tracker.TimeEntry; +import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; @@ -12,15 +13,16 @@ import org.springframework.http.HttpMethod; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; +import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.test.context.junit4.SpringRunner; import java.time.LocalDate; import java.util.Collection; +import java.util.TimeZone; import static com.jayway.jsonpath.JsonPath.parse; import static org.assertj.core.api.Assertions.assertThat; import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; - @RunWith(SpringRunner.class) @SpringBootTest(classes = PalTrackerApplication.class, webEnvironment = RANDOM_PORT) public class TimeEntryApiTest { @@ -30,6 +32,17 @@ public class TimeEntryApiTest { private TimeEntry timeEntry = new TimeEntry(123L, 456L, LocalDate.parse("2017-01-08"), 8); + @Before + public void setUp() throws Exception { + MysqlDataSource dataSource = new MysqlDataSource(); + dataSource.setUrl(System.getenv("SPRING_DATASOURCE_URL")); + + JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource); + jdbcTemplate.execute("TRUNCATE time_entries"); + + TimeZone.setDefault(TimeZone.getTimeZone("UTC")); + } + @Test public void testCreate() throws Exception { ResponseEntity createResponse = restTemplate.postForEntity("/time-entries", timeEntry, String.class); From 080d7c48144c4929de4de7a9a4ba8593250ae37a Mon Sep 17 00:00:00 2001 From: Tushar Mane Date: Thu, 22 Feb 2018 13:53:53 -0800 Subject: [PATCH 05/13] added tracker database details --- ci/build.yml | 16 ++++++++++++++-- manifest-production.yml | 4 +++- manifest-review.yml | 4 +++- 3 files changed, 20 insertions(+), 4 deletions(-) diff --git a/ci/build.yml b/ci/build.yml index 4ba28db53..17f9f5974 100644 --- a/ci/build.yml +++ b/ci/build.yml @@ -16,9 +16,21 @@ outputs: run: path: bash args: + args: - -exc - | + + export DEBIAN_FRONTEND="noninteractive" + + apt-get update + + apt-get -y install mysql-server + service mysql start + cd pal-tracker + mysql -uroot < databases/tracker/create_databases.sql chmod +x gradlew - ./gradlew -P version=$(cat ../version/number) build - cp build/libs/pal-tracker-*.jar ../build-output + ./gradlew -P version=$(cat ../version/number) testMigrate clean build || (service mysql stop && exit 1) + service mysql stop + + cp build/libs/pal-tracker-*.jar ../build-output \ No newline at end of file diff --git a/manifest-production.yml b/manifest-production.yml index 340b53421..ca505eaea 100644 --- a/manifest-production.yml +++ b/manifest-production.yml @@ -2,4 +2,6 @@ applications: - name: pal-tracker path: build/libs/pal-tracker.jar - host: ps-pal-tracker \ No newline at end of file + host: ps-pal-tracker + services: + - tracker-database \ No newline at end of file diff --git a/manifest-review.yml b/manifest-review.yml index cd3361d30..897eba97d 100644 --- a/manifest-review.yml +++ b/manifest-review.yml @@ -2,4 +2,6 @@ applications: - name: pal-tracker path: build/libs/pal-tracker.jar - host: ps-pal-tracker-review \ No newline at end of file + host: ps-pal-tracker-review + services: + - tracker-database \ No newline at end of file From 52177828801bfb4c3c5bd2349aac8a3cbec35a63 Mon Sep 17 00:00:00 2001 From: Tushar Mane Date: Thu, 22 Feb 2018 14:02:53 -0800 Subject: [PATCH 06/13] pipeline details --- ci/pipeline.yml | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/ci/pipeline.yml b/ci/pipeline.yml index c34c3b2a9..06b53a452 100644 --- a/ci/pipeline.yml +++ b/ci/pipeline.yml @@ -60,9 +60,22 @@ jobs: - name: deploy-review plan: - get: pal-tracker + passed: [build] - get: pal-tracker-artifacts trigger: true passed: [build] + - task: migrate database + file: pal-tracker/ci/migrateDatabase.yml + params: + CF_API_URL: {{cf-api-url}} + CF_USERNAME: {{cf-username}} + CF_PASSWORD: {{cf-password}} + CF_ORG: {{cf-org}} + CF_SPACE: review + MYSQL_IP: {{mysql-ip}} + DATABASE_NAME: {{review-database-name}} + DATABASE_USERNAME: {{review-database-username}} + DATABASE_PASSWORD: {{review-database-password}} - put: review-deployment params: manifest: pal-tracker/manifest-review.yml @@ -73,11 +86,24 @@ jobs: - name: deploy-production plan: - get: pal-tracker + passed: [deploy-review] - get: pal-tracker-artifacts passed: [deploy-review] + - task: migrate database + file: pal-tracker/ci/migrateDatabase.yml + params: + CF_API_URL: {{cf-api-url}} + CF_USERNAME: {{cf-username}} + CF_PASSWORD: {{cf-password}} + CF_ORG: {{cf-org}} + CF_SPACE: production + MYSQL_IP: {{mysql-ip}} + DATABASE_NAME: {{production-database-name}} + DATABASE_USERNAME: {{production-database-username}} + DATABASE_PASSWORD: {{production-database-password}} - put: production-deployment params: manifest: pal-tracker/manifest-production.yml path: pal-tracker-artifacts/pal-tracker-*.jar environment_variables: - WELCOME_MESSAGE: "Hello from the production environment" \ No newline at end of file +WELCOME_MESSAGE: "Hello from the production environment" \ No newline at end of file From 8794346aca0576d2c6fb819c0f067c90fb6d2eb3 Mon Sep 17 00:00:00 2001 From: Tyson Gern Date: Wed, 26 Jul 2017 11:45:04 -0600 Subject: [PATCH 07/13] adding databases folder --- ci/build.yml | 6 ------ databases/tracker/create_databases.sql | 11 +++++++++++ databases/tracker/migrations/V1__initial.schema.sql | 11 +++++++++++ 3 files changed, 22 insertions(+), 6 deletions(-) create mode 100644 databases/tracker/create_databases.sql create mode 100644 databases/tracker/migrations/V1__initial.schema.sql diff --git a/ci/build.yml b/ci/build.yml index 17f9f5974..9f5a19a41 100644 --- a/ci/build.yml +++ b/ci/build.yml @@ -16,21 +16,15 @@ outputs: run: path: bash args: - args: - -exc - | - export DEBIAN_FRONTEND="noninteractive" - apt-get update - apt-get -y install mysql-server service mysql start - cd pal-tracker mysql -uroot < databases/tracker/create_databases.sql chmod +x gradlew ./gradlew -P version=$(cat ../version/number) testMigrate clean build || (service mysql stop && exit 1) service mysql stop - cp build/libs/pal-tracker-*.jar ../build-output \ No newline at end of file diff --git a/databases/tracker/create_databases.sql b/databases/tracker/create_databases.sql new file mode 100644 index 000000000..8b5ed7ba5 --- /dev/null +++ b/databases/tracker/create_databases.sql @@ -0,0 +1,11 @@ +DROP DATABASE IF EXISTS tracker_dev; +DROP DATABASE IF EXISTS tracker_test; + +CREATE DATABASE tracker_dev; +CREATE DATABASE tracker_test; + +CREATE USER IF NOT EXISTS 'tracker'@'localhost' + IDENTIFIED BY ''; +GRANT ALL PRIVILEGES ON tracker_dev.* TO 'tracker' @'localhost'; +GRANT ALL PRIVILEGES ON tracker_test.* TO 'tracker' @'localhost'; + diff --git a/databases/tracker/migrations/V1__initial.schema.sql b/databases/tracker/migrations/V1__initial.schema.sql new file mode 100644 index 000000000..d529ac1b1 --- /dev/null +++ b/databases/tracker/migrations/V1__initial.schema.sql @@ -0,0 +1,11 @@ +CREATE TABLE time_entries ( + id BIGINT(20) NOT NULL AUTO_INCREMENT, + project_id BIGINT(20), + user_id BIGINT(20), + date DATE, + hours INT, + + PRIMARY KEY (id) +) + ENGINE = innodb +DEFAULT CHARSET = utf8; From b455c6285d44d18dd9eb5febbc28ee14f0ba71ae Mon Sep 17 00:00:00 2001 From: Tyson Gern Date: Wed, 26 Jul 2017 12:28:32 -0600 Subject: [PATCH 08/13] Add tests for Actuator lab --- .../pivotal/pal/trackerapi/HealthApiTest.java | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 src/test/java/test/pivotal/pal/trackerapi/HealthApiTest.java diff --git a/src/test/java/test/pivotal/pal/trackerapi/HealthApiTest.java b/src/test/java/test/pivotal/pal/trackerapi/HealthApiTest.java new file mode 100644 index 000000000..b3eef23cc --- /dev/null +++ b/src/test/java/test/pivotal/pal/trackerapi/HealthApiTest.java @@ -0,0 +1,38 @@ +package test.pivotal.pal.trackerapi; + +import com.jayway.jsonpath.DocumentContext; +import io.pivotal.pal.tracker.PalTrackerApplication; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.test.context.junit4.SpringRunner; + +import static com.jayway.jsonpath.JsonPath.parse; +import static org.assertj.core.api.Assertions.assertThat; +import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = PalTrackerApplication.class, webEnvironment = RANDOM_PORT) +public class HealthApiTest { + + @Autowired + private TestRestTemplate restTemplate; + + @Test + public void healthTest() { + ResponseEntity response = this.restTemplate.getForEntity("/health", String.class); + + + assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK); + + DocumentContext healthJson = parse(response.getBody()); + + assertThat(healthJson.read("$.status", String.class)).isEqualTo("UP"); + assertThat(healthJson.read("$.db.status", String.class)).isEqualTo("UP"); + assertThat(healthJson.read("$.diskSpace.status", String.class)).isEqualTo("UP"); + } +} From 0febb850a9c491fc5a6d597614c1a69e7164d70f Mon Sep 17 00:00:00 2001 From: Tushar Mane Date: Fri, 23 Feb 2018 09:12:19 -0800 Subject: [PATCH 09/13] Health Check --- .../java/io/pivotal/pal/tracker/TimeEntryHealthIndicator.java | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 src/main/java/io/pivotal/pal/tracker/TimeEntryHealthIndicator.java diff --git a/src/main/java/io/pivotal/pal/tracker/TimeEntryHealthIndicator.java b/src/main/java/io/pivotal/pal/tracker/TimeEntryHealthIndicator.java new file mode 100644 index 000000000..6c066a7d1 --- /dev/null +++ b/src/main/java/io/pivotal/pal/tracker/TimeEntryHealthIndicator.java @@ -0,0 +1,4 @@ +package io.pivotal.pal.tracker; + +public class TimeEntryHealthIndicator { +} From c7522fed347f1aedda6bfe7c8fd907cc21aac550 Mon Sep 17 00:00:00 2001 From: Tushar Mane Date: Fri, 23 Feb 2018 09:29:07 -0800 Subject: [PATCH 10/13] added health api status --- build.gradle | 9 ++++-- ci/pipeline.yml | 3 +- .../pal/tracker/TimeEntryController.java | 28 ++++++++++++++---- .../pal/tracker/TimeEntryHealthIndicator.java | 29 +++++++++++++++++-- .../pal/tracker/TimeEntryControllerTest.java | 12 ++++++-- .../pivotal/pal/trackerapi/HealthApiTest.java | 7 +++++ 6 files changed, 74 insertions(+), 14 deletions(-) diff --git a/build.gradle b/build.gradle index 4563f9acc..de2e321f5 100644 --- a/build.gradle +++ b/build.gradle @@ -14,9 +14,8 @@ dependencies { compile("org.springframework.boot:spring-boot-starter-web") compile("com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.9.1") compile("org.springframework.boot:spring-boot-starter-jdbc") - compile("mysql:mysql-connector-java:6.0.6") - + compile("org.springframework.boot:spring-boot-starter-actuator") testCompile("org.springframework.boot:spring-boot-starter-test") } @@ -24,12 +23,14 @@ def developmentDbUrl = "jdbc:mysql://localhost:3306/tracker_dev?user=tracker&use bootRun.environment([ "WELCOME_MESSAGE": "hello", "SPRING_DATASOURCE_URL": developmentDbUrl, + "MANAGEMENT_SECURITY_ENABLED": false, ]) def testDbUrl = "jdbc:mysql://localhost:3306/tracker_test?user=tracker&useSSL=false&useTimezone=true&serverTimezone=UTC&useLegacyDatetimeCode=false" test.environment([ "WELCOME_MESSAGE": "Hello from test", "SPRING_DATASOURCE_URL": testDbUrl, + "MANAGEMENT_SECURITY_ENABLED": false, ]) flyway { @@ -41,4 +42,8 @@ flyway { task testMigrate(type: FlywayMigrateTask) { url = testDbUrl +} + +springBoot{ + buildInfo() } \ No newline at end of file diff --git a/ci/pipeline.yml b/ci/pipeline.yml index 06b53a452..548a3732c 100644 --- a/ci/pipeline.yml +++ b/ci/pipeline.yml @@ -88,6 +88,7 @@ jobs: - get: pal-tracker passed: [deploy-review] - get: pal-tracker-artifacts + trigger: true passed: [deploy-review] - task: migrate database file: pal-tracker/ci/migrateDatabase.yml @@ -106,4 +107,4 @@ jobs: manifest: pal-tracker/manifest-production.yml path: pal-tracker-artifacts/pal-tracker-*.jar environment_variables: -WELCOME_MESSAGE: "Hello from the production environment" \ No newline at end of file + WELCOME_MESSAGE: "Hello from the production environment" \ No newline at end of file diff --git a/src/main/java/io/pivotal/pal/tracker/TimeEntryController.java b/src/main/java/io/pivotal/pal/tracker/TimeEntryController.java index cf9276799..427ed4aaf 100644 --- a/src/main/java/io/pivotal/pal/tracker/TimeEntryController.java +++ b/src/main/java/io/pivotal/pal/tracker/TimeEntryController.java @@ -1,5 +1,7 @@ package io.pivotal.pal.tracker; +import org.springframework.boot.actuate.metrics.CounterService; +import org.springframework.boot.actuate.metrics.GaugeService; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; @@ -10,32 +12,43 @@ @RequestMapping("/time-entries") public class TimeEntryController { + private final CounterService counter; + private final GaugeService gauge; private TimeEntryRepository timeEntriesRepo; - public TimeEntryController(TimeEntryRepository timeEntriesRepo) { + public TimeEntryController( + TimeEntryRepository timeEntriesRepo, + CounterService counter, + GaugeService gauge + ) { this.timeEntriesRepo = timeEntriesRepo; + this.counter = counter; + this.gauge = gauge; } - @PostMapping public ResponseEntity create(@RequestBody TimeEntry timeEntry) { - TimeEntry createdTimeEntry = timeEntriesRepo.create(timeEntry); - return new ResponseEntity<>(createdTimeEntry, HttpStatus.CREATED); + TimeEntry createdTimeEntry = timeEntriesRepo.create(timeEntry); + counter.increment("TimeEntry.created"); + gauge.submit("timeEntries.count", timeEntriesRepo.list().size()); + + return new ResponseEntity<>(createdTimeEntry, HttpStatus.CREATED); } @GetMapping("{id}") - public ResponseEntity read(@PathVariable long id) { + public ResponseEntity read(@PathVariable Long id) { TimeEntry timeEntry = timeEntriesRepo.find(id); if (timeEntry != null) { + counter.increment("TimeEntry.read"); return new ResponseEntity<>(timeEntry, HttpStatus.OK); } else { return new ResponseEntity<>(HttpStatus.NOT_FOUND); } } - @GetMapping public ResponseEntity> list() { + counter.increment("TimeEntry.listed"); return new ResponseEntity<>(timeEntriesRepo.list(), HttpStatus.OK); } @@ -43,6 +56,7 @@ public ResponseEntity> list() { public ResponseEntity update(@PathVariable Long id, @RequestBody TimeEntry timeEntry) { TimeEntry updatedTimeEntry = timeEntriesRepo.update(id, timeEntry); if (updatedTimeEntry != null) { + counter.increment("TimeEntry.updated"); return new ResponseEntity<>(updatedTimeEntry, HttpStatus.OK); } else { return new ResponseEntity<>(HttpStatus.NOT_FOUND); @@ -52,6 +66,8 @@ public ResponseEntity update(@PathVariable Long id, @RequestBody Time @DeleteMapping("{id}") public ResponseEntity delete(@PathVariable Long id) { timeEntriesRepo.delete(id); + counter.increment("TimeEntry.deleted"); + gauge.submit("timeEntries.count", timeEntriesRepo.list().size()); return new ResponseEntity<>(HttpStatus.NO_CONTENT); } diff --git a/src/main/java/io/pivotal/pal/tracker/TimeEntryHealthIndicator.java b/src/main/java/io/pivotal/pal/tracker/TimeEntryHealthIndicator.java index 6c066a7d1..49b1f175d 100644 --- a/src/main/java/io/pivotal/pal/tracker/TimeEntryHealthIndicator.java +++ b/src/main/java/io/pivotal/pal/tracker/TimeEntryHealthIndicator.java @@ -1,4 +1,29 @@ package io.pivotal.pal.tracker; -public class TimeEntryHealthIndicator { -} +import org.springframework.boot.actuate.health.Health; +import org.springframework.boot.actuate.health.HealthIndicator; +import org.springframework.stereotype.Component; + +@Component +public class TimeEntryHealthIndicator implements HealthIndicator { + + private static final int MAX_TIME_ENTRIES = 5; + private final TimeEntryRepository timeEntryRepo; + + public TimeEntryHealthIndicator(TimeEntryRepository timeEntryRepo) { + this.timeEntryRepo = timeEntryRepo; + } + + @Override + public Health health() { + Health.Builder builder = new Health.Builder(); + + if(timeEntryRepo.list().size() < MAX_TIME_ENTRIES) { + builder.up(); + } else { + builder.down(); + } + + return builder.build(); + } +} \ No newline at end of file diff --git a/src/test/java/test/pivotal/pal/tracker/TimeEntryControllerTest.java b/src/test/java/test/pivotal/pal/tracker/TimeEntryControllerTest.java index 49c54aa02..5956ecd88 100644 --- a/src/test/java/test/pivotal/pal/tracker/TimeEntryControllerTest.java +++ b/src/test/java/test/pivotal/pal/tracker/TimeEntryControllerTest.java @@ -5,6 +5,8 @@ import io.pivotal.pal.tracker.TimeEntryRepository; import org.junit.Before; import org.junit.Test; +import org.springframework.boot.actuate.metrics.CounterService; +import org.springframework.boot.actuate.metrics.GaugeService; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -20,11 +22,15 @@ public class TimeEntryControllerTest { private TimeEntryRepository timeEntryRepository; private TimeEntryController controller; + private CounterService counterService; + private GaugeService gaugeService; @Before public void setUp() throws Exception { timeEntryRepository = mock(TimeEntryRepository.class); - controller = new TimeEntryController(timeEntryRepository); + counterService = mock(CounterService.class); + gaugeService = mock(GaugeService.class); + controller = new TimeEntryController(timeEntryRepository, counterService, gaugeService); } @Test @@ -34,7 +40,7 @@ public void testCreate() throws Exception { .when(timeEntryRepository) .create(any(TimeEntry.class)); - ResponseEntity response = controller.create(new TimeEntry(123L, 456L, LocalDate.parse("2017-01-08"), 80)); + ResponseEntity response = controller.create(new TimeEntry(123L, 456L, LocalDate.parse("2017-01-08"), 8)); assertThat(response.getStatusCode()).isEqualTo(HttpStatus.CREATED); assertThat(response.getBody()).isEqualTo(expected); @@ -103,4 +109,4 @@ public void testDelete() throws Exception { verify(timeEntryRepository).delete(1L); assertThat(response.getStatusCode()).isEqualTo(HttpStatus.NO_CONTENT); } -} +} \ No newline at end of file diff --git a/src/test/java/test/pivotal/pal/trackerapi/HealthApiTest.java b/src/test/java/test/pivotal/pal/trackerapi/HealthApiTest.java index b3eef23cc..499a47748 100644 --- a/src/test/java/test/pivotal/pal/trackerapi/HealthApiTest.java +++ b/src/test/java/test/pivotal/pal/trackerapi/HealthApiTest.java @@ -1,7 +1,9 @@ package test.pivotal.pal.trackerapi; import com.jayway.jsonpath.DocumentContext; +import com.mysql.cj.jdbc.MysqlDataSource; import io.pivotal.pal.tracker.PalTrackerApplication; +import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; @@ -9,8 +11,11 @@ import org.springframework.boot.test.web.client.TestRestTemplate; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; +import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.test.context.junit4.SpringRunner; +import java.util.TimeZone; + import static com.jayway.jsonpath.JsonPath.parse; import static org.assertj.core.api.Assertions.assertThat; import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; @@ -22,6 +27,8 @@ public class HealthApiTest { @Autowired private TestRestTemplate restTemplate; + + @Test public void healthTest() { ResponseEntity response = this.restTemplate.getForEntity("/health", String.class); From c92a66f5eaac84103a7c2b3d50e2428c412de6f6 Mon Sep 17 00:00:00 2001 From: Tyson Gern Date: Wed, 26 Jul 2017 12:50:47 -0600 Subject: [PATCH 11/13] Add tests for Security lab --- .../pal/trackerapi/SecurityApiTest.java | 52 +++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 src/test/java/test/pivotal/pal/trackerapi/SecurityApiTest.java diff --git a/src/test/java/test/pivotal/pal/trackerapi/SecurityApiTest.java b/src/test/java/test/pivotal/pal/trackerapi/SecurityApiTest.java new file mode 100644 index 000000000..72099994b --- /dev/null +++ b/src/test/java/test/pivotal/pal/trackerapi/SecurityApiTest.java @@ -0,0 +1,52 @@ +package test.pivotal.pal.trackerapi; + +import io.pivotal.pal.tracker.PalTrackerApplication; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.context.embedded.LocalServerPort; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.web.client.RestTemplateBuilder; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.test.context.junit4.SpringRunner; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = PalTrackerApplication.class, webEnvironment = RANDOM_PORT) +public class SecurityApiTest { + + @LocalServerPort + private String port; + private TestRestTemplate authorizedRestTemplate; + + @Autowired + private TestRestTemplate unAuthorizedRestTemplate; + + @Before + public void setUp() throws Exception { + RestTemplateBuilder builder = new RestTemplateBuilder() + .rootUri("http://localhost:" + port) + .basicAuthorization("user", "password"); + + authorizedRestTemplate = new TestRestTemplate(builder); + } + + @Test + public void unauthorizedTest() { + ResponseEntity response = this.unAuthorizedRestTemplate.getForEntity("/", String.class); + + assertThat(response.getStatusCode()).isEqualTo(HttpStatus.UNAUTHORIZED); + } + + @Test + public void authorizedTest() { + ResponseEntity response = this.authorizedRestTemplate.getForEntity("/", String.class); + + assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK); + } +} From 08231e85a30d592089db2318278e0df27a08d6b3 Mon Sep 17 00:00:00 2001 From: Tushar Mane Date: Fri, 23 Feb 2018 10:22:17 -0800 Subject: [PATCH 12/13] added basic security auth --- build.gradle | 2 ++ manifest-production.yml | 4 ++- manifest-review.yml | 4 ++- .../pal/tracker/SecurityConfiguration.java | 35 +++++++++++++++++++ .../pivotal/pal/trackerapi/HealthApiTest.java | 14 ++++++++ .../pal/trackerapi/TimeEntryApiTest.java | 11 ++++++ .../pal/trackerapi/WelcomeApiTest.java | 15 ++++++++ 7 files changed, 83 insertions(+), 2 deletions(-) create mode 100644 src/main/java/io/pivotal/pal/tracker/SecurityConfiguration.java diff --git a/build.gradle b/build.gradle index de2e321f5..fab2ad967 100644 --- a/build.gradle +++ b/build.gradle @@ -17,6 +17,8 @@ dependencies { compile("mysql:mysql-connector-java:6.0.6") compile("org.springframework.boot:spring-boot-starter-actuator") testCompile("org.springframework.boot:spring-boot-starter-test") + compile("org.springframework.boot:spring-boot-starter-security") + } def developmentDbUrl = "jdbc:mysql://localhost:3306/tracker_dev?user=tracker&useSSL=false&useTimezone=true&serverTimezone=UTC&useLegacyDatetimeCode=false" diff --git a/manifest-production.yml b/manifest-production.yml index ca505eaea..3ae5ad9e4 100644 --- a/manifest-production.yml +++ b/manifest-production.yml @@ -4,4 +4,6 @@ applications: path: build/libs/pal-tracker.jar host: ps-pal-tracker services: - - tracker-database \ No newline at end of file + - tracker-database + env: + SECURITY_FORCE_HTTPS: true \ No newline at end of file diff --git a/manifest-review.yml b/manifest-review.yml index 897eba97d..cbfddd6cd 100644 --- a/manifest-review.yml +++ b/manifest-review.yml @@ -4,4 +4,6 @@ applications: path: build/libs/pal-tracker.jar host: ps-pal-tracker-review services: - - tracker-database \ No newline at end of file + - tracker-database + env: + SECURITY_FORCE_HTTPS: true \ No newline at end of file diff --git a/src/main/java/io/pivotal/pal/tracker/SecurityConfiguration.java b/src/main/java/io/pivotal/pal/tracker/SecurityConfiguration.java new file mode 100644 index 000000000..8548a54b7 --- /dev/null +++ b/src/main/java/io/pivotal/pal/tracker/SecurityConfiguration.java @@ -0,0 +1,35 @@ +package io.pivotal.pal.tracker; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; + +@EnableWebSecurity +public class SecurityConfiguration extends WebSecurityConfigurerAdapter { + + + @Override + protected void configure(HttpSecurity http) throws Exception { + String forceHttps = System.getenv("SECURITY_FORCE_HTTPS"); + + if (forceHttps != null && forceHttps.equals("true")) { + http.requiresChannel().anyRequest().requiresSecure(); + } + + http + .authorizeRequests().antMatchers("/**").hasRole("USER") + .and() + .httpBasic() + .and() + .csrf().disable(); + } + + @Autowired + public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { + auth + .inMemoryAuthentication() + .withUser("user").password("password").roles("USER"); + } +} diff --git a/src/test/java/test/pivotal/pal/trackerapi/HealthApiTest.java b/src/test/java/test/pivotal/pal/trackerapi/HealthApiTest.java index 499a47748..d72d80066 100644 --- a/src/test/java/test/pivotal/pal/trackerapi/HealthApiTest.java +++ b/src/test/java/test/pivotal/pal/trackerapi/HealthApiTest.java @@ -7,8 +7,10 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.context.embedded.LocalServerPort; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.web.client.RestTemplateBuilder; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.jdbc.core.JdbcTemplate; @@ -27,7 +29,17 @@ public class HealthApiTest { @Autowired private TestRestTemplate restTemplate; + @LocalServerPort + private String port; + @Before + public void setUp(){ + RestTemplateBuilder builder = new RestTemplateBuilder(). + rootUri("http://localhost:"+port). + basicAuthorization("user","password"); + + restTemplate = new TestRestTemplate(builder); + } @Test public void healthTest() { @@ -41,5 +53,7 @@ public void healthTest() { assertThat(healthJson.read("$.status", String.class)).isEqualTo("UP"); assertThat(healthJson.read("$.db.status", String.class)).isEqualTo("UP"); assertThat(healthJson.read("$.diskSpace.status", String.class)).isEqualTo("UP"); + + } } diff --git a/src/test/java/test/pivotal/pal/trackerapi/TimeEntryApiTest.java b/src/test/java/test/pivotal/pal/trackerapi/TimeEntryApiTest.java index df213a69d..18319e22e 100644 --- a/src/test/java/test/pivotal/pal/trackerapi/TimeEntryApiTest.java +++ b/src/test/java/test/pivotal/pal/trackerapi/TimeEntryApiTest.java @@ -7,8 +7,10 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.context.embedded.LocalServerPort; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.web.client.RestTemplateBuilder; import org.springframework.http.HttpEntity; import org.springframework.http.HttpMethod; import org.springframework.http.HttpStatus; @@ -32,6 +34,9 @@ public class TimeEntryApiTest { private TimeEntry timeEntry = new TimeEntry(123L, 456L, LocalDate.parse("2017-01-08"), 8); + @LocalServerPort + private String port; + @Before public void setUp() throws Exception { MysqlDataSource dataSource = new MysqlDataSource(); @@ -41,6 +46,12 @@ public void setUp() throws Exception { jdbcTemplate.execute("TRUNCATE time_entries"); TimeZone.setDefault(TimeZone.getTimeZone("UTC")); + + RestTemplateBuilder builder = new RestTemplateBuilder(). + rootUri("http://localhost:"+port). + basicAuthorization("user","password"); + + restTemplate = new TestRestTemplate(builder); } @Test diff --git a/src/test/java/test/pivotal/pal/trackerapi/WelcomeApiTest.java b/src/test/java/test/pivotal/pal/trackerapi/WelcomeApiTest.java index cc7091ed4..804f1a7e0 100644 --- a/src/test/java/test/pivotal/pal/trackerapi/WelcomeApiTest.java +++ b/src/test/java/test/pivotal/pal/trackerapi/WelcomeApiTest.java @@ -1,11 +1,14 @@ package test.pivotal.pal.trackerapi; import io.pivotal.pal.tracker.PalTrackerApplication; +import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.context.embedded.LocalServerPort; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.web.client.RestTemplateBuilder; import org.springframework.test.context.junit4.SpringRunner; import static org.assertj.core.api.Assertions.assertThat; @@ -18,6 +21,18 @@ public class WelcomeApiTest { @Autowired private TestRestTemplate restTemplate; + @LocalServerPort + private String port; + + @Before + public void setUp(){ + RestTemplateBuilder builder = new RestTemplateBuilder(). + rootUri("http://localhost:"+port). + basicAuthorization("user","password"); + + restTemplate = new TestRestTemplate(builder); + } + @Test public void exampleTest() { String body = this.restTemplate.getForObject("/", String.class); From e37d0d1cc02f46f112cc79461d28ce933303654e Mon Sep 17 00:00:00 2001 From: Tushar Mane Date: Fri, 23 Feb 2018 13:50:32 -0800 Subject: [PATCH 13/13] edited gitignore --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index d5c2a6a3c..aaf6b661a 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,4 @@ out .gradle .idea *.iml -ci/variables.yml +ci/variables.ymdl