Ir para o conteúdo

Capture Alterações de Dados com Consultas Baseadas em Carimbo de Data/hora

Caso de Uso

Os dados, como alterações de dados mestre ou novas transações, devem ser movidos de uma origem para um destino. Uma consultar periódica, sustentada por uma programação, incluirá uma condição que usa um carimbo de data/hora para selecionar os registros da origem que devem ser processados no destino.

Existem várias considerações:

  • Armazenamento persistente dos dados do carimbo de data/hora
  • Evite um 'loop infinito', onde as mudanças feitas pelo Jitterbit no alvo são captadas e aplicadas de volta na fonte, e assim por diante.
  • O isolamento de alterações intencionais de alterações não intencionais na fonte, como dados alterados por um acionador, não deve ser incluído, mas os dados alterados por um usuário devem.

Existem prós e contras nessa abordagem em comparação com uma abordagem push baseada em eventos/em tempo real.

  • Prós:
    • Se o destino não estiver disponível, a origem continuará tentando mover os dados até que esteja completo.
    • Pode 'retroceder' o timestamp para permitir novas execuções
    • Pode começar relativamente rápido
    • Mais fácil de desenvolver e testar usando conjuntos de dados menores.
    • Pode controlar melhor o tamanho dos dados a serem processados.
    • Se um 'write-back' para a origem for implementado, você poderá rastrear a atividade de integração da origem para o destino.
  • Contras:
    • Aplicável somente se um carimbo de data/hora estiver disponível ou uma condição de consultar puder ser construída.
    • Pesquisas/consultas podem ser mais complicadas do que baseadas em eventos.
      • O primeiro requer um armazenamento de dados de carimbo de data/hora, consultas com condições e possivelmente outros filtros e é sensível a alterações de esquema na origem. Neste último, o Jitterbit está simplesmente recebendo um payload. Desde que esse esquema não mude, os sistemas são acoplados de forma mais flexível, o que é uma vantagem do ponto de vista do desenvolvimento.
    • Mova a sobrecarga administrativa da ferramenta de integração. Por exemplo, se você precisar interromper um fluxo ou precisar alterar/atualizar a programação no Jitterbit, que é uma alteração na configuração do software. Para muitas empresas, fazer uma alteração é um processo de controle de software e requer mais etapas. Com um processo orientado a eventos, a alteração é feita na origem.
    • Como os timestamps geralmente são gerados pelo sistema, eles não acomodam regras de negócios, o que leva à inclusão de regras de negócios no middleware e scripts extensos. Do ponto de vista da arquitetura corporativa, as regras de negócios devem ser mantidas apenas nos aplicativos. Como veremos neste exemplo, há extensos scripts de regras de negócios.

Nota

Este padrão de design usa Design Studio como um exemplo; você pode aplicar os mesmos conceitos em Cloud Studio usando etapas semelhantes.

Exemplo

Consultar o NetSuite, atualizar o Salesforce

anexo

JB Sync: Obter Script de Carimbo de Data/hora

Os carimbos de data/hora são armazenados no SFDC e uma consultar obtém o ID de sincronização e o próprio carimbo de data/hora. Observe que os timestamps são UTC e os valores são retornados em uma 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);

Obter Sync_Time

Use uma função salesforce para obter a hora atual, que será usada para atualizar o registro JB Sync. Observe que isso está sendo feito antes da consultar NS em vez de após o upsert SFDC, que é o método mais tradicional. No entanto, descobriu-se que os registros estavam sendo perdidos, pois estavam sendo feitas alterações na fonte que ocorreram entre o momento em que a consultar foi feita e o momento em que o upsert foi concluído. A decisão foi usar essa abordagem, mesmo à custa de pegar os mesmos registros na consultar de origem. Observe também que não há 'write-back' nos registros selecionados para atualizá-los com base em uma atualização bem-sucedida no SFDC. Se isso fosse implementado, uma consultar poderia ser construída para não selecionar registros duplicados.

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

Passe a variável global synctimestampticket para a consultar

anexo

Mapeamento

Uma condição é usada para filtrar ainda mais os dados.

anexo

Doença

O requisito era filtrar determinados sites com base em datas até que o lançamento nacional fosse concluído. Como a consultar não filtra com base nos requisitos de alteração de data, uma condição é usada dentro da transformação.

Os dados recebidos são gravados no log de operação. Em seguida, os IDs internos do local são verificados e, se o local estiver no escopo, a última modificação do registro por valor é verificada e, se feita por Jitterbit, é sinalizada para ser ignorada.

Como os valores LMB dependem do ambiente, uma verificação é feita no ambiente atual.

Em seguida, o registro é verificado em relação a uma lista de intervalos de datas, pois os registros anteriores a um determinado horário são excluídos. Se o registro passar em todos os testes, ele será usado.

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

Depois que os dados são gravados em um arquivo temporário, Update Jitterbit Syncs é chamado:

anexo

anexo

anexo

Finalmente, a operação A02 é chamada se houver algum registro a ser processado.