FRAMEWORK DE REPLICAÇÃO DE DADOS COM CRIPTOGRAFIA SIMÉTRICA UTILIZANDO PUSH NOTIFICATION PARA ANDROID - PDF
FRAMEWORK DE REPLICAÇÃO DE DADOS COM CRIPTOGRAFIA SIMÉTRICA UTILIZANDO PUSH NOTIFICATION PARA ANDROID
Download "FRAMEWORK DE REPLICAÇÃO DE DADOS COM CRIPTOGRAFIA SIMÉTRICA UTILIZANDO PUSH NOTIFICATION PARA ANDROID"
Margarida Camilo Carreira
1 UNIVERSIDADE REGIONAL DE BLUMENAU CENTRO DE CIÊNCIAS EXATAS E NATURAIS CURSO DE CIÊNCIA DA COMPUTAÇÃO BACHARELADO FRAMEWORK DE REPLICAÇÃO DE DADOS COM CRIPTOGRAFIA SIMÉTRICA UTILIZANDO PUSH NOTIFICATION PARA ANDROID FERNANDO KLOCK BLUMENAU /2-09
2 FERNANDO KLOCK FRAMEWORK DE REPLICAÇÃO DE DADOS COM CRIPTOGRAFIA SIMÉTRICA UTILIZANDO PUSH NOTIFICATION PARA ANDROID Trabalho de Conclusão de Curso submetido à Universidade Regional de Blumenau para a obtenção dos créditos na disciplina Trabalho de Conclusão de Curso II do curso de Ciência da Computação Bacharelado. Prof. Dalton Solano dos Reis, M.Sc. - Orientador BLUMENAU /2-09
3 FRAMEWORK DE REPLICAÇÃO DE DADOS COM CRIPTOGRAFIA SIMÉTRICA UTILIZANDO PUSH NOTIFICATION PARA ANDROID Por FERNANDO KLOCK Trabalho aprovado para obtenção dos créditos na disciplina de Trabalho de Conclusão de Curso II, pela banca examinadora formada por: Presidente: Membro: Membro: Prof. Dalton Solano dos Reis, Mestre Orientador, FURB Prof. Aurélio Faustino Hoppe, Mestre FURB Prof. Paulo Cesar Rodacki Gomes, Doutor FURB Blumenau, 12 de dezembro de 2011
4 Dedico este trabalho a todos os amigos e familiares, especialmente aqueles que me ajudaram diretamente na realização deste.
5 AGRADECIMENTOS A Deus, pelo seu imenso amor e graça. À minha família, que sempre esteve presente. Ao meu orientador, Dalton Solano dos Reis, por ter acreditado na conclusão deste trabalho.
6 Falar obscuramente qualquer um sabe; com clareza, raríssimos. Galileu Galilei
7 RESUMO Este trabalho apresenta um framework para replicação de dados com a utilização de criptografia simétrica e o conceito de push notification para dispositivos móveis da plataforma Android. Com a utilização do framework na criação de aplicações móveis o desenvolvedor tem a possibilidade de replicar os dados do banco SQLite entre um dispositivo Android e um servidor remoto. O sentido de replicação e a chave da criptografia simétrica poderão ser configurados de acordo com a necessidade da aplicação. A utilização do push notification de dados está disponível no framework desenvolvido para o servidor, tendo como objetivo inicial alertar o dispositivo móvel para eventuais atualizações. Com a utilização desta tecnologia o dispositivo não necessita requisitar o servidor diversas vezes procurando atualizações, sendo que para isto seriam gastos muito processamento e bateria do aparelho. Palavras-chave: Android. Criptografia. Push. Replicação.
8 ABSTRACT This paper presents a framework for data replication with the use of symmetric cryptography and the concept of push notification mobile platform Android. Using the framework in creating mobile applications developer has the ability to replicate data between a database SQLite Android device and a remote server. The direction of replication and the symmetric encryption key can be configured according to application needs. The use of the push notification data is available on the framework developed for the server, with the initial aim to alert the mobile device to any updates. Using this technology, the device does not need to order the server several times looking for updates, and it would cost to much processing and battery of the device. Key-word: Android. Cryptography. Push. Replication.
9 LISTA DE ILUSTRAÇÕES Figura 1 Push no Android...20 Figura 2 Camadas da plataforma Android...21 Figura 3 Funcionamento do DBMoto...22 Quadro 1 Comparação entre os trabalhos correlatos...24 Figura 4 - Diagrama de casos de uso...26 Figura 5 - Diagrama de pacotes do dispositivo...32 Figura 6 - Diagrama de classe do pacote com.google.android.c2dm...33 Figura 7 - Diagrama de classe do pacote br.com.fernandoklock.replication...34 Figura 8 - Diagrama de classe do pacote br.com.fernandoklock.crypto...35 Figura 9 - Diagrama de classe do pacote br.com.fernandoklock.database...36 Figura 10 - Diagrama de pacotes do servidor...37 Figura 11 - Diagrama de classe do pacote br.com.fernandoklock.database...38 Figura 12 - Diagrama de classe do pacote br.com.fernandoklock.replication..39 Figura 13 - Diagrama de atividades de notificações...40 Figura 14 - Diagrama de seqüência da replicação de dados...41 Quadro 10 Fragmento do manifesto para indicar a classe receptora de notificação...43 Quadro 11 Fragmento do manifesto de permissão da aplicação para notificação...43 Quadro 12 Fragmento de código para disparo de registro de notificação...44 Quadro 13 - Recebimento de notificação na classe C2DMBroadcastReceiver...44 Quadro 14 - Tratamento das mensagens recebidas na classe C2DMBaseReceiver...45 Quadro 15 Geração de notificação Android...45 Quadro 16 Requisitando token de autenticação no servidor C2DM Quadro 17 Envio de notificação push para dispositivo...47 Quadro 18 - Utilização da criptografia simétrica AES...48 Quadro 19 - Trecho de código da implementação socket do servidor...49 Quadro 20 Trecho de código da implementação socket no dispositivo...50 Quadro 21 - Análise para execução do comando update...52 Figura 15 - Localização das bases de dados SQLite no projeto...53 Quadro 22 - Classe AtualizaDB que estende a classe abstrata DBManipulate...54 Quadro 23 - Instância das classes de parametrização do framework...55
10 Figura 16 - Tela do menu da aplicação...56 Figura 17 - Log de erros da Replicação...56 Figura 18 - Telas da aplicação teste do framework...57 Figura 19 - Registrar presença para um aluno...57 Figura 20 - Tela preferências para replicação de dados...58 Quadro 24 - Registro de presença do aluno no servidor...59 Figura 21 - Recebimento da notificação no dispositivo...59 Figura 22 - Desempenho da replicação de dados...61 Figura 23 - Desempenho da criptografia simétrica...63 LISTA DE TABELAS Tabela 1 Desempenho da transmissão de dados no dispositivo...60 Tabela 2 Desempenho da criptografia simétrica...62
11 LISTA DE SIGLAS ADT - Android Development Tools API - Application Programming Interface ASCII - American Standard Code for Information Interchange C2DM - Cloud to Device Message CPU - Central Processing Unit HTTP - Hyper Text Transfer Protocol I/O - Input/Output Java SE - Java Standard Edition JDBC - Java Data Base Connectivity JSON - JavaScript Object Notation KB - Kilobytes OHA - Open Handset Alliance ORB - Object Request Broker PDA - Personal Digital Assistants REST - REpresentational State Transfer RPC - Remote Procedure Call SDK - Software Developer Kit SGBD - Sistema de Gerenciamento de Banco de Dados SGBDH - Sistema de Gerenciamento de Banco de Dados Heterogêneos SOA - Service Oriented Architecture SOAP - Simple Object Access Protocol SQL - Structured Query Language TCP/IP - Transmission Controle Protocol / Internet Protocol
12 UDP - User Datagram Protocol UML - Unified Modeling Language URL - Universal Resource Locator UTF-8 - Unicode Transformation Format 8-bit XML - extensible Markup Language
13 SUMÁRIO 1 INTRODUÇÃO OBJETIVOS DO TRABALHO ESTRUTURA DO TRABALHO FUNDAMENTAÇÃO TEÓRICA CRIPTOGRAFIA SIMÉTRICA SQLITE SOCKET PUSH NOTIFICATION PLATAFORMA ANDROID TRABALHOS CORRELATOS DBMoto Heros Tabela comparativa entre os trabalhos correlatos DESENVOLVIMENTO DO FRAMEWORK REQUISITOS PRINCIPAIS DO PROBLEMA A SER TRABALHADO ESPECIFICAÇÃO Casos de Uso Visualizar notificações Configurar parâmetros de conexão Configurar parâmetros de replicação Consumir e processar transações Enviar e finalizar transações Retornar erros SQL Iniciar servidor de replicação Notificar dispositivo Diagrama de classe Diagrama de classes do dispositivo Pacote com.google.android.c2dm Pacote br.com.fernandoklock.replication Pacote br.com.fernandoklock.crypto Pacote br.com.fernandoklock.database...36
14 Diagrama de classes do servidor Pacote br.com.fernandoklock.database Pacote br.com.fernandoklock.replication Diagrama de atividades Diagrama de seqüência IMPLEMENTAÇÃO Técnicas e ferramentas utilizadas Preparando ambiente Android para push Envio de notificações para o dispositivo Android pelo servidor Criptografia simétrica AES Utilização do socket para transferência de dados Gerenciamento da replicação de dados Operacionalidade da implementação RESULTADOS E DISCUSSÃO CONCLUSÕES EXTENSÕES...65 REFERÊNCIAS BIBLIOGRÁFICAS...66
15 14 1 INTRODUÇÃO Os dispositivos móveis estão entrando no cotidiano da sociedade apresentando várias facilidades que, até então, eram disponíveis apenas para computadores desktop, como transferências interbancárias e compra de produtos. O aumento no uso destes dispositivos, principalmente smartphones, trouxe algumas preocupações com relação à segurança dos dados manipulados. Ataques de cibercriminosos vêm crescendo devido a grande adesão de dispositivos móveis em ambientes coorporativos, combinada à infra-estrutura frágil dos telefones celulares e ao lento avanço em relação à segurança (INFOMONEY, 2011). Sendo assim, como garantir a segurança dos dados manipulados nos dispositivos móveis? Uma solução para garantir a segurança nestes casos é o uso da criptografia. A criptografia pode ser aplicada nos vários níveis de interação do sistema. Um deles é o nível de replicação de dados, onde as informações são transferidas entre o cliente e o servidor como cópia de dados. Esta cópia é acionada por uma transação executada em um Sistema de Gerenciamento de Banco de Dados (SGBD) source, replicando para um ou mais targets, de forma que a informação seja consistente em todas as bases (HOPKINS; THOMAS, 1998). As vantagens de assegurar a segurança neste nível são: sigilo, integridade e autenticação. Diante do exposto, disponibilizou-se um framework para a plataforma de desenvolvimento Android Software Developer Kit (SDK), que agrega características necessárias para garantir a segurança da informação e que possibilita ao desenvolvedor abstração na replicação de dados entre o dispositivo e o servidor. A replicação utiliza como repositório de dados o SQLite, uma biblioteca que disponibiliza a modelagem de dados através do padrão Structured Query Language (SQL). O diferencial da aplicação é a utilização do push 1, servindo como mensageiro para alertar novas atualizações nas bases de dados. Após o recebimento da notificação via push notification, o dispositivo móvel e o servidor irão estabelecer uma comunicação utilizando a arquitetura de comunicação socket. Os dados transferidos utilizam a criptografia simétrica, tornando a comunicação cliente/servidor segura. 1 Push é um serviço onde os servidores notificam as aplicações móveis, a fim de atualizar a ferramenta ou dados do usuário (CODE, 2011a).
16 OBJETIVOS DO TRABALHO O objetivo deste trabalho é desenvolver um framework de replicação de dados com criptografia simétrica utilizando push notification para o Android. Os objetivos específicos do trabalho são: a) disponibilizar a replicação de dados entre o dispositivo móvel e o servidor utilizando a biblioteca SQLite; b) aplicar criptografia simétrica com a utilização de chaves de 128 bits; c) definir a interface de comunicação entre o dispositivo e o servidor; d) validar o framework criando um aplicativo exemplo que utilize a replicação de dados. 1.2 ESTRUTURA DO TRABALHO A estrutura deste trabalho está apresentada em quatro capítulos, onde o segundo capítulo contém a fundamentação teórica necessária para o entendimento deste trabalho. O terceiro capítulo apresenta como foi desenvolvida a ferramenta para as plataformas Android e Java Stardard Edition (Java SE), os casos de uso da aplicação, diagramas de classe e a especificação que define a ferramenta. No terceiro capítulo são apresentadas também, as partes principais da implementação juntamente com resultados e discussões que aconteceram durante o desenvolvimento do projeto. Por fim, o quarto capítulo refere-se às conclusões do presente trabalho e sugestões para trabalhos futuros.
17 16 2 FUNDAMENTAÇÃO TEÓRICA Este capítulo está organizado em 7 seções: a primeira trata da criptografia simétrica, a segunda descreve o funcionamento da biblioteca SQLite, a terceira apresenta o REST, a quarta o socket, a quinta mostra o funcionamento do push notification, a sexta a plataforma Android e a última traz os trabalhos correlatos ao trabalho proposto. 2.1 CRIPTOGRAFIA SIMÉTRICA O termo criptografia surgiu da fusão das palavras gregas kryptós e gráphein, que significam oculto e escrever, respectivamente. Trata-se de um conjunto de conceitos e técnicas que visam codificar uma informação de forma que somente o emissor e o receptor possam acessá-la, evitando que um intruso consiga interpretála. (ALECRIM, 2005). Cifragem é o processo pelo qual a criptografia torna dados incompreensíveis, isso é, codificados ou secretos, normalmente chamados de texto cifrado. Já o processo inverso é a decifragem, em que dados são decodificados para possibilitar sua leitura e normalmente chamados de texto claro (CARVALHO, 2001, p. 52). Para a cifragem e decifragem de uma informação é necessário o uso de chaves. As chaves são um conjunto de bits baseado em um determinado algoritmo capaz de criptografar um conjunto de informações. Se o receptor da mensagem usar uma chave incompatível com a chave do emissor, não conseguirá extrair a informação (ALECRIM, 2005). Existem tamanhos diferentes de chaves a serem utilizadas na criptografia, como por exemplo, 8 bits e 128 bits. Quanto mais bits forem utilizados, mais segura será a criptografia. Caso um algoritmo utilize chaves de 8 bits, apenas 256 chaves poderão ser usadas na decodificação. Porém, se for usado 128 bits existirá uma grande quantidade de combinações deixando a informação criptografada mais segura (ALECRIM, 2005). Há maneiras diferentes de cifrar uma informação sendo uma delas a criptografia de chave simétrica. Este estilo de criptografia realiza a cifragem e a decifragem de uma informação por meio de algoritmos que utilizam a mesma chave, garantindo sigilo na transmissão de dados (ALECRIM, 2005). Os algoritmos atuais são especializados para serem executados por computadores ou por alguns dispositivos de hardware. Na maioria das
18 17 aplicações, a criptografia é realizada através de software de computador. De modo geral os algoritmos simétricos são executados muito mais rapidamente que os assimétricos, pois no assimétrico o emissor deve criar uma chave de codificação e envia-la ao receptor (NUNES, 2007). Existem vários algoritmos de criptografia simétrica disponibilizados comercialmente, dentre eles citam-se o Data Encryption Standard (DES) e o Advanced Encryption Standard (AES). O DES é um tipo de cifra de bloco de 64 bits, ou seja, um algoritmo que torna uma string de tamanho fixo de um texto plano e a transforma, através de uma série de complicadas operações, em um texto cifrado do mesmo tamanho. Já o AES, predecessor do DES, é o algoritmo padrão adotado pelo governo dos Estados Unidos e tem as seguintes características: cifra em blocos de 128 bits usando chaves de criptografia com 128, 192 e 256 bits, é implementado tanto em hardware como em software e apresenta um algoritmo de variação recursiva do DES (TECNOLOGIADAREDE, 2010). 2.2 SQLITE O SQLite é uma biblioteca que implementa uma engine de banco de dados SQL. Diferentemente da maioria dos outros bancos de dados, o SQLite não tem um processo de servidor separado, pois a leitura e escrita dos dados são feitas diretamente em arquivos comuns. Toda a estrutura de SQL da biblioteca, como as tabelas, índices, triggers e views estão contidos em um único arquivo no disco. O formato do arquivo de banco de dados é multi-plataforma, ou seja, pode ser utilizado em sistemas 32 bits e 64 bits, bem como para as plataformas Android e ios (SQLITE, 2009). A biblioteca apresenta algumas características relevantes quanto à utilização de hardware nos dispositivos. Com todos os recursos habilitados, seu tamanho pode ser inferior a 300 kilobytes (KB), dependendo das configurações de otimização do compilador. Se os recursos opcionais são omitidos, o tamanho pode ser reduzido a menos de 180 KB. Além disso, a biblioteca pode ser utilizada em um espaço mínimo de stack (4 KB) e de heap (100 KB). Estas características tornam SQLite uma ótima escolha para dispositivos de memória limitada, como celulares e Personal Digital Assistant (PDA) (SQLITE, 2009). A base do código SQLite é mantida por uma equipe internacional de desenvolvedores que trabalham em tempo integral. Os desenvolvedores continuam expandindo as capacidades
19 18 da biblioteca, além de aumentar sua confiabilidade e desempenho, mantendo a compatibilidade. A cada lançamento o produto é cuidadosamente testado com relação a erros de Input/Output (I/O), falhas nos sistemas ou falhas de energia, diminuindo possíveis erros durante a execução (SQLITE, 2009). 2.3 SOCKET Segundo Macoratti (2004), socket pode ser entendido como uma porta de um canal de comunicação que permite a um processo executando em um computador enviar ou receber mensagens para ou de outro processo que pode estar sendo executado no mesmo computador ou em um computador remoto. Para que exista comunicação em rede, faz-se necessário o uso de um protocolo de comunicação. Um protocolo funciona como linguagem entre computadores em rede e para validar esta comunicação, é preciso que os computadores utilizem o mesmo protocolo. Existem diversos tipos de protocolos. As aplicações de socket são feitas baseadas no Transmission Control Protocol / Internet Protocol (TCP/IP) ou User Datagram Protocol (UDP) (MACORATTI, 2004). O socket representa um ponto de conexão para uma rede TCP/IP, muito semelhante aos soquetes elétricos encontrados em casas, que fornecem um ponto de conexão para os aparelhos eletrodomésticos. Quando dois computadores querem manter uma conversação, cada um deles utiliza um socket. Um computador é chamado servidor, pois ele abre um socket e presta atenção nas conexões, e outro computador denomina-se cliente, chamando o socket servidor para iniciar a conexão (FRACO; SILVA, 2009). Segundo Franco e Silva (2009), existem dois tipos de troca de mensagens via socket: a orientada a conexão e a não orientada a conexão. Na comunicação orientada a conexão, TCP ou Datastream, uma aplicação servidora disponibiliza um canal ao qual aplicações clientes se conectarão para trocarem dados. Uma aplicação servidora pode ter conexões com vários clientes. Já na comunicação não orientada a conexão, UDP ou Datagram, não é estabelecida uma conexão entre a aplicação cliente e a servidora. A aplicação servidora estabelece uma porta que estará disponível para que qualquer cliente possa enviar dados. A comunicação é unidirecional e não há garantias de que os dados realmente chegarão.
20 PUSH NOTIFICATION A maioria dos aplicativos desenvolvidos para a plataforma Android utiliza a internet para manter o dispositivo atualizado. Tradicionalmente, os aplicativos utilizam polling para recuperar as informações, como um cliente de que acessa o servidor em intervalos de tempo. O problema é que o polling gera um desgaste desnecessário dos recursos, pois utiliza processamento para buscar algo que normalmente ainda não existe. Isso é um problema, em especial, para os dispositivos móveis, pois consome uma preciosa banda de rede e a vida útil da bateria (EMIDIO, 2010). Para as aplicações móveis que precisam utilizar os dados de um servidor remoto é mais eficiente as informações serem enviadas para o dispositivo móvel, ao invés de ficar várias vezes requisitando o servidor. A aplicação pode simplesmente aguardar o servidor informar quando ocorre uma mudança de dados (LANE, 2009). Na versão 2.2 do Android a Google disponibilizou Cloud to Device Message (C2DM), cujo objetivo é facilitar o envio de dados dos servidores às aplicações em dispositivos Android. O serviço fornece um mecanismo simples e leve onde os servidores notificam as aplicações móveis, a fim de atualizar a ferramenta ou dados do usuário. O serviço C2DM controla todos os aspectos de enfileiramento e entrega de mensagens para o aplicativo em execução no dispositivo de destino (CODE, 2011a). Existem algumas limitações do C2DM documentas pela Google que devem ser abordadas. A mensagem enviada do servidor para o dispositivo móvel pode conter apenas bytes e o servidor remetente é limitado para o envio de mensagens, sejam elas globais ou para um dispositivo em específico. Já o número máximo de mensagens que podem ser enviadas não foi mencionado pela Google (CODE, 2011b). A Figura 1 apresenta o funcionamento do C2DM.
21 20 etapas: Fonte: AMU Team (2010). Figura 1 Push no Android Conforme AMU Team (2010), o ciclo de vida do C2DM pode ser divido em duas a) habilitando C2DM: a APPlication (APP) do dispositivo registra-se com o Google, obtendo um IDentificador (ID). Após isso, a aplicação envia o ID de registro para o APPlication Server (APP SERVER); b) enviando mensagem: o APP SERVER envia uma mensagem ao servidor Cloud to Device Message Front End (C2D MSG FRONTEND). O servidor C2D MSG FRONTEND armazena a mensagem caso o dispositivo móvel esteja inativo, senão a mensagem é enviada ao dispositivo. A APP do dispositivo processa a mensagem recebida através do CONNection Server (CONN SERVER). 2.5 PLATAFORMA ANDROID Segundo Faria (2008), Android é uma plataforma de código aberto para dispositivos móveis criado pela Google em parceria com a Open Handset Alliance (OHA). O kit de desenvolvimento provê ferramentas e chamadas via Application Programming Interface (API) para o desenvolvimento de aplicativos baseados na linguagem Java. Os principais recursos dessa plataforma móvel são a máquina virtual otimizada, o navegador integrado e a biblioteca SQLite.
22 21 A Figura 2 apresenta as camadas da plataforma Android. Fonte: Faria (2008). Figura 2 Camadas da plataforma Android Conforme Faria (2008), a arquitetura é dividida em cinco camadas, as quais são: a) Linux kernel: responsável pelos serviços e segurança, além dos gerenciamentos de memória, processos, rede e drivers; b) libraries: carrega um conjunto de bibliotecas C/C++ utilizadas pelo sistema. Estão incluídas neste conjunto a biblioteca C padrão (Libc), além de funções para navegadores web, de aceleração de hardware, renderização 3D e funções de acesso a biblioteca SQLite; c) Android runtime: é uma instância da máquina virtual Dalvik criada para as aplicações executadas no Android. A Dalvik é uma máquina virtual com melhor desempenho e maior integração com a nova geração de hardware, otimizada para consumo mínimo de memória, bateria e Central Processing Unit (CPU); d) application framework: camada onde estão todas as APIs e recursos utilizados pelos aplicativos, como classes visuais e provedor de conteúdo, além dos gerenciamentos de recursos, notificação e pacotes; e) applications: encontram-se todos os aplicativos do Android, como cliente de e- mail, contatos, navegador web, entre outros.
23 TRABALHOS CORRELATOS Algumas ferramentas possuem comportamentos semelhantes ao trabalho proposto. Entre elas, citam-se a ferramenta DBMoto (HIT SOFTWARE, 2010) e o framework Heros (UCHÔA; MELO, 1999) DBMoto O DBMoto apresenta uma solução de replicação de dados para servidores e possíveis estações de trabalho que necessitem contingência de informações (HIT SOFTWARE, 2010). Para efetuar a replicação cada comando transacional executado no banco de dados de source é gerenciado pelo DBMoto, para que o dado possa ser transferido com êxito ao banco de dados target. Como o DBMoto opera com replicação entre banco de dados heterogêneos, a ferramenta apresenta um interpretador SQL para traduzir os comandos específicos de cada tipo de banco de dados para o padrão SQL American National Standards Instituite (ANSI) (HIT SOFTWARE, 2010). A Figura 3 ilustra o funcionamento do DBMoto, sendo que as diferentes bases de dados em ambos os lados demonstram a heterogeneidade e o microcomputador ao centro o motor de funcionamento da aplicação, cujo objetivo é interpretar os comandos SQL e comunicar-se com os SGBD. Fonte: HIT Software (2010). Figura 3 Funcionamento do DBMoto
24 23 Segundo o HIT Software (2010), a ferramenta apresenta três estados de funcionamento: a) refresh: lê os dados de um SGBD, conforme regras definidas pelo administrador da aplicação e escreve o resultado na base de dados de destino; b) mirroring: refere-se a espelhamento, executando replicação em tempo real, baseando-se nos registros de transações (logs); c) synchronization: permite manter as bases de origem e destino sincronizadas. Além dos estados de funcionamento, a aplicação inclui características como: alta confiabilidade e rápida implementação (HIT SOFTWARE, 2010) Heros O Departamento de Informática da Pontifícia Universidade Católica (PUC), Rio de Janeiro, desenvolveu um framework para Sistema Gerenciador de Bancos de Dados Heterogêneos (SGBDH), chamado Heros. O framework HEROS tem por objetivo possibilitar a instanciação de softwares (SGBDHs) que permitam que um conjunto de sistemas de bancos de dados heterogêneos, cooperativos mas autônomos, sejam integrados de tal forma em uma federação, que consultas e atualizações possam ser realizadas, de forma transparente à localização dos dados, aos caminhos de acesso e a qualquer heterogeneidade ou redundância que exista. (UCHÔA; MELO, 1999, p. 3). O Heros disponibiliza para comunicação em experiências já comprovadas, componentes que interagem com os protocolos Remote Procedure Call (RPC), Object Request Broker (ORB), JSON, socket e chamada direta. No entanto, podem ser definidos outros tipos de comunicação como o Distributed Component Model (DCOM) da Microsoft (UCHÔA; MELO, 1999, p. 5). frameworks: Segundo Uchôa e Melo (1999, p. 4), o framework Heros é composto por seis a) interface usuário: responsável pela comunicação do Heros com o usuário final. Realiza analise sintática das solicitações, detectando erros de sintaxe ou referências inválidas a objetos do esquema; b) esquema: gerencia as coleções de objetos que podem ser tabelas, índices, visões e procedimentos armazenados; c) consulta: produz o plano de execução otimizado, com base nos planos de
25 24 execuções e de dados adicionais dos SGBDH componentes do Heros; d) transação: submete consultas ou solicitações de execução dos SGBDH componentes do Heros; e) comunicação: responsável pela realização física da comunicação entre os SGBDH; f) regra: responsável por prover ao Heros o comportamento ativo, isto é, a capacidade de reagir automaticamente às ocorrências de eventos Tabela comparativa entre os trabalhos correlatos A Quadro 1 demonstra de forma resumida as principais características entre os trabalhos correlatos, tendo como base os critérios mais importantes extraídos a partir dos conceitos descritos. As informações foram dispostas em colunas, representando na vertical os trabalhos analisados e as linhas apresentam características de cada sistema, indicando semelhanças e/ou diferenças. características / trabalhos analisados DBMoto Heros heterogeneidade X X diferentes protocolos de comunicação - X replicação através de refresh X X replicação através de mirroring X - replicação através de synchronization X - Quadro 1 Comparação entre os trabalhos correlatos Podemos observar que os trabalhos correlatos estudados apresentam a heterogeneidade para replicação entre banco de dados distintos, entretanto apenas o DBMoto apresenta técnicas de replicação mais sofisticadas como o mirroring e o synchronization. Apesar dos relatos indicarem que os sistemas apresentados atingem uma alta compatibilidade com os SGDB atuais, nenhum deles apresenta a replicação de dados para as plataformas de dispositivos móveis, como Android e o IOS.
26 25 3 DESENVOLVIMENTO DO FRAMEWORK Este capítulo demonstra o desenvolvimento da ferramenta construída. São apresentados os principais requisitos, especificação, implementação, operacionalidade e os resultados obtidos. 3.1 REQUISITOS PRINCIPAIS DO PROBLEMA A SER TRABALHADO Para atender os objetivos da utilização da replicação com criptografia simétrica e o uso de push notification, os frameworks do dispositivo e do servidor foram construídos a partir dos seguintes Requisitos Funcionais (RF): a) permitir replicar a base de dados SQLite do dispositivo para o servidor e do servidor para o dispositivo (RF01); b) permitir receber notificações no dispositivo com alerta de dados a serem replicados do servidor (RF02); c) permitir o envio de notificação do servidor para o dispositivo (RF03); d) permitir represar dados no dispositivo e no servidor quando os mesmos não tiverem acesso a web (RF04); e) permitir criptografar dados para serem replicados (RF05); f) permitir descriptografar dados recebidos (RF06); g) permitir alterar o tamanho de chave para criptografia (RF07). Os frameworks atendem os seguintes Requisitos Não-Funcionais (RNF): a) o sistema será desenvolvido na linguagem Java (RNF01); b) o sistema utilizará a biblioteca SQLite (RNF02); c) o sistema deve ser compatível com o sistema operacional Android 2.2 ou posterior (RNF03).
27 ESPECIFICAÇÃO A especificação foi realizada a partir da ferramenta Enterprise Architect, utilizando a linguagem de modelagem Unified Modeling Language (UML). Para a modelagem foram utilizados casos de uso, diagramas de classe, atividade e seqüência Casos de Uso Nesta sessão são descritos os casos de uso de todos os recursos do framework. Foram identificados três atores principais. O primeiro deles, o Servidor, que disponibiliza o listener para a conexão com o dispositivo. O segundo ator, o Usuário Dispositivo, representa o utilizador do sistema, interagindo através do recebimento de notificações. O terceiro ator, o Sistema utilizador do framework, faz o uso das ferramentas disponibilizadas para possibilitar o funcionamento da replicação de dados no Android. Na Figura 4 é apresentado o diagrama de casos de uso do framework. Figura 4 - Diagrama de casos de uso
28 Visualizar notificações Este caso de uso descreve como o Usuário Dispositivo interage com o dispositivo no recebimento de notificações. Detalhes deste caso de uso estão descritos no Quadro 2. Descrição Pré-condições Cenário principal Exceção 01 Exceção 02 Pós-condições UC01 Visualizar Notificações Permite ao Usuário Dispositivo visualizar notificações no dispositivo. Aplicação com o framework deve estar instalada no dispositivo. 1. Sistema recebe notificações pela web; 2. Usuário Dispositivo clica na mensagem recebida pela notificação no menu superior do dispositivo; 3. Sistema processa a notificação recebida iniciando a replicação de dados. No passo 1 se o dispositivo apresentar erros de comunicação com a web, o mesmo não receberá a notificação. No passo 2 se o Usuário Dispositivo clicar no botão Limpar nas notificações, o sistema não faz o processamento da solicitação recebida. Notificação recebida e encaminhada para replicação de dados. Quadro 2 - Caso de uso UC Configurar parâmetros de conexão Este caso de uso descreve como são configurados os parâmetros de conexão do dispositivo com o servidor. Detalhes deste caso de uso estão descritos no Quadro 3. Descrição Pré-condições Cenário principal Exceção 01 Pós-condições UC02 Configurar Parâmetros de Conexão Permite ao Sistema utilizador do framework configurar parâmetros de conexão como nome do servidor de destino e porta de conexão. Dispositivo e Servidor devem ter acesso a web. 1. O Sistema utilizador do framework informa nome do Servidor e porta de conexão através da classe ParameterReplication; 2. Sistema armazena as configurações; 3. O Sistema utilizador do framework solicita conexão via socket ao Servidor. No passo 3 se a conexão com o Servidor falhar, o framework não irá fixar as configurações repassadas. Configurações de conexões com o Servidor estabelecidas. Quadro 3 - Caso de uso UC02
29 Configurar parâmetros de replicação Este caso de uso descreve como são configurados os parâmetros de replicação do framework. Detalhes deste caso de uso estão descritos no Quadro 4. Descrição Pré-condições Cenário principal Exceção 01 Exceção 02 Pós-condições UC03 Configurar parâmetros de replicação Permite ao Sistema utilizador do framework / Servidor configurar a criptografia e o sentido da replicação. Aplicação com o framework deve estar instalada no dispositivo. 1. O Sistema utilizador do framework / Servidor informa a chave de criptografia através da classe ParameterReplication; 2. Sistema armazena a chave informada; 3. O Sistema utilizador do framework / Servidor informa se será configurado como source ou target na comunicação. 4. Sistema configura a replicação para o modo escolhido No passo 1 se a chave de criptografia informada for diferente entre dispositivo e Servidor, o sistema não conseguira descriptograr a solicitação recebida. No passo 3 se o Sistema utilizador do framework e o Servidor forem configurados como source ou target, a replicação de dados não irá funcionar. Parâmetros de replicação configurados. Quadro 4 - Caso de uso UC Consumir e processar transações Este caso de uso descreve como as transações são consumidas e processadas durante a replicação de dados. Detalhes deste caso de uso estão descritos no Quadro 5.
30 29 Descrição Pré-condições Cenário principal Exceção 01 Exceção 02 Pós-condições UC04 Consumir e processar transações Permite ao Sistema utilizador do framework / Servidor consumir e processar transações recebidas do banco de dados source. 1. Servidor deve estar ativo; 2. Parâmetros de conexão devem estar configurados; 3. Parâmetros de replicação devem estar configurados. 1. O Sistema utilizador do framework no dispositivo solicita o envio da replicação de dados; 2. O framework do Servidor recebe a solicitação e estabelece a comunicação; 3. O Sistema utilizador do framework / Servidor configurado como source inicia a transação de replicação; 4. O Sistema utilizador do framework / Servidor configurado como target recebe a transação e aplica no banco de dados; 5. O Sistema utilizador do framework / Servidor configurado como target retorna a confirmação da replicação de dados; 6. O Sistema utilizador do framework / Servidor configurado como source encerra a replicação. No passo 4 se ocorrer erros ao aplicar a transação na base target, o framework irá retornar os registros com problemas para a base source. No passo 5 se o framework não receber resposta do sucesso da replicação, a transação continuará pendente. Recebimento da replicação de dados efetuado. Quadro 5 - Caso de uso UC Enviar e finalizar transações Este caso de uso descreve como são enviadas e finalizadas as transações da base de dados source para target. Detalhes deste caso de uso estão descritos no Quadro 6.
31 30 Descrição Pré-condições Cenário principal Exceção 01 Exceção 02 Pós-condições UC05 Enviar e finalizar transações Permite ao Sistema utilizador do framework / Servidor enviar e finalizar transações. 1. Servidor deve estar ativo; 2. Parâmetros de conexão devem estar configurados; 3. Parâmetros de replicação devem estar configurados. 1. O Sistema utilizador do framework / Servidor executa transação SQL (insert, update e delete); 2. O framework adiciona as transações no banco de dados after-image; 3. O Sistema utilizador do framework / Servidor solicita o inicio da replicação de dados através do método startreplication(); 4. O framework do dispositivo se conecta no servidor e executa a replicação; 5. O Sistema utilizador do framework / Servidor recebe a confirmação da replicação No passo 2 se ocorrer algum erro de sintaxe no comando SQL, o framework não irá inserir as transações no after-image. No passo 5 se o framework não receber resposta do sucesso da replicação, a transação continuará pendente. Envio da replicação de dados efetuado. Quadro 6 - Caso de uso UC Retornar erros SQL Este caso de uso descreve como são retornados os erros SQL ocorridos na replicação de dados. Detalhes deste caso de uso estão descritos no Quadro 7. Descrição Pré-condições Cenário principal Pós-condições UC06 Retornar erros SQL Permite ao Sistema utilizador do framework / Servidor que sejam retornados os erros SQL da replicação. 1. Servidor deve estar ativo; 2. Parâmetros de conexão devem estar configurados; 3. Parâmetros de replicação devem estar configurados; 4. Transações consumidas e processadas. 1. O Sistema utilizador do framework / Servidor solicita os registros que apresentaram erros através do método getreplicationerror(); 2. O framework retorna os registros que apresentaram erros na replicação; 3. O Sistema utilizador do framework / Servidor trata os erros conforme suas regras de negócio. Retorna os erros obtidos durante o sincronismo dos bancos. Quadro 7 - Caso de uso UC06
32 Iniciar servidor de replicação Este caso de uso descreve como é iniciado o servidor de replicação. Detalhes deste caso de uso estão descritos no Quadro 8. Descrição Pré-condições Cenário principal Pós-condições UC07 Iniciar servidor de replicação Permite ao Servidor que o listener de replicação de dados seja iniciado. Parâmetros de replicação devem estar configurados; 1. O Servidor faz a leitura dos parâmetros de replicação; 2. O Servidor solicita a ativação do listener através do método startlistenerreplication() ; 3. O framework inicia os serviços para replicação de dados. Iniciado o servidor de replicação. Quadro 8 - Caso de uso UC Notificar dispositivo Este caso de uso descreve como o Servidor notifica os dispositivos. Detalhes deste caso de uso estão descritos no Quadro 9. Descrição Pré-condições Cenário principal Exceção 01 Pós-condições UC08 Notificar dispositivo Permite ao Servidor que sejam notificados os dispositivos. 1. Servidor deve estar ativo; 2. Parâmetros de conexão devem estar configurados; 3. Parâmetros de replicação devem estar configurados. 1. O Servidor solicita o envio de notificações; 2. O framework envia a notificação através do método sendmessage(); 3. O Servidor recebe a confirmação do envio. No passo 3 caso ocorra algum erro de comunicação com o servidor da Google no envio da notificações, o framework não irá enviar as notificações. Envia notificações para os dispositivos. Quadro 9 - Caso de uso UC Diagrama de classe A seguir serão mostrados os diagramas de classe, primeiramente uma abordagem na
33 32 diagramação do framework no dispositivo, em seguida o servidor Diagrama de classes do dispositivo Neste item serão descritos os pacotes componentes do framework desenvolvido para o dispositivo. Na Figura 5 é possível visualizar os pacotes que compõem a aplicação. Figura 5 - Diagrama de pacotes do dispositivo Pacote com.google.android.c2dm Este pacote é responsável por prover os recursos necessários para o funcionamento do push. A Figura 6 mostra com mais detalhes o pacote com.google.android.c2dm.
34 33 Figura 6 - Diagrama de classe do pacote com.google.android.c2dm A classe C2DMessaging é responsável pelo registro da aplicação no servidor Google onde deixa a aplicação elegível a receber notificações externas. Esta solicitação é gerada através do método register(), obtendo uma identificação. Para a remoção deste registro no servidor, o utilizador do framework deverá invocar o método unregister(). A classe C2DMBroadcastReceiver recebe as mensagens C2DM no método onreceive(), e repassa a solicitação para o método runintentservice() da classe C2DMBaseReceiver. Já a classe C2DMBaseReceiver é uma classe abstrata responsável por manipular o corpo das mensagens recebidas via push, verificando se é uma mensagem de registro, uma mensagem de remoção de registro ou uma mensagem de notificação. Para o recebimento de uma mensagem de registro a classe solicita o método onregistered() e para remoção de registro o onunregistered(), sendo que os mesmos irão executar na classe que herda a C2DMBaseReceiver. Caso a mensagem recebida seja apenas de notificação, a classe repassa para o método onmessage() Pacote br.com.fernandoklock.replication Pacote responsável por sincronizar as bases de dados source e target. As classes componentes deste pacote fazem a conexão entre o framework do dispositivo e do servidor, a replicação de dados entre as bases e parametrização dos serviços utilizados para a replicação. A Figura 7 mostra com mais detalhes o pacote br.com.fernandoklock.replication.
35 34 Figura 7 - Diagrama de classe do pacote br.com.fernandoklock.replication A classe ManagerReplication faz o controle da replicação de dados e aplica os dados repassados entre o servidor e o dispositivo. Além disso, esta classe armazena todas as transações efetuadas no banco SQLite do dispositivo através do método addregistryreplication(), para que os dados possam ser represados quando o dispositivo não está conectado na web. A classe ParameterReplication é responsável por armazenar as configurações de replicação informadas pelo utilizador do framework. Já a classe SocketClient faz a conexão
36 35 do dispositivo com o servidor para que a replicação de dados seja efetuada. Todos os dados replicados através do socket são recebidos da classe ManagerReplication. A classe C2DMReceiver é responsável por manipular as mensagens recebidas pelo servidor da Google. Quando o registro é feito no servidor Google é reservado uma espécie de ticket que é enviado para o dispositivo confirmando o registro. Nesse momento a classe C2DMReceiver intercepta o registro através do método onregistered() e envia o ticket recebido para o servidor, que o mantém para futuras notificações. Além do método onregistered(), a classe herda os métodos onmessage(), onerror() e onunregistered() da classe C2DMBaseReceiver. No recebimento da mensagem pelo método onmessage() são geradas as notificações, chamando o método crianotificacao(), para que as mesmas possam ser visualizadas pelo usuário da aplicação. A classe ParameterC2DM é responsável por armazenar as configurações para criar a notificação no dispositivo. Os métodos getnamemessagereceive() e gettitlemesagereceive() armazenam a mensagem e o titulo, respectivamente, da notificação criada Pacote br.com.fernandoklock.crypto Este pacote contém as classes responsáveis por aplicar a criptografia nos dados enviados e recebidos no dispositivo. A Figura 8 mostra com mais detalhes o diagrama de classes do pacote br.com.fernandoklock.crypto. Figura 8 - Diagrama de classe do pacote br.com.fernandoklock.crypto A classe Base64 é responsável por padronizar a formatação dos dados, transformando
37 36 os bytes cifrados e decifrados em texto para ser transmitido. A classe CryptographyAES é responsável por cifrar e decifrar os dados, utilizando o algoritmo de criptografia simétrica chamado de AES Pacote br.com.fernandoklock.database Este pacote é responsável por manipular os dados solicitados pelo utilizador do framework no banco de dados da aplicação. A Figura 9 mostra com mais detalhes o pacote br.com.fernandoklock.database. Figura 9 - Diagrama de classe do pacote br.com.fernandoklock.database A classe Data é responsável por padronizar os dados que serão repassados para atualização e inserção de registros no banco SQLite. Cada registro da base de dados é representado por um objeto Data no framework. A classe DBManipulate é uma classe abstrata na qual o desenvolvedor irá utilizar para manipular as queries e transações no banco de dados, através dos métodos selectreg(), insertreg(), updatereg() e deletereg(). Além disso, a classe fornece os métodos para iniciar a replicação e recuperar possíveis erros ocorridos durante o sincronismo das bases.
38 Diagrama de classes do servidor Neste item serão descritos os pacotes componentes do framework desenvolvido para o servidor. Grande parte das funcionalidades desenvolvidas no dispositivo estão implementadas no servidor, entretanto sua codificação apresenta algumas variâncias. O pacote br.com.fernandoklock.crypto não será abortado nesta sessão, pois as classes são idênticas as desenvolvidas no dispositivo que já foi apresentado anteriormente. Na Figura 10 é possível visualizar os pacotes que compõem a aplicação. Figura 10 - Diagrama de pacotes do servidor Pacote br.com.fernandoklock.database Este pacote é responsável por manipular os dados do banco SQLite do usuário no servidor via Java DataBase Connectivity (JDBC). A Figura 11 mostra com mais detalhes o pacote br.com.fernandoklock.database.
39 38 Figura 11 - Diagrama de classe do pacote br.com.fernandoklock.database A classe abstrata DBManipulate prove os recursos necessários ao desenvolvedor para acessar a base de dados, através dos métodos selectreg(), insertreg(), updatereg() e deletereg(). Além disso, através dela o desenvolvedor poderá solicitar a abertura do listener no servidor, com o método createlistenerreplication() e solicitar o envio de notificações para o dispositivo, com o método notifyforreplication() Pacote br.com.fernandoklock.replication Este pacote é responsável por gerenciar a replicação de dados do servidor, solicitar as notificações aos dispositivos, parametrizar as configurações de replicação e das notificações. A Figura 12 mostra com mais detalhes o pacote br.com.fernandoklock.replication.
40 39 Figura 12 - Diagrama de classe do pacote br.com.fernandoklock.replication A classe ManagerReplication faz o controle da replicação de dados através da troca de tags entre os hosts participantes do sincronismo e aplica os comandos SQL transmitidos nas base de dados. Além disso, a classe gerencia a thread que inicia o servidor de replicação, através do método createlistenerreplication(), possibilitando a conexão do dispositivo para efetivar a replicação de dados. Os métodos retregistryc2dm(), addregistryc2dm() e clearregistryc2dm() manipulam o banco de dados do framework para gerenciar o recebimento do ticket C2DM, que o dispositivo envia ao servidor para solicitar as notificações. Já a classe ParameterReplication é responsável por armazenar as configurações de replicação informadas pelo utilizador do framework. A classe ParameterC2DM é responsável por armazenar as configurações para que o servidor possa enviar notificações aos dispositivos. Outra classe relacionada é a NotifyClientC2DM, cujo objetivo é notificar os dispositivos com o envio da mensagem via push, assim o servidor informa o aplicativo de que há dados a serem sincronizados entre os
41 40 bancos. O método sendmessage() faz uma requisição HTTP ao servidor da Google. A classe SocketServer é uma thread que recebe e envia os dados transferidos do dispositivo para o servidor. Todas as informações recebidas nesta classe são repassadas para a classe ManagerReplication, que irá aplicar a requisição solicitada Diagrama de atividades A Figura 13 mostra o diagrama de atividades da rotina completa de notificações do servidor para o dispositivo. Figura 13 - Diagrama de atividades de notificações A primeira operação é o envio de notificação por parte do servidor, onde é solicitado ao servidor C2DM da Google a notificação ao dispositivo móvel. Após isto, o dispositivo móvel recebe a notificação e apresenta na aba de notificações do Android o evento. O usuário do dispositivo pode optar em limpar a notificação, finalizando o processo, ou abrir a notificação onde será solicitado o processamento da mensagem para a aplicação responsável pelo evento.
42 Diagrama de seqüência O diagrama de seqüência da Figura 14 mostra a interação do Sistema utilizador do framework com o framework na replicação de dados do dispositivo, nos casos de uso UC04 e UC05. Figura 14 - Diagrama de seqüência da replicação de dados O sincronismo entre as bases de dados é iniciado pelo Sistema utilizador do framework através do método startreplication() da classe DBManipulate, que faz a interface do desenvolvedor com o framework. Após a solicitação da replicação, a classe RelicationManager recupera os registros a serem replicados no after-image, com o método retregistryreplication(), e solicita a cifragem dos mesmos através do método cifra() na classe CryptographyAES. Com isso, temos os dados cifrados e prontos a serem enviados via socket. Como o dispositivo móvel é um cliente socket, o envio dos dados é solicitado para a classe SocketClient. Todas as chamadas para a comunicação entre os frameworks são iniciadas pela classe ManagerReplication. O método enviadados() faz o envio dos
43 42 comandos SQL ao servidor, já os métodos addregistrybasetarget() e ApplyBaseTarget() são responsáveis por aplicar os registros SQL no banco de dados local utilizado pelo framework. 3.3 IMPLEMENTAÇÃO A seguir são descritas as técnicas e ferramentas utilizadas na implementação, bem como detalhes das principais classes e rotinas implementadas durante o desenvolvimento da aplicação Técnicas e ferramentas utilizadas O desenvolvimento do sistema proposto foi efetuado em duas partes, paralelas e interligadas por um serviço socket. As funcionalidades propostas foram desenvolvidas em um aplicativo cliente, a ser executado na plataforma Android. A parte que atende ao servidor foi desenvolvida em Java SE, utilizando um server socket para comunicar-se com aplicação do dispositivo. O desenvolvimento da replicação de dados usando push notification foi desenvolvido na linguagem Java com a API de desenvolvimento do Android na versão 2.2, também conhecida por Froyo (ver seção 2.5). O ambiente de desenvolvimento utilizado foi o Eclipse com o conjunto de plugins do Android Development Tools (ADT). Para a execução e a depuração da aplicação também foi utilizado um dispositivo smartphone da fabricante Motorola chamado Milestone que possui o sistema operacional Android Froyo. Para o framework do servidor foi utilizado o banco SQLite através da interface JDBC para os controles internos da aplicação e para utilização do banco de dados local do usuário. Nas requisições push foi utilizado o protocolo HTTP com a URL de requisição da Google.
44 Preparando ambiente Android para push O arquivo AndroidManifest.xml possui informações necessárias para as aplicações Android executarem. Para utilizar o serviço de push notification da Google, a aplicação deve manter um serviço de registro no servidor da Google. Este serviço indica ao servidor que a aplicação está apta para receber notificações. No Quadro 10 é exibido trecho de código XML que informa pelo manifest qual serviço faz o papel de receptor de notificações. <receiver android:name="com.google.android.c2dm.c2dmbroadcastreceiver" android:permission="com.google.android.c2dm.permission.send"> <intent-filter> <action android:name="com.google.android.c2dm.intent.receive" / <category android:name="br.com.fernandoklock.replication" /> </intent-filter> <intent-filter> <action android:name="com.google.android.c2dm.intent.registration"/> <category android:name="br.com.fernandoklock.replication" /> </intent-filter> </receiver> Quadro 10 Fragmento do manifesto para indicar a classe receptora de notificação Após indicar para o Android qual será a classe que consome as notificações, deve ser indicado que a aplicação tem permissão para registrar e receber as mensagens, e também que pode manipular a mensagem. O Quadro 11 mostra como são declaradas as permissões no manifesto através das tags uses-permission, sendo que cada uma delas representa um tipo de permissão distinta. <!-- Somente esta aplicação pode receber as mensagens e registrar o resultado --> <permission android:name="br.com.fernandoklock.replication.permission.c2d_message" android:protectionlevel="signature" /> <uses-permission android:name="br.com.fernandoklock.replication.permission.c2d_message" /> <!--Esta aplicação tem permissão para registrar e receber notificações --> <uses-permission android:name="com.google.android.c2dm.permission.receive" /> Quadro 11 Fragmento do manifesto de permissão da aplicação para notificação Após configurada, a aplicação deve iniciar o processo de registro no servidor C2DM da Google para receber um ticket que representa o dispositivo na Google e enviar esse ticket ao servidor, assim o servidor pode enviar futuras notificações. O Quadro 11 mostra o trecho
45 44 de código onde é iniciado o serviço de registro do dispositivo, sendo que o parâmetro senderid representa a conta do utilizador do framework na Google e o objeto Context representa o pacote no qual a aplicação está rodando. public static void register(context context, String senderid) { Intent registrationintent = new Intent(REQUEST_REGISTRATION_INTENT); registrationintent.setpackage(gsf_package); registrationintent.putextra(extra_application_pending_intent, PendingIntent.getBroadcast(context, 0, new Intent(), 0)); registrationintent.putextra(extra_sender, senderid); context.startservice(registrationintent); } Quadro 12 Fragmento de código para disparo de registro de notificação Com o serviço de registro iniciado, entra em ação a classe que faz o papel de receptora, C2DMBroadcastReceiver, definida no manifesto. Essa classe intercepta pelo método onreceive() todos os dados enviados do servidor da Google para aplicação. No Quadro 13 segue o trecho de código que captura as mensagens enviadas para o dispositivo. Todos os dados recebidos são encaminhados para a classe C2DMBaseReceiver que faz o tratamento especifico de cada solicitação. public final void onreceive(context context, Intent intent){ C2DMBaseReceiver.runIntentInService(context, intent); setresult(activity.result_ok, null /* data */, null /* extra */); } Quadro 13 - Recebimento de notificação na classe C2DMBroadcastReceiver Após o recebimento das mensagens, a classe C2DMBroadcastReceiver faz a chamada do método onhandleintent() na classe C2DMBaseReceiver. No Quadro 14 segue o trecho de código que faz o tratamento das mensagens recebidas. Dentro do processamento temos: processamento de notificação recebido através da tag C2DM_INTENT e processamento de registro de notificação recebido através das tags C2DM_RETRY / REGISTRATION_CALLBACK_INTENT. O registro de notificação é responsável por enviar para o servidor o ticket do servidor Google que deve ser usado para envio de notificações.
46 45 public final void onhandleintent(intent intent) { try { Context context = getapplicationcontext(); if (intent.getaction().equals(registration_callback_intent)) { handleregistration(context, intent); } else if (intent.getaction().equals(c2dm_intent)) { onmessage(context, intent); } else if (intent.getaction().equals(c2dm_retry)) { C2DMessaging.register(context, senderid); } } finally { mwakelock.release(); } Quadro 14 - Tratamento das mensagens recebidas na classe C2DMBaseReceiver O processo de registro retorna um ticket que deve ser redirecionado para o servidor que gerará notificações. O processo de envio para o servidor é feito pela classe SocketClient no método registrac2dmserver() através de uma conexão socket. O consumo de notificações no dispositivo gera um alerta na área de notificações, mostrando que o servidor deseja sincronizar dados com a aplicação. No Quadro 15 é demonstrado o trecho de código de geração de notificação para Android. Através dos objetos Notification e NotificationManager são repassados os parâmetros necessários para a notificação como o titulo, descrição e frame que deverá ser aberto, representados respectivamente por dstitlec2dm, dsmessagec2dm e nmaplication. private void crianotificacao(context ctx, String evento) { NotificationManager notificationmanager = (NotificationManager) ctx.getsystemservice(context.notification_service); Notification notificacao = new Notification(R.drawable.icon, this.dstitlec2dm,system.currenttimemillis()); notificacao.flags = Notification.FLAG_INSISTENT; notificacao.flags = Notification.FLAG_AUTO_CANCEL; Class classe = null; try { classe = Class.forName(this.nmAplication); } catch (ClassNotFoundException e) { e.printstacktrace(); return; } PendingIntent p = PendingIntent.getActivity(ctx, 0, new Intent(ctx.getApplicationContext(),classe), 0); notificacao.setlatesteventinfo(ctx, this.dstitlec2dm, this.dsmessagec2dm + evento, p); notificacao.vibrate = new long[] { 100, 1000, 1000, 1000 }; notificationmanager.notify(r.string.app_name, notificacao); } Quadro 15 Geração de notificação Android
47 Envio de notificações para o dispositivo Android pelo servidor No servidor foi implementado o envio de notificações, conforme regra da replicação de dados definida para o framework, pré-requisito para o envio é possuir o ticket do dispositivo. Isto é feito apenas porque o envio é solicitado para um servidor da Google de C2DM. Com o ticket, recebido pelo dispositivo, o servidor precisa primeiramente de uma sessão autenticada no servidor Google. No Quadro 16 é demonstrado um trecho de código de captura de sessão com servidor Google de C2DM. Dentro da lista de objetos NameValuePair são repassados os parâmetros de autenticação, solicitados via HTTP. public String getauthentification() { HttpClient client = new DefaultHttpClient(); HttpPost post = new HttpPost("https://www.google.com/accounts/ClientLogin"); try { List<NameValuePair> namevaluepairs = new ArrayList<NameValuePair>(1); namevaluepairs.add(new BasicNameValuePair(" ", this.paramc2dm.get ())); namevaluepairs.add(new BasicNameValuePair("Passwd", this.paramc2dm.getpasswd())); namevaluepairs.add(new BasicNameValuePair("accountType", this.paramc2dm.getaccounttype())); namevaluepairs.add(new BasicNameValuePair("source", "Google-cURL-Example")); namevaluepairs.add(new BasicNameValuePair("service", "ac2dm")); post.setentity(new UrlEncodedFormEntity(nameValuePairs)); HttpResponse response = client.execute(post); BufferedReader rd = new BufferedReader( new InputStreamReader(response.getEntity().getContent())); String line = ""; while ((line = rd.readline())!= null) { if (line.startswith("auth=")) { return line.substring(5, line.length()); } } } catch (Exception e) { return ""; } return ""; } Quadro 16 Requisitando token de autenticação no servidor C2DM. Com a autenticação recebida, agora o servidor pode mandar uma notificação para o dispositivo. O Quadro 17 mostra o envio de notificações aos dispositivos, sendo que para cada
48 47 identificador recebido do dispositivo móvel o servidor faz uma solicitação HTTP com o Google C2DM e o envia através da tag PARAM_REGISTRATION_ID. public void sendmessage() throws Exception { ArrayList<String> authdispositivos = this.replmanager.retregistryandroidc2dm(); if (authdispositivos == null) return; for (String auth_android : authdispositivos) { System.out.println("Started"); String auth_key = getauthentification(); if (auth_key.trim().equalsignorecase("")) { throw new Exception("Nao foi possivel autenticar" + " no servidor da google."); } StringBuilder postdatabuilder = new StringBuilder(); postdatabuilder.append(param_registration_id).append("="). append(auth_android); postdatabuilder.append("&").append(param_collapse_key). append("=").append("0"); postdatabuilder.append("&").append("data.payload").append("="). append(urlencoder.encode("lars war hier", UTF8)); byte[] postdata = postdatabuilder.tostring().getbytes(utf8); URL url = new URL("http://android.clients.google.com/c2dm/send"); HttpURLConnection conn = (HttpURLConnection)url.openConnection(); conn.setdooutput(true); conn.setusecaches(false); conn.setrequestmethod("post"); conn.setrequestproperty("content-type", "application/x-www-form-urlencoded"); conn.setrequestproperty("content-length", Integer.toString(postData.length)); conn.setrequestproperty("authorization", "GoogleLogin auth=" + auth_key); OutputStream out = conn.getoutputstream(); out.write(postdata); out.close(); Quadro 17 Envio de notificação push para dispositivo No envio da notificação o ticket é informado no parâmetro PARAM_REGISTRATION_ID e para poder se comunicar respeitando a segurança do servidor da Google, é enviado o token de autorização onde deve ser requisitado junto ao servidor como já explicado anteriormente.
49 Criptografia simétrica AES Através da criptografia simétrica AES o framework do dispositivo e do servidor cifram e decifram os dados transferidos a fim de estabelecer um padrão de segurança no sincronismo das bases de dados. A chave de criptografia deve ser idêntica no servidor e no dispositivo, sendo que a mesma deve ser informada no momento em que a classe ParameterReplication é instanciada. O tamanho da chave de criptografia utilizada pode variar de acordo com o nível de segurança que o desenvolvedor deseja utilizar na aplicação, aplicando ao algoritmo chaves de 128, 192 ou 256 bits. A aplicação utiliza a API javax.cripto e não apresenta um mecanismo para transferência das chaves entre os integrantes da replicação. Ao cifrar ou decifrar algum dado o framework utiliza a classe Base64 para padronizar o texto a ser transferido e recebido, com objetivo de não apresentar problemas com diferentes padrões de string, como Unicode Transformation Format 8-bit (UTF-8) e American Standard Code for Information Interchange (ASCII). O Quadro 18 mostra com mais detalhes a utilização da criptografia simétrica AES na aplicação. Através do objeto SecretKeySpec são repassadas a chave de criptografia e a string contendo o algoritmo de criptografia que será utilizado. Após isto é instanciado o objeto Cipher que fará a cifragem/decifragem dos dados com a chamada do método dofinal(). public static String cifrar(string value) throws Exception { String retorno = null; SecretKeySpec spec = new SecretKeySpec(chave, "AES"); AlgorithmParameterSpec paramspec = new IvParameterSpec(new byte[16]); Cipher cifra = Cipher.getInstance("AES/CBC/PKCS5Padding"); cifra.init(cipher.encrypt_mode, spec, paramspec); byte[] cifrado = cifra.dofinal(value.getbytes()); retorno = Base64.encodeBytes(cifrado); return retorno; } public static String decifrar(string cifra) throws Exception { String retorno = null; SecretKeySpec skeyspec = new SecretKeySpec(chave, "AES"); AlgorithmParameterSpec paramspec = new IvParameterSpec(new byte[16]); byte[] decoded = Base64.decode(cifra); Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); cipher.init(cipher.decrypt_mode, skeyspec, paramspec); retorno = new String(cipher.doFinal(decoded)); return retorno; } Quadro 18 - Utilização da criptografia simétrica AES
50 49 A mesma implementação de criptografia utilizada no dispositivo móvel foi disponibilizada para o servidor, entretanto é o servidor que define qual o nível de segurança utilizada no canal de comunicação. Caso o framework do dispositivo informe um tamanho de chave diferente do servidor, a replicação não poderá ser estabelecida. Esta funcionalidade foi disponibilizada para que o utilizador do framework possa garantir um nível de segurança da replicação de dados no dispositivo móvel Utilização do socket para transferência de dados Os frameworks do dispositivo e do servidor utilizam a tecnologia socket para criar o canal de comunicação na replicação dos bancos de dados. O servidor conta com uma thread na classe SocketServer, responsável por prover os acessos ao dispositivo. Além de receber os dados de sincronismos das bases, o socket recebe as requisições de registros push notification dos dispositivos, para que o servidor possa enviar as notificações. O Quadro 19 mostra um trecho de código da implementação socket no servidor. serversocket = echoserver.accept(); is = new DataInputStream(serverSocket.getInputStream()); os = new DataOutputStream(serverSocket.getOutputStream()); ArrayList<String> dadoslidos = new ArrayList<String>(); String dadolido = is.readutf(); if (dadolido.equals(this.paramreplication.tamanhochave())) { os.writeutf("ok"); } else { os.writeutf("nok"); is.close(); os.close(); continue; } dadolido = is.readutf(); if ((dadolido.equals("beginreplicationsource") && this.paramreplication.ispassiveserver() ) (dadolido.equals("beginreplicationtarget") &&!this.paramreplication.ispassiveserver()) ) { os.writeutf("ok"); } else { os.writeutf("nok"); is.close(); os.close(); continue; } Quadro 19 - Trecho de código da implementação socket do servidor
51 50 Já no dispositivo a utilização do socket funciona como cliente, sendo que o mesmo se conecta no servidor e efetua a transferência dos dados. Durante todas as transferências de dados, o dispositivo e o servidor trocam tags para informar o tipo de solicitação de replicação, como por exemplo, a tag BeginReplicationSource informando que uma requisição para transação de um banco source está sendo solicitada. Além disso, na utilização da classe SocketClient são geradas exceções através do recebimento das tags NOK, informando que os frameworks estão com a mesma configuração de sincronismo ou que as chaves de criptografias são distintas. O Quadro 20 mostra o trecho de código da implementação socket no dispositivo. SocketAddress sockaddr = new InetSocketAddress(addr, this.paramreplication.getnrporthost()); smtpsocket = new Socket(); smtpsocket.connect(sockaddr, 2000); os = new DataOutputStream(smtpSocket.getOutputStream()); is = new DataInputStream(smtpSocket.getInputStream());... dadolido = is.readutf(); if (dadolido.equals("nok")) { throw new Exception("Chaves de criptografia incompativeis!"); } if (!this.paramreplication.ispassiveclient()) { dadossync = this.replmanager.retdatasync(); os.writeutf("beginreplicationsource"); dadolido = is.readutf(); if (dadolido.equals("nok")) { throw new Exception("Server e Client de replicacao" " estão configurados como SOURCE!"); } for (String dadosync : this.dadossync) { os.writeutf(dadosync); } os.writeutf("endoftransmission");... } this.replmanager.returnreplication(errorreplication, dadoslidos); Quadro 20 Trecho de código da implementação socket no dispositivo
52 Gerenciamento da replicação de dados O framework criado disponibiliza ao desenvolvedor a escolha de qual será o sentido da replicação de dados entre os equipamentos contidos no canal de comunicação socket. Tanto o dispositivo móvel como o servidor podem ser utilizados como base source e target. Quando um dos frameworks é configurado para agir como source o mesmo habilita as funções de after-image, que funciona como uma base de dados de transações já efetivadas durante a utilização do banco local. Ao executar uma rotina de inserção de dados, por exemplo, as informações são armazenadas no banco local e no banco after-image da replicação, para que possam ser replicadas na base target. Quando o sistema utilizador do framework solicita a replicação de dados, o banco source faz a leitura dos dados existentes no after-image e retorna para a classe ManagerReplication, que encaminha as solicitações ao envio por socket. A base de dados target somente recebe as transações executadas no banco source e as aplica. No caso em que o banco target for o dispositivo móvel, os comandos SQL são divididos em tokens para serem inseridos no objeto ContentValues do Android. Isto se faz necessário, pois os comandos delete, update e insert apresentam modos distintos de implementação. Sendo assim, cada comando enviado via socket é analisado e encaminhado para sua respectiva operação no banco de dados. O Quadro 21 mostra a analise para a execução do comando update, sendo que cada token da string recebida é verificado para montar os parâmetros que serão repassados ao método update().
53 52 while (tokens.hasmoretokens()) { String token = tokens.nexttoken(); if (Pattern.compile("update", Pattern.CASE_INSENSITIVE).matcher(token).find()) { continue; } if (Pattern.compile("set", Pattern.CASE_INSENSITIVE).matcher(token).find()) { clausula_set = true; continue; } if (Pattern.compile("where", Pattern.CASE_INSENSITIVE).matcher(token).find()) { clausula_where = true; clausula_set = false; continue; } if (clausula_set) { set += " " + token; continue; } } if (clausula_where) { where += " " + token; continue; } tabela = token; ContentValues cv = new ContentValues(); String vet_column_alter[] = set.split(","); for (int i = 0; i < vet_column_alter.length; i++) { String vet_update[] = vet_column_alter[i].split("="); cv.put(vet_update[0].trim(), vet_update[1].trim()); } result = this.dbmanipulate.getdb().update(tabela, cv, where, new String[] {}); Quadro 21 - Análise para execução do comando update Caso ocorram erros durante as atualizações dos registros, os mesmos são retornar a base source para que possam ser adicionados ao log de erros Operacionalidade da implementação Para demonstrar a operacionalidade do framework foi desenvolvida uma aplicação de demonstração para o dispositivo móvel e para o servidor, a fim de explorar todas as
54 53 funcionalidades disponibilizadas. Serão apresentadas imagens da aplicação no simulador utilizado para o desenvolvimento. Antes de iniciar o desenvolvimento da aplicação, o desenvolvedor deverá importar sua base de dados no projeto dos frameworks, tanto no dispositivo móvel quanto no servidor. Além de sua base de dados, o desenvolvedor deverá copiar também a base de dados ReplicationDB, que faz os controles para a replicação de dados. A Figura 15 mostra o local onde as bases de dados deverão estar para o funcionamento do framework. Figura 15 - Localização das bases de dados SQLite no projeto Para melhor entendimento da utilização do framework, será detalhada a implementação realizada na aplicação de teste. Tanto no dispositivo como no servidor o desenvolvedor deverá criar uma classe que irá estender a classe abstrata DBManipulate, contendo os métodos necessário para utilização da replicação de dados e da base de dados SQLite. O Quadro 22 mostra a classe AtualizaDB criada para estender a classe DBManipulate.
55 54 public class AtualizaDB extends DBManipulate { public AtualizaDB(String dbname, Context context, ParameterReplication paramreplication) throws IOException { super( dbname,context, paramreplication); public int deletereg(string table, String where) throws Exception { return super.deletereg(table, where); public long insertreg(data data) throws Exception { return super.insertreg(data); public int updatereg(data data, String where) throws Exception { return super.updatereg(data, where); public ArrayList<String> selectreg(string tables, String projection, String where) throws Exception { return super.selectreg(tables, projection, where); } Quadro 22 - Classe AtualizaDB que estende a classe abstrata DBManipulate Após criar a classe, basta o sistema instanciar as classes ParameterReplication e ParameterC2DM, para que sejam definidos os parâmetros de utilização do framework. Com isto todas as chamadas de métodos utilizados na replicação e manipulação dos dados podem ser feitos através da classe que estende a DBManipulate. O Quadro 23 mostra o trecho de código onde são instanciadas as classes para utilização do framework.
56 55 ParameterReplication paramreplication = null; AtualizaDB db = null; ParameterC2DM paramc2dm = null; try { paramc2dm = new ParameterC2DM(this, "Framework FURBRepl", "Mensagem do framework FURBRepl", this.getclass()); } catch (IOException e) { e.printstacktrace(); } try { paramreplication = new ParameterReplication(this, " ", 15001, true, true, new byte[] { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }); } catch (IOException e1) { e1.printstacktrace(); } try { db = new AtualizaDB("FurbDB", this, paramreplication); } catch (IOException e) { e.printstacktrace(); } Quadro 23 - Instância das classes de parametrização do framework Sabendo como utilizar o framework na codificação, agora serão apresentadas as telas da aplicação teste implementada. A aplicação console criada para o servidor será utilizada nesta demonstração como receptora dos dados para o Android e não será apresentada em sua totalidade, pois contém as mesmas funcionalidades utilizadas no dispositivo, com exceção do envio das notificações. A aplicação no dispositivo foi implementada de forma a possuir uma tela inicial de menu que permite restaurar as configurações padrões do framework, verificar o log de erros de transação e entrar no sistema que utiliza o framework. No momento que a aplicação é aberta a tela de menu possui três botões, conforme pode ser configura na Figura 16.
57 56 Figura 16 - Tela do menu da aplicação Quando o botão Restaurar Conf. Padrão é pressionado o sistema confirma se o usuário deseja restaurar as configurações de replicação e o banco de dados utilizado pelo sistema. Neste momento o framework faz a copia dos bancos que estão no diretório padrão da aplicação, conforme apresentado anteriormente na Figura 26. Através do botão Log Replicação o framework apresenta os erros SQL que ocorreram durante a replicação de dados, obtidos através do método getreplicationerror() da classe DBManipulate. Estes erros podem ocorrer quando o dispositivo está configurado como banco de dados source e o servidor como target. A Figura 17 mostra erros ocorridos durante a replicação de dados. Figura 17 - Log de erros da Replicação
58 57 O botão Aplicação apresenta o sistema utilizador do framework, onde são manipulados os dados no banco de dados SQLite. Através desta aplicação as transações são registradas no gerenciador interno de replicação, a fim de replicar os dados. Para manipular os registros o desenvolvedor utilizará os métodos selectreg(), updatereg(), deletereg() e insertreg() da classe DBManipulate. A Figura 18 mostra as telas da aplicação criada para utilizar o framework. Figura 18 - Telas da aplicação teste do framework Ao entrar na aplicação podem-se iniciar os testes de replicação com a utilização do framework. Como a aplicação trata-se de um sistema de chamada para acadêmicos, é registrada uma presença para um aluno, conforme Figura 19. Figura 19 - Registrar presença para um aluno
59 58 Após isto, o utilizador do framework poderá acionar a replicação de dados através do método startreplication(), que estará disponível na classe que irá estender a DBManipulate. No caso da aplicação implementada no dispositivo, foi utilizada uma tela de preferências onde são passados todos os parâmetros necessários para o sincronismo, conforme Figura 20. Assim, a classe ParameterReplication receberá como parâmetro os dados informados na tela abaixo. Neste caso, a aplicação do dispositivo está configurada como base source. Figura 20 - Tela preferências para replicação de dados Ao iniciar a replicação no dispositivo o servidor deverá estar com server socket habilitado para receber dados. Neste caso, o desenvolvedor da aplicação no servidor deverá iniciar a thread que aguarda solicitações de replicação, através do método createlistenerreplication() da classe DBManipulate. Com a replicação efetuada, o servidor da replicação recebe os dados e registra na sua base de dados. No Quadro 24 pode ser vista a presença registrada para o aluno no servidor, através da aplicação console.