Skip to content

Commit 1c3b8ce

Browse files
committed
Added more config for the update and delete external sync
1 parent b1c0cbe commit 1c3b8ce

File tree

4 files changed

+66
-21
lines changed

4 files changed

+66
-21
lines changed

lib/EventListener/ObjectCreatedEventListener.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ public function handle(Event $event): void
4040
$synchronizations = $this->synchronizationService->findAllBySourceId(register: $object->getRegister(), schema: $object->getSchema());
4141
foreach ($synchronizations as $synchronization) {
4242
try {
43-
$this->synchronizationService->synchronize(synchronization: $synchronization, force: true, object: $object->jsonSerialize());
43+
$this->synchronizationService->synchronize(synchronization: $synchronization, force: true, object: $object->jsonSerialize(), mutationType: 'create');
4444
} catch (\Exception $e) {
4545
$this->logger->error('Failed to process object event: ' . $e->getMessage() . ' for synchronization ' . $synchronization->getId(), [
4646
'exception' => $e,

lib/EventListener/ObjectDeletedEventListener.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ public function handle(Event $event): void
4040
$synchronizations = $this->synchronizationService->findAllBySourceId(register: $object->getRegister(), schema: $object->getSchema());
4141
foreach ($synchronizations as $synchronization) {
4242
try {
43-
$this->synchronizationService->synchronize(synchronization: $synchronization, force: true, object: $object);
43+
$this->synchronizationService->synchronize(synchronization: $synchronization, force: true, object: $object, mutationType: 'delete');
4444
} catch (\Exception $e) {
4545
$this->logger->error('Failed to process object event: ' . $e->getMessage() . ' for synchronization ' . $synchronization->getId(), [
4646
'exception' => $e,

lib/EventListener/ObjectUpdatedEventListener.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,20 +27,20 @@ public function handle(Event $event): void
2727
return;
2828
}
2929

30-
if (method_exists($event, 'getObject') === false) {
30+
if (method_exists($event, 'getNewObject') === false) {
3131
return;
3232
}
3333

3434

35-
$object = $event->getObject();
36-
if ($object === null || $object->getRegister() === null || $object->getSchema() === null && $object->getObject() !== null) {
35+
$object = $event->getNewObject();
36+
if ($object === null || $object->getRegister() === null || $object->getSchema() === null && $object->getNewObject() !== null) {
3737
return;
3838
}
3939

4040
$synchronizations = $this->synchronizationService->findAllBySourceId(register: $object->getRegister(), schema: $object->getSchema());
4141
foreach ($synchronizations as $synchronization) {
4242
try {
43-
$this->synchronizationService->synchronize(synchronization: $synchronization, force: true, object: $object->jsonSerialize());
43+
$this->synchronizationService->synchronize(synchronization: $synchronization, force: true, object: $object->jsonSerialize(), mutationType: 'update');
4444
} catch (\Exception $e) {
4545
$this->logger->error('Failed to process object event: ' . $e->getMessage() . ' for synchronization ' . $synchronization->getId(), [
4646
'exception' => $e,

lib/Service/SynchronizationService.php

Lines changed: 60 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ class SynchronizationService
7171
const MERGE_EXTRA_DATA_OBJECT_LOCATION = 'mergeExtraData';
7272
const UNSET_CONFIG_KEY_LOCATION = 'unsetConfigKey';
7373
const FILE_TAG_TYPE = 'files';
74+
const VALID_MUTATION_TYPES = ['create', 'update', 'delete'];
7475

7576
public function __construct(
7677
CallService $callService,
@@ -120,10 +121,11 @@ public function findAllBySourceId($register, $schema) {
120121
* @param bool $isTest Whether this is a test run (does not persist data if true).
121122
* @param \OCA\OpenRegister\Db\ObjectEntity|array $object The object to be synchronized, also referenced so its updated in parent objects.
122123
* @param SynchronizationLog $log
124+
* @param string|null $mutationType If dealing with single object synchronization, the type of the mutation that will be handled, 'create', 'update' or 'delete'. Used for syncs to extern sources.
123125
*
124126
* @return SynchronizationContract|array|null Returns a synchronization contract, an array for test cases, or null if conditions are not met.
125127
*/
126-
private function synchronizeInternToExtern(Synchronization $synchronization, ?bool $isTest = false, ?bool $force = false, \OCA\OpenRegister\Db\ObjectEntity|array &$object, SynchronizationLog $log)
128+
private function synchronizeInternToExtern(Synchronization $synchronization, ?bool $isTest = false, ?bool $force = false, \OCA\OpenRegister\Db\ObjectEntity|array &$object, SynchronizationLog $log, ?string $mutationType = null)
127129
{
128130
if ($synchronization->getConditions() !== [] && !JsonLogic::apply($synchronization->getConditions(), $object)) {
129131

@@ -165,7 +167,7 @@ private function synchronizeInternToExtern(Synchronization $synchronization, ?bo
165167
$synchronizationContract->setOriginId($originId);
166168
}
167169

168-
$synchronizationContract = $this->synchronizeContract(synchronizationContract: $synchronizationContract, synchronization: $synchronization, object: $object, isTest: $isTest, force: $force, log: $log);
170+
$synchronizationContract = $this->synchronizeContract(synchronizationContract: $synchronizationContract, synchronization: $synchronization, object: $object, isTest: $isTest, force: $force, log: $log, mutationType: $mutationType);
169171

170172
if ($isTest === true && is_array($synchronizationContract) === true) {
171173
// If this is a log and contract array return for the test endpoint.
@@ -175,7 +177,7 @@ private function synchronizeInternToExtern(Synchronization $synchronization, ?bo
175177
}
176178
} else {
177179
// @todo this is wierd
178-
$synchronizationContract = $this->synchronizeContract(synchronizationContract: $synchronizationContract, synchronization: $synchronization, object: $object, isTest: $isTest, force: $force, log: $log);
180+
$synchronizationContract = $this->synchronizeContract(synchronizationContract: $synchronizationContract, synchronization: $synchronization, object: $object, isTest: $isTest, force: $force, log: $log, mutationType: $mutationType);
179181
if ($isTest === false && $synchronizationContract instanceof SynchronizationContract === true) {
180182
// If this is a regular synchronizationContract update it to the database.
181183
$this->synchronizationContractMapper->update(entity: $synchronizationContract);
@@ -298,6 +300,7 @@ private function synchronizeExternToIntern(
298300
* @param bool|null $isTest False by default, currently added for synchronziation-test endpoint
299301
* @param bool|null $force False by default, if true, the object will be updated regardless of changes
300302
* @param array|\OCA\OpenRegister\Db\ObjectEntity|null $object Object to synchronize, updated by reference
303+
* @param string|null $mutationType If dealing with single object synchronization, the type of the mutation that will be handled, 'create', 'update' or 'delete'. Used for syncs to extern sources.
301304
*
302305
* @return array
303306
* @throws ContainerExceptionInterface
@@ -315,8 +318,14 @@ public function synchronize(
315318
?bool $isTest = false,
316319
?bool $force = false,
317320
array|\OCA\OpenRegister\Db\ObjectEntity|null &$object = null,
321+
?string $mutationType = null
318322
): array
319323
{
324+
if ($mutationType !== null && in_array($mutationType, $this::VALID_MUTATION_TYPES) === false) {
325+
throw new Exception(sprintf('Invalid mutation type: %s given. Allowed mutation types are: %s', $mutationType, implode(', ', $this::VALID_MUTATION_TYPES)));
326+
}
327+
328+
320329
// Start execution time measurement
321330
$startTime = microtime(true);
322331

@@ -345,7 +354,7 @@ public function synchronize(
345354
// lets always create the log entry first, because we need its uuid later on for contractLogs
346355
$log['result']['type'] = 'internToExtern';
347356
$log = $this->synchronizationLogMapper->createFromArray($log);
348-
return [$this->synchronizeInternToExtern($synchronization, $isTest, $force, $object, $log)];
357+
return [$this->synchronizeInternToExtern(synchronization: $synchronization, isTest: $isTest, force: $force, object: $object, log: $log, mutationType: $mutationType)];
349358
}
350359

351360
$log['result']['type'] = 'externToIntern';
@@ -672,7 +681,8 @@ public function deleteInvalidObjects(Synchronization $synchronization, ?array $s
672681
* @param bool|null $isTest False by default, currently added for synchronization-test endpoint
673682
* @param bool|null $force False by default, if true, the object will be updated regardless of changes
674683
* @param SynchronizationLog|null $log The log to update
675-
*
684+
* @param string|null $mutationType If dealing with single object synchronization, the type of the mutation that will be handled, 'create', 'update' or 'delete'. Used for syncs to extern sources.
685+
*
676686
* @return SynchronizationContract|Exception|array
677687
* @throws ContainerExceptionInterface
678688
* @throws NotFoundExceptionInterface
@@ -687,6 +697,7 @@ public function synchronizeContract(
687697
?bool $isTest = false,
688698
?bool $force = false,
689699
?SynchronizationLog $log = null,
700+
?string $mutationType = null
690701
): SynchronizationContract|Exception|array
691702
{
692703
$contractLog = null;
@@ -798,7 +809,8 @@ public function synchronizeContract(
798809
// Update target and create log when not in test mode
799810
$synchronizationContract = $this->updateTarget(
800811
synchronizationContract: $synchronizationContract,
801-
targetObject: $object
812+
targetObject: $object,
813+
mutationType: $mutationType
802814
);
803815

804816
if ($synchronization->getTargetType() === 'register/schema') {
@@ -1082,6 +1094,7 @@ private function updateIdOnSubObject(string $synchronizationId, array $subObject
10821094
* @param SynchronizationContract $synchronizationContract
10831095
* @param array|null $targetObject
10841096
* @param string|null $action Determines what needs to be done with the target object, defaults to 'save'
1097+
* @param string|null $mutationType If dealing with single object synchronization, the type of the mutation that will be handled, 'create', 'update' or 'delete'. Used for syncs to extern sources.
10851098
*
10861099
* @return SynchronizationContract
10871100
* @throws ContainerExceptionInterface
@@ -1092,7 +1105,7 @@ private function updateIdOnSubObject(string $synchronizationId, array $subObject
10921105
* @throws \OCP\DB\Exception
10931106
* @throws Exception
10941107
*/
1095-
public function updateTarget(SynchronizationContract $synchronizationContract, ?array &$targetObject = [], ?string $action = 'save'): SynchronizationContract
1108+
public function updateTarget(SynchronizationContract $synchronizationContract, ?array &$targetObject = [], ?string $action = 'save', ?string $mutationType = null): SynchronizationContract
10961109
{
10971110
// The function can be called solo set let's make sure we have the full synchronization object
10981111
if (isset($synchronization) === false) {
@@ -1113,7 +1126,7 @@ public function updateTarget(SynchronizationContract $synchronizationContract, ?
11131126
break;
11141127
case 'api':
11151128
$targetConfig = $synchronization->getTargetConfig();
1116-
$synchronizationContract = $this->writeObjectToTarget(synchronization: $synchronization, contract: $synchronizationContract, endpoint: $targetConfig['endpoint'] ?? '', targetObject: $targetObject);
1129+
$synchronizationContract = $this->writeObjectToTarget(synchronization: $synchronization, contract: $synchronizationContract, endpoint: $targetConfig['endpoint'] ?? '', targetObject: $targetObject, mutationType: $mutationType);
11171130
break;
11181131
case 'database':
11191132
//@todo: implement
@@ -1507,6 +1520,7 @@ public function getAllObjectsFromArray(array $array, Synchronization $synchroniz
15071520
* @param SynchronizationContract $contract The contract to enforce.
15081521
* @param string $endpoint The endpoint to write the object to.
15091522
* @param array|null $targetObject Update referenced targetObject so we can return response here.
1523+
* @param string|null $mutationType If dealing with single object synchronization, the type of the mutation that will be handled, 'create', 'update' or 'delete'. Used for syncs to extern sources.
15101524
*
15111525
* @return SynchronizationContract The updated contract.
15121526
*
@@ -1522,6 +1536,7 @@ private function writeObjectToTarget(
15221536
SynchronizationContract $contract,
15231537
string $endpoint,
15241538
?array &$targetObject = null,
1539+
?string $mutationType = null
15251540
): SynchronizationContract
15261541
{
15271542
$target = $this->sourceMapper->find(id: $synchronization->getTargetId());
@@ -1549,10 +1564,27 @@ private function writeObjectToTarget(
15491564
$endpoint = str_replace(search: $target->getLocation(), replace: '', subject: $endpoint);
15501565
}
15511566

1552-
if ($contract->getOriginId() === null) {
1567+
if ($mutationType === 'delete') {
1568+
$method = 'DELETE';
1569+
1570+
// @todo check for {{targetId}} in endpoint and replace
1571+
if (isset($targetConfig['deleteEndpoint']) === true) {
1572+
$endpoint = $targetConfig['deleteEndpoint'];
1573+
} else {
1574+
$endpoint .= '/'.$contract->getTargetId();
1575+
}
1576+
1577+
if (isset($targetConfig['deleteMethod']) === true) {
1578+
$method = $targetConfig['deleteMethod'];
1579+
}
1580+
1581+
if (isset($targetConfig['deleteMapping']) === true) {
1582+
$deleteMapping = $this->mappingService->getMapping($targetConfig['deleteMapping']);
1583+
$targetConfig['json'] = $this->mappingService->executeMapping(mapping: $deleteMapping, input: $object);
1584+
}
1585+
1586+
$response = $this->callService->call(source: $target, endpoint: $endpoint, method: $method, config: $targetConfig)->getResponse();
15531587

1554-
$endpoint .= '/'.$contract->getTargetId();
1555-
$response = $this->callService->call(source: $target, endpoint: $endpoint, method: 'DELETE', config: $targetConfig)->getResponse();
15561588

15571589
$contract->setTargetHash(md5(serialize($response['body'])));
15581590
$contract->setTargetId(null);
@@ -1587,16 +1619,26 @@ private function writeObjectToTarget(
15871619
$data = array_merge($this->objectService->getOpenRegisters()->find(
15881620
id: $contract->getOriginId(),
15891621
)->getObject(), ['targetId' => $targetId], ['id' => $contract->getOriginId()]);
1590-
$this->objectService->getOpenRegisters()->saveObject(register: $this->objectService->getOpenRegisters()->getRegister(), schema: $this->objectService->getOpenRegisters()->getSchema(), object: $data);
1622+
$this->objectService->getOpenRegisters()->saveObject(register: $this->objectService->getOpenRegisters()->getRegister(), schema: $this->objectService->getOpenRegisters()->getSchema(), object: $data, throwEvent: false);
15911623

15921624
$contract->setTargetId($targetId);
1593-
15941625
return $contract;
15951626
}
15961627

1628+
$method = 'PUT';
15971629
$endpoint .= '/'.$contract->getTargetId();
15981630

1599-
$response = $this->callService->call(source: $target, endpoint: $endpoint, method: 'PUT', config: $targetConfig)->getResponse();
1631+
1632+
if (isset($targetConfig['updateEndpoint']) === true) {
1633+
$endpoint = $targetConfig['updateEndpoint'];
1634+
}
1635+
1636+
if (isset($targetConfig['updateMethod']) === true) {
1637+
$method = $targetConfig['updateMethod'];
1638+
}
1639+
1640+
1641+
$response = $this->callService->call(source: $target, endpoint: $endpoint, method: $method, config: $targetConfig)->getResponse();
16001642

16011643
$body = array_merge(json_decode($response['body']), ['targetId' => $contract->getTargetId()], true);
16021644
$targetObject = $body;
@@ -1705,7 +1747,10 @@ private function processSaveObjectRule(Rule $rule, array $data): array
17051747
$object = $this->objectService->getOpenRegisters()->getMapper('objectEntity')->find($id);
17061748
$data = array_merge($object->getObject(), ['id' => $object->getId()], $data);
17071749
}
1708-
return $objectService->saveObject(register: $register, schema: $schema, object: $data)->jsonSerialize();
1750+
1751+
$object = $objectService->saveObject(register: $register, schema: $schema, object: $data)->jsonSerialize();
1752+
1753+
return $object;
17091754
}
17101755

17111756
/**

0 commit comments

Comments
 (0)