Antes mesmo de escrever um livro sobre Administração do WebSphere Application Server Usando Jython, percebi que existem muito poucos exemplos descrevendo o que deve ser feito para criar um script completo. Portanto, pensei que poderia ser útil para os criadores de scripts wsadmin descrever o processo que usei muitas vezes para criar esses scripts.
Em geral, estas são as etapas de alto nível que devem ser seguidas para criar um script wsadmin a partir de zero:
- Decida que tarefa administrativa você deseja executar.
- Consulte a documentação para aprender mais sobre a tarefa e os diferentes métodos que podem ser usados.
- Identifique os parâmetros do método e compreenda como usá-los.
- Use uma sessão wsadmin interativa para verificar e fazer experiências com o método, sua utilização e seus valores de parâmetro.
- Usando um modelo de script, determine a melhor técnica para fornecer valores de parâmetro do método ao script (por exemplo, em um arquivo de propriedades ou por meio de parâmetros de linha de comando).
- Adicione o código de processamento de parâmetros e informações sobre o seu uso ao script.
- Adicione código para executar o(s) método(s) do script que efetivamente realizarão a tarefa desejada.
Para fins de demonstração, este artigo descreve as etapas que seriam executadas para construir um script que permite criar membros de cluster. Trata-se de uma tarefa relativamente simples, mas, como na maioria das tarefas, pode haver fatores que a tornem mais complicada. Por exemplo, o script deve ser capaz de criar apenas um membro de cluster ou você também quer ter a possibilidade de usá-lo para criar mais de um membro de cada vez?
Seguindo as etapas descritas neste artigo, você começará de maneira simples para criar, ao final, um script que permite criar um único membro de cluster.
Este artigo é aplicável ao IBM WebSphere Application Server V7.0 e V6.1.
Inicialmente, a ideia é localizar informações sobre a tarefa em que você interessado para compreender o processo e os parâmetros envolvidos. Isso lhe permitirá criar um script que execute a tarefa de maneira adequada e eficiente.
Por exemplo, usando um navegador da Web, navegue até o Centro de Informações do IBM WebSphere Application Server V7 Network Deployment e procure pela frase create cluster member. O resultado é animador, porque itens com o título Creating cluster members using scripting são exibidos na parte superior dos resultados da pesquisa. Selecione o primeiro link para exibir a documentação relacionada:
- A seção Before you begin explica que há várias abordagens que podem ser utilizadas para executar essa tarefa. Por exemplo, para criar novos membros de cluster, é possível:
- Usar o objeto de criação de scripts AdminConfig.
- Usar o grupo de comandos ClusterConfigCommands no objeto de criação de scripts AdminTask.
- Usar o método createClusterMember na biblioteca de scripts AdminClusterManagement.
- Adicionalmente, a seção About this task aponta algumas questões interessantes, como:
- Quão genérico você quer (ou precisa) que o script seja?
- O script deverá ser capaz de criar o primeiro membro de um cluster, apenas os membros subsequentes do cluster ou ambos?
- O cluster já deverá existir para que o script tenha êxito ou você quer (ou precisa) que o script seja capaz de criar um novo cluster como parte do processo?
Examinaremos cada uma dessas abordagens antes de decidir como prosseguir.
Usando o objeto de criação de scripts AdminConfig
Como está claro que algum tipo de objeto de criação de scripts AdminConfig será usado para essa tarefa, é uma boa ideia começar procurando informações sobre ele no Centro de Informações.
A busca por AdminConfig produz vários resultados, inclusive um no início da lista de resultados chamado Commands for the AdminConfig object using wsadmin scripting. A leitura desse item revela que existe um método createClusterMember no objeto de criação de scripts AdminConfig. Uma leitura mais atenta revela que esse método tem alguns parâmetros obrigatórios. Examine os exemplos fornecidos mais adiante na página para compreender melhor como eles são usados. Curiosamente, a lista de parâmetros obrigatórios (mostrada na Tabela 1) não corresponde ao código de exemplo.
Tabela 1. Parâmetros obrigatórios de AdminConfig.createClusterMember()
| Nome do parâmetro | Descrição |
|---|---|
| clusterID | ID de configuração do cluster ao qual o membro deverá ser adicionado. |
| nodeID | ID de configuração do nó em que o membro deverá ser criado. |
| memberAttributes | Especifica os atributos que serão usados para criar o novo membro. |
| templateID | ID de configuração do modelo a ser usado pelo processo de criação de membro. |
Como o parâmetro templateID pode ser deixado fora do código de exemplo se é realmente obrigatório? Na verdade, o parâmetro templateID só é permitido para o primeiro membro do cluster. A criação de membros subsequentes do cluster usa o primeiro membro como modelo.
Para criar um membro de cluster, porém, primeiramente você terá que criar um cluster, bem como o primeiro membro do cluster. Para ajudá-lo a fazer isso, você pode usar estes scripts, que estão incluídos nos materiais para download que acompanham este artigo (e que foram criados usando as técnicas descritas aqui):
- createCluster.py: Cria um cluster vazio.
- createFirstClusterMember.py: Cria o primeiro membro do cluster usando um modelo cujo nome é especificado pelo usuário.
Agora usaremos uma sessão wsadmin interativa para ver quais etapas serão necessárias para criar um novo membro do cluster usando o método AdminConfig.createClusterMember(). A Listagem 1 mostra essa sessão interativa e a Tabela 2 explica a sessão em detalhes.
Listagem 1. Usando AdminConfig.createClusterMember()
1|[root@ragdoll bin]#./wsadmin.sh -lang jython
2|WASX7209I: Connected to process "dmgr" on node ragdollCellManager02 using SOAP
3|connector; The type of process is: DeploymentManager
4|WASX7031I: For help, enter: "print Help.help()"
5|
6|wsadmin>print AdminConfig.list( 'ClusterMember' )
7|Member1(cells/ragdollCell02/clusters/Cluster1|cluster.xml#ClusterMember_1261105354124)
8|
9|wsadmin>clusterID = AdminConfig.getid('/ServerCluster:Cluster1/' )
10|wsadmin>nodeID = AdminConfig.getid( '/Node:ragdollNode03/' );
11|wsadmin>memberID = AdminConfig.createClusterMember(clusterID, nodeID, '[[memberName
Member2]]' )
12|wsadmin>print AdminConfig.list( 'ClusterMember' )
13|Member1(cells/ragdollCell02/clusters/Cluster1|cluster.xml#ClusterMember_1261105354124)
14|Member2(cells/ragdollCell02/clusters/Cluster1|cluster.xml#ClusterMember_1261145939139)
|
Tabela 2. Explicação do uso de AdminConfig.createClusterMember()
| Linha(s) | Comentários |
|---|---|
| 1 | Inicia o wsadmin e especifica a linguagem como Jython. |
| 2-4 | Informações geradas por wsadmin mostrando que ocorreu uma conexão bem-sucedida com um gerenciador de implementação. |
| 5 | Uma linha em branco adicionada para facilitar a leitura. |
| 6-7 | Chamada de AdminConfig.list() para mostrar os IDs de configuração dos membros existentes no cluster. |
| 8 | Uma linha em branco adicionada para facilitar a leitura. |
| 9-10 | Instruções de designação usadas para obter os IDs de configuração do cluster ao qual o membro deverá ser adicionado e do nó em que o membro deverá ser criado. |
| 11 | Chamada do método AdminConfig.createClusterMember() para criar o novo membro do cluster. |
| 12-13 | Chamada de AdminConfig.list() para comprovar a existência do membro recém-criado no cluster (Member2). |
Aqui está o que um script precisaria fazer para criar um único membro do cluster usando essa técnica:
- Verificar os parâmetros de linha de comando.
- Consultar o ID de configuração do cluster, tendo recebido o parâmetro de linha de comando clusterName. (O script deverá solicitar ao usuário que especifique os nomes do cluster e do nó, mas não seus IDs de configuração.)
- Consultar o ID de configuração do nó, tendo recebido o parâmetro de linha de comando nodeName.
- Talvez verificar se o memberName especificado já não existe no cluster.
- Executar o método createClusterMember para realizar a ação desejada.
- Verificar o êxito ou falha da solicitação.
Evidentemente, esta é apenas uma descrição aproximada do processo, mas poderá lhe dar uma ideia do tipo de codificação necessária para usar essa técnica específica. Porém, antes de investir tempo e esforço implementando um script que use essa abordagem, examinaremos as alternativas para ver no que diferem e se uma delas pode ser mais fácil de implementar que as demais.
Usando o objeto de criação de scripts AdminTask
Pesquise novamente o Centro de Informações, desta vez procurando pelo termo AdminTask. Com mais de 200 resultados, você terá que rolar a tela para baixo até encontrar um item chamado ClusterConfigCommands command group for the AdminTask object. Esse item fornece um link para o método createClusterMember, que é descrito mais adiante na página. Esta seção o ajudará a compreender melhor o uso desse método:
- Para criar o membro do cluster, há duas alternativas:
- Especificar o nome de um modelo de servidor de aplicativos (se especificar o nome de modelo, você não precisará consultar o ID de configuração, porque o objeto de criação de scripts AdminTask fará isso para você).
- Especificar um servidor de aplicativos existente que deva ser usado como modelo.
- Você pode especificar um destes dois itens:
- O nome do cluster.
- O ID de configuração do cluster ao qual o membro deverá ser adicionado.
- É possível ter membros de cluster em diferentes versões do WebSphere Application Server (V6.1 e V7.0), mas esse cenário está além do escopo deste artigo.
Para certificar-se de que sua comparação de diferentes abordagens é válida, verifique se a tarefa real que está sendo comparada é a mesma em todas as abordagens; no caso, a tarefa seria criar um script que lhe permita criar membros adicionais em um cluster. Isso significa que você pode ignorar os parâmetros relacionados ao modelo e concentrar-se apenas nos parâmetros relacionados à criação dos membros subsequentes do cluster.
Se pretende usar métodos de objeto de criação de scripts em seu script de criação de membros de cluster, você terá que compreender os parâmetros disponíveis. Como a documentação a esse respeito pode ser confusa, tente usar sessões wsadmin interativas para obter uma melhor compreensão.
Uma as características realmente poderosas e úteis do objeto de criação de scripts AdminTask é que praticamente todos os métodos incluem uma maneira de "avançar passo a passo" pelas definições de parâmetros. Isso é feito chamando o método e especificando -interactive como o único parâmetro. Use essa técnica agora para perceber a diferença entre o uso do ID de configuração do cluster e o nome do cluster no que concerne ao método createClusterMember().
Comece chamando o método, como é mostrado na Linha 1 da Listagem 2a. (Devido ao número de linhas geradas, essa sessão wsadmin é dividida aqui em várias Listagens, 2a a 2e.)
Listagem 2a. Criação interativa do membro do cluster
1|wsadmin>M1 = AdminTask.createClusterMember( '-interactive' )
2|Create Cluster Member
3|
4|Creates a new member of an application server cluster.
5|
6|Cluster Object ID: Cluster1(cells/ragdollCell02/clusters/Cluster1|cluster.xml#Server
Cluster_1261065198076)
|
O resultado da chamada interativa é atribuído a uma variável (Listagem 2a, Linha 1) porque, quando a especificação interativa de parâmetros estiver concluída, a chamada resultante de AdminTask.createClusterMember() será a chamada real que você desejará fazer, incluindo todos os parâmetros que venham a ser especificados. O resultado da chamada será o ID de configuração do membro do cluster que acabou de ser criado.
Na linha 6, o objeto de criação de scripts AdminTask solicita informações, informando que está buscando o valor de Cluster Object ID (ou seja, o ID de configuração do cluster ao qual um novo membro está sendo adicionado). Como você deseja descobrir qual será a aparência desse comando quando especificar um ID de configuração, copie e cole o ID de configuração completo do cluster em resposta a esse prompt. (Se um ID de configuração inválido ou desconhecido for especificado, ocorrerá uma exceção e o controle retornará ao prompt wsadmin>. Como a técnica interativa com AdminTask não suporta ou permite o uso de nomes de variáveis, valores como o ID de configuração mostrado aqui deverão ser especificados explicitamente.)
Continuando a sessão interativa na Listagem 2b, você será solicitado a fornecer o nome do cluster em que o membro deverá ser criado. Como você já identificou o cluster pelo seu ID de configuração, não é necessário especificar o nome do cluster. Portanto, você pode simplesmente pressionar Enter (Listagem 2b, Linha 1).
Listagem 2b. Criação interativa do membro do cluster
1|Cluster Name (clusterName):
2|Create Cluster Member
3|
4|Creates a new member of an application server cluster.
5|
6|-> *1. Member Configuration (memberConfig)
7| 2. First Member Configuration (firstMember)
8| 3. Promote Proxy Server Settings To Cluster (promoteProxyServer)
9| 4. Configure the event service during cluster member creation. (eventServiceConfig)
10|
11|S (Select)
12|N (Next)
13|C (Cancel)
14|H (Help)
15|
16|
17|Select [S, N, C, H]: [S]
|
Isso resulta na exibição das etapas disponíveis como um submenu (Linhas 6 a 9), das opções de entrada disponíveis (Linhas 11 a 14) e do prompt de comando solicitando sua entrada (Linha 17, com a seleção padrão mostrada entre colchetes).
O asterisco * ao lado da etapa 1 indica que uma entrada é obrigatória. Observe como o comando padrão é S (de Select). Se você pressionar Enter ou a letra S seguida de Enter, a etapa especificada será executada e você verá as informações mostradas na Listagem 2c.
Listagem 2c. Criação interativa do membro do cluster
1|Member Configuration (memberConfig)
2|
3|*Node Name (memberNode):
4|*Member Name (memberName):
5|Member Weight (memberWeight):
6|Member UUID (memberUUID):
7|Generate Unique HTTP Ports (genUniquePorts): [true]
8|enable data replication (replicatorEntry): [false]
9|Specific short name of cluster member (specificShortName):
10|
11|
12|Select [C (Cancel), E (Edit)]: [E]
|
Na Listagem 2c, a descrição e o nome da etapa selecionada são mostrados na Linha 1. Os valores atuais dos atributos da etapa atual são mostrados nas Linhas 3 a 9. Novamente, os valores obrigatórios são precedidos por um asterisco. Como os valores de alguns atributos obrigatórios ainda precisam ser definidos, o comando padrão é E de Edit (Linha 12). Quando você pressionar Enter nesse ponto, será solicitado a fornecer os valores obrigatórios ausentes. A Listagem 2d mostra esses prompts e as respostas que foram fornecidas (Linhas 1 a 8). No caso, os únicos valores inseridos foram dos atributos obrigatórios (Linhas 1 e 2).
Listagem 2d. Criação interativa do membro do cluster
1|*Node Name (memberNode): ragdollNode03
2|*Member Name (memberName): Member2
3|Member Weight (memberWeight):
4|Member UUID (memberUUID):
5|Generate Unique HTTP Ports (genUniquePorts): [true]
6|enable data replication (replicatorEntry): [false]
7|Specific short name of cluster member (specificShortName):
8|Create Cluster Member
9|
10|Creates a new member of an application server cluster.
11|
12| 1. Member Configuration (memberConfig)
13|-> 2. First Member Configuration (firstMember)
14| 3. Promote Proxy Server Settings To Cluster (promoteProxyServer)
15| 4. Configure the event service during cluster member creation. (eventServiceConfig)
16|
17|S (Select)
18|N (Next)
19|P (Previous)
20|F (Finish)
21|C (Cancel)
22|H (Help)
23|
24|
25|Select [S, N, P, F, C, H]: [F]
|
Após a resposta final, o submenu Create Cluster Member é exibido novamente, desta vez indicando com uma seta (->) a próxima etapa; no caso, é a etapa 2 (Linha 13). É importante notar que, como todos os valores de atributos obrigatórios foram fornecidos, um novo comando, F (Finish) agora está disponível (Linha 20) e é também o comando padrão (Linha 25).
A seleção do comando Finish dá início à última fase do método interativo, que resulta na exibição do comando gerado. O resultado é mostrado na Listagem 2e.
Listing 2e. Generated createClusterMember command
WASX7278I: Generated command line: AdminTask.createClusterMember('Cluster1(cells/ragdoll
Cell02/clusters/Cluster1|cluster.xml#ServerCluster_1261065198076)', '[-memberConfig
[-memberNode ragdollNode03 -memberName Member2 -genUniquePorts true -replicatorEntry
false]]')
|
Como é um comando razoavelmente extenso, vamos dividi-lo em partes para facilitar a interpretação. A forma básica do comando é:
AdminTask.createClusterMember( TargetObject,
Parameters )
TargetObject, como é fácil perceber, é o ID de configuração do cluster de destino ao qual o novo membro será adicionado. O valor Parameters é um pouco mais complicado, mas trata-se de uma cadeia de caractere no seguinte formato:
‘[-memberConfig [values]]’
Talvez você se lembre de ter visto memberConfig anteriormente; ele apareceu na Listagem 2B (Linha 6), na Listagem 2c (Linha 1) e na subseção Steps da documentação do Centro de Informações. Agora você pode correlacionar a documentação à sessão interativa de createClusterMember e ver como as peças do quebra-cabeça se encaixam. Também é possível ver que o comando gerado inclui alguns dos valores padrão (por exemplo, genUniquePorts e replicatorEntry). Como eles são padrão, você poderá decidir mais adiante se o seu script precisará ou não fornecer esses valores.
Neste ponto, você usou a forma interativa do método createClusterMember() para determinar a aparência exata do comando caso você decida usar o ID de configuração do cluster. O mesmo procedimento pode ser seguido para determinar a aparência do comando caso você use, alternativamente, o parâmetro clusterName. Tudo o que você precisa fazer é usar o método AdminConfig.reset() para descartar o membro que acabou de ser criado no cluster e executar novamente o método AdminTask.createClusterMember( '-interactive' ), desta vez especificando o parâmetro clusterName em vez do ID de configuração do cluster. O resultado disso é mostrado na Listagem 3.
Listagem 3. Comando createClusterMember alternativo
WASX7278I: Generated command line: AdminTask.createClusterMember('[-clusterName Cluster1
-memberConfig [-memberNode ragdollNode03 -memberName Member1 -genUniquePorts true
-replicatorEntry false]]')
|
Essa forma do comando teria a seguinte aparência:
AdminTask.createClusterMember( Parameters )
A cadeia de caractere Parameter nessa forma seria a seguinte:
‘[-clusterName value -memberConfig [values]]’
De fato, os valores -memberConfig são idênticos aos anteriores. Isso poderá ajudá-lo a compreender melhor a documentação on-line, na qual o parâmetro -clusterName é identificado como obrigatório. (A descrição do parâmetro -clusterName indica que é necessário especificar o valor de TargetObject ou de -clusterName. Se ambos forem fornecidos, uma exceção será gerada e o comando não será executado.)
Este exercício deve tê-lo ajudado a compreender o método createClusterMember(), sua execução em modo interativo (-interactive) e a documentação de suporte. A mesma técnica pode ser usada para criar um segundo membro do cluster; a única diferença do comando que acabou de ser executado é o nome do membro a ser criado.
Tendo feito isso, você sabe que os parâmetros que seu script deverá manipular para usar o método AdminTask.createClusterMember() com o objetivo de criar um membro adicional no cluster são:
- O nome do cluster a ser alterado.
- O nome do nó em que o membro deverá ser criado.
- O nome do membro a ser criado.
Para os fins deste artigo, e para simplificar a explicação, em todos os outros valores será aceito o valor padrão.
Neste ponto, você deve ter uma compreensão razoavelmente precisa do que é necessário para usar essa abordagem ao criar um script.
A terceira abordagem a ser considerada para a tarefa de criação membros de cluster é usar o método createClusterMember na biblioteca de scripts AdminClusterManagement. Como as scriptLibraries já existem no WebSphere Application Server V7, talvez essa abordagem possa atender às suas necessidades com um mínimo de esforço. Vamos examiná-la para ver se de fato pode ser útil para você.
Ao pesquisar o termo AdminClusterManagement no Centro de Informações, você será conduzido para um item chamado Jython script library: Scripts de administração do cluster usando script wsadmin, que descreve alguns dos métodos existentes nesse módulo de biblioteca, inclusive o método createClusterMember – que parece ser exatamente o tipo de informação que você está procurando.
Para testar isso, você precisará de uma configuração de gerenciador de implementação que tenha pelo menos um cluster com pelo menos um membro. Como é a configuração que você já tem, parece que está tudo pronto para você testar essa abordagem. A Listagem 4 mostra uma sessão wsadmin interativa de exemplo usada para testar essa situação e a Tabela 3 descreve as etapas em detalhes.
Listagem 4. Teste interativo com wsadmin de um método scriptLibrary
1|C:\IBM\WebSphere\AppServer70\bin>wsadmin –lang jython
2|WASX7209I: Connected to process "dmgr" on node ragweedCellManager02 using SOAP
3| connector; The type of process is: DeploymentManager
4|WASX7031I: For help, enter: "print Help.help()"
5|wsadmin>cluster, node, member = 'Cluster1', 'ragweedNode03', 'Member2'
6|wsadmin>AdminClusterManagement.createClusterMember( cluster, node, member )
7|----------------------------------------------------------------------
8| AdminClusterManagement: Create a new cluster server member
9| Cluster name: Cluster1
10| Member node name: ragweedNode03
11| New member name: Member2
12| Usage: AdminClusterManagement.createClusterMember("Cluster1", "ragweedNode03", ...
13| Return: The configuration ID of the new cluster member.
14|-----------------------------------------------------------------------
15|
16|
17|'Member2(cells/ragweedCell02/clusters/Cluster1|cluster.xml#ClusterMember_...)'
18|wsadmin>
|
Tabela 3. Explicação da sessão wsadmin interativa
| Linha(s) | Comentários |
|---|---|
| 1 | Inicia o wsadmin e especifica a linguagem como Jython. |
| 2-4 | Informações geradas por wsadmin mostrando que ocorreu uma conexão bem-sucedida com um gerenciador de implementação. |
| 5 | Atribuição de variável local para que a próxima linha não seja excessivamente longa. |
| 6 | Chamada do método createClusterMember() para criar o novo membro. |
| 7-16 | Informações geradas pelo método para detalhar o que está sendo feito. (A Linha 12 foi truncada aqui.) |
| 17 | Truncar o resultado retornado pela chamada do método createClusterMember(). |
Aparentemente, esse método tem vantagens e desvantagens:
- A vantagem mais significativa provavelmente é a interface simples. Usando apenas três parâmetros, é possível criar um novo membro para um cluster existente de maneira rápida e fácil. De fato, esses parâmetros são idênticos aos que são exigidos pelo método AdminTask.createClusterMember() visto anteriormente.
- Quanto às desvantagens, talvez você considere a seção de geração de banner (Listagem 4, Linhas 7 a 16) desnecessária ou incômoda. Embora isso possa ser aceitável durante o desenvolvimento do script, aparentemente não há uma maneira fácil de desabilitar essas linhas. Se isso for razão suficiente para que você evite usar regularmente esse método, há uma alternativa a ser considerada que envolve outra vantagem das bibliotecas de scripts: a disponibilidade do código de origem para análise.
Trabalhando com o código de origem
É relativamente fácil localizar o código de origem de um método específico. Quando um módulo de biblioteca é usado, basta adicionar um atributo __file__ ao comando para que o arquivo do qual essa biblioteca foi carregada seja identificado. A Listagem 5 mostra um exemplo do uso desse atributo.
Listagem 5. Localizando o arquivo de origem de uma biblioteca
1|...>wsadmin -lang jython -conntype none -c "print AdminClusterManagement.__file__"
2|WASX7357I: By request, this scripting client is not connected to any server process.
3|Certain configuration and application operations will be available in local mode.
4|C:\IBM\WebSphere\AppServer70\scriptLibraries\servers\V70\AdminClusterManagement.py
|
Evidentemente, esses arquivos da biblioteca de scripts não devem ser modificados diretamente. Faça uma cópia de qualquer arquivo de biblioteca que queira examinar e edite somente essa cópia.
Examinando o código de origem do script, você poderá aprender várias coisas:
- Como verificar valores de parâmetros.
- Que chamadas de métodos de objetos de criação de scripts do WebSphere Application Server podem ser usadas.
- Como fornecer parâmetros a esses métodos de objetos de criação de scripts.
- Como configurar manipuladores de erros.
Verificando parâmetros
O exame atento do método AdminClusterManagement.createClusterMember() pode lhe proporcionar uma melhor compreensão de como verificar valores de parâmetros. Por exemplo, talvez você perceba que nenhum valor padrão é fornecido para os três primeiros parâmetros (clusterName, nodeName e newMember). Portanto, é necessário especificar um valor para cada um deles quando a função é chamada. Isso se torna aparente ao examinar o código, porque, com a exceção do banner do método, que exibe informações sobre o método e como foi chamado, os valores desses parâmetros são verificados para determinar se contêm uma cadeia de caractere vazia. A Listagem 6 mostra parte desse código. (Os detalhes específicos dos parâmetros fornecidos ao método AdminUtilities._formatNLS() simplesmente fornecem valores para identificar o valor do parâmetro em que um erro foi encontrado e não são necessários para compreender como a verificação de parâmetros efetivamente ocorre.)
Listagem 6. Verificação de parâmetros
1|# check the required arguments
2|if (clusterName == ""):
3| raise AttributeError(AdminUtilities._formatNLS(...))
4|
5|if (nodeName == ""):
6| raise AttributeError(AdminUtilities._formatNLS(...))
7|
8|if (newMember == ""):
9| raise AttributeError(AdminUtilities._formatNLS(...))
10|
11|# check if cluster exists
12|cluster = AdminConfig.getid("/ServerCluster:" +clusterName+"/")
13|if (len(cluster) == 0):
14| raise AttributeError(AdminUtilities._formatNLS(...))
15|#endIf
16|
17|# check if node exists
18|node = AdminConfig.getid("/Node:"+nodeName+"/")
19|if (len(node) == 0):
20| raise AttributeError(AdminUtilities._formatNLS(...))
21|#endIf
|
Essas verificações são necessárias -- ou suficientes -- para o seu ambiente? Isso depende dos seus requisitos e do nível de detalhamento necessário; por exemplo, talvez você precise verificar se há:
- Um valor None.
- Um tipo de dado diferente de cadeia de caractere.
- Valores compostos apenas por espaços em branco.
Os módulos da biblioteca de scripts emitem uma ScriptLibraryException quando ocorre um erro de parâmetro. Para que isso não ocorra, é necessário decidir o que deverá acontecer quando um erro for detectado.
O código, então, determinará se os valores especificados são válidos. É possível, porém, fazer algumas melhorias no código mostrado na Listagem 6. Por exemplo, a Linha 2 mostra uma verificação que determina se foi fornecida uma cadeia de caractere vazia. Se a resposta for negativa, as Linhas 12 e 13 verificam se o cluster especificado existe. Um problema ocorrerá nesse código quando um clusterName contendo um único espaço em branco for especificado; a verificação de cadeia de caractere vazia da Linha 2 retornará false e o resultado da chamada do método AdminConfig.getid( "/ServerCluster: /" ) será uma lista de IDs de configuração de cluster. Além disso, o teste da Linha 13 não detectará um erro porque o resultado da chamada não será uma cadeia de caractere vazia.
Fazendo a chamada
Quando a verificação de parâmetros é concluída, tudo o que resta é a chamada do método AdminTask.createClusterMember() propriamente dito. Tendo investigado recentemente essa chamada, é fácil compreender a instrução:
clusterMember =
AdminTask.createClusterMember(['-clusterName', clusterName,
'-memberConfig', ['-memberNode', nodeName, '-memberName',
newMember]])
Como você talvez saiba, os métodos de objeto de criação de scripts wsadmin em Jython podem passar uma lista de cadeias de caractere (como é visto aqui) ou uma cadeia de caractere de listas (como foi visto anteriormente). A diferença está na sintaxe. Se você examinar atentamente a instrução anterior, perceberá que todos os valores individuais são cadeias de caractere literais (delimitadas por aspas simples) ou nomes de variáveis, todos separados por vírgulas. Isso lhe permite usar nomes de variáveis (como clusterName, nodeName e newMember) nos lugares onde deseja usar o valor de uma variável.
Parameters = '[-clusterName ' + clusterName + '
–memberConfig [-memberNode ' + nodeName + ' –memberName ' + newMember
+ ']]’
Se você preferir não usar uma longa instrução de concatenação de cadeia de caractere como essa, uma alternativa é usar o operador de formatação de cadeia de caractere, o que lhe permite ter uma expressão como esta:
FormatString % ( values )
A operação de formato de cadeia de caractere requer o processamento de FormatString, a localização das sequências de especificação de formato e o uso dessas sequências para formatar os dados associados a partir do operando direito. Para qualquer outro texto na cadeia de caractere de formatação, os dados são copiados sem alteração para a cadeia de caractere de resultados. Nesse exemplo simples, é possível usar a sequência de especificação de formato %s em FormatString para indicar que deve ocorrer uma substituição de cadeia de caractere. Esses caracteres serão substituídos pela representação de cadeia de caractere do próximo valor na tupla (uma sequência ordenada de valores delimitados por parênteses e separados por vírgulas). A construção dessa mesma cadeia de parâmetros usando formatação de cadeia de caractere em vez de concatenação, portanto, seria semelhante a isto:
Parameters = '[-clusterName %s –memberConfig
[-memberNode %s –memberName %s]]’ % ( clusterName, nodeName, newMember
)
Toda esta explicação, porém, é apenas secundária. O que ela lhe permite fazer é simplificar a chamada do método propriamente dita para algo assim:
memberID = AdminTask.createClusterMember( Parameters
)
Este é o cerne real do script que você deve tentar criar.
Tendo investigado as várias abordagens disponíveis para executar a tarefa que você deseja realizar com o script, chegou o momento de tomar uma decisão. Qual destes métodos você deseja usar:
- O método AdminConfig.createClusterMember().
- O método AdminTask.createClusterMember().
- O método AdminClusterManagement.createClusterMember()scriptingLibrary.
Se você optar pela primeira técnica, terá que fornecer ao método IDs de configuração do cluster e do nó. Se você optar pela terceira técnica, o banner da scriptingLibrary será exibido quando o método for chamado. Tudo indica, portanto, que a melhor opção é a segunda técnica.
Via de regra, ao escolher entre um método AdminTask e algum outro método para executar uma ação específica, geralmente é melhor optar pelo método AdminTask, porque os métodos AdminTask tendem a fazer mais coisas para o autor do script, resultando em scripts mais robustos e mais fáceis de escrever.
Agora que você conhece o comando (ou método) específico que deverá ser chamado para executar a ação desejada, poderá criar um script para usar esse comando. Uma última decisão que você deverá tomar refere-se ao grau de robustez do script. Em outras palavras, é aceitável que o script execute apenas uma verificação mínima, ou ele deverá verificar e confirmar absolutamente tudo? A resposta depende do grau de risco que você pode (ou deve) aceitar.
Uma das primeiras verificações a serem feitas é se o script foi executado ou importado. Isso pode ser determinado em Jython verificando o valor de uma variável global especial chamada __name__. Se o script foi executado, o valor dessa variável será __main__; se foi importado, o valor será o nome do arquivo importado. Portanto, para verificar se o script foi executado, o arquivo de script deverá conter um teste simples semelhante ao que é mostrado na Listagem 7.
Listagem 7. Verificando se o script foi executado ou importado
1|if ( __name__ == '__main__' ) :
2| # The script was executed
3|else :
4| # The script was imported
|
Como a abordagem que estamos adotando aqui é construir o script progressivamente, você terá que decidir o que deseja que o script faça a seguir. Adicione estes itens ao código mostrado na Listagem 7 para continuar o script:
- Um bloco de comentário (prólogo) descrevendo o script.
- Uma função vazia como marcador para o código que efetivamente executará o trabalho desejado.
- Uma função Usage() que deve começar a ser preenchida.
O resultado é mostrado na Listagem 8,
Listagem 8. Iteração 1
1|#---------------------------------------------------------------------
2|# Name: createClusterMember.01.py
3|# Role: Example script, created from scratch.
4|# Author: Robert A. (Bob) Gibson
5|# Iteration: 1
6|# What's new? Verify that the script was executed, not imported, and
7|# start populating the Usage information
8|#---------------------------------------------------------------------
9|import sys
10|
11|#---------------------------------------------------------------------
12|# Name: createClusterMember()
13|# Role: Placeholder for routine to perform the desired action
14|#---------------------------------------------------------------------
15|def createClusterMember() :
16| print 'createClusterMember() - iteration 1'
17|
18|#---------------------------------------------------------------------
19|# Name: Usage()
20|# Role: Routine used to provide user with information necessary to
21|# use the script.
22|#---------------------------------------------------------------------
23|def Usage( cmdName = None ) :
24| if not cmdName :
25| cmdName = 'createClusterMember'
26|
27| print '''
28|Command: %(cmdName)s\n
29|Purpose: wsadmin script used to create an additional member to an
30| existing cluster.\n
31| Usage: %(cmdName)s [options]\n
32|Example: ./wsadmin.sh -lang jython -f %(cmdName)s.py ...''' % locals();
33|
34|#---------------------------------------------------------------------
35|# This is the point at which execution begins
36|#---------------------------------------------------------------------
37|if ( __name__ == '__main__' ) :
38| createClusterMember();
39|else :
40| print 'Error: this script must be executed, not imported.';
41| Usage(__name__);
|
Salve o script para poder testá-lo; dê-lhe o nome de createClusterMember.py. (Os sistemas UNIX® possuem um recurso de link simbólico em que o nome do arquivo pode apontar para a iteração atual; por exemplo, createClusterMember.01.py.)
O teste é mostrado na Listagem 9. Ele mostra que o script determinou com êxito se era executado ou importado e exibe uma mensagem indicando que está tudo OK (Linha 3) ou informações de uso (Linhas 11 a 18).
Listagem 9. Iteração de teste 1
1|[root@ragdoll bin]# ./wsadmin.sh -lang jython -f createClusterMember.py
2|WASX7209I: Connected to process "dmgr" ...
3|createClusterMember() - iteration 1
4|
5|[root@ragdoll bin]# ./wsadmin.sh -lang jython
6|WASX7209I: Connected to process "dmgr" ...
7|
8|wsadmin>import createClusterMember
9|Error: this script must be executed, not imported.
10|
11|Command: createClusterMember
12|
13|Purpose: wsadmin script used to create an additional member to an
14| existing cluster.
15|
16| Usage: createClusterMember [optios]
17|
18|Example: ./wsadmin.sh -lang jython -f createClusterMember.py ...
19|wsadmin>
|
Processando os parâmetros e opções de linha de comando
Um dos aspectos mais complexos da criação de scripts é o tratamento dos parâmetros de linha de comando. Uma técnica usada com frequência é usar parâmetros de linha de comando dependentes da posição. Isso significa que é necessário saber que o primeiro parâmetro deve representar clusterName, o segundo parâmetro deve representar nodeName, o terceiro parâmetro deve ser o nome do membro a ser criado, e assim por diante.
Um dos aspectos realmente positivos da linguagem Jython é que ela é fornecida com rotinas de biblioteca que podem facilitar a sua vida, tornando seus scripts melhores e mais fáceis de usar. Uma dessas bibliotecas é getopt, baseada no trabalho realizado há muito tempo para a linguagem de programação C para facilitar o processamento de parâmetros de linha de comando por essa linguagem.
Há algumas coisas que você deve saber para poder usar a biblioteca getopt. Em primeiro lugar, é necessário selecionar letras de parâmetro de formato curto e nomes de parâmetro de formato longo para cada valor de parâmetro. Com uma opção de formato curto (uma única letra), um script pode ser executado da seguinte maneira:
... –f createCluseterMember.py –X clusterName –Y
nodeName –Z memberName
No comando acima, X, Y e Z são usados como marcadores. Identifique letras convenientes que ajudem a identificar os parâmetros no comando. Por exemplo, -c para clusterName, -n para nodeName e -m para memberName. Neste caso, porém, -c não está disponível, porque é uma opção de linha de comando reservada para o utilitário wsadmin e, portanto, não pode ser usada em scripts. Em vez disso, use -L como opção de linha de comando em formato curto para especificar o valor do parâmetro clusterName. (O uso da letra maiúscula evita confusão com o número 1.)
Em seguida, é necessário determinar à rotina do utilitário getopt que procure por essas opções. Para isto:
- Importe o módulo de biblioteca getopt.
- Invoque a função getopt.getopt() e passe os parâmetros necessários.
A função getopt() requer os seguintes parâmetros:
- Lista de parâmetros de linha de comando especificados pelo usuário.
- Cadeia de caractere identificando as opções de formato curto.
- Lista contendo as opções de formato longo.
A cadeia de caractere de formato curto deve incluir cada letra de opção válida, seguida de dois-pontos (:) para indicar que a opção de linha de comando deve ser seguida de um valor. Lembre-se que a rotina de biblioteca getopt é genérica por natureza e nem todas as opções de linha de comando deverão necessariamente ter um valor associado. Considere uma situação em que talvez uma opção de linha de comando (por exemplo, para habilitar a depuração) não exija um valor. Isso poderia perfeitamente ser indicado com um parâmetro de opção como '-X'.
Não deve ser difícil perceber como isso faz sentido. No caso, portanto, você decidiu usar três letras de opção de formato curto, cada uma das quais deverá ser seguida por um valor. A cadeia de caractere de opção shortForm teria a seguinte aparência:
shortForm = 'L:m:n:';
Nesse exemplo, você deseja que a função getopt verifique se qualquer das letras de opção existe na cadeia de caractere, sendo que cada uma deverá ter um valor. Não é necessário fazer nada de especial para definir a ordem em que esses parâmetros ocorrem, nem para indicar, na cadeia de caractere fornecida à função getopt(), quantas vezes cada opção pode ocorrer. Logo você verá como decidir se isso faz ou não sentido para o seu script.
Agora, o que fazer com as opções de linha de comando de formato longo? Lembre-se que as opções de linha de comando de formato curto são representadas por um único caractere, precedido por um único hífen (-) e seguidas de um caractere opcional de dois-pontos (:) para indicar que haverá um valor após a opção de linha de comando. As opções de linha de comando de formato longo possuem um formato semelhante, com ligeiras diferenças. Todas as opções de formato longo começam com dois hífens (--) e são representadas por um número variável de caracteres alfanuméricos. Neste exemplo, faz sentido usar os seguintes identificadores de opções de formato longo:
- clusterName
- nodeName
- memberName
Além disso, é necessário informar à função getopt() que cada uma dessas opções deverá ser seguida de um valor. Isso pode ser feito com uma lista de valores de cadeia de caractere, cada um identificando o identificador da opção, seguidos de um sinal de igual. A lista de opções longForm para este exemplo seria semelhante a esta:
longForm = [ ‘clusterName=’, ‘nodeName=’,
‘memberName=’ ];
Outra maneira, mais compacta, de representar a mesma expressão é usar uma instrução de designação semelhante a esta:
longForm = 'clusterName=,memberName=,nodeName='.split(
',' );
Aqui, split() é um método que processa uma cadeia de caractere de entrada (do tipo string) contendo um caractere delimitador especificado (no caso, uma vírgula) e retorna uma lista de cadeias de caractere. Portanto, ambas as instruções de designação acima criam a mesma lista de valores de cadeia de caractere. Você pode usar a que julgar mais fácil de ler e compreender.
Finalmente, a chamada da rotina getopt propriamente dita terá a seguinte aparência:
getopt.getopt( sys.argv, shortForm, longForm );
Parece interessante, mas como a função consegue determinar quais opções foram efetivamente encontradas? A resposta é que a função retorna dois itens:
- Uma lista de pares nome/valor de opções válidas.
- Uma lista das opções restantes (não processadas).
A Listagem 10 mostra como deverá ser o código para lidar com essa situação.
Listagem 10. Usando a função getopt()
1|try :
2| opts, args = getopt.getopt( sys.argv, shortForm, longForm );
3|except getopt.GetoptError :
4| # code to handle the exception situation
5|
6|for name, value in opts :
7| # code to handle each value option letter/identifier
8|
9|if ( args != [] ) :
10| # code to handle “extra” stuff on the command line
|
Isso parece bem fácil, mas há lugares onde o código foi omitido (Linhas 4, 7 e 10):
- Uma exceção será gerada pela função getopt() quando uma opção não reconhecida for encontrada ou uma opção não contiver um valor obrigatório. O código do manipulador de exceção (Linha 4) deverá exibir a mensagem apropriada e encerrar o script.
- O código no loop for (Linha 7) é onde cada uma das opções suportadas é processada. É aqui que o script deverá verificar se há várias ocorrências de uma opção de linha de comando, caso isso seja importante para você.
- Na última seção (Linha 10), o script poderá verificar e processar qualquer informação adicional que tenha sido fornecida mas não esteja associada a qualquer das opções válidas.
Estas informações deverão ajudá-lo a compreender a rotina parseOpts() mostrada na Listagem 11. Ao ser chamada, essa rotina retorna um dicionário refletindo as opções de linha de comando especificadas pelo usuário.
Listagem 11. A rotina parseOpts() completa
1|#---------------------------------------------------------------------
2|# Name: parseOpts()
3|# Role: Process the user specified (command line) options
4|# Returns: A dictionary containing the user specified values
5|#---------------------------------------------------------------------
6|def parseOpts( cmdName ) :
7| shortForm = 'L:m:n:';
8| longForm = 'clusterName=,memberName=,nodeName='.split( ',' );
9| badOpt = '%(cmdName)s: Unknown/unrecognized parameter%(plural)s: %(argStr)s';
10| optErr = '%(cmdName)s: Error encountered processing: %(argStr)s';
11|
12| try :
13| opts, args = getopt.getopt( sys.argv, shortForm, longForm );
14| except getopt.GetoptError :
15| argStr = ' '.join( sys.argv );
16| print optErr % locals();
17| Usage( cmdName );
18|
19| #-------------------------------------------------------------------
20| # Initialize the Opts dictionary using the longForm key identifiers
21| #-------------------------------------------------------------------
22| Opts = {};
23| for name in longForm :
24| if name[ -1 ] == '=' :
25| name = name[ :-1 ]
26| Opts[ name ] = None;
27|
28| #-------------------------------------------------------------------
29| # Process the list of options returned by getopt()
30| #-------------------------------------------------------------------
31| for opt, val in opts :
32| if opt in ( '-L', '--clusterName' ) : Opts[ 'clusterName' ] = val
33| elif opt in ( '-m', '--memberName' ) : Opts[ 'memberName' ] = val
34| elif opt in ( '-n', '--nodeName' ) : Opts[ 'nodeName' ] = val
35|
36| #-------------------------------------------------------------------
37| # Check for unhandled/unrecognized options
38| #-------------------------------------------------------------------
39| if ( args != [] ) : # If any unhandled parms exist => error
40| argStr = ' '.join( args );
41| plural = '';
42| if ( len( args ) > 1 ) : plural = 's';
43| print badOpt % locals();
44| Usage( cmdName );
45|
46| #-------------------------------------------------------------------
47| # Return a dictionary of the user specified command line options
48| #-------------------------------------------------------------------
49| return Opts;
|
O script completo, incluindo a rotina parseOpts() acima, está disponível no arquivo createClusterMember.02.py, incluído nos materiais para download.
Verificando e usando as opções de linha de comando
Neste ponto, você tem uma pequena função que verifica os parâmetros de linha de comando especificados pelo usuário e retorna o resultado em um dicionário. O que pode ser feito com isso?
Em primeiro lugar, compreenda que a função parseOpts() só retorna um resultado em dicionário quando nenhuma condição de erro é detectada – o que significa que a rotina parseOpts() não encontrou qualquer problema nas condições verificadas, mas não necessariamente que não existam problemas.
A Listagem 12 mostra como a segunda iteração desse script processa esses parâmetros.
Listagem 12. Iteração 2: Chamando a rotina parseOpts()
1|missingParms = '%(cmdName)s: Insufficient parameters provided.';
2|
3|#-------------------------------------------------------------------
4|# How many user command line parameters were specified?
5|#-------------------------------------------------------------------
6|argc = len( sys.argv ); # Number of arguments
7|if ( argc < 3 ) : # If too few are present,
8| print missingParms % locals(); # tell the user, and
9| Usage( cmdName ); # provide the Usage info
10|else : # otherwise
11| Opts = parseOpts( cmdName ); # parse the command line
|
Na Listagem 12, o código mostra como a rotina parseOpts() rotina só é chamada se três ou mais parâmetros foram especificados; três é o número mínimo de parâmetros que devem ser processados pela rotina getopt():
[ ‘-LclusterName’, ‘-nNodeName’, ‘-mMemberName’
]
A instrução de impressão na Linha 8 é outra das operações de formatação de cadeia de caractere discutidas anteriormente. A diferença aqui é que a cadeia de caractere de formatação deve identificar, em cada especificação de formatação, qual entrada do dicionário será usada para fornecer a substituição. Portanto, a cadeia de formatações contendo %(cmdName)s será substituída pela variável local cmdName e o valor será exibido como uma cadeia de caractere.
Trata-se de um idioma muito poderoso que também é usado na rotina Usage(). Por exemplo, se você examinar a Listagem 8, Linhas 27 a 32, encontrará outra dessas mensagens mapeadas. O aspecto interessante a ser observado sobre a cadeia de formatações nesse exemplo é que a mesma variável local (cmdName) ocorre várias vezes na mesma cadeia de caractere.
O que pode ser feito com o dicionário retornado pelas rotinas parseOpts()? Os valores individuais do dicionário podem ser acessados usando o índice correspondente, mas isso seria muito mais fácil se você atribuísse os valores do dicionário a variáveis locais. Compare as duas instruções na Listagem 13 e veja qual delas é mais simples e fácil de entender.
Listagem 13. Qual é mais fácil de ler e entender?
1|if ( not Opts[ ‘clusterName’ ] ) :
2| print ‘Required option missing: clusterName’
3|
4|if ( not clusterName ) :
5| print ‘Required option missing: clusterName’
|
Uma maneira fácil de converter o dicionário retornado pela rotina parseOpts() para as variáveis locais correspondentes é usar um conjunto de instruções de designação (Listagem 14).
Listagem 14. Conversão simples de entradas de dicionário para variáveis locais
1|clusterName = Opts[ ‘clusterName’ ];
2|nodeName = Opts[ ‘nodeName’ ];
3|memberName = Opts[ ‘memberName’ ];
|
Essa abordagem funciona satisfatoriamente, contanto que o número de identificadores de linha de comando (formato longo) válidos seja pequeno. Mas há outra maneira de fazer isso usando os identificadores que existem no dicionário, mostrados na Listagem 15.
Listagem 15. Conversão genérica de entradas do dicionário para variáveis locais
1|#-------------------------------------------------------------------
2|# Assign values from the user Options dictionary, to make value
3|# access simplier, and easier. For example, instead of using:
4|# Opts[ 'clusterName' ]
5|# we will be able to simply use:
6|# clusterName
7|# to access the value. Additionally, this allows us to make use of
8|# mapped error messages that reference local variable values.
9|#-------------------------------------------------------------------
10|for key in Opts.keys() :
11| cmd = '%s=Opts["%s"]' % ( key, key );
12| exec( cmd );
|
A chave desse segmento de código é a cadeia de caractere criada, semelhante às instruções de designação da Listagem 14, e a rotina exec() que executa a instrução de designação e efetivamente realiza a atribuição de variáveis.
Neste ponto, tudo que essa iteração faz no script é exibir uma mensagem mostrando os valores especificados pelo usuário. Esta versão do script pode ser usada para testar o processamento de linha de comando e verificar se ele funciona satisfatoriamente.
Tudo o que falta fazer é adicionar código para verificar os valores especificados pelo usuário e depois usar esses valores para executar a ação desejada.
Caso um dos valores exigidos seja None, isso significa que uma das opções de linha de comando não foi especificada. Como isso pode acontecer? O código para processar os parâmetros de linha de comando na função parseOpts() não verifica se há duplicatas. Portanto, o usuário pode especificar parâmetros de linha de comando como estes:
--clusterName=C1 –L C2 –L C3
Nesse caso, o valor das opções nodeName e memberName será None. É possível modificar a função parseOpts() para verificar se há várias ocorrências da mesma opção de linha de comando, mas antes é necessário decidir até que ponto a inclusão desse tipo de verificação poderá ser útil.
Talvez seja aconselhável verificar também se há valores de cadeia de caractere vazios. Um usuário pode especificar um valor em branco delimitado por aspas duplas:
./wsadmin.sh -f createClusterMember.py -L " " -n " "
-m " "
Se você testar a iteração 2 do script, a saída poderá ser algo como isto:
createClusterMember: --clusterName --nodeName
--memberName
Como todos os valores são obrigatórios, as mesmas verificações devem ser realizadas em cada valor. (Seria possível até adicionar verificações para determinar se o clusterName e nodeName especificados já existem e se o memberName especificado não existe. Essas verificações estão além do escopo deste artigo, mas poderão ser acrescentadas posteriormente se você decidir que são úteis.)
Lembre-se também que é possível adicionar as verificações no mesmo loop usado para criar variáveis locais a partir do dicionário Opts. A Listagem 16 mostra qual seria a aparência do código modificado.
Listagem 16. Adicionando verificações de valores obrigatórios inválidos
1|badReqdParam = '%(cmdName)s: Invalid required parameter: %(key)s.\n';
2|
3|#-------------------------------------------------------------------
4|# Assign values from the user Options dictionary, to make value
5|# access simplier, and easier. For example, instead of using:
6|# Opts[ 'clusterName' ]
7|# we will be able to simply use:
8|# clusterName
9|# to access the value. Additionally, this allows us to make use of
10|# mapped error messages that reference local variable values.
11|#-------------------------------------------------------------------
12|for key in Opts.keys() :
13| val = Opts[ key ];
14| if ( not val ) or ( not val.strip() ) :
15| print badReqdParam % locals();
16| Usage();
17| cmd = '%s=Opts["%s"]' % ( key, key );
18| exec( cmd );
|
Na Listagem 16, a Linha 1 mostra a criação de uma nova mensagem de erro mapeada que é exibida quando um valor Nome (ou uma cadeia de caractere vazia) é encontrado. As linhas modificadas ocorrem nas Linhas 13 a 16, onde o valor do identificador especificado é recuperado.
A primeira parte da expressão na Linha 14 é usada para verificar se há um valor None. Se o valor da variável val for None, o resultado de ( not val ) será verdadeiro e a mensagem de erro será exibida. O restante da expressão é usado para verificar se o valor (sem espaços em branco antes ou depois) é uma cadeia de caractere vazia. Em caso afirmativo, a mensagem de erro é exibida, a rotina Usage() é chamada e o script é encerrado.
Chamando AdminTask.createClusterMember()
Tendo verificado se o usuário forneceu valores para todos os parâmetros obrigatórios, tudo o que falta fazer é usá-los na chamada do método AdminTask.createClusterMember(). Como a construção da cadeia de caractere de parâmetros desse método foi descrita anteriormente, parece que está tudo pronto.
Bem, quase. É importante que o script seja protegido contra erros; se a chamada do método falhar, ele gerará uma exceção. A Listagem 17 mostra a parte do script em que o método AdminTask.createClusterMember() finalmente é chamado.
Listagem 17. Chamando AdminTask.createClusterMember()
1|#-------------------------------------------------------------------
2|# Call the AdminTask.createClusterMember() method using the command
3|# line parameter values.
4|#-------------------------------------------------------------------
5|parms = '%(cmdName)s --clusterName %(clusterName)s --nodeName %(nodeName)s
--memberName %(memberName)s';
6|print parms % locals();
7|try :
8| Parms = '[-clusterName %s -memberConfig [-memberNode %s -memberName %s]]' %
( clusterName, nodeName, memberName )
9| AdminTask.createClusterMember( Parms );
10| AdminConfig.save();
11| print '%(cmdName)s success. Member %(memberName)s created successfully.' % locals();
12|except :
13| #-----------------------------------------------------------------
14| # An exception occurred. Convert the exception value to a string
15| # using the backtic operator, then look for the presence of a
16| # WebSphere message, which start with 'ADMG'. If one is found,
17| # only display the last part of the value string.
18| #-----------------------------------------------------------------
19| val = `sys.exc_info()[ 1 ]`;
20| pos = val.rfind( 'ADMG' )
21| if pos > -1 :
22| val = val[ pos: ]
23| print '%(cmdName)s Error. %(val)s' % locals();
|
A Tabela 4 explica o segmento de código mostrado na Listagem 17 para ajudá-lo a compreender o que o código está tentando fazer e como essa tarefa é executada.
Tabela 4. Explicação da chamada de AdminTask.createClusterMember()
| Linha(s) | Comentários |
|---|---|
| 1-4 | Bloco de comentário identificando a ação a ser executada. |
| 5 | Mensagem mapeada usada para exibir a ação que está sendo executada e os valores especificados pelo usuário. |
| 6 | Exibe a mensagem mapeada usando valores de variáveis locais. |
| 7-23 | Chamada do método createClusterMember() protegida por um manipulador de exceção (por exemplo, um bloco try/except). |
| 8 | Cadeia de caractere de formatação mapeada usada para construir a cadeia de caractere de parâmetros do método. |
| 9 | Chamada do método createClusterMember() propriamente dito. |
| 10 | Se createClusterMember() tiver êxito, será necessário chamar AdminConfig.save() para salvar a configuração modificada. |
| 11 | Imprimir uma mensagem indicando a conclusão bem-sucedida da ação solicitada. |
| 12-18 | Caso ocorra uma exceção, a instrução com maior probabilidade de falha é a chamada da rotina createClusterMember(). |
| 19 | Chamar sys.exc_info() para descobrir o que aconteceu. Somente o segundo valor (o valor do erro) é realmente importante neste caso; portanto, somente ele é mantido. Usar os operadores backtic para converter o valor retornado em uma cadeia de caractere. |
| 20 | Chamada de rfind() para localizar a última ocorrência do prefixo de número de mensagem ADMG na cadeia de caractere. |
| 21-22 | Se o prefixo da mensagem estiver presente, descartar todos os caracteres que o precedem e manter apenas a importante mensagem de erro gerada pela exceção. |
| 23 | Exibir o texto da mensagem de erro. |
Esse artigo mostrou uma abordagem para a criação de um script Jython wsadmin com o objetivo de executar uma tarefa administrativa específica do IBM WebSphere Application Server administrative task, neste caso, para criar um membro adicional em um cluster existente. Depois de descrever como usar a documentação do Centro de Informações para conhecer as várias opções disponíveis para executar a tarefa e como comparar as opções para determinar a abordagem mais prática, ele descreveu passo a passo, em etapas compreensíveis, a construção de um script de exemplo. Este artigo também forneceu informações sobre precauções comuns, boas práticas, como testar um script e como lidar com condições de erro.
Esperamos que você tenha considerado estas informações úteis e valiosas.
Leia o livro do autor: WebSphere Application Server Administration Using Jython

| Descrição | Nome | Tamanho | Método de download |
|---|---|---|---|
| Sample scripts | createClusterMember.scripts.zip | 16 KB | HTTP |
Informações sobre métodos de download
Aprender
-
WebSphere Application Server Administration Using Jython
-
Suporte do WebSphere Application Server
-
Centro de Informações do WebSphere Application Server (todas as versões)
-
Documentação do WebSphere Application Server Network Deployment (distribuído)
-
Criando Membros de Cluster Utilizando Script
-
Comandos para o objeto AdminConfig usando o script wsadmin
-
Grupo de Comandos ClusterConfigCommands para o Objeto AdminTask
-
Biblioteca de Scripts Jython: Scripts de administração do cluster usando script wsadmin
-
Zona do WebSphere Application Server no IBM developerWorks
-
WebSphere no IBM developerWorks
Obter produtos e tecnologias
-
Download de avaliação: Obtenha o IBM WebSphere Application Server V7 (versão de teste)
-
Oferta gratuita: Faça download do WebSphere Application Server for Developers

Bob Gibson é Advisory Software Engineer, com um quarto de século de experiência em numerosas funções relacionadas a software na IBM, inclusive Application Programmer, Architect, Developer, Instructor, Technical Support Analyst e Tester. Atualmente, é líder de equipe do grupo de suporte técnico responsável pelo IBM WebSphere Distributed Application Server. É formado em Ciência da Engenharia, com mestrado em Ciência da Computação pela University of Virgínia.