terça-feira, 6 de maio de 2014

Django custon tags

Salve galera,

Nesse post vou mostrar como criar tags customizadas usando o Django. Para isso temos que criar um arquivo, que vamos chamar de app_extras.py dentro de um diretório chamado templatetags um nível abaixo de nossa aplicação. Por exemplo.: Se nossa aplicação se chamar osapp então ela ficará dentro da pasta osapp, como na imagem abaixo:


Dentro do arquivo app_extras.py vamos criar uma tag para formatação de data/hora que recebe como parametro um valor temporal e um formato para formatação:

from django import template
from datetime import datetime

register = template.Library()

@register.simple_tag(name="dateformat")
def dateformat(value, format):
    if value is None:
        return "-"
    try:
        return value.strftime(format)
    except Exception, e:
        return "-"


Para usar nossa tag temos antes que carrega-la na página:

{% load app_extras %}

Então podemos fazer a formatação de um valor:

{% dateformat form_data.begin_date '%d/%m/%Y %H:%M' %}


Rápido e limpo! Até a próxima.

Django + UTF

Salve galera,

Ao começar a desenvolver com o Django tive alguns problemas com a codificação dos caracteres e então achei a seguinte solução:

Em ambiente de desenvolvimento usando o webserver embarcado do Django, temos que alterar o arquivo manage.py adicionando o seguinte conteúdo:

import sys
reload(sys)
sys.setdefaultencoding("utf-8")

Em ambiente de produção usando o Apache e o modulo WSGI, temos que alterar o arquivo wsgi.py, o qual referenciamos na configuração do Django no httpd.conf, adicionando as mesmas linhas:

import sys
reload(sys)
sys.setdefaultencoding("utf-8")


E isso deve resolver o problema de codificação. Até a próxima.

Django + http authentication

Salve galera,

Dica de como habilitar a autenticação do Django no Apache. As três linhas abaixo no httpd.conf já fazem o Django trabalhar no Apache com autenticação:

WSGIScriptAlias /opt/app/wsgi.py
WSGIPythonPath /opt/app/webapp
WSGIPassAuthorization On


 E instalar o módulo WSGI:

LoadModule wsgi_module modules/mod_wsgi.so


Se estiver usando o framework REST rest_framework e quiser uma autnticação básica, é só delarar no settings.py:

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework.authentication.BasicAuthentication',
        'rest_framework.authentication.SessionAuthentication',
    ),

    'DEFAULT_PERMISSION_CLASSES': (
        'rest_framework.permissions.IsAuthenticated',
    ), 
    'DEFAULT_RENDERER_CLASSES': (
        'rest_framework.renderers.UnicodeJSONRenderer',
        'rest_framework.renderers.BrowsableAPIRenderer',
    )
}

Aqui o wsgi.py caso alguém precise:

import os
import sys

reload(sys)

sys.setdefaultencoding("utf-8")


os.environ.setdefault("DJANGO_SETTINGS_MODULE", "app.settings")

from django.core.wsgi import get_wsgi_application
application = get_wsgi_application()


E era isso! Até a próxima.

Tomcat + Spring + ActiveMQ Embedded Broker + Redelvery

Salve galera!

Não vou fazer um tutorial gigante de como configurar o ActiveMQ com Spring por que já existem vários por ai. Mas vou colocar as configurações necessárias para subir um Broker Embedded usando Spring num servidor Apache Tomcat trabalhando com Redelivery Messages.

Versões 

A versão current do ActiveMQ é 5.9. Não consegui fazer funcionar na última versão no Spring, então tive que usar a versão 3.1.1.RELEASE. A versão do Tomcat usada foi 7.0.41.

Maven Dependências 

Nessa relação deve ter coisas desnecessárias, mas como uso bastante coisa do Spring nesse projeto que fiz vou colocar a lista completa que já contempla MVC, JPA, Hibernate e tudo mais.

 3.1.1.RELEASE
 1.6
 2.5.0
 1.6.1


 
        

        
            javax
            javaee-api
            6.0
            provided
              

        

        
            javax.servlet.jsp
            jsp-api
            2.1
            provided
        

        
            javax.servlet
            jstl
            1.2
                                     

        

        
            org.springframework
            spring-context
            ${spring.version}           
        

        
            org.springframework
            spring-context-support
            ${spring.version}           
        

        
            org.springframework
            spring-core
            ${spring.version}                     
        

        
            org.springframework
            spring-web
            ${spring.version}
        

        
            org.springframework
            spring-beans
            ${spring.version}
        

        
            org.springframework
            spring-oxm
            ${spring.version}
        

        
            org.springframework
            spring-orm
            ${spring.version}
        

        
            org.springframework
            spring-webmvc
            ${spring.version}
          

        
            org.springframework
            spring-aspects
            ${spring.version}
                    

        
            org.springframework
            spring-tx
            ${spring.version}
             

        
            org.springframework.security
            spring-security-config
            ${spring.version}
        

        
            org.springframework.security
            spring-security-web
            ${spring.version}
          

        
            org.springframework.security
            spring-security-taglibs
            ${spring.version}
                     

        
            org.springframework.security
            spring-security-core
            ${spring.version}
          

        
            org.springframework
            spring-jms
            ${spring.version}
                     

        
            javax.servlet
            com.springsource.javax.servlet
            ${servlet-api.version}
            provided
        

        
            com.thoughtworks.xstream
            xstream
            1.3.1
        

             

        
            junit
            junit
            4.7
            test
        
     
        

        
            org.hibernate
            hibernate-entitymanager
            4.2.0.Final
        

        
            org.hibernate
            hibernate-validator
            4.2.0.Final           
         

        
            org.hibernate
            hibernate-c3p0
            4.2.0.Final
             

        
            org.hibernate
            hibernate-ehcache
            4.2.0.Final
               

        
            c3p0
            c3p0
            0.9.1.2
        
                                   
        
            net.sf.ehcache
            ehcache-core
            2.5.0
        
                            
        

        
            javassist
            javassist
            3.4.GA
               

        

        
            log4j
            log4j
            1.2.17           
        

        
            org.slf4j
            slf4j-api
            ${slf4j.version}           
        

        
            org.slf4j
            jcl-over-slf4j
            ${slf4j.version}           
        

        
            org.slf4j
            slf4j-log4j12
            ${slf4j.version}           
                             

        
            commons-io
            commons-io
            1.4
               
     
        
            cglib
            cglib
            2.2
                            

        
            org.apache.xbean
            xbean-spring
            3.6           
        
       
        
            org.apache.activemq
            activemq-all
            5.9.1           
                     

        
            org.apache.activemq
            activemq-pool
            5.9.1           
          

        
            javax.jms
            com.springsource.javax.jms
            1.1.0
                                                                                                                                                                  
                        
    
Spring Configuration Embedded Broker 

Aqui vou mostrar como configurar o Embedded Broker dentro do arquivo de configurações do Spring, sem precisar declarar nada no server.xml do Tomcat.

http://activemq.apache.org/how-do-i-embed-a-broker-inside-a-connection.html

No applicationContext.xml podemos fazer todas as configurações do Broker:


 

        
            
                   
              

                   
            
        

       

        
            
                
                    
                

                
                    
                

                
                    
                
                                 

           

       

                           
             
           

                                                                

    

 
                           
                   
                   
                   
   

                    

    
                   
        
  



Ou podemos externalizar as configurações e apontar o arquivo usando o brokerConfig:


 

                       

               

               

               

       

                    

    

               

        

    

 

Configuração Topic
    

        

    
Configuração MessageListener
 

     

         

         

         

         

         

                  

             

     
Código do Cnsumidor:
public class TopicConsumer extends SessionAwareMessageListener{

   public void onMessage(Message message, Session session) throws JMSException {

            try {

                //process message

                message.acknowledge(); // consume message

            } catch (Exception e) {               

                session.recover();

                throw new RuntimeException(e);

            }      

   }

}

Código do produtor:
@Service
public class TopicProducer  {

    @Resource(name = "jmsConnectionFactory")

    private ConnectionFactory connectionFactory;

    @Resource(name = "jmsTopicProducerConsumer")

    private Destination destination;

    private Connection connection;

    private Session session;

  public void produce(){

             connection = connectionFactory.createConnection();

            connection.start();

            session = connection.createSession(true, Session.CLIENT_ACKNOWLEDGE);                        TopicSession session

                            = connection.value.createTopicSession(false, Session.CLIENT_ACKNOWLEDGE);

                    TopicPublisher publisher = session.createPublisher((Topic) destination);

           TextMessage message = session.createTextMessage("Message Content");

           publisher.publish(message);

           connection.close();

 }

}

Redelivery Message 

Como podemos ver na configuração estamos criando um objeto redeliveryPolicy que define a política de reentrega das mensagens em caso de falha. Como não estamos trabalhando com mensagens transacionais, segundo a documentação do ActiveMQ, temos que usar o acknowledgeMode = Session.CLIENT_ACKNOWLEDGE. Trecho da documentação:

http://activemq.apache.org/message-redelivery-and-dlq-handling.html

Messages are redelivered to a client when any of the following occurs: 
  • A transacted session is used and rollback() is called. 
  • A transacted session is closed before commit is called. 
  •  A session is using CLIENT_ACKNOWLEDGE and Session.recover() is called. 

 Redelivery com Bridge 

Aqui um detalhe importante! Se estivermos consumindo as mensagens diretamente do Broker onde a mensagem é produzida não precisamos definir no Listener o acknowledgeMode como pode ver na configuração:
  
Mas caso estivermos usando uma Bridge, precisamos definir o tipo de recebimento no Listener para que a reentrega funcione.


Não tão simples mas também não tão complicado. É só prestar atenção nos detalhes que tudo funciona.

Até a próxima!

quinta-feira, 1 de maio de 2014

ava.net.BindException: Address already in use: JVM_Bind + ActiveMQ port 61616

Salve galera!

Volta e meia no Windows 8 (onde testei) ao iniciar o ActiveMQ na porta padrão (61616) a seguinte mensagem é exibida:

ava.net.BindException: Address already in use: JVM_Bind 

Mas ao analisar as portas abertas do Windows não encontramos a porra 61616 aberta. A solução é desativar o ICS (Internet Connection Sharing) nos serviços do Windows que o ActiveMQ volta a funcionar.