Openbus - Tecgraf JIRA / Confluence - PUC-Rio

Propaganda
SDK Openbus - Java
Tecgraf PUC-Rio
maio de 2011
A API do Openbus
• Para facilitar o desenvolvimento das
aplicações que usam o barramento, provendo
ou consumindo serviços, o SDK Java fornece
uma classe Openbus que encapsula as
principais funcionalidades para:
• inicialização e conexão com o barramento.
• obtenção das facetas dos serviços básicos.
• obtenção do ORB e do POA utilizados
• A própria classe OpenBus já cuida da
renovação da credencial emitida na conexão
Openbus é um Singleton
• Uma aplicação pode ter apenas uma instância
de Openbus.
• atualmente, uma nesma aplicação não pode
utilizar dois barramentos diferentes
public static Openbus getInstance();
Inicialização do barramento
• Possui métodos para inicializar o ORB com as
propriedades informadas e faz reset no estado do
barramento.
• Ativa o mecanismo de interceptação das requisições para que
a credencial seja utilizada
• Ativa o POA “RootPOA”
public void init(String[] args, Properties props, String host, int
port)
throws UserException, OpenbusAlreadyInitializedException;
Conexão com o barramento
• Os métodos de inicialização são sobrecarregados para
diferentes formas de conexão com o barramento
• Todos retornam a referência para o IRegistryService
public synchronized IRegistryService connect(String user,
String password)
throws ACSLoginFailureException, ACSUnavailableException,
ServiceUnavailableException, InvalidCredentialException,
CORBAException, OpenBusException;
public synchronized IRegistryService connect(String name,
RSAPrivateKey privateKey, X509Certificate acsCertificate)
throws ACSLoginFailureException, ServiceUnavailableException,
PKIException, ACSUnavailableException,
InvalidCredentialException, OpenBusException, CORBAException;
public IRegistryService connect(Credential credential)
throws InvalidCredentialException, OpenBusException,
ServiceUnavailableException, ACSUnavailableException,
CORBAException;
Listener para expiração da credencial
• Possui um método que permite adicionar um listener
que é avisado quando a credencial expirou e não foi
possível renovar o leasing.
public void setLeaseExpiredCallback(LeaseExpiredCallback lec);
• O listener é chamado pela thread que faz a renovação
automática do leasing, que a própria instância do
Openbus já inicia.
Credencial por Thread
• Possui o método setThreadCredential
que permite que uma credencial válida,
diferente daquela que foi usada na conexão,
seja configurada para a thread corrente.
• As requisições aos serviço usam a credencial
atribuída à thread corrente, caso exista.
public void setThreadCredential(Credential credential);
Credencial por Thread
• Um uso comum da credencial por thread é
criar uma nova credencial como uma cópia
daquela resultado da autenticação corrente,
alterando apenas o delegate.
Credential credential = Openbus.getInstance().getCredential();
Credential newCredential = new Credential(credential.identifier,
credential.owner,
delegate);
Openbus.getInstance().setThreadCredential(newCredential);
Acesso aos serviços básicos
• Possui métodos para obter as referências para
as facetas do serviços básicos:
• IAccessControlService
• IRegistryService
• ISessionService
public IAccessControlService getAccessControlService();
public IRegistryService getRegistryService();
public ISessionService getSessionService();
Acesso aos ORB e ao POA
• Possui métodos para obter as referências para
as ORB utilizado e ao POA “RootPOA”:
public org.omg.CORBA.ORB getORB();
public POA getRootPOA();
Finaliza a conexão
• Possui um métod para suspender a renovação
da credencial e fazer logout no serviço de
acesso
public synchronized boolean disconnect();
Outras classes auxiliares
•
•
•
•
CryptoUtils
Log
LeaseExpiredCallback
…
Desenvolvendo com o
SDK Java Openbus
Passo 1: Obtendo o SDK Openbus
• A última versão do SDK Java do Openbus
pode ser obtida em:
• https://jira.tecgraf.pucrio.br/confluence/display/ESDPUB/Openbus+Do
wnload
• Precisaremos também do JDK 1.5 ou superior
Libs do SDK Openbus 1.5
• Openbus:
• openbus-api-1.5.0.jar
• openbus-idl-jacorb-1.5.0.jar
• As libs do Jacorb são distribuídas com o SDK:
• avalon-framework-4.1.5.jar
• jacorb-2.3.0.jar
• logkit-1.2.jar
• As libs do SCS são distribuídas com o SDK:
• scs-core-1.1.0.jar
• scs-idl-jacorb-1.1.0.jar
• A lib para encoding:
• commons-codec-1.3.jar
Passo 2: Preparando os stubs e
skeletons
• Usaremos como base, as mesmas IDLs do
exemplo StockServer mostrado na parte de
CORBA e do SCS
• Compilar a IDL
• Compilar o código Java das classes geradas pelo
compilador IDL e das classes que implementam
as facetas descritas na IDL
Passo 3: Implementando as facetas do
componente
• O componente StockSeller possui duas
facetas:
• StockServer
• StockExchanger
• As classes StockServerImpl e
StockExchangeImpl implementam,
respectivamente, cada uma dessas facetas.
• Para compartilhar o estado entre as duas
facetas, iremos implementar a classe
StockSellerContextImpl de contexto do
componente.
Implementando o contexto
StockSellerContextImpl
public class StockSellerContextImpl extends ComponentContextImpl {
/** As ações com seus respectivos valores */
private Map<String, Float> myStock;
...
public StockSellerContextImpl(ComponentBuilder builder,
ComponentId componentId) {
super(builder, componentId);
...
}
public synchronized boolean containsStockSymbol(String symbol) {
return myStock.containsKey(symbol);
}
public synchronized float getStockValue(String symbol) {
return myStock.get(symbol);
}
public synchronized String[] getAllSymbols() {
return myStock.keySet().toArray(new String[0]);
}
public synchronized void decrementStockValue(String symbol,
float value) {
float newValue = getStockValue(symbol) - value;
myStock.put(symbol, newValue);
}
Implementando a faceta (Servant)
StockServer
public class StockServerImpl extends StockServerPOA {
private StockSellerContextImpl context;
public StockServerImpl(ComponentContext context) {
this.context = StockSellerContextImpl.class.cast(context);
}
public float getStockValue(String symbol) {
if (context.containsStockSymbol(symbol)) {
return context.getStockValue(symbol);
}
else {
return 0f;
}
}
public String[] getStockSymbols() {
return context.getAllSymbols();
}
public org.omg.CORBA.Object _get_component() {
return context.getIComponent();
}
}
Implementando a faceta (Servant)
StockExchange
public class StockExchangeImpl extends StockExchangePOA {
StockSellerContextImpl context;
public StockExchangeImpl(ComponentContext context) {
this.context = StockSellerContextImpl.class.cast(context);
}
public boolean buyStock(String symbol) {
if (!context.containsStockSymbol(symbol)
|| context.getStockValue(symbol) == 0.0F) {
return false;
}
context.decrementStockValue(symbol, 1);
return true;
}
public org.omg.CORBA.Object _get_component() {
return context.getIComponent();
}
Passo 4: Implementando o Servidor
• O programa servidor se encarrega de:
– inicializar o Openbus
– fazer a conexão por certificado
– criar o componente que implementa as facetas
StockServer e StockExchange
– registrar uma oferta de serviço
– instalar um ShutdownHook para desconectar
com o barramento antes de finalizar a aplicação
– iniciar a execução do ORB
Fluxo principal do servidor
private void run(String[] args) throws StockServerOpenbusException
{
Properties props = loadProperties();
initOpenbus(args, props);
IRegistryService registryService = connectWithOpenBus(props);
ComponentContext context = createComponent(props);
String registrationId = registerServiceOffer(registryService,
context);
Runtime.getRuntime().addShutdownHook(new
ShutdownThread(registrationId));
Openbus.getInstance().getORB().run();
}
public static void main(String[] args) {
StockServerOpenbus demo = new StockServerOpenbus();
try {
demo.run(args);
}
catch (Throwable e) {
e.printStackTrace();
}
}
Inicializar o Openbus
private void initOpenbus(String[] args, Properties props)
throws StockServerOpenbusException {
String host = props.getProperty("host.name");
String portString = props.getProperty("host.port");
int port = Integer.valueOf(portString);
Log.setLogsLevel(Level.WARNING);
Properties orbProps = new Properties();
orbProps.setProperty("org.omg.CORBA.ORBClass",
"org.jacorb.orb.ORB");
orbProps.setProperty("org.omg.CORBA.ORBSingletonClass",
"org.jacorb.orb.ORBSingleton");
Openbus bus = Openbus.getInstance();
try {
bus.init(args, orbProps, host, port);
}
catch (Exception e) {
throw new StockServerOpenbusException(
"Erro durante a inicialização do Openbus.", e);
}
}
Fazer a conexão por certificado
private IRegistryService connectWithOpenBus(Properties props)
throws StockServerOpenbusException {
String entityName = props.getProperty("entity.name");
String privateKeyFile = props.getProperty("private.key");
String acsCertificateFile = props.getProperty("acs.certificate");
try {
RSAPrivateKey privateKey =
CryptoUtils.readPrivateKey(privateKeyFile);
X509Certificate acsCertificate =
CryptoUtils.readCertificate(acsCertificateFile);
Openbus bus = Openbus.getInstance();
IRegistryService registryService =
bus.connect(entityName, privateKey, acsCertificate);
if (registryService == null) {
throw new RSUnavailableException();
}
System.out.println("Stock Server conectado.");
return registryService;
}
catch (Exception e) {
...
}
}
Criar o componente
private ComponentContext createComponent(Properties props)
throws StockServerOpenbusException {
Openbus bus = Openbus.getInstance();
ComponentBuilder builder =
new ComponentBuilder(bus.getRootPOA(), bus.getORB());
ComponentId componentId =
new ComponentId("StockSeller",
(byte) 1, (byte) 0, (byte) 0, "Java");
ComponentContext context =
new StockSellerContextImpl(builder, componentId);
ExtendedFacetDescription[] facetDescriptions =
createFacetDescriptions(props);
ReceptacleDescription[] recDescriptions =
createReceptacleDescriptions();
try {
context = builder.newComponent(facetDescriptions,
recDescriptions, componentId, context);
return context;
}
catch (Exception e) {
...
}
}
Criar o componente - facetas
private ExtendedFacetDescription[]
createFacetDescriptions(Properties props) {
String stockServerFacetClass =
props.getProperty("stockserver.class");
String stockExchageFacetClass =
props.getProperty("stockexchange.class");
ExtendedFacetDescription[] facetDescriptions =
new ExtendedFacetDescription[2];
facetDescriptions[0] =
new ExtendedFacetDescription("StockServer",
StockServerHelper.id(),
stockServerFacetClass);
facetDescriptions[1] =
new ExtendedFacetDescription("StockExchange",
StockExchangeHelper.id(),
stockExchageFacetClass);
return facetDescriptions;
}
Criar o componente - receptáculos
private ReceptacleDescription[] createReceptacleDescriptions() {
ReceptacleDescription[] recDescriptions = new
ReceptacleDescription[1];
recDescriptions[0] =
new ReceptacleDescription("Printer",
ExchangePrinterHelper.id(), false,
null);
return recDescriptions;
}
Registrar a oferta de serviço
private String registerServiceOffer(IRegistryService
registryService,
ComponentContext context) throws StockServerOpenbusException {
org.omg.CORBA.Object obj = context.getIComponent();
IComponent component = IComponentHelper.narrow(obj);
Property registrationProps[] = new Property[0];
ServiceOffer serviceOffer = new ServiceOffer(registrationProps,
component);
try {
String registrationId =
registryService.register(serviceOffer);
System.out.println("Stock Server registrado.");
return registrationId;
}
catch (Exception e) {
throw new StockServerOpenbusException(
"Erro ao registrar a oferta do componente SCS", e);
}
}
Instalar o ShutdownHook
Runtime.getRuntime().addShutdownHook(new
ShutdownThread(registrationId));
...
private static class ShutdownThread extends Thread {
private String registrationId;
ShutdownThread(String registrationId) {
this.registrationId = registrationId;
}
run() {
Openbus bus = Openbus.getInstance();
IRegistryService registryService = bus.getRegistryService();
registryService.unregister(registrationId);
bus.disconnect();
}
}
Iniciar a execução do ORB
Openbus.getInstance().getORB().run();
Passo 5: Implementando o Cliente
• O programa cliente se encarrega de:
– inicializar o Openbus
– fazer a conexão por usuário e senha
Fluxo principal do cliente
private void run(String[] args) throws StockClientOpenbusException
{
Properties props = loadProperties();
Openbus bus = initOpenbus(args, props);
IRegistryService registryService = connectWithOpenBus(props);
StockServer stockServer = getStockServer (registryService);
System.out.println("Ações de mercado obtidas do StockServer:");
// Obtém os símbolos de todas as ações
String[] stockSymbols = stockServer.getStockSymbols();
// Mostra as ações de mercado com seus respectivos valores
for (int i = 0; i < stockSymbols.length; i++) {
System.out.println(stockSymbols[i] + " "
+ stockServer.getStockValue(stockSymbols[i]));
}
StockExchange stockExchange = getStockExchange(registryService);
// Compra uma ação
if (stockSymbols.length > 0) {
String first = stockSymbols[0];
System.out.println("--Compra a ação :" + first);
stockExchange.buyStock(first);
System.out.println("--Ação " + first + " depois da negociação:
"
+ stockServer.getStockValue(first));
}
bus.disconnect();
Conectando com usuário e senha
private IRegistryService connectWithOpenBus(Properties props)
throws StockClientOpenbusException {
String userLogin = props.getProperty("login");
String userPassword = props.getProperty("password");
Openbus bus = Openbus.getInstance();
try {
IRegistryService registryService = bus.connect(userLogin,
userPassword);
if (registryService == null) {
throw new RSUnavailableException();
}
System.out.println("Stock Client conectado.");
return registryService;
}
catch (Exception e) {
throw new StockClientOpenbusException(
"Erro ao fazer a conexão com o Openbus", e);
}
}
Procurando pelas facetas
private StockServer getStockServer(IRegistryService
registryService) {
ServiceOffer[] servicesOffers =
registryService.find(new String[] { "StockServer”});
ServiceOffer serviceOffer = servicesOffers[0];
IComponent component = serviceOffer.member;
org.omg.CORBA.Object stockServerObject =
component.getFacetByName("StockServer");
return StockServerHelper.narrow(stockServerObject);
}
private StockExchange getStockExchange(IRegistryService
registryService) {
ServiceOffer[] servicesOffers =
registryService.find(new String[] { "StockServer" });
ServiceOffer serviceOffer = servicesOffers[0];
IComponent component = serviceOffer.member;
org.omg.CORBA.Object stockExchangeObject =
component.getFacetByName("StockExchange");
return StockExchangeHelper.narrow(stockExchangeObject);
}
Download