Skip to content

igor-franca/OSGI

Repository files navigation

Osgi guide

ReadMe escrito sintetizando conteúdos presentes em:

Brian Chan: Liferat Basic Training OSGI.

Quitumba:YouTube Playlist.

Open Service Getway initiative

É uma especificação que produzir um sistema dinâmico de componentes Java, com o objetivo de reduzir a complexidade de um software através de uma arquitetura modular orientada a serviços.

Bundles

São modulos que possuem identificadores únicos (Manifesto) com cabeçalhos específicos (válidos) e devem ser armazenados em um arquivo JAR. Podemos dizer que o Bundle é a unidade básica de modularidade.

Na identificação do bundle temos dois cabeçalhos específicos no manifesto que são utilizados para identificar um Bundles, são eles:

  • Bundle-SymbolicName
  • Bundle-Version

Versionamento Semântico

This is a alt text.

Intervalo de versão

Exemplo: version= [ 1.2, 2.0 )

Nesse caso estamos informando que as versões que devem ser utilizadas pelo meu Bundles está entre 1.2 e inevitavelmente antes da 2.0 (existem funcionalidades incompatíveis com as versões anteriores na versão 2.0)

Ou seja, se observarmos bem. Utilizamos o colchete para incluir versões e o parenteses para excluir versões incompatíveis

Ciclo de vida de um Bundle

Um Bundle inevitavelmente possui 6 estados, sendo eles:

  1. Installed
  2. Resolved
  3. Starting
  4. Active
  5. Stopping
  6. Uninstalled

This is a alt text.

Podemos gerenciar o ciclo de vida de um Bundle usando linha de comando. Utilizando o Gogo Shell que é um recurso que permite acessar o container OSGI utilizando o Telnet.

Uma vez presente no Gogo Shell podemos utilizar alguns comandos para gerenciar o bundle como:

  1. install caminho/para/bundle/nomeBundle.jar

Após o bundle ser instalado será gerado bundle ID, esse ID pode ser utilizado na execução dos outros comandos que gerenciam o estado de um bundle.

  1. uninstall bundleId
  2. resolve bundleId
  3. update bundleId
  4. refresh bundleId
  5. start bundleId
  6. stop bundleId

Componente

Componente é um objeto que possui uma funcionalidade específica. Exemplo: Serviço, Servelet, Portlet e Comandos.

Qualquer classe dentro de um Bundle pode ser declarada como um componente.

Component é um objeto gerenciado pelo OSGI e possui um ciclo de vida, assim como o bundle.

O componente ficará dentro do Bundle e o Container OSGI cuidará dos dois.

A vantagem de utilizar uma classe como um componente é que elas podem ser publicadas como serviços e estar disponíveis para outros componentes. Além disso, possui um ciclo de vida independente e reutilizado, podendo possuir propriedades e ativação.

O @component é usado para registrar um componente dentro do registro de serviços.

Serviço

O serviço é um componente registrado pelo Service Registry no container do OSGI.

O bundle pode declarar as funcionalidades que ele fornece como serviço OSGI.

Além disso, o bundle pode pedir por funcionalidades específicas nos serviços OSGI.

O Service Registry funciona como uma distribuidora que recebe serviços exportados pelos Bundles e envia serviços para os Bundles que estão solicitando.

Declarative Services - DS

É um Framework de ingestão de dependência OSGI, permite declarar e consumir serviços via XML e anotações. Inicializa a classe, injeta as dependências, ativa os componentes e registra os serviços.

O @reference é utilizado para solicitar ao registro de serviço uma referência de um componente específico.

Construindo um projeto OSGI

This is a alt text.

Inicialmente criamos um diretório que irá conter nosso projeto.

Em seguida, criamos o arquivo settings.gradle

buildscript {
	dependencies {
		classpath group: "com.liferay", name: "com.liferay.gradle.plugins.workspace", version: "latest.release"
	}

	repositories {
		mavenLocal()

		maven {
			url "https://repository-cdn.liferay.com/nexus/content/groups/public"
		}
	}
}

apply plugin: "com.liferay.workspace"

As informações presentes em settings.gradle são responsáveis por criar o com.liferay.workspace Gradle Plugin

Em seguida é criado o arquivo gradle.properties que seleciona uma versão específica do Portal

gradle.properties

liferay.workspace.product=portal-7.3-ga7

Criando o primeiro modulo(Bundle)

Inicialmente criamos uma estrutura de pasta.

 mkdir -p basic-training-able-impl/src/main/java/com/liferay/basic/training/able/internal/activator

Posteriormente criamos um arquivo .java, no diretório recém criado activate, nomeado de AbleBundleActivator e adicionamos as seguintes informações:

package com.liferay.basic.training.able.internal.activator;

public class AbleBundleActivator {

	public AbleBundleActivator() {
		System.out.println("Constructing AbleBundleActivator");
	}

}

Porém ao tentarmos compilar nosso programa:

./gradlew classes

Iremos perceber que as features Gradle utilizadas nesse Build estão depreciadas, mas o comando foi executado com sucesso.

Porém o diretório de compilação build não foi criado.

Ainda em nosso diretório activator devemos criar um arquivo de configuração com os metadados básicos necessários para os módulos OSGI.

code basic-training-able-impl/bnd.bnd
Bundle-Name: Liferay Basic Training Able Implementation
Bundle-SymbolicName: com.liferay.basic.training.able.impl
Bundle-Version: 1.0.0

Em seguida, iremos criar um arquivo build.gradle

touch basic-training-able-impl/build.gradle

Um arquivo build.gradle informa ao Liferay Workspace que esse diretório é um módulo Java.

Finalmente, ao tentarmos compilar novamente nosso programa:

./gradlew classes

Iremos perceber que um novo diretório (build) se encontra em basic-training-able-impl.

Agora podemos deployar nosso modulo:

./gradlew deploy

Entretanto nosso novo módulo com.liferay.basic.training.able.impl.jar ainda não pode ser lido pela Liferay(Ainda não enviamos nosso arquivo para iamgem Docker).

Podemos levantar uma imagem Docker da Liferay para constatar:

d run --name ephesians-liferay --rm -it -p 8080:8080 liferay/portal:7.3.6-ga7

O name informa o nome do nosso container Docker e o --rm configura o container para ser removido após a finalização do mesmo, não tendo suas informações persistidas.

Se analizarmos os módulos dentro da imagem Docker em opt/liferay/osgi/modules:

d exec -it ephesians-liferay /bin/ls /opt/liferay/osgi/modules

Iremos receber como retorno uma pasta vazia.

Agora iremos enviar nosso novo módulo recém deployado para o caminho opt/liferay/osgi/modules dentro da imagem Docker:

d cp bundles/osgi/modules/com.liferay.basic.training.able.impl.jar ephesians-liferay:/opt/liferay/osgi/modules

E se executarmos outro ls dentro do Docker:

d exec -it ephesians-liferay /bin/ls /opt/liferay/osgi/modules

Iremos receber como resposta:

com.liferay.basic.training.able.impl.jar

Porém, existe uma maneira de Deployar nosso arquivo jar e já envia-lo para o nosso caminho /opt/liferay/osgi/modules substituindo o nosso ./gradlew deploy + docker cp...:

./gradlew deploy -Ddeploy.docker.container.id=ephesians-liferay

Se executarmos novamente o ls no diretório de módulos do Docker podemos perceber que iremos receber como retorno:

com.liferay.basic.training.able.impl.jar
com.liferay.basic.training.able.impl-1.0.0.jar

Em seguida finalizamos a execução do nosso container docker e inicializamos novamente. Com isso, será gerada outra imagem totalmente dissociada da imagem anterior.

Podemos repetir o processo com a nova imagem Docker:

d run --name ephesians-liferay --rm -it -p 8080:8080 liferay/portal:7.3.6-ga7
./gradlew deploy -Ddeploy.docker.container.id=ephesians-liferay

E verificarmos que o arquivo deployado já consta no nosso Docker:

d exec -it ephesians-liferay /bin/ls /opt/liferay/osgi/modules

Retorno:

com.liferay.basic.training.able.impl-1.0.0.jar

E por fim, se precisarmos atualizar o módulo deployado:

 ./gradlew clean deploy -Ddeploy.docker.container.id=ephesians-liferay

Esse comando irá deletar os objetos buildados antes de deployar novamente, forcando o Gradle a ser recompilado.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages