Codemountain, Paulo Suzart's Blog

Posts Tagged ‘scala

Twitter Finagle, primeiras impressões

leave a comment »

Quanto tempo sem postar sobre Scala! Mas isso não significa que fiquei sem estudar a linguagem e muito do que gira ao seu redor. Neste Post, vou colocar alguma scoisas sobre o Twitter Finagle, auto entitulado como uma biblioteca para construção de servidores e clientes RPC assíncronos em Java, Scala ou qualquer coisa que execute na JVM.

O finagle é uma camada muuuuuito fina em cima do JBoss Netty, que é um framework Java NIO realmente surpreendente e sabidamente veloz. O Netty é a base para o Aleph (clojure), framework que postei outro dia.

Aqui vai um hello world tosco com o Finagle:

class SimpleService extends Service[HttpRequest, HttpResponse] {
  def apply(request: HttpRequest): Future[HttpResponse] = {
    val response = new DefaultHttpResponse(HTTP_1_1, Ok)
    Future.value(response)
  }
}

A coisa é simples. Service é uma classe do finagle que extende uma função que recebe um HttpRequest do netty e retorna um Future[HttpResponse]. Future é uma estrutura para programação assíncrona fantástica, mas talvez seja assunto para outro post. No exemplo acima, a única coisa que o servidor faz é responder um 200 para o cliente.

E sim, se eu quiser saber os parâmetros de uma query string ou mesmo de um formulário submetido, teria que fazer tudo isso manualmente. Para isso o finagle traz uma pequena abstração em cima do HttpRequest do Netty, é o Request. Nela é possível encontrar funções mais civilizadas e algumas outras facilidades como gerar o response a partir da requisição, aproveitando então seu encoding, versão http, etc. Uma versão mais interessante usando algumas classes providas no finagle é a seguinte:

class AdvancedService extends Service[Request, Response] {
  def apply(request: Request): Future[Response] = {
    (Path(request.path)) match {
      case Root / "user" / Integer(id) =>
        val response = request.response
        response.setContentString("The user id is %d\n\n" format id)
        Future.value(response)
    }
  }
}

Aqui aparecem algumas coisas interessantes. A classe Path permite extrair os conhecidos Path Parameters em um pattern match, que no caso pega o caminho imediatamente após /user. Se requisitarmos /user/21, a resposta do servidor apresentará o identificador repreentado no path. O pacote http.path do finagle possui outras facilidades para parâmetros em query string e métodos Http. Acabei usando em um pequeno trabalho pessoal para facilitar as coisas.

Mas espera! Tem muito código aqui. Então por que não reduzir essa coisa toda? Eu queria chegar ao ponto de apenas entregar uma função parcialmente aplicada que fizesse um match na requisição para saber seu HTTP VERB. Se for o que desejo tratar, então faço um pattern mach nos seus parâmetros para seguir com o processamento. Pode ficar assim:


val superAd = ~~ {
  case (Get, request) =>
    (Path(request.path)) match {
       case Root / "user" / Integer(id) =>
            val response = request.response
            response.setContentString("The user id is %d\n\n" format id)
            Future.value(response)
    }
}

Wow! Bem melhor.E fiz isso com uma minuscula abstração que é a seguinte:

  val methNotAllwd: PartialFunction[(HttpMethod, Request), Future[Response]] = {
    case (_, request) =>
      val response = request.response
      response.status = MethodNotAllowed
      Future.value(response)
  }

  def ~~(body: PartialFunction[(HttpMethod, Request), Future[Response]]) = {
    new Service[Request, Response] {
      def apply(request: Request): Future[Response] = {

        val pf: PartialFunction[(HttpMethod, Request), Future[Response]] = {
          body orElse methNotAllwd
        }
        pf(request.method, request)
      }
    }

  }

Além de poder usar a função ~~ para tratar minhas requisições, caso o método da requisição não tenha um pattern definido, será retornado um 405 para o cliente. Prefiro abstrações pequenas à mega abstrações que custumávamos fazer há uns 8 anos atrás. Tinhamos quase que um framework caseiro em cima de qualquer outro framework que usávamos.

Para executar um servidor http com o superAd atendendo as requisições, use o codec RitchHttp ao invés do Http puro.

Aqui falei muito rapidamente da parte Http para o lado servidor do Finagle, mas existe uma gama de features muito legais. Uma delas é a possibilidade de encadear filtros na requisição, semelhante aos filtros Servlet. No código de exemplo deste post, você pode ver que usei o ExceptionFilter que já vem no finagle. Ele vai tratar qualquer exceção no seu código.

Como estou usando o Finagle?

Bem, construí um proxy SQS para um projeto de um amigo. Ele precisa receber mensagens mas não pode tornar as suas filas públicas. Além disso, é preciso validar a mensagem e autenticar o usuário antes de permitir que a mensagem vá para a fila.

Por que o Finagle?

Eu realmente acredito que precisamos reaproveitar coisas boas. O finagle oferece uma camada fina sobre o netty, e por isto não precisamos de um container WEB ou Servido de aplicação JEE, etc. Todo o seu código vai rodar com o mínimo de camadas e num nível baixo de abstração, o que tende a ser mais performático. Além de tornar o netty com uma cara de Scala.

Outro ponto importante é que a construção de clients é tão simples quanto a criação de services. Além de poder em alguns casos usar outros protocolos (Thrift, TCP puro com codecs) e manter a mesma simplicidade.

O finagle – e quase todos os projetos open source do Twitter – pode fazer sua vida ficar mais fácil. Outro projeto que uso neste mesmo caso é Logging. Simples, direto e com cara de Scala.

O código do post pode ser baixado aqui no meu github.

Written by paulosuzart

outubro 14, 2011 at 5:04 pm

Publicado em scala

Tagged with ,

CEP com Scala + Drools Fusion

with 3 comments

Motivado pelo post de um grande “broder”, o Daniel Amadei, resolvi mostrar uma alternativa open source para o mostrado no seu post: Jb**s Drools Fusion.

Tive a oportunidade de trabalhar com o Drools como engine de promoções em um grande e-commerce brasileiro em 2008, e agora com o aumento do interesse por EDA (Event Driven Architecture), apresento um overview do Drools Fusion que promete trazer o conceito de processamento complexo de eventos sem demandar o aprendizado de uma nova linguagem ou ferramenta. Desenvolvedores já familiarizados com o Drools core podem começar imediatamente a construção de lógicas baseadas em eventos.

O Drools Fusion pode ser aplicado nos cenários clássicos de CEP como detecção de fraude, mercado financeiro e todo caso onde é necessário analisar um grande volume de eventos e obter um significado a partir deles.

Para exemplificar o uso do Drools Fusion, saí do ambiente corporativo e parti pra algo mais industrial. Imagine uma caldeira numa fábrica de alimentos.  Esta caldeira possui uma restrição de operação onde a tempreratura interna não pode sofrer as seguintes variações:

  • cenário 1: a caldeira não pode operar próxima do limite máximo de temperatura (acima dos 135 graus celsius) por mais de 20 segundos.
  • cenário 2: Dentro de 5 segundos, a variação de temperatura não deve passar de 10 graus celsius pra mais ou para menos. Caso contrário o aparelho corre o risco de explosão. Exemplo: se a caldeira opera a 90 graus e em 5 segundos a temperatura atingir 111 graus, o risco de explosão é eminente.

Em ambos os casos a medida de tempo está presente além da variável temperatura.  Para concluir o caso, suponha um sensor enviando os dados de temperatura para o nosso sistema.

Logo, Traduzindo para o Drools temos a o evento:

import cep.fusion.CEP.TemperatureChange //we need to import it
declare TemperatureChange
 @role(event) //set the role as an event
 @timestamp(time) //indicate the timestamp attribute in the event
end

Que provem da classe Scala:

case class TemperatureChange(@BeanProperty temperature : Double, @BeanProperty time : Date)

Cada variação na temperatura é um novo evento que guarda o novo valor. TemperatureChange possui um atributo – temperature – acessível por métodos get/set no Drools por conta da anotação @BeanProperty. O outro atributo é o tempo em que a mudança ocorre, fator importante para o disparo correto das regras baseadas em Sliding Windows e Temporal Reasoning. Se não informado um atributo como timestamp do evento, o momento de entrada do evento na memória do Drools Fusion é considerado seu timestamp. Eu experimentei problemas durante os testes por não ter escolhido e explicitado um timestamp para meus eventos.

Para atender o cenário 1, vamos criar a regra de Sliding Windows:

rule "Inside the limits for 20s"

 when
 $n : Number(doubleValue >= 135 && doubleValue <= 145) from
      accumulate (
          TemperatureChange($t: temperature)  over window:time(20s) from entry-point "temp-change",
               average($t)
                 )
 then
     System.out.println("About to Blow Up!!!!! Morhe than 20 seconds inside the limits. Average: " + $n);
end

Note a clausula from entry-point na regra. Ela é utilizada para que o Fusion leia constantemente os eventos do fluxo (Stream) de nome temp-change.

Um evento é inserido diretamente em um dado Stream quando fazemos o seguinte no nosso código Scala:

   val clock  = session.getSessionClock.asInstanceOf[SessionPseudoClock]
   val stream = session.getWorkingMemoryEntryPoint("temp-change")
   stream.insert(TemperatureChange(78))
   clock.advanceTime(5, TimeUnit.SECONDS)

Onde “temp-change” é o nome do Stream de eventos capturado na nossa regra.

Para facilitar nosso teste, o Drools Fusion fornece um “clock controlado”. Assim podemos inserir eventos na sessão e manter o controle da passagem do tempo como queiramos. Para o exemplo usei o PseudoClock e a cada inserção avanço o relógio em x segundos. Não podemos esquecer de avançar o timestamp de entrada dos eventos. Por isso, no código de exemplo criei uma função scala para avançar ambos ao mesmo tempo (função advanceSeconds).

Para o cenário 2 temos a regra considerando tempo entre eventos:


rule "High Variance"

 when
   $a : TemperatureChange(t: temperature) from entry-point "temp-change"
   $b : TemperatureChange(t2: temperature, ( eval ((t - temperature) >= 10) || eval ((temperature - t) >= 10)), this after[0s, 5s] $a) from entry-point "temp-change"
 then
   System.out.println("High Temperature Variance!!!!!");
end

A regra diz que, na ocorrência de uma mudança de temperatura, um nova ocorrência dentro dos limites de 0 a 5 segundos, acionará esta regra caso a variação seja maior que 10 graus. Isto é possível com o uso do this afert[0s, 5s] na regra.

Pronto, agora podemos testar nossas regras:


package cep.fusion;

import cep.fusion.CEP._
import CEP.MyTimer._
//other imports...

object CEPTest {
 def suite: Test = {
 val suite = new TestSuite(classOf[CEPTest]);
 suite
 }

 def main(args : Array[String]) {
 junit.textui.TestRunner.run(suite);
 }
}

/**
 * Unit test for CEP.
 */
class CEPTest extends TestCase("CEP") {

 implicit val (session, stream, clock) = start

 /**
 * Case 1 must fire exactly fire two rules
 */
 def testCase1 = {

 stream.insert(TemperatureChange(135, advanceSeconds(1)))
 stream.insert(TemperatureChange(140, advanceSeconds(3)))
 stream.insert(TemperatureChange(143, advanceSeconds(4)))
 assertEquals(1, session.fireAllRules)

 }

 /**
 * Case 1 must fire exactly fire one rule
 */
 def testCase2 = {

 stream.insert(TemperatureChange(120, advanceSeconds(2)))
 stream.insert(TemperatureChange(131, advanceSeconds(1)))
 assertEquals(1, session.fireAllRules)
 }

}

//run using mvn test

O código da aplicação que usa Scala em um projeto Maven com o Maven Scala Plugin pode ser baixado direto no meu github. Não explorei no post as configurações do Drools para não perder o foco, mais detalhes você encontra no código. depois de baixar o projeto, basta executar mvn test para ver os resultados.

CEP sem dúvida é algo cada vez mais próximo de se tornar mandatório em ambientes dinâmicos, onde ações preventivas ou corretivas podem ser disparadas através da detecção de padrões em inúmeros fluxos de eventos no momento em que eles ocorrem.

Para gerar um projeto no eclipse basta executar: mvn eclipse:eclipse ;)

Bons estudos!

Written by paulosuzart

maio 11, 2010 at 3:31 pm

Publicado em cep, eda, scala

Tagged with , , ,

Sem Elvis Operator? Crie um!

with 6 comments

Meu querido amigo @lucastex Postou sobre Elvis operator em Groovy. Ele também me perguntou se Scala tinha este operador. E eu disse: Não, mas eu posso criar agora. E assim fiz:

implicit def toRockStar[B](v : B) = new { def ?: (opt: => B) : B =
                                           if (opt == null) v else opt}

Se voce observar bem neste Post, eu criei o operador % aplicável a Strings para facilitar a configuração de alguns parâmetros em uma conexão com o RabbitMQ.

Então, para usarmos nosso Rock Start Elvis operator fazemos assim:

scala> val name : String = null
name: String = null

scala> val l = name ?: "Lucas"
l: java.lang.String = Lucas // resultado deve ser Lucas

scala> val p = l ?: "Paulo" // Resultado Deve ser Lucas
p: java.lang.String = Lucas

A variável imutável p só deve receber o valor Paulo se a variável l não tiver sido atribuído a uma String. O Elvis aqui serve para qualquer tipo, pois foi construído de forma genérica com tipos parametrizados (ver o [B]).

Em Scala os operadors aritiméticos também são funções e não operadores da linguagem. Logo, existe a possibilidade de criação de qualquer operador com o nível de complexidade necessário para resolver o seu problema.

Foi um post curto, e um bate bola com o Lucas. Tento usar o público dele e de outras linguagens para atrair a atenção para Scala, uma linguagem sem dúvida promissora. ;)

Com Scala é assim, não espere a linguagem criar um operador interessante como esse, simplesmente o faça.

Written by paulosuzart

outubro 22, 2009 at 7:57 pm

Publicado em scala

Tagged with

Especificando validações com Scala, Specs e Lift – Parte II

with 3 comments

No último Post tivemos uma visão inicial do uso de Specs, BDD e um exemplo de utilização do framework. Mas como você deve ter percebido, as especificações eram blocos de códigos ainda soltos no Post. Specifications são objects ou classes Scala, vejamos como declarar a especificação do post anterior, configurar uma sessão Lift, criar um contexto de execução das especificações, e por fim estender o framework Specs com Matchers personalizados.

object TodoSpec extends Specification with Contexts {

    "Create/Update a ToDo item" should {
       //... spec from last post.
    }

   //Inicia um sessão Lift
    val session = new LiftSession("", StringHelpers.randomString(20),
                                                new MockHttpSession, null)
   //Executa a dentro da sessão Lift
   def inSession(a: => Any) = {
        S.initIfUninitted(session) { a }
    }

   //Novo usuário para execução da especificação
    def loginUser = inSession {
        val user = User.create
        user.email("tester@gmail.com").password("xxxxxx")
        user.save
        User.logUserIn(user)
    }

    //Contexto de execuão da Especificação
    new SpecContext {
        //Estabelece Conexão com o banco antes da execução.
        beforeSpec {
            if (!DB.jndiJdbcConnAvailable_?)
            DB.defineConnectionManager(DefaultConnectionIdentifier,
                                                     DBVendor)
            loginUser //Acontece o login do usuário
        }
        aroundExpectations(inSession(_))

        //Remove o usuário de teste
        afterSpec {
            val user = User.find(By(User.email, "tester@gmail.com"))
            User.delete_!(user.open_!)
        }
    }
}
class TodoSpecTest extends JUnit4(TodoSpec)

Uma especificação é um objeto que extends a classe org.specs.Specification. Specification oferece um conjunto de conversores implícitos para Strings, por isso os métodos should, in e >> aparentam serem invocados a partir das strings que descrevem a especificação.

Como todo teste que deve acontecer dentro de um contexto (jndi, spring, hibernate, ejb3, etc), precisamos de um código extra para usarmos recursos do Lift e definir um contexto para a execução da especificação. Por isso, aqui usamos a trait Contexts e criamos uma nova instância de SpecContext com os métodos beforeSpec fazendo a conexão com a base de dados e aroundExpectations garantindo que a especificação ocorra dentro da sessão Lift criada.

Com Specs, você pode visulizar o resultado das execuções na sua IDE como se fossem testes JUnit. Por isso a TodoSpec é um objecto e há uma classe TodoSpecTest que extends org.specs.runner.JUnit4. O objeto da especificação é passado como construtor do runner de JUnit4. Assim temos a execução da especificação integrada com a IDE. Veja outras formas executá-las aqui.

Usamos o próprio Lift Test Kit  uma instância de HttpSession (new MockHttpSession), assim podemos instanciar corretamente uma sessão Lift.

Para a execução dos testes vamos precisar das dependências abaixo. Lembre-se de instalar no seu repositório local Maven a versão SNAPSHOT do Specs 1.6.1 encontrado aqui.

        <dependency>
            <groupId>org.scala-tools.testing</groupId>
            <artifactId>specs</artifactId>
            <version>1.6.1</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>net.liftweb</groupId>
            <artifactId>lift-testkit</artifactId>
            <version>1.0</version>
            <scope>test</scope>
        </dependency>

Outro ponto importante do framework Specs, é a sua extensibilidade. Podemos criar Matchers tão poderosos quanto queiramos para oferecer um melhor suporte à linguagem única utilizada no negócio do sistema. Supondo que a especificação descreva que um usuário logado no sistema deve ser um usuário Gmail, podemos criar nosso próprio matcher para tornar nossa especificação mais natural. Vamos adicionar o seguinte sistema para especificar o comportamento do nosso matcher, facilitando o entendimento:

    "A logged user" should {
        "be a Gmail user" in {
            val user = User.currentUser.open_!
            user.email.asString must beAtGmail
        }
    }

beAtGamil é um matcher definido em um object que pode conter diversos matchers customizados. Até aqui temos apenas um matcher:

object CustomMatcherSpec extends Specification {
    "beAtGmail" can {
        "assert users at Gmail" in {
            "paulosuzart@gmail.com" must beAtGmail
        }
    }
}

object CustomMatcher {
    import java.util.regex.Pattern
    val beAtGmail = new Matcher[String]{
        def apply(m : => String) = {
            val pattern = Pattern.compile(".+\\@gmail.com")
                                      (pattern.matcher(m).matches,
                        m + " is at Gmail",  m + " is not at Gmail")
        }
    }
}
class CustomSpecTest extends JUnit4(CustomMatcherSpec)

Não podemos esquecer de um executor JUnit4 para a integração com a IDE. Seguindo os passos do post passado, você pode ver o resultado das especificações do sistema ToDo e a especificação do Matcher customizado.

BDD é sem dúvida uma metodologia com grande potencial de expansão no mercado e torço pra que muito em breve apareçam oportunidades com tecnologias e metodologias como essas.

Ainda não sei dizer em qual a dimensão de projeto o BDD é mais apropriado, talvez as mesmas dimensões onde TDD e DDD são aplicáveis.

Detalhes como as classes DB, S e todos os fontes do Post, você vai encontrar na aplicação disponibilizada no meu repositório github. Reforço que o projeto froi criado seguindo o tutorial de Getting Started do Lift e modificado para a construção do Post. E não se esqueça de me seguir no Twitter.

Written by paulosuzart

outubro 20, 2009 at 10:55 am

Publicado em bdd, lift, scala

Tagged with , , ,

Especificando validações com Scala, Specs e Lift – Parte I

with one comment

Pra variar um post sem ligação alguma com o anterior. Mas vamos lá.

Há pouco mais de um ano que comecei a estudar Scala, e durante este tempo me dediquei quase que puramente à linguagem. O máximo que brinquei foi com Scala SBT, o Dispatch do n8han e outras coisinhas. Acredito que até mesmo por não ser meu foco profissional (por hora) demorei pra estudar o Lift, o framework MVC para Scala.

Completei o getting started do framework e comecei a fazer uma segunda aplicação de estudo com @lucastex e @r4f4e1. Mas o motivo desse post é um processo de desenvolvimento que me chamou a atenção depois que vi o Cucumber. BDD, ou BehaviourDrivenDevelopment é uma metodologia ágil que vem como um complemento – ou mesmo evolução – ao TDD (Test Driven Development) e se transformando em uma ferramenta primordial para o DDD (DomainDrivenDesign).

Existem muitos frameworks BDD como RSpec, Specs, Scala Test, Cucumber, JBehave, jsspec, e escolhi o Specs por algum motivo obscuro.

Sendo bem objetivo e tentando reduzir a quantidade de palavras no post (deixando o máximo de código possível), o foco do BDD é a construção de comportamentos esperados para o sistema ao invés de testes. A construção de testes, em última instância, tem interesse em verificar o comportamento que o sistema deve (should) ter em diversos cenários (examples), por isso BDD.

Outro ponto importante é a tão falada linguagem ubíqua, ou seja, uma linguagem que todos os envolvidos na construção do software consigam entender. Frameworks BDD permitem que esta linguagem seja executável e escrita na propria linguagem de construção do sistema. Scala é muito poderosa na construção de DSLs (Domain Specific Languages), chegando ao ponto do código se parecer com uma escrita em ingles, não em uma linguagem de programação. Neste post, o comportamento que escolhi especificar foi de validação de dados de domínio:

"Create/Update a ToDo item" should {
   "show the following error messages:" >> {
     "Description must be 3 characters" >> {
       "if description field length is less than 3" in {
         val todo = ToDo.create.owner(User.currentUser)
         todo.desc("").validate must
         contain(FieldError(todo.desc, Text("Description must be 3 characters")))
       }
     }
     "Priority must be 1-10" >> {
       "if priority field is not between, including, 1 and 10" in {
         val todo = ToDo.create.owner(User.currentUser)
         todo.priority(-1).validate must
         contain(FieldError(todo.priority, <b>Priority must be 1-10</b>))
        }
     }
   }
 }

Nos parágrafos acima note em negrito as palavras should e example. Indicamos com should o que o sistema (ToDo app) deve fazer nos (in) exemplos, ou cenários, que seguem.

Dada cada uma das mensagens esperadas, o trecho de código delimitado por in {…} é implementado com um ou mais matchers.  o matcher must contain é usado aqui por que o método de Validação de uma classe mapper no lift retorna um List[FieldError]. FieldError é uma case class de construção FieldError[Identifier, NodeSeq]. Logo, o matcher must contain verifica a existência de um objeto com o formato especificado na lista de erros retornados na validação.

Logo, os matcher são os responsáveis por assegurar que a especificação descrita no texto será atendida pelo resultado do código nos exemplos.

O guia de matchers apresenta uma listagem completa desta DSL que pode ser aplicada em Iterables, String, Objects, Maps, Numer, Options, ScalaChecks, XML, Arquivos e grafos de objetos. E para ilustrar o uso de matchers para string.

Ao executar a especificação acima, temos o resultado:

-------------------------------------------------------
Running com.liftworkshop.todo.TodoSpecTest
Tests run: 3, Failures: 3, Errors: 0, Skipped: 0, Time elapsed: 2.694 sec <<< FAILURE!
Running com.liftworkshop.todo.AppTest
Tests run: 2, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 2.042 sec
Results :
Failed tests:
  Create/Update a ToDo item should show the following error messages: Description must be 3 characters if description field length is less than 3
  Create/Update a ToDo item should show the following error messages: Priority must be 1-10 if priority field is not between, including, 1 and 10
  Create/Update a ToDo item should show the following error messages: Priority must be 1-10 if priority field is not between, including, 1 and 10
Tests run: 5, Failures: 3, Errors: 0, Skipped: 0

Isto por que os campos desc e priority (mostrados abaixo) não implementam nenhuma validação:

class ToDo extends LongKeyedMapper[ToDo] with IdPK {
    lazy val priorityList = (1 to 10).map(v =>; (v.toString, v.toString))
    def getSingleton = ToDo
    object done extends MappedBoolean(this)
    object owner extends MappedLongForeignKey(this, User)
    object priority extends MappedInt(this) {
        override def defaultValue = 5
        override def _toForm = Full(select(ToDo.priorityList,
                                           Full(is.toString),
                                           f => set(f.toInt)))
    }
    object desc extends MappedPoliteString(this, 128)
}
object ToDo extends ToDo with LongKeyedMetaMapper[ToDo]

E aqui chegamos a um ponto interessante do BDD, certamente herdado do TDD: vamos escrever o código estritamente necessário para atender a nossa especificação. Supondo que você tenha o mínimo de conhecimento com Lift e quem sabe tenha feito o getting started, adicionemos as validações assim:

    object desc extends MappedPoliteString(this, 128) {
        override def validations = valMinLen(3, &quot;Description must be 3 characters&quot;) _ :: super.validations
    } // para o mapeamento da descrição e ...
    object priority extends MappedInt(this) {
    ...
        override def validations = validPriority _ :: super.validations
        def validPriority(in : Int) : List[FieldError] =
        if (in &gt; 0 && in >= 10) Nil
        else List(FieldError(this, <b>Priority must be 1-10</b>))
    ...
    }
<p>

O método validations é redefinido em cada propriedade mepada que necessida validação. O campo desc apenas obriga o tamanho mínimo para 3 com a mensagem especificada definido pela função utilitária valMinLen. Já o campo priority instancia diretamente um FieldError passando o campo contendo o erro junto com a mensagem em negrito.

Este projeto foi montado usando o NetBeans junto com o Maven conforme descrito no getting started do Lift. Fazendo um pequeno ajuste (descrito no próximo post), temos a execução da especificação integrada ao JUnit na IDE NetBeans.

Executando outra vez a especificação, teremos todos os testes ok como na figura a seguir. Um print do Netbeans.

Especificação atendida!

Especificação atendida!

Esta foi talvez a parte mágica da coisa. Onde tudo já está funcionando e precisamos só curtir o BDD num exemplo sofrível com intuito de ilustrar esta metodologia, o framework Specs, o framework Lift e a linguagem Scala.

O código completo do projeto estará disponível no próximo Post desta série. As versões utilizadas no projeto são: Lift 1.0, Scala Specs 1.6.1, EasyMock 2.5.2 (instalada no repositório maven local). E no próximo Post teremos: Configurando seu projeto Maven para o uso de Scala Specs; Explorando mais matchers; Configurando Contexto Specs para execução da especificação em uma LiftSession acessando a base de dados; Especificando Snippets Lift, e mais. Será que cabe tudo em mais um Post? Vai ter que caber.

Se puder visite o site do BDD e conheça mais sobre esta metodologia no mínimo interessante. Dado que não sou especialista em nenhum metodologia ágil, se você tem ou teve alguma experiência prática com BDD, TDD ou DDD deixe seu comentário ou sua sugestão sobre como abordar o tema de maneira mais prática.

Veja a Parte II deste post.

Written by paulosuzart

outubro 14, 2009 at 3:21 am

Publicado em bdd, lift, scala

Tagged with , , ,

Scala: Implicits, Options and Pattern Match to start with RabbitMQ

with 3 comments

update: link to code, now using sxr 0.2.1

Hi folks. Long time away! Confess I hadn’t had nice ideas to work on, but now I have a lot.

While implementing one of them (sort of Scala lib to use Actors as RabbitMQ Queue consumers over the Java API), I figured that my lib user shouldn’t explicitly instantiate or even interact with some original RabbitMQ Java API classes. This small piece of my construct is sufficient to show nice Scala features and functional programming style (the following is not the unique solution or the best way to do that, but funny and teaching).

To consume a Queue, we  first connect to the broker and get a Connection and a Channel. Using this ConnectionFactory constructor is useful to get a Connection. However, it takes a set of parameters wrapped in ConnectionParameters class.

So I decided follow these rules:

1. lib users must not instantiate ConnectionParameters directly

2. configuration must appear in the order: user, password, virtual host

3. configuration must take one line and be transparent to lib client

4. Ah! Users shouldn’t use common Scala Lists

How to make it happens in Scala? My answer was put some interesting features together such as Pattern Match, Options, Case Classes and Implicit Conversions.

Using a SBT aproach to declare project dependencies, We have the format:


val connParams = "guest" % "guest" % "/" //say a abstract val named connParams

An implicit function will help to convert a String to an object that takes a String value and the previous declared parameter as arguments. So we get  Param(“/, Param(“guest”, Param(“guest”, None))). Every time the user call the function % on a String, this implicit converter will instantiate a new Param.

The convertion function can be done as:

 implicit def s2Param(s : String) = Param(s, None)

Here a new element takes place, the Param class hasn’t a new keyword. That is a Case Class, a especial Class that help us with PatternMatch and  doesn’t need such a keyword.  And more, the parameters of a case class are “mapped to” attributes accessible by its own names:

case class Param(value : String, precending : Option[Param])

So, say a variable named x referencing Param, x allows x.value and x.precending without any extra declarations. :)

s2Param implicitly converts a String to a Param Instance to bring the function %. Let see the function %:


case class Param(value : String, preceding : Option[Param]) {

def % (value : String) = Param(value, Some(this))

}

For our surprise, we have one more element here, the Some –  in conjunction with None (see s2Param) – extends Option[+A]. Option is used to represent optional values, and here is a nice place to apply it. For example, the preceding Param of a Param is not required for the first in the chain.

None means no value, and Some means some value of the type of +A. Option has many other features not covered here.

Now, with the class designed, we can add another function (used strictly by the lib) to transform the parameter chain into the Rabbit ConnectionParameters:


def asConnectionParams = { 

 val (user, pass, vHost)  = this match {
   case Param(user, None) =>  (user, ConnectionParameters.DEFAULT_PASS, ConnectionParameters.DEFAULT_VHOST)
   case Param(pass, Some(Param(user, None))) => (user, pass, ConnectionParameters.DEFAULT_VHOST)
   case Param(vHost, Some(Param(pass, Some(Param(user, None))))) => (user, pass, vHost)
   case _=> error("ConnectionParameters configuration Failed")
 }

 //Returning ConnectionParametters
 new ConnectionParameters {
   setUsername(user)
   setPassword(pass)
   setVirtualHost(vHost)
 }

 }

asConnectionParams uses Pattern Match to declare the val user, pass and vHost matching the current instance of Param (supposed to be the las declared by the user) against some expected patterns. This Pattern Match carres about the default values to configure the ConnectionParametters instance returned. Any other Param combination not allowed will fall into case _, and a error is raised.

Now the Param class complete:


   case class Param(value : String, preceding : Option[Param]) {

      require(value != null)  

      def % (value : String) = Param(value, Some(this))

      def asConnectionParams = { 

        val (user, pass, vHost)  = this match {
           case Param(user, None) =>  (user, ConnectionParameters.DEFAULT_PASS, ConnectionParameters.DEFAULT_VHOST)
           case Param(pass, Some(Param(user, None))) => (user, pass, ConnectionParameters.DEFAULT_VHOST)
           case Param(vHost, Some(Param(pass, Some(Param(user, None))))) => (user, pass, vHost)
           case _=> error("ConnectionParameters configuration Failed")
          }

        //Returnin ConnectionParametters
        new ConnectionParameters {
        	setUsername(user)
        	setPassword(pass)
        	setVirtualHost(vHost)
        }

      }
    }

Usage:


val params = "guest" % "guest" % "/"

Thus, the super class can execute params asConnectionParams to grab the params required to get a Connection and a RabbitMQ channel.

To make things simple to test by yourself, you can find the code that runs stand alone here (with Scala X-Ray). Next time I promess a Scalatest or something like.

Thats it! Impressive? No! Useful? Maybe. Funny? For sure!!!

Stay up and see more POSTs about real RabbitMQ and Scala soon. It was an appetizer to play around with Scala.

Thanks for coming!

Written by paulosuzart

agosto 1, 2009 at 7:52 pm

Publicado em RabbitMQ, scala

Tagged with ,

Preparando um Talk

leave a comment »

AccurTalkEm breve, eu e alguns colegas de trabalho faremos um talk na empresa.
O objetivo é apresentar ao restante da companhia, as algumas inovações tecnológicas que cada um vem estudando nos últimos meses.
Dentre elas, Groovy/Grails, CEP, SOA, Terracotta e um talk sobre Scala apresentado por mim.
Para o exemplo usado, Scala X-Ray vai ajudar a ilustrar o uso da linguagem: http://is.gd/tmFg

Acompanhe! ;)

obs: logo não oficial.

Written by paulosuzart

abril 20, 2009 at 2:02 am

Publicado em me, scala

Tagged with

micropost: How to begin with Scala?

leave a comment »

Acessando a principal fonte sobre a linguagem.
E quer começar a brincar de verdade? Instale o Scala Plugin para a IDE de sua preferência. Eu particularmente me dei muito bem com o plugin para NetBeans, até por que achei a parte de debug um mais completa.

Faça um teste! Nada melhor que um código bem colorido e code completation para começar.

Written by paulosuzart

março 8, 2009 at 1:31 am

Publicado em me, scala

Tagged with

Empréstimos em Scala

with one comment

Continuando meus estudos em Scala, me deparei com um padrão sugerido pelos autores do livro Programming Scala, o loan pattern, ou seja, empréstimos. O objetivo deste padrão é permitir que o desenvolvedor crie estruturas semelhantes a built-in controls da linguagem, leia-se if, while, try, etc. Estas estruturas nativas em Scala tem um comportamento e até aplicações diferentes destas mesmas estruturas de controle em Java. Mas isso é um assunto para um próximo post.
Então onde está a vantagem do uso de loan pattern e a construção de estruturas parecidas com um while?
Tomando como exemplo códigos Java, muito frequentimente usamos um padrão para escrever DAOs:

public String getAdditionalInfo(String uoo) throws Exception {
        Connection conn = null;
        CallableStatement cs = null;
        ResultSet rs = null;
        String info = null;
        try {
            //prepara recursos envolvidos
            ...
            cs.registerOutParameter(1, Types.VARCHAR);
            ...
            info = cs.getString(1);
        } finally {
            if (conn != null)
                conn.close();
            if (rs != null)
                rs.close();
            if (cs != null)
                cs.close();
        }
       return info;
}

Logo, é comum existirem DAOs com todos os métodos com o mesmo finally,  os mesmos testes para verificar se o recurso não é nullo, e a depender do caso outros testes mais complexos.
Além de repetitivo, esse código não tem um visual natural, e pode ser esquecido facilmente de ser anexado ao método do DAO em questão, e até modificações devem ser custosamente reescritas manualmente em cada método. O resultado é um risco de problemas decorrente do não fechamento de conexões, Statements e ResultSets, que incluem impactos na performance da aplicação. Supondo este mesmo DAO em Scala, podemos escrevê-lo assim:

def getAdditionalInfo(uoo: String) = {
    var conn : Connection = null
    var cs : CallableStatement = null
    var rs  : ResultSet = null

    useAndClose(conn, cs, rs) {
        //prepara recursos envolvidos
        ...
        cs.registerOutParameter(1, Types.VARCHAR)
        ...
        cs getString 1;
    }
}

A função useAndClose com cara de while foi criada para permitir a execuçao de algum código e no fim, garantir o fechamento dos recursos passados como argumento para a função.  Esta função irá englobar de maneira centralizada o comportamento do fechamento dos recursos envolvidos. Outro ponto positivo é a eliminação de reatribuição, ou seja, enquanto o código Java demandava uma variável local para servir de retorno para o método, o DAO em Scala usa o próprio resultado da invocação de useAndClose como resultado da função getAdditionalInfo.
Nossa função useAndClose poderia ser escrita assim:


def useAndClose[T](conn: Connection, rs : ResultSet, ps: PreparedStatement)(op: => T) = {
    try { op }
    finally {
        if (conn != null)
                conn.close()
            if (rs != null)
                rs.close()
            if (cs != null)
                cs.close()
        }

Aqui fazemos o uso do padrão loan, porque a função useAndClose empresa seu comportamento padrão a um trecho de código escrito em outra parte. A função continua com cara de Java, além disso, por algum motivo, podemos desejar fechar apenas o ResultSet e preservar a conexão.

Criar outra função sobrecarregada recebendo desta vez apenas o ResultSet e o Statement é possível, mas também soa repetitiva. Se os três objetos ao menos obedecessem uma mesma interface, poderiamos usar sua interface comum e algo como vargars, então, após executar o código em questão, iterariamos este array e fechariamos cada recursos. Mas infelizmente estas três classes não compartilham uma mesma hierarquia.

O que fazer?

Bom, sabemos que as três classes possuem ao menos um método em comum: close(), que é o que nos interessa.  Scala fornece um mecanismo muito interessante que permite que tratemos estes 3 objetos de classes diferentes como algo compatível entre sí por possuírem este mesmo método close().
Escrevemos então nossa função useAndClose assim:

def useAndClose[T](closeable : {def close() : Unit}*)(op: => T) : T = {
try { op }
finally {
   for (c <- closeable if c!= null)
     c close
 }
}

Wow! Estranho? Depende dos olhos de quem vê! O intrigante é que não definimos exatamente quais os tipos dos parâmetros de entrada para a função useAndClose, apenas informamos que quem for enviado, deve conter um método close que não recebe parâmetros e nem retorna valor. Outra coisa importante aqui é o uso de * para indicar que a função pode receber mais de um objeto que contém ao menos um método close().

Você pode estar se perguntando, e como fica o tratamento das exceções destes métodos? Elas podem ser ligeiramente diferentes, não? Sim, podem. Em outra oportunidade podemos falar nisso, por hora, é só confiar.

O código então é executado, invocando-se op, que representa o trecho de código passando entre chaves para useAndClose, e depois, no bloco finally, cada “closeable” é fechado, se este for diferente de null.

O código do cliente (o DAO) não precisa de modificações para tirar vantagem do empréstimo de useAndClose, agora modificado. E se formos além, este comportamento de usar e fechar pode ser empregados em muitas situações diferentes, a exemplo do uso de Streams sem nenhuma alteração na nossa função.

Em outro post também pretendo falar sobre Generics em Scala, o uso aqui permite que useAndClose retorne o mesmo valor que o código passado como parâmetro retornaria, permitindo inclusive atribuições desse jeito:


    val myInfo = useAndClose(conn, cs, rs) {
        //prepara recursos envolvidos
        ...
        cs.registerOutParameter(1, Types.VARCHAR)
        ...
        cs getString 1;
    }

Que atribui a myInfo uma String retornada após a invocação do Statement. Podemos ainda aninhar este tipo de estrutura criando uma forma mais natural e  concisa de programar, adicionando comportamento distintos onde nossa imaginação é o limite.

Espero ter despertado a curiosidade dos leitores do blog.
Tenham uma boa diversão com Scala.

Nota Sobre os autores do livro Programing Scala:
Martin Odersky é o criador da linguagem e professor na EPFL. Lex Spoon trabalou com Scala por 2 anos em seu pós-doutorado e Bill Vennes é somente o presidente da Artma, a editora do livro

Written by paulosuzart

fevereiro 22, 2009 at 9:40 pm

Publicado em Java, scala

Tagged with ,

Scala, Scala, Scala

with 3 comments

Estava eu vagando pelo meu Google Reader, e encontrei este post falando sobre uma comparação  “for fun” entra Java, C# e F# em alguns aspectos comuns em linguagens funcionais.

Então, pra complementar o post interessante, resolvi gerar exatamente os mesmos 3 exemplos usando Scala. Scala é uma linguagem funcional staticamente tipada, e tem seu código executado na VM Java. Isso se dá pelo fato do compilador Scala gerar Byte code.

Logo, Scala é considerada uma das linguagens que rodam na plataforma Java de forma mais transparente quando “conversa” com o Java. Você simplesmente faz um import de uma classe Java e usa no seu programa Scala, e vice-versa. Veja aqui neste post um pequeno comparativo entra as linguagens que podem rodar na plataforma Java (leia-se JVM).

Voltando aos exemplos do post do Mark Needham, primeiro temos:

1. Dados os números de 1 a 5, retornar o quadrado de cada elemento.

List[Int](1,2,3,4,5) map (x => Console.println(x*x))

2. Dados os números  de 1 a 5, retornar apenas aqueles maiores que 3. 

for (i <- numbers if i > 3) yield Console.println(i)

3. Dada uma lista dos  números de 1 a 5,  some todos e imprima o resultado.

numbers.reduceLeft((x,y) => x + y)

Para os exemplos 2 e 3, assume-se :

 val numbers = List[Int](1,2,3,4,5)

Simples, não? De fato ficou mais simples que Java, C# e F# juntas.  ;)

Scala é uma linguagem fantástica que nas horas vagas tenho estudado. Me considero bem alternativo nesse aspecto, e faltou pouco um dos projetos que participei para uma grande instituição governamental ser escritom Ruby on Rails, por exemplo. Infelizmente tenho a impressão de que este negócio vai demorar de decolar por aqui (Brasil), porém mundo a fora pode-se encontrar gente especializada no assunto e até grandes sites web 2.0 usando a tecnologia. Qualquer dia desse chego lá!

Pretendo em breve postar mais coisas sobre Scala, incluindo o seu principal framework web, o Lift, assim como as recente integrações com o Tapestry.

Written by paulosuzart

janeiro 22, 2009 at 6:44 pm

Publicado em Java, scala

Tagged with

Seguir

Obtenha todo post novo entregue na sua caixa de entrada.