Java EE Cloud application deployment with Amazon EC2

From Resin 4.0 Wiki

(Difference between revisions)
Jump to: navigation, search
 
(30 intermediate revisions by 2 users not shown)
Line 2: Line 2:
  
  
This tutorial is going to cover the basics of using Resin with Amazon Web Services for cloud deployment. If you are new to cloud computing and IaaS ([http:///en.wikipedia.org/wiki/Cloud_computing#Infrastructure Infrastructure as a Service]), follow along and you will soon be deploying Java web applications in the cloud. You wil create an EC2 instance. You will download and install Resin on Ubuntu on a local machine. You will install Resin on an Amazon Linux AMI instance (EC2 instance). You will use Roo to create a simple application and deploy it.
+
This tutorial is going to cover the basics of using the Resin Java application server with Amazon Web Services for cloud deployment. If you are new to cloud computing and IaaS ([http:///en.wikipedia.org/wiki/Cloud_computing#Infrastructure Infrastructure as a Service]), follow along and you will soon be deploying Java web applications in the cloud. You wil create an EC2 instance. You will download and install Resin on Ubuntu on a local machine. You will install Resin on an Amazon Linux AMI instance (EC2 instance).  
  
We use [http://www.springsource.org/spring-roo Roo because Spring] is fairly widely used, and Roo is a quick way to generate a sample app. Future tutorials will use other common Java tools as well as show you how to configure and manage a complete Resin cluster. Think of this as the first tutorial in a series of tutorials.
+
We use Eclipse to create a simple war file and then we deploy it to Amazon EC2. Future tutorials will use other common Java tools as well as show you how to configure and manage a complete Resin server cluster. Think of this as the first tutorial in a series of tutorials.
  
For this tutorial you will need Resin 4.0.24 or later.  Check back periodically because as we are going to expand the tutorial and improve Resin's support of cloud deployments. The Resin engineering team plans on improving cloud support continuously.
+
For this tutorial you will need Resin 4.0.27 or later.  Check back periodically because as we are going to expand the tutorial and improve Resin's support of cloud deployments. The Resin engineering team plans on improving cloud support continuously.
  
 
Many of the steps in this tutorial would be similar even if you were using [http://www.eucalyptus.com/ Eucalyptus],  [http://cloudstack.com/ CloudStack] with [http://cloudstack.org/download.html CloudBridge], [http://www.rightscale.com/products/plans-pricing/mycloud.php RightScale myCloud] or even [http://opennebula.org/documentation:rel3.0:ec2qcg OpenNebula] this guide should help you along as they all support the Amazon EC2 REST APIs. Also any cloud computing environment (private or public, on premises or hosted) will have similar characteristics. Thus even if you are using a private cloud using [http://www.openstack.org/ OpenStack] like [http://deliver.citrix.com/projectolympus Project Olympus], the principles will be the same. In fact even using remote servers deployed in a datacenter or virtualized servers with [http://www.citrix.com/English/ps2/products/subfeature.asp?contentID=2300456 Xen Server], [http://xen.org/products/cloudxen.html Xen Cloud] or [http://www.vmware.com/products/vsphere/overview.html VMWare vSphere] the steps will be very similar.
 
Many of the steps in this tutorial would be similar even if you were using [http://www.eucalyptus.com/ Eucalyptus],  [http://cloudstack.com/ CloudStack] with [http://cloudstack.org/download.html CloudBridge], [http://www.rightscale.com/products/plans-pricing/mycloud.php RightScale myCloud] or even [http://opennebula.org/documentation:rel3.0:ec2qcg OpenNebula] this guide should help you along as they all support the Amazon EC2 REST APIs. Also any cloud computing environment (private or public, on premises or hosted) will have similar characteristics. Thus even if you are using a private cloud using [http://www.openstack.org/ OpenStack] like [http://deliver.citrix.com/projectolympus Project Olympus], the principles will be the same. In fact even using remote servers deployed in a datacenter or virtualized servers with [http://www.citrix.com/English/ps2/products/subfeature.asp?contentID=2300456 Xen Server], [http://xen.org/products/cloudxen.html Xen Cloud] or [http://www.vmware.com/products/vsphere/overview.html VMWare vSphere] the steps will be very similar.
Line 13: Line 13:
 
For this tutorial we expect you are familiar with starting, and stopping Amazon WS instances. If you are not, go through this [http://docs.amazonwebservices.com/AWSEC2/latest/GettingStartedGuide/ tutorial from Amazon WS]. You will need an Amazon WS account. Amazon WS allows you to have [http://aws.amazon.com/free/ free tier so you can learn Amazon WS (EC2, S3, Elastic Load Balancer, Block Storage, SimpleDB,  Simple Queue Service, Simple Notification Service)].
 
For this tutorial we expect you are familiar with starting, and stopping Amazon WS instances. If you are not, go through this [http://docs.amazonwebservices.com/AWSEC2/latest/GettingStartedGuide/ tutorial from Amazon WS]. You will need an Amazon WS account. Amazon WS allows you to have [http://aws.amazon.com/free/ free tier so you can learn Amazon WS (EC2, S3, Elastic Load Balancer, Block Storage, SimpleDB,  Simple Queue Service, Simple Notification Service)].
  
 +
This tutorial will show how to install Resin and manage on CentOS/Amazon Linux/Red Hat Enterprise Linux as well as Ubuntu/Debian. The local development box for this tutorial is Ubuntu/Debian. The instance running in the cloud is Amazon Linux which is a fork of CentOS which is a clone of Red Hat Enterprise Linux. Thus even if you are not interested in Amazon
 +
cloud deployment, you might find this tutorial a good intro to Resin install and app deployment.
 +
 +
==Related Slide deck with screenshots, etc.==
 +
For those in a hurry, you might find the slides useful as an addition or replacement for the wiki tutorial. There is more detail in the wiki and background.
 +
 +
[http://www.slideshare.net/billdigman/resin-deployment-cloud-clustering-and-ec2-how-to-part-i Slideshare on Java EE Cloud Deployment with Resin].
  
 
==Fire up an Amazon Instance==
 
==Fire up an Amazon Instance==
 +
 +
  
 
Fire up an Amazon Instance using Amazon Linux (basically CentOS 5.4). Then [http://caucho.com/resin-4.0/changes/resin-4.0.24.xtp#RPM install Resin as follows using RPM]:
 
Fire up an Amazon Instance using Amazon Linux (basically CentOS 5.4). Then [http://caucho.com/resin-4.0/changes/resin-4.0.24.xtp#RPM install Resin as follows using RPM]:
 +
 +
  
 
<code> <pre>
 
<code> <pre>
  
 
$ sudo rpm --import http://caucho.com/download/rpm/RPM-GPG-KEY-caucho
 
$ sudo rpm --import http://caucho.com/download/rpm/RPM-GPG-KEY-caucho
$ sudo yum install http://caucho.com/download/rpm/4.0.24/x86_64/resin-pro-4.0.24-1.x86_64.rpm
+
$ sudo yum install http://caucho.com/download/rpm/4.0.27/x86_64/resin-pro-4.0.27-1.x86_64.rpm
  
 
</pre></code>
 
</pre></code>
  
 +
If the above steps confuses you, make sure you go through the Amazon EC2 tutorial and then return to this step ([http://docs.amazonwebservices.com/AWSEC2/latest/GettingStartedGuide/ tutorial from Amazon WS]).
  
==Install Resin on a Local Box==
+
If everything went well, then Resin should be installed. You can test this as follows:
 +
 
 +
<pre>
 +
$ resinctl status
 +
</pre>
 +
 
 +
'''Output'''
 +
 
 +
<pre>
 +
Resin/4.0.27 status for watchdog at 127.0.0.1:6600
 +
 
 +
watchdog:
 +
  watchdog-pid: 1455
 +
 
 +
server 'app-0' : ACTIVE
 +
  password: missing
 +
  watchdog-user: root
 +
  user: resin(resin)
 +
  root: /var/www
 +
  conf: /etc/resin/resin.xml
 +
  pid: 1570
 +
  uptime: 0 days 00h04
 +
</pre>
 +
 
 +
==Install Resin on a Local Box (Ubuntu)==
  
 
Install  
 
Install  
Line 42: Line 78:
  
 
<code> <pre>
 
<code> <pre>
apt-get update
+
$ sudo apt-get update
apt-get install resin-pro
+
$ sudo apt-get install resin-pro
 
</pre></code>
 
</pre></code>
  
Line 52: Line 88:
 
<code> <pre>
 
<code> <pre>
 
$ ls /etc/resin
 
$ ls /etc/resin
app-default.xml local.d resin.properties  resin.xml
+
app-default.xml     health.xml resin.properties
 +
cluster-default.xml resin-inf  resin.xml
  
$ ls /var/www/
+
 
 +
$ ls /var/www
 
doc  licenses  log  resin-data  watchdog-data  webapps
 
doc  licenses  log  resin-data  watchdog-data  webapps
  
Line 61: Line 99:
  
 
$ ls -l /usr/local/share/resin
 
$ ls -l /usr/local/share/resin
lrwxrwxrwx 1 root root 16 2011-11-18 09:03 /usr/local/share/resin -> resin-pro-4.0.24
+
lrwxrwxrwx 1 root root 16 2012-03-22 18:42 /usr/local/share/resin -> resin-pro-4.0.27
 +
 
  
 
</pre></code>
 
</pre></code>
Line 68: Line 107:
 
Also at this point, Resin should be running as well, and you can verify this with resinctl status:
 
Also at this point, Resin should be running as well, and you can verify this with resinctl status:
  
<code> <pre>
+
<pre>
 
$ resinctl status
 
$ resinctl status
Resin/4.0.24 status for watchdog at 127.0.0.1:6600
+
</pre>
 +
 
 +
'''Output'''
 +
 
 +
<pre>
 +
Resin/4.0.27 status for watchdog at 127.0.0.1:6600
  
 
watchdog:
 
watchdog:
   watchdog-pid: 7383
+
   watchdog-pid: 18597
  
 
server 'app-0' : ACTIVE
 
server 'app-0' : ACTIVE
Line 81: Line 125:
 
   root: /var/www
 
   root: /var/www
 
   conf: /etc/resin/resin.xml
 
   conf: /etc/resin/resin.xml
   pid: 7590
+
   pid: 18692
   uptime: 0 days 00h19
+
   uptime: 0 days 00h13
  
</pre></code>
+
</pre>
  
== Install Maven 3 (Optional, for Roo example) ==
+
== Create a simple war file to test deployment with ==
  
If you already have a test .war file, you can skip to the deploy section and deploy your own war.
+
If you already have a war file that you want to deploy, then you can skip this section.
  
Install maven. Maven is not in the public Ubuntu repository.
+
[http://www.eclipse.org/downloads/packages/eclipse-ide-java-ee-developers/indigosr2 Use Eclipse for Java EE Indigo or higher].
  
<code><pre>
 
$ sudo add-apt-repository "deb http://build.discursive.com/apt/ lucid main"
 
$ sudo apt-get update
 
$ sudo apt-get install maven
 
</pre></code>
 
  
Create a symbolic link:
 
<code><pre>
 
$ sudo ln -s /usr/local/maven/bin/mvn /usr/local/bin/mvn
 
</pre></code>
 
  
 +
Using Eclipse Indigo
  
== Install Spring Roo (Optional) ==
+
# Go to File menu -> New Project -> Dynamic Web Project
 +
# In New Dynamic Web Project Dialog-> New Runtime...
 +
# In New Runtime Dialog -> Download Additional Server Adapters -> Select Resin (Java EE Web Profile) 4.0.24
 +
# (Click Next and Ok until it installs Resin runtime)
 +
# (Eclipse needs to restart)
 +
# File -> New Project -> Dynamic Web Project
 +
# In New Dynamic Web Project Dialog-> New Runtime...->Select Resin->Check create local server checkbox
 +
# Step 2 of New Runtime...->Click Download and Install
 +
# Fill out project name etc. (hello).
 +
# (Click Next and Ok until you are done)
  
If you already have a test .war file, you can skip to the deploy section and deploy your own war.
 
  
[http://static.springsource.org/spring-roo/reference/html/intro.html#intro-installation Download and install Spring Roo using directions at the Spring Roo site].
+
After the project is setup, do the following:
  
This is how I install roo:
+
File->New->Servlet (Name the new Servlet example.HelloWorld)
  
<code><pre>
+
Modify the class so it looks like this:
$ unzip spring-roo-1.2.0.RC1.zip
+
$ sudo mv spring-roo-1.2.0.RC1 /usr/local/share/
+
$ sudo ln -s /usr/local/share/spring-roo-1.2.0.RC1/ /usr/local/share/spring-roo
+
$ sudo ln -s /usr/local/share/spring-roo/bin/roo.sh /usr/bin/roo
+
</pre></code>
+
  
At the roo prompt, type hint.
+
<pre>
 +
package example;
  
<code><pre>
+
import java.io.IOException;
 +
import javax.servlet.ServletException;
 +
import javax.servlet.annotation.WebServlet;
 +
import javax.servlet.http.HttpServlet;
 +
import javax.servlet.http.HttpServletRequest;
 +
import javax.servlet.http.HttpServletResponse;
  
$ roo
+
@WebServlet("/hello")
    ____  ____  ____ 
+
public class HelloWorld extends HttpServlet {
  / __ \/ __ \/ __ \
+
  / /_/ / / / / / / /
+
/ _, _/ /_/ / /_/ / 
+
/_/ |_|\____/\____/    1.2.0.RC1 [rev dcaa483]
+
  
 +
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
 +
response.getWriter().print("HELLO WORLD!");
 +
}
  
Welcome to Spring Roo. For assistance press TAB or type "hint" then hit ENTER.
 
...
 
roo> hint
 
  
..
+
}
 +
</pre>
  
</pre></code>
+
Use Eclipse to Export the project as a war file.
  
Hint should always let you know what you might want to do next. Please feel free to read the Roo docs for details or just follow along and read the Roo docs later.
 
  
Create the project, this generates maven project files and Spring starter project.
+
# Right click project
 +
# Select Export->War menu
  
<code><pre>
+
Save file as hello.war.
  
roo> project --topLevelPackage com.example.blog
 
  
Created ROOT/pom.xml
+
== Deploy locally and test ==
Created SRC_MAIN_RESOURCES
+
Created SRC_MAIN_RESOURCES/log4j.properties
+
Created SPRING_CONFIG_ROOT
+
Created SPRING_CONFIG_ROOT/applicationContext.xml
+
  
</pre></code>
+
Deploy the example Servlet app with Resin.
 
+
Next setup the database and JPA, keep it simple to minimize the amount of things we need to configure later.
+
  
 
<code><pre>
 
<code><pre>
  
roo> jpa setup --database H2_IN_MEMORY --provider HIBERNATE
+
$ resinctl deploy hello.war
 +
 
 +
Deployed production/webapp/default/hello from hello.war to hmux://127.0.0.1:6800
  
Created SPRING_CONFIG_ROOT/database.properties
 
Updated SPRING_CONFIG_ROOT/applicationContext.xml
 
Created SRC_MAIN_RESOURCES/META-INF/persistence.xml
 
Updated ROOT/pom.xml [added dependencies com.h2database:h2:1.3.161, org.hibernate:hibernate-core:3.6.8.Final, ...]
 
  
 
</pre></code>
 
</pre></code>
  
Create a entity class called blog.
+
 
 +
You can see if the app was actually deployed:
  
 
<code><pre>
 
<code><pre>
 +
$ resinctl deploy-list
  
roo> entity jpa --class ~.domain.Blog
+
production/webapp/default/hello
Created SRC_MAIN_JAVA/com/example/blog/domain
+
Created SRC_MAIN_JAVA/com/example/blog/domain/Blog.java
+
Created SRC_MAIN_JAVA/com/example/blog/domain/Blog_Roo_Configurable.aj
+
Created SRC_MAIN_JAVA/com/example/blog/domain/Blog_Roo_Jpa_ActiveRecord.aj
+
Created SRC_MAIN_JAVA/com/example/blog/domain/Blog_Roo_ToString.aj
+
Created SRC_MAIN_JAVA/com/example/blog/domain/Blog_Roo_Jpa_Entity.aj
+
 
+
 
</pre></code>
 
</pre></code>
  
 +
Now you should be able to load the Hello world example.
  
Add two fields to the Blog class.
+
http://localhost:8080/hello/hello
  
<code><pre>
 
~.domain.Blog roo> field string --fieldName title
 
Updated SRC_MAIN_JAVA/com/example/blog/domain/Blog.java
 
Created SRC_MAIN_JAVA/com/example/blog/domain/Blog_Roo_JavaBean.aj
 
  
~.domain.Blog roo> field string --fieldName message
+
==Create an Elastic IP and assign it to your Amazon WS Linux instance==
Updated SRC_MAIN_JAVA/com/example/blog/domain/Blog.java
+
Updated SRC_MAIN_JAVA/com/example/blog/domain/Blog_Roo_JavaBean.aj
+
</pre></code>
+
  
Create the web tier
+
'''Background on Elastic IP'''
<code><pre>
+
Amazon EC2 instances are assigned two IP addresses at launch: a private (RFC 1918) address and a public address. The public address is mapped to the private IP address through Network Address Translation ([http://en.wikipedia.org/wiki/Network_address_translation NAT]). Every time you start or restart an instance, it gets new public and private addresses.
~.domain.Blog roo> web mvc setup
+
Created ROOT/src/main/webapp/WEB-INF/spring
+
Created ROOT/src/main/webapp/WEB-INF/spring/webmvc-config.xml
+
Created ROOT/src/main/webapp/WEB-INF/web.xml
+
...
+
Updated ROOT/src/main/webapp/WEB-INF/web.xml
+
Updated ROOT/pom.xml [added dependencies org.springframework:spring-webmvc:${spring.version}, ...]
+
Updated SRC_MAIN_WEBAPP/WEB-INF/views/footer.jspx
+
</pre></code>
+
  
 +
Amazon EC2 provides a service called Elastic IP addresses. Elastic IP addresses are static IP addresses. Elastic IP addresses are associated with your account, not a specific instances.
 +
You can associate an Elastic IP address with an instance. It is good to associate your instance with an IP address so you can direct your calls to that instance when deploying an application.
  
Generate the web tier.  
+
If you are not familiar with Elastic IPs, read the Amazon documentation on Elastic IP [http://docs.amazonwebservices.com/AWSEC2/latest/UserGuide/using-instance-addressing.html#using-instance-addressing-eips Elastic IP], just scroll down a bit and you can see how to create an Elastic IP from the Amazon WS Web Console.
  
<code><pre>
 
~.domain.Blog roo> web mvc all --package ~.web
 
  
Created SRC_MAIN_JAVA/com/example/blog/web
+
'''Directions'''
Created SRC_MAIN_JAVA/com/example/blog/web/BlogController.java
+
...
+
Created SRC_MAIN_WEBAPP/WEB-INF/views/blogs
+
Created SRC_MAIN_WEBAPP/WEB-INF/views/blogs/views.xml
+
Updated SRC_MAIN_WEBAPP/WEB-INF/views/blogs/views.xml
+
...
+
Updated SRC_MAIN_WEBAPP/WEB-INF/views/blogs/views.xml
+
...
+
Created SRC_MAIN_WEBAPP/WEB-INF/views/blogs/update.jspx
+
</pre></code>
+
  
Package our web app
+
Create an Elastic IP and assign it to the Amazon WS Linux instance using the [http://aws.amazon.com/console/ Amazon web console].
  
<code><pre>
+
I got this IP address.
roo> perform package
+
</pre></code>
+
  
 +
23.21.195.83
  
Exit roo.
+
In order to use it, you must assign it to our instance that has Resin.  
<code><pre>
+
In the console for managing Elastic IP address is an option under actions to assign the Elastic IP address to our instance.
roo> exit
+
</pre></code>
+
  
== Deploy locally and test ==
 
  
Deploy the example Roo app with Resin.
+
'''Warning'''
 +
Remember after you restart the server, you need to reassign it
 +
the Amazon Elastic IP. This means go to the console. Find the list of
 +
Elastic IPs. Select the one you want. Click the Associate Address
 +
button and pick the instance ID of the server that has Resin.
 +
Every time an instance restarts it forgets its IP address unless you reassign it.
  
<code><pre>
 
$ resinctl deploy target/blog-0.1.0.BUILD-SNAPSHOT.war -name blog
 
  
Deployed production/webapp/default/blog from target/blog-0.1.0.BUILD-SNAPSHOT.war to hmux://127.0.0.1:6800
+
==Create password for your Amazon Cloud instance==
  
</pre></code>
 
  
 +
<pre>
 +
$ resinctl generate-password -user admin -password mypassword
  
You can see if the app was actually deployed:
 
  
<code><pre>
+
</pre>
$ resinctl deploy-list
+
  
production/webapp/default/blog
+
'''Output'''
</pre></code>
+
<pre>
 +
admin_user : admin
 +
admin_password : {SSHA}somerealpasswordNv3IzMO0GlqNmzk3J
 +
</pre>
  
Now you should be able to load the Roo blog example.
+
==Create a properties file and put it into user-data of Amazon AMI==
  
http://localhost:8080/blog/
+
Create a file that looks like this:
  
  
==Create an Elastic IP and assign it to your Amazon WS Linux instance==
+
<code><pre>
 +
https        : 8443
 +
admin_user : admin
 +
admin_password : {SSHA}UaNyLiyzU1kepY7OSayrtdVGZf5/XJCE
 +
web_admin_enable : true
 +
remote_cli_enable : true
 +
web_admin_external : true
 +
</pre></code>
  
Create an Elastic IP and assign it to the Amazon WS Linux instance using the [http://aws.amazon.com/console/ Amazon web console].
 
  
I got this IP address.
 
203.0.113.26
 
  
  
==Create password==
+
To put the above in the user-data of that instance, you typically need
 +
to stop the instance from the Amazon EC2 console or command line. Then from the
 +
Amazon Management Console, select the instance in the instances list,
 +
then select the action "View/Change User Data" and add the contents
 +
above. In a later lesson, we show you how to do this from the command
 +
line.
  
 +
'''Reminder Associate with Elastic IP after restarting instance'''
 +
Remember after you restart the server, you need to reassign it
 +
the Amazon Elastic IP. This means go to the console. Find the list of
 +
Elastic IPs. Select the one you want. Click the Associate Address
 +
button and pick the instance ID of the server that has Resin.
  
<code><pre>
+
After you restart the Amazon instance, look at its [http://docs.amazonwebservices.com/AWSEC2/latest/UserGuide/using-network-security.html security group] and make sure the following inbound ports are open up.
$ resinctl generate-password -user admin -password roofoo
+
  
admin_user : admin
+
It should have the following
admin_password : {SSHA}BGBKQdCr0a5orH99eqIFwR/fffffffff
+
  
</pre></code>
+
InBound Port (Scheme) Source
  
==Create a properties file and put it into user-data of Amazon AMI==
+
<table>
 +
<tr><td>22 (SSH)</td> <td>0.0.0.0/0</td></tr>
 +
<tr><td>80 (HTTP)</td> <td> 0.0.0.0/0</td></tr>
 +
<tr><td>443 (HTTPS)</td> <td> 0.0.0.0/0</td></tr>
 +
<tr><td>8080 (HTTP*)</td> <td> 0.0.0.0/0</td></tr>
 +
<tr><td>8443 (HTTPS*)</td> <td> 0.0.0.0/0</td></tr>
 +
<tr><td>6800-6899</td> <td> sg-47yourSGGroupId</td></tr>
 +
</table>
  
[http://caucho.com/resin-4.0/changes/resin-4.0.24.xtp#resinproperties Resin properties].
+
When you setup a security in Amazon WS, it is given a name.  
 +
If you are later going to turn on clustering, you need to open up ports 6800-6899 to
 +
your own security group. Replace sg-47yourSGGroupId with you actual security group id.
  
  
<code><pre>
+
=Create ec2.xml file=
log_level    : info
+
dev_mode      : true
+
resin_doc    : true
+
  
app_tier      : 127.0.0.1
+
With Resin 4.0.27 and above you can configure additional config files like mycustom.xml and drop them
web_tier      :
+
under /etc/resin/resin-inf/mycustom.xml, and these XML files get picked up by Resin and
cache_tier    :
+
become part of the Resin configuration. This was added to make configuration simpler for cloud deployments.
  
setuid_user  : www-data
 
setuid_group  : www-data
 
  
http          : 8080
+
'''Background'''
https        : 8443
+
  
admin_user : admin
+
The actual directive that looks for these additional xml files is in
admin_password : {SSHA}BGBKQdCr0a5orH99eqIFwR/ffffffff
+
/etc/resin/cluster-default.xml which gets included by /etc/resin/resin.xml.
admin_external : true
+
admin_remote_enable : true
+
session_store : true
+
  
</pre></code>
+
'''/etc/resin/cluster-default.xml'''
 +
<pre>
 +
...
 +
<resin:import fileset="${__DIR__}/resin-inf/**/*.xml"/>
 +
...
 +
</pre>
  
 +
The above is why you can define xml files into /etc/resin/resin-inf/ and they get picked up by Resin.
  
Create an amazon.xml
 
  
 +
'''Directions'''
  
<code><pre>
+
Create the file that is listed below called ec2.xml and put it into /etc/resin/app-inf/ec2.xml on the Amazon instance.
 +
 
 +
<pre>
 
<resin xmlns="http://caucho.com/ns/resin"
 
<resin xmlns="http://caucho.com/ns/resin"
 
       xmlns:resin="urn:java:com.caucho.resin">
 
       xmlns:resin="urn:java:com.caucho.resin">
  
 
   <resin:properties path="http://169.254.169.254/latest/user-data"
 
   <resin:properties path="http://169.254.169.254/latest/user-data"
                     optional="true"/>
+
                     optional="true" recover="true"/>
  
 
</resin>
 
</resin>
</pre></code>
+
</pre>
  
 +
The IP address (http://169.254.169.254) is a meta address that Xen, and Amazon EC2 use to
 +
configure per instance data about the instance you are running. The above is configured to read properties out of this user data location.
  
Log into Amazon AMI instance and add the above to /etc/resin/local.d/amazon.xml.
 
  
 +
Log into Amazon AMI instance and add the above to /etc/resin/app-inf/ec2.xml.
  
<code><pre>
 
$ ssh -i resin2.pem ec2-user@203.0.113.26
 
$ sudo nano /etc/resin/local.d/amazon.xml
 
</pre></code>
 
  
From your local machine execute this command:
+
<pre>
 +
$ ssh -i resin2.pem ec2-user@23.21.195.83
 +
$ sudo mkdir /etc/resin/resin-inf
 +
$ sudo nano /etc/resin/resin-inf/ec2.xml
 +
</pre>
 +
 
 +
XML files that you add to /etc/resin/app-inf/ get added to the resin
 +
app cluster configuration configuration. This allows you add just the additional config you need
 +
without changing the rest on the resin configuration.
 +
 
 +
'''Remember''': the Amazon security group that this instance needs has to open up
 +
the following ports 8080, and 8443, 80, and 443.
 +
 
 +
 
 +
To test out our changes, from your local development machine execute this command:
  
  
 
<code><pre>
 
<code><pre>
$ resinctl deploy target/blog-0.1.0.BUILD-SNAPSHOT.war -name blog -address 203.0.113.26 -port 8080 -user admin -password roofoo
+
$ resinctl deploy --address 23.21.195.83 --port 8080 --user
 +
admin --password mypassword  hellow.war
 
</pre></code>
 
</pre></code>
 +
 +
You can see if the deploy worked by do the following:
 +
 +
<pre>
 +
 +
$ resinctl deploy-list --address 23.21.195.83 --port 8080 --user admin --password roofoo
 +
 +
production/webapp/default/blog
 +
</pre>
 +
  
  
 
Now it works in the cloud:
 
Now it works in the cloud:
  
http://203.0.113.26:8080/blog/
+
http://23.21.195.83:8080/hello/hello
 +
 
 +
Now you have created an single box and deployed to it.
 +
 
 +
To undeploy this instance,
 +
 
 +
<pre>
 +
$ resinctl deploy-list --address 23.21.195.83 --port 8080 --user admin --password roofoo
  
 +
</pre>
  
Next step learn how to spin up instances with eucatools [[Resin Cloud deployment with Amazon WS EC2 and Euca Tools]].
+
In the next example, we will show you how to deploy another box, cluster it with this instance that you just setup, and then put an Amazon Load Balancer in front of it.
  
 +
[[EC2:_Java_EE_Cloud_Deployment,_Clustering,_Session_Replication,_and_Setting_up_Amazon_Load_Balancer | Java EE EC2 Deployment, Setting up Cluster, Session Replication and Amazon Load Balancer]]
  
Next step learn how to use MySQL setup with Resin and Amazon RDS [[Resin MySQL and RDS setup with Amazon RDS]].
 
  
 +
== Cookbooks and Tutorials ==
  
[[Resin Cloud Deployment Reference]]
+
* [[Building a simple listing in JSP]]: covers model 2, Servlets, JSP intro.
 +
* [[Java EE Servlet tutorial : Adding create, update and delete to the bookstore listing]]: covers more interactions.
 +
* [[Java EE Servlet tutorial : Using JSPs to create header, footer area, formatting, and basic CSS for bookstore]].
 +
* [[Java EE Servlet tutorial : Adding MySQL and JDBC to bookstore example]].
 +
* [[Java EE Servlet tutorial : Adding validation and JSP tag files to bookstore example]].
 +
* [[Java EE Servlet tutorial : Adding I18N support to bookstore example]].
 +
* [[Java EE Servlet tutorial : Load testing and health monitoring using bookstore example]].
 +
* [[Java EE Servlet tutorial : Setting up clustering and session replication]].
 +
* [[Java EE Servlet tutorial : Setting up security for bookstore example]].
 +
* [[Java EE Servlet tutorial : File uploads for bookstore example]].
 +
* [[Java EE Servlet tutorial : Using JPA for bookstore example]].
 +
* [[Java EE Servlet tutorial : Using JCache for bookstore example]].

Latest revision as of 00:00, 11 September 2012

Cookbook-48.pngCloud-48.png


This tutorial is going to cover the basics of using the Resin Java application server with Amazon Web Services for cloud deployment. If you are new to cloud computing and IaaS (Infrastructure as a Service), follow along and you will soon be deploying Java web applications in the cloud. You wil create an EC2 instance. You will download and install Resin on Ubuntu on a local machine. You will install Resin on an Amazon Linux AMI instance (EC2 instance).

We use Eclipse to create a simple war file and then we deploy it to Amazon EC2. Future tutorials will use other common Java tools as well as show you how to configure and manage a complete Resin server cluster. Think of this as the first tutorial in a series of tutorials.

For this tutorial you will need Resin 4.0.27 or later. Check back periodically because as we are going to expand the tutorial and improve Resin's support of cloud deployments. The Resin engineering team plans on improving cloud support continuously.

Many of the steps in this tutorial would be similar even if you were using Eucalyptus, CloudStack with CloudBridge, RightScale myCloud or even OpenNebula this guide should help you along as they all support the Amazon EC2 REST APIs. Also any cloud computing environment (private or public, on premises or hosted) will have similar characteristics. Thus even if you are using a private cloud using OpenStack like Project Olympus, the principles will be the same. In fact even using remote servers deployed in a datacenter or virtualized servers with Xen Server, Xen Cloud or VMWare vSphere the steps will be very similar.


For this tutorial we expect you are familiar with starting, and stopping Amazon WS instances. If you are not, go through this tutorial from Amazon WS. You will need an Amazon WS account. Amazon WS allows you to have free tier so you can learn Amazon WS (EC2, S3, Elastic Load Balancer, Block Storage, SimpleDB, Simple Queue Service, Simple Notification Service).

This tutorial will show how to install Resin and manage on CentOS/Amazon Linux/Red Hat Enterprise Linux as well as Ubuntu/Debian. The local development box for this tutorial is Ubuntu/Debian. The instance running in the cloud is Amazon Linux which is a fork of CentOS which is a clone of Red Hat Enterprise Linux. Thus even if you are not interested in Amazon cloud deployment, you might find this tutorial a good intro to Resin install and app deployment.

Contents

Related Slide deck with screenshots, etc.

For those in a hurry, you might find the slides useful as an addition or replacement for the wiki tutorial. There is more detail in the wiki and background.

Slideshare on Java EE Cloud Deployment with Resin.

Fire up an Amazon Instance

Fire up an Amazon Instance using Amazon Linux (basically CentOS 5.4). Then install Resin as follows using RPM:



$ sudo rpm --import http://caucho.com/download/rpm/RPM-GPG-KEY-caucho
$ sudo yum install http://caucho.com/download/rpm/4.0.27/x86_64/resin-pro-4.0.27-1.x86_64.rpm

If the above steps confuses you, make sure you go through the Amazon EC2 tutorial and then return to this step (tutorial from Amazon WS).

If everything went well, then Resin should be installed. You can test this as follows:

$ resinctl status

Output

Resin/4.0.27 status for watchdog at 127.0.0.1:6600

watchdog:
  watchdog-pid: 1455

server 'app-0' : ACTIVE
  password: missing
  watchdog-user: root
  user: resin(resin)
  root: /var/www
  conf: /etc/resin/resin.xml
  pid: 1570
  uptime: 0 days 00h04

Install Resin on a Local Box (Ubuntu)

Install Resin locally so you test locally and deploy. Feel free to install it on any supported OS.


Add Caucho's Debian repository to your system's repositories to use automated update tools like Synaptic and apt-get. To do this, add the following line to your /etc/apt/sources.list

deb http://caucho.com/download/debian unstable multiverse


Then install Resin as follows:

$ sudo apt-get update
$ sudo apt-get install resin-pro

It is a good idea to make sure the version you install on Amazon AMI matches the version you install locally.

You can see that Resin is installed as follows:

$ ls /etc/resin
app-default.xml      health.xml  resin.properties
cluster-default.xml  resin-inf   resin.xml


$ ls /var/www
doc  licenses  log  resin-data  watchdog-data  webapps

$ ls /etc/init.d/resin
/etc/init.d/resin

$ ls -l /usr/local/share/resin
lrwxrwxrwx 1 root root 16 2012-03-22 18:42 /usr/local/share/resin -> resin-pro-4.0.27



Also at this point, Resin should be running as well, and you can verify this with resinctl status:

$ resinctl status

Output

Resin/4.0.27 status for watchdog at 127.0.0.1:6600

watchdog:
  watchdog-pid: 18597

server 'app-0' : ACTIVE
  password: missing
  watchdog-user: root
  user: www-data(www-data)
  root: /var/www
  conf: /etc/resin/resin.xml
  pid: 18692
  uptime: 0 days 00h13

Create a simple war file to test deployment with

If you already have a war file that you want to deploy, then you can skip this section.

Use Eclipse for Java EE Indigo or higher.


Using Eclipse Indigo

  1. Go to File menu -> New Project -> Dynamic Web Project
  2. In New Dynamic Web Project Dialog-> New Runtime...
  3. In New Runtime Dialog -> Download Additional Server Adapters -> Select Resin (Java EE Web Profile) 4.0.24
  4. (Click Next and Ok until it installs Resin runtime)
  5. (Eclipse needs to restart)
  6. File -> New Project -> Dynamic Web Project
  7. In New Dynamic Web Project Dialog-> New Runtime...->Select Resin->Check create local server checkbox
  8. Step 2 of New Runtime...->Click Download and Install
  9. Fill out project name etc. (hello).
  10. (Click Next and Ok until you are done)


After the project is setup, do the following:

File->New->Servlet (Name the new Servlet example.HelloWorld)

Modify the class so it looks like this:

package example;

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet("/hello")
public class HelloWorld extends HttpServlet {

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		response.getWriter().print("HELLO WORLD!");
	}


}

Use Eclipse to Export the project as a war file.


  1. Right click project
  2. Select Export->War menu

Save file as hello.war.


Deploy locally and test

Deploy the example Servlet app with Resin.


$ resinctl deploy hello.war

Deployed production/webapp/default/hello from hello.war to hmux://127.0.0.1:6800



You can see if the app was actually deployed:

$ resinctl deploy-list

production/webapp/default/hello

Now you should be able to load the Hello world example.

http://localhost:8080/hello/hello


Create an Elastic IP and assign it to your Amazon WS Linux instance

Background on Elastic IP Amazon EC2 instances are assigned two IP addresses at launch: a private (RFC 1918) address and a public address. The public address is mapped to the private IP address through Network Address Translation (NAT). Every time you start or restart an instance, it gets new public and private addresses.

Amazon EC2 provides a service called Elastic IP addresses. Elastic IP addresses are static IP addresses. Elastic IP addresses are associated with your account, not a specific instances. You can associate an Elastic IP address with an instance. It is good to associate your instance with an IP address so you can direct your calls to that instance when deploying an application.

If you are not familiar with Elastic IPs, read the Amazon documentation on Elastic IP Elastic IP, just scroll down a bit and you can see how to create an Elastic IP from the Amazon WS Web Console.


Directions

Create an Elastic IP and assign it to the Amazon WS Linux instance using the Amazon web console.

I got this IP address.

23.21.195.83

In order to use it, you must assign it to our instance that has Resin. In the console for managing Elastic IP address is an option under actions to assign the Elastic IP address to our instance.


Warning Remember after you restart the server, you need to reassign it the Amazon Elastic IP. This means go to the console. Find the list of Elastic IPs. Select the one you want. Click the Associate Address button and pick the instance ID of the server that has Resin. Every time an instance restarts it forgets its IP address unless you reassign it.


Create password for your Amazon Cloud instance

$ resinctl generate-password -user admin -password mypassword


Output

admin_user : admin
admin_password : {SSHA}somerealpasswordNv3IzMO0GlqNmzk3J

Create a properties file and put it into user-data of Amazon AMI

Create a file that looks like this:


https         : 8443
admin_user : admin
admin_password : {SSHA}UaNyLiyzU1kepY7OSayrtdVGZf5/XJCE
web_admin_enable : true
remote_cli_enable : true
web_admin_external : true



To put the above in the user-data of that instance, you typically need to stop the instance from the Amazon EC2 console or command line. Then from the Amazon Management Console, select the instance in the instances list, then select the action "View/Change User Data" and add the contents above. In a later lesson, we show you how to do this from the command line.

Reminder Associate with Elastic IP after restarting instance Remember after you restart the server, you need to reassign it the Amazon Elastic IP. This means go to the console. Find the list of Elastic IPs. Select the one you want. Click the Associate Address button and pick the instance ID of the server that has Resin.

After you restart the Amazon instance, look at its security group and make sure the following inbound ports are open up.

It should have the following

InBound Port (Scheme) Source

22 (SSH) 0.0.0.0/0
80 (HTTP) 0.0.0.0/0
443 (HTTPS) 0.0.0.0/0
8080 (HTTP*) 0.0.0.0/0
8443 (HTTPS*) 0.0.0.0/0
6800-6899 sg-47yourSGGroupId

When you setup a security in Amazon WS, it is given a name. If you are later going to turn on clustering, you need to open up ports 6800-6899 to your own security group. Replace sg-47yourSGGroupId with you actual security group id.


Create ec2.xml file

With Resin 4.0.27 and above you can configure additional config files like mycustom.xml and drop them under /etc/resin/resin-inf/mycustom.xml, and these XML files get picked up by Resin and become part of the Resin configuration. This was added to make configuration simpler for cloud deployments.


Background

The actual directive that looks for these additional xml files is in /etc/resin/cluster-default.xml which gets included by /etc/resin/resin.xml.

/etc/resin/cluster-default.xml

...
 <resin:import fileset="${__DIR__}/resin-inf/**/*.xml"/>
 ...

The above is why you can define xml files into /etc/resin/resin-inf/ and they get picked up by Resin.


Directions

Create the file that is listed below called ec2.xml and put it into /etc/resin/app-inf/ec2.xml on the Amazon instance.

<resin xmlns="http://caucho.com/ns/resin"
      xmlns:resin="urn:java:com.caucho.resin">

  <resin:properties path="http://169.254.169.254/latest/user-data"
                    optional="true" recover="true"/>

</resin>

The IP address (http://169.254.169.254) is a meta address that Xen, and Amazon EC2 use to configure per instance data about the instance you are running. The above is configured to read properties out of this user data location.


Log into Amazon AMI instance and add the above to /etc/resin/app-inf/ec2.xml.


$ ssh -i resin2.pem ec2-user@23.21.195.83 
$ sudo mkdir /etc/resin/resin-inf
$ sudo nano /etc/resin/resin-inf/ec2.xml

XML files that you add to /etc/resin/app-inf/ get added to the resin app cluster configuration configuration. This allows you add just the additional config you need without changing the rest on the resin configuration.

Remember: the Amazon security group that this instance needs has to open up the following ports 8080, and 8443, 80, and 443.


To test out our changes, from your local development machine execute this command:


$ resinctl deploy --address 23.21.195.83 --port 8080 --user
admin --password mypassword  hellow.war

You can see if the deploy worked by do the following:


$ resinctl deploy-list --address 23.21.195.83 --port 8080 --user admin --password roofoo

production/webapp/default/blog


Now it works in the cloud:

http://23.21.195.83:8080/hello/hello

Now you have created an single box and deployed to it.

To undeploy this instance,

$ resinctl deploy-list --address 23.21.195.83 --port 8080 --user admin --password roofoo

In the next example, we will show you how to deploy another box, cluster it with this instance that you just setup, and then put an Amazon Load Balancer in front of it.

Java EE EC2 Deployment, Setting up Cluster, Session Replication and Amazon Load Balancer


Cookbooks and Tutorials

Personal tools
TOOLBOX
LANGUAGES