Kinesis Streams

Introdução

O Amazon Kinesis Data Streams consome uma grande quantidade de dados em tempo real, armazena os dados de forma durável e os torna disponíveis para consumo. A unidade de dados armazenada pelo Kinesis Data Streams é um registro de dados. Um streamrepresenta uma sequência ordenada de registros de dados. Os registros de dados em um stream são distribuídas em shards (fragmentos).

Uma shard é um grupo de registros de dados em um stream. Quando você cria um stream, você especifica o número de shards desse stream. Cada shard pode suportar até 5 transações por segundo para leituras, até uma taxa total máxima de leitura de dados de 2 MB por segundo. Shards também suportam até 1.000 registros por segundo para gravações, até uma taxa total máxima de gravação de dados de 1 MB por segundo (inclusive chaves de partição). A capacidade total de um stream é a soma das capacidades de suas shards. Você pode aumentar ou diminuir o número de shards em um stream de acordo com a necessidade. No entanto, você é cobrado por shard (e muito bem cobrado).

Um produtor coloca registros de dados em shards e um consumidor obtém registros de dados a partir delas.

Como determinar o tamanho inicial do Kinesis Stream

Antes de criar um stream, você precisa determinar um tamanho inicial para ele. Depois de criá-lo, você pode aumentar ou diminuir dinamicamente a capacidade de seu shard usando o Console de gerenciamento da AWS ou a API UpdateShardCount. Você pode fazer atualizações enquanto houver umaAmazon Kinesis Data Streams application consumindo dados do stream.

Para determinar o tamanho inicial de um stream, você precisa dos seguintes valores de entrada:

  • O tamanho médio do registro de dados gravado no stream do em kilobytes (KB) arredondando para o próximo 1 KB, o tamanho dos dados (average_data_size_in_KB).
  • O número de registros de dados gravados e lidos no stream por segundo (records_per_second).
  • O número de Amazon Kinesis Data Streams applications que consomem dados simultânea e independentemente do stream, ou seja, os consumidores (number_of_consumers).
  • A largura de banda de gravação de entrada em KB (incoming_write_bandwidth_in_KB), que é igual a average_data_size_in_KBmultiplicado por records_per_second.
  • A largura de banda de leitura de saída em KB (outgoing_read_bandwidth_in_KB), que é igual a incoming_write_bandwidth_in_KBmultiplicado por number_of_consumers.

Você pode calcular o número inicial de shards (number_of_shards) que seu stream precisará usando os valores de entrada na seguinte fórmula:

number_of_shards = max(incoming_write_bandwidth_in_KB/1000, outgoing_read_bandwidth_in_KB/2000)

Criar um Stream

Você pode criar um stream usando o console do Kinesis Data Streams, a API do Kinesis Data Streams ou a AWS CLI.

Para criar um stream usando o console

  1. Abra o console do Kinesis Data Streams em https://console.aws.amazon.com/kinesis/.
  2. Na barra de navegação, expanda o seletor de região e escolha uma região.
  3. Selecione Create Stream.
  4. Na página Create Stream, insira um nome para o stream e o número de shards necessárias e, em seguida, clique em Criar.

    Na página Stream List, o Status de seu stream será CREATING enquanto ele estiver sendo criado. Quando o stream fica pronto para uso, o Status é alterado para ACTIVE.

  5. Escolha o nome do fluxo. A página Stream Details exibe um resumo da configuração do fluxo com informações de monitoramento.

Para criar um stream usando a API do Kinesis Data Streams

  • Para obter informações sobre a criação de um stream usando a API do Kinesis Data Streams, consulte Criar um stream.

Para criar um stream usando a AWS CLI

  • Para obter mais informações sobre a criação de um stream usando a AWS CLI, consulte o comando create-stream.

Atualizar um Stream

Você pode atualizar os detalhes de um stream usando o console do Kinesis Data Streams, a API do Kinesis Data Streams ou a AWS CLI.

nota

Você pode ativar a criptografia no lado do servidor para streams existentes ou para os recém-criados.

Para atualizar um stream usando o console

  1. Abra o console do Kinesis Data Streams em https://console.aws.amazon.com/kinesis/.
  2. Na barra de navegação, expanda o seletor de região e selecione uma região.
  3. Escolha o nome do fluxo. A página Stream Details exibe um resumo das informações de configuração e monitoramento do stream.
  4. Para editar o número de shards, selecione Editar na seção shards e, em seguida, insira uma nova shard.
  5. Para ativar a criptografia de registros de dados no lado do servidor, selecione Editar na seção de Criptografia no lado do servidor. Escolha uma chave do KMS para usar como chave mestra de criptografia, ou use a chave mestra padrão, aws/kinesis, gerenciada pelo Kinesis. Se você ativar a criptografia para um stream e usar sua própria chave mestra do KMS, seus aplicativos produtores e consumidores precisam ter acesso à chave mestra do KMS que você usou. Para atribuir permissões a um aplicativo para acessar uma chave do KMS gerado pelo usuário, consulte Permissões para usar as chaves mestras do KMS geradas pelo usuário
  6. Para editar o período de retenção de dados, selecione Editar na seção de Período de retenção de dados e, em seguida, insira um novo período de retenção de dados.
  7. Se você tiver ativado as métricas personalizadas na sua conta, selecione Editar na seção Métricas em nível de shard e, em seguida, especifique as métricas de seu stream. Para obter mais informações, consulte Monitorar o serviço do Amazon Kinesis Data Streams com o Amazon CloudWatch.

Atualizar um Stream usando a API

Para atualizar os detalhes do stream usando a API, consulte os seguintes métodos:

 

JHipster – Introdução

Conceito

JHipster é um poderoso framework que ajuda a criar aplicações Java, Spring Boot e Angular.

Instalação

Pré-requisitos

  • Java 8
  • Node.js
  • Yarn

Instalando JHipster

Para instalação, execute os itens abaixo.

  • npm i -g bower
  • npm i -g yeoman-doctor
  • npm cache clean -f
  • npm i -g yo
  • npm install -g generator-jhipster

Criando projeto

Para criar um projeto.

  • Crie um diretório onde deseja que seja criado o projeto, por exemplo /opt/jhipster-teste/.
  • Execute o comando
    • yo jhipster
  • Ele poderá fazer algumas perguntas sobre ajuda anônima

Tipo de Aplicação

? Which *type* of application would you like to create? (Use arrow keys)
> Monolithic application (recommended for simple projects)
Microservice application
Microservice gateway
JHipster UAA server (for microservice OAuth2 authentication)

Nome da Aplicação

? What is the base name of your application? (jhipster)

Nome do Pacote

? What is your default Java package name? (com.mycompany.myapp)

Configuração de Monitor

? Do you want to use the JHipster Registry to configure, monitor and scale your application? (Use arrow keys)
> No
Yes

Tipo de Banco de Dados

? Which *type* of database would you like to use? (Use arrow keys)
> SQL (H2, MySQL, MariaDB, PostgreSQL, Oracle, MSSQL)
MongoDB
Cassandra
[BETA] Couchbase

Tipo de BD – Produção

? Which *production* database would you like to use? (Use arrow keys)
> MySQL
MariaDB
PostgreSQL
Oracle (Please follow our documentation to use the Oracle proprietary driver)
Microsoft SQL Server

Tipo de BD – Development

? Which *development* database would you like to use? (Use arrow keys)
> H2 with disk-based persistence
H2 with in-memory persistence
MySQL

Tipo de Cache

? Do you want to use the Spring cache abstraction? (Use arrow keys)
> Yes, with the Ehcache implementation (local cache, for a single node)
Yes, with the Hazelcast implementation (distributed cache, for multiple nodes)
[BETA] Yes, with the Infinispan (hybrid cache, for multiple nodes)
No (when using an SQL database, this will also disable the Hibernate L2 cache)

Hibernate 2nd level

? Do you want to use Hibernate 2nd level cache? (Y/n)

Ferramenta de build

? Would you like to use Maven or Gradle for building the backend? (Use arrow keys)
> Maven
Gradle

Outras tecnologias

? Which other technologies would you like to use? (Press <space> to select, <a> to toggle all, <i> to inverse selection
)
>( ) Social login (Google, Facebook, Twitter)
( ) Search engine using Elasticsearch
( ) WebSockets using Spring Websocket
( ) API first development using swagger-codegen
( ) Asynchronous messages using Apache Kafka

Client Framework (Angular)

? Which *Framework* would you like to use for the client? (Use arrow keys)
> Angular 5
AngularJS 1.x

Biblioteca SASS

? Would you like to enable *SASS* support using the LibSass stylesheet preprocessor? (y/N)

Internacionalização

? Would you like to enable internationalization support? (Y/n)

Idioma nativo

? Please choose the native language of the application (Use arrow keys)
> English
Estonian
Farsi
French
Galician
German
Greek
(Move up and down to reveal more choices)

Idiomas adicionais

? Please choose additional languages to install (Press <space> to select, <a> to toggle all, <i> to inverse selection)
>( ) Arabic (Libya)
( ) Armenian
( ) Catalan
( ) Chinese (Simplified)
( ) Chinese (Traditional)
( ) Czech
( ) Danish
(Move up and down to reveal more choices)

Frameworks de testes

? Besides JUnit and Karma, which testing frameworks would you like to use? (Press <space> to select, <a> to toggle all,
<i> to inverse selection)
>( ) Gatling
( ) Cucumber
( ) Protractor

Geradores adicionais

? Would you like to install other generators from the JHipster Marketplace? (y/N)

Geradores adicionais – escolha

? Which other modules would you like to use? (Press <space> to select, <a> to toggle all, <i> to inverse selection)
>( ) (ignite-jhipster-1.5.1) A React Native boilerplate for JHipster apps.
( ) (generator-jhipster-module-2.3.1) JHipster module, used to create a JHipster module
( ) (generator-jhipster-docker-2.4.0) Additional Docker support: Docker Hub, Local SMTP Server, NGinx
( ) (generator-jhipster-primeng-2.0.18) Generate PrimeNG Components
( ) (generator-jhipster-circleci-2-1.1.2) Generating CircleCI configuration file version 2 for a JHipster project
( ) (generator-jhipster-ci-1.0.0) JHipster module, Continuous Integration support in your JHipster application
( ) (generator-jhipster-bootstrap-material-design-3.5.1) Add Material design to your JHipster application
(Move up and down to reveal more choices)

Processo de instalação

yarn install v1.3.2
info No lockfile found.
[1/5] Validating package.json…
[2/5] Resolving packages…

Server application generated successfully.

Run your Spring Boot application:
./mvnw (mvnw if using Windows Command Prompt)

Client application generated successfully.

Start your Webpack development server with:
yarn start

Application successfully committed to Git.

Importando arquivo JDL

É possível criar um arquivo de modelagem do JHipster (arquivo .jdl) através do JDL-Studio:

https://start.jhipster.tech/jdl-studio/

Após gerar e baixar o arquivo (geralmente será jhipster-jdl.jh), no diretório do projeto.

Executar o comando para importar as entidades (veja que o arquivo foi renomeado):

$ jhipster import-jdl ./jhipster-jdl

Rodando a aplicação

Entre no diretório da aplicação e digite:

$ mvnw

Abrir um navegador e digitar:

http://localhost:8080 (usr e pwd: admin)

JSON Server

Introdução

Para simulação de aplicações REST, existe uma poderosa ferramenta que pode ser utilizada, o JSON Server.

Conceito

Entender o funcionamento dessa ferramenta é simples. Ele utiliza a definição de um arquivo de dados no formato Json e, disponibiliza os métodos para interagir, através de chamadas http (GET, POST, PUT, DELETE, etc).

Se fizermos request do tipo POST, PUT, DELETE, etc, o conteúdo do arquivo json será atualizado, através do lowdb.

Exemplo

Instalar a ferramenta

A instalação é feita através do comando npm.

  • Abra um prompt de comando
  • Digite o comando para instalar o json-server
  • $ npm install -g json-server
  • Pode-se constatar a instalação com o comando
  • $ json-server -v
    • 0.12.1

Criar arquivo json

Devemos, agora, criar um arquivo db.json, que servirá para armazenar os dados que desejamos utilizar.

Exemplo (db.json):

{
   "posts": [
      { "id": 1, "title": "json-server", "author": "typicode" }
   ],
   "comments": [
      { "id": 1, "body": "some comment", "postId": 1 }
   ],
   "profile": { "name": "typicode" }
}

Subindo o servidor

Para subir o serviço, utilizamos o comando json-server.

  • Abra um prompt de comando
  • Vá ao diretório, onde encontra-se o arquivo db.json
  • Digite o comando
  • $ json-server db.json

Como resultado, será apresentado alguns exemplos de chamada. Utilizando CTRL+C pára o servidor.

\{^_^}/ hi!

Loading db.json
Done

Resources
http://localhost:3000/posts
http://localhost:3000/comments
http://localhost:3000/profile

Home
http://localhost:3000

Type s + enter at any time to create a snapshot of the database

Exemplos:

http://localhost:3000/comments

http://localhost:3000/comments/1

 


							

Dados em streaming

Introdução

Dados em streaming são dados gerados continuamente por milhares de fontes de dados, que geralmente enviam os registros de dados simultaneamente, em tamanhos pequenos (na ordem dos kilobytes). Os dados em streaming incluem uma ampla variedade de dados, como arquivos de log gerados por clientes usando seus aplicativos móveis ou da web, compras de e-commerce, atividade de jogador durante o jogo, informações de redes sociais, pregões financeiros ou serviços geoespaciais, como também telemetria de serviços conectados ou instrumentação em datacenters.

Esses dados devem ser processados sequencial e incrementalmente por registro ou durante períodos móveis, e usados para uma ampla variedade de dados analíticos, como correlações, agregações, filtragem e amostragem. As informações derivadas de tais análises proporcionam às empresas visibilidade sob vários aspectos de suas atividades de negócios e de clientes, como uso de serviços (para medição/faturamento), atividade do servidor, cliques no site, além da geolocalização de dispositivos, pessoas e mercadorias, permitindo que elas respondam de imediato a situações emergentes. Por exemplo, as empresas podem monitorar alterações na percepção pública de suas marcas e produtos, analisando continuamente streams de mídias sociais e respondendo em tempo hábil, conforme o surgimento das necessidades.

Benefícios

O processamento de dados em streaming é benéfico na maioria dos cenários em que novos dados dinâmicos são gerados continuamente. Ele se aplica à maior parte dos casos de uso de segmentos do setor e de big data. Geralmente, as empresas começam com aplicações simples, como a coleta de logs do sistema, e processamentos rudimentares, como a rotação de computações mín/máx. Então, essas aplicações se desenvolvem, tornando-se um processamento mais sofisticado praticamente em tempo real. Inicialmente, as aplicações podem processar streams de dados para produzir relatórios simples e executar ações pouco complexas em resposta, como emitir alertas quando medidas fundamentais excederem determinados limites. Eventualmente, essas aplicações executam modelos de análise de dados mais sofisticados, como a aplicação de algoritmos de aprendizagem de máquina e a obtenção de informações mais profundas dos dados. Com o tempo, são aplicados algoritmos complexos de processamento em streams e de eventos, como períodos cada vez menores para a localização de filmes, enriquecendo ainda mais as informações obtidas.

Exemplos

  • Sensores em veículos de transporte, equipamentos industriais e máquinas agrícolas enviam dados para uma aplicação de streaming. A aplicação monitora o desempenho, detecta de antemão qualquer defeito em potencial e faz automaticamente pedidos de peças extras, o que evita períodos de inatividade do equipamento.
  • Uma instituição financeira monitora alterações na bolsa de valores em tempo real, calcula o valor em risco e recompõe carteiras com base nas flutuações de preço das ações.
  • Um site do setor imobiliário monitora um subconjunto de dados de dispositivos móveis de consumidores e recomenda em tempo real propriedades a visitar com base em sua localização geográfica.
  • Uma empresa de energia solar precisa manter a produtividade da energia para seus clientes, ou pagará multas. Ela implementou uma aplicação de dados em streaming que monitora todos os painéis em campo, e programa serviços em tempo real, o que minimiza os períodos de baixa produtividade de cada painel e os pagamentos de multas associados.
  • Uma editora transmite bilhões de registros de sequências de cliques de suas propriedades on-line, agrega e enriquece dados com informações demográficas sobre usuários e otimiza a disposição do conteúdo no site, proporcionando relevância e uma melhor experiência para o público.
  • Uma empresa de jogos on-line coleta dados em streaming sobre as interações dos jogadores com o jogo e alimenta os dados em sua plataforma de jogos. Em seguida, a empresa analisa os dados em tempo real, oferece incentivos e experiências dinâmicas para envolver seus jogadores.

Processamento em lote vs. Processamento em streams

Antes de utilizar dados em streaming, vale a pena comparar o processamento em streams e o processamento em lotes. O processamento em lotes pode ser utilizado para computar consultas arbitrárias sobre diferentes conjuntos de dados. Ele geralmente computa resultados derivados de todos os dados que engloba e permite a análise profunda de conjuntos de big data. Sistemas baseados em MapReduce, são exemplos de plataformas compatíveis com trabalhos em lote. Em comparação, o processamento em streams exige a ingestão de uma sequência de dados e a atualização incremental de métricas, relatórios e estatísticas de resumo em resposta a cada registro de dados recebido. Ele é mais adequado para funções de monitoramento e resposta em tempo real.

Processamento em lotes Processamento em streams
 Escopo de dados Consultas ou processamento de todos ou da maioria dos dados no conjunto de dados. Consultas ou processamento de dados dentro de um período rotacional, ou apenas do registro de dados mais recente.
Tamanho dos dados Grandes lotes de dados. Registros individuais ou microlotes compostos de alguns registros.
Desempenho Latências em minutos para horas. Exige latência na ordem dos segundos ou milissegundos.
Análise Dados analíticos complexos. Métricas simples de funções, agregação e rotação de respostas.

Muitas empresas estão criando um modelo híbrido ao combinar as duas abordagens, além de manter uma layer em tempo real e uma layer em lote. Primeiro, os dados são processados por uma plataforma de dados em streaming, para extrair informações em tempo real, e depois são mantidos em um armazém, como o S3, onde podem ser transformados e carregados para uma variedade de casos de uso de processamento em lotes.

Funcionamento

O processamento de dados em streaming exige duas layers: uma de armazenamento e outra de processamento. A layer de armazenamento precisa suportar a solicitação de registros e uma forte consistência para permitir leituras e gravações rápidas, de baixo custo e reproduzíveis, de grandes streams de dados. A layer de processamento é responsável pelo consumo de dados da layer de armazenamento, realizando cálculos sobre esses dados e, em seguida, enviando notificações para a layer de armazenamento excluir os dados desnecessários. Você também deve planejar a escalabilidade, a durabilidade de dados e a tolerância a falhas nas layers de armazenamento e processamento. Como resultado, surgiram muitas plataformas que disponibilizam a infraestrutura necessária para criar aplicações de dados de streaming, como Amazon Kinesis Streams, Amazon Kinesis Firehose, Apache Kafka, Apache Flume, Apache Spark Streaming e Apache Storm.

Kafka – Introdução

Introdução

O Apache Kafka é um sistema de código aberto com envio distribuído de mensagens que permite que você crie aplicativos em tempo real usando dados de streaming.

Você pode enviar dados de streaming, como sequências de cliques de sites, transações financeiras e logs de aplicativo, para o cluster do Kafka. Ele reserva os dados e os distribui para aplicativos de processamento de streams incorporados às estruturas, como Apache Spark Streaming, Apache Storm ou Apache Samza.

Desde leitura e escrita direta entre diversos bancos e mecanismos de pesquisas (SQL, MongoDB, RethinkDB, ElasticSearch) até materialização de dados on streaming com KTable por exemplo, é possível utilizar o Kafka de diversas maneiras para mover e transformar grande volume de dados.

Conceitos

Mensagens

Mensagem é o principal recurso do Kafka. Todos os eventos do Kafka podem ser resumidos em mensagens, sendo consumidas e produzidas através de tópicos. Uma mensagem pode ser desde uma simples String com “Hello World!” ou até mesmo um JSON contendo um objeto do seu domínio.

O Kafka permite definir Schemas para mensagens, como por exemplo utilizando o Avro. Como num exemplo de um JSON contendo um objeto do seu domínio, o Schema pode auxiliar impedindo que mensagens contendo conteúdos inválidos sejam trafegadas no tópico.

Uma mensagem pode também ser composta por uma chave (key/value), que é utilizada para sharding e compactação dentro do Kafka. Assim em um ambiente distribuído, é garantido a ordem das mensagens uma vez que mensagens com a mesma chaves são direcionadas para uma única partição do Kafka.

Tópicos

Um tópico é como categorizamos grupos de mensagens dentro do Kafka. Todas as mensagens enviadas para o Kafka permanecem em um tópico. Como comentado sobre Event Sourcing, mensagens são imutáveis e ordenadas.

Para manter a ordenação em um ecossistema de Kafka, os tópicos possuem partições e fatores de replicação. Um tópico pode possuir n partições, mas ao receber uma nova mensagem o Kafka automaticamente direciona aquela mensagem para uma partição específica dependendo de sua chave (key). Assim mensagens de uma mesma chave estarão apenas em uma única partição, garantindo assim a leitura ordenada de todas as mensagens de um tópico.

Producer

Um Kafka Producer é responsável por enviar uma mensagem para um tópico específico. De forma simples, você pode produzir uma mensagem em um tópico.

Uma vez que uma mensagem é produzida em um tópico o próprio Kafka organiza a mensagem em uma partição, garantindo sempre a ordem das mensagens produzidas, como citado anteriormente.

Consumer

Temos os tópicos, e as mensagens dentro dos tópicos. Com o Kafka Consumer é possível ler essas mensagens de volta. Importante entender que, ao ler uma mensagem com o consumer, a mensagem não é retirada do tópico.

Você pode ter vários Kafka Consumers conectados em um mesmo tópico, e cada um terá a posição onde parou de ler. Assim você pode ter um tópico produzindo como no exemplo acima, pontuações de um jogador, e ter diversos consumers em pontos diferentes do tópico realizando ações diferentes. Você também pode escolher ter vários consumers lendo o mesmo tópico e na mesma partição, para escalar sua aplicação por exemplo, neste caso estes consumers fariam parte de um Consumer Group, e compartilharão sempre a posição final de leitura entre eles (offsets).

Apache Zookeeper

O Zookeeper é um serviço centralizado para, entre outras coisas, coordenação de sistemas distribuídos. O Kafka é um sistema distribuído, e consequentemente delega diversas funções de gerenciamento e coordenação para o Zookeeper.

Eles possuem uma dependência muito forte, mas isso não é tão ruim. O Kafka pode fazer o que ele intencionalmente tem que saber fazer de melhor, delegando essas demais funcionalidades para quem sabe fazer isso bem, sem precisar reinventar a roda.

Kafka Brokers / Clusters

O Broker é o coração do ecossistema do Kafka. Um Kafka Broker é executado em uma única instância em sua máquina. Um conjunto de Brokers entre diversas máquinas formam um Kafka Cluster.

Uma das principais características do Kafka é a escalabilidade e resiliência que ele oferece. Você pode rodar o Kafka local na sua máquina onde sua própria máquina teria um Kafka Broker formando um Kafka Cluster, como pode subir n instâncias de Kafka Brokers e todas estarem no mesmo Kafka Cluster. Com isso é possível escalar sua aplicação, e replicar os dados entre os Brokers.

Code Playgrounds – Introdução e soluções

Introdução

Code Playground é uma ferramenta para editar e testar aplicações Web, utilizando HTML, CSS e JavaScript de forma online.

Com esse tipo de ferramenta é possível configurar pré-compiladores HTML, CSS e JavaScript, por exemplo:

  • HTML – Hml, Markdown, Slim e Pug
  • CSS – LESS, SCSS, Sass, Stylus e PostCSS
  • Javascript – CoffeeScript, LiveScript, TypeScript e Babel

Soluções

Abaixo, seguem algumas boas soluções:

  • Codepen – http://codepen.io/
  • JSBin – http://jsbin.com/
  • Plunker – https://plnkr.co/
  • CSSDeck – http://cssdeck.com/
  • Dabblet – http://dabblet.com/
  • Liveweave – http://liveweave.com/
  • JSFiddle – http://jsfiddle.net/

Conclusão

Entre os que mais se destacam, encontram-se o Codepen (possui mais pré-processadores Javascript), CSSDeck (bastante utilizado). Porém, assim como ocorrem com editores (Visual Studio Code, Atom, Sublime e Vim), a escolha depende da melhor adequação da ferramenta ao desenvolvedor.

Desenvolvendo uma aplicação Spring Data REST e H2

Desenvolvendo uma aplicação Spring Data, REST e H2

Criando a aplicação

Acesse o site http://start.spring.io/ e configure uma aplicação conforme imagem abaixo.

Baixe e descompacte o arquivo (spring-rest-data-h2.zip) em algum diretório de trabalho.

Abra o Eclipse e importe o projeto (Maven Project).

Criação da classe controller

No Eclipse, clique em File / New / Java Class e defina-a conforme abaixo.

Código

package br.com.whs.springrestdatah2.controller;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
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.RestController;

import br.com.whs.springrestdatah2.Model.User;
import br.com.whs.springrestdatah2.repository.UserRepository;

@RestController
@RequestMapping("/user")
public class UserController {
        @Autowired
        private UserRepository userRepo;
    
        @RequestMapping(value = "/list", method = RequestMethod.GET)
        public List<User> findAll(){
                return userRepo.findAll();
        }

        @RequestMapping(value = "/find-by-id/{id}", method = RequestMethod.GET)
        public ResponseEntity<?> findById(@PathVariable final Long id){
                User user = userRepo.findOne(id);
                if( user == null ){
                        String msg = "{\"message\":\"User with id " + id + " not found.\"}";
                        return new ResponseEntity<String>(msg,HttpStatus.NOT_FOUND);
                }else{
                        return new ResponseEntity<User>(user,HttpStatus.OK);
                }
        }

        @RequestMapping(value = "/find-by-login/{loginName}", method = RequestMethod.GET)
        public ResponseEntity<?> findByLoginName(@PathVariable final String loginName){
                User user = userRepo.findByLoginName(loginName);
                if( user == null ){
                        String msg = "{\"message\":\"User with login " + loginName + " not found.\"}";
                        return new ResponseEntity<String>(msg,HttpStatus.NOT_FOUND);
                }else{
                        return new ResponseEntity<User>(user,HttpStatus.OK);
                }
        }
        @RequestMapping(value = "/create", method = RequestMethod.POST)
        public ResponseEntity<User> create(@RequestBody final User user){
                userRepo.save(user);
                return new ResponseEntity<User>(userRepo.findByLoginName(user.getLoginName()),HttpStatus.OK);
        }

        @RequestMapping(value = "/update/{id}", method = RequestMethod.PUT)
        public ResponseEntity<?> update(@PathVariable("id") long id, @RequestBody User user) {
            User userData = userRepo.findOne(id);
            if (userData == null) {
                String msg = "{\"message\":\"User with id " + id + " not found.\"}";
                return new ResponseEntity<String>(msg,HttpStatus.NOT_FOUND);
            }
            userData.setLoginName(user.getLoginName());
            userData.setFullName(user.getFullName());
            userData.setPassword(user.getPassword());
            userRepo.save(userData);
            return new ResponseEntity<User>(userData, HttpStatus.OK);
        }
    
        @RequestMapping(value = "/delete/{id}", method = RequestMethod.DELETE)
        public ResponseEntity<?> delete(@PathVariable("id") long id) {
            User user = userRepo.findOne(id);
            if (user == null) {
                String msg = "{\"message\":\"User with id " + id + " not found.\"}";
                return new ResponseEntity<String>(msg,HttpStatus.NOT_FOUND);
            }
            userRepo.delete(id);
            return new ResponseEntity<User>(HttpStatus.NO_CONTENT);
        }
}

Criando a interface UserRepository

Código

package br.com.whs.springrestdatah2.repository;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Component;

import br.com.whs.springrestdatah2.Model.User;

@Component
public interface UserRepository extends JpaRepository<User, Long>{
    public User findByLoginName(String loginName);
}

 

Criando a classe Model (User.java)

Código

package br.com.whs.springrestdatah2.Model;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;

@Entity
public class User {

    @Id
    @GeneratedValue
    private Long id;
    private String loginName;
    private String fullName;
    private String password;
public Long getId() {
    return id;
}

public void setId(Long id) {
    this.id = id;
}

public String getLoginName() {
    return loginName;
}

public void setLoginName(String loginName) {
    this.loginName = loginName;
}

public String getFullName() {
    return fullName;
}

public void setFullName(String fullName) {
    this.fullName = fullName;
}

public String getPassword() {
    return password;
}

public void setPassword(String password) {
    this.password = password;
}

}

 

Rodando a aplicação

Essa é uma aplicação Spring Boot, onde o framework baixará e utilizará os recursos necessários, conforme a configuração (definida na Criação da Aplicação). Neste caso, será utilizado Tomcat e banco de dados H2 (ambos embedded)

Procedimento

  1. Abra a classe SpringRestDataH2Application.java
  2. Clique no menu Run / Run as / Java Aplication
  3. Espere até que apareça “Tomcat started on port(s): 8080 (http)”
  4. Abra um navegador e forneça a url de listagem (http://localhost:8080/user/list)
  5. Deverá aparecer apenas 2 colchetes ([]), pois o List está vazio

 

Postman

Para facilitar as chamadas de POST (/user/create), PUT (/user/update) e DELETE (/user/delete), vou utilizar o Postman.

Método POST

Método PUT

Método DELETE

Código-Fonte (github)

https://github.com/lfchaim/spring-rest-data-h2

 

Criando projeto JAX-RS

Introdução

O objetivo deste post é demonstrar como criar um projeto RESTful, usando Eclipse e Jersey.

Procedimento

Instalando archetype-catalog do Jersey

  1. Abra o Eclipse
  2. Vá em Window / Preferences
  3. Abra o item Maven
  4. Selecione Archetype
  5. Clique em Add Remote Catalog…
  6. Em Catalog File: http://repo1.maven.org/maven2/archetype-catalog.xml
  7. Em Description: Maven Catalog
  8. Clique em OK

Criando o projeto

  1. Vá em File / New / Other…
  2. Digite: Maven
  3. Selecione: Maven Project
  4. Clique em Next
  5. Digite em Filter: jersey-quickstart
  6. Selecione: jersey-quickstart-webapp (versão 2.26)
  7. Clique em Next
  8. Digite Group Id: br.com.whs.jaxrsdemo
  9. Artifact Id: jax-rs-demo
  10. Version: 1.0.0
  11. Package: br.com.whs.jaxrsdemo
  12. Clique em Finish

Instalando Tomcat

  1. Acesse a página: https://tomcat.apache.org/download-80.cgi
  2. Baixe a versão 8.5.24
  3. Descompacte no local desejado
  4. No Eclipse, clique na aba: Servers
  5. Clique no link: Click this link to create a new server…
  6. Selecione: Apache
  7. Selecione: Tomcat v8.5 Server
  8. Clique em Next
  9. Localize o caminho raiz da instalação
  10. Clique em Next
  11. Adicione o projeto recém criado
  12. Clique em Finish

Testando Aplicação

  1. Clique no servidor criado (aba Servers)
  2. Clique no botão Start (mesma janela de Servers)
  3. Abra um navegador e digite: http://localhost:8080/jax-rs-demo/
  4. Clique no link Jersey resource

Código-fonte do projeto

Você pode baixar os fontes desse projeto no github.

Instalando NodeJs usando NVM no Ubuntu

Introdução

Neste post, vamos instalar o NodeJs, através da ferramenta NVM (Node Version Manager).

NVM

Excelente ferramenta de administração de versões do NodeJs. Procure utilizar essa ferramenta, pois torna o trabalho bem mais fácil.

Instalação do NVM

  1. Abra um Terminal
  2. Curl
    1. curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.6/install.sh | bash
  3. Wget
    1. wget -qO- https://raw.githubusercontent.com/creationix/nvm/v0.23.2/install.sh | bash
  4. Digite
    1. nvm
    2. Deve aparecer o help do comando (já está instalado)

Instalação do NodeJs

Agora sim, vai ser complicado.

  1. No Terminal, digite
    1. nvm install 8.9.1
    2. 8.9.1 foi a versão estável selecionada no momento desse post
  2. Basta digitar
    1. node -v (aparecerá v8.9.1)
    2. npm -v (aparecerá 5.5.1)

Mamão com açucar! Está pronto!

 

MongoDB – Primeiros Comandos – Linux

Introdução

Este post tem o objetivo de iniciar a utilização do MongoDB, usando comandos.

Pré-requisitos

Para começarmos, é necessário ter executado o procedimento do post Instalar MongoDB no Ubuntu.

Console do MongoDB

Para abrir o console do MongoDB, utilize o comando

$ mongo

Listando bancos

> show dbs

admin 0.000GB
escola 0.000GB
local 0.000GB

Criando ou entrando no banco

Para entrar ou criar um banco, utilize o comando “use”. Se o banco não existir, será criado automaticamente.

> use escola

switched to db escola

Criando tabela e inserindo dado

Podemos criar uma tabela e inserir o dado ao mesmo tempo. Para isso, utilizamos o comando db.[[TABELA]].insert.

> db.aluno.insert({‘nome’:’Luis Fernando Chaim’,’dataNasc’:new Date(‘1972-05-22’)})

WriteResult({ “nInserted” : 1 })

Listando tabelas

> show collections

aluno

Pesquisando dado

Para pesquisar os dados de uma tabela, utilizar db.[[TABELA]].find().

> db.aluno.find()

{ “_id” : ObjectId(“5a02e14ef52458010bddaf80”), “nome” : “Luis Fernando Chaim”, “dataNasc” : ISODate(“1972-05-22T00:00:00Z”) }

> db.aluno.find({nome: ‘Luis Fernando Chaim’})

Exemplos

db.professores.insert({nome: ‘Jean’, idade:26, disciplinas:[‘Tecnicas de Programacao’, ‘Topicos Avancados’], sexo: ‘m’})

db.professores.insert({nome: ‘John’, idade:46, disciplinas:[‘Tecnicas de Programacao’, ‘Topicos Avancados’], sexo: ‘m’})

db.professores.insert({nome: ‘Joseph’, idade:53, disciplinas:[‘Tecnicas de Programacao’, ‘Topicos Avancados’], sexo: ‘m’})

db.professores.find()
Então nosso comando find() nos retornará a lista de todos os registros. Se eu quiser passar alguma cláusula para a busca, posso fazer da seguinte forma:

db.professores.find({nome: ‘Jean’})
//db.professores.find({nome: ‘Jean’, idade:26})
Lembrando que se nossa consulta for falsa, ele não escreverá nenhum resultado, como podemos ver na tela abaixo:

Para fazermos comparações entre valores, usaremos uma sintaxe um pouco diferente. Vamos ter como exemplo a busca por professores com idade acima de 30 anos.

db.professores.find({idade: {$gt:30}})
Como podemos notar com o exemplo, utilizamos um operador condicional o $gt que significa great than, ou maior que, em português.

Também podemos usar os seguintes operadores condicionais: $gte, $lt, $lte, $all, $in, $nin, $ne, $exists, $mod

Ou seja podemos ver que na função find() podemos passar 1 paramêtro que vai fazer a comparacao de valores para delimitar a busca. Tendo em vista que se utilizarmos operadores de comparação como >, >=, <, <= e outros, teremos que usar a seguinte regra:

db.collection.find({campo: {$operador: valor}})

Podemos passar um paramêtro para a comparação de valores, mas também posso passar outro parâmetro, informando quais campos eu quero que retornem na busca; neste caso, nosso exemplo ficará:

db.collection.find({campo: {$operador: valor}}, {campo1: 1, campo2: 1, campoN: 1})
Como visto no exemplo acima ele sempre retorna o _id de cada registro, para que isto não ocorra podemos repassar no paramêtro dos campos _id:0

Porém, caso eu não queira comparar nenhum valor, terei que passar null no primeiro paramêtro, podendo ficar da seguinte maneira:

db.collection.find(null, {campo1: 1, campo2: 1, campoN: 1})

Uma outra função bem útil é a ordenação da busca, que se assemelha ao ORDER BY do SQL. No MongoDB temos a função sort() que recebe um paramêtro para ordernar.

db.collection.find(null, {nome:1, idade:1, _id:0}).sort({idade:1})
Onde passaremos o 1 paras ASC ou seja, do menor para o maior, ou -1 que é o DESC, do maior para menor.

Além de ordenar, também podemos limitar a busca, parecido com o LIMIT do SQL, passando um valor inteiro para a função limit().

db.collection.find(null, {nome:1}).sort({idade:1, nome:-1}).limit(2)

Outra função que auxilia ao limit() é a skip(), que receberá um valor inteiro para pular até aquele registro. Até agora, nossas funções convertidas em SQL ficam assim:

select nome, idade from professores ORDER BY idade ASC LIMIT1,2
Bom, já aprendemos como inserir dados e listá-los esta na hora de modificarmos os registros. Para isto, utilizamos a função update({busca}, {atualizacao}).

Assim como temos o modificador $set, também temos o $unset, que elimina a chave.

db.professores.update({nome: ‘Jean’}, {$unset: {disicplinas: 1}})
Também podemos apenas incrementar ou decrementar um valor inteiro utilizando o modificador $inc

db.professores.update({nome: ‘Jean’}, {$inc: {idade: 5}})
//incrementa em 5 a idade do professor Jean
db.professores.update({nome: ‘Jean’}, {$inc: {idade: -5}})
//incrementa em 5 a idade do professor Jean

Agora para removermos documentos, utilizamos a função remove(json). Onde passamos como parâmetro a clausula de comparação.

Porém, caso queiramos limpar toda a collection, é mais rapido usando drop()