Você está na página 1de 45

Tutorial:

Migrating a Spring Framework Java Application to Microsoft Windows Azure and Windows Azure SQL Database
TM

Windows Azure SQL Database Technical Article


Authors: Michael Ashby, Anders Westby, Logic 20/20

Technical Reviewers: Gregory Leake, Microsoft Corporation Published: October, 2013 Applies to: Windows Azure and Windows Azure SQL Database Download code: https://github.com/Logic2020Inc/spring-petclinic-mod Live Application running on Windows Azure: http://petclinic.cloudapp.net/ Summary: This guide is written for Java developers to demonstrate how to migrate a typical Java application to the Windows Azure cloud. While the tutorial focuses on a popular Spring Framework sample application, the Java PetClinic, the tutorial will introduce you to the Windows Azure Java SDK, Windows Azure Caching using memcached, Windows Azure Cloud Services, Windows Azure SQL Database, and a variety of other technologies that will be used in many other types of Java applications deployed on Windows Azure.

Copyright
The information contained in this document represents the current view of Microsoft Corporation on the issues discussed as of the date of publication. Because Microsoft must respond to changing market conditions, it should not be interpreted to be a commitment on the part of Microsoft, and Microsoft cannot guarantee the accuracy of any information presented after the date of publication. This white paper is for informational purposes only. MICROSOFT MAKES NO WARRANTIES, EXPRESS, IMPLIED, OR STATUTORY, AS TO THE INFORMATION IN THIS DOCUMENT. Complying with all applicable copyright laws is the responsibility of the user. Without limiting the rights under copyright, no part of this document may be reproduced, stored in, or introduced into a retrieval system, or transmitted in any form or by any means (electronic, mechanical, photocopying, recording, or otherwise), or for any purpose, without the express written permission of Microsoft Corporation. Microsoft may have patents, patent applications, trademarks, copyrights, or other intellectual property rights covering subject matter in this document. Except as expressly provided in any written license agreement from Microsoft, the furnishing of this document does not give you any license to these patents, trademarks, copyrights, or other intellectual property.

2011-2013 Microsoft Corporation. All rights reserved.

Microsoft, SQL Server, Windows Server, SharePoint, Excel are trademarks of the Microsoft group of companies.

All other trademarks are property of their respective owners.

October 11, 2013

Page 2

Contents
I. II. III. Executive Summary ......................................................................................................................................... 5 Windows Azure Cloud Services or Windows Azure Virtual Machines? .......................................................... 5 Spring Framework on the Windows Azure Platform ................................................................................... 6

About Windows Azure ........................................................................................................................................ 6 IV. Pet Clinic on Azure: High-Level Architecture ..................................................................................................... 7 Defining Key Windows Azure Services ................................................................................................................ 7 Windows Azure Worker Role .......................................................................................................................... 8 Windows Azure SQL Database ........................................................................................................................ 8 Windows Azure Cache Service ........................................................................................................................ 8 Typical Tiered Architecture of a Web Application .............................................................................................. 8 Spring Framework Pet Clinic on Windows Azure ................................................................................................ 9 Apache Tomcat 7.0 .......................................................................................................................................... 9 Spring Data JPA .............................................................................................................................................. 10 Memcached ................................................................................................................................................... 10 High-Level Windows Azure Application Lifecycle ............................................................................................. 11 Local Development ........................................................................................................................................ 12 Local Windows Azure Emulator Deployment ................................................................................................ 12 Windows Azure (Staging/Production) Deployment ...................................................................................... 12 V. Windows Azure Java Application Lifecycle: Prerequisites................................................................................ 12 VI. Windows Azure Java Application Lifecycle Development Environment Configuration Steps ........................ 13 Step 0: Install Spring Tool Suite ......................................................................................................................... 13 Step 1: Install the Windows Azure Plugin for Eclipse with Java ........................................................................ 13 Step 2: Download the Pet Clinic source files..................................................................................................... 14 Step 3: Import Pet Clinic into the Eclipse (STS) project workspace .................................................................. 14 Step 4: Add Tomcat into the Eclipse (STS) server list ........................................................................................ 16 Step 5: Add the Microsoft JDBC 4.0 Driver to Pet Clinics project library. ........................................................ 18 Step 6: Create a Windows Azure SQL Database ............................................................................................... 20 Step 7: Get connection string information from the Windows Azure Portal ................................................... 21
October 11, 2013 Page 3

Step 8: Enable Database Connections to Windows Azure SQL Database......................................................... 22 Step 9: Configure LogBack to use Windows Azure SQL Database .................................................................... 27 Step 10: Inject Exception Handling for Transient Faults via AOP...................................................................... 29 Step 11: Inject Exception Handling for Transient Faults via AOP...................................................................... 31 Step 12: Add Memcached to PetClinic via AOP ................................................................................................ 32 VII. Windows Azure Java Application Lifecycle ..................................................................................................... 35 Deployment Consideration: Modifying Code to Maintain Database during Instance Redeployments .......... 35 VIII. Windows Azure Java Application Lifecycle: Creating a New Azure Deployment Project ............................. 36 Step 1: Export WAR File..................................................................................................................................... 36 Step 2: Create a Windows Azure Deployment Project ..................................................................................... 37 Import WAR File............................................................................................................................................. 39 Step 3: Deploy to the Windows Azure Compute local emulator ...................................................................... 42 Step 4: Publish to the Windows Azure Cloud: Staging and Production ............................................................ 43 IX. Reference Articles ............................................................................................................................................ 44

October 11, 2013

Page 4

I.

Executive Summary

Windows Azure is Microsoft's application platform for the public cloud. You can use this platform in many different ways. For instance, you can use Windows Azure to build a web application that runs and stores its data in Microsoft datacenters. You can use Windows Azure just to store data, with the applications that use this data running on-premises (that is, outside the public cloud). You can use Windows Azure to create virtual machines for development and test or to run Microsoft SQL Server, mySQL and other applications. You can use Windows Azure to build massively scalable applications with lots and lots of users. Because the platform offers a wide range of services, all of these things-and more-are possible. Most importantly, Windows Azure is an open cloud platform, and supports a wide variety of programming languages and frameworks, including Microsoft .NET, Java, Node.js, PHP, Python and Ruby. This guide is written specifically for Java developers to demonstrate how to migrate a typical Java application to the Windows Azure cloud. While the tutorial focuses on a popular Spring Framework sample application (the Java PetClinic); the tutorial will introduce you to the Azure Java SDK, Windows Azure Caching using memcached, Windows Azure Cloud Services, Windows Azure SQL Database, and a variety of other technologies that would be used in many other types of Java applications.

II.

Windows Azure Cloud Services or Windows Azure Virtual Machines?

Fundamentally, there are two different ways to run an application layer, such as a Web site, on Windows Azure. The first is via Platform as a Service (PaaS) via Azure Cloud Services. The second is via Infrastructure as a Service (IaaS) via Windows Azure Virtual Machines (VMs). With either, the developer chooses from one of eight worldwide data centers (four in the U.S., two in Europe, and two in Asia) to host their application. With Windows Azure Cloud Services, the developer just focuses on the application, and the platform automatically provisions and maintains the instances (under the covers these are Windows Hyper-V VMs) upon which the application layer runs. The instances can be horizontally scaled from one to several hundred clones, and load balancing is automatic. While the instances can be sized (with different numbers of virtual cores and memory), the instances are fundamentally managed by Windows Azure, including all patching and security updates of the OS layer. This guide focuses on running the Java Pet Clinic sample application on Windows Azure Cloud Services. With Windows Azure Virtual Machines, the developer creates his/her own VM image, and is responsible for installing and managing that VM including any software to be installed on the VM. For Java developers, there are a variety of pre-built VM images available, including Windows and several distributions of Linux. This is also a great way to run Java applications in the Windows Azure Cloud; as the developer has low-level control of the OS and VM, and can install software such as mySQL directly on any number of VMs, to build-out a complete application from application layer to data layer. Most Java applications will simply migrate with little or no code changes required. Load balancing can also be setup such that multiple VMs (perhaps running Tomcat/JSP layer) are load balanced via round-robin. Unlike Azure Cloud Services, however, the developer must manage the VM including any security patching just as if the VM was running on-premises. In addition, the hourly compute rate for a given instance (VM) size is higher. While this guide focuses on Java running on Windows Azure Cloud
October 11, 2013 Page 5

Services, we encourage developers to also try out Windows Azure Virtual Machines, using either Windows or Linux VMs.

III.

Spring Framework on the Windows Azure Platform

This guide will help Spring Framework developers migrate their applications to the Windows Azure Platform. Spring Frameworks recently updated PetClinic sample was chosen because it is a familiar vehicle for demonstrating several enterprise technologies that are used to create scalable J2EE applications such as Spring Data JPA, MVC, AOP, JMX, EhCache, and Logback. We will be extending PetClinic by injecting transient fault handling and Memcached on Azure Cache via AOP. For Java developers who are familiar with Eclipse and STS, Microsoft has provided the Windows Azure Toolkit for Eclipse with Java. This toolkit provides the following resources for aiding in Java development in Eclipse on Windows Azure: Windows Azure Plugin for Eclipse with Java Microsoft JDBC 4.0 Driver for SQL Server Package for Apache Qpid Client Libraries for JMS Package for Windows Azure Libraries for Java Windows Azure Access Control Services Filter Windows Azure Common Plugin

In this guide, we will be using the Windows Azure Plugin for Eclipse with Java and the Microsoft JDBC 4.0 Driver for SQL Server. The plugin to Eclipse provides Java wrappers for Windows Azure services and a Windows Azure emulator.

About Windows Azure


Before we go any further, here is a brief overview of the Windows Azure hosting options. New services appear often to check the Windows Azure portal for the latest. http://www.windowsazure.com Windows Azure provides several ways to host services in the cloud: Web Sites, Virtual Machine, and Cloud Services. (See Figure 1 for more detail of each.) In this guide, we will be deploying a Spring Framework application on Windows Azure Cloud Services. This will allow developers the ability to host scalable

October 11, 2013

Page 6

applications to the cloud using Worker Roles, while reducing time on operations tasks.

Figure 1: Windows Azure Platform Deployment Methods

IV. Pet Clinic on Azure: High-Level Architecture


Defining Key Windows Azure Services
Below are some key Windows Azure specific reference terms used throughout this guide.

LB

LB

Worker Role Worker Role Worker Role

Windows SQL Azure Database

Storage

Windows Azure Cache

Figure 2: Simple Scalable Web Application Deployment in Windows Azure

October 11, 2013

Page 7

Windows Azure Worker Role A Worker Role is a deployable compute package that allows Windows Azure the ability to manage many aspects of data center operations such as OS patching, monitoring, deploying, and hardware-failure recovery. The Worker Role deployment can later be scaled out via the Windows Azure Portal UI, or by using the Windows Azure REST-API. The ability to scale a deployment from a single package is a significant advantage that Worker Roles provide. Windows Azure SQL Database Windows Azure SQL Database extends SQL Server capabilities to the cloud. You can easily provision and deploy relational database solutions. Benefits include manageability, high availability, scalability, and a familiar ER model. (Source: MSDN Windows Azure SQL Database) Windows Azure Cache Service Windows Azure Caching is an in-memory, distributed object cache that can be used to boost application performance. It can be easily used with Java as it supports a standard memcached interface. As user load increases, the Cache helps applications be more responsive, allowing your applications to scale. Data you store in the cache is accessible from multiple instances of your application enabling state to be easily and quickly shared between instances. Uses of the cache include centrally storing session state across multiple loadbalanced instances of your application layer; as well as caching frequently accessed database query results or any other type of Java object. Windows Azure Caching adds additional control and resilience options like high availability to ensure that your cached data is resilient. (See: Windows Azure Caching and Memcached Wrapper for Windows Azure Caching)

Typical Tiered Architecture of a Web Application


As seen in Figure 2, on the previous page, hosting the Pet Clinic application in Windows Azure provides elastic scalability, so that the number of required Worker Roles can be increased or decreased, depending on the traffic load.

October 11, 2013

Page 8

Spring Framework Pet Clinic on Windows Azure

LB

LB

Spring Framework Pet Clinic Microsoft JDBC Memcached Client

Worker Role

LB

Windows SQL Azure Database

Storage

Windows Azure Cache

Figure 3: Worker Role Architecture Apache Tomcat 7.0 In this example, we are using Tomcat 7.0 as our servlet container; however other servlet containers such as Jetty or Websphere can be used. For the purposes of distributed cache as workers scale, Memcached is integrated with Windows Azure Caching Services. To the Memcached Client the integration is seamless.

October 11, 2013

Page 9

Spring Data JPA The Pet Clinic sample illustrates many persistence layer interfaces, such as Spring Data JPA, JPA and JDBC. Here we are using Spring Data JPA. To handle database connectivity with Windows Azure SQL Database, we are using the Microsoft Java Database Connectivity Driver (JDBC) 4.0 that is provided in the Windows Azure Toolkit for Java. We will also be showing how to handle transient faults. Memcached Memcached is a high-performance, distributed memory object caching system, intended for increasing dynamic web applications by alleviating database load. In our sample application, we have demonstrated how Memcached can be implemented as a performance/scalability enhancer. There are two approaches available for implementing memcache for a Windows Azure application: the Dedicated Caching roles approach, and the Co-located approach. From a developer perspective, either approach supports the standard memcache API calls. The only change you should have to make to existing memcache implementations is the endpoint.
Co-located Role VS Dedicated Role

Memcache Enabled Application

Memcache Enabled Application Client Shim handles translation locally Client Shim uses Windows Azure Cache Protocol

Worker Role
Network call for re-hash Server Gateway uses Memcache wire protocol

Worker Role

Shim

Windows Azure Cache Service

Cache Server

Cache Server

Cache Server

Cache Server

Cache Server

Cache Server

Cache Server

Cache Server

Cache Server

Storage

Memcache Server Gateway (Co-located Cache) The server gateway approach (generally used with Co-located Cache) offers very simple deployment. No shim is required. However, this approach has performance limitations in some scenarios, because memcache and Windows Azure Caching Service use different hashing algorithms, resulting in the need to re-hash keys to determine which server a key should be stored on. Another consideration is that this approach only has

October 11, 2013

Page 10

available space remaining on the instances deployed in your cluster. If you have 5 web heads then you have 5 cache servers. We will be focusing on this method here.

Memcache Client Shim (Dedicated Cache) The client shim (generally used with a Dedicated Cache), on the other hand, is installed on the client application (which may be hosted on Windows Azure), and provides a memcache protocol handler for the application, with calls translated locally to Windows Azure Caching API calls which are sent to the cache servers. This results in better performance because there are no extra network hops for re-hashing keys, but deployment requires installation of the client shim on application roles, whereas the server gateway approach does not require any installation or setup steps on the client. Another advantage is that since a dedicated instance is used for cache you have better control over the space available to cache.

High-Level Windows Azure Application Lifecycle


Figure 4 details the typical application lifecycle for deploying Java applications into Windows Azure. On deployment to Azure, the Windows Azure Plugin for Eclipse with Java will take care of packaging the web archive file (WAR) file, Java Development Kit (JDK) and Tomcat. This plugin component provides wizards to help the user manage the deployment process by creating a Deployment Project.

Figure 4: Java Web Application Cloud Deployment Process

October 11, 2013

Page 11

Local Development You can develop your Java application locally in Eclipse(STS). For simplicity in this sample, your JDBC connections will point to your database hosted in Windows Azure. You could also have a local database in Azure using the emulator. But here we are hosting our development database in Azure to keep deployment steps across the lifecycle consistent. Also we need to be sure that Memcached service is running. The project files assume you are running Memcached locally. If you are running Memcached remotely you need to update ~src\main\resources\spring\tools-config.xml. Change the address property of the defaultMemcachedClient bean. Local Windows Azure Emulator Deployment When you are ready to test the deployment of your worker role package you can deploy locally to Windows Azure emulator services. Details on Memcached client changes below. Windows Azure (Staging/Production) Deployment Finally, when you are ready to deploy to staging and production you will package up your application for deployment to Windows Azure using the provided Eclipse (STS) plugin which includes an easy to use wizard that will guide you through the steps. We will cover this in detail in this guide.

V. Windows Azure Java Application Lifecycle: Prerequisites


The following items are required for this sample. You should use: A Java Developer Kit (JDK): The 64bit JDK used here is 1.7.0_09 and can be downloaded here. A Windows Azure subscription: Trial versions can be acquired from http://www.microsoft.com/windowsazure/offers/. Spring Tool Suite (STS): The version the Spring Tool Suite (v3.2.0) can be downloaded here. Tomcat 7.0: To download the latest 64bit version of Tomcat (7.0), visit the Tomcat website. Windows Azure Account: Set up your free trial account by visiting the Windows Azure website. Simple Spring Memcached (SSM): Download 3.1.0 from here Windows Azure SDK v2.1 or later: Download via Web Platform Installer Pet Clinic: Modified for Windows Azure is found here: https://github.com/Logic2020Inc/springpetclinic-mod . You can download the zip file from the link in the lower right. Memcached: Project home is here. Compiling Memcached for Windows is beyond the scope of this guide. You can Bing for many good references on this topic. Developers Note: Your Windows operating system must be 64bit. All components (Java, Eclipse (STS), Tomcat, etc.) must be 64 bit.

October 11, 2013

Page 12

VI. Windows Azure Java Application Lifecycle Development Environment Configuration Steps
At a high-level, the configuration steps to set up a development environment for this project are as follows: 0. 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. Install Spring Tool Suite (STS) Install the Windows Azure Plugin for Eclipse with Java Download the Pet Clinic source files Import Pet Clinic into STS project workspace Add Tomcat into to STS server list (assumes Tomcat is already installed) Add the Microsoft JDBC 4.0 Driver to Pet Clinics project library. Create Windows Azure SQL database Get connection string information from the Windows Azure Portal Enable Database Connections to Windows Azure SQL Database Configure LogBack to use Windows Azure SQL Database Inject Exception Handling for Transient Faults via AOP Add Memcached to PetClinic via AOP Create Azure deployment package in STS Configure Azure deployment by adding in Azure subscription

Step 0: Install Spring Tool Suite


1. http://www.springsource.org/sts

Step 1: Install the Windows Azure Plugin for Eclipse with Java
1. Start Eclipse(STS) 2. Click the Help dropdown menu and select Install New Software

October 11, 2013

Page 13

3. A new window appears. In the Work With text box, type http://dl.msopentech.com/eclipse and then click Add. Name the repository Windows Azure http://dl.msopentech.com/eclipse. The Windows Azure Toolkit for Java software downloads will appear.

4. Click Next and then click Finish. If you are prompted to restart, please do so.

Step 2: Download the Pet Clinic source files.


1. Follow instruction on Github: https://github.com/Logic2020Inc/spring-petclinic-mod. You can download the zip file from the lower right link.

Step 3: Import Pet Clinic into the Eclipse (STS) project workspace
1. Open Eclipse (STS). On your dashboard, right-click in the Package Explorer Window. 2. Scroll down, and select Import.

3. Under Maven select, Existing Maven Project.


October 11, 2013 Page 14

4. The Import Projects window opens. Here you will select the local directory structure that has the Pet Clinic, navigating to the base folder that has the POM.XML file. Select the folder. 5. Click Next and Finish. 6. Your Pet Clinic source code is now loaded into development environment. Developers Note: If you are building the project by using Maven, or import by using an Existing Maven Project, Eclipse (STS) will build using a different JRE System Library. You need to have the JRE System Library set to jdk 1.7.0_09, otherwise you may get a jdbc.BadSqlGrammarException exception when deploying.

October 11, 2013

Page 15

Step 4: Add Tomcat into the Eclipse (STS) server list


If you dont already have Tomcat installed go ahead and do that. You will need Tomcat installed to develop but you will also need to have Tomcat unzipped in an un-used directory for deployment to Azure. 1. In Eclipse (STS), right-click under the Servers tab in the lower left-hand corner. 2. Select New from the menu, and then select Server.

3. A new window will open. Under Select the server type, open the Apache Folder and select Tomcat 7.0..

4. If there are no environments then click Add


October 11, 2013 Page 16

5. Notice the path here is to the local installed instance of Tomcat. In later steps, while creating a deployment package for Azure, we will need a clean unzipped version of Tomcat that has not been installed. 6. Click Next and then add the sample application to the Configured Resources window.

7. Click Finish to close to wizard. 8. Your Tomcat server has now been added to your server list in STS.

October 11, 2013

Page 17

Step 5: Add the Microsoft JDBC 4.0 Driver to Pet Clinics project library.
1. If you have not already done so, download the Microsoft JBDC 4.0 driver by clicking here. 2. Open Eclipse(STS). In the Package Explorer Tab box, open the right-click menu and select Properties.

3. A new window opens. In the left navigation area, select Java Build Path. 4. Select the Libraries tab, and select the Add Library button.

October 11, 2013

Page 18

5. In the Add Library window, select the Microsoft JDBC 4.0 Driver for SQL Server and then click Finish.

6. This is what your Package Explorer should look like at the end of this step. Notice the toolbar now has the Windows Azure buttons, and the Microsoft JDBC Driver 4.0 is added to your project.

October 11, 2013

Page 19

Step 6: Create a Windows Azure SQL Database


1. Log into the Windows Azure Portal 2. Click on New on the lower left hand corner of the left navigation

3. Select Data Services, then select SQL Database, and finally select Quick Create

4. Select a 3-Month Free Trial or another subscription 5. Provide a database name, as well as a login name and password. 6. Select Create SQL Database.

October 11, 2013

Page 20

Step 7: Get connection string information from the Windows Azure Portal
1. 2. 3. 4. Log onto Windows Azure Portal Click on the Database in the left navigation Select your database On the lower-right hand side of the screen, select Show Connection Strings. Save string for later.

Developers Note: Notice the Allow the connection in firewall rules section. You most likely will not have to make any configuration changes to your firewall. However, this will all depend on the environment that the application is running in. Click on the link to add IP address to October 11, 2013 Page 21 firewall rules.

Step 8: Enable Database Connections to Windows Azure SQL Database


Moving back to STS and our project. We need to add build scripts for Windows Azure SQL Database, add bootstrap data to the database, add tables for Logback logging framework, add SQL Database connection information, and finally give DBCP hints on how to handle null connections in the pool. 1. Add SQL scripts in a new directory: ~\src\main\resources\db a. Name new directory mssqldb b. In new directory, add InitDB.sql script to create the database:
--Modified by Mike Ashby, added section to remove all FK constraints and then all tables dynamically. --Added explicit NOT NULL declarations on PK candidates as required by SQL Server. --Added clustered index to vet_specialties, SQL Azure requires all tables to have a PK. declare @sql nvarchar(2000) while(exists(select 1 from INFORMATION_SCHEMA.TABLE_CONSTRAINTS where CONSTRAINT_TYPE='FOREIGN KEY')) begin SELECT TOP 1 @sql=('ALTER TABLE ' + TABLE_SCHEMA + '.[' + TABLE_NAME + '] DROP CONSTRAINT [' + CONSTRAINT_NAME + ']') FROM information_schema.table_constraints WHERE CONSTRAINT_TYPE = 'FOREIGN KEY' exec (@sql) PRINT @sql end while(exists(select 1 from INFORMATION_SCHEMA.TABLES)) begin SELECT TOP 1 @sql=('DROP TABLE ' + TABLE_SCHEMA + '.[' + TABLE_NAME + ']') FROM INFORMATION_SCHEMA.TABLES exec (@sql) PRINT @sql end CREATE TABLE vets ( id INTEGER NOT NULL IDENTITY PRIMARY KEY, first_name VARCHAR(30), last_name VARCHAR(30) ); CREATE INDEX vets_last_name ON vets(last_name); CREATE TABLE specialties ( id INTEGER NOT NULL IDENTITY PRIMARY KEY, name VARCHAR(80) ); CREATE INDEX specialties_name ON specialties(name); CREATE TABLE vet_specialties ( vet_id INTEGER NOT NULL , specialty_id INTEGER NOT NULL ); CREATE CLUSTERED INDEX vet_specialties_PK ON vet_specialties(vet_id, specialty_id);

October 11, 2013

Page 22

alter table vet_specialties add constraint fk_vet_specialties_vets foreign key (vet_id) references vets(id); alter table vet_specialties add constraint fk_vet_specialties_specialties foreign key (specialty_id) references specialties(id); CREATE TABLE types ( id INTEGER NOT NULL IDENTITY PRIMARY KEY, name VARCHAR(80) ); CREATE INDEX types_name ON types(name); CREATE TABLE owners ( id INTEGER NOT NULL IDENTITY PRIMARY KEY, first_name VARCHAR(30), last_name VARCHAR(30), address VARCHAR(255), city VARCHAR(80), telephone VARCHAR(20) ); CREATE INDEX owners_last_name ON owners(last_name); CREATE TABLE pets ( id INTEGER NOT NULL IDENTITY PRIMARY KEY, name VARCHAR(30), birth_date DATE, type_id INTEGER NOT NULL, owner_id INTEGER NOT NULL ); alter table pets add constraint fk_pets_owners foreign key (owner_id) references owners(id); alter table pets add constraint fk_pets_types foreign key (type_id) references types(id); CREATE INDEX pets_name ON pets(name); CREATE TABLE visits ( id INTEGER NOT NULL IDENTITY PRIMARY KEY, pet_id INTEGER NOT NULL, visit_date DATE, description VARCHAR(255) ); alter table visits add constraint fk_visits_pets foreign key (pet_id) references pets(id); CREATE INDEX visits_pet_id ON visits(pet_id);

2. Create PopulateDB.sql script to bootstrap data into database. a. In the new directory, add populateDB.sql script to bootstrap the database:
--Modified by Mike Ashby: modified to work with Windows Azure SQL Database. --SQL Server requires Identity to be disabled when explicitly setting a column with Identity on. --Insert INTO statements in SQL Server require explicit columns. SET IDENTITY_INSERT vets ON; INSERT INTO vets (id, first_name, last_name) VALUES (1, 'James', 'Carter'); INSERT INTO vets (id, first_name, last_name) VALUES (2, 'Helen', 'Leary'); INSERT INTO vets (id, first_name, last_name) VALUES (3, 'Linda', 'Douglas'); INSERT INTO vets (id, first_name, last_name) VALUES (4, 'Rafael', 'Ortega'); INSERT INTO vets (id, first_name, last_name) VALUES (5, 'Henry', 'Stevens'); INSERT INTO vets (id, first_name, last_name) VALUES (6, 'Sharon', 'Jenkins'); SET IDENTITY_INSERT vets OFF;

October 11, 2013

Page 23

SET IDENTITY_INSERT specialties ON; INSERT INTO specialties (id, name) VALUES (1, 'radiology'); INSERT INTO specialties (id, name) VALUES (2, 'surgery'); INSERT INTO specialties (id, name) VALUES (3, 'dentistry'); SET IDENTITY_INSERT specialties OFF; INSERT INTO vet_specialties VALUES (2, 1); INSERT INTO vet_specialties VALUES (3, 2); INSERT INTO vet_specialties VALUES (3, 3); INSERT INTO vet_specialties VALUES (4, 2); INSERT INTO vet_specialties VALUES (5, 1); SET IDENTITY_INSERT types ON; INSERT INTO types (id, name) VALUES (1, 'cat'); INSERT INTO types (id, name) VALUES (2, 'dog'); INSERT INTO types (id, name) VALUES (3, 'lizard'); INSERT INTO types (id, name) VALUES (4, 'snake'); INSERT INTO types (id, name) VALUES (5, 'bird'); INSERT INTO types (id, name) VALUES (6, 'hamster'); SET IDENTITY_INSERT types OFF;

SET IDENTITY_INSERT owners ON; INSERT INTO owners (id,first_name ,last_name ,address ,city ,telephone) VALUES (1, 'George', 'Franklin', '110 W. Liberty St.', 'Madison', '6085551023'); INSERT INTO owners (id,first_name ,last_name ,address ,city ,telephone) VALUES (2, 'Betty', 'Davis', '638 Cardinal Ave.', 'Sun Prairie', '6085551749'); INSERT INTO owners (id,first_name ,last_name ,address ,city ,telephone) VALUES (3, 'Eduardo', 'Rodriquez', '2693 Commerce St.', 'McFarland', '6085558763'); INSERT INTO owners (id,first_name ,last_name ,address ,city ,telephone) VALUES (4, 'Harold', 'Davis', '563 Friendly St.', 'Windsor', '6085553198'); INSERT INTO owners (id,first_name ,last_name ,address ,city ,telephone) VALUES (5, 'Peter', 'McTavish', '2387 S. Fair Way', 'Madison', '6085552765'); INSERT INTO owners (id,first_name ,last_name ,address ,city ,telephone) VALUES (6, 'Jean', 'Coleman', '105 N. Lake St.', 'Monona', '6085552654'); INSERT INTO owners (id,first_name ,last_name ,address ,city ,telephone) VALUES (7, 'Jeff', 'Black', '1450 Oak Blvd.', 'Monona', '6085555387'); INSERT INTO owners (id,first_name ,last_name ,address ,city ,telephone) VALUES (8, 'Maria', 'Escobito', '345 Maple St.', 'Madison', '6085557683'); INSERT INTO owners (id,first_name ,last_name ,address ,city ,telephone) VALUES (9, 'David', 'Schroeder', '2749 Blackhawk Trail', 'Madison', '6085559435'); INSERT INTO owners (id,first_name ,last_name ,address ,city ,telephone) VALUES (10, 'Carlos', 'Estaban', '2335 Independence La.', 'Waunakee', '6085555487'); SET IDENTITY_INSERT owners OFF;

October 11, 2013

Page 24

SET IDENTITY_INSERT pets ON; INSERT INTO pets (id, name ,birth_date 1, 1); INSERT INTO pets (id, name ,birth_date 06', 6, 2); INSERT INTO pets (id, name ,birth_date 2, 3); INSERT INTO pets (id, name ,birth_date 07', 2, 3); INSERT INTO pets (id, name ,birth_date 3, 4); INSERT INTO pets (id, name ,birth_date 20', 4, 5); INSERT INTO pets (id, name ,birth_date 04', 1, 6); INSERT INTO pets (id, name ,birth_date 1, 6); INSERT INTO pets (id, name ,birth_date 06', 5, 7); INSERT INTO pets (id, name ,birth_date 02-24', 2, 8); INSERT INTO pets (id, name ,birth_date 09', 5, 9); INSERT INTO pets (id, name ,birth_date 24', 2, 10); INSERT INTO pets (id, name ,birth_date 1, 10); SET IDENTITY_INSERT pets OFF; SET IDENTITY_INSERT visits ON; INSERT INTO visits (id, pet_id 'rabies shot'); INSERT INTO visits (id, pet_id 'rabies shot'); INSERT INTO visits (id, pet_id 'neutered'); INSERT INTO visits (id, pet_id 'spayed'); SET IDENTITY_INSERT visits OFF;

,type_id ,type_id ,type_id ,type_id ,type_id ,type_id ,type_id ,type_id ,type_id ,type_id ,type_id ,type_id ,type_id

,owner_id) VALUES (1, 'Leo', '2000-09-07', ,owner_id) VALUES (2, 'Basil', '2002-08,owner_id) VALUES (3, 'Rosy', '2001-04-17', ,owner_id) VALUES (4, 'Jewel', '2000-03,owner_id) VALUES (5, 'Iggy', '2000-11-30', ,owner_id) VALUES (6, 'George', '2000-01,owner_id) VALUES (7, 'Samantha', '1995-09,owner_id) VALUES (8, 'Max', '1995-09-04', ,owner_id) VALUES (9, 'Lucky', '1999-08,owner_id) VALUES (10, 'Mulligan', '1997,owner_id) VALUES (11, 'Freddy', '2000-03,owner_id) VALUES (12, 'Lucky', '2000-06,owner_id) VALUES (13, 'Sly', '2002-06-08',

,visit_date ,visit_date ,visit_date ,visit_date

,description ) VALUES (1, 7, '1996-03-04', ,description ) VALUES (2, 8, '1996-03-04', ,description ) VALUES (3, 8, '1996-06-04', ,description ) VALUES (4, 7, '1996-09-04',

3. Go ahead and add the script for Logback (logging framework) a. In the new directory create, mssql.sql:

October 11, 2013

Page 25

-- Logback: the reliable, generic, fast and flexible logging framework. -- Copyright (C) 1999-2010, QOS.ch. All rights reserved. --- See http://logback.qos.ch/license.html for the applicable licensing -- conditions. -- This SQL script creates the required tables by ch.qos.logback.classic.db.DBAppender --- The event_id column type was recently changed from INT to DECIMAL(40) -- without testing. --Modified by Mike Ashby: modified to work with Windows Azure SQL Database. --reduced Decimal(40) to Decimal(38) which is SQL Servers max. CREATE TABLE logging_event ( timestamp DECIMAL(20) NOT NULL, formatted_message VARCHAR(4000) NOT NULL, logger_name VARCHAR(254) NOT NULL, level_string VARCHAR(254) NOT NULL, thread_name VARCHAR(254), reference_flag SMALLINT, arg0 VARCHAR(254), arg1 VARCHAR(254), arg2 VARCHAR(254), arg3 VARCHAR(254), caller_filename VARCHAR(254) NOT NULL, caller_class VARCHAR(254) NOT NULL, caller_method VARCHAR(254) NOT NULL, caller_line CHAR(4) NOT NULL, event_id DECIMAL(38) identity NOT NULL, PRIMARY KEY(event_id) ); CREATE TABLE logging_event_property ( event_id DECIMAL(38) NOT NULL, mapped_key VARCHAR(254) NOT NULL, mapped_value VARCHAR(1024), PRIMARY KEY(event_id, mapped_key), FOREIGN KEY (event_id) REFERENCES logging_event(event_id) ) CREATE TABLE logging_event_exception ( event_id DECIMAL(38) NOT NULL, i SMALLINT NOT NULL, trace_line VARCHAR(254) NOT NULL, PRIMARY KEY(event_id, i), FOREIGN KEY (event_id) REFERENCES logging_event(event_id) )

4. Modify JDBC properties a. In properties file at ~\src\main\resources\spring\data-access.properties b. Comment out HSQL section. c. Add new SQL Server section:

October 11, 2013

Page 26

#------------------------------------------------------------------------------# SQL Server Settingstcp:XXXXXXXX.database.windows.net;Initial Catalog=PetClinicDB;Persist Security Info=True;User ID=login@server;Password=*********** jdbc.driverClassName=com.microsoft.sqlserver.jdbc.SQLServerDriver jdbc.url=jdbc:sqlserver://server.database.windows.net:1433;databaseName=PetClinicDB jdbc.username=login@server jdbc.password=password # Properties that control the population of schema and data for a new data source jdbc.initLocation=classpath:db/mssqldb/initDB.sql jdbc.dataLocation=classpath:db/mssqldb/populateDB.sql jdbc.logdataLocation=classpath:db/mssqldb/mssql.sql # Property that determines which Hibernate dialect to use # (only applied with "applicationContext-hibernate.xml") hibernate.dialect=org.hibernate.dialect.SQLServer2008Dialect # Property that determines which JPA DatabasePlatform to use with TopLink Essentials jpa.databasePlatform=org.springframework.samples.petclinic.sqlserver.EssentialsSQLPlatformWithNativeSequence # Property that determines which database to use with an AbstractJpaVendorAdapter jpa.database=SQL_SERVER

5. Modify data source configuration file a. In ~\src\main\resources\spring\datasource-config.xml b. Change:


<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close" p:driverClassName="${jdbc.driverClassName}" p:url="${jdbc.url}" p:username="${jdbc.username}" p:password="${jdbc.password}" />

To:
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close" p:driverClassName="${jdbc.driverClassName}" p:url="${jdbc.url}" p:username="${jdbc.username}" p:password="${jdbc.password}" p:testOnBorrow="True" p:testOnReturn="True" p:validationQuery="SELECT 1; />

6. Modify web.xml to enable Spring Data JPA a. Open ~\src\main\webapp\WEB-INF\web.xml b. Under <param-name>spring.profiles.active</param-name> c. Set the active profile to Spring-data-jpa: <param-value>spring-data-jpa</param-value>

Step 9: Configure LogBack to use Windows Azure SQL Database


By configuring LogBack to connect to Windows Azure SQL Database you can easily collect logs from several instances. There are performance consideration and the below configuration is meant only to show how to configure the appender to work with SQL Database. In Step 7, we showed how to retrieve connection string details from the Windows Azure portal and you will need those here. 1. In the logback configuration, ~\src\main\resources\logback.xml a. Add a database appender, DBAppender b. Add a logger for the DBAppender
October 11, 2013 Page 27

<?xml version="1.0" encoding="UTF-8"?> <configuration scan="false" scanPeriod="30 seconds" > <contextListener class="ch.qos.logback.classic.jul.LevelChangePropagator"> <resetJUL>true</resetJUL> </contextListener> <!-- To enable JMX Management --> <jmxConfigurator/> <appender name="console" class="ch.qos.logback.core.ConsoleAppender"> <encoder> <pattern>%-5level %logger{0} - %msg%n</pattern> </encoder> </appender> <appender name="FILE" class="ch.qos.logback.core.FileAppender"> <file>C:/temp/LogFile.log</file> <append>true</append> <!-- encoders are assigned the type ch.qos.logback.classic.encoder.PatternLayoutEncoder by default --> <encoder> <pattern>%-4relative [%thread] %-5level %logger{35} - %msg%n</pattern> </encoder> </appender> <appender name="DB" class="ch.qos.logback.classic.db.DBAppender"> <connectionSource class="ch.qos.logback.core.db.DriverManagerConnectionSource"> <driverClass>com.microsoft.sqlserver.jdbc.SQLServerDriver</driverClass> <url>jdbc:sqlserver://Put_server_here.database.windows.net:1433;databaseName=Put_Database_Here</url> <user>Put_login_here@put_servername_here</user> <password>Put_Password_Here</password> </connectionSource> </appender> <logger name="org.hibernate" level="warn"> <appender-ref ref="console" /> </logger> <logger name="org.springframework.samples.petclinic" level="warn"> <appender-ref ref="DB" /> </logger>

October 11, 2013

Page 28

Warning: Writing logs to the DB can be time consuming and can delay Tomcat start up beyond its Start Timeout. In Spring Tool Suite the timeout can be increased finding and double clicking on Tomcat under Servers. Then click on Timeouts section and increase the Start timeout to something like 3 minutes.

Step 10: Inject Exception Handling for Transient Faults via AOP
Windows Azure SQL Database is a multi-tenant, high availability database implementation of Microsoft SQL Server 2012. Its HA and Internet-scale architecture requires that certain transient faults be captured and SQL commands retriedon these conditions. The database connections can be throttled internally by the SQL Database for several reasons, such as excessive resource usage, long-running transactions, and possible failover and load balancing actions, leading to termination of a client session or temporary inability to establish new connections while a transient condition persists. The database connections may also be dropped due to the variety of reasons related to Internet connectivity between the client and distant Microsoft data centers: quality of network, intermittent network faults in the clients LAN or WAN infrastructure and other transient technical reasons. For this reason we need to be able to intercept these errors, determine their severity, and then determine our course of action. Here we demonstrate how to intercept errors via AOP. 2. In the logback configuration, ~\src\main\resources\logback.xml a. Add a database appender, DBAppender b. Add a logger for the DBAppender

October 11, 2013

Page 29

<?xml version="1.0" encoding="UTF-8"?> <configuration scan="false" scanPeriod="30 seconds" > <contextListener class="ch.qos.logback.classic.jul.LevelChangePropagator"> <resetJUL>true</resetJUL> </contextListener> <!-- To enable JMX Management --> <jmxConfigurator/> <appender name="console" class="ch.qos.logback.core.ConsoleAppender"> <encoder> <pattern>%-5level %logger{0} - %msg%n</pattern> </encoder> </appender> <appender name="FILE" class="ch.qos.logback.core.FileAppender"> <file>C:/temp/LogFile.log</file> <append>true</append> <!-- encoders are assigned the type ch.qos.logback.classic.encoder.PatternLayoutEncoder by default --> <encoder> <pattern>%-4relative [%thread] %-5level %logger{35} - %msg%n</pattern> </encoder> </appender> <appender name="DB" class="ch.qos.logback.classic.db.DBAppender"> <connectionSource class="ch.qos.logback.core.db.DriverManagerConnectionSource"> <driverClass>com.microsoft.sqlserver.jdbc.SQLServerDriver</driverClass> <url>jdbc:sqlserver://Put_server_here.database.windows.net:1433;databaseName=Put_Database_Here</url> <user>Put_login_here@put_servername_here</user> <password>Put_Password_Here</password> </connectionSource> </appender> <logger name="org.hibernate" level="warn"> <appender-ref ref="console" /> </logger> <logger name="org.springframework.samples.petclinic" level="warn"> <appender-ref ref="DB" /> </logger>

October 11, 2013

Page 30

Warning: writing logs to the DB can be time consuming and can delay Tomcat start up beyond its Start Timeout. In Spring Tool Suite the timeout can be increased finding and double clicking on Tomcat under Servers. Then click on Timeouts section and increase the Start timeout to something like 3 minutes.

Step 11: Inject Exception Handling for Transient Faults via AOP
Windows Azure SQL Database services implements a throttling behavior which can throttle resources. For instance, when a client is establishing connections to a Windows Azure SQL Database or running queries against it. The database connections can be throttled internally by Windows Azure SQL Database for several reasons, such as excessive resource usage, long-running transactions, and possible failover and load balancing actions, leading to termination of a client session or temporary inability to establish new connections while a transient condition persists. The database connections may also be dropped due to the variety of reasons related to network connectivity between the client and distant Microsoft data centers: quality of network, intermittent network faults in the clients LAN or WAN infrastructure and other transient technical reasons. For this reason we need to be able to intercept these errors, determine their severity, and then determine our course of action. Here we demonstrate how to intercept errors via AOP. 1. Add new class file, ExceptionHandler.java at ~\src\main\java\org\springframework\samples\petclinic\service\ 2. To this file, add this code which will target two methods in the ClientServiceImpl:

October 11, 2013

Page 31

package org.springframework.samples.petclinic.service; import java.sql.SQLException; import java.util.Locale; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.AfterThrowing; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Pointcut; import org.springframework.context.MessageSource; import org.springframework.context.MessageSourceAware; import org.springframework.stereotype.Component; @Aspect @Component public class ExceptionHandler { private MessageSource messageSource; @Pointcut("execution(* org.springframework.samples.petclinic.service.ClinicServiceImpl*.*(..))") public void findPetTypes() { } @Pointcut("execution(* org.springframework.samples.petclinic.service.ClinicServiceImpl*.*(..))") public void findOwnerById() { } @Around("findPetTypes() || findOwnerById()") public Object profile(ProceedingJoinPoint pjp) throws Throwable { long start = System.currentTimeMillis(); System.out.println("Going to call method: " + pjp.getSignature()); Object output = pjp.proceed(); System.out.println("Method execution completed."); long elapsedTime = System.currentTimeMillis() - start; System.out.println("Method execution time: " + elapsedTime + " milliseconds."); //add your Transient Fault Exception Handling here // throw new SQLException(); return output; } }

3. AOP requires a default constructor, so we need to add one to ClinicServiceImpl. In ~\src\main\java\org\springframework\samples\petclinic\service\ClinicServiceImpl.java Add this constructor:
public ClinicServiceImpl(){}

Step 12: Add Memcached to PetClinic via AOP


1. Before you test this step in your local development environment, you need to have a Memcached service available. See prerequisites. 2. Add Simple Spring Memcached framework to project path. 3. In Pom.XML add dependency:
<groupId>com.google.code.simple-spring-memcached</groupId> <artifactId>spymemcached-provider</artifactId> <version>3.1.0</version> October 11, 2013

Page 32

</dependency>

4. Add SSM to Tools Configuration a. Open ~\src\main\resources\spring\tools-config.xml b. Add: <import resource="simplesm-context.xml"/> c. And add the following beans:
<bean id="clinicServiceImpl" class="org.springframework.samples.petclinic.service.ClinicServiceImpl" /> <bean id="exceptionHandler" class="org.springframework.samples.petclinic.service.ExceptionHandler" /> Add SSM Memcached Client bean: <bean name="defaultMemcachedClient" class="com.google.code.ssm.CacheFactory"> <property name="cacheClientFactory"> <bean class="com.google.code.ssm.providers.spymemcached.MemcacheClientFactoryImpl" /> </property> <property name="addressProvider"> <bean class="com.google.code.ssm.config.DefaultAddressProvider"> <property name="address" value="localhost:11211" /> </bean> </property> <property name="configuration"> <bean class="com.google.code.ssm.providers.CacheConfiguration"> <property name="consistentHashing" value="true" /> </bean> </property> </bean>

5. Add SSM context XML file to path Simple Spring Memcached comes with a xml configuration file which can be found in the SSM project files. a. Add simplesm-context.xml to ~\src\main\resources\spring\ 6. Make objects to be cached serializable by altering base class. a. Open base entity class, and change BaseEntity to implement Serializable, ~\src\main\java\org\springframework\samples\petclinic\model\BaseEntity.java b. Open Person class and add SSMs CacheKeyMethod reference and annot ation import com.google.code.ssm.api.CacheKeyMethod; () @CacheKeyMethod public String getLastName() { c. Make Vets un-cached so we can add it to Memcached by commenting out @Cacheable in ~\src\main\java\org\springframework\samples\petclinic\repository\jpa\JpaVetRepositoryImpl.jav 7. Simple-Spring-Memcached requires that all methods it intercepts implement signatures a specific way. For instance, only List<> is allowed as a parameter for collection types and if they need @ParameterValueKeyProvider (which is used by single key provider types) then the type needs to be integer. See SSM documentation for more details. The following changes are required in ~\src\main\java\org\springframework\samples\petclinic\service\ClinicService.java public void saveOwner(Owner owner, int id) throws DataAccessException;
October 11, 2013 Page 33

List<Owner> findOwnerByLastName(List<String> lastName) In ~\src\main\java\org\springframework\samples\petclinic\service\ClinicServiceImpl.java this is where the meat of the implementation occurs. Notice that the changes we are making are to method signatures and annotations. There arent any functional changes required. New code in red:
@Transactional(readOnly = true, timeout = 60) @ReadThroughSingleCache( namespace="Owner", expiration = 300) public List<Owner> findOwnerByLastName(@ParameterValueKeyProvider List<String> lastName) throws DataAccessException { return (List<Owner>) ownerRepository.findByLastName( lastName.get(0)); } @Override @Transactional(readOnly = true, timeout = 60) @ReadThroughAssignCache(namespace="OwnersAll" , assignedKey ="0", expiration = 300) public List<Owner> findOwnerByLastName(String lastName) throws DataAccessException { return (List<Owner>) ownerRepository.findByLastName( lastName); } @Override @Transactional(timeout = 60) @InvalidateSingleCache(namespace = "Owner" ) @InvalidateAssignCache(namespace = "OwnersAll" , assignedKey ="0" ) public void saveOwner(Owner owner, @ParameterValueKeyProvider int id) throws DataAccessException { ownerRepository.save(owner); } @Override @Transactional(readOnly = true, timeout = 60) @ReadThroughSingleCache( namespace="Owner" , expiration = 300) public Owner findOwnerById(@ParameterValueKeyProvider int id) throws DataAccessException { return ownerRepository.findById(id); } @Override @Transactional(readOnly = true, timeout = 60) @ReadThroughAssignCache( namespace="Vets" , assignedKey ="0", expiration = 300) public Collection<Vet> findVets( ) throws DataAccessException { return vetRepository.findAll(); }

In ~\src\main\java\org\springframework\samples\petclinic\web\OwnerController.java mostly simple signature changes required by SSM. But the biggest code change also occurs here. We had to add logic because SSM doesnt handle the situation where a parameter is null. So we had to create a new findOwnerByLastName with a new signature that could be used with an AssignCache annotation. Note: These are limitations of SSM not Azure. We only use the AssignCache when the parameter is null/empty. This happens when the user searches for all pet owners and leaves the search field blanks.

October 11, 2013

Page 34

Collection<Owner> results; if(owner.getLastName().trim().isEmpty()) { results = this.clinicService.findOwnerByLastName( owner.getLastName()); } else{ List<String> param = new ArrayList<String>(); param.add( owner.getLastName()); results = this.clinicService.findOwnerByLastName( param); }

With that we conclude coverage of the code changes required to add Windows Azure SQL Database, Memcached, and Transient Fault Exception Handling to the Spring Framework Pet Clinic Demo. In the following sections we describe how to package and deploy Pet Clinic to Azure Compute.

VII. Windows Azure Java Application Lifecycle


Deployment Consideration: Modifying Code to Maintain Database during Instance Redeployments
After following the steps above, successfully building, and initial run locally in Tomcat, the database will be built on the target environment in a Windows Azure SQL Database. For subsequent runs, you need to decide which behavior will follow. Depending on your deployment architecture, you have two options: 1. Redeploy the database each build: Doing nothing will result in the database entities being rebuilt each build. This is generally desirable in early phases of development. 2. Maintain the database: (RECOMMENDED) If your database structures are stable, you want to leave the database in its current state. Therefore, comment out the initialize-database section of the applicationContext-dataSource.xml file. (~\src\main\resources\spring\datasource-config.xml) <!-<jdbc:initialize-database data-source="dataSource"> <jdbc:script location="${jdbc.initLocation}"/> <jdbc:script location="${jdbc.dataLocation}"/> <jdbc:script location="${jdbc.logdataLocation}"/> </jdbc:initialize-database> -->

October 11, 2013

Page 35

VIII. Windows Azure Java Application Lifecycle: Creating a New Azure Deployment Project
Now you are ready to start deploying to Window Azure Compute. Before we can deploy to Windows Azure, we must create an Azure Deployment Project. On a high level, the steps to create a deployment project are as follows: 1. 2. 3. 4. --Export the WAR file Create a Windows Azure Deployment Project Deploy to the local Windows Azure Compute emulator Publish to the Windows Azure cloud

Step 1: Export WAR File


NOTE: To have Petclinic run as the root site of Tomcat you need to name the war file as ROOT.war. If you name the war file something like PetClinic.war then the URL will be http://localhost/petclinic. See Tomcat documentation for details. 1. In Eclipse (STS), right-click the Package Explorer Window, and then click Export 2. In the Export window, select WAR under the Web folder and then click Next

3. Select your web project and then select the destination area, as the place in which you are maintaining your source code. 4. Set Target Runtime to Apache 7.0.

October 11, 2013

Page 36

5. Click Finish.

Step 2: Create a Windows Azure Deployment Project


1. While focus is on your project in STSs Project Explorer, select the New Windows Azure Deployment Project button.

2. A new deployment project wizard window opens. Name your project and then click Next. a. Note: Your project name must be unique from what you have named your source-code file directory.

3. Hit Next, then select the latest JDK, (which you have already downloaded).

October 11, 2013

Page 37

4. Hit Next, then select the application server. Select Apache Tomcat 7.

October 11, 2013

Page 38

Note: The Tomcat directory here is not the path to your local Tomcat instance. Instead, it is a path to the Tomcat extracted files from a zip file. Import WAR File 5. Hit Next, under Application, click Add. The Add Application window will open. Click Browse and then point to the Pet Clinic sample application which if you followed steps from above is named ROOT.war which is a reserved name in Tomcat for the root app. Click OK and your web application will be included in the list of applications.

6. Click Finish. 7. Open the new deployment project, PetClinicAzureDeployment 8. Notice the WorkerRole1 that was created. Right mouse click on it, select Windows Azure -> properties. You should see this:

October 11, 2013

Page 39

9. Increase numbers of instances as appropriate. This will set an initial deployment count. This can be increased or decreased from web service calls or the Windows Azure Portal UI later after deployment. Note: a minimum of 2 is required for high availability option in Caching. 10. Select Caching

a. Click on Enable co-located caching to use all the compute instances in the deployment as cache servers. b. Since we have more than one instance, select High Availability to Yes. c. NOTE: the Host name is localhost_workerrole1, make sure the SSM address provider in toolsconfig.xml is set like:
<property name="addressProvider"> <bean class="com.google.code.ssm.config.DefaultAddressProvider"> <property name="address" value="localhost_WorkerRole1:11211" /> </bean>

If not, then fix this and re-export your war file. As long as you deploy the war file to the same location the Azure Deployment Project will pick up the new war during build. d. Right click on the PetClinicAzureDeploymentProject again. Bring up Windows Azure Properties. Click on Subscriptions.

October 11, 2013

Page 40

e. If no account settings have previously been downloaded click in Import from PUBLISH -SETTINGS File

f. Click on Download PUBLISH-SETTINGS File, you will be connected to the Windows Azure portal. g. After logging into the portal, a download of your account settings will start automatically. Save the file with your project. h. Now click Browse on the Import Subscription Information window, and import the file downloaded. i. Now you can select the storage account from the drop down list. j. Click Ok.

October 11, 2013

Page 41

Step 3: Deploy to the Windows Azure Compute local emulator


1. Click the Run in Windows Azure Emulator button on the taskbar.

2. After Tomcat has started, open a browser...

3. You can now test your application and debug locally.

October 11, 2013

Page 42

Step 4: Publish to the Windows Azure Cloud: Staging and Production


When you are ready to deploy into Windows Azure, follow the below steps. 1. In Eclipse (STS), click the Publish to Windows Azure Cloud button.

2. The Publish Wizard will appear, import your Azure settings you downloaded in when we deployed to emulator. This will import all your subscription information. 3. If you dont have an existing storage account you can create a new storage account for your deployment by clicking New next to Storage Account. In the New Storage Account window, provide a unique name and access key. 4. Create a new Cloud Service by clicking on New next to Service Name. In the New Cloud Service window, provide a unique name and location. 5. Set Target environment to Production

October 11, 2013

Page 43

6. Click Publish and watch the progress in Eclipse (STS). A typical deployment can take a few minutes.

In this example, since the service name is petclinic the URL in Windows Azure will be:

IX. Reference Articles


Caching in Windows Azure Introduction to Windows Azure What's New in the Windows Azure Plugin for Eclipse with Java (by Microsoft Open Technologies) Windows Azure SQL Database Debugging Windows Azure applications in Eclipse

October 11, 2013

Page 44

October 11, 2013

Page 45

Você também pode gostar