domingo, 20 de setembro de 2020

Criar e publicar um web service grátis com Heroku


 Olá pessoal!


Nesse artigo quero mostrar como colocar um web service em um servidor gratuito, o Heroku. Inicialmente, é claro, você terá que acessar o site https://heroku.com e em seguida criar uma conta. Feito isso, pode continuar com o tutorial.

O código fonte desse projeto você pode baixar em:

https://github.com/igorthribeiro/pagamento-heroku


1. Iniciando um projeto no eclipse:

Para a criação desse projeto eu utilizei o eclipse-oxygen-3a for Java EE Developers que pode ser baixado no link https://www.eclipse.org/downloads/packages/release/oxygen/3a.

Eu vou dar continuidade ao projeto que eu criei no webinar da Ka Solution. Você pode acessar o vídeo do webinar no link https://youtu.be/1NdM68V-KCM.


        a) Peça um novo projeto no eclipse e escolha a opção Maven Project:

 


        b) Click Next escolha o melhor lugar para criar seu projeto e em seguida Next novamente e escolha do arquétipo maven-arquetype-webapp


 

        c) Clique Next outra vez, dê o nome para o projeto e em seguida clique Finish:

 



2. Incluindo as dependências (pom.xml)

    Vamos colocar as dependências do projeto configurando o arquivo pom.xml. Essa configuração é necessária para que, no momento da compilação e deploy do projeto, os jars sejam baixados e compilados junto. Você pode simplesmente copiar e colar o código abaixo para o pom.xml do seu projeto:

 <project xmlns="http://maven.apache.org/POM/4.0.0"  
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
      xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">  
      <modelVersion>4.0.0</modelVersion>  
      <groupId>igordev</groupId>  
      <artifactId>pagamento-app</artifactId>  
      <packaging>war</packaging>  
      <version>0.0.1-SNAPSHOT</version>  
      <name>pagamento-app Maven Webapp</name>  
      <url>http://maven.apache.org</url>  
      <properties>  
           <spring.version>4.2.3.RELEASE</spring.version>  
      </properties>  
      <dependencies>  
           <!-- DEPENDÊNCIAS DO SPRING -->  
           <dependency>  
                <groupId>org.springframework</groupId>  
                <artifactId>spring-aop</artifactId>  
                <version>${spring.version}</version>  
           </dependency>  
           <dependency>  
                <groupId>org.springframework</groupId>  
                <artifactId>spring-aspects</artifactId>  
                <version>${spring.version}</version>  
           </dependency>  
           <dependency>  
                <groupId>org.springframework</groupId>  
                <artifactId>spring-beans</artifactId>  
                <version>${spring.version}</version>  
           </dependency>  
           <dependency>  
                <groupId>org.springframework</groupId>  
                <artifactId>spring-context</artifactId>  
                <version>${spring.version}</version>  
           </dependency>  
           <dependency>  
                <groupId>org.springframework</groupId>  
                <artifactId>spring-core</artifactId>  
                <version>${spring.version}</version>  
           </dependency>  
           <dependency>  
                <groupId>org.springframework</groupId>  
                <artifactId>spring-expression</artifactId>  
                <version>${spring.version}</version>  
           </dependency>  
           <dependency>  
                <groupId>org.springframework</groupId>  
                <artifactId>spring-instrument</artifactId>  
                <version>${spring.version}</version>  
           </dependency>  
           <dependency>  
                <groupId>org.springframework</groupId>  
                <artifactId>spring-instrument-tomcat</artifactId>  
                <version>${spring.version}</version>  
           </dependency>  
           <dependency>  
                <groupId>org.springframework</groupId>  
                <artifactId>spring-jdbc</artifactId>  
                <version>${spring.version}</version>  
           </dependency>  
           <dependency>  
                <groupId>org.springframework</groupId>  
                <artifactId>spring-jms</artifactId>  
                <version>${spring.version}</version>  
           </dependency>  
           <dependency>  
                <groupId>org.springframework</groupId>  
                <artifactId>spring-messaging</artifactId>  
                <version>${spring.version}</version>  
           </dependency>  
           <dependency>  
                <groupId>org.springframework</groupId>  
                <artifactId>spring-orm</artifactId>  
                <version>${spring.version}</version>  
           </dependency>  
           <dependency>  
                <groupId>org.springframework</groupId>  
                <artifactId>spring-oxm</artifactId>  
                <version>${spring.version}</version>  
           </dependency>  
           <dependency>  
                <groupId>org.springframework</groupId>  
                <artifactId>spring-test</artifactId>  
                <version>${spring.version}</version>  
                <scope>test</scope>  
           </dependency>  
           <dependency>  
                <groupId>org.springframework</groupId>  
                <artifactId>spring-tx</artifactId>  
                <version>${spring.version}</version>  
           </dependency>  
           <dependency>  
                <groupId>org.springframework</groupId>  
                <artifactId>spring-web</artifactId>  
                <version>${spring.version}</version>  
           </dependency>  
           <dependency>  
                <groupId>org.springframework</groupId>  
                <artifactId>spring-webmvc</artifactId>  
                <version>${spring.version}</version>  
           </dependency>  
           <dependency>  
                <groupId>org.springframework</groupId>  
                <artifactId>spring-webmvc-portlet</artifactId>  
                <version>${spring.version}</version>  
           </dependency>  
           <dependency>  
                <groupId>org.springframework</groupId>  
                <artifactId>spring-websocket</artifactId>  
                <version>${spring.version}</version>  
           </dependency>  
           <!-- DEMAIS DEPENDÊNCIAS -->  
           <dependency>  
                <groupId>antlr</groupId>  
                <artifactId>antlr</artifactId>  
                <version>2.7.7</version>  
           </dependency>  
           <dependency>  
                <groupId>aopalliance</groupId>  
                <artifactId>aopalliance</artifactId>  
                <version>1.0</version>  
           </dependency>  
           <dependency>  
                <groupId>com.fasterxml</groupId>  
                <artifactId>classmate</artifactId>  
                <version>1.0.0</version>  
           </dependency>  
           <dependency>  
                <groupId>org.apache.commons</groupId>  
                <artifactId>commons-dbcp2</artifactId>  
                <version>2.4.0</version>  
           </dependency>  
           <dependency>  
                <groupId>commons-logging</groupId>  
                <artifactId>commons-logging</artifactId>  
                <version>1.2</version>  
           </dependency>  
           <dependency>  
                <groupId>org.apache.commons</groupId>  
                <artifactId>commons-pool2</artifactId>  
                <version>2.6.2</version>  
           </dependency>  
           <dependency>  
                <groupId>dom4j</groupId>  
                <artifactId>dom4j</artifactId>  
                <version>1.6.1</version>  
           </dependency>  
           <dependency>  
                <groupId>org.hibernate.common</groupId>  
                <artifactId>hibernate-commons-annotations</artifactId>  
                <version>4.0.4.Final</version>  
           </dependency>  
           <dependency>  
                <groupId>org.hibernate</groupId>  
                <artifactId>hibernate-core</artifactId>  
                <version>4.3.0.Final</version>  
           </dependency>  
           <dependency>  
                <groupId>org.hibernate</groupId>  
                <artifactId>hibernate-entitymanager</artifactId>  
                <version>4.3.0.Final</version>  
           </dependency>  
           <dependency>  
                <groupId>org.hibernate.javax.persistence</groupId>  
                <artifactId>hibernate-jpa-2.1-api</artifactId>  
                <version>1.0.0.Final</version>  
           </dependency>  
           <dependency>  
                <groupId>org.hibernate</groupId>  
                <artifactId>hibernate-validator</artifactId>  
                <version>5.0.2.Final</version>  
           </dependency>  
           <dependency>  
                <groupId>com.fasterxml.jackson.core</groupId>  
                <artifactId>jackson-databind</artifactId>  
                <version>2.11.1</version>  
           </dependency>  
           <dependency>  
                <groupId>com.fasterxml.jackson.core</groupId>  
                <artifactId>jackson-core</artifactId>  
                <version>2.11.1</version>  
           </dependency>  
           <dependency>  
                <groupId>com.fasterxml.jackson.core</groupId>  
                <artifactId>jackson-annotations</artifactId>  
                <version>2.11.1</version>  
           </dependency>  
           <dependency>  
                <groupId>org.codehaus.jackson</groupId>  
                <artifactId>jackson-mapper-asl</artifactId>  
                <version>1.9.13</version>  
           </dependency>  
           <dependency>  
                <groupId>org.jboss</groupId>  
                <artifactId>jandex</artifactId>  
                <version>1.1.0.Final</version>  
           </dependency>  
           <dependency>  
                <groupId>org.javassist</groupId>  
                <artifactId>javassist</artifactId>  
                <version>3.18.1-GA</version>  
           </dependency>  
           <dependency>  
                <groupId>org.glassfish.web</groupId>  
                <artifactId>javax.servlet.jsp.jstl</artifactId>  
                <version>1.2.1</version>  
           </dependency>  
           <dependency>  
                <groupId>javax.servlet.jsp.jstl</groupId>  
                <artifactId>javax.servlet.jsp.jstl-api</artifactId>  
                <version>1.2.1</version>  
           </dependency>  
           <dependency>  
                <groupId>org.jboss.logging</groupId>  
                <artifactId>jboss-logging</artifactId>  
                <version>3.1.3.GA</version>  
           </dependency>  
           <dependency>  
                <groupId>org.jboss.logging</groupId>  
                <artifactId>jboss-logging-annotations</artifactId>  
                <version>1.2.0.Beta1</version>  
                <scope>provided</scope>  
           </dependency>  
           <dependency>  
                <groupId>org.jboss.spec.javax.transaction</groupId>  
                <artifactId>jboss-transaction-api_1.2_spec</artifactId>  
                <version>1.0.0.Final</version>  
           </dependency>  
           <dependency>  
                <groupId>org.postgresql</groupId>  
                <artifactId>postgresql</artifactId>  
                <version>9.4.1211</version>  
           </dependency>  
           <dependency>  
                <groupId>javax.validation</groupId>  
                <artifactId>validation-api</artifactId>  
                <version>1.1.0.Final</version>  
           </dependency>  
           <dependency>  
                <groupId>junit</groupId>  
                <artifactId>junit</artifactId>  
                <version>3.8.1</version>  
                <scope>test</scope>  
           </dependency>  
           <dependency>  
                <groupId>junit</groupId>  
                <artifactId>junit</artifactId>  
                <version>3.8.1</version>  
                <scope>test</scope>  
           </dependency>  
      </dependencies>  
      <build>  
           <finalName>pagamento-app</finalName>  
           <plugins>  
                <plugin>  
                     <artifactId>maven-compiler-plugin</artifactId>  
                     <configuration>  
                          <source>1.8</source>  
                          <target>1.8</target>  
                     </configuration>  
                </plugin>  
                <plugin>  
                     <groupId>org.apache.maven.plugins</groupId>  
                     <artifactId>maven-dependency-plugin</artifactId>  
                     <executions>  
                          <execution>  
                               <phase>package</phase>  
                               <goals>  
                                    <goal>copy</goal>  
                               </goals>  
                               <configuration>  
                                    <artifactItems>  
                                         <artifactItem>  
                                              <groupId>com.heroku</groupId>  
                                              <artifactId>webapp-runner</artifactId>  
                                              <version>9.0.30.0</version>  
                                              <destFileName>webapp-runner.jar</destFileName>  
                                         </artifactItem>  
                                    </artifactItems>  
                               </configuration>  
                          </execution>  
                     </executions>  
                </plugin>  
           </plugins>  
      </build>  
 </project>  


    Esse arquivo contém as dependências do Spring Framework, Jackson e Postgresql. Se você verificar irá ver que existe quase no final do arquivo um plugin que aponta para o Dyno do projeto com o nome webapp-runner.jar que como o nome já sugere, será utilizado pelo Heroku para iniciar seu web service. Vamos falar mais sobre Dynos mais adiante nesse tutorial.


3. Criando os pacotes

        Para esse projeto, vou criar 3 pacotes:

         br.com.igordev.dominio

         br.com.igordev.dao

         br.com.igordev.controller


    No pacote dominio vamos colocar nosso POJO, no pacote DAO a classe responsável pelo gerenciamento do banco de dados e finalmente no pacote controller a classe que irá gerenciar as requisições do nosso web service. 

    Antes da criação dos pacotes, vamos criar no projeto uma pasta java dentro da pasta main. Clique com o botão direito na pasta  main > New > Folder, dê o nome java e clique Finish:


 

    Para criar os pacotes, clique com o botão direito na pasta src/main/java > New > Package. Dê o nome para o pacote e clique em Finish



    Repita o mesmo procedimento para os demais pacotes do projeto.


4. POJO

    No pacote dominio vamos incluir o POJO Pagamento como foi feito durante o webinar. Para isso, basta criar uma classe java clicando com o botão direito no pacote dominio > New > Class, dê o nome Pagamento para a classe e clique Finish:



    Substitua todo conteúdo da classe criada pelo código abaixo:


 package br.com.igordev.dominio;  
 import java.time.LocalDate;  
 import javax.persistence.Entity;  
 import javax.persistence.GeneratedValue;  
 import javax.persistence.GenerationType;  
 import javax.persistence.Id;  
 import com.fasterxml.jackson.annotation.JsonFormat;  
 @Entity  
 public class Pagamento {  
   @Id  
   @GeneratedValue(strategy=GenerationType.IDENTITY)  
   private Integer codigo;  
   private String descricao;  
   @JsonFormat(pattern = "dd/MM/yyyy")  
   private LocalDate dataVencimento;  
   private Double valor;  
   private Boolean pago;  
   public Pagamento() {  
   }  
   public Pagamento(String descricao, LocalDate dataVencimento, Double valor, Boolean pago) {  
     this.descricao = descricao;  
     this.dataVencimento = dataVencimento;  
     this.valor = valor;  
     this.pago = pago;  
   }  
   public Boolean getPago() {  
     return pago;  
   }  
   public void setPago(Boolean pago) {  
     this.pago = pago;  
   }  
   public Integer getCodigo() {  
     return codigo;  
   }  
   public void setCodigo(Integer codigo) {  
     this.codigo = codigo;  
   }  
   public String getDescricao() {  
     return descricao;  
   }  
   public void setDescricao(String descricao) {  
     this.descricao = descricao;  
   }  
   public LocalDate getDataVencimento() {  
     return dataVencimento;  
   }  
   public void setDataVencimento(LocalDate dataVencimento) {  
     this.dataVencimento = dataVencimento;  
   }  
   public Double getValor() {  
     return valor;  
   }  
   public void setValor(Double valor) {  
     this.valor = valor;  
   }  
      @Override  
   public String toString() {  
     return "Pagamento{" + "codigo=" + codigo + ", descricao=" + descricao + ", dataVencimento=" + dataVencimento + ", valor=" + valor + ", pago=" + pago + '}';  
   }  
 }  


5. Criação do DAO


    Vamos utilizar o Hibernate + Spring para gerenciar nosso contexto de persistência. Mais adiante no tutorial, vou comentar sobre a criação da conexão com o BD e ainda falar sobre como o Spring gerencia e injeta essa conexão automaticamente dentro do nosso DAO.

    Clique com o botão direito no pacote dao > New > Class, dê o nome de JpaPagamentoDao e clique Finish. Em seguida, substitua todo conteúdo da classe pelo código abaixo:


 package br.com.igordev.dao;  
 import java.time.LocalDate;  
 import java.util.ArrayList;  
 import java.util.List;  
 import javax.persistence.EntityManager;  
 import javax.persistence.PersistenceContext;  
 import org.springframework.stereotype.Repository;  
 import br.com.igordev.dominio.Pagamento;  
 @Repository  
 public class JpaPagamentoDao {  
   private static List<Pagamento> pagamentos = new ArrayList<>();  
   static {  
     pagamentos.add(new Pagamento("Mouse", LocalDate.of(2020,8,20), 45.00, true));  
     pagamentos.add(new Pagamento("Teclado", LocalDate.now(), 145.00, false));  
     pagamentos.add(new Pagamento("Material Escritório", LocalDate.of(2020,7,12), 200.00, false));  
     pagamentos.add(new Pagamento("Cursos", LocalDate.of(2020,8,19), 2300.00, true));  
     pagamentos.add(new Pagamento("Cadeira", LocalDate.of(2020,9,5), 750.00, false));  
     pagamentos.add(new Pagamento("Energia", LocalDate.of(2020,10,10), 280.00, false));  
     pagamentos.add(new Pagamento("Fatura Celular", LocalDate.now(), 190.00, false));  
     pagamentos.add(new Pagamento("Fatura Netflix", LocalDate.of(2020,11,15), 60.00, false));  
   }  
      @PersistenceContext  
      EntityManager manager;  
      public void popula() {  
           pagamentos  
                .forEach(manager::persist);  
      }  
      public void exclui(Pagamento Pagamento) {  
           manager.remove(Pagamento);  
      }  
      public Pagamento buscaPorId(int id) {  
           return manager.find(Pagamento.class, id);  
      }  
      public List<Pagamento> buscaTodos() {  
           return manager.createQuery("select f from Pagamento f", Pagamento.class).getResultList();  
      }  
 }  


6. Criação do Restful Controller


    O Spring irá gerenciar as requisições feitas ao nosso web service, logo, precisamos criar no pacote controller uma classe capaz de entender essas requisições e repassá-las para o método que irá executar o serviço solicitado. Para esse projeto, vou disponibilizar os seguintes serviços:

         popula: será utilizado para inserir automaticamente alguns pagamentos no banco de dados;

         get-pagamentos: mostra todos os pagamentos cadastrados;

         get-pagamento/id: busca o pagamento pelo código

         remove-pagamento/id: remove o pagamento pelo código


        Clique com o botão direito no pacote controller > New > Class de o nome para a classe de RestfulController e clique Finish. Substitua o conteúdo do arquivo pelo código abaixo:


 package br.com.igordev.controller;  
   
 import java.util.List;  
   
 import javax.transaction.Transactional;  
   
 import org.springframework.beans.factory.annotation.Autowired;  
 import org.springframework.beans.factory.annotation.Qualifier;  
 import org.springframework.http.MediaType;  
 import org.springframework.web.bind.annotation.CrossOrigin;  
 import org.springframework.web.bind.annotation.PathVariable;  
 import org.springframework.web.bind.annotation.RequestBody;  
 import org.springframework.web.bind.annotation.RequestMapping;  
 import org.springframework.web.bind.annotation.RequestMethod;  
 import org.springframework.web.bind.annotation.ResponseBody;  
 import org.springframework.web.bind.annotation.RestController;  
   
 import br.com.igordev.dao.JpaPagamentoDao;  
 import br.com.igordev.dominio.Pagamento;  
   
 @CrossOrigin(origins = "*", allowedHeaders = "*")  
 @Transactional  
 @RestController  
 public class RestfulController {  
        
      @Autowired  
      @Qualifier("jpaPagamentoDao")  
      private JpaPagamentoDao dao;  
        
        
      @RequestMapping("/")  
      public String index() {  
           return "index";  
      }  
        
      @RequestMapping(value = "popula", method = RequestMethod.GET)  
      @ResponseBody  
      public String populaPagamentos() {  
           dao.popula();  
           return "<h3>dados populados!</h3>";  
      }  
   
      @RequestMapping(value = "get-pagamentos", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)  
      @ResponseBody  
      public List<Pagamento> getPagamentos() {  
           return dao.buscaTodos();  
      }  
   
      @RequestMapping(value = "get-pagamento/{id}", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)  
      @ResponseBody  
      public Pagamento getPagamento(@PathVariable("id") int id) {  
           return dao.buscaPorId(id);  
      }  
   
      @RequestMapping(value = "remove-pagamento/{id}", method = RequestMethod.GET)  
      @ResponseBody  
      public String remove(@PathVariable("id") int id) {  
           Pagamento p = dao.buscaPorId(id);  
           dao.exclui(p);  
           return "<h3>pagamento exluido!</h3>";  
      }  
   
 }  
   



7. Configuração do Spring no projeto


    Toda parte de codificação já está pronta, resta agora configurar o projeto para que o servidor consiga identificar nosso controller e atender as requisições. Vamos primeiro configurar o arquivo WEB-INF/web.xml pois, é nesse arquivo direcionamos todas as requisições para o Spring Framework:

    Abra o arquivo web.xml e substitua o todo conteúdo pelo código abaixo:


 <?xml version="1.0" encoding="UTF-8"?>  
 <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">  
  <display-name>pagamento-app</display-name>  
  <welcome-file-list>  
   <welcome-file>index.html</welcome-file>  
   <welcome-file>index.htm</welcome-file>  
   <welcome-file>index.jsp</welcome-file>  
   <welcome-file>default.html</welcome-file>  
   <welcome-file>default.htm</welcome-file>  
   <welcome-file>default.jsp</welcome-file>  
  </welcome-file-list>  
    
    
   <servlet>  
     <servlet-name>Spring MVC Dispatcher Servlet</servlet-name>  
     <servlet-class>  
       org.springframework.web.servlet.DispatcherServlet  
     </servlet-class>  
     <init-param>  
       <param-name>contextConfigLocation</param-name>  
       <param-value>  
         /WEB-INF/dispatcher-servlet.xml  
       </param-value>  
     </init-param>  
     <load-on-startup>1</load-on-startup>  
   </servlet>  
   
   <servlet-mapping>  
     <servlet-name>Spring MVC Dispatcher Servlet</servlet-name>  
     <url-pattern>/</url-pattern>  
   </servlet-mapping>  
    
    
 </web-app>  


    Basicamente o que fizemos foi registrar no web.xml o DispatcherServlet que é o Front Controller do Spring, responsável por atender as requisições e repassá-las para os controllers do projeto. O Spring tem um arquivo de configuração próprio que nesse projeto demos o nome de dispatcher-servlet.xml que é onde irá ficar todas as configurações necessárias para que o Spring encontre nossa classe RestfulController.java e saiba como criar uma conexão com o banco de dados e injetá-la no nosso DAO

    Vamos criar na pasta WEB-INF o arquivo dispatcher-servlet.xml. Clique com o direito na pasta WEB-INF > New > File, dê o nome de dispatcher-servlet.xml e clique Finish. Substitua todo conteúdo do arquivo pelo código abaixo:


 <?xml version="1.0" encoding="UTF-8"?>  
 <beans xmlns="http://www.springframework.org/schema/beans"  
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
      xmlns:context="http://www.springframework.org/schema/context"  
      xmlns:mvc="http://www.springframework.org/schema/mvc"  
      xmlns:tx="http://www.springframework.org/schema/tx"  
      xsi:schemaLocation="http://www.springframework.org/schema/mvc   
                               http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd  
                               http://www.springframework.org/schema/beans   
                               http://www.springframework.org/schema/beans/spring-beans-4.0.xsd  
                               http://www.springframework.org/schema/context   
                               http://www.springframework.org/schema/context/spring-context-4.0.xsd  
                               http://www.springframework.org/schema/tx   
                               http://www.springframework.org/schema/tx/spring-tx-4.0.xsd  
                               http://www.springframework.org/schema/aop  
                               http://www.springframework.org/schema/aop/spring-aop-4.0.xsd">  
   
   
      <context:component-scan  
           base-package="br.com.igordev" />  
   
      <mvc:annotation-driven />  
   
      <tx:annotation-driven />  
   
      <bean id="databaseCredentials"  
           class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">  
   
           <property name="location" value="WEB-INF/database.properties" />  
   
      </bean>  
   
      <bean id="postgresDataSource"  
           class="org.apache.commons.dbcp2.BasicDataSource">  
           <property name="driverClassName"  
                value="org.postgresql.Driver" />  
           <property name="url"  
                value="jdbc:postgresql://${database.host}:${database.port}/${database.schema}" />  
           <property name="username" value="${database.username}" />  
           <property name="password" value="${database.password}" />  
      </bean>  
   
      <!-- gerenciamento de jpa pelo spring -->  
      <bean id="entityManagerFactory"  
           class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">  
           <property name="dataSource" ref="postgresDataSource" />  
           <property name="packagesToScan">  
                <list>  
                     <value>br.com.igordev.dominio</value>  
                </list>  
           </property>  
           <property name="persistenceUnitName" value="funcionario" />  
           <property name="jpaVendorAdapter">  
                <bean  
                     class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" />  
           </property>  
           <property name="jpaProperties">  
                <props>  
                     <prop key="hibernate.dialect">org.hibernate.dialect.PostgreSQL9Dialect</prop>  
                     <prop key="hibernate.show_sql">true</prop>  
                     <prop key="hibernate.format_sql">true</prop>  
                     <prop key="hibernate.hbm2ddl.auto">update</prop>  
                </props>  
           </property>  
      </bean>  
   
      <!-- gerenciamento de transações pelo spring -->  
      <bean id="transactionManager"  
           class="org.springframework.orm.jpa.JpaTransactionManager">  
           <property name="entityManagerFactory"  
                ref="entityManagerFactory" />  
      </bean>  
   
      <bean  
           class="org.springframework.web.servlet.view.InternalResourceViewResolver">  
           <property name="prefix" value="/WEB-INF/jsp/" />  
           <property name="suffix" value=".jsp" />  
      </bean>  
   
 </beans>  


    Se você observar esse arquivo, irá encontrar nele 3 beans responsáveis por gerenciar o acesso ao banco de dados:


         entityManagerFactory: responsável por encontrar nosso POJO, criar a tabela correspondente no banco de dados e injetar o entityManager no DAO. Nesse bean usamos a propriedade packagesToScan para registrar o local onde o Spring irá buscar os POJOs.

         postgresDataSource: utilizado para abrir uma conexão com o banco de dados e repassá-la para o EntityManagerFactory.

         databaseCredentials: Arquivo que contém as credenciais do banco. Esse arquivo será criado no passo 9.



8. Logando no heroku, criando a app e adicionando um Datasource

    Nesse momento, vamos dar uma pausa no projeto e criar a aplicação no Heroku. Esse passo é necessário para que possamos pegar as credenciais do BD que será incluído no nosso projeto.

    Para utilização do Heroku você também precisará do Git (não é necessário ter uma conta no github, mas eu recomendo). Acesse o link abaixo e siga as orientações de instalação de acordo com seu sistema operacional:

    https://devcenter.heroku.com/articles/heroku-cli#download-and-install 

    Terminada a instalação, podemos agora fazer login no Heroku e criar nosso app.

     Eu vou mostrar os passos de criação do projeto pelo terminal, mas é possível também fazê-los diretamente no site do Heroku.

    No prompt de comando digite $ heroku login e aperte ENTER 2x. Automaticamente irá abrir o navegador solicitando seu login e senha. Digite suas credenciais e em seguida pode fechar o navegador.

 


    Ainda no prompt de comando, digite:

    $ heroku create pagamento-app

    Feito isso, ele irá criar uma aplicação com o nome pagamento-app na sua conta.

    O próximo passo é a criação de um banco de dados Postgres para utilizarmos no projeto. Para isso, digite o comando:

    $ heroku addons:create heroku-postgresql

    ou

    $ heroku addons:create heroku-postgresql --app pagamento-app

    A segunda opção cria o banco de dados para uma aplicação específica. Usamos para o caso de ter mais de uma aplicação hospedada.

    Feito isso, podemos ir até o site e pegar as credenciais do banco de dados que foi criado. Acesse o site https://heroku.com, faça login e em seguida clique sobre o nome da aplicação: pagamento-app.

    Nessa página você terá acesso a todo conteúdo da sua aplicação no heroku. Clique sobre Heroku Postgres para ter acesso ao banco de dados:

 



    Agora entre na aba Settings e em seguida clique no botão View Credentials...:

 


    Permaneça na página que foi aberta pois iremos precisar dos dados exibidos para incluir no projeto.


9. Configurando as credenciais do banco de dados no projeto

    Volte para o projeto no eclipse. Clique com o botão direito na pasta WEB-INF > New > File, dê o nome database.properties. Esse arquivo, como foi dito anteriormente, será usado pelo dispatcher-servlet.xml no momento de abrir a conexão com o BD.

    Preencha o arquivo criados de acordo com os dados exibidos na página Database Credentials do Heroku (passo 8):


 database.host=<copie e cole o conteúdo de Host>  
 database.schema=<copie e cole o conteúdo de Database>  
 database.username=<copie e cole o conteúdo de User>  
 database.port=<copie e cole o conteúdo de Port>  
 database.password=<copie e cole o conteúdo de Password>  


10. Criando o dino e fazendo o deploy do projeto na nuvem

    Finalmente, vamos fazer o deploy do projeto para a nuvem, porém, para que o Heroku consiga “subir” o web service, é necessário criar um arquivo na pasta raiz do projeto. Pelo terminal, acesse a pasta onde está o código fonte do projeto e crie um arquivo o nome Procfile. Copie e cole a linha abaixo dentro do arquivo:


web: java $JAVA_OPTS -jar target/dependency/webapp-runner.jar --port $PORT target/*.war


    Salve e feche o arquivo.


    Agora, podemos fazer o deploy. Ainda na raiz do projeto, digite os seguintes comandos no terminal:


        $ git init

        $ git add . 

        $ git commit -m "primeiro commit"

        $ heroku git:remote -a pagamento-app

        $ git push heroku master


    Feito isso, toda aplicação será enviada para a nuvem do Heroku. Para verificar se funcionou, digite no terminal:

        $ heroku open

    O navegador deverá abrir com a URL do seu web service e exibir a mensagem Hello World!

 


    Faça também o teste nos serviços (verifique a URL, deve estar um pouco diferente):


https://pagamento-app.herokuapp.com/popula    >> vai carregar os pagamentos

https://pagamento-app.herokuapp.com/get-pagamento/1    >> vai mostrar o pagamento com código 1

https://pagamento-app.herokuapp.com/get-pagamentos >> vai mostrar todos os pagamentos

https://pagamento-app.herokuapp.com/remove-pagamento/1    >> apaga o pagamento com código 1



Por hoje é isso, até mais!


Nenhum comentário:

Postar um comentário