Oracle Fusion Middleware: conceitos

Oracle Fusion Middleware (OFM) é uma família de produtos que compreende desde ferramentas de desenvolvimento para a plataforma Java Enterprise Edition (JavaEE), até  soluções para integração de sistemas, gerenciamento de identidade, colaboração e Business Intelligence (BI). O OFM é fornecido e mantido pela empresa Oracle e é composto por uma grande variedade de produtos que oferecem suporte ao desenvolvimento, implantação e gerenciamento de sistemas para a plataforma JavaEE.

De forma bem simplista podemos definir middleware como sendo o software responsável por conectar componentes de software ou aplicações corporativas. Em um sistema multicamadas (ex: três camadas: apresentação, lógica/negócio e dados) o Middleware atua na camada do meio hospedando os componentes com a lógica de negócio da aplicação. Outra função importate do Middleware é fornecer a infraestrutura necessária para o desenvolvimento de aplicações de negócio (business applications). Serviços tais como: acesso concorrente à recursos computacionais, controle transacional, mensageria, segurança, logging etc. Tudo isso é oferecido pelo Middleware de forma, pelo menos em tese, a deixar o desenvolvedor responsável apenas com o que diz respeito ao negócio da aplicação.

A imagem a seguir destaca alguns componentes do OFM em uma visão de divisão em três camadas.

Oracle Fusion Middleware Architecture

Não se preocupe com o significado de cada componente que aparece na imagem acima neste momento. Ao longo do post iremos comentar os principais deles.

Dada uma breve descrição sobre o OFM exponho neste post alguns conceitos importantes para aqueles que pretendem iniciar sua jornada pelo arcabouço de produtos que compõem o Middleware da Oracle.

Hoje em dia instalar um software não é tarefa complicada. Para obter o binário correto basta saber em qual plataforma (arquitetura de hardware e sistema operacional) de destino da instalação e realizar o download no site do fornecedor. Em seguida basta seguir o guia de instalação do produto. Entretanto, para alguns tipos de software, existem alguns aspectos importantes que devem ser observados para evitar problemas futuros. É o caso do Middleware. Uma solução de Middleware geralmente é composta por uma variedade de componentes desenvolvida sob uma arquitetura modular. Essa característica implica uma certa complexidade na gerência do software que vai desde a instalação, operação até a gerência do ambiente.

Middleware Component

O primeiro conceito diz respeito aos tipos de componentes utilizados no OFM. Existem dois tipos:

  • java component: componente composto por uma ou mais aplicações e recursos JavaEE impltantado (deployado) em um domínio do Oracle Weblogic Server. Exemplos:
    • Oracle SOA Suite
    • Oracle Webcenter Portal
    • Oracle Business Intelligence Enterprise Edition
  • system component: serviço (processo) gerenciado pelo Oracle Process Manager and Notification (OPMN) – gerenciador de processos com uma interface de linha de comando (CLI). Exemplos:
    • Oracle Http Server
    • Oracle Web Cache
    • Oracle Internet Directory
    • Oracle Forms
    • Oracle Reports
    • Oracle Business Intelligence

Todo produto da linha OFM é executado sobre um mesmo componente de middleware: o Weblogic Server (WLS). Esta é a “runtime” (não confundir com a Java Virtual Machine – JVM sobre a qual roda o Weblogic) de todo o middleware Oracle. Em praticamente toda a instalação de um produto OFM você encontrará uma estrutura de diretórios contendo os binários do Weblogic.

Após instalar o OFM teremos um ambiente composto por, pelo menos:

  • Um Oracle Weblogic Server Domain, que nada mais é que um conjunto de instâncias de servidores conhecido como Managed Servers, sendo que um deles é utilizado para administração dos demais – o Administration Console. Os managed servers hospedam as aplicações e recursos (java component) JavaEE (EJBs, Data Sources, JMS Destinations, etc).
  • Um ou mais Oracle Instance (system component).
  • Se o componente/produto do OFM (ex: Oracle Business Intelligence ou Oracle SOA Suite) necessitar de um banco de dados de metadados, um database será criado como metadata repository.

Dessa forma é muito importante se familiarizar com a estrutura de diretórios utilizada na instalação do WLS. A imagem abaixo esquematiza a estrutura criada para a instalação do produto Oracle SOA Suite.

Oracle Middleware Home

Middleware Home e Weblogic Home

O Middleware Home é o diretório raiz de qualquer componente/produto (java ou system component) do OFM. Logo abaixo encontra-se o Weblogic Server Home criado durante a instalação do Weblogic. O Weblogic Home hospeda o servidor de aplicação Weblogic.

Weblogic Server Home após a instalação do Weblogic

NOTA: um detalhe importante e que confunde bastante em alguns casos é: em um mesmo Host o diretório Middleware Home deve ser único para uma determinada release do OFM (ex: 11g ou 12c). Outro detalhe é que dentro do Middleware Home só pode haver um Weblogic Server Home. Dessa forma não é possível instalar duas versões diferentes do Weblogic dentro de uma mesma estrutura do Middleware Home. Quando for necessário instalar releases diferentes do OFM em um mesmo Host recomenda-se criar estrutura de diretórios diferentes para cada release (ex: Middleware11g e Middleware12c).

No mesmo nível do Weblogic Server Home encontram-se outros diretórios. Abaixo descrevemos cada um deles.

Oracle Home

Com exceção do Weblogic Server Home, que contém os binários do application server, cada produto OFM é instalado em seu próprio Oracle Home. Este diretório armazena os binários do produto. Dessa forma nenhum processo escreve nele. No diagrama abaixo os binários do Oracle SOA Suite foram instalados dentro do Oracle Home chamado oracle_soa1 (neste caso também referenciado como SOA Oracle Home). Para produtos do tipo java component um weblogic domain também é criado para hospeda a aplicação e recursos JavaEE que compõem o produto.

Oracle Home após a instalação do Oracle SOA Suite

Oracle Home após a instalação do Oracle SOA Suite

Domain Home

Um Weblogic Domain deve ser entendido como um grupo lógico de java components (neste contexto são aplicações e recursos JavaEE). Um domínio é composto por um Administration Server (geralmente referenciado como admin server) e geralmente possui um ou mais Managed Servers (também referenciados como instâncias do weblogic). As aplicações e recursos são implantadas e executadas dentro do(s) Managed Server(s). Na instalação padrão de um produto do OFM a estrutura de diretórios utilizada para hospedar um domínio do weblogic segue o digrama abaixo:

SOA Domain após a instalação do Oracle SOA Suite

SOA Domain após a instalação do Oracle SOA Suite

O domínio não necessariamente deve residir dentro do diretório User Projects na estrutura do Oracle Middleware Home. Observe que a estrutura utilizada para hospedar o domain está fora do Weblogic Home e pode, inclusive, residir fora do Middleware Home (ex: em um storage remoto utilizando um protocolo NFS ou SAN). O diagrama abaixo destaca o domain criado para o Oracle SOA Suite.

É muito comum a instalação de vários produtos OFM em um mesmo ambiente/host. Dessa forma cada produto pode utilizar seu próprio domínio weblogic. O diagrama abaixo destaca dois domains distintos: um para hospedar o Oracle WebCenter e outro para o Oracle SOA Suite. Observe também dois Oracle Homes distintos, um para cada produto OFM.

Estrutura de Weblogic Domains para múltiplos produtos OFM instalados em um mesmo ambiente Oracle Middleware.

Estrutura de Weblogic Domains para múltiplos produtos OFM instalados em um mesmo ambiente Oracle Middleware.

NOTA: todos os produtos instalados dentro de uma estrutura Oracle Middleware Home devem ser compatíveis com a mesma release do OFM utilizada no ambiente em questão. Por exemplo, não seria possível instalar o Oracle WebCenter 12c em um ambiente preparado para o OFM 11g.

Outro aspecto interessante relacionado ao Weblogic Domain é possibilidade de extender (escalar) determinado domínio existente dentro de um host. Durante a criação ou configuração de um domain é possível adicionar novos managed servers, seja para extender um produto ou reutilizar um mesmo domínio. Por exemplo, ao invés de criar um novo domínio para instalar o Oracle WebCenter, poderíamos utilizar o mesmo domain criado para o Oracle SOA Suite. Nesse caso a estrutura de diretórios do OFM em nosso ambiente ficaria conforme a imagem abaixo:

Domínio extendido

Domínio extendido

Oracle Instance

Diferentemente dos diretórios descritos nos tópicos anteriores um diretório Oracle Instance hospeda system components, ou seja, serviços/processos não JavaEE tais como: Oracle Http Server, Oracle Web Cache ou Oracle Internet Directory.

Diferentemente do Oracle Home um diretório Oracle Instance contém arquivos passíveis de alteração (configuração, logs e temporários gerados durante a execução do processo/serviço). Assim como o diretório Weblogic Domain um Oracle Instance pode residir fora da estrutura do Oracle Middleware. O diagrama abaixo destaca um ambiente OFM contendo dois produtos instalados: um system component (WebTier composto por Oracle Http Server e Oracle WebCache) e um java component (Oracle SOA Suite), este último reside em um Weblogic Domain:

OFM com Webtier (system component) e SOA Suite (java compoenent - Weblogic Domain)

OFM com Webtier (system component) e SOA Suite (java compoenent – Weblogic Domain)

Oracle Common Home

Este diretório não está associado à um componente ou produto específico dentro da estrutura Oracle Middleware Home. Ele contém uma variedade de utilitários e bibliotecas utilizadas e necessárias pela solução de gerenciamento e monitoramento do OFM conhecida como Oracle (Enterprise Manager) Fusion Middleware Control e também pelo conjunto de bibliotecas, não incluídas por padrão no Weblogic, Java Required Files (JRF).

NOTA: dentro da estrutura Middleware Home só pode haver um único diretório Oracle Common.

O diagrama abaixo destaca o diretório Oracle Common Home:

Oracle Common Directory

Oracle Common Directory

Oracle Metadata Repository

Alguns produtos do OFM, tais como o Oracle BPEL Process Manager, Oracle Business Activity Monitoring, Oracle Business Intelligence necessitam de um Banco de Dados específicos para armazenar metadados do produto. Um Metadata Repository pode ser de dois tipos: baseado em banco de dados (database-based) ou baseado em um sistema de arquivos (filesystem-based). Embora os dois tipos sejam suportados a Oracle recomenda a utilização de repositórios baseados em Banco de Dados para o ambiente de produção.

Para esses produtos que necessitam de um repositório de metadados é necessário executar o passo de criação do repositório antes de prosseguir com a instalação do produto. Para isso é utilizada uma ferramenta específica: o Repository Creation Utility (RCU). Essa ferramenta cria os schemas de Banco de Dados necessários para o funcionamento do produto.

O diagrama abaixo destaca o Metadata Repository utilizado pelo produto Oracle SOA Suite:

Oracle SOA Suite's metadata repository

Oracle SOA Suite’s metadata repository

Espero com este post ter esclarecido alguns conceitos, geralmente ignorados ou confundidos, durante a instalação ou preparação de um ambiente de execução do Oracle Fusion Middleware. A fonte de referência para os conceitos aqui expostos é a excelente documentação oficial do produto disponível no siste da Oracle.

Nos próximos posts pretendo continuar explorando alguns conceitos específicos do Oracle Weblogic Server.

Abraço ;-)

Weblogic e Java Classloading: parte 1

Neste post descrevo um pouco sobre o modelo de Classloading Java. Na sequência pretendo escrever sobre Classloading no contexto do Oracle Weblogic Application Server. A fonte de referência usada neste post é a excelente documentação oficial do Weblogic [1].

O mecanismo de Classloading é uma “peça” importantíssima dentro da Máquina Virtual Java (JVM). É o mecanismo responsável por encontrar e carregar uma Classe Java na memória da JVM em tempo de execução. Quando uma aplicação referencia uma Classe Java em tempo de execução, é o Classloader (CL) quem localiza e carrega sua definição na Memória Heap. Nesse processo de carga, caso a classe não seja localizada no Classpath ocorre a famosa ClassNotfoundException (dentre outras exceptions associadas à este tipo de problema).

Classloader hierárquico

Por definição a JVM trabalha com uma hierarquia de Classloader (Java Classloader Hierarchy) semelhante ao relacionamento hierárquico entre classes Java (Superclasses e Subclasses). Na raiz dessa hierarquia está o bootstrap classloader – carregado pela JVM e composto por classes internas distribuídas pelas bibliotecas da JDK (classes pertencentes ao pacote java.*) – geralmente localizadas em <JAVA_HOME>/jre/lib/rt.jar.

No segundo nível do CL está o extensions classloader. Neste CL são carregadas as classes localizadas em <JAVA_HOME>/jre/lib/ext. Utilizar este diretório é uma forma de estender o CL padrão do Java. Entretanto as bibliotecas localizadas nesse diretório devem ser autocontidas, ou seja, não podem depender de classes/bibliotecas externas.

Estendendo o “extension classloader” está o system classloader, responsável por carregar classes contidas no classpath utilizado para carregar a JVM. Seguindo a hierarquiva vem o “application classloader“. A partir desse nível são definidos os classloaders específicos da aplicação (por exemplo o classloader carregado pelo Weblogic).

NOTA: No contexto do Weblogic, o termo utilizado pela Oracle para referenciar o classloader utilizado pelo Applciation Server é “system classloader”. Nesse mesmo contxto o temo “application classloader” refere-se às bibliotecas e aplicações Java Enterprise Edition (JavaEE).

A imagem abaixo [2] mostra a hierarquia padrão do modelo de classloader do Java.

clhierarchy

Carregamento (loading) de classes

De acordo com o artigo “Demystifying class loading problems, Part 1: An introduction to class loading and debugging tools” [2] publicado no site IBM developerWorks, o processo de carregamento de uma Classe Java pode ser separado em três momentos distintos: loading, linking e initializing.

A imagem abaixo [2] mostra o processo de class loading de uma Classe Java.

cl phases

Primeiro (loading phase) o arquivo (.class) binário da classe é localizado (dentro da lista de classes/bibliotecas informada no classpath usado pela JVM) e carregado no Bytecode. O processo de loading define, internamente na JVM, uma estrutura básica para que a classe seja carregada em memória.

No segundo momento o processo de linking realiza três passos adicionais:

  • Bytecode verification: neste passo o classloader se certifica de que o bytecode da classe está ok.
  • Class preparation: neste passo a estrutura necessária para acomodar a definição da classe (métodos, campos, interfaces implementadas, etc) é preparada.
  • Resolving: neste passo o classloader carrega todas as dependências referenciadas pela classe em questão. Pode-se entender como a montagem do grafo de dependências referenciadas por: hierarquia de classes pais (superclasses), interfaces, campos, assinatura de métodos, etc.

No terceiro e último momento (initializing) o conteúdo estático (static fields, static blocks, etc) da classe é inicializado.

Após esse processo a Classe é considerada como carregada e pode ser utilizada pela aplicação.

Modelo de Delegação (delegation model)

Outro aspecto importante relacionado ao Classloader é o modelo utilizado para carregamento de uma classe. Antes de falar sobre o modelo de delegação em si vale a pena comentar um pouco sobre o “disparo” de carregamento de uma Classe Java. Existe basicamente duas formas de iniciar (disparar/delegar) o carregamento de uma classe: carregamento explícito e carregamento implícito.

Na primeira forma a classe é carregada explicitamente usando as seguintes chamadas no código Java:

 cl.loadClass("com.mycompany.MyClass");  //cl é uma instância de java.lang.ClassLoader
 Class.forName("com.mycompany.MyClass"); //o classloader pais neste caso é o mesmo usado para carregar a classe na qual a chamada à Class.forName() está sendo realizada.

Quando uma dessas chamadas é realizada de forma explícita ocorre o seguinte: se a classe referenciada já estiver sido carregada anteriormente, uma referência à esta classe é retornada. Caso contrário o CL utiliza o modelo de delegação para carregar a classe.

Na segunda forma a classe é carregada por referência, ou seja, quando ela é referenciada por outra classe carregada em um momento distinto (conforme descrito no passo ‘Resolving‘ da fase ‘Linking‘ do processo de classloading descrito no tópico anterior). Assim como no carregamento implícito, caso a classe já tenha sido carregada, uma referência à ela é retornada. Caso contraário o carregamento realizado usando o modelo de delegação.

No modelo de delegação a implementação do classloader faz uma checagem inicial para verificar se a classe solicitada já foi carregada e reside no cache. Essa checagem melhora a performance de carregamento, pois caso a classe já esteja no cache, não será necessário carregá-la novamente do disco. Se a classe não for encontrada no cache o CL atual primeiro solicita a classe ao seu pai (superior imediato na hierarquia). Somente se a classe não puder ser carregada pelo CL pai o CL em questão (filho) tenta carregar a classe. Caso a classe solicitada seja encontrada nos dois CLs (pai e filho), a versão encontrada no CL pai é carregada.

Este modelo de delegação é utilizado para evitar que existam múltiplas cópias de uma mesma classe sejam carregadas. Múltiplas cópias de uma mesma classe podem ocosionar problemas de conflito de classes gerando exception como a famosa ClassCastException. Para mais detalhes sobre os diferentes problemas ocasionados devido ao conflito de classes em um classloader consulte o artigo “Demystifying class loading problems, Part 2: Basic class loading exceptions” [3]. Nesse artigo o autor explica as diferentes exceptions geralmente relaciodas ao conflito de classes em classloaders.

O ponto a ser destacado no modelo de delegação utilizado pelo Java Classloader é:

Um classloader filho (ex: application classloader) solicita a classe primeiro ao seu pai antes de tentar localizar e carregar por conta própria.

Por exemplo: Quando uma classe da sua aplicação (carregada pelo CL da aplicação) referencia uma classe fornecida pelo JDK (ex: java.lang.String), o carregamento é delegado pelo boostrap/root classloader (que de fato carregou as classes contidas em JAVA_HOME/jre/lib/rt.jar).

___
[1] http://docs.tpu.ru/docs/oracle/en/fmw/11.1.1.6.0/web.1111/e13706/classloading.htm
[2] http://www.ibm.com/developerworks/java/library/j-dclp1/
[3] http://www.ibm.com/developerworks/java/library/j-dclp2/

Onde obter versões antigas do Java (JDK e JRE)

A plataforma Java é uma tecnologia bastante madura e bem antiga. De acordo com a página Java Version History no Wikipedia a primeira release (1.0) do Java Development Kit (JDK) data de Janeiro de 1996. Com uma trajetória tão longa e com sucesso comprovado no mercado corporativo não é raro nos depararmos com projetos em plena execução em versões antigas dessa plataforma.

“Volta e meia” precisamos baixar uma versão antiga da JVM para realizar testes ou preparar um ambiente semelhante ao atual ambiente de execução do projeto. Mas, onde podemos obter versões oficiais e específicas do Java (JVM, JRE, bibliotecas, etc)? As versões mais antigas eram mantidas pelo “falecida” Sun Microsystems. Bem, existe uma página que faço questão de manter em meus Favoritos. Trata-se da página “Oracle Java Archive“. Nela é possível obter todas as versões antigas da plataforma Java Standard/Enterprise Edition, inclusive bibliotecas depreciadas.

oraclejavaarchive

Ninguém gosta de lidar com velharia. Mas pra quem lida com consultoria em plataformas “maduras” como o Java isso é quase inevitável.

Abraço.

Root login no Oracle Solaris 11

Recentemente criei uma máquina virtual x86 para rodar o Oracle Solaris 11 usando o VirtualBox. A ideia é utilizar essa VM como ambiente de prova de conceito para produtos da linha Oracle Fusion Middleware. Como todo sistema Unix-like o Solaris possui algumas restrições de segurança que impossibilita o acesso de root via SSH. Minha primeira tentativa foi editar a configuração do serviço sshd e habilitar a flag ‘PermitRootLogin’. Entretanto, isso não basta para que o login de root funcione no Solaris.

Após algumas “googladas” descobri que é necessário realizar os seguintes ajustes na configuração do S.O:

  • Habilitar o login de root no serviço sshd. Edite o arquivo /etc/ssh/sshd_config
# Are root logins permitted using sshd.
# Note that sshd uses pam_authenticate(3PAM) so the root (or any other) user
# maybe denied access by a PAM module regardless of this setting.
# Valid options are yes, without-password, no.
PermitRootLogin yes
  • Comentar a propriedade ‘CONSOLE’ no arquivo /etc/default/login
# If CONSOLE is set, root can only login on that device.
# If the specified device is /dev/console, then root can also log into
# any of the currently enabled /dev/vt/# virtual terminal devices.
# Comment this line out to allow remote login by root.
#
#CONSOLE=/dev/console
  • Editar a configuração do módulo PAM. Edite o arquivo /etc/pam.conf

Adicione a seguinte linha no fim do arquivo:

sshd-kbdint   account   required   pam_unix_account.so.1

Adicionado em 18/01/2013.

  • Para permitir o login de root pela console/shell da própria máquina é necessário alterar a role na qual o root está associado. Execute o seguinte comando como root.
root@solaris11:~# rolemod -K type=normal root
Found user in files repository.
UX: rolemod: root is currently logged in, some changes may not take effect until next login.

Agora tente executar o login como root pela console da máquina/VM (sem ser via ssh).

obs: obviamente, por questões de segurança, essa configuração não é interessante em ambiente de produção.

;-)

TDC 2012: slides e demo da palestra

Na edição Goiânia que acontenceu nos dias 20 e 21 de Outubro participei da trilha Java com a paelstra “Aumentando a eficiência do web container com chamadas assíncronas“.

Após um longo tempo finalmente tive tempo de disponibilizar a demo no github.

Os slides estão disponíveis no slideshare.

 

O projeto usado na demo está disponível no Github no repositório TDC2012-asyncservlets.

Abraço.

Bash Script: substituindo um texto em vários arquivos

Neste post quero compartilhar um bash script que criei para um necessidade bastante comum em ambientes Unix Like.

Necessidade:

“alterar um texto em vários arquivos de uma única vez”

Situação hipotética:

“vários arquivos texto (xml, properties, txt etc) espalhados dentro de um diretório raiz contendo um determinado termo (palavra, path de arquivo, propriedade etc)”

Esse tipo de situação é bastante comum no dia a dia de um administrador de sistemas e servidores. A abordagem da utilização de um script para automatizar esse tipode tarefa é bastante utilizada em ambientes baseados em Unix que possuam um shell com suporte a qualquer linguagem de script (bash, ksh, python, ruby etc).

No meu caso implementei um script bash para execução em sistemas Linux. Minha necessidade inicial foi alterar o caminho da instalação do Oracle Weblogic Application Server – WLS. A instalação do WLS escreve o caminho do diretório raiz da instalação em vários arquivos de configuração (arquivos .properties e .xml) e scripts de gerenciamento (arquivos .sh) espalhados por toda a sua estrutura de diretórios. Caso seja necessário alterar o caminho raiz da instalação do WLS, você tem duas alternativas: 1) instalar novamente o WLS; 2) alterar o path da instalação em todos os arquivos de configuração.

No meu caso meu WLS foi instalado em ‘/opt/Oracle/Middleware‘, porém precisei mudar o caminho raiz para ‘/opt/Oracle/Middlware11g.

Pois bem, meu scritpt recebe como entrada os seguintes parâmetros:

  1. path: diretório raiz onde os arqivos se encontram
  2. file pattern name: nome do arquivo a ser alterado (geralmente um coringa ‘*.’)
  3. old text: texto a ser alterado
  4. new text: novo texto

Quando executar o script sem parâmetros um pequeno help será exibido sugerindo um exemplo de uso.

# ~/replaceText.sh
invalid call!
 usage: ./replaceText <path> <file pattern name> <old text> <new text>
NOTES:
 1) don't use the pattern '*', instead specify a file extension (eg: '*.sh', '*.txt', '*.properties', '*.xml')
 2) for text containing special chars you have to scape them with '\'
eg: ./replaceText "/opt/Oracle/Middleware" "*.xml" "Oracle\/Middleware\/" "Oracle\/Middleware11g\/"

Ao executar o script com todos os parâmetros o diretório raiz (primeiro argumento) será percorrido e, para cada arquivo encontrado (obedecendo o padrão informado no segundo argumento), será necessário confirmar a alteração.

# ~/replaceText.sh /opt/Oracle/Middleware/ "*.properties" "Oracle\/Middleware\/" "Oracle\/Middleware11g\/"
 alterar o arquivo: /opt/Oracle/Middleware/user_projects/domains/cluster-replicated-domain/init-info/tokenValue.properties
 deseja continuar? ([S]im/[n]ao/[t]odos) S
 substituir [Oracle\/Middleware\/] por [Oracle\/Middleware11g\/]
 diff /opt/Oracle/Middleware/user_projects/domains/cluster-replicated-domain/init-info/tokenValue.properties /opt/Oracle/Middleware/user_projects/domains/cluster-replicated-domain/init-info/tokenValue.properties.BAK
 ----------------------------------------
 21c21
 < @DOMAIN_HOME=/opt/Oracle/Middleware11g/user_projects/domains/cluster-replicated-domain
 ---
 > @DOMAIN_HOME=/opt/Oracle/Middleware/user_projects/domains/cluster-replicated-domain
 24c24
 < @USERDOMAIN_HOME=/opt/Oracle/Middleware11g/user_projects/domains/cluster-replicated-domain
 ---
 > @USERDOMAIN_HOME=/opt/Oracle/Middleware/user_projects/domains/cluster-replicated-domain
 ----------------------------------------

No exemplo acima alterei todos os arquivos de propriedades (*.properties). Observe que existe a opção de alterar todos os arquivos encontrados de uma única vez. Basta selecionar a opção [a]ll quando for solicitada a confirmação. Observe também que o script faz um backup de todos os arquivos alterados (.BAK).

Ok. Após todo esse bla bla bla o código do script:

#!/bin/bash

DIR_PATH=$1
FILE_SEARCH_PATTERN=$2
OLD_STRING=$3
NEW_STRING=$4

LAST_REPLY="S"

askToContinue(){
   if [[ ! $LAST_REPLY =~ ^[Aa]$  ]]
   then
      read -p "continue? ([Y]es/[n]o/[A]ll) " -n1
      echo

      LAST_REPLY=$REPLY
      if [[ ! $REPLY =~ ^[Yy]$ ]]
      then
         continue
      fi
   fi
}

usage(){
   echo
   echo -e "\r invalid call!"
   echo -e "   usage: ./replaceText    "
   echo
   echo -e "\r NOTES:"
   echo -e "\r\t 1) don't use the pattern '*', instead specify a file extension (eg: '*.sh', '*.txt', '*.properties', '*.xml')"
   echo -e "\r\t 2) for text containing special chars you have to scape them with '\'"
   echo
   echo -e "   eg: ./replaceText \"/opt/Oracle/Middleware\" \"*.xml\" \"Oracle\\/Middleware\\/\" \"Oracle\\/Middleware11g\\/\""
   echo
   exit
}

[[ ! "$#" = "4" ]] && usage

for file_name in `find "$DIR_PATH" -type f -name "$FILE_SEARCH_PATTERN"`
do
  #Testa se o arquivo contem o texto a ser substituido
  file $file_name | grep -i "text" > /dev/null
  [[ "$?" -eq "1"  ]] && continue
  grep $OLD_STRING $file_name > /dev/null
  [[ "$?" -eq "1"  ]] && continue

  echo -e "\r\r\r changes the file: $file_name \r"
  askToContinue

  echo -e "\t replace [$OLD_STRING] by [$NEW_STRING] \r"

  if [ -d $DIR_PATH  ];
  then
     sed -i.BAK -e "s/${OLD_STRING}/${NEW_STRING}/g" $file_name

     echo -e "\t\t diff $file_name $file_name.BAK"
     echo -e "\r ----------------------------------------"
     diff $file_name $file_name.BAK
     echo -e "\r ----------------------------------------"
  else
     echo -e "\r $PATH_DIR does not exists!"
     exit
  fi

done

Eu usei o script sem problemas em um Linux Fedora (Linux Red Hat based). Mas creio que funcionará sem grandes problemas em qualquer Unix com um shell Bash.

Abraço ;-)

TDC 2012: the developers conference

 The Developers Conference 2012, um evento organizado pela Globalcode

Este ano tive a honra de ter uma palestra aceita no evento The Developers Conference (edição Goiânia). O TDC é um dos maiores eventos de software do país. O evento reune anualmente desenvolvedores das principais plataformas e tecnologias do mundo do software. É uma verdadeira mistura de tribos tecnologicas. São várias trilhas com debates e palestras de altíssima qualidade disponíveis para todos os interesses e gostos. As trilhas acontencem simultâneamente durante o evento.

Na edição Goiânia que acontence dias 20 e 21 de Outubro participarei da trilha Java com a paelstra “Aumentando a eficiência do web container com chamadas assíncronas“.

Se você ainda não fez a sua inscrição corra e não perca a oportunidade de ficar por dentro das novidades no mundo do software e aproveite para fazer um ótimo social network durante o evento.

Seguir

Obtenha todo post novo entregue na sua caixa de entrada.

Junte-se a 209 outros seguidores