あいつの日誌β

働きながら旅しています。

getting started dropwizard 0.7.0 part2

this article is copied from いますぐ採用すべきJavaフレームワークDropWizard(その3) - Qiita

maven

edit pom.xml:

% git diff
diff --git a/pom.xml b/pom.xml
index d4b67a8..4bfd736 100644
--- a/pom.xml
+++ b/pom.xml
@@ -27,6 +27,11 @@
       <artifactId>dropwizard-core</artifactId>
       <version>${dropwizard.version}</version>
     </dependency>
+    <dependency>
+      <groupId>io.dropwizard</groupId>
+      <artifactId>dropwizard-hibernate</artifactId>
+      <version>${dropwizard.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>io.dropwizard</groupId>
+      <artifactId>dropwizard-migrations</artifactId>
+      <version>${dropwizard.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>com.h2database</groupId>
+      <artifactId>h2</artifactId>
+      <version>1.4.182</version>
+    </dependency>
   </dependencies>
 
   <build>
% git add pom.xml
% git commit -m 'add dependency dropwizard-hibernate'

Entitiy

create src/main/java/com/example/helloworld/core/Person.java:

package com.example.helloworld.core;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.Table;
import java.util.Objects;

@Entity
@Table(name = "people")
@NamedQueries({
  @NamedQuery(
    name = "com.example.helloworld.core.Person.findAll",
    query = "SELECT p FROM Person p"
  )
})
public class Person {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long id;

    @Column(name = "fullName", nullable = false)
    private String fullName;

    @Column(name = "jobTitle", nullable = false)
    private String jobTitle;

    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }

    public String getFullName() {
        return fullName;
    }

    public void setFullName(String fullName) {
        this.fullName = fullName;
    }

    public String getJobTitle() {
        return jobTitle;
    }

    public void setJobTitle(String jobTitle) {
        this.jobTitle = jobTitle;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof Person)) return false;

        final Person that = (Person) o;

        return Objects.equals(this.id, that.id) &&
                Objects.equals(this.fullName, that.fullName) &&
                Objects.equals(this.jobTitle, that.jobTitle);
    }

    @Override
    public int hashCode() {
        return Objects.hash(id, fullName, jobTitle);
    }
}
% git add src/main/java/com/example/helloworld/core/Person.java
% git commit -m 'add Person entity'

DAO

create src/main/java/com/example/helloworld/db/PersonDAO.java:

package com.example.helloworld.db;

import com.example.helloworld.core.Person;
import com.google.common.base.Optional;
import io.dropwizard.hibernate.AbstractDAO;
import org.hibernate.SessionFactory;

import java.util.List;

public class PersonDAO extends AbstractDAO<Person> {
    public PersonDAO(SessionFactory factory) {
        super(factory);
    }

    public Optional<Person> findById(Long id) {
        return Optional.fromNullable(get(id));
    }

    public Person create(Person person) {
        return persist(person);
    }

    public List<Person> findAll() {
        return list(namedQuery("com.example.helloworld.core.Person.findAll"));
    } 
}
% git add src/main/java/com/example/helloworld/db/PersonDAO.java
% git commit -m 'add PersonDAO'

PeopleResource

create src/main/java/com/example/helloworld/resources/PeopleResource.java:

package com.example.helloworld.resources;

import com.example.helloworld.core.Person;
import com.example.helloworld.db.PersonDAO;
import io.dropwizard.hibernate.UnitOfWork;

import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import java.util.List;

@Path("/people")
@Produces(MediaType.APPLICATION_JSON)
public class PeopleResource {

    private final PersonDAO peopleDAO;

    public PeopleResource(PersonDAO peopleDAO) {
        this.peopleDAO = peopleDAO;
    }

    @POST
    @UnitOfWork
    public Person createPerson(Person person) {
        return peopleDAO.create(person);
    }

    @GET
    @UnitOfWork
    public List<Person> listPeople() {
        return peopleDAO.findAll();
    }
}
% git add src/main/java/com/example/helloworld/resources/PeopleResource.java
% git commit -m 'add PeopleResource'

DB

edit myapp.yml

diff --git a/myapp.yml b/myapp.yml
index 89c931f..436e549 100644
--- a/myapp.yml
+++ b/myapp.yml
@@ -1,2 +1,24 @@
 template: Hello, %s!
 defaultName: Stranger
+database:
+  driverClass: org.h2.Driver
+
+  user: sa
+
+  password: sa
+
+  url: jdbc:h2:~/target/example
+
+  properties:
+    charSet: UTF-8
+    hibernate.dialect: org.hibernate.dialect.H2Dialect
+
+  maxWaitForConnection: 1s
+
+  validationQuery: "/* MyApplication Health Check */ SELECT 1"
+
+  minSize: 8
+
+  maxSize: 32
+
+  checkConnectionWhileIdle: false
% git add myapp.yml
% git commit -m 'add db configuration'

create schema

create src/main/resources/migrations.xml:

<?xml version="1.0" encoding="UTF-8"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog
         http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.1.xsd">
    <changeSet id="1" author="">
        <createTable tableName="people">
            <column name="id" type="bigint" autoIncrement="true">
                <constraints primaryKey="true" nullable="false" />
            </column>
            <column name="fullName" type="varchar(255)">
                <constraints nullable="false" />
            </column>
            <column name="jobTitle" type="varchar(255)" />
        </createTable>
    </changeSet>
</databaseChangeLog>
% git add src/main/resources/migrations.xml
% git commit -m 'add schema'

edit src/main/java/com/example/helloworld/HelloWorldConfiguration.java:

diff --git a/src/main/java/com/example/helloworld/HelloWorldConfiguration.java b/src/main/java/com/example/helloworld/HelloWorldConfiguration.java
index ef46722..b84cfe1 100644
--- a/src/main/java/com/example/helloworld/HelloWorldConfiguration.java
+++ b/src/main/java/com/example/helloworld/HelloWorldConfiguration.java
@@ -1,9 +1,14 @@
 package com.example.helloworld;
 
 import io.dropwizard.Configuration;
+import io.dropwizard.db.DataSourceFactory;
+
 import com.fasterxml.jackson.annotation.JsonProperty;
 import org.hibernate.validator.constraints.NotEmpty;
 
+import javax.validation.Valid;
+import javax.validation.constraints.NotNull;
+
 public class HelloWorldConfiguration extends Configuration {
     @NotEmpty
     private String template;
@@ -11,6 +16,10 @@ public class HelloWorldConfiguration extends Configuration {
     @NotEmpty
     private String defaultName = "Stranger";
 
+    @Valid
+    @NotNull
+    private DataSourceFactory database = new DataSourceFactory();
+
     @JsonProperty
     public String getTemplate() {
         return template;
@@ -30,4 +39,14 @@ public class HelloWorldConfiguration extends Configuration {
     public void setDefaultName(String name) {
         this.defaultName = name;
     }
+
+    @JsonProperty("database")
+    public DataSourceFactory getDataSourceFactory() {
+        return database;
+    }
+
+    @JsonProperty("database")
+    public void setDataSourceFactory(DataSourceFactory dataSourceFactory) {
+        this.database = dataSourceFactory;
+    }
 }
% git add src/main/java/com/example/helloworld/HelloWorldConfiguration.java
% git commit -m 'add database configuration'

edit src/main/java/com/example/helloworld/HelloWorldApplication.java:

diff --git a/src/main/java/com/example/helloworld/HelloWorldApplication.java b/src/main/java/com/example/helloworld/HelloWorldApplication.java
index 9afca10..bc68d91 100644
--- a/src/main/java/com/example/helloworld/HelloWorldApplication.java
+++ b/src/main/java/com/example/helloworld/HelloWorldApplication.java
@@ -1,16 +1,32 @@
 package com.example.helloworld;
 
 import io.dropwizard.Application;
+import io.dropwizard.hibernate.HibernateBundle;
+import io.dropwizard.db.DataSourceFactory;
+import io.dropwizard.migrations.MigrationsBundle;
 import io.dropwizard.setup.Bootstrap;
 import io.dropwizard.setup.Environment;
-import com.example.helloworld.resources.HelloWorldResource;
+
+import com.example.helloworld.core.Person;
+import com.example.helloworld.db.PersonDAO;
 import com.example.helloworld.health.TemplateHealthCheck;
+import com.example.helloworld.resources.HelloWorldResource;
+import com.example.helloworld.resources.PeopleResource;
+
 
 public class HelloWorldApplication extends Application<HelloWorldConfiguration> {
+    
     public static void main(String[] args) throws Exception {
         new HelloWorldApplication().run(args);
     }
 
+    public HibernateBundle<HelloWorldConfiguration> hibernateBundle = new HibernateBundle<HelloWorldConfiguration>(Person.class) {
+        @Override
+        public DataSourceFactory getDataSourceFactory(HelloWorldConfiguration configuration) {
+            return configuration.getDataSourceFactory();
+        }
+    };
+
     @Override
     public String getName() {
         return "hello-world";
@@ -18,17 +34,25 @@ public class HelloWorldApplication extends Application<HelloWorldConfiguration>
 
     @Override
     public void initialize(Bootstrap<HelloWorldConfiguration> bootstrap) {
-        // nothing to do yet
+        bootstrap.addBundle(hibernateBundle);
+        bootstrap.addBundle(new MigrationsBundle<HelloWorldConfiguration>() {
+            @Override
+            public DataSourceFactory getDataSourceFactory(HelloWorldConfiguration configuration) {
+                return configuration.getDataSourceFactory();
+            }
+        });
     }
 
     @Override
     public void run(HelloWorldConfiguration configuration,
                     Environment environment) {
-        // nothing to do yet
         final HelloWorldResource resource = new HelloWorldResource(
             configuration.getTemplate(),
             configuration.getDefaultName()
         );
+        final PersonDAO dao = new PersonDAO(hibernateBundle.getSessionFactory());
+        environment.jersey().register(new PeopleResource(dao));
+        
         final TemplateHealthCheck healthCheck =
             new TemplateHealthCheck(configuration.getTemplate());
         environment.healthChecks().register("template", healthCheck);
% git add src/main/java/com/example/helloworld/HelloWorldApplication.java
% git commit -m 'add HibernateBundle, MigrationsBundle'
% mvn package
% java -jar target/myapp-1.0-SNAPSHOT.jar db migrate myapp.yml

Run

% java -jar target/myapp-1.0-SNAPSHOT.jar server myapp.yml

POST

% curl -H "Content-Type: application/json" -X POST -d '{"fullName":"Coda Hale", "jobTitle" : "Chief Wizard" }' http://localhost:8080/people
{"id":1,"fullName":"Coda Hale","jobTitle":"Chief Wizard"}
% curl -H "Content-Type: application/json" -X POST -d '{"fullName":"ko2ic", "jobTitle" : "hoge" }' http://localhost:8080/people
{"id":2,"fullName":"ko2ic","jobTitle":"hoge"}

GET

% curl http://localhost:8080/people
[{"id":1,"fullName":"Coda Hale","jobTitle":"Chief Wizard"},{"id":2,"fullName":"ko2ic","jobTitle":"hoge"}]