|
| 1 | +:imagesdir: images |
| 2 | + |
1 | 3 | [[JavaEE7_PreBuilt_WAR]] |
2 | | -## Deploy Java EE 7 Application (Pre-Built WAR) |
| 4 | +## Deploy Java EE 7 Application |
3 | 5 |
|
4 | 6 | https://github.com/javaee-samples/javaee7-hol[Java EE 7 Movieplex] is a standard multi-tier enterprise application that shows design patterns and anti-patterns for a typical Java EE 7 application. |
5 | 7 |
|
6 | 8 | .Java EE 7 Application Architecture |
7 | 9 | image::javaee7-hol.png[] |
8 | 10 |
|
| 11 | +This section explains how this application can be deployed in a Docker container using a pre-built WAR in two different ways: |
| 12 | + |
| 13 | +. Using in-memory database in WildFly |
| 14 | +. Using container linking to link WildFly and MySQL database |
| 15 | + |
| 16 | +And then it will cover how to test such applications. |
| 17 | + |
| 18 | +### Deploy Using Pre-Built WAR |
| 19 | + |
9 | 20 | Pull the Docker image that contains WildFly and pre-built Java EE 7 application WAR file as shown: |
10 | 21 |
|
11 | 22 | [source, text] |
@@ -47,3 +58,134 @@ CMD ["/opt/jboss/wildfly/bin/standalone.sh", "-c", "standalone-full.xml", "-b", |
47 | 58 | ---- |
48 | 59 | RUN curl -L https://github.com/javaee-samples/javaee7-hol/raw/master/solution/movieplex7-1.0-SNAPSHOT.war -o /opt/jboss/wildfly/standalone/deployments/movieplex7-1.0-SNAPSHOT.war |
49 | 60 | ---- |
| 61 | + |
| 62 | +### Deploy Using Container Linking |
| 63 | + |
| 64 | +<<JavaEE7_PreBuilt_WAR>> explained how to use an in-memory database with the application server. This gets you started rather quickly but becomes a bottleneck soon as the database is only in-memory. This means that any changes made to your schema and data are lost when the application server shuts down. In this case, you need to use a database server that resides outside the application server. For example, MySQL as the database server and WildFly as the application server. |
| 65 | + |
| 66 | +.Two Containers On Same Docker Host |
| 67 | +image::javaee7-hol-container-linking.png[] |
| 68 | + |
| 69 | +This section will show how https://docs.docker.com/userguide/dockerlinks/[Docker Container Linking] can be used to connect to a service running inside a Docker container via a network port. |
| 70 | + |
| 71 | +. Start MySQL server as: |
| 72 | ++ |
| 73 | +[source, text] |
| 74 | +---- |
| 75 | +docker run --name mysqldb -e MYSQL_USER=mysql -e MYSQL_PASSWORD=mysql -e MYSQL_DATABASE=sample -e MYSQL_ROOT_PASSWORD=supersecret -p 3306:3306 -d mysql |
| 76 | +---- |
| 77 | ++ |
| 78 | +`-e` define environment variables that are read by the database at startup and allow us to access the database with this user and password. |
| 79 | ++ |
| 80 | +. Start WildFly and deploy Java EE 7 application as: |
| 81 | ++ |
| 82 | +[source, text] |
| 83 | +---- |
| 84 | +docker run -it --name mywildfly --link mysqldb:db -p 8080:8080 arungupta/wildfly-mysql-javaee7 |
| 85 | +---- |
| 86 | ++ |
| 87 | +`--link` takes two parameters - first is name of the container we're linking to and second is the alias for the link name. |
| 88 | ++ |
| 89 | +.Container Linking |
| 90 | +[NOTE] |
| 91 | +=============================== |
| 92 | +Creating a link between two containers creates a conduit between a source container and a target container and securely transfer information about source container to target container. |
| 93 | + |
| 94 | +In our case, target container (WildFly) can see information about source container (MySQL). When containers are linked, information about a source container can be sent to a recipient container. This allows the recipient to see selected data describing aspects of the source container. For example, IP address of MySQL server is expoed at $DB_PORT_3306_TCP_ADDR and port of MySQL server is exposed at $DB_PORT_3306_TCP_PORT. These are then used to create the JDBC resource. |
| 95 | + |
| 96 | +See more about container communication on the Docker website https://docs.docker.com/userguide/dockerlinks/[Linking Containers Together] |
| 97 | +=============================== |
| 98 | ++ |
| 99 | +. See the output as: |
| 100 | ++ |
| 101 | +[source, text] |
| 102 | +---- |
| 103 | +> curl http://dockerhost:8080/employees/resources/employees |
| 104 | +<?xml version="1.0" encoding="UTF-8" standalone="yes"?><collection><employee><id>1</id><name>Penny</name></employee><employee><id>2</id><name>Sheldon</name></employee><employee><id>3</id><name>Amy</name></employee><employee><id>4</id><name>Leonard</name></employee><employee><id>5</id><name>Bernadette</name></employee><employee><id>6</id><name>Raj</name></employee><employee><id>7</id><name>Howard</name></employee><employee><id>8</id><name>Priya</name></employee></collection> |
| 105 | +---- |
| 106 | + |
| 107 | +### Test Java EE 7 Application |
| 108 | + |
| 109 | +Testing Java EE applications is a very important aspect. Especially when it comes to in-container tests, http://www.arquillian.org[JBoss Arquillian] is well known to make this very easy for Java EE application servers. Picking up where unit tests leave off, Arquillian handles all the plumbing of container management, deployment and framework initialization so you can focus on the task at hand, writing your tests. |
| 110 | + |
| 111 | +With Arquillian, you can use http://arquillian.org/modules/wildfly-arquillian-wildfly-remote-container-adapter/[WildFly remote container adapter] and connect to any WildFly instance running in a Docker container. But this wouldn't help with the Docker container lifycycle management. |
| 112 | + |
| 113 | +http://arquillian.org/modules/cube-extension/[Arquillian Cube], an extension of Arquillian, allows you to control the lifecycle of Docker images as part of the test lifecyle, either automatically or manually. This extension allows to start a Docker container with a server installed, deploy the required deployable file within it and execute Arquillian tests. |
| 114 | + |
| 115 | +The key point here is that if Docker is used as deployable platform in production, your tests are executed in a the same container as it will be in production, so your tests are even more real than before. |
| 116 | + |
| 117 | +. Check out the workspace: |
| 118 | ++ |
| 119 | +[source, text] |
| 120 | +---- |
| 121 | +git clone http://github.com/javaee-samples/javaee-arquillian-cube |
| 122 | +---- |
| 123 | ++ |
| 124 | +. Edit `src/test/resources/arquillian.xml` file and change the IP address specified in `serverUri` property value to point to your Docker host's IP. This can be found out as: |
| 125 | ++ |
| 126 | +[source, text] |
| 127 | +---- |
| 128 | +docker-machine ip lab |
| 129 | +---- |
| 130 | ++ |
| 131 | +. Run the tests as: |
| 132 | ++ |
| 133 | +[source, text] |
| 134 | +---- |
| 135 | +mvn test |
| 136 | +---- |
| 137 | ++ |
| 138 | +This will create a container using the image defined in `src/test/resources/wildfly/Dockerfile`. The container qualifier in `arquillian.xml` defines the directory name in `src/test/resources` directory. |
| 139 | ++ |
| 140 | +[NOTE] |
| 141 | +==== |
| 142 | +A pre-built image can be used by specifying: |
| 143 | + |
| 144 | + wildfly: |
| 145 | + image: jboss/wildfly |
| 146 | + |
| 147 | +instead of |
| 148 | + |
| 149 | + wildfly: |
| 150 | + buildImage: |
| 151 | + dockerfileLocation: src/test/resources/wildfly |
| 152 | +==== |
| 153 | ++ |
| 154 | +By default, the "`cube`" profile is activated and this includes all the required dependencies. |
| 155 | ++ |
| 156 | +The result is shown as: |
| 157 | ++ |
| 158 | +[source, text] |
| 159 | +---- |
| 160 | +Running org.javaee7.sample.PersonDatabaseTest |
| 161 | +Jun 16, 2015 9:23:04 AM org.jboss.arquillian.container.impl.MapObject populate |
| 162 | +WARNING: Configuration contain properties not supported by the backing object org.jboss.as.arquillian.container.remote.RemoteContainerConfiguration |
| 163 | +Unused property entries: {target=wildfly:8.1.0.Final:remote} |
| 164 | +Supported property names: [managementAddress, password, managementPort, managementProtocol, username] |
| 165 | +Jun 16, 2015 9:23:13 AM org.xnio.Xnio <clinit> |
| 166 | +INFO: XNIO version 3.2.0.Beta4 |
| 167 | +Jun 16, 2015 9:23:13 AM org.xnio.nio.NioXnio <clinit> |
| 168 | +INFO: XNIO NIO Implementation Version 3.2.0.Beta4 |
| 169 | +Jun 16, 2015 9:23:13 AM org.jboss.remoting3.EndpointImpl <clinit> |
| 170 | +INFO: JBoss Remoting version (unknown) |
| 171 | +Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 16.406 sec - in org.javaee7.sample.PersonDatabaseTest |
| 172 | +
|
| 173 | +Results : |
| 174 | +
|
| 175 | +Tests run: 1, Failures: 0, Errors: 0, Skipped: 0 |
| 176 | +
|
| 177 | +[INFO] ------------------------------------------------------------------------ |
| 178 | +[INFO] BUILD SUCCESS |
| 179 | +[INFO] ------------------------------------------------------------------------ |
| 180 | +---- |
| 181 | ++ |
| 182 | +. In `arquillian.xml`, add the following property: |
| 183 | ++ |
| 184 | +[source, xml] |
| 185 | +---- |
| 186 | +<property name="connectionMode">STARTORCONNECT</property> |
| 187 | +---- |
| 188 | ++ |
| 189 | +This bypasses the create/start Cube commands if a Docker Container with the same name is already running on the target system. |
| 190 | ++ |
| 191 | +This allows you to prestart the containers manually during development and just connect to them to avoid the extra cost of starting the Docker Containers for each test run. This assumes you are not changing the actual definition of the Docker Container itself. |
0 commit comments