quarta-feira, 30 de outubro de 2013

REST - Aula Prática - Controles com o Bower

Antes de começarmos vamos concordar em pelo menos um item: Tudo o que já vimos até aqui é bem interessante, porém ter que controlar todos esses pacotes na mão vai acabar virando um verdadeiro círculo do Inferno de Dante (me desculpe acabei me viciando no livro de Dan Brown). São muitos pacotes para conseguirmos uma aplicação completa. Durante as minhas pesquisas, descobri um aplicativo (também feito em JavaScript) chamado BOWER que é um gerenciador de pacotes para a Web.

Para usá-lo, devemos seguir alguns pré-requisitos como a necessidade do software GIT, que é um sistema de controle de versão distribuído e um sistema de gerenciamento de código fonte muito comum para quem utiliza o Linux. E também precisaremos do NodeJS já instalado. Vamos colocar em ordem nossos pré-requisitos:

  • Instale o GIT for Windows
  • Instale o NodeJS

Uma vez pronto, podemos começar e instalar o Bower. Em uma tela de comandos digite:

npm install -g bower

O NPM foi instalado junto com o NodeJS, informe-se mais nos artigos anteriores (a opção -g significa "instalação global"). Uma vez que o Bower foi instalado corretamente podemos usá-lo para instalar e manter quaisquer pacotes que sejam necessários. Por exemplo se desejamos brincar com a jQuery. Proceda da seguinte forma:

bower install jquery

Observe que criada uma pasta chamada "bower_components" no qual contém todos os arquivos necessários para usarmos a última versão estável da jQuery. Podemos manter todos os pacotes baixados com um simples comando:

bower update

Também podemos rapidamente verificar quais são os pacotes que temos com o comando:

bower list

Ou, se desejarmos, desinstalar qualquer pacote com o comando:

bower uninstall <nome_pacote>

Acha que isso tudo é bobeira? Pois bem, na aula passada comentei sobre o projeto AngularStrap, se ficou curioso descobriu que entre o projeto existe uma série de dependências entre: jQuery, BootStrap e AngularStrap. As escolhas são, baixar corretamente e acertar todos os pacotes ou resolver tudo com o seguinte comando:

bower install angular-strap

E utilizar corretamente todos os pacotes necessários para montar a página HTML de modo a utilizar o objeto TimePicker:

<!DOCTYPE html>
<html>
 <head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  <link 
   href="bower_components/bootstrap/docs/assets/css/bootstrap.css" 
   type="text/css" rel="stylesheet"  />
  <link 
   href="bower_components/angular-strap/vendor/bootstrap-timepicker.css" 
   type="text/css" rel="stylesheet" />
  <script type="text/javascript" 
   src="bower_components/jquery/jquery.min.js"></script>
  <script type="text/javascript" 
   src="bower_components/bootstrap/docs/assets/js/bootstrap.js"></script>
  <script type="text/javascript" 
   src="bower_components/angular-strap/dist/angular-strap.js"></script>
  <script type="text/javascript" 
   src="bower_components/angular-strap/vendor/bootstrap-timepicker.js"></script>
 </head>
 <body>
  <div class="input-append bootstrap-timepicker">
   <input id="timepicker1" type="text" class="input-small">
   <span class="add-on"><i class="icon-time"></i></span>
  </div>
  <script type="text/javascript">
   $('#timepicker1').timepicker();
  </script>
 </body>
</html>

Sem querer bancar o chato, prefiro a coisa mais prática.

Obrigado e até a próxima
Fernando Anselmo

terça-feira, 15 de outubro de 2013

REST - Aula Prática - AngularJS, Bootstrap e Listas

Uma das piores características sobre um sistema HTML, é um sistema HTML feio. Existem milhares de possibilidades através do CSS3 e não é necessário ser/ter um maravilhoso Artista Gráfico para conseguir compor algo decente. O projeto Bootstrap é um daqueles que aparecem para salvar a alma de muitos projetos medíocres. Contém arquivos em formato CSS3 para criar um layout bem definido.

Para o nosso segundo trabalho com o AngularJS, baixe o Bootstrap e crie o nosso projeto conforme o seguinte conjunto de pastas:

 \exemplo
     \css
        bootstrap.min.css
     \script
        angular.min.js

Na pasta exemplo, crie um arquivo chamado "notas.html", com a seguinte codificação:

<!doctype html>
<html ng-app>
 <head>
  <title>Anotações do Dia</title>
  <meta charset="utf-8">
  <link rel="stylesheet" href="css/bootstrap.min.css">
  <script src="script/angular.min.js"></script>
  <script src="script/notas.js"></script>
  <style type="text/css">
   .feito-true {
    text-decoration: line-through;
    color: red;
   }
  </style>  
 </head>
 <body>
  <div class="container" ng-controller="NotasController">
   <div class="row">
    <div class="page-header">
     <h1>Lista de Coisas a Fazer</h1>
    </div>
   </div>
   <div class="row">
    <table class="table table-striped">
      <thead>
     <tr>
       <th>Título</th>
       <th>Horário</th>
       <th>Realizado?</th>
     </tr>
      </thead>
      <tbody>
     <tr ng-repeat="nota in notas" class="feito-{{ nota.feito }}">
       <td><strong>{{ nota.titulo }}</strong></td>
       <td>{{ nota.horario }}</td>
       <td><input type="checkbox" ng-model="nota.feito"></td>
     </tr>
      </tbody>
    </table>
   </div>
   <div class="row">
    <form class="form-inline" name="frmNota">
      <input type="text" ng-model="nota.titulo" placeholder="Título">
      <input type="text" ng-model="nota.horario" placeholder="Horário">
      <button class="btn btn-primary" ng-click="adicionarNota()">Adicionar Nota</button>
    </form>
   </div>
  </div>
 </body>
</html>

E na pasta script crie um arquivo chamado "notas.js" com a seguinte codificação:

function NotasController($scope) {
 $scope.notas = [
  {titulo: 'Bater o Ponto', horario: '08:00 AM', feito: false},
  {titulo: 'Tomar Café', horario: '09:20 AM', feito: false}
 ];

 $scope.adicionarNota = function () {
  $scope.notas.push({titulo: $scope.nota.titulo,
         horario: $scope.nota.horario,
         feito: false});
  $scope.nota.titulo = $scope.nota.horario = '';
 };
}

O AngularJS cria uma lista com base em um array de elementos, sejam estes quais forem, no caso teremos 3 campos: titulo, horario e feito (realizado). Na página HTML montamos uma tabela usando a tag ng-repeat que percorre cada elemento da lista. Criamos um formulário que ao ser executado chama a função adicionarNota que insere um novo elemento a partir dos dados do formulário com o comando push e limpa os dados da tela.

Um exercício para ajudar a desenvolver seu potencial. O campo "horário" ficou um tanto estranho na tela já que o ideal seria mais interativo. Recomendo que conheça o projeto AngularStrap, uma mistura entre o AngularJS e o Bootstrap com algumas séries de novas tags criadas para facilitar alguns trabalhos. Na página, encontramos uma série de exemplos e entre eles um elemento chamado Timepicker.

Obrigado e até a próxima
Fernando Anselmo

quinta-feira, 10 de outubro de 2013

REST - Aula Prática - Node.JS e MongoDB

Nesta segunda parte da aplicação REST, entenderemos o que vem a ser o Node.JS e como inserir dados no banco MongoDB. A IBM publicou um dos melhores e dos mais esclarecedores artigos sobre o que exatamente é o Node.js?. Resumidamente, o Node é uma plataforma de software que liberta JavaScript do navegador e permite que seja usado como uma plataforma de desenvolvimento de software em aplicações Server-Side. Executa sobre um motor ultra-rápido do Chrome, V8, e acrescenta em uma biblioteca rápida e robusta de módulos de I/O de rede assíncrona. Tendo como foco principal a construção de alto desempenho, um servidor altamente escalável e aplicativos cliente para o "Real Time Web". Uau. Aposto que pelo menos ficou curioso, então vamos brincar.

Criando a Aplicação com Express

No site oficial do Node.js baixe e instale o servidor. Vamos brincar em um esquema um pouco diferente de um simples 'Hello World', abra uma janela de comandos e instale o Express:

npm install -g express@2.5.8

Para manter uma organização, criaremos uma pasta para hospedar os projetos, por exemplo C:\rest. Dentro desta digite o seguinte comando para criar nosso projeto:

express notas

Finalize a configuração com:

cd notas
npm install

Então, temos nosso primeiro projeto em C:\rest\notas. Vamos baixar os drivers para acessarmos nosso banco, para tanto altere o arquivo package.json, da seguinte forma:

{
  "name": "Notas", 
  "version": "0.0.1",
  "private": true,
  "dependencies": {
    "express": "2.5.8",
    "jade": ">= 0.0.1",
    "mongoose": "2.6.5"
  }
}

Adicionamos uma dependência ao Mongoose (que é o driver para o MongoDB), instale através do seguinte comando:

npm install

Estamos com o esqueleto da aplicação totalmente montada. O Express funciona quase como o 'Maven', só que ao invés de Java utiliza uma dependência de pacotes com JavaScript e JSON. Editamos o arquivo app.js na raiz do projeto e adicionamos as seguintes linhas:

var express = require('express'),
  routes = require('./routes'),
  fs = require('fs'),
  NotaModel = require('./models/NotaModel.js');

...

app.configure('production', function(){
  app.use(express.errorHandler());
});

app.get('/form', function(req, res) {
  fs.readFile('./form.html', function(error, content) {
    if (error) {
      res.writeHead(500);
      res.end();
    } else {
      res.writeHead(200, { 'Content-Type': 'text/html' });
      res.end(content, 'utf-8');
    }
  });
});

app.post('/gravar', function(req, res) {
  var titulo = req.body.titulo;
  var descricao = req.body.descricao;
  NotaModel.gravarNota(titulo, descricao, function(err, user) {
    if (err) throw err;
      res.redirect('/form');
  });
});
...

Criamos duas chamadas: "/form" e "/gravar". A primeira traz um formulário HTML enquanto que a segunda recebe os dados deste formulário e grava no banco. Criamos, nesta mesma pasta (que é a raiz do nosso projeto), um arquivo chamado form.html com a seguinte codificação:

<h1>Minhas Notas</h1>
<form action="/gravar" method="post">
  <div>
    <label>Título:</label>
    <input type="text" name="titulo"/><br/>
  </div><div>
    <label>Descrição:</label>
    <textarea row="3" col="60" name="descricao"></textarea>
  </div><div>
    <input type="submit" value="Gravar Nota"/>
  </div>
</form>

Este formulário recebe os dados e quando submetido executa a chamada a ação "/gravar". No meu site publiquei um documento chamado MongoDB com Java, recomendo que baixe e leia para ter melhores referências sobre este banco.

Na camada com o MongoDB

O próximo passo é criar um arquivo de configuração para acessar o MongoDB. Na raiz do projeto criamos uma pasta chamada \lib, nesta um arquivo chamado db.js com a seguinte codificação:

var mongoose = require('mongoose');
var Schema = mongoose.Schema;
module.exports.mongoose = mongoose;
module.exports.Schema = Schema;
connect();

function connect() {
  var url = 'mongodb://localhost:27017/notas';
  mongoose.connect(url);
}
function disconnect() {
  mongoose.disconnect()
}

Temos dois métodos neste script, um para conectar e outro para desconectar o banco. Na url de conexão passamos o endereço do servidor, a porta e o nome da base de dados (que se não existe, será criada). Próximo passo é criarmos a tabela (que no MongoDB é chamado de Coleção). Na raiz do projeto criamos uma pasta chamada \models, nesta um arquivo chamado NotaModel.js com a seguinte codificação:

var db = require('../lib/db');

var NotaSchema = new db.Schema({
  titulo: {type: String, unique: true},
  descricao: String
})

var MinhaNota = db.mongoose.model('Nota', NotaSchema);

module.exports.gravarNota = gravarNota;

function gravarNota(titulo, descricao, callback) {
  var instance = new MinhaNota();
  instance.titulo = titulo;
  instance.descricao = descricao;
  instance.save(function (err) {
    if (err) {
      callback(err);
    } else {
      callback(null, instance);
    }
  });
}

Executar a aplicação

Inicie o servidor do MongoDB (veja no PDF disponibilizado como proceder) e o servidor do Node.JS com o seguinte comando:

node app.js

Acesse o endereço http://localhost:3000/form para testar a aplicação e cadastre algumas notas. Em seguida acesse o servidor do MongoDB e digite os seguintes comandos:

show dbs [e verifique que existe uma base chamada notas]
use notas
show collections [e verifique que existe uma coleção chamada notas]
db.notas.find() [e observe os dados que foram digitados]

Então é isso, agora podemos nos divertir persistindo dados no MongoDB através de um servidor puramente JavaScript.

Obrigado e até a próxima
Fernando Anselmo

terça-feira, 8 de outubro de 2013

REST - Aula Prática - AngularJS

Vi no Facebook um artigo bem interessante sobre um workshop para ensinar como criar sistemas inteiros apenas com Javascript. Com um pequeno escopo de softwares entre eles o AngularJS, Node.js e utilizando o MongoDB. O que mais me interessou foi a frase final "O aluno terminará o workshop entendendo como cada parte se integra para criar uma aplicação REST". E isso ativou todas minhas antenas (ou meus Eus), então fomos (eu e meus Eus) atrás de toda a informação possível sobre essas ferramentas (apesar de já conhecer muito bem o MongoDB).

Os artigos que pretendo postar aqui sobre essa junção vem com base em um documento chamado "Créer une <<application web>> avec AngularJS, nodeJS et mongoDB" v110813 - Brouillon (fiquei meio perdido quanto ao autor mas, acredito se tratar de David Roche), além disso dou graças aos livros da O'Reilly e Manning que me ajudaram a tirar muitas dúvidas. Então vamos juntos travar conhecimento do Rest através de uma aplicação prática ao invés de ficarmos somente na teoria.

Vamos começar pelo AngularJS que é um framework JavaScript, open source e desenvolvido pela Google. Este framework segue o modelo MVC (model-view-control) e foi a base de construção do Gmail e GoogleDoc. O AngularJS possui algumas características bem interessantes entre elas os atributos "ng-", para produzirmos nosso primeiro exemplo baixe o arquivo "angular.min.js". Para facilitar nosso estudo, criamos a seguinte estrutura de pastas:

\exemplo
   \script
       angular.min.js
       exemplo01.js
   exemplo01.html

Edite o arquivo exemplo01.js e insira os seguintes códigos:

function meuControle($scope){
  $scope.minhaVariavel="Famoso Hello World !";
} 

E para o arquivo exemplo01.html, insira os seguintes códigos:

<!doctype html>
<html ng-app>
 <head>
  <title>Teste do AngularJS</title>
  <script src="script/angular.min.js"></script>
  <script src="script/exemplo01.js"></script>
 </head>
 <body>
  <h1 ng-controller="meuControle">{{minhaVariavel}}</h1>
 </body>
</html>

O atributo ng-app define que este é um programa AngularJS, e o atributo ng-controller informa que o escopo da aplicação está definido com base em um determinado controlador. Um dos princípios base do AngularJS é a nomeação da data-binding, isto é, a capacidade de modificar informações da parte HTML através do JavaScript. Só que essa modificação se faz nos dois sentidos: HTML para JavaScript quanto JavaScript para HTML.

Adicione mais duas linhas ao HTML (ou crie um outro arquivo chamado exemplo02.html, copie as mesmas linhas deixando o <body> vazio):

...
  Outra Variável: <input type="text" ng-model="outraVariavel" size="30" placeholder="Insira o valor da Variável" />
  <h1>{{outraVariavel}}</h1>
 </body>
</html>

E na medida que digitamos um valor na caixa de texto, este aparece simultaneamente em tela. Como o outro valor advém de um controlador, devemos criar um formulário e submetê-lo. Então adicione (ou crie um outro arquivo chamado exemplo03.html e deixe o <body> idêntico ao exemplo01.html) as seguintes linhas:

  <form ng-submit="modificarVariavel()">
   Minha Variável: <input type="text" ng-model="valorForm" size="30" placeholder="Insira o valor da Variável" />
   <input class="btn-primary" type="submit" value="Mudar"/>
  </form>
 </body>
</html>  

Também precisaremos modificar o arquivo exemplo01.js para o seguinte conteúdo:

function meuControle($scope){
  $scope.minhaVariavel="Famoso Hello World!";
  $scope.modificarVariavel = function() {
    $scope.minhaVariavel = $scope.valorForm;
    $scope.valorForm = '';
  };
} 

A ideia é tremendamente simples, uma vez que o formulário for submetido será chamado a função "modificarVariavel" que troca o valor de "minhaVariavel" pelo conteúdo do campo "valorForm" e limpa o campo "valorForm". Porém observe que não funcionou. O que está errado? Tente descobrir antes de continuar lendo...

Observe que o atributo "ng-controller" está definido somente para a tag "h1", pode-se dizer que o controle só atende a esta tag então, para solucionar o problema retire esse atributo desta tag e coloque-o na tag "body", deixando o seguinte código:

<body ng-controller="meuControle">
Obrigado e até a próxima
Fernando Anselmo

domingo, 6 de outubro de 2013

Mineração de Dados - Arquitetura do Hadoop

Na postagem anterior, instalamos o Hadoop que é uma plataforma para o fornecimento de armazenamento distribuído e capacidades computacionais. O Hadoop foi concebido para corrigir o problema de escalabilidade que existia na Nutch um pesquisador e rastreador de código aberto. Nessa época a Google havia publicado diversos artigos que descreviam um problema com o sistema de arquivos distribuídos, o GFS (Google File System) e o MapReduce, uma estrutura computacional para o processamento em paralelo.

A implementação bem sucedida desses papéis do Nutch resultou em dois projetos separados, o segundo se tornou o Hadoop, e foi criado como um projeto da Apache.

Componentes do Hadoop

HDFS é o componente de armazenagem de Hadoop. Um sistema de arquivos distribuído é modelado com base no GFS. HDFS é otimizado para um alto rendimento e funciona melhor quando a leitura/escrita e realizada em arquivos grandes (gigabytes e maiores). Para suportar esta transferência o HDFS aproveita grandes (para um sistema de arquivos) tamanhos de bloco e otimizações pesquisa de dados para reduzir o I/O de rede.

Escalabilidade e disponibilidade são também características chaves do HDFS, conseguida em parte devido à replicação dos dados e da tolerância a falhas. HDFS é tolerante a falhas de software e hardware, e automaticamente replica os blocos de dados dos nós que falharam.

MapReduce é um framework de computação distribuídos baseada em lote (batch). Permite paralelizar o trabalho ao longo de uma grande quantidade de dados brutos, tais como combinar web logs com dados relacionais de um banco de dados OLTP para o modelo como os usuários interagem com o site. Este tipo de trabalho poderia levar vários dias ao utilizar as técnicas convencionais de programação em série, porém, é reduzido a poucos minutos.

O modelo MapReduce simplifica o processamento em paralelo ao abstrair as complexidades envolvidas no trabalho com sistemas distribuídos, como a paralelização computacional, a distribuição do trabalho e ao lidar com hardware/software confiáveis. Com essa abstração, o MapReduce permite que o programador se concentre em atender às necessidades de negócios, ao invés de perder tempo em complicações de um sistema distribuído.

Arquivos de Configuração do Hadoop

  • hadoop-env.sh - configurações específicas do ambiente. Na instalação configuramos o JAVA_HOME. Também podemos especificar opções da JVM para vários componentes do Hadoop, personalizar os diretórios e os locais dos arquivos do master e dos slaves.
  • core-site.xml - contém os itens de configuração do Hadoop ao nível do sistema, como a URL do HDFS, o diretório temporário e os locais de script de suporte de reconhecimento de clusters.
  • hdfs-site.xml - configurações como o total de replicação de arquivos, tamanho do bloco, e quais permissões são aplicadas.
  • mapred-site.xml - configurações como o número padrão para a redução de tarefas, padrão mínimo/máximo de tamanhos de memória e execução especulativa.
  • masters - lista com os hosts que estão no servidor. Devemos ter cuidado pois ao iniciar o Hadoop é lançado o NameNode e JobTracker no host local a partir do qual emitimos o start, e em seguida o SSH para todos os nós que estão neste arquivo para iniciar um SecondaryNameNode.
  • slaves - lista com os hosts que são escravos do Hadoop. Ao iniciar o Hadoop é localizado o SSH de cada host neste arquivo e lançado os DataNode e TaskTracker daemons.

Agora que já entendemos o que é o Hadoop e como funciona seu mecanismo podemos partir para novas atividades em breve.

Obrigado e até a próxima
Fernando Anselmo

PS.
Conheça mais sobre o GFS em http://research.google.com/archive/gfs.html.
Conheça mais sobre o MapReduce em http://research.google.com/archive/
mapreduce.html.

Mineração de Dados - Hadoop no Windows (com Cygwin)

O Apache Hadoop é um banco extraordinário e feito especialmente para Big Data. Em vários sites pode-se obter as características deste banco. Porém um detalhe, foi criado para Linux, o que pretendo fazer é em uma máquina exclusivamente Windows 7 (sem nenhuma espécie de emulador) rodar este banco. Para isto vamos precisar do Cygwin. (Lembro: que por ser um banco feito em Java é necessário que a JDK tenha sido instalada corretamente antes de começarmos).

1º Passo: Instalando o Cygwin


Baixe e execute o instalador do Cygwin até o momento que for solicitado os pacotes. Nesta tela pesquise (search) cada um dos seguintes pacotes marcando todas suas opções (troque aonde estiver escrito skip):

  • openssh
  • openssl
  • Tcp_wrappers
  • Diffutils
Deixe prosseguir e finalizar a instalação. Ao término pode desmarcar a opção "Add icon to Start Menu".


2º Passo: Configurando o Cygwin


Entre no ícone criado do Cygwin e digite o comando: ssh-host-config, digite a seguinte configuração:

  • privilege: yes (ENTER)
  • new local account: yes (ENTER)
  • install ssh as service: yes (ENTER)
  • value of CYGWIN: (somente pressione ENTER)
  • different name: no (ENTER)
  • create new privilege: yes (ENTER)
  • Entre com uma senha
No Windows, ative o serviço: CYGWIN sshd


3º Passo: Configurando o Hadoop


Baixe no site do Hadoop o arquivo hadoop-[versão atual]-bin.tar.gz e coloque-o na pasta do seu usuário (C:\users\seu_usuário), pois esta é a pasta que o Cygwin utiliza por padrão.

Para descompactar o arquivo, retorne ao Cygwin e digite: tar xzvf hadoop-[versão atual]-bin.tar.gz. Após o término da descompactação, entre na pasta do Hadoop através do gerenciador de arquivos e selecione a pasta conf. Edite (como por exemplo Notepad++) agora os seguintes arquivos:

a. hadoop-env.ssh

Existe uma linha comentada da localização da JAVA_HOME, remova o comentário (#) e corrija com a localização correta da pasta aonde está instalada a JDK. Por exemplo:

export JAVA_HOME=C:/arquiv~1/Java/jdk1.7.0_01

Lembrando que no Linux não existe a pasta "Arquivos de Programas" que deve ser trocada para seu nome simples "arquiv~1"

b. core-site.xml

Adicione para a tag <configuration> o seguinte conjunto:

<configuration>
  <property>
    <name>fs.default.name</name>
    <value>hdfs://localhost:9000</value>
  </property>
</configuration>

c. hdfs-site.xml

Adicione para a tag <configuration> o seguinte conjunto:

<configuration>
  <property>
    <name>dfs.replication
    <value>1
  </property>
</configuration>

d. mapred-site.xml

Adicione para a tag <configuration> o seguinte conjunto:

<configuration>
  <property>
    <name>mapred.job.tracker</name>
    <value>localhost:9001</value>
  </property>
</configuration>

4º Passo: Iniciando o Ambiente


De volta ao Cygwin, digite: cd hadoop-[versão atual]. Precisamos verificar se podemos criar uma nova keygen, use o seguinte comando:

$ ssh localhost

Realizado todos os procedimentos digite:

$ ssh-keygen -t dsa -P '' -f ~/.ssh/id_dsa 
$ cat ~/.ssh/id_dsa.pub >> ~/.ssh/authorized_keys
$ exit

Somente na primeira vez, precisamos distribuir os arquivos de sistema, para tanto digite:

$ bin/hadoop namenode -format

Para iniciar o Hadoop digite:

$ bin/start-all.sh

Para testar se esta tudo funcionando, abra um navegador e digite o seguinte endereço: http://localhost:50070, e como resposta a página do Hadoop aparecerá. Agora já estamos com o nosso banco instalado e funcionando, futuramente vamos realizar alguns testes.

Obrigado e até a próxima
Fernando Anselmo

PS. Para interromper o Hadoop digite:

$ bin/stop-all.sh