Limitações de migração

O software Migrate to Containers automatiza o uso do kit de ferramentas de migração do servidor da Web do IBM WebSphere para binários de aplicativo no cluster do Anthos ou do GKE, para descobrir, avaliar e gerar relatórios de migração e scripts de configuração. Você é o único responsável por adquirir, licenciar e usar o kit de ferramentas.

A ferramenta de scanner binário tem várias limitações que você precisa conhecer antes de começar a migrar apps tradicionais da WAS. Este documento descreve essas limitações e oferece soluções alternativas que permitem migrar seus apps tradicionais da WAS.

Para cada app tradicional da WAS que você migra, o Migrate to Containers cria um arquivo de script Python .py usado ao criar o contêiner do app. As soluções alternativas para essas limitações exigem a edição do script .py do Python antes de implantar um contêiner de app. O script .py do Python faz parte dos artefatos de migração. Veja instruções sobre como acessar e fazer o download em Antes de começar.

Configuração de SSL do JMS não extraída

As informações de configuração do JMS SSL não são extraídas pela ferramenta de scanner binário para a Fábrica de conexões de fila e para a especificação de ativação. Neste procedimento, descrevemos como migrar uma configuração SSL do JMS ao usar certificados SSL gerenciados centralmente no WAS tradicional.

Para mais informações, consulte a documentação da IBM aqui.

Solução alternativa para configuração SSL

Edite o script Python .py do app para adicionar informações de configuração SSL adicionando a sinalização -sslType=CENTRAL no nível de especificação de ativação ou da Fábrica de conexões de fila.

Veja abaixo exemplos da especificação de ativação e da Fábrica de conexões de fila do script Python .py:

Especificação de ativação:

AdminTask.createWMQActivationSpec(Node, ["-name", "BrownActivationSpecification",
 "-jndiName", "jms/BrownActivationSpecification", "-authAlias", "m4a-twas-ndNode01/BrownAuthAlias",
 "-destinationJndiName", "jms/BrownRequestQueue", "-destinationType", "javax.jms.Queue",
 "-qmgrHostname", "m4a-db2-mq.c.velos-auto-1.internal", "-qmgrName", "LQM1",
 "-qmgrPortNumber", "1414", "-qmgrSvrconnChannel", "CLOUD.APP.SVRCONN",
 "-wmqTransportType", "BINDINGS_THEN_CLIENT"])

Fábrica de conexões de fila:

AdminConfigVar_0=AdminTask.createWMQConnectionFactory(Node, ["-name", "BrownConnectionFactory",
 "-jndiName", "jms/BrownConnectionFactory", "-type", "QCF", "-mappingAlias",
 "DefaultPrincipalMapping", "-containerAuthAlias", "m4a-twas-ndNode01/BrownAuthAlias", "-qmgrName", "LQM1",
 "-qmgrHostname", "m4a-db2-mq.c.velos-auto-1.internal",
 "-qmgrPortNumber", "1414", "-qmgrSvrconnChannel", "CLOUD.APP.SVRCONN",
 "-wmqTransportType", "BINDINGS_THEN_CLIENT"])

No exemplo a seguir, mostramos as modificações necessárias para adicionar a sinalização -sslType=CENTRAL. Você só precisa seguir uma destas especificações

Especificação de ativação:

AdminTask.createWMQActivationSpec(Node, ["-name", "BrownActivationSpecification",
 "-jndiName", "jms/BrownActivationSpecification", "-authAlias", "m4a-twas-ndNode01/BrownAuthAlias",
 "-destinationJndiName", "jms/BrownRequestQueue", "-destinationType", "javax.jms.Queue",
 "-qmgrHostname", "m4a-db2-mq.c.velos-auto-1.internal", "-qmgrName", "LQM1",
 "-qmgrPortNumber", "1414", "-qmgrSvrconnChannel", "CLOUD.APP.SVRCONN",
 "-wmqTransportType", "BINDINGS_THEN_CLIENT", "-sslType", "CENTRAL"])

Fábrica de conexões de fila:

AdminConfigVar_0=AdminTask.createWMQConnectionFactory(Node, ["-name", "BrownConnectionFactory",
 "-jndiName", "jms/BrownConnectionFactory", "-type", "QCF", "-mappingAlias",
 "DefaultPrincipalMapping", "-containerAuthAlias", "m4a-twas-ndNode01/BrownAuthAlias", "-qmgrName", "LQM1",
 "-qmgrHostname", "m4a-db2-mq.c.velos-auto-1.internal",
 "-qmgrPortNumber", "1414", "-qmgrSvrconnChannel", "CLOUD.APP.SVRCONN",
 "-wmqTransportType", "BINDINGS_THEN_CLIENT", "-sslType", "CENTRAL"])

As informações de autenticação LDAP foram omitidas

Quando um app usa autenticação LDAP, o script Python .py para o app omite essas informações de LDAP. Como solução alternativa, edite o script Python .py para adicionar as informações necessárias.

As informações do LDAP são gravadas nos arquivos appname_server.xml e appname_server_sensitiveData.xml criados para o app. Esses arquivos são gravados na pasta /deploy do bucket do Cloud Storage que contém os artefatos de migração.

As informações necessárias estão em um conjunto de variáveis nesses arquivos. Por exemplo, de appname_server.xml:

<!-- The following variables, which often differ between environments
     have been extracted from the migrated configuration to allow
     for easy substitution. -->
    <variable defaultValue="9080" name="httpEndpoint_port_4"/>
    <variable defaultValue="1389" name="ldapRegistry_port_4"/>
    <variable defaultValue="m4a-db2-mq.c.my-co.internal" name="ldapRegistry_host_4"/>
    <variable defaultValue="9443" name="httpEndpoint_secure_port_4"/>
    <variable defaultValue="*" name="httpEndpoint_host_4"/>
    <variable defaultValue="ou=users,dc=example,dc=org" name="ldapRegistry_baseDN_4"/>

E de appname_server_sensitiveData.xml:

<!-- The following variables are used to replace sensitive data in the
     server.xml file for the application. -->
    <variable name="ldapRegistry_bindDN_1" defaultValue="cn=admin,dc=example,dc=org"/>
    <variable name="ldapRegistry_bindPassword_1" defaultValue="PASSWORD"/>

Edite o script Python .py no app para adicionar definições de variável e comandos adicionais para criar e configurar o LDAPUserRegistry e para torná-lo o registro padrão em Segurança global. Adicione estas linhas após a linha NodeName=AdminControl.getNode():

. . .
NodeName=AdminControl.getNode()

# The following variables are used to replace sensitive data in the
# configuration for the application.
# ============================================================
ldapRegistry_bindDN='cn=admin,dc=example,dc=org'
ldapRegistry_bindPassword='PASSWORD'
# ============================================================

# LDAP related variables
# ============================================================
ldapRegistry_port='1389'
#ldapRegistry_host='m4a-db2-mq.c.my-co.internal'
ldapRegistry_host='35.241.207.81'
ldapRegistry_baseDN='ou=users,dc=example,dc=org'
ldapRegistry_primaryAdminId='cn=user01,ou=users,dc=example,dc=org'
ldapRegistry_userFilter='(&(uid=%v)(objectclass=posixAccount))'
# ============================================================

print 'Starting Creating LDAP Registry'
# https://www.ibm.com/support/knowledgecenter/SSEQTP_8.5.5/com.ibm.websphere.base.iseries.doc/ae/rxml_7securityconfig.html#rxml_7securityconfig__SecurityConfigurationCommands.cmd7
AdminTask.configureAdminLDAPUserRegistry(['-autoGenerateServerId', 'true', '-primaryAdminId', ldapRegistry_primaryAdminId, '-ldapServerType', 'CUSTOM', '-ldapHost',
 ldapRegistry_host, '-ldapPort', ldapRegistry_port, '-baseDN', ldapRegistry_baseDN, '-bindDN', ldapRegistry_bindDN, '-bindPassword', ldapRegistry_bindPassword,
 '-userFilter', ldapRegistry_userFilter, '-groupFilter', '(&(cn=%v)(|(objectclass=groupOfNames)(objectclass=groupOfUniqueNames)))', '-userIdMap',
 '*:uid', '-groupIdMap', '*:cn', '-groupMemberIdMap', 'ibm-allGroups:member;ibm-allGroups:uniqueMember;groupOfNames:member;groupOfUniqueNames:uniqueMember'])

AdminConfig.save()

print 'Starting Creating Admin Security Settings'

# https://www.ibm.com/support/knowledgecenter/SSEQTP_8.5.5/com.ibm.websphere.base.iseries.doc/ae/rxml_7securityconfig.html#rxml_7securityconfig__SecurityConfigurationCommands.cmd8
AdminTask.setAdminActiveSecuritySettings(['-enableGlobalSecurity', 'true', '-cacheTimeout', '300', '-enforceJava2Security', 'false', '-appSecurityEnabled', 'true', '-activeUserRegistry', 'LDAPUserRegistry'])

AdminConfig.save()

. . .

As informações do controle de acesso baseado em papéis (RBAC, na sigla em inglês) foram omitidas

Quando um app de WAS é configurado para usar a autorização de controle de acesso baseado em papéis (RBAC, na sigla em inglês), você precisa mapear os papéis do aplicativo para usuários, grupos ou usuários especiais, como Todos ou Nenhum. Essa configuração não é extraída pela ferramenta scanner binária, mas é necessária para que o aplicativo funcione e imponha a autorização como esperado.

Para configurar o RBAC para o app, edite o comando de instalação do aplicativo no script .py do Python para o app.

Veja abaixo um exemplo de comando de instalação de aplicativo no script .py do Python sem os papéis para o mapeamento do usuário:

AdminApp.install('/work/config/SuperSnoop.ear', ["-node", NodeName, "-server", "server1", "-appname", "SuperSnoop.ear"])

Para aplicar regras de mapeamento de papéis, edite o script Python .py no app para adicionar a sinalização -MapRolesToUsers conforme mostrado abaixo:

AdminApp.install('/work/config/SuperSnoop.ear', ["-node", NodeName, "-server", "server1", "-appname", "SuperSnoop.ear",
 "-MapRolesToUsers", [["Manager", "AppDeploymentOption.No", "AppDeploymentOption.No",
 "cn=user02,ou=users,dc=example,dc=org", "some_group_name"]]])

Para mais informações, consulte a documentação da IBM aqui.

Como alterar o carregador de classes do aplicativo

Os aplicativos WebSphere podem usar arquivos JAR que entram em conflito com os arquivos JAR fornecidos pelo WebSphere. Para resolver conflitos de arquivos JAR, você pode controlar a ordem do carregador de classe para um aplicativo ou para um módulo WAR.

Por exemplo, é possível especificar o uso do carregador de classe de aplicativo primeiro ou somente um único carregador de classe para todo o aplicativo, em vez de usar o carregador de classes WebSphere e o carregador de classes do aplicativo.

As alterações no carregador de classes do aplicativo não são extraídas pela ferramenta do scanner binário, portanto, é necessário editar o comando de instalação do aplicativo no script .py do Python para que o app aplique essas alterações.

Exemplo de configuração do servidor

Para um aplicativo com configurações de carregador de classe modificadas, as alterações são armazenadas no arquivo descritor do aplicativo, deployment.xml. Por exemplo, o descritor de implantação tem as configurações do carregador de classes conforme marcado abaixo:

<?xml version="1.0" encoding="UTF-8"?>
<appdeployment:Deployment xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:appdeployment="http://www.ibm.com/websphere/appserver/schemas/5.0/appdeployment.xmi" xmi:id="Deployment_1614732697">
  <deployedObject xmi:type="appdeployment:ApplicationDeployment" xmi:id="ApplicationDeployment_1614732697"
    deploymentId="0" startingWeight="1" binariesURL="CurrenciesServices/CurrenciesServices.ear"
    useMetadataFromBinaries="false" enableDistribution="true" warClassLoaderPolicy="SINGLE"
    createMBeansForResources="true" reloadEnabled="false" appContextIDForSecurity="href:was-nd-2Cell01/CurrenciesServices"
    filePermission=".*\.dll=755#.*\.so=755#.*\.a=755#.*\.sl=755" allowDispatchRemoteInclude="false"
    allowServiceRemoteInclude="false" asyncRequestDispatchType="DISABLED" standaloneModule="true" enableClientModule="false">
    <targetMappings xmi:id="DeploymentTargetMapping_1614732697" enable="true" target="ClusteredTarget_1614732697"/>
    <classloader xmi:id="Classloader_1614732697" mode="PARENT_LAST"/>
    <modules xmi:type="appdeployment:WebModuleDeployment" xmi:id="WebModuleDeployment_1614732697" deploymentId="1" startingWeight="10000" uri="CurrenciesServices.war" containsEJBContent="0">
      <targetMappings xmi:id="DeploymentTargetMapping_1614732698" target="ClusteredTarget_1614732697"/>
      <classloader xmi:id="Classloader_1614732698"/>
    </modules>
    <properties xmi:id="Property_1614732697" name="metadata.complete" value="true"/>
  </deployedObject>
  <deploymentTargets xmi:type="appdeployment:ClusteredTarget" xmi:id="ClusteredTarget_1614732697" name="Cluster1"/>
</appdeployment:Deployment>

As duas seções relevantes no descritor de implantação são os valores SINGLE e PARENT_LAST que precisam ser migrados manualmente. Para aplicar as alterações do carregador de classes, edite o script Python .py.

Veja abaixo um exemplo de comando de instalação do aplicativo no script .py do Python:

AdminApp.install('/work/app/CurrenciesServices.war',
  [ "-node", NodeName, "-server", "server1", "-appname", "CurrenciesServices.war",
    "-contextroot", "/CurrenciesServices", "-CtxRootForWebMod",
    [["TafnitCurrenciesServices", "CurrenciesServices.war,WEB-INF/web.xml", "/CurrenciesServices"]]])

AdminConfig.save()

Para aplicar as alterações do carregador de classes, edite o script Python .py do app para adicionar as configurações, conforme mostrado abaixo:

AdminApp.install('/work/app/CurrenciesServices.war',
  ["-node", NodeName, "-server", "server1", "-appname", "CurrenciesServices.war",
    "-contextroot", "/CurrenciesServices", "-CtxRootForWebMod",
    [["TafnitCurrenciesServices", "CurrenciesServices.war,WEB-INF/web.xml", "/CurrenciesServices"]]])

dep = AdminConfig.getid('/Deployment:CurrenciesServices.war/')
depObject = AdminConfig.showAttribute(dep, 'deployedObject')
classldr = AdminConfig.showAttribute(depObject, 'classloader')
print AdminConfig.showall(classldr)
print AdminConfig.show(depObject, 'warClassLoaderPolicy')
AdminConfig.modify(classldr, [['mode', 'PARENT_LAST']])
AdminConfig.modify(depObject, [['warClassLoaderPolicy', 'SINGLE']])

AdminConfig.save()