Creación de la plantilla del conector de servicio Web SAP ECC 7.51 para ECMA2Host
Esta guía te explica el proceso de creación de una plantilla para el conector del agente de administración de conectividad de extensibilidad del servicio Web (ECMA) para administrar usuarios de SAP ECC.
Suposiciones y limitaciones
Esta plantilla muestra cómo administrar los usuarios. En esta guía no se tratan otros tipos de objetos como grupos de actividades locales, roles y perfiles, ya que ECMA2Host no admite actualmente referencias multivalor. Las operaciones de contraseña también están fuera del ámbito de esta guía.
Esta guía no cubre la creación de la cuenta de servicio dentro de SAP que se usa para llamar a las funciones BAPI expuestas. Se supone que se usa una cuenta de demostración creada previamente de desarrollador con un perfil RFC_ALL que concede permisos a los BAPI mencionados a continuación.
La herramienta de configuración del servicio Web no admite las siguientes características expuestas en SAP de forma predeterminada: directivas WSP y varios enlaces por punto de conexión. Espera un WSDL solo con SOAP 1.1, enlace de estilo de documento todo en uno sin directivas.
Funciones BAPI de SAP ECC que se usan en esta plantilla:
- BAPI_USER_GETLIST: obtiene una lista de todos los usuarios conectados a este sistema.
- BAPI_USER_GETDETAIL: obtiene detalles de un usuario específico.
- BAPI_USER_CREATE1: crea un usuario.
- BAPI_USER_DELETE: elimina un usuario.
- BAPI_USER_CHANGE: actualiza un usuario.
Todas las propiedades de usuario de SAP de esta guía se tratan como propiedades con valores únicos.
El lenguaje de programación que se usa es Visual Basic.
Definición de un punto de conexión de servicio Web y creación de un esquema
Para poder diseñar flujos de trabajo de importación y exportación, debes crear una plantilla y definir un punto de conexión con las funciones de SAP BAPI expuestas a través de una interfaz SOAP. A continuación, crea un esquema de los objetos ECMA2 y sus propiedades está disponible en esta plantilla.
- En la carpeta "C:\Program Files\Microsoft ECMA2Host\Web Service Configuration Tool", inicia la herramienta de configuración del servicio Web wsconfigTool.exe
- En el menú Nuevo-Archivo, elige Crear nuevo proyecto SOAP.
- Haz clic en Proyecto SOAP y elige Agregar nuevo servicio Web.
- Asigna un nombre al servicio Web SAPECC, proporciona una dirección URL para descargar WSDL publicado y escribe SAPECC como espacio de nombres. El nombre del servicio Web te ayuda a distinguir este servicio Web en la plantilla de otros usuarios. Namespace define un nombre del espacio de nombres de Microsoft .NET que se usa para generar clases. Elige el modo de autenticación básico a menos que el administrador de SAP indique lo contrario. Haz clic en Siguiente.
- Proporciona credenciales para conectarte al punto de conexión de SAP ECC. Haz clic en Siguiente.
- En la página puntos de conexión y operaciones, asegúrate de que se muestran los BAPIs y haz clic en Finalizar.
Nota:
si ves más de un punto de conexión, tienes habilitados los enlaces SOAP 1.2 y SOAP 1.1. Esto hace que se produzca un error en el conector. Modifica la definición de enlace en SOAMANAGER y mantén solo una. Luego, vuelve a agregar un servicio Web.
- Guarda el proyecto en la carpeta C:\Program Files\Microsoft ECMA2Host\Service\ECMA.
- Haz clic en la pestaña Tipos de objeto y elige agregar el tipo de objeto de usuario. Haz clic en Aceptar.
- Expande la pestaña Tipos de objeto y haz clic en Definición de tipo de usuario.
- Agrega los atributos siguientes al esquema y elige userName como anclaje.
- Guarda el proyecto.
Nombre | Tipo | Anclaje |
---|---|---|
city | string | |
company | cadena | |
department | string | |
string | ||
expirationTime | string | |
firstName | string | |
lastName | string | |
middleName | string | |
telephoneNumber | string | |
jobTitle | string | |
userName | string | Activado |
Creación de un flujo de trabajo de importación completa
El flujo de trabajo de importación, si bien es opcional en ECMA2Host, te permite importar usuarios de SAP existentes en la caché en memoria ECMA2Host y evitar que se creen usuarios duplicados durante el aprovisionamiento.
Si no creas un flujo de trabajo de importación, el conector funciona en modo de solo exportación y hace que ECMA2Host emita siempre operaciones de creación de usuarios, incluso para los usuarios existentes. Esto puede provocar errores o duplicados cuando se usan BAPI de SAP estándar a menos que el flujo de trabajo de exportación controle duplicados.
SAP ECC no ofrece un mecanismo integrado para leer los cambios realizados desde la última lectura.
Por lo tanto, solo estamos implementando el flujo de trabajo de importación completa. Si necesitas implementar importaciones delta por motivos de rendimiento, consulta al administrador de SAP para obtener una lista de BAPI y hacer que se publiquen como un servicio web SOAP. Luego, implementa el flujo de trabajo de importación delta mediante el enfoque descrito a continuación y una propiedad customData que contiene una marca de tiempo de la ejecución correcta anterior.
SAP ECC ofrece varias funciones BAPI para obtener una lista de usuarios con sus propiedades:
- BAPI_USER_GETLIST: obtiene una lista de todos los usuarios conectados a este sistema.
- BAPI_USER_GETDETAIL: obtiene detalles de un usuario específico.
Solo estos dos BAPIs se usan para recuperar usuarios existentes de SAP ECC en esta plantilla.
- Ve a Object Types - > User - > Import -> Full Import workflow y desde el cuadro de herramientas en la derecha, arrastra y coloca la actividad Sequence en el panel del diseñador de flujo de trabajo.
- En la parte inferior izquierda, busca el botón Variables y haz clic en él para expandir una lista de variables definidas en esta secuencia.
- Agrega las variables siguientes. Para seleccionar un tipo de variable generado desde WSDL de SAP, haz clic en Buscar tipos y expande generado y después expande el espacio de nombres SAPECC.
Nombre | Tipo de variable | Ámbito | Valor predeterminado |
---|---|---|---|
selRangeTable | SAPECC.TABLE_OF_BAPIUSSRGE | Sequence | new TABLE_OF_BAPIUSSRGE with {.item = new BAPIUSSRGE(){new BAPIUSSRGE}} |
getListRetTable | SAPECC.TABLE_OF_BAPIRET2 | Sequence | new TABLE_OF_BAPIRET2 |
pageSize | Int32 | Sequence | 200 |
returnedSize | Int32 | Sequence | |
usersTable | SAPECC.TABLE_OF_BAPIUSNAME | Sequence | new TABLE_OF_BAPIUSNAME() |
- En el cuadro de herramientas, arrastra y coloca cuatro actividades de asignación dentro de la actividad Sequence y establece estos valores:
selRangeTable.item(0).PARAMETER = "USERNAME"
selRangeTable.item(0).SIGN = "I" selRangeTable.item(0).OPTION = "GT" selRangeTable.item(0).LOW = ""
Estos parámetros se usan para llamar a la función BAPI_USER_GETLIST e implementar la paginación.
- Para implementar la paginación, desde el cuadro de herramientas, arrastra y coloca la actividad DoWhile dentro de la actividad Sequence después de la última operación Asignar.
- En el panel derecho, cambia a la pestaña Propiedades y escribe esta condición para DoWhile.
- ciclo:
returnedSize = pageSize
- Haz clic en las variables y agrega la propiedad currentPageNumber del tipo int32 dentro del ciclo DoWhile con el valor predeterminado 0.
- Paso opcional: si planeas implementar el flujo de trabajo de importación delta, desde el cuadro de herramientas arrastra y coloca la actividad Assign dentro de la actividad Sequence después del ciclo DoWhile. Establece este valor:
customData(schemaType.Name + "_lastImportTime") = DateTimeOffset.UtcNow.Ticks.ToString()
Esto guarda la fecha y hora de la última ejecución de importación completa y esta marca de tiempo se puede usar más adelante en el flujo de trabajo de importación delta.
- En el cuadro de herramientas, arrastra y coloca la actividad Sequence dentro de la actividad DoWhile. Arrastra y coloca la actividad WebServiceCall dentro de esa actividad Sequence y selecciona Nombre de servicio SAPECC, punto de conexión ZSAPCONNECTORWS y operación BAPI_USER_GETLIST.
- Haz clic en el botón Argumentos ... para definir los parámetros para la llamada del servicio Web de la siguiente manera:
Nombre | Dirección | Tipo | Valor |
---|---|---|---|
MAX_ROWS | In | Int32 | pageSize |
MAX_ROWSSpecified | In | Boolean | True |
RETURN | In/Out | TABLE_OF_BAPIRET2 | getListRetTable |
SELECTION_EXP | In/Out | TABLE_OF_BAPIUSSEXP | |
SELECTION_RANGE | In/Out | TABLE_OF_BAPIUSSRGE | selRangeTable |
USERLIST | In/Out | TABLE_OF_BAPIUSNAME | usersTable |
WITH_USERNAME | In | String | |
ROWS | Out | Int32 | returnedSize |
- Haz clic en Aceptar. El signo de advertencia desaparece. La lista de usuarios almacenados en la variable usersTable. Dado que SAP no devuelve una lista completa de usuarios en una sola respuesta, es necesario implementar la paginación y llamar a esta función varias veces al cambiar de página. Luego, para cada usuario importado, debes obtener los detalles del usuario realizando una llamada independiente. Esto significa que para un entorno con 1000 usuarios y un tamaño de página de 200, el conector del servicio Web realiza 5 llamadas para recuperar una lista de usuarios y 1000 llamadas individuales para recuperar los detalles de los usuarios. Para mejorar el rendimiento, pide al equipo de SAP que desarrolle un programa BAPI personalizado que muestre todos los usos con sus propiedades para evitar la necesidad de realizar 1000 llamadas individuales y exponer esa función BAPI a través del punto de conexión de SOAP WS.
- En el cuadro de herramientas, arrastra y coloca la actividad IF dentro de la actividad DoWhile después de la actividad WebServiceCall. Especifica esta condición para comprobar si hay una respuesta no vacía y ausencia de errores:
IsNothing(getListRetTable.item) OrElse getListRetTable.item.Count(Function(errItem) errItem.TYPE.Equals("E") = True) = 0
- En el cuadro de herramientas, arrastra y coloca la actividad Throw en la rama Else de la actividad IF para producir un error al importar incorrectamente. Cambia a la pestaña Propiedades y escribe esta expresión para la propiedad Exception de la actividad Throw:
New Exception(getListRetTable.item.First(Function(retItem) retItem.TYPE.Equals("E")).MESSAGE)
- Para procesar una lista de usuarios importados, arrastra y coloca la actividad ForEachWithBodyFactory desde el cuadro de herramientas en la rama Then de la actividad IF. Cambia a la pestaña Propiedades y selecciona SAPECC.BAPIUSNAME como TypeArgument. Haz clic en el botón ... y escribe esta expresión para la propiedad values:
if(usersTable.item,Enumerable.Empty(of BAPIUSNAME)())
- En el cuadro de herramientas, arrastra y coloca la actividad Sequence dentro de la actividad ForEach. Al activar esta ventana de actividad Sequence, haz clic en el botón Variables y define estas variables:
Nombre | Tipo de variable | Ámbito | Valor predeterminado |
---|---|---|---|
company | SAPECC.BAPIUSCOMP | Sequence | new BAPIUSCOMP() |
address | SAPECC.BAPIADDR3 | Sequence | new BAPIADDR3() |
defaults | SAPECC.BAPIDEFAUL | Sequence | new BAPIDEFAUL() |
logondata | SAPECC.BAPILOGOND | Sequence | new BAPILOGOND() |
getDetailRetTable | SAPECC.TABLE_OF_BAPIRET2 | Sequence | new TABLE_OF_BAPIRET2() |
La actividad IF tiene este aspecto:
- Arrastra y coloca la actividad CreateCSEntryChangeScope dentro de la actividad Sequence. En la propiedad DN, escribe schemaType.Name & item.USERNAME. En el campo CreateAnchorAttribute AnchorValue, escribe item.username.
- Para recuperar detalles de cada usuario, desde el cuadro de herramientas, arrastra y coloca la actividad WebServiceCall dentro de la actividad Sequence justo antes de la actividad CreateAnchorAttribute. Selecciona el nombre de servicio SAPECC, el punto de conexión ZSAPCONNECTORWS y la operación BAPI_USER_GET_DETAIL. Haz clic en el botón Argumentos ... para definir los parámetros para la llamada del servicio Web de la siguiente manera:
Nombre | Dirección | Tipo | Value |
---|---|---|---|
RETURN | In/Out | TABLE_OF_BAPIRET2 | getDetailRetTable |
USERNAME | In | String | item.username |
ADDRESS | Out | BAPIADDR3 | address |
COMPANY | Out | BAPIUSCOMP | company |
DEFAULTS | Out | BAPIUSDEFAUL | defaults |
LOGONDATA | Out | BAPILOGOND | logonData |
WITH_USERNAME | In | String | |
ROWS | Out | Int32 | returnedSize |
- Haz clic en Aceptar. El signo de advertencia desaparece. Los detalles de un usuario se almacenan en las variables enumeradas anteriormente. La actividad IF tiene este aspecto:
- Para comprobar los resultados de la operación BAPI_USER_GET_DETAIL, desde el cuadro de herramientas, arrastra y coloca la actividad IF y colócala dentro de la actividad Sequence entre las actividades WebServiceCall y CreateAnchorAttribute. Escribe esta condición:
IsNothing(getDetailRetTable.item) OrElse getDetailRetTable.item.Count(Function(errItem) errItem.TYPE.Equals("E") = True) = 0
Como los detalles del usuario que faltan no deben tratarse como un evento catastrófico, queremos indicar este error y continuar el procesamiento de otros usuarios. Arrastra y coloca la actividad Sequence en la rama Else de la actividad IF. Agrega la actividad Log dentro de esa nueva actividad Sequence. Cambia a la pestaña Propiedades y cambia la propiedad Level a High, Tag a Trace. Escribe lo siguiente en la propiedad LogText: string.Join("\n", getDetailRetTable.item.Select (Function(item) item.MESSAGE ))
- Arrastra y coloca la actividad Sequence en la rama Then de la actividad IF. Arrastra y coloca la actividad CreateAnchorAttribute existente en la actividad Sequence dentro de la rama Then de la actividad IF. La actividad ForEach ahora tiene el siguiente aspecto:
- Para cada propiedad de un usuario como ciudad, empresa, departmento o correo electrónico, agrega la actividad IF después de la actividad CreateAnchorAttribute y comprueba si hay valores no vacíos mediante la escritura de condiciones como
Not string.IsNullOrEmpty(address.city)
y la adición de las actividades CreateAttributeChange en la rama Then de esa actividad IF.
Por ejemplo: agrega actividades CreateAttributeChange para todas las propiedades de usuario mediante esta tabla de asignación:
Propiedad usuario ECMA | Propiedad SAP |
---|---|
city | address.city |
department | address.department |
company | company.company |
address.e_mail | |
firstName | address.firstName |
lastName | address.lastName |
middleName | address.middleName |
jobTitle | address.function |
expirationTime | logonData.GLTGB |
telephoneNumber | address.TEL1_NUMBR |
- Por último, agrega la actividad SetImportStatusCode después de la última actividad CreateAttributeChange. Establece ErrorCode en Correcto en la rama Then. Agrega una actividad de código SetImportStatus más en la rama Else y establece ErrorCode en ImportErrorCustomContinueRun.
- Contrae la actividad Sequence dentro de la actividad ForEach para que el ciclo DoWhile tenga este aspecto:
- Para recuperar la página siguiente de los usuarios, actualiza la propiedad
selRangeTable.item(0).LOW
. Arrastra y coloca la actividad IF en la actividad Sequence dentro de DoWhile y colócala después de la actividad IF existente. Escribe returnedSize>0 como Condición. Agrega la actividad Assign a la rama Then de la actividad IF y estableceselRangeTable.item(0).LOW
enusersTable.item(returnedSize-1).username
.
Has completado la definición del flujo de trabajo de importación completa.
Creación de un flujo de trabajo de adición de exportación
Para crear un usuario en SAP ECC, puedes llamar al programa BAPI_USER_CREATE1 y proporcionar todos los parámetros, incluido un nombre de cuenta y una contraseña inicial. Si necesitas que se genere un nombre de cuenta en SAP, consulta con el administrador de SAP y usa una función BAPI personalizada que devuelva una propiedad userName de una cuenta de usuario recién creada.
En esta guía no se muestra la asignación de licencias, los grupos de actividades locales o globales, los sistemas o perfiles. Consulta con el administrador de SAP y modifica este flujo de trabajo en consecuencia.
No es necesario implementar la paginación en flujos de trabajo de exportación. Solo hay un objeto objectToExport disponible en el contexto del flujo de trabajo.
- Ve a Object Types - > User - > Export - > Add workflow y desde el cuadro de herramientas de la derecha, arrastra y coloca la actividad Sequence en el panel del diseñador de flujo de trabajo.
- En la parte inferior izquierda, busca el botón Variables y haz clic en él para expandir una lista de variables definidas en esta secuencia.
- Agrega las variables siguientes. Para seleccionar un tipo de variable generado desde WSDL de SAP, haz clic en Buscar tipos y expande generado y después expande el espacio de nombres SAPECC. Esto inicializa las estructuras de datos usadas por el programa BAPI_USER_CREATE1.
Nombre | Tipo de variable | Ámbito | Valor predeterminado |
---|---|---|---|
address | SAPECC.BAPIADDR3 | Sequence | new BAPIADDR3() |
userName | String | Sequence | |
password | SAPECC.BAPIPWD | Sequence | new BAPIPWD() |
company | SAPECC.BAPIUSCOMP | Sequence | new BAPIUSCOMP() |
defaults | SAPECC.BAPIDEFAUL | Sequence | new BAPIDEFAUL() |
logOnData | SAPECC.BAPILOGOND | Sequence | new BAPILOGOND() |
bapiret2Table | SAPECC.TABLE_OF_BAPIRET2 | Sequence | new TABLE_OF_BAPIRET2() |
- Como definimos la propiedad userName como un id. inmutable, un anclaje, necesitaremos extraer el valor userName de una colección de anclajes de nuestro objeto de exportación. Arrastra y coloca la actividad ForEachWithBodyFactory desde el cuadro de herramientas a la actividad Sequence. Reemplaza el nombre de la variable de elemento por anclaje, cambia a las propiedades y elige TypeArgument de
Microsoft.MetadirectoryServices.AnchorAttribute
. En el campo Valor, escribeobjectToExport.AnchorAttributes
.
- Para extraer un valor de cadena de un anclaje userName, arrastra y coloca la actividad Switch dentro de la actividad ForEach. En la ventana emergente, selecciona el tipo
Microsoft.IdentityManagement.MA.WebServices.Activities.Extensions.AnchorAttributeNameWrapper
de un modificador. Escribe el valor Expression de: New AnchorAttributeNameWrapper(anchor.Name). - Haz clic en Add new case area de la actividad Switch. Escribe userName como valor Case. Arrastra y coloca la actividad Assign en el cuerpo del caso userName y asigna anchor.Value.ToString() a la variable userName.
- Ahora que hemos extraído el valor userName de la propiedad de anclaje de objeto exportado, es necesario rellenar otras estructuras como company, defaults, address, logon data que contienen otros detalles de usuario de SAP. Para ello, realizamos un ciclo a través de la colección de cambios de atributo.
- Contrae la actividad ForEach, arrastra y coloca otra actividad ForEachWithBothFactory dentro de la actividad Sequence después de la actividad ForEach existente. Reemplaza el nombre de la variable de elemento por attributeChange, cambia a propiedades y elige TypeArgument de
Microsoft.MetadirectoryServices.AttributeChange
. En el campo Valor, escribeobjectToExport.AttributeChanges
.
- Arrastra y coloca la actividad Switch en el cuerpo de la actividad ForEach.
- En el menú emergente, selecciona
Microsoft.IdentityManagement.MA.WebServices.Activities.Extensions.AttributeNameWrapper
y haz clic en Aceptar. - Escribe la expresión siguiente: New AttributeNameWrapper(attributeChange.Name). Verás un icono de advertencia en la esquina superior derecha de la actividad Switch sobre los atributos no controlados definidos en el esquema y no asignados a ninguna propiedad.
- Haz clic en Add new case carea de la actividad Switch y escribe un valor Case city.
- Arrastra y coloca la actividad Assign en el cuerpo de este caso. Asigna
attributeChange.ValueChanges(0).Value.ToString()
a address.city.
- Agrega los otros casos y asignaciones que faltan. Usa esta tabla de asignación como guía:
Caso | Asignación |
---|---|
city | address.city = attributeChange.ValueChanges(0)Value.ToString() |
company | company.company = attributeChange.ValueChanges(0)Value.ToString() |
department | address.department = attributeChange.ValueChanges(0)Value.ToString() |
address.e_mail = attributeChange.ValueChanges(0)Value.ToString() | |
expirationTime | logOnData.GLTGB = attributeChange.ValueChanges(0)Value.ToString() |
firstname | address.firstname = attributeChange.ValueChanges(0)Value.ToString() |
lastName | address.lastname = attributeChange.ValueChanges(0)Value.ToString() |
middleName | address.middlename = attributeChange.ValueChanges(0)Value.ToString() |
telephoneNumber | address.TEL1_Numbr = attributeChange.ValueChanges(0)Value.ToString() |
jobTitle | address.function = attributeChange.ValueChanges(0)Value.ToString() |
export_password | password.BAPIPWD1 = attributeChange.ValueChanges(0)Value.ToString() |
Aquí export_password es un atributo virtual especial que siempre se define en el esquema y se puede usar para pasar una contraseña inicial del usuario que se va a crear.
- Contrae la actividad ForEach, arrastra y coloca la actividad IF en la actividad Sequence, después de la segunda actividad ForEach, para validar las propiedades del usuario, antes de enviar la solicitud de creación del usuario. Necesitamos al menos 3 valores no vacíos: nombre de usuario, apellido, contraseña inicial. Escribe esta condición:
(String.IsNullOrEmpty(address.lastname) = False ) AND (String.IsNullOrEmpty(userName) = False) AND (String.IsNullOrEmpty(password.BAPIPWD1) = False)
- En la rama Else de la actividad IF, agrega una actividad IF más, ya que queremos producir errores diferentes en función de lo que falta. Escribe el valor de condición: String.IsNullOrEmpty(userName). Arrastra y coloca las actividades
CreateCSEntryChangeResult
en ambas ramas de la segunda actividad IF y configura ErrorCode deExportErrorMissingAnchorComponent
yExportErrorMissingProvisioningAttribute
.
- Arrastra y coloca la actividad Sequence en la rama Then vacía de la primera actividad IF. Arrastra y coloca la actividad WebSeviceCall dentro de la actividad Sequence. Selecciona el nombre de servicio SAPECC, el punto de conexión ZSAPCONNECTORWS y la operación BAPI_USER_CREATE1. Haz clic en el botón Argumentos ... para definir los parámetros para la llamada del servicio Web de la siguiente manera:
Nombre | Dirección | Tipo | Valor |
---|---|---|---|
ADDRESS | In | BAPIADDR3 | address |
COMPANY | In | BAPIUSCOMP | company |
DEFAULTS | In | BAPIDEFAUL | defaults |
LOGONDATA | In | BAPILOGOND | logOnData |
PASSWORD | In | BAPIPWD | password |
RETURN | In-Out | TABLE_OF_BAPIRET2 | bapiret2Table |
SELF_REGISTER | In | String | "X" |
USERNAME | In | String | userName |
- Haz clic en Aceptar. El signo de advertencia desaparece.
- Para procesar la creación de resultados de solicitudes de usuario, arrastra y coloca la actividad IF dentro de la actividad Sequence después de la actividad WebServiceCall. Escribe la siguiente condición:
IsNothing (bapiret2Table.item) OrElse bapiret2Table.item.Count(Function(errItem) errItem.TYPE.Equals("E") = True) <> 0
- Si no se produce ningún error, se supone que la operación de exportación se completó correctamente y queremos indicar la exportación correcta de este objeto mediante la creación de CSEntryChangeResult con el estado Correcto. Arrastra y coloca la actividad CreateCSEntryChangeResult en la rama Else de la actividad IF y selecciona el código de error correcto.
- Opcional: si la llamada al servicio Web devuelve un nombre de cuenta generado de un usuario, es necesario actualizar un valor de anclaje del objeto exportado. Para ello, arrastra y coloca la actividad
CreateAttrubuteChange
dentro de la actividadCreateCSEntryChangeResult
y selecciona Add a userName. Luego, arrastra y coloca la actividadCreateValueChange
dentro de la actividadCreateAttributeChange
y escribe el nombre de la variable rellenado por una actividad de llamada de servicio Web. En esta guía, usarás la variable userName que no se actualiza en la exportación.
- El último paso del flujo de trabajo de adición de exportación es controlar y registrar los errores de exportación. Arrastra y coloca la actividad Sequence en la rama Then vacía de la actividad IF.
- Arrastra y coloca actividad de registro en la actividad Sequence. Cambia a la pestaña Propiedades y escribe el valor logText de:
bapiret2Table.item.First(Function(retItem) retItem.TYPE.Equals("E"))
.MESSAGE. Mantén el nivel de registro alto y la etiqueta de seguimiento. Esto registra un mensaje de error en ConnectorsLog o en el registro de eventos ECMA2Host cuando está habilitado el seguimiento detallado. - Arrastra y coloca la actividad Switch dentro de la actividad Sequence después de la actividad Log. En la ventana emergente, selecciona tipo String del valor Switch. Escribe la siguiente expresión:
bapiret2Table.item.First(Function(retItem) retItem.TYPE.Equals("E")).NUMBER
- Haz clic en Caso predeterminado, arrastra y coloca la actividad CreateCSEntryChangeResult en el cuerpo de este caso. Elige el código de error ExportErrorInvalidProvisioningAttributeValue.
- Haz clic en Add new case area y escribe un valor Case de 224. Arrastra y coloca la actividad
CreateCSEntryChangeResult
en el cuerpo de este caso. Elige el código de errorExportErrorCustomContinueRun
.
Has completado la definición del flujo de trabajo de adición de exportación.
Creación de un flujo de trabajo de eliminación de exportación
Para eliminar un usuario de SAP ECC, puedes llamar al programa BAPI_USER_DELETE y proporcionar el nombre de cuenta que se va a eliminar en el sistema conectado. Consulta con el administrador de SAP si este escenario es obligatorio, ya que la mayoría de las cuentas de SAP ECC no se van a eliminar, pero que han expirado para mantener registros históricos.
En esta guía no se tratan escenarios relacionados con el sistema de administración de usuarios comunes de SAP, el desaprovisionamiento de usuarios de los sistemas conectados, la revocación de licencias, etc.
No es necesario implementar la paginación en flujos de trabajo de exportación. Solo hay un objeto objectToExport disponible en el contexto del flujo de trabajo.
- Ve a Object Types - > User - > Export -> Delete workflow y desde el cuadro de herramientas de la derecha, arrastra y coloca la actividad Sequence en el panel del diseñador de flujo de trabajo.
- En la parte inferior izquierda, busca el botón Variables y haz clic en él para expandir una lista de variables definidas en esta secuencia.
- Agrega las variables siguientes. Para seleccionar un tipo de variable generado desde WSDL de SAP, haz clic en Buscar tipos y expande generado y después expande el espacio de nombres SAPECC. Esto inicializa las estructuras de datos usadas por el programa BAPI_USER_DELETE.
Nombre | Tipo de variable | Ámbito | Valor predeterminado |
---|---|---|---|
userName | String | Sequence | |
bapiret2Table | SAPECC.TABLE_OF_BAPIRET2 | Sequence | new TABLE_OF_BAPIRET2() |
- Como definimos la propiedad userName como un id. inmutable, un anclaje, necesitaremos extraer el valor userName de una colección de anclajes de nuestro objeto de exportación. Arrastra y coloca la actividad ForEachWithBodyFactory desde el cuadro de herramientas a la actividad Sequence. Reemplaza el nombre de la variable de elemento por anclaje, cambia a las propiedades y elige TypeArgument de
Microsoft.MetadirectoryServices.AnchorAttribute
. En el campo Valor, escribeobjectToExport.AnchorAttributes
.
- Para extraer un valor de cadena de un anclaje userName, arrastra y coloca la actividad Switch dentro de la actividad ForEach. En la ventana emergente, selecciona el tipo
Microsoft.IdentityManagement.MA.WebServices.Activities.Extensions.AnchorAttributeNameWrapper
de un modificador. Escribe el valor Expression de: NewAnchorAttributeNameWrapper(anchor.Name)
. Haz clic en Add new case area de la actividad Switch. Escribe userName como valor Case. Arrastra y coloca la actividad Assign en el cuerpo del caso userName y asígnaleanchor.Value.ToString()
a la variable userName. - Arrastra y coloca la actividad WebSeviceCall dentro de la actividad Sequence después de la actividad ForEach. Selecciona el nombre de servicio SAPECC, el punto de conexión ZSAPCONNECTORWS y la operación BAPI_USER_DELETE. Haz clic en el botón Argumentos ... para definir los parámetros para la llamada del servicio Web de la siguiente manera:
Nombre | Dirección | Tipo | Value |
---|---|---|---|
RETURN | In/Out | TABLE_OF_BAPIRET2 | bapiret2Table |
USERNAME | In | String | userName |
- Haz clic en Aceptar. El signo de advertencia desaparece.
- Para procesar la eliminación de los resultados de la solicitud de usuario, arrastra y coloca la actividad IF dentro de la actividad Sequence después de la actividad WebServiceCall. Escribe la siguiente condición:
If(bapiRet2Table.item, Enumerable.Empty(Of BAPIRET2)()).Count(Function(errItem) errItem.TYPE.Equals("E") = True) <> 0
- Si no se produce ningún error, se supone que la operación de eliminación se completó correctamente y queremos indicar la exportación correcta de este objeto mediante la creación
CSEntryChangeResult
con el estado Correcto. Arrastra y coloca la actividadCreateCSEntryChangeResult
en la rama Else de la actividad IF y selecciona código de error correcto.
- El último paso del flujo de trabajo de eliminación de exportación es controlar y registrar los errores de exportación. Arrastra y coloca la actividad Sequence en la rama Then vacía de la actividad IF.
- Arrastra y coloca actividad de registro en la actividad Sequence. Cambia a la pestaña Propiedades y escribe el valor logText de:
bapiRetTable.item.First(Function(retItem) retItem.TYPE.Equals("E")= True).MESSAGE
. Mantén el nivel de registro alto y la etiqueta de seguimiento. Esto registra un mensaje de error en el registro de eventos ConnectorsLog o ECMA2Host cuando está habilitado el seguimiento detallado. - Arrastra y coloca la actividad Switch dentro de la actividad Sequence después de la actividad Log. En la ventana emergente, selecciona tipo String del valor Switch. Escribe la siguiente expresión:
bapiret2Table.item.First(Function(retItem) retItem.TYPE.Equals("E")).NUMBER
- Haz clic en Caso predeterminado, arrastra y coloca la actividad CreateCSEntryChangeResult en el cuerpo de este caso. Elige el código de error ExportarErrorSyntaxViolation.
- Haz clic en Add new case area y escribe un valor Case de 124. Arrastra y coloca la actividad
CreateCSEntryChangeResult
en el cuerpo de este caso. Elige el código de errorExportErrorCustomContinueRun
.
Has completado la definición del flujo de trabajo de eliminación de exportación.
Creación de un flujo de trabajo de reemplazo de exportación
Para actualizar un usuario de SAP ECC, puedes llamar al programa BAPI_USER_CHANGE y proporcionar todos los parámetros, incluido un nombre de cuenta y todos los detalles del usuario, incluidos los que no cambian. El modo de exportación ECMA2 cuando se proporcionan todas las propiedades de usuario se denomina Reemplazar. En comparación, el modo de exportación de AttributeUpdate solo proporciona atributos que se están cambiando y esto puede hacer que algunas propiedades de usuario se sobrescriban con valores vacíos. Por lo tanto, el conector de servicios Web siempre usa el modo de exportación reemplazar objeto y espera que el conector se configure para Tipo de exportación: Reemplazar.
El flujo de trabajo de reemplazo de exportación es casi idéntico al flujo de trabajo de adición de exportación. La única diferencia es que necesitas especificar parámetros adicionales como addressX o companyX para el programa BAPI_USER_CHANGE, donde la X que termina en addressX indica que la estructura de dirección contiene un cambio.
- Ve a Object Types -> User -> Export -> Replace workflow y desde el cuadro de herramientas de la derecha, arrastra y coloca la actividad Sequence en el panel del diseñador de flujo de trabajo.
- En la parte inferior izquierda, busca el botón Variables y haz clic en él para expandir una lista de variables definidas en esta secuencia.
- Agrega las variables siguientes. Para seleccionar un tipo de variable generado desde WSDL de SAP, haz clic en Buscar tipos y expande generado y después expande el espacio de nombres SAPECC. Esto inicializa las estructuras de datos usadas por el programa BAPI_USER_CHANGE.
Nombre | Tipo de variable | Ámbito | Valor predeterminado |
---|---|---|---|
userName | String | Sequence | |
bapiret2Table | SAPECC.TABLE_OF_BAPIRET2 | Sequence | new TABLE_OF_BAPIRET2() |
addressX | SAPECC.BAPIADDR3X | Sequence | new BAPIADDR3X() |
address | SAPECC.BAPIADDR3 | Sequence | new BAPIADDR3() |
companyX | SAPECC. BAPIUSCOMX | Sequence | new BAPIUSCOMX() |
company | SAPECC.BAPIUSCOMP | Sequence | new BAPIUSCOMP() |
defaultsX | SAPECC.BAPIDEFAX | Sequence | new BAPIDEFAX() |
defaults | SAPECC.BAPIDEFAUL | Sequence | new BAPIDEFAUL() |
logOnDataX | SAPECC.BAPILOGONX | Sequence | new BAPILOGONX() |
logOnData | SAPECC.BAPILOGOND | Sequence | new BAPILOGOND() |
El flujo de trabajo de reemplazo de exportación tiene este aspecto:
- Como definimos la propiedad userName como un id. inmutable, un anclaje, necesitaremos extraer el valor userName de una colección de anclajes de nuestro objeto de exportación. Arrastra y coloca la actividad ForEachWithBodyFactory desde el cuadro de herramientas a la actividad Sequence. Reemplaza el nombre de la variable de elemento por anclaje, cambia a las propiedades y elige TypeArgument de
Microsoft.MetadirectoryServices.AnchorAttribute
. En el campo Valor, escribeobjectToExport.AnchorAttributes
.
- Para extraer un valor de cadena de un anclaje userName, arrastra y coloca la actividad Switch dentro de la actividad ForEach. En la ventana emergente, selecciona el tipo
Microsoft.IdentityManagement.MA.WebServices.Activities.Extensions.AnchorAttributeNameWrapper
de un modificador. Escribe el valor Expression de: NewAnchorAttributeNameWrapper(anchor.Name)
. Haz clic en Add new case area de la actividad Switch. Escribe userName como valor Case. Arrastra y coloca la actividad Assign en el cuerpo del caso userName y asígnaleanchor.Value.ToString()
a la variable userName. El flujo de trabajo de reemplazo de exportación tiene este aspecto:
- Ahora que hemos extraído el valor userName de la propiedad de anclaje de objeto exportado, es necesario rellenar otras estructuras como company, defaults, address, logon data que contienen otros detalles de usuario de SAP. Para ello, realizamos el ciclo a través de la recopilación de todos los atributos definidos en el esquema.
- Contrae la actividad ForEach, arrastra y coloca otra actividad ForEachWithBothFactory dentro de la actividad Sequence después de la actividad ForEach existente. Reemplaza el nombre de la variable de elemento por schemaAttr, cambia a las propiedades y elige TypeArgument de
Microsoft.MetadirectoryServices.SchemaAttribute
. En el campo Valor, escribeschemaType.Attributes
.
- Arrastra y coloca la actividad Sequence en el cuerpo de la actividad ForEach. En la parte inferior izquierda, busca el botón Variables y haz clic en él para expandir una lista de variables definidas en esta secuencia. Agrega la variable siguiente: xValue de tipo String. Arrastra y coloca la actividad Assign en la actividad Sequence. Asignar xValue a la expresión de:
If(objectToExport.AttributeChanges.Contains(schemaAttr.Name), objectToExport.AttributeChanges(schemaAttr.Name).ValueChanges(0).Value.ToString(), String.Empty)
extraerá los cambios almacenados provisionalmente para la exportación para este atributo o lo inicializará con una cadena vacía. El flujo de trabajo de reemplazo de exportación tiene este aspecto:
- Arrastra y coloca la actividad Switch después de la actividad Assign. En el menú emergente, selecciona
Microsoft.IdentityManagement.MA.WebServices.Activities.Extensions.AttributeNameWrapper
y haz clic en Aceptar. Escribe la siguiente expresión: newAttributeNameWrapper(schemaAttr.Name)
. Verás un icono de advertencia en la esquina superior derecha de la actividad Switch sobre los atributos no controlados definidos en el esquema y no asignados a ninguna propiedad. Haz clic en Add new case carea de la actividad Switch y escribe un valor Case city. Arrastra y coloca la actividad Sequence en el cuerpo de este caso. Arrastra y coloca la actividad Assign en el cuerpo de este caso. Asigna el valor "X" a addressX.city. Arrastra y coloca otra actividad Assign en el cuerpo de este caso. Asigna xValue a address.city. El flujo de trabajo de reemplazo de exportación tiene este aspecto:
10. Agrega los otros casos y asignaciones que faltan. Usa esta tabla de asignación como guía:
Caso | Asignación |
---|---|
city | addressX.city = "X" address.city = xValue |
company | companyX.company = "X" company.company = xValue |
department | address.departmentX = "X" address.department = xValue |
addressX.e_mail = "X" address.e_mail = xValue | |
expirationTime | logOnDataX.GLTGB = "X" logOnData.GLTGB = xValue |
firstname | addressX.firstname = "X" address.firstname = xValue |
lastName | addressX.lastname = "X" address.lastname = xValue |
middleName | addressX.middlename = "X" address.middlename = xValue |
telephoneNumber | addressX.TEL1_Numbr = "X" address.TEL1_Numbr = xValue |
jobTitle | addressX.function = "X" address.function = xValue |
El flujo de trabajo de reemplazo de exportación tiene este aspecto:
Antes de llamar al programa BAPI_USER_CHANGE, es necesario comprobar si hay un nombre de usuario no vacío. Contrae las actividades ForEach y arrastra y coloca la actividad IF después de la segunda actividad ForEach. Escribe la siguiente condición:
String.IsNullOrEmpty(userName ) = False
Cuando el nombre de usuario está vacío, queremos indicar que la operación no se realizó correctamente. Arrastra y coloca la actividad
CreateCSEntryChangeResult
en la rama Else de la actividad IF y selecciona el código de errorExportErrorCustomContinueRun
. El flujo de trabajo de reemplazo de exportación tiene este aspecto:Arrastra y coloca la actividad Sequence en la rama Then vacía de la primera actividad IF. Arrastra y coloca la actividad WebSeviceCall dentro de la actividad Sequence. Selecciona el nombre de servicio SAPECC, el punto de conexión ZSAPCONNECTORWS y la operación BAPI_USER_CHANGE. Haz clic en el botón Argumentos ... para definir los parámetros para la llamada del servicio Web de la siguiente manera:
Nombre | Dirección | Tipo | Valor |
---|---|---|---|
ADDRESS | In | BAPIADDR3 | address |
ADDRESSX | In | BAPIADDR3X | addressX |
COMPANY | In | BAPIUSCOMP | company |
COMPANYX | In | BAPIUSCOMX | company |
DEFAULTS | In | BAPIDEFAUL | defaults |
DEFAULTSX | In | BAPIDEFAX | defaultsX |
LOGONDATA | In | BAPILOGOND | logOnData |
LOGONDATAX | In | BAPILOGONX | logOnDataX |
RETURN | In/Out | TABLE_OF_BAPIRET2 | bapiret2Table |
USERNAME | In | String | userName |
- Haz clic en Aceptar. El signo de advertencia desaparece. El flujo de trabajo de reemplazo de exportación tiene este aspecto:
- Para procesar los resultados de la solicitud de usuario, arrastra y coloca la actividad IF dentro de la actividad Sequence después de la actividad WebServiceCall. Escribe la siguiente condición:
Not IsNothing(bapiret2Table.item) AndAlso bapiret2Table.item.Count(Function(errItem) errItem.TYPE.Equals("E") = True) <> 0
- Si no se produce ningún error, se supone que la operación de exportación se completó correctamente y queremos indicar la exportación correcta de este objeto mediante la creación de
CSEntryChangeResult
con el estado Correcto. Arrastra y coloca la actividadCreateCSEntryChangeResult
en la rama Else de la actividad IF y selecciona código de error correcto. - Arrastra y coloca la actividad Sequence en la rama Then de la actividad IF. Agrega la actividad Log con el valor LogText de
string.Join("\n",bapiret2Table.item.Where(Function(retItem) retItem.TYPE.Equals("E")).Select(Function(r) r.MESSAGE))
y la etiqueta Error. Agrega la actividadCreateCSEntryChangeResult
después de la actividad Log con código de errorExportErrorCustomContinueRun
. El flujo de trabajo de reemplazo de exportación tiene este aspecto:
Has completado la definición del flujo de trabajo de reemplazo de exportación.
El siguiente paso consiste en configurar el conector de servicios Web ECMA2Host mediante esta plantilla.