Saltar al contenido

Capture Cambios de Datos con Consultas Basadas en Marcas de Tiempo

Caso de Uso

Los datos, como los cambios en los datos maestros o las nuevas transacciones, deben trasladarse de un origen a un destino. Una consultar periódica, respaldada por un cronograma, incluirá una condición que utiliza una marca de tiempo para seleccionar los registros del origen que deben procesarse en el destino.

Hay varias consideraciones:

  • Almacenamiento persistente de los datos de la marca de tiempo
  • Evite un 'bucle infinito', donde los cambios realizados por Jitterbit en el destino se recogen y se aplican de nuevo a la fuente, y así sucesivamente.
  • No se debe incluir el aislamiento de los cambios previstos de los cambios no previstos en la fuente, como los datos modificados por un activador, pero sí los datos modificados por un usuario.

Hay pros y contras de este enfoque frente a un enfoque de inserción basado en eventos/en tiempo real.

  • Ventajas:
    • Si el destino no está disponible, el origen seguirá intentando mover los datos hasta que esté completo.
    • Puede 'retroceder' la marca de tiempo para permitir repeticiones
    • Puede comenzar relativamente rápido
    • Más fácil de desarrollar y probar mediante el uso de conjuntos de datos más pequeños.
    • Puede controlar mejor el tamaño de los datos a procesar.
    • Si se implementa una 'reescritura' en el origen, puede rastrear la actividad de integración desde el origen hasta el destino.
  • Contras:
    • Solo se aplica si hay una marca de tiempo disponible o se puede construir una condición de consultar.
    • Las encuestas/consultas pueden ser más complicadas que las basadas en eventos.
      • El primero requiere un almacén de datos de marca de tiempo, consultas con condiciones y posiblemente otros filtros, y es sensible a los cambios de esquema en la fuente. En este último, Jitterbit simplemente recibe una carga útil. Siempre que ese esquema no cambie, los sistemas estarán más débilmente acoplados, lo que es una ventaja desde el punto de vista del desarrollo.
    • Mover la sobrecarga administrativa de la herramienta de integración. Por ejemplo, si necesita detener un flujo o necesita cambiar/actualizar la programación en Jitterbit, que es un cambio de configuración de software. Para muchas empresas, realizar un cambio está sujeto a un proceso de control de software y requiere más pasos. Con un proceso dirigido por eventos, el cambio se realiza en la fuente.
    • Dado que las marcas de tiempo generalmente son generadas por el sistema, no se adaptan a las reglas comerciales, lo que lleva a incluir reglas comerciales en el middleware y secuencias de comandos extensas. Desde el punto de vista de la arquitectura empresarial, las reglas comerciales deben mantenerse solo en las aplicaciones. Como veremos en este ejemplo, hay una gran cantidad de secuencias de comandos de reglas comerciales.

Nota

Este patrón de diseño usa Design Studio como ejemplo; puede aplicar los mismos conceptos en Cloud Studio usando pasos similares.

Ejemplo

Consultar NetSuite, actualizar Salesforce

adjunto

JB Sync: Obtener Secuencia de Comandos de Marca de Tiempo

Las marcas de tiempo se almacenan en SFDC y una consultar obtiene el ID de sincronización y la marca de tiempo en sí. Tenga en cuenta que las marcas de tiempo son UTC y los valores se devuelven en una matriz.

$result = SfLookupAll("<TAG>Salesforce Orgs/sysadmin@example.com</TAG>",
    "Select Id, Object_Last_Modified_Date_del__c from Jitterbit_Syncs__c where Object_Name_del__c = 'Ticket'");
$Jitterbit_SyncsId = Get($result,0,0);
$synctimestampticket = Get($result,0,1);

Obtener Sync_Time

Utilice una función de Salesforce para obtener la hora actual, que se utilizará para actualizar el registro JB Sync. Tenga en cuenta que esto se hace antes de la consultar NS en lugar de después de la inserción de SFDC, que es el método más tradicional. Sin embargo, se descubrió que se estaban perdiendo registros porque se estaban realizando cambios en la fuente que ocurrieron entre el momento en que se realizó la consultar y el momento en que finalizó la inserción. Se tomó la decisión de utilizar este enfoque, incluso a expensas de seleccionar los mismos registros en la consultar de origen. También tenga en cuenta que no hay 'reescritura' en los registros seleccionados para actualizarlos en función de una inserción exitosa en SFDC. Si eso se implementara, entonces se podría construir una consultar que no detectaría registros duplicados.

$Sync_Time = GetUTCFormattedDateTime(
    LoginToSalesforceAndGetTimestamp("<TAG>Salesforce Orgs/sysadmin@example.com</TAG>","UTC"),"UTC",false);

Pase la variable global synctimestampticket a la consultar

adjunto

Cartografía

Se utiliza una condición para filtrar aún más los datos.

adjunto

Condición

El requisito era filtrar ciertos sitios en función de las fechas hasta que se completara la implementación a nivel nacional. Dado que la consultar no filtra en función de los requisitos de fecha cambiante, se utiliza una condición dentro de la transformación.

Los datos entrantes se escriben en el registro de operación. Luego, se verifican los ID internos de la ubicación y, si la ubicación está dentro del alcance, se verifica el último valor modificado por valor del registro y, si lo hizo Jitterbit, se marca para que se omita.

Dado que los valores de LMB dependen del entorno, se realiza una comprobación en el ambiente actual.

A continuación, el registro se compara con una lista de rangos de fechas, ya que se excluyen los registros anteriores a un tiempo determinado. Si el registro pasa todas las pruebas, se utilizará.

WriteToOperationLog(
"----------"+"\r\n"+
"Int id: "+searchResponse$searchResult$recordList$record.SalesOrder$internalId+"\r\n"+
"Ord id: "+searchResponse$searchResult$recordList$record.SalesOrder$tranId$ +"\r\n"+
"LMD: " +searchResponse$searchResult$recordList$record.SalesOrder$lastModifiedDate$+"\r\n"+
"Loc: " +searchResponse$searchResult$recordList$record.SalesOrder$location$internalId+"\r\n"+
"LMB: " +searchResponse$searchResult$recordList$record.SalesOrder$customFieldList$Last_Modified_By$value$internalId+"\r\n"+
"Cust:" +searchResponse$searchResult$recordList$record.SalesOrder$entity$internalId);
If(searchResponse$searchResult$recordList$record.SalesOrder$location$internalId==25||
 searchResponse$searchResult$recordList$record.SalesOrder$location$internalId==6||
 searchResponse$searchResult$recordList$record.SalesOrder$location$internalId==3||
 searchResponse$searchResult$recordList$record.SalesOrder$location$internalId==10||
 searchResponse$searchResult$recordList$record.SalesOrder$location$internalId==4||
 searchResponse$searchResult$recordList$record.SalesOrder$location$internalId==18||
 searchResponse$searchResult$recordList$record.SalesOrder$location$internalId==26||
 searchResponse$searchResult$recordList$record.SalesOrder$location$internalId==29||
 searchResponse$searchResult$recordList$record.SalesOrder$location$internalId==16||
 searchResponse$searchResult$recordList$record.SalesOrder$location$internalId==22||
 searchResponse$searchResult$recordList$record.SalesOrder$location$internalId==14||
 searchResponse$searchResult$recordList$record.SalesOrder$location$internalId==15||
 searchResponse$searchResult$recordList$record.SalesOrder$location$internalId==35||
 searchResponse$searchResult$recordList$record.SalesOrder$location$internalId==19||
 searchResponse$searchResult$recordList$record.SalesOrder$location$internalId==17||
 searchResponse$searchResult$recordList$record.SalesOrder$location$internalId==12||


 searchResponse$searchResult$recordList$record.SalesOrder$location$internalId==84,

 $loccheck = true,
 $loccheck = false);
//exclude changes in NS made by Jitterbit
If($loccheck && GetEnvironmentName()=='DEV',
 If(
 searchResponse$searchResult$recordList$record.SalesOrder$customFieldList$Last_Modified_By$value$internalId=='9836'||
 searchResponse$searchResult$recordList$record.SalesOrder$customFieldList$Last_Modified_By$value$internalId=='9837'||
 searchResponse$searchResult$recordList$record.SalesOrder$customFieldList$Last_Modified_By$value$internalId=='9838',
 $idcheck = false,
 $idcheck = true));
If($loccheck && GetEnvironmentName()=='PROD',
 If(
 searchResponse$searchResult$recordList$record.SalesOrder$customFieldList$Last_Modified_By$value$internalId=='10780'||
 searchResponse$searchResult$recordList$record.SalesOrder$customFieldList$Last_Modified_By$value$internalId=='10781'||
 searchResponse$searchResult$recordList$record.SalesOrder$customFieldList$Last_Modified_By$value$internalId=='9631',
 $idcheck = false,
 $idcheck = true));
Case(
 $loccheck==false, $result=false;WriteToOperationLog("Skip loc"),
$loccheck==true && $idcheck == false, $result = false; WriteToOperationLog("Skip id"),
$loccheck==true && $idcheck == true,$result = true; WriteToOperationLog("Pass")
 );

// region & timestamp check
If($result == true && (searchResponse$searchResult$recordList$record.SalesOrder$location$internalId==4||
 searchResponse$searchResult$recordList$record.SalesOrder$location$internalId==26),
//check create date not before point in time when region went live. For these two regions, that is 2015-09-13T13:00:00Z
 If(Date(GetUtCFormattedDateTime(searchResponse$searchResult$recordList$record.SalesOrder$createdDate$,"UTC",false))
< Date(GetUTCFormattedDateTime("2015-09-13T13:00:00Z","UTC",false)),
 $result = false;
 WriteToOperationLog("Colo Region ticket before 2015-09-13"))
);
If($result == true && searchResponse$searchResult$recordList$record.SalesOrder$location$internalId==18,
//check create date not before point in time when region went live.
 If(Date(GetUtCFormattedDateTime(searchResponse$searchResult$recordList$record.SalesOrder$createdDate$,"UTC",false))
< Date(GetUTCFormattedDateTime("2015-09-20T13:00:00Z","UTC",false)),
 $result = false;
 WriteToOperationLog("Williston Region ticket before 2015-09-20"))
);
If($result == true && searchResponse$searchResult$recordList$record.SalesOrder$location$internalId==29,
//check create date not before point in time when region went live.
 If(Date(GetUtCFormattedDateTime(searchResponse$searchResult$recordList$record.SalesOrder$createdDate$,"UTC",false))
< Date(GetUTCFormattedDateTime("2015-09-23T16:00:00Z","UTC",false)),
 $result = false;
 WriteToOperationLog("Caspar Region ticket before 2015-09-23")
 )
);
//AR
If($result == true && searchResponse$searchResult$recordList$record.SalesOrder$location$internalId==16,
//check create date not before point in time when region went live.
 If(Date(GetUtCFormattedDateTime(searchResponse$searchResult$recordList$record.SalesOrder$createdDate$,"UTC",false))
< Date(GetUTCFormattedDateTime("2015-10-04T12:00:00Z","UTC",false)),
 $result = false;
 WriteToOperationLog("AR Region ticket before 2015-10-4")
 )
);
//DFW
If($result == true && searchResponse$searchResult$recordList$record.SalesOrder$location$internalId==22||
searchResponse$searchResult$recordList$record.SalesOrder$location$internalId==14||
searchResponse$searchResult$recordList$record.SalesOrder$location$internalId==15||
searchResponse$searchResult$recordList$record.SalesOrder$location$internalId==17||
searchResponse$searchResult$recordList$record.SalesOrder$location$internalId==35,
//check create date not before point in time when region went live.
 If(Date(GetUtCFormattedDateTime(searchResponse$searchResult$recordList$record.SalesOrder$createdDate$,"UTC",false))
< Date(GetUTCFormattedDateTime("2015-10-11T08:00:00Z","UTC",false)),
 $result = false;
 WriteToOperationLog("DFW Region ticket before 2015-10-11")
 )
);
$result

Una vez que los datos se escriben en un archivo temporal, se llama a Update Jitterbit Syncs:

adjunto

adjunto

adjunto

Finalmente, se llama a la operación A02 si hay registros para procesar.