A apresentação está carregando. Por favor, espere

A apresentação está carregando. Por favor, espere

Versão 1 - julho/2013 Tecgraf PUC-Rio Novembro de 2013 API C# do SCS.

Apresentações semelhantes


Apresentação em tema: "Versão 1 - julho/2013 Tecgraf PUC-Rio Novembro de 2013 API C# do SCS."— Transcrição da apresentação:

1 versão 1 - julho/2013 Tecgraf PUC-Rio Novembro de 2013 API C# do SCS

2 versão 1 - julho/2013 A API do SCS A API da biblioteca SCS permite a construção de componentes –Manualmente –Através de descritores A API lida apenas com a representação local do componente –Encarrega-se apenas da construção –Não lida com a composição de vários componentes (que pode ser distribuída) A representação local de um componente SCS-C# é dada pela interface ComponentContext

3 versão 1 - julho/2013 Criação de um Componente São necessários alguns passos: 1.Alterar facetas básicas (opcional) 2.Implementar suas facetas (opcional) 3.Criar o ComponentId 4.Instanciar a representação local do componente 5.Adicionar facetas (opcional) 6.Adicionar receptáculos (opcional)

4 versão 1 - julho/2013 Criação de um Componente Outra opção é utilizar descritores XML Externalizam como deve ser a construção do componente Não é necessário recompilar o código para mudar a configuração do componente Os passos passam a ser: Descrever o componente em um arquivo XML Implementar suas facetas (opcional) Utilizar a API para construir o componente a partir do arquivo XML

5 versão 1 - julho/2013 Implementação de uma Faceta

6 versão 1 - julho/2013 Uma faceta SCS nada mais é do que uma implementação de uma interface CORBA O SCS adiciona algumas convenções, mas a implementação da interface se dá da mesma forma public class MyFacetServant : MarshalByRefObject, MyFacet { } Criação de Facetas

7 versão 1 - julho/2013 Pode ser útil também ter um construtor que receba a representação local do componente ao qual essa faceta pertencerá Assim pode-se ter acesso a outras facetas e dados comuns ao componente como um todo Essa representação local é chamada de contexto do componente (interface ComponentContext) Esse construtor não é obrigatório, a não ser na construção por XML Criação de Facetas

8 versão 1 - julho/2013 Exemplo de faceta completa public class MyFacetServant : MarshalByRefObject, MyFacet { private ComponentContext _context; public MyFacetServant(ComponentContext context) { _context = context; }... } Criação de Facetas

9 versão 1 - julho/2013 Representação Local do Componente (ComponentContext)

10 versão 1 - julho/2013 Definição do ComponentId Idêntico ao demonstrado na IDL ComponentId cpId = new ComponentId( “MyComponentName”, 1, 0, 0, “.NET 4.0” ); Criação do ComponentId

11 versão 1 - julho/2013 ComponentContext – Atua como um envólucro que facilita o uso do componente como uma entidade única e não apenas um aglomerado de facetas e receptáculos Representação local do componente Acesso a todas as facetas (incluindo as básicas) e receptáculos Guarda os metadados, como descrições de facetas e receptáculos e identificador do componente (ComponentId) Implementação padrão dada pela classe DefaultComponentContext O Componente C#

12 versão 1 - julho/2013 ComponentContext – Diferença entre representações – Visão distribuída de um componente – Em um ambiente distribuído (CORBA), existe apenas o que está no contrato da IDL (scs.idl) – O componente é essencialmente o conjunto das facetas IComponent, IReceptacles, IMetaInterface e facetas adicionais – NÃO existe uma “caixa” que agrupe essas facetas em um bloco, representando o componente como um todo – A faceta IComponent é o que mais se aproxima de representar o componente – Receptáculos não existem de fato, e são manuseados apenas através da faceta IReceptacles – Visão local de um componente – Objeto ComponentContext une as facetas e receptáculos em uma única representação O Componente C#

13 versão 1 - julho/2013 ComponentContext – A classe DefaultComponentContext pode ser estendida para adicionar outros dados de uso global no componente Dados acessados por mais de uma faceta Dados referentes ao componente em si, não a uma faceta específica Métodos O Componente C#

14 versão 1 - julho/2013 public (Default)ComponentContext(ComponentId id) – Construtor que recebe o ComponentId – Adiciona automaticamente as facetas básicas (e já as ativa no ORB) ComponentId GetComponentId() – Retorna o ComponentId fornecido no construtor IComponent GetIComponent() – Retorna o objeto CORBA referente à faceta IComponent do componente Interface C# ComponentContext

15 versão 1 - julho/2013 void AddFacet(String name, String interfaceName, MarshalByRefObject servant) – Adiciona uma faceta ao componente – Ativa o objeto CORBA no ORB void RemoveFacet(String name) – Remove uma faceta do componente – Desativa o objeto CORBA no ORB void UpdateFacet(String name, MarshalByRefObject servant) – Desativa o objeto CORBA da faceta no ORB – Substitui o objeto CORBA pelo novo fornecido – Ativa o novo objeto CORBA no ORB Interface C# ComponentContext

16 versão 1 - julho/2013 void AddReceptacle(String name, String interfaceName, Boolean isMultiple) – Adiciona um receptáculo ao componente void RemoveReceptacle(String name) – Remove um receptáculo do componente Interface C# ComponentContext

17 versão 1 - julho/2013 IDictionary GetFacets() – Retorna um dicionário com todas as facetas do componente, associadas aos seus nomes – A classe Facet contém o objeto CORBA e os metadados associados Facet GetFacetByName(String name) – Retorna uma faceta específica IDictionary GetReceptacles() – Retorna um dicionário com todos os receptáculos do componente, associados aos seus nomes Receptacle GetReceptacleByName(String name) – Retorna um receptáculo específico Interface C# ComponentContext

18 versão 1 - julho/2013 Como obter uma faceta a partir de outra? Como acessar uma dependência conectada a um receptáculo? context.GetReceptacleByName(“ReceptacleName”).Get Connections() context.GetFacetByName(“FacetName”).Reference Exemplos

19 versão 1 - julho/2013 Novas implementações podem ser fornecidas para as facetas básicas A implementação é feita normalmente como em qualquer faceta / objeto CORBA, basta seguir a interface desejada Após criar o ComponentContext, deve-se substituir o servant da faceta desejada pelo novo (método updateFacet) Alteração de Facetas Básicas

20 versão 1 - julho/2013 ComponentId cpId = new ComponentId( “MyComponentName”, (byte) 1, (byte) 0, (byte) 0, “windows” ); ComponentContext context = new DefaultComponentContext(cpId); MyIComponentClass myIC = new MyIComponentClass(context); context.UpdateFacet(“IComponent”, myIC); Alteração de Facetas Básicas

21 versão 1 - julho/2013 Outras Funcionalidades

22 versão 1 - julho/2013 É possível montar um componente a partir de um arquivo descritor em XML ‒ Substitui os passos demonstrados anteriormente O descritor deve conter no mínimo: ‒ Identificador do componente Pode-se fornecer, opcionalmente: ‒ Descrições de facetas (nome, interface, e classe a ser instanciada) A classe da faceta deve conter um construtor que receba apenas um ComponentContext como parâmetro ‒ Descrições de receptáculos (nome, interface, multiplex) ‒ Classe a ser usada como ComponentContext A biblioteca fornece um arquivo xsd com o formato XMLComponentBuilder

23 versão 1 - julho/2013 Exemplo de arquivo XML MyComponent 1.0.0.NET 4.0 MyFacet IDL:module/Interface:1.0 mypackage.InterfaceImpl AnotherFacet IDL:module/AnotherInterface:1.0 mypackage.AnotherInterfaceImpl XMLComponentBuilder

24 versão 1 - julho/2013 Exemplo de uso da API … XmlTextReader reader = new XmlTextReader(args[0]); XmlComponentBuilder xmlBuilder = new XmlComponentBuilder(reader); ComponentContext context = xmlBuilder.build(); … XMLComponentBuilder

25 versão 1 - julho/2013 Aplicação Exemplo

26 versão 1 - julho/2013 Exemplo passo-a-passo Veremos um exemplo, passo-a-passo, de desenvolvimento de uma aplicação SCS usando C# Para desenvolver a aplicação, usaremos o IIOP.NET como ORB tanto para o cliente quanto para o servidor, e as bibliotecas do SCS

27 versão 1 - julho/2013 Exemplo de Aplicação StockSeller StockServer Stock Exchange StockLogger ExchangePrinter O componente StockSeller implementa duas facetas: StockServer e StockExchange O componente StockSeller tem um receptáculo para componentes que implementem a faceta ExchangePrinter O componente StockLogger implementa a faceta ExchangePrinter

28 versão 1 - julho/2013 Passo 1: Alterando a IDL // StockMarket.idl // O módulo StockMarket consiste das definições // úteis para desenvolvimento de aplicações // que lidam com mercado de ações. module StockMarket {... // A interface ExchangePrinter é a interface que // representa uma impressora de negociações de ações. interface ExchangePrinter { // Imprime que houve uma negociação da ação indicada. // A saída utilizada para impressão não é especificada. // Exemplos de saídas: tela, arquivo, clients remotos. void print(in StockSymbol symbol); }; // A interface StockExchange é a interface que permite // a compra de ações. interface StockExchange { // Usa os componentes ExchangePrinter que estejam // conectados para imprimir a negociaçao efetuada. boolean buyStock(in StockSymbol symbol); };};

29 versão 1 - julho/2013 Passo 2: Implementando as facetas Facetas são interfaces CORBA e, portanto, sua implementação segue as mesmas regras que vimos nos exemplos de CORBA Precisaremos alterar a classe StockServerImpl para que ela se torne uma Faceta SCS Além disso, precisaremos implementar as facetas StockExchange e ExchangePrinter

30 versão 1 - julho/2013 StockServerImpl namespace StockSeller { public class StockServerImpl : MarshalByRefObject, StockServer { public StockServerImpl(StockSellerContext context) { } /// /// Retorna o valor corrente de uma ação específica. /// /// Símbolo identificador da ação. /// O valor da ação requisitada. public float getStockValue(string symbol) { } /// /// Retorna os símbolos de todas as ações disponíveis. /// /// As ações disponíveis. public string[] getStockSymbols() { } public override object InitializeLifetimeService() { } }

31 versão 1 - julho/2013 StockExchangeImpl namespace StockSeller { public class StockExchangeImpl : MarshalByRefObject, StockExchange { public StockExchangeImpl(StockSellerContext context) { _context = context; } /// /// Realiza a compra de uma ação. Quando uma ação é negociada, seu valor /// aumenta em uma taxa de 10%. /// /// Usa os componentes ExchangePrinter que estejam /// conectados para imprimir a negociaçao efetuada. /// /// Símbolo da ação a ser comprada. /// True se a venda da ação foi bem sucedida, False caso contrário. /// public bool buyStock(string symbol) { } public override object InitializeLifetimeService() { } }

32 versão 1 - julho/2013 DisplayExchangePrinter namespace StockLogger { public class DisplayExchangePrinter : MarshalByRefObject, ExchangePrinter { public DisplayExchangePrinter(ComponentContext context) { } /// /// Imprime que houve uma negociação da ação indicada. /// A saída utilizada para impressão é a tela. /// /// Texto a ser impresso na tela. public void print(string text) { } public override object InitializeLifetimeService() { } }

33 versão 1 - julho/2013 Passo 3: Criando o componente StockSeller O componente StockSeller oferece as facetas StockServer e StockExchange O componente StockSeller possui um receptáculo para conectar um ou mais compontes que implementem a faceta ExchangePrinter

34 versão 1 - julho/2013 Inicia o ORB A inicialização do ORB, ao iniciar o servidor, é igual à que já usamos nos exemplos anteriores. O servidor deve, após criar o componente, deixar ao menos uma thread ativa para que o ORB possa ficar aguardando as requisições // inicializa o ORB, indicando que utilize uma porta aleatória para // receber chamadas IiopChannel chan = new IiopChannel(0); ChannelServices.RegisterChannel(chan, false);... Thread.Sleep(Timeout.Infinite);

35 versão 1 - julho/2013 Criando o identificador do componente Todo componente precisa ter um identificador, que é descrito usando a classe ComponentId ComponentId componentId = new ComponentId( "StockSeller", 1, 0, 0, “.NET 4.0");

36 versão 1 - julho/2013 Criando o componente A classe DefaultComponentContext deve ser instanciada para servir como representação local do componente (ou uma classe mais específica definida pelo usuário) Esse componente já conterá as facetas básicas do SCS ComponentContext context = new DefaultComponentContext(componentId);

37 versão 1 - julho/2013 Criando e adicionando as facetas // cria as facetas StockServerImpl stockServer = new StockServerImpl(context); StockExchangeImpl stockExchange = new StockExchangeImpl(context); // adiciona as facetas ao componente string serverType = Repository.GetRepositoryID(typeof (StockServer)); string exchangeType = Repository.GetRepositoryID(typeof (StockExchange)); context.AddFacet("StockServer", serverType, stockServer); context.AddFacet("StockExchange", exchangeType, stockExchange);

38 versão 1 - julho/2013 Adicionando receptáculos // adiciona o receptáculo string printerType = Repository.GetRepositoryID(typeof (ExchangePrinter)); context.AddReceptacle("ExchangePrinter", printerType, true);

39 versão 1 - julho/2013 Salva o IOR em um arquivo Nessa solução, ainda usaremos um arquivo para gravar a referência para o objeto CORBA Note que estamos usando a referência para um IComponent OrbServices orb = OrbServices.GetSingleton(); string ior = orb.object_to_string(context.GetIComponent()); File.WriteAllText(args[0], ior);

40 versão 1 - julho/2013 Passo 4: Criando o componente StockLogger O componente StockLogger oferece a faceta ExchangePrinter O código StockLoggerMain.cs é responsável por criar o componente SCS StockLogger Em nosso exemplo, o código que o conecta ao componente StockSeller é uma aplicação separada A criação do componente StockLogger é similar ao que fizemos para criar o StockSeller, exceto que não há receptáculos

41 versão 1 - julho/2013 Passo 5: Recuperando as referências dos componentes para conectá-los A conexão pode ser feita por um dos componentes do sistema ou por um cliente externo // Lê os IORs dos arquivos cujos nomes são passados como parâmetros string sellerIOR = File.ReadAllText(args[0]); string loggerIOR = File.ReadAllText(args[1]);

42 versão 1 - julho/2013 Obtendo as facetas IReceptacles do StockSeller e ExchangePrinter do StockLogger Precisaremos da faceta ExchangePrinter do componente StockLogger, pois é essa faceta que será conectada ao receptáculo do StockSeller A faceta IComponent tem métodos para recuperar suas outras facetas ORB orb = OrbServices.GetSingleton(); // Obtém as referências para os objetos CORBA IComponent sellerIC = orb.string_to_object(sellerIOR) as IComponent; if (sellerIC == null) {...} IComponent loggerIC = orb.string_to_object(loggerIOR) as IComponent; if (loggerIC == null) {...} string receptaclesType = Repository.GetRepositoryID(typeof (IReceptacles)); IReceptacles irStockSeller = sellerIC.getFacet(receptaclesType) as IReceptacles; if (irStockSeller == null) {...} string printerType = Repository.GetRepositoryID(typeof (ExchangePrinter)); ExchangePrinter printer = loggerIC.getFacet(printerType) as ExchangePrinter; if (printer == null) {...}

43 versão 1 - julho/2013 Conectando a faceta ExchangePrinter do StockLogger no receptáculo do StockSeller Usamos a faceta IReceptacles de StockSeller para fazer a conexão dos componentes O método connect faz a conexão do componente StockLogger usando sua faceta ExchangePrinter O exemplo não mostra para simplificar, mas deve-se tratar as exceções CORBA como no exercício anterior em toda chamada remota CORBA, assim como exceções específicas do método // Faz a conexão da faceta ExchangePrinter do componente StockLogger no // receptáculo do StockSeller irStockSeller.connect("ExchangePrinter", printer);

44 versão 1 - julho/2013 Passo 6: Usando os componentes conectados ao receptáculo do StockSeller A implementação do método buyStock pela faceta StockExchange do componente StockSeller deve chamar o método print da faceta ExchangePrinter conectada a esse mesmo componente

45 versão 1 - julho/2013 Obtendo o receptáculo correspondente a ExchangePrinter O contexto do componente possui o método GetReceptacleByName que retorna um receptáculo A classe Receptacle permite então recuperar as descrições das conexões As descrições das conexões são recuperadas com o método GetConnections de Receptacle O campo objref de ConnectionDescription possui a referência para a faceta IComponent da dependência conectada public bool buyStock(string symbol) {... IList conns = _context.GetReceptacleByName( "ExchangePrinter").GetConnections(); foreach (ConnectionDescription conn in conns) { try { ((ExchangePrinter)conn.objref).print( "Negociação da ação " + symbol + ". Novo valor: " + value); } catch(...) {...} }... }

46 versão 1 - julho/2013 Passo 7: Usando o componente StockSeller O cliente usa o componente StockSeller através de suas facetas O StockMarketClient.cs possui a etapa de inicialização do ORB que já vimos nos exemplos anteriores O que muda é o uso das facetas do componente para invocar os métodos remotos

47 versão 1 - julho/2013 Obtendo a referência para o componente StockSeller O cliente recupera a referência para o componente StockSeller lendo do arquivo recebido por parâmetro // Lê o IOR do arquivo cujo nome é passado como parâmetro string ior = File.ReadAllText(args[0]); ORB orb = OrbServices.GetSingleton(); // Obtém a referência para o objeto CORBA IComponent sellerIC = orb.string_to_object(ior) as IComponent; if (sellerIC == null) {…}

48 versão 1 - julho/2013 Obtendo as facetas StockServer e StockExchange do componente StockSeller Tendo o componente, as facetas StockServer e StockExchange são recuperadas, pelo nome ou pela interface try { string serverType = Repository.GetRepositoryID(typeof(StockServer)); string exchangeType = Repository.GetRepositoryID(typeof(StockExchange)); StockServer server = sellerIC.getFacet(serverType) as StockServer; if (server == null) {...} StockExchange exchange = sellerIC.getFacet(exchangeType) as StockExchange; if (exchange == null) {...} } catch (…) { … }

49 versão 1 - julho/2013 Invocando os métodos disponibilizados em cada faceta O cliente faz as chamadas aos métodos usando as respectivas facetas try { // Obtém os símbolos de todas as ações string[] symbols = server.getStockSymbols(); // Mostra as ações com seus respectivos valores foreach (string symbol in symbols) { Console.WriteLine(symbol + " " + server.getStockValue(symbol)); } // Compra uma ação if (symbols.Length > 0) { String first = symbols[0]; Console.WriteLine("--Compra a ação :" + first); bool success = exchange.buyStock(first); if (success) { Console.WriteLine("--Ação " + first + " depois da negociação: " + server.getStockValue(first)); } else { Console.WriteLine("--Não foi possivel negociar a ação " + first); } } catch (…) {…}


Carregar ppt "Versão 1 - julho/2013 Tecgraf PUC-Rio Novembro de 2013 API C# do SCS."

Apresentações semelhantes


Anúncios Google