From 81fbcfc2409f885dd8405042b05d272d4eb629e5 Mon Sep 17 00:00:00 2001
From: Dan K <dk14142@gmail.com>
Date: Mon, 22 Jul 2019 21:38:35 +0200
Subject: [PATCH] WIP(ch9lab) add source for java-based todo-api app

---
 todo-api-micro/src/main/java/com/redhat/training/rest/CORSResponseFilter.java                 |   32 ++
 todo-api-micro/src/main/java/com/redhat/training/example/todoapi/rest/HelloWorldEndpoint.java |   19 +
 todo-api-micro/src/main/java/com/redhat/training/model/Host.java                              |   24 ++
 todo-api-micro/src/main/fabric8/route.yml                                                     |   18 +
 todo-api-micro/src/main/resources/modules/com/mysql/main/module.xml                           |   16 +
 todo-api-micro/src/main/java/com/redhat/training/model/Item.java                              |   53 ++++
 todo-api-micro/pom.xml                                                                        |  111 ++++++++++
 todo-api-micro/src/main/resources/META-INF/persistence.xml                                    |   18 +
 todo-api-micro/src/main/resources/sql/drop.sql                                                |    1 
 todo-api-micro/src/main/resources/sql/load.sql                                                |    2 
 todo-api-micro/src/main/java/com/redhat/training/rest/CORSRequestFilter.java                  |   30 ++
 todo-api-micro/src/main/java/com/redhat/training/rest/HostService.java                        |   28 ++
 todo-api-micro/src/main/java/com/redhat/training/rest/ItemService.java                        |   97 ++++++++
 todo-api-micro/src/main/fabric8/svc.yml                                                       |   21 +
 todo-api-micro/src/main/java/com/redhat/training/example/todoapi/rest/Main.java               |   25 ++
 todo-api-micro/src/main/resources/project-defaults.yml                                        |   13 +
 todo-api-micro/src/main/resources/sql/create.sql                                              |    1 
 todo-api-micro/src/main/fabric8/deployment.yml                                                |   21 +
 todo-api-micro/src/main/java/com/redhat/training/rest/RestApplication.java                    |    8 
 todo-api-micro/src/main/java/com/redhat/training/ui/PaginatedListWrapper.java                 |   72 ++++++
 20 files changed, 610 insertions(+), 0 deletions(-)

diff --git a/todo-api-micro/pom.xml b/todo-api-micro/pom.xml
new file mode 100755
index 0000000..b227a11
--- /dev/null
+++ b/todo-api-micro/pom.xml
@@ -0,0 +1,111 @@
+<?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>
+  <groupId>com.redhat.training.example</groupId>
+  <artifactId>todo-api</artifactId>
+  <name>WildFly Swarm Example</name>
+  <version>1.0.0-SNAPSHOT</version>
+  <packaging>war</packaging>
+
+  <properties>
+    <version.wildfly.swarm>2017.12.1</version.wildfly.swarm>
+    <version.mysql>6.0.6</version.mysql>
+    <maven.compiler.source>1.8</maven.compiler.source>
+    <maven.compiler.target>1.8</maven.compiler.target>
+    <failOnMissingWebXml>false</failOnMissingWebXml>
+    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+    <fabric8.maven.plugin.version>3.1.80.redhat-000019</fabric8.maven.plugin.version>
+    <fabric8.version>2.3.6</fabric8.version>
+  </properties>
+
+  <dependencyManagement>
+    <dependencies>
+      <dependency>
+        <groupId>org.wildfly.swarm</groupId>
+        <artifactId>bom-all</artifactId>
+        <version>${version.wildfly.swarm}</version>
+        <scope>import</scope>
+        <type>pom</type>
+      </dependency>
+    </dependencies>
+  </dependencyManagement>
+
+  <build>
+    <finalName>demo</finalName>
+    <plugins>
+      <plugin>
+        <groupId>org.wildfly.swarm</groupId>
+        <artifactId>wildfly-swarm-plugin</artifactId>
+        <version>${version.wildfly.swarm}</version>
+        <executions>
+          <execution>
+            <goals>
+              <goal>package</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+      <plugin>
+        <groupId>io.fabric8</groupId>
+        <artifactId>fabric8-maven-plugin</artifactId>
+        <executions>
+          <execution>
+            <goals>
+              <goal>resource</goal>
+              <goal>build</goal>
+            </goals>
+          </execution>
+        </executions>
+        <configuration>
+          <generator>
+            <includes>
+              <include>wildfly-swarm</include>
+            </includes>
+            <excludes>
+              <exclude>webapp</exclude>
+            </excludes>
+            <config>
+              <wildfly-swarm>
+                <fromMode>isTag</fromMode>
+                <from>redhat-openjdk18-openshift</from>
+              </wildfly-swarm>
+            </config>
+          </generator>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+
+  <dependencies>
+    <!-- Java EE 7 dependency -->
+    <dependency>
+      <groupId>javax</groupId>
+      <artifactId>javaee-api</artifactId>
+      <version>7.0</version>
+      <scope>provided</scope>
+    </dependency>
+    <!-- WildFly Swarm Fractions -->
+    <dependency>
+      <groupId>org.wildfly.swarm</groupId>
+      <artifactId>jaxrs-jsonp</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.wildfly.swarm</groupId>
+      <artifactId>jpa</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.wildfly.swarm</groupId>
+      <artifactId>ejb</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.wildfly.swarm</groupId>
+      <artifactId>datasources</artifactId>
+    </dependency>
+
+    <dependency>
+      <groupId>mysql</groupId>
+      <artifactId>mysql-connector-java</artifactId>
+      <version>${version.mysql}</version>
+    </dependency>
+  </dependencies>
+</project>
diff --git a/todo-api-micro/src/main/fabric8/deployment.yml b/todo-api-micro/src/main/fabric8/deployment.yml
new file mode 100644
index 0000000..f9fa89d
--- /dev/null
+++ b/todo-api-micro/src/main/fabric8/deployment.yml
@@ -0,0 +1,21 @@
+spec:
+  template:
+    spec:
+      containers:
+        - 
+          resources:
+            requests:
+              cpu: "0.2"
+#              memory: 256Mi
+            limits:
+              cpu: "1.0"
+#              memory: 256Mi
+          env:
+          - name: DATABASE_USER
+            value: '${database.user}'
+          - name: DATABASE_PASSWORD
+            value: '${database.password}'
+          - name: DATABASE_SVC_HOSTNAME
+            value: '${database.svc.hostname}'
+          - name: DATABASE_NAME
+            value: '${database.name}'
diff --git a/todo-api-micro/src/main/fabric8/route.yml b/todo-api-micro/src/main/fabric8/route.yml
new file mode 100644
index 0000000..d7f59ab
--- /dev/null
+++ b/todo-api-micro/src/main/fabric8/route.yml
@@ -0,0 +1,18 @@
+---
+apiVersion: v1
+kind: Route
+metadata:
+  labels:
+    expose: "true"
+    app: ${project.artifactId}
+    provider: fabric8
+    version: "1.0"
+    group: com.redhat.training
+  name: ${project.artifactId}
+spec:
+  host: ${hostname}
+  port:
+    targetPort: ${service-port}
+  to:
+    kind: Service
+    name: ${project.artifactId}
diff --git a/todo-api-micro/src/main/fabric8/svc.yml b/todo-api-micro/src/main/fabric8/svc.yml
new file mode 100644
index 0000000..b812eb9
--- /dev/null
+++ b/todo-api-micro/src/main/fabric8/svc.yml
@@ -0,0 +1,21 @@
+---
+apiVersion: v1
+kind: Service
+metadata:
+  annotations:
+    fabric8.io/iconUrl: img/icons/camel.svg
+  labels:
+    expose: "true"
+    app: ${project.artifactId}
+    provider: fabric8
+    version: "1.0"
+    group: com.redhat.training
+  name: ${project.artifactId}
+spec:
+  ports:
+  - name: http
+    port: ${service-port}
+    protocol: TCP
+    targetPort: ${service-port}
+  selector:
+    deploymentconfig: ${project.artifactId}
diff --git a/todo-api-micro/src/main/java/com/redhat/training/example/todoapi/rest/HelloWorldEndpoint.java b/todo-api-micro/src/main/java/com/redhat/training/example/todoapi/rest/HelloWorldEndpoint.java
new file mode 100755
index 0000000..ec8817b
--- /dev/null
+++ b/todo-api-micro/src/main/java/com/redhat/training/example/todoapi/rest/HelloWorldEndpoint.java
@@ -0,0 +1,19 @@
+package com.redhat.training.example.todoapi.rest;
+
+
+import javax.ws.rs.Path;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.GET;
+import javax.ws.rs.Produces;
+
+
+@Path("/hello")
+public class HelloWorldEndpoint {
+
+	@GET
+	@Produces("text/plain")
+	public Response doGet() {
+		return Response.ok("Hello World!").build();
+
+	}
+}
diff --git a/todo-api-micro/src/main/java/com/redhat/training/example/todoapi/rest/Main.java b/todo-api-micro/src/main/java/com/redhat/training/example/todoapi/rest/Main.java
new file mode 100644
index 0000000..2dbeece
--- /dev/null
+++ b/todo-api-micro/src/main/java/com/redhat/training/example/todoapi/rest/Main.java
@@ -0,0 +1,25 @@
+package com.redhat.training.example.todoapi.rest;
+
+import org.wildfly.swarm.Swarm;
+import org.wildfly.swarm.datasources.DatasourcesFraction;
+
+public class Main {
+    public static void main(String[] args) throws Exception {
+        String host = System.getenv("HOST");
+        new Swarm()
+                .fraction(new DatasourcesFraction()
+                        .jdbcDriver("mysql", (d) -> {
+                            d.driverClassName("com.mysql.cj.jdbc.Driver");
+                            d.xaDatasourceClass("com.mysql.jdbc.jdbc2.optional.MysqlXADataSource");
+                            d.driverModuleName("com.mysql");
+                        })
+                        .dataSource("MySQLDS", (ds) -> {
+                            ds.driverName("mysql");
+                            ds.connectionUrl("jdbc:mysql://"+host+":8889/todo");
+                            ds.userName("root");
+                            ds.password("root");
+                        }))
+                .start()
+                .deploy();
+    }
+}
diff --git a/todo-api-micro/src/main/java/com/redhat/training/model/Host.java b/todo-api-micro/src/main/java/com/redhat/training/model/Host.java
new file mode 100644
index 0000000..30dbcf2
--- /dev/null
+++ b/todo-api-micro/src/main/java/com/redhat/training/model/Host.java
@@ -0,0 +1,24 @@
+package com.redhat.training.model;
+
+import java.net.InetAddress;
+
+public class Host {
+
+	private String ip;
+	private String hostname;
+	
+	public Host(String ip, String hostname) {
+		this.ip = ip;
+		this.hostname = hostname;
+	}
+
+	public String getIp() {
+		return ip;
+	}
+
+	public String getHostname() {
+		return hostname;
+	}
+	
+}
+
diff --git a/todo-api-micro/src/main/java/com/redhat/training/model/Item.java b/todo-api-micro/src/main/java/com/redhat/training/model/Item.java
new file mode 100644
index 0000000..5067fe5
--- /dev/null
+++ b/todo-api-micro/src/main/java/com/redhat/training/model/Item.java
@@ -0,0 +1,53 @@
+package com.redhat.training.model;
+
+import javax.persistence.*;
+
+@Entity
+public class Item {
+    @Id
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    private Long id;
+
+    private String description;
+
+    private Boolean done = false;
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public String getDescription() {
+        return description;
+    }
+
+    public void setDescription(String description) {
+        this.description = description;
+    }
+
+    public Boolean isDone() {
+        return done;
+    }
+
+    public void setDone(Boolean done) {
+        this.done = done;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) { return true; }
+        if (o == null || getClass() != o.getClass()) { return false; }
+
+        Item item = (Item) o;
+
+        return id.equals(item.id);
+    }
+
+    @Override
+    public int hashCode() {
+        return id.hashCode();
+    }
+}
diff --git a/todo-api-micro/src/main/java/com/redhat/training/rest/CORSRequestFilter.java b/todo-api-micro/src/main/java/com/redhat/training/rest/CORSRequestFilter.java
new file mode 100644
index 0000000..d8b03ce
--- /dev/null
+++ b/todo-api-micro/src/main/java/com/redhat/training/rest/CORSRequestFilter.java
@@ -0,0 +1,30 @@
+package com.redhat.training.rest;
+ 
+import java.io.IOException;
+import java.util.logging.Logger;
+
+import javax.ws.rs.container.ContainerRequestContext;
+import javax.ws.rs.container.ContainerRequestFilter;
+import javax.ws.rs.container.PreMatching;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.ext.Provider;
+ 
+@Provider
+@PreMatching
+public class CORSRequestFilter implements ContainerRequestFilter {
+ 
+    private final static Logger log = Logger.getLogger(CORSRequestFilter.class.getName());
+ 
+    @Override
+    public void filter(ContainerRequestContext requestCtx) throws IOException {
+        log.fine("Executing REST request filter");
+ 
+        // When HttpMethod comes as OPTIONS, just acknowledge that it accepts...
+        if (requestCtx.getRequest().getMethod().equals( "OPTIONS" )) {
+            log.fine("HTTP Method (OPTIONS) - Detected!");
+ 
+            // Just send a OK signal back to the browser
+            requestCtx.abortWith(Response.status(Response.Status.OK).build());
+        }
+    }
+}
diff --git a/todo-api-micro/src/main/java/com/redhat/training/rest/CORSResponseFilter.java b/todo-api-micro/src/main/java/com/redhat/training/rest/CORSResponseFilter.java
new file mode 100644
index 0000000..6421190
--- /dev/null
+++ b/todo-api-micro/src/main/java/com/redhat/training/rest/CORSResponseFilter.java
@@ -0,0 +1,32 @@
+package com.redhat.training.rest;
+
+import java.io.IOException;
+import java.util.logging.Logger;
+
+import javax.ws.rs.container.ContainerRequestContext;
+import javax.ws.rs.container.ContainerResponseContext;
+import javax.ws.rs.container.ContainerResponseFilter;
+import javax.ws.rs.container.PreMatching;
+import javax.ws.rs.core.MultivaluedMap;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.ext.Provider;
+ 
+@Provider
+@PreMatching
+public class CORSResponseFilter implements ContainerResponseFilter {
+
+    private final static Logger log = Logger.getLogger(CORSResponseFilter.class.getName());
+ 
+    @Override
+	public void filter(ContainerRequestContext requestCtx, ContainerResponseContext responseCtx) throws IOException {
+        log.fine("Executing REST response filter");
+
+		MultivaluedMap<String, Object> headers = responseCtx.getHeaders();
+
+		headers.add("Access-Control-Allow-Origin", "*");
+		headers.add("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT, OPTIONS");			
+		headers.add("Access-Control-Allow-Headers", "X-Requested-With, Content-Type");
+		//responseCtx.getHeaders().add( "Access-Control-Allow-Credentials", "true" );
+	}
+
+}
diff --git a/todo-api-micro/src/main/java/com/redhat/training/rest/HostService.java b/todo-api-micro/src/main/java/com/redhat/training/rest/HostService.java
new file mode 100644
index 0000000..f62aac1
--- /dev/null
+++ b/todo-api-micro/src/main/java/com/redhat/training/rest/HostService.java
@@ -0,0 +1,28 @@
+package com.redhat.training.rest;
+
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+
+import javax.ejb.Stateless;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+
+import com.redhat.training.model.Host;
+
+@Stateless
+@Path("host")
+@Consumes(MediaType.APPLICATION_JSON)
+@Produces(MediaType.APPLICATION_JSON)
+public class HostService {
+	  
+    @GET
+    public Host getHostInfo() throws UnknownHostException {
+    	InetAddress address = InetAddress.getLocalHost();
+    	Host host = new Host(address.getHostAddress(), address.getHostName());
+    	return host;
+    }
+}
+
diff --git a/todo-api-micro/src/main/java/com/redhat/training/rest/ItemService.java b/todo-api-micro/src/main/java/com/redhat/training/rest/ItemService.java
new file mode 100644
index 0000000..bf0b030
--- /dev/null
+++ b/todo-api-micro/src/main/java/com/redhat/training/rest/ItemService.java
@@ -0,0 +1,97 @@
+package com.redhat.training.rest;
+
+import com.redhat.training.model.Item;
+import com.redhat.training.ui.PaginatedListWrapper;
+
+import javax.ejb.Stateless;
+import javax.persistence.EntityManager;
+import javax.persistence.PersistenceContext;
+import javax.persistence.Query;
+import javax.persistence.TypedQuery;
+import javax.ws.rs.*;
+import javax.ws.rs.core.Application;
+import javax.ws.rs.core.MediaType;
+
+import java.util.List;
+
+@Stateless
+@Path("items")
+@Consumes(MediaType.APPLICATION_JSON)
+@Produces(MediaType.APPLICATION_JSON)
+public class ItemService extends Application {
+	
+    @PersistenceContext
+    private EntityManager entityManager;
+
+    private Integer countItems() {
+        Query query = entityManager.createQuery("SELECT COUNT(i.id) FROM Item i");
+        return ((Long) query.getSingleResult()).intValue();
+    }
+
+    private List<Item> findItems(int startPosition, int maxResults, String sortFields, String sortDirections) {
+        TypedQuery<Item> query =
+                entityManager.createQuery("SELECT i FROM Item i ORDER BY i." + sortFields + " " + sortDirections, 
+                		Item.class);
+        query.setFirstResult(startPosition);
+        query.setMaxResults(maxResults);
+        return query.getResultList();
+    }
+
+    private PaginatedListWrapper findItems(PaginatedListWrapper wrapper) {
+        wrapper.setTotalResults(countItems());
+        int start = (wrapper.getCurrentPage() - 1) * wrapper.getPageSize();
+        wrapper.setList(findItems(start,
+                                    wrapper.getPageSize(),
+                                    wrapper.getSortFields(),
+                                    wrapper.getSortDirections()));
+        return wrapper;
+    }
+
+    @GET
+    @Produces(MediaType.APPLICATION_JSON)
+    public PaginatedListWrapper listItems(@DefaultValue("1")
+                                            @QueryParam("page")
+                                            Integer page,
+                                            @DefaultValue("id")
+                                            @QueryParam("sortFields")
+                                            String sortFields,
+                                            @DefaultValue("asc")
+                                            @QueryParam("sortDirections")
+                                            String sortDirections) {
+        PaginatedListWrapper paginatedListWrapper = new PaginatedListWrapper();
+        paginatedListWrapper.setCurrentPage(page);
+        paginatedListWrapper.setSortFields(sortFields);
+        paginatedListWrapper.setSortDirections(sortDirections);
+        paginatedListWrapper.setPageSize(10);
+        return findItems(paginatedListWrapper);
+    }
+
+    @GET
+    @Path("{id}")
+    public Item getitem(@PathParam("id") Long id) {
+        return entityManager.find(Item.class, id);
+    }
+
+    @POST
+    public Item saveItem(Item item) {
+        if (item.getId() == null) {
+            Item itemToSave = new Item();
+            itemToSave.setDescription(item.getDescription());
+            itemToSave.setDone(item.isDone());
+            entityManager.persist(item);
+        } else {
+            Item itemToUpdate = getitem(item.getId());
+            itemToUpdate.setDescription(item.getDescription());
+            itemToUpdate.setDone(item.isDone());
+            item = entityManager.merge(itemToUpdate);
+        }
+
+        return item;
+    }
+
+    @DELETE
+    @Path("{id}")
+    public void deleteItem(@PathParam("id") Long id) {
+        entityManager.remove(getitem(id));
+    }
+}
diff --git a/todo-api-micro/src/main/java/com/redhat/training/rest/RestApplication.java b/todo-api-micro/src/main/java/com/redhat/training/rest/RestApplication.java
new file mode 100644
index 0000000..d6aa93a
--- /dev/null
+++ b/todo-api-micro/src/main/java/com/redhat/training/rest/RestApplication.java
@@ -0,0 +1,8 @@
+package com.redhat.training.rest;
+
+import javax.ws.rs.ApplicationPath;
+import javax.ws.rs.core.Application;
+
+@ApplicationPath("/todo/api")
+public class RestApplication extends Application {
+}
diff --git a/todo-api-micro/src/main/java/com/redhat/training/ui/PaginatedListWrapper.java b/todo-api-micro/src/main/java/com/redhat/training/ui/PaginatedListWrapper.java
new file mode 100644
index 0000000..7eaeb51
--- /dev/null
+++ b/todo-api-micro/src/main/java/com/redhat/training/ui/PaginatedListWrapper.java
@@ -0,0 +1,72 @@
+package com.redhat.training.ui;
+
+import com.redhat.training.model.Item;
+
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+
+import java.io.Serializable;
+import java.util.List;
+
+@XmlRootElement
+public class PaginatedListWrapper implements Serializable {
+
+	private static final long serialVersionUID = 1L;
+	
+	private Integer currentPage;
+    private Integer pageSize;
+    private Integer totalResults;
+
+    private String sortFields;
+    private String sortDirections;
+    @XmlElement
+    private List<Item> list;
+
+    public Integer getCurrentPage() {
+        return currentPage;
+    }
+
+    public void setCurrentPage(Integer currentPage) {
+        this.currentPage = currentPage;
+    }
+
+    public Integer getPageSize() {
+        return pageSize;
+    }
+
+    public void setPageSize(Integer pageSize) {
+        this.pageSize = pageSize;
+    }
+
+    public Integer getTotalResults() {
+        return totalResults;
+    }
+
+    public void setTotalResults(Integer totalResults) {
+        this.totalResults = totalResults;
+    }
+
+    public String getSortFields() {
+        return sortFields;
+    }
+
+    public void setSortFields(String sortFields) {
+        this.sortFields = sortFields;
+    }
+
+    public String getSortDirections() {
+        return sortDirections;
+    }
+
+    public void setSortDirections(String sortDirections) {
+        this.sortDirections = sortDirections;
+    }
+
+    public List<Item> getList() {
+        return list;
+    }
+
+    public void setList(List<Item> list) {
+        this.list = list;
+    }
+}
diff --git a/todo-api-micro/src/main/resources/META-INF/persistence.xml b/todo-api-micro/src/main/resources/META-INF/persistence.xml
new file mode 100644
index 0000000..acf40ff
--- /dev/null
+++ b/todo-api-micro/src/main/resources/META-INF/persistence.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<persistence version="2.1"
+             xmlns="http://xmlns.jcp.org/xml/ns/persistence"
+             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+             xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
+    <persistence-unit name="Items" transaction-type="JTA">
+        <jta-data-source>java:jboss/datasources/MySQLDS</jta-data-source>
+        <properties>
+            <property name="javax.persistence.schema-generation.database.action" value="none"/>
+            <property name="javax.persistence.schema-generation.create-source" value="script"/>
+            <property name="javax.persistence.schema-generation.drop-source" value="script"/>
+            <property name="javax.persistence.schema-generation.create-script-source" value="sql/create.sql"/>
+            <property name="javax.persistence.schema-generation.drop-script-source" value="sql/drop.sql"/>
+            <property name="javax.persistence.sql-load-script-source" value="sql/load.sql"/>
+            <property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5InnoDBDialect" />
+        </properties>
+    </persistence-unit>
+</persistence>
diff --git a/todo-api-micro/src/main/resources/modules/com/mysql/main/module.xml b/todo-api-micro/src/main/resources/modules/com/mysql/main/module.xml
new file mode 100644
index 0000000..6d88728
--- /dev/null
+++ b/todo-api-micro/src/main/resources/modules/com/mysql/main/module.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Copyright 2015 Red Hat, Inc. and/or its affiliates.
+  ~
+  ~ Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0
+  -->
+<module xmlns="urn:jboss:module:1.3" name="com.mysql">
+
+    <resources>
+        <artifact name="mysql:mysql-connector-java:6.0.6"/>
+    </resources>
+    <dependencies>
+        <module name="javax.api"/>
+        <module name="javax.transaction.api"/>
+    </dependencies>
+</module>
\ No newline at end of file
diff --git a/todo-api-micro/src/main/resources/project-defaults.yml b/todo-api-micro/src/main/resources/project-defaults.yml
new file mode 100644
index 0000000..16a4f1e
--- /dev/null
+++ b/todo-api-micro/src/main/resources/project-defaults.yml
@@ -0,0 +1,13 @@
+swarm:
+  datasources:
+    jdbc-drivers:
+      com.mysql:
+        driver-class-name: com.mysql.cj.jdbc.Driver
+        xa-datasource-class-name: com.mysql.jdbc.jdbc2.optional.MysqlXADataSource
+        driver-module-name: com.mysql
+    data-sources:
+      MySQLDS:
+        driver-name: com.mysql
+        connection-url: jdbc:mysql://${env.DATABASE_SVC_HOSTNAME}:3306/${env.DATABASE_NAME}
+        user-name: ${env.DATABASE_USER}
+        password: ${env.DATABASE_PASSWORD}
diff --git a/todo-api-micro/src/main/resources/sql/create.sql b/todo-api-micro/src/main/resources/sql/create.sql
new file mode 100644
index 0000000..6289f7c
--- /dev/null
+++ b/todo-api-micro/src/main/resources/sql/create.sql
@@ -0,0 +1 @@
+CREATE TABLE `Item` (`id` BIGINT not null auto_increment primary key, `description` VARCHAR(100), `done` BIT);
diff --git a/todo-api-micro/src/main/resources/sql/drop.sql b/todo-api-micro/src/main/resources/sql/drop.sql
new file mode 100644
index 0000000..35ef5b3
--- /dev/null
+++ b/todo-api-micro/src/main/resources/sql/drop.sql
@@ -0,0 +1 @@
+DROP TABLE `Item`;
diff --git a/todo-api-micro/src/main/resources/sql/load.sql b/todo-api-micro/src/main/resources/sql/load.sql
new file mode 100644
index 0000000..6dec667
--- /dev/null
+++ b/todo-api-micro/src/main/resources/sql/load.sql
@@ -0,0 +1,2 @@
+INSERT INTO `Item` (`id`,`description`,`done`) VALUES (1,'Pick up newspaper', 0);
+INSERT INTO `Item` (`id`,`description`,`done`) VALUES (2,'Buy groceries', 1);

--
Gitblit v1.9.3