Integração de aplicações em Luiz Eduardo Borges http://ark4n.wordpress.com/
Integração de aplicações em
Luiz Eduardo Borgeshttp://ark4n.wordpress.com/
Sumário
● Integração de aplicações
● Aplicações distribuídas
● Camada de comunicação
● Formatos de dados
● Aplicações externas
Integração de aplicações (tradicional)
Ambiente que requer muita administração
para se manter organizado.
Funções disponíveis para as aplicações.
Dados e regras de negócio precisam estar em um SGBD
para garantir a integridade e sigilo.
AplicaçãoA
AplicaçãoB
Bibliotecas
Dados
Integração através de middleware
AplicaçãoA
AplicaçãoB
Regras de negócio podem ficar em componentes.
Middleware
Funções disponíveis para
todas as aplicações.
Dados
O ambiente requer muita padronização
para se manter organizado.
Middleware
● É uma camada de software que conecta componentes ou aplicações, tendo como o objetivo a interoperabilidade.
● Várias opções:
– ZOPE (Z Object Publishing Environment)– WSGI (Web Server Gateway Interface)
– Twisted
– Muitos outros● O próprio Python pode ser encarado como um
middleware.
Modelo computacional
A B
C D
O servidor distribui as requisições e centraliza os
resultados.
Os outros nós (workers) recebem as tarefas e
calculam os resultados.
Modelo de recursos
A B
C D E F
G HOs servidores recebem as requisições e devolvem os
resultados.
Os clientes enviam as requisições e recebem
os resultados.
Modelo híbrido ou de aplicação
A B
C D
A aplicação se confunde com a infraestrutura, provendo os
recursos.
Cada nó pode atuar como servidor e cliente, inclusive
ao mesmo tempo.
Modelos (comparação)
Escalabilidade
Complexidade
Tolerância a falhas
Exemplo
PrincipalAplicação
Computacional
Média
Baixa
Média
SETI@home
Processamento memória
Recursos
Alta
Média
Alta
Servidores Web
Infra
Híbrido
Alta
Alta
Alta
P2P
Arquivos
Aplicações distribuídas (requisito I)
A B
C D
Primeiro requisito: definir a forma de comunicação
entre os nós.
Aplicações distribuídas (requisito II)
A B
C D
Segundo requisito: manter os metadados sobre os
nós, usuários, arquivos e outros recursos.
Aplicações distribuídas (requisito III)
A B
C D
Terceiro requisito: fazer o monitoramento e
controle dos componentes do sistema.
Aplicações distribuídas (requisito IV)
A B
C D
Quarto requisito: manter a segurança (sigilo, integridade e disponibilidade) dos dados e
sistemas envolvidos.
Camada de comunicação
Rede
Máquina
Aplicação
Framework
Máquina
Aplicação
Framework
A camada torna transparente os protocolos de
rede.
PYRO (Python Remote Objects)
Implementa:
● Um protocolo que permite a execução remota via TCP/IP de métodos de um objeto.
● Envio de estruturas de dados “serializáveis” como parâmetros.
● Servidor de nomes que facilita a localização automática dos métodos.
● Validadores para verificar as credenciais do cliente.
PYRO (servidor)
import numpyimport Pyro.core
class Dist(Pyro.core.ObjBase): def fft(self, l): return numpy.fft.fft(l)
# Inicia a thread do servidorPyro.core.initServer()
# Cria o servidordaemon = Pyro.core.Daemon()
# Publica o objetouri = daemon.connect(Dist(),'dist')
# Coloca o servidor em estado operacionaldaemon.requestLoop()
Classe do objeto que será publicado na rede pelo PYRO.
Método que calcula a transformada de Fourier.
PYRO (cliente)
# -*- coding: utf-8 -*-
import numpyimport Pyro.core
# Dados de testedados = numpy.random.rand(100)
# Cria um objeto local para acessar o objeto remotoproxy = Pyro.core.getProxyForURI('PYROLOC://127.0.0.1/dist')
# Evoca um método do objeto distribuídoprint proxy.fft(dados)
XML-RPC
Implementa:
● Protocolo de execução remota de procedimentos.
● Transferências de dados em XML usando HTTP ou HTTPS (criptografado) como protocolo de transporte.
● Suporte a tipos básicos: inteiro, ponto flutuante, texto, ...
XML-RPC (servidor)
import numpyfrom SimpleXMLRPCServer import SimpleXMLRPCServer
# Cria um servidorserver = SimpleXMLRPCServer(('localhost', 8888))server.register_introspection_functions()
def fft(l):
return [ float(x) for x in numpy.fft.fft(l) ]
server.register_function(fft)
# Inicia o loop do servidorserver.serve_forever()
Conversão para tipos que o XML-RPC aceita.
XML-RPC (cliente)
import numpyimport xmlrpclib
# Dados de testedados = [ float(x) for x in numpy.random.rand(100) ]
server = xmlrpclib.Server("http://localhost:8888")
# Evoca o procedimento remotoprint server.fft(dados)
Conversão para tipos que o XML-RPC aceita.
Socket
Implementa:
● Acesso de baixo nível a biblioteca de sockets que disponível em praticamente qualquer sistema operacional atual.
● Conexões ponto a ponto vai TCP/IP.
Socket (servidor I)
import cPickleimport socketimport threadingimport numpy
class Server(threading.Thread):
def __init__(self, skt): self.skt = skt threading.Thread.__init__ (self)
def run(self): # Recebe os dados rec = self.skt.recv(5000) # Calcula o resultado ff = numpy.fft.fft(cPickle.loads(rec)) # Retorna a resposta self.skt.send(cPickle.dumps(ff))
Continua...
Classe que implementa as threads para o servidor.
Método que é executado na thread.
Dados foram serializados no cliente.
Socket (servidor II)
# cria um socket INET STREAMserver = socket.socket( socket.AF_INET, socket.SOCK_STREAM)
# Associa o socket a uma porta na interface de redeserver.bind((socket.gethostname(), 8000))
# Passa a "ouvir" a portaserver.listen(5)
while True: # aceita acesso externo (skt, addr) = server.accept() svr =Server(skt) svr.start()
Socket (cliente)
import cPickleimport socketimport numpy
# Dadosdados = numpy.random.rand(100)
# cria um socket INET STREAMsvr = socket.socket( socket.AF_INET, socket.SOCK_STREAM)
# Conecta na interface de redesvr.connect((socket.gethostname(), 8000))svr.send(cPickle.dumps(dados))
# Recebe a respostarec = svr.recv(5000)print cPickle.loads(rec)
Os resultados foram serializados no servidor.
Comunicação (comparação)
Performance
Portabilidade
Escalabilidade
Complexidade
Dependências
PYRO
Alta
Baixa
Alta
Baixa
Média
XML-RPC
Baixa
Alta
Baixa
Média
Baixa
Socket
Alta
Alta
Depende da aplicação
Alta
Baixa
YAML (YAML Ain't a Markup Language)
Implementa:
● Formato de serialização de dados para texto, amigável para humanos.
● Representação de dados através de combinações de listas, dicionários e escalares.
● Convenções de sintaxe similares as linguagens dinâmicas, com forte influência do Python.
● Um superset do JSON (JavaScript Object Notation).
YAML (exemplo)
- Artista: King Crimson Faixas: - Starless - Frature - Red - Lizard- Artista: Genesis Faixas: - Supper's Ready - In The Cage - The Lamia
[{'Artista': 'King Crimson', 'Faixas': ['Starless', 'Frature', 'Red', 'Lizard']}, {'Artista': 'Genesis', 'Faixas': ["Supper's Ready", 'In The Cage', 'The Lamia']}]
Estrutura Python
Documento YAML
Formatos (comparação)
Performance
Portabilidade
Escalabilidade
Complexidade
Dependências
YAML / JSON
Média
Alta
Média
Baixa
Média
XML
Baixa
Alta
Alta
Média
Baixa
(c)Pickle
Alta
Baixa
Alta
Baixa
Baixa
Aplicações externas
Aplicações “pythônicas”:
● BrOffice.org
● Blender
● GIMP
● Inkscape
● PostgreSQL
BrOffice.org
Implementa:
● Suporte ao Python como linguagem de macro, permitindo a automatização de tarefas e a construção de extensões (add ons).
● Serviço para atender conexões, através de uma API chamada UNO (Universal Network Objects).
BrOffice.org (serviço)
Interpretador
Aplicação
PyUNO BrOffice.org
Aceita conexões remotas via
named pipes ou sockets.
Python UNO Bridge
BrOffice.org (exemplo I)
# -*- coding: latin1 -*-
# Para iniciar o BrOffice.org como servidor:# swriter.exe -headless# "-accept=pipe,name=py;urp;StarOffice.ServiceManager"
import osimport unofrom com.sun.star.beans import PropertyValue
# Dados...mus = [('Artista', 'Faixa'), ('King Crimson', 'Starless'), ('Yes', 'Siberian Khatru'), ('Led Zeppellin', 'No Quarter'), ('Genesis', 'Supper\'s Ready')]
rows = len(mus)cols = len(mus[0])
Continua...
BrOffice.org (exemplo II)
# Inicio do "Boiler Plate"...
# Contexto de componente localloc = uno.getComponentContext()
# Para resolver URLsres = loc.ServiceManager.createInstanceWithContext( 'com.sun.star.bridge.UnoUrlResolver', loc)
# Contexto para a URLcon = res.resolve('uno:pipe,name=py;urp;StarOffice.ComponentContext')
# Documento correntedesktop = con.ServiceManager.createInstanceWithContext( 'com.sun.star.frame.Desktop', con)
# Fim do "Boiler Plate"...
Continua...
BrOffice.org (exemplo III)
# Cria um documento novo no Writerdoc = desktop.loadComponentFromURL('private:factory/swriter', '_blank', 0, ())
# Cursor de textocursor = doc.Text.createTextCursor()
# Muda propriedadescursor.setPropertyValue('CharFontName', 'Verdana')cursor.setPropertyValue('CharHeight', 20)cursor.setPropertyValue('CharWeight', 180)doc.Text.insertString(cursor, 'Músicas favoritas\n', 0)
# Cria tabelatab = doc.createInstance('com.sun.star.text.TextTable')tab.initialize(rows, cols)doc.Text.insertTextContent(cursor, tab, 0)
Continua...
Texto inserido
BrOffice.org (exemplo IV)
# Preenche a tabelafor row in xrange(rows): for col in xrange(cols): cel = chr(ord('A') + col) + str(row + 1) tab.getCellByName(cel).setString(mus[row][col])
# Propriedades para exportar o documentoprops = []p = PropertyValue()p.Name = 'Overwrite'p.Value = True # Sobrescreve o documento anteriorprops.append(p)
p = PropertyValue()p.Name = 'FilterName'p.Value = 'writer_pdf_Export' # Writer para PDFprops.append(p)
Continua...
Tabela
BrOffice.org (exemplo V)
# URL de destinourl = uno.systemPathToFileUrl(os.path.abspath('musicas.pdf'))
# Salva o documento como PDFdoc.storeToURL(url, tuple(props))
# Fecha o documentodoc.close(True)
Arquivo de saída
Referências
PYRO:
● http://pyro.sourceforge.net/
Socket Programming HOWTO:
● http://www.amk.ca/python/howto/sockets/
YAML Cookbook:
● http://yaml4r.sourceforge.net/cookbook/
Python – OpenOffice.org Wiki:
● http://wiki.services.openoffice.org/wiki/Python
Integração de aplicações em
Luiz Eduardo Borgeshttp://ark4n.wordpress.com/
Fim