Monday, April 22, 2013

Openshift, como configurar o DataSource para o MySQL no Tomcat 7

Nesse post descrevo como configurar o componente DataSource para o banco de dados MySQL, no Tomcat 7 dentro do OpenShift. O OpenShift é a plataforma de cloud computing da Red Hat, um serviço na modalidade PaaS (Plataform as a Service), que disponibiliza uma infra-estrutura pré-definida para implantação de projetos em nuvem. No OpenShift é possível implantar projetos desenvolvidos em Java, Python, Ruby, JavaScript, PHP ou Perl.

No contexto desse post, configuramos no OpenShift uma aplicação web com uma instância (cartridge) de Tomcat 7 (JBoss EWS) e MySQL 5.1. Com o uso de DataSource, o Tomcat é o responsável por gerenciar (abrir / manter / encerrar) as conexões com o MySQL. A nossa aplicação Java solicita (JNDI) ao Tomcat a referência para o DataSource para acessar os dados.

Depois de criar a aplicação no Openshift e instalar a chave ssh, faça o clone do repositório git em sua máquina (local).

yaw@local/~$ git clone ssh:{hash_}@{app-namespace}.rhcloud.com/~/git/{app}.git

A url git do repositório fica disponível na página do projeto (My Apps no OpenShift).

Definir o DataSource

No repositório local além dos fontes, nós temos acesso a alguns arquivos de configurações dos serviços disponíveis do Openshift. Vamos utilizar alguns desses arquivos para definir do DataSource no Tomcat.

Depois de baixar o repositório (git), entre na pasta do projeto que foi clonado e acesse o subdiretório .openshift:
yaw@local/~$ cd app
yaw@local/~/app$ cd .openshift/

Agora acesse o subdiretório config, local aonde ficam os arquivos de configuração do Tomcat, e modifique o conteúdo do arquivo server.xml:
yaw@local/~/app/.openshift$ cd config
yaw@local/~/app/.openshift/config$ gedit server.xml

No arquivo server.xml é necessário definir a tag Resource com as propriedades do DataSource. Atenção: escreva essa tag dentro da tag GlobalNamingResources, e não remova nenhum conteúdo desse arquivo!

A seguir o trecho do server.xml com a definição da tag Resource (boa parte do conteúdo desse arquivo foi omitido):
<?xml version='1.0' encoding='utf-8'?>
<Server port="-1" shutdown="SHUTDOWN">
  ...

  <GlobalNamingResources>
     ...
    <!-- mysql datasource definition -->
    <Resource auth="Container" driverClassName="com.mysql.jdbc.Driver" type="javax.sql.DataSource" 
      maxActive="20" maxIdle="10" maxWait="-1" name="jdbc/MysqlDS" 
      username="{database_username}" password="{database_password}" 
      url="jdbc:mysql://${env.OPENSHIFT_MYSQL_DB_HOST}:${env.OPENSHIFT_MYSQL_DB_PORT}/{database}" />

  </GlobalNamingResources>

  ...
</Server>

Importante: substitua os valores {database_username}, {database_password} e {database} para os respectivos valores de seu serviço MySQL. Note que utilizei na propriedade name o valor padrão "jdbc/MysqlDS". Esse valor será utilizado posteriormente, na configuração de persistência da aplicação (persistence.xml).

Agora modifique o arquivo context.xml, no mesmo diretório, para definir o link com o DataSource que acabamos de definir. Utilize a tag ResourceLink, conforme o exemplo a seguir:
<?xml version='1.0' encoding='utf-8'?>
<Context>

  <!-- Default set of monitored resources -->
  <WatchedResource>WEB-INF/web.xml</WatchedResource>

  <!-- link for mysql datasource -->
  <ResourceLink name="jdbc/MysqlDS" global="jdbc/MysqlDS" type="javax.sql.DataSource"/>

  ...
</Context>

Instalar o driver JDBC

Agora precisamos instalar no Tomcat o jar do driver MySQL JDBC. O OpenShift mantém restrições de segurança em boa parte da estrutura de arquivos da plataforma. Não é possível copiar um arquivo para a pasta lib do Tomcat. O jar deve ser instalado na pasta app-root/data/ do Openshift. Você pode acessar o OpenShift via ssh e fazer um wget do jar, ou então copiar o arquivo em uma pasta acessível no OpenShift.

A seguir o comando scp para copiar o arquivo da máquina local para o OpenShift (assumindo que o arquivo mysql-connector-java.jar está armazenado em /home/yaw/):
yaw@local/~/app/.openshift/config$ scp /home/yaw/mysql-connector-java.jar
   {hash_}@{app-namespace}.rhcloud.com/~/app-root/data/

Agora é necessário configurar o diretório app-root/data no classpath do Tomcat. Vamos fazer isso no arquivo catalina.properties, que também fica no diretório {app}/.openshift/config/. Abra o arquivo e procure pela chave common.loader.
yaw@local/~/app/.openshift/config$ gedit catalina.properties

Adicione no fim da propriedade common.loader o conteúdo: ,${catalina.home}/../data/*.jar

A seguir o trecho do properties com essa configuração:
#...
common.loader=${catalina.base}/lib,${catalina.base}/lib/*.jar
  ,${catalina.home}/lib,${catalina.home}/lib/*.jar
  ,${catalina.home}/../app-root/data/*.jar

Publicar as modificações

Próxima etapa é efetivar as modificações nos arquivos de configuração do Tomcat, vamos fazer um commit e push no repositório:
yaw@local/~/app/$ git commit -m "mysql datasource config"
yaw@local/~/app/$ git push

Após concluir o push (no repositório remoto) você pode notar que o OpenShift reinicializa os serviços (inclusive o Tomcat).

Configuração na aplicação Java

Agora que o DataSource já foi instalado no Tomcat, resta configurá-lo na aplicação Java. Isso pode ser feito no arquivo persistence.xml, assumindo que o projeto utiliza JPA, através da tag non-jta-data-source. Curiosidade, no exemplo a seguir utilizo o Hibernate como provider JPA:

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0"
  xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
  <persistence-unit name="appUnit" transaction-type="RESOURCE_LOCAL">
    <provider>org.hibernate.ejb.HibernatePersistence</provider>
    <non-jta-data-source>java:/comp/env/jdbc/MysqlDS</non-jta-data-source>
    <properties>
      <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect" />
      <property name="hibernate.show_sql" value="true" />
      <property name="hibernate.hbm2ddl.auto" value="update" />
      <property name="hibernate.connection.charSet" value="UTF-8" />
    </properties>
  </persistence-unit>
</persistence>

Pronto, agora é fazer o commit e o push do código fonte e testar a aplicação no OpenShift. Na YaW desenvolvemos algumas demos no OpenShift.

http://twitter.com/edermag
http://www.yaw.com.br

3 comments:

Cleverton Heusner said...

Edemarg, estou tentando há dois dias configurar um DataSource usando Eclipse, Tomcat 7, MySQL e Hibernate, mas tudo o que vejo é a seguinte exceção sendo lançada ao rodar a aplicação:

javax.naming.NameNotFoundException: Name [java:comp/env/jdbc/LocadoraDB] is not bound in this Context. Unable to find [java:comp].

O que eu poderia estar fazendo de errado, já que nenhuma solução que vi em posts, artigos e documentações parece funcionar?

Fabiano Góes said...

Edermag, muito bom seu post, me ajudou muito a entender melhor como funciona a estrutura do openshift, agora ficou facil demais e muito profissional,
obrigado por compartilhar seu conhecimento, um abraço!

Blogger said...

AvaHost is definitely the best web-hosting provider with plans for all of your hosting requirements.