@Override public String debugDump() { return debugDump(0); }
private String getOidFromChange(Change change) { String shadowOid = null; if (change.getObjectDelta() != null && change.getObjectDelta().getOid() != null) { shadowOid = change.getObjectDelta().getOid(); } else { if (change.getCurrentShadow().getOid() != null) { shadowOid = change.getCurrentShadow().getOid(); } else { if (change.getOldShadow().getOid() != null) { shadowOid = change.getOldShadow().getOid(); } else { throw new IllegalArgumentException("No oid value defined for the object to synchronize."); } } } return shadowOid; }
SecurityViolationException, ObjectNotFoundException, ExpressionEvaluationException, EncryptionException { PrismObject<ShadowType> shadow = change.getCurrentShadow(); if (change.getObjectDelta() != null) { if (change.getObjectDelta().isAdd()) { shadow = (PrismObject<ShadowType>) change.getObjectDelta().getObjectToAdd(); } else if (change.getObjectDelta().isDelete()) { } catch (SchemaException ex) { parentResult.recordFatalError("Can't create shadow from identifiers: " + change.getIdentifiers()); throw new SchemaException("Can't create shadow from identifiers: " + change.getIdentifiers());
private void deleteShadowFromRepoIfNeeded(Change change, OperationResult parentResult) throws ObjectNotFoundException { if (change.getObjectDelta() != null && change.getObjectDelta().getChangeType() == ChangeType.DELETE && change.getOldShadow() != null) { LOGGER.trace("Deleting detected shadow object form repository."); try { repositoryService.deleteObject(ShadowType.class, change.getOldShadow().getOid(), parentResult); LOGGER.debug("Shadow object successfully deleted form repository."); } catch (ObjectNotFoundException ex) { // What we want to delete is already deleted. Not a big problem. LOGGER.debug("Shadow object {} already deleted from repository ({})", change.getOldShadow(), ex); parentResult.recordHandledError( "Shadow object " + change.getOldShadow() + " already deleted from repository", ex); } } }
while (iterator.hasNext()) { Change change = iterator.next(); LOGGER.trace("Original change:\n{}", change.debugDump()); if (change.isTokenOnly()) { continue; PrismObject<ShadowType> currentShadow = change.getCurrentShadow(); ObjectClassComplexTypeDefinition changeObjectClassDefinition = change.getObjectClassDefinition(); if (changeObjectClassDefinition == null) { if (!ctx.isWildcard() || change.getObjectDelta() == null || !change.getObjectDelta().isDelete()) { throw new SchemaException("No object class definition in change "+change); change.setObjectClassDefinition(shadowCtx.getObjectClassDefinition()); if (change.getObjectDelta() == null || !change.getObjectDelta().isDelete()) { if (currentShadow == null) { LOGGER.trace("Re-fetching object {} because it is not in the change", change.getIdentifiers()); currentShadow = fetchResourceObject(shadowCtx, change.getIdentifiers(), shadowAttrsToReturn, true, parentResult); // todo consider whether it is always necessary to fetch the entitlements change.setCurrentShadow(currentShadow); change.getIdentifiers()); identification.validatePrimaryIdenfiers(); LOGGER.trace("Re-fetching object {} because of attrsToReturn", identification); change.setCurrentShadow(processedCurrentShadow); LOGGER.trace("Processed change\n:{}", change.debugDump());
@Test public void test200FetchChanges() throws Exception { final String TEST_NAME = "test200FetchChanges"; TestUtil.displayTestTitle(this, TEST_NAME); OperationResult result = new OperationResult(this.getClass().getName() + "." + TEST_NAME); ObjectClassComplexTypeDefinition accountDefinition = resourceSchema.findObjectClassDefinition(OpenDJController.OBJECT_CLASS_INETORGPERSON_NAME); PrismProperty<Integer> lastToken = cc.fetchCurrentToken(accountDefinition, null, result); System.out.println("Property:"); System.out.println(SchemaDebugUtil.prettyPrint(lastToken)); System.out.println("token " + lastToken.toString()); assertNotNull("No last token", lastToken); assertNotNull("No last token value", lastToken.getRealValue()); List<Change> changes = cc.fetchChanges(accountDefinition, lastToken, null, null, result); display("Changes", changes); // Just one pseudo-change that updates the token AssertJUnit.assertEquals(1, changes.size()); Change change = changes.get(0); assertNull(change.getCurrentShadow()); assertNull(change.getIdentifiers()); assertNull(change.getObjectDelta()); assertNotNull(change.getToken()); }
if (change.isTokenOnly()) { LOGGER.trace("Found token-only change: {}", change); task.setExtensionProperty(change.getToken()); continue; ObjectClassComplexTypeDefinition changeObjectClassDefinition = change.getObjectClassDefinition(); if (change.getObjectDelta() != null && change.getObjectDelta().isDelete()) { oldShadow = change.getOldShadow(); if (oldShadow == null) { oldShadow = shadowManager.findOrAddShadowFromChangeGlobalContext(ctx, change, if (change.getOldShadow() == null) { PrismProperty<?> newToken = change.getToken(); task.setExtensionProperty(newToken); processedChanges++; task.setExtensionProperty(change.getToken()); processedChanges++; task.incrementProgressAndStoreStatsIfNeeded();
Collection<ResourceAttribute<?>> identifiers = ConnIdUtil.convertToIdentifiers(icfDelta.getUid(), deltaObjClassDefinition, resourceSchema); Change change = new Change(identifiers, objectDelta, getToken(icfDelta.getToken())); change.setObjectClassDefinition(deltaObjClassDefinition); changeList.add(change); LOGGER.trace("END creating delta of type DELETE"); objectDelta.setObjectToAdd(currentShadow); Change change = new Change(identifiers, objectDelta, getToken(icfDelta.getToken())); change.setObjectClassDefinition(deltaObjClassDefinition); changeList.add(change); LOGGER.trace("END creating delta of type CREATE"); Change change = new Change(identifiers, currentShadow, getToken(icfDelta.getToken())); change.setObjectClassDefinition(deltaObjClassDefinition); changeList.add(change); LOGGER.trace("END creating delta of type {}:\n{}", icfDeltaType, change.debugDump());
change.setOldShadow(null); return; change.setOldShadow(oldShadow); if (change.getCurrentShadow() != null) { PrismObject<ShadowType> currentShadow = completeShadow(ctx, change.getCurrentShadow(), oldShadow, false, parentResult); change.setCurrentShadow(currentShadow); if (change.getObjectDelta() != null && change.getObjectDelta().getOid() == null) { change.getObjectDelta().setOid(oldShadow.getOid()); if (change.getObjectDelta() != null && change.getObjectDelta().isDelete()) { PrismObject<ShadowType> currentShadow = change.getCurrentShadow(); if (currentShadow == null) { currentShadow = oldShadow.clone(); change.setCurrentShadow(currentShadow);
@Override public void notifyEvent(ResourceEventDescription eventDescription, Task task, OperationResult parentResult) throws SchemaException, CommunicationException, ConfigurationException, SecurityViolationException, ObjectNotFoundException, GenericConnectorException, ObjectAlreadyExistsException, ExpressionEvaluationException { Validate.notNull(eventDescription, "Event description must not be null."); Validate.notNull(task, "Task must not be null."); Validate.notNull(parentResult, "Operation result must not be null"); LOGGER.trace("Received event notification with the description: {}", eventDescription.debugDump()); if (eventDescription.getCurrentShadow() == null && eventDescription.getDelta() == null){ throw new IllegalStateException("Neither current shadow, nor delta specified. It is required to have at least one of them specified."); } applyDefinitions(eventDescription, parentResult); PrismObject<ShadowType> shadow = null; shadow = eventDescription.getShadow(); ProvisioningContext ctx = provisioningContextFactory.create(shadow, task, parentResult); ctx.assertDefinition(); Collection<ResourceAttribute<?>> identifiers = ShadowUtil.getPrimaryIdentifiers(shadow); Change change = new Change(identifiers, eventDescription.getCurrentShadow(), eventDescription.getOldShadow(), eventDescription.getDelta()); ObjectClassComplexTypeDefinition objectClassDefinition = ShadowUtil.getObjectClassDefinition(shadow); change.setObjectClassDefinition(objectClassDefinition); LOGGER.trace("Start to precess change: {}", change.toString()); try { shadowCache.processChange(ctx, change, null, parentResult); } catch (EncryptionException e) { // TODO: better handling throw new SystemException(e.getMessage(), e); } LOGGER.trace("Change after processing {} . Start synchronizing.", change.toString()); shadowCache.processSynchronization(ctx, change, parentResult); }
@Test public void test101FetchAddChange() throws Exception { final String TEST_NAME = "test101FetchAddChange"; TestUtil.displayTestTitle(this, TEST_NAME); OperationResult result = new OperationResult(this.getClass().getName() + "." + TEST_NAME); ObjectClassComplexTypeDefinition accountDefinition = resourceSchema.findDefaultObjectClassDefinition(ShadowKindType.ACCOUNT); PrismProperty<?> lastToken = cc.fetchCurrentToken(accountDefinition, null, result); assertNotNull("No last sync token", lastToken); // Add account to the resource dummyResource.setSyncStyle(DummySyncStyle.DUMB); DummyAccount newAccount = new DummyAccount("blackbeard"); newAccount.addAttributeValues("fullname", "Edward Teach"); newAccount.setEnabled(true); newAccount.setPassword("shiverMEtimbers"); dummyResource.addAccount(newAccount); // WHEN List<Change> changes = cc.fetchChanges(accountDefinition, lastToken, null, null, result); AssertJUnit.assertEquals(1, changes.size()); Change change = changes.get(0); assertNotNull("null change", change); PrismObject<ShadowType> currentShadow = change.getCurrentShadow(); assertNotNull("null current shadow", currentShadow); PrismAsserts.assertParentConsistency(currentShadow); Collection<ResourceAttribute<?>> identifiers = change.getIdentifiers(); assertNotNull("null identifiers", identifiers); assertFalse("empty identifiers", identifiers.isEmpty()); }
@SuppressWarnings("rawtypes") private Collection<? extends ItemDelta> createShadowResultModification(Change change, OperationResult shadowResult) { PrismObjectDefinition<ShadowType> shadowDefinition = getResourceObjectShadowDefinition(); Collection<ItemDelta> modifications = new ArrayList<>(); PropertyDelta resultDelta = prismContext.deltaFactory().property().createModificationReplaceProperty(ShadowType.F_RESULT, shadowDefinition, shadowResult.createOperationResultType()); modifications.add(resultDelta); if (change.getObjectDelta() != null && change.getObjectDelta().getChangeType() == ChangeType.DELETE) { PropertyDelta failedOperationTypeDelta = prismContext.deltaFactory().property().createModificationReplaceProperty( ShadowType.F_FAILED_OPERATION_TYPE, shadowDefinition, FailedOperationTypeType.DELETE); modifications.add(failedOperationTypeDelta); } return modifications; }
private List<PrismObject<ShadowType>> searchShadowByIdenifiers(ProvisioningContext ctx, Change change, OperationResult parentResult) throws SchemaException, ConfigurationException, ObjectNotFoundException, CommunicationException, ExpressionEvaluationException { Collection<ResourceAttribute<?>> identifiers = change.getIdentifiers(); ObjectQuery query = createSearchShadowQuery(ctx, identifiers, true, prismContext, parentResult); List<PrismObject<ShadowType>> accountList = null; try { accountList = repositoryService.searchObjects(ShadowType.class, query, null, parentResult); } catch (SchemaException ex) { parentResult.recordFatalError( "Failed to search shadow according to the identifiers: " + identifiers + ". Reason: " + ex.getMessage(), ex); throw new SchemaException("Failed to search shadow according to the identifiers: " + identifiers + ". Reason: " + ex.getMessage(), ex); } MiscSchemaUtil.reduceSearchResult(accountList); return accountList; }
Change lastChange = new Change((ObjectDelta)null, getToken(lastReceivedToken)); LOGGER.trace("Adding last change: {}", lastChange); changeList.add(lastChange);
if ((change.getObjectDelta() != null && change.getObjectDelta().getChangeType() == ChangeType.DELETE)) { if (accountList.isEmpty()) { String oid = repositoryService.addObject(foundShadow, null, parentResult); foundShadow.setOid(oid); if (change.getObjectDelta() != null && change.getObjectDelta().getOid() == null) { change.getObjectDelta().setOid(oid);
@SuppressWarnings("unchecked") private ResourceObjectShadowChangeDescription createResourceShadowChangeDescription( Change change, ResourceType resourceType, String channel) { ResourceObjectShadowChangeDescription shadowChangeDescription = new ResourceObjectShadowChangeDescription(); shadowChangeDescription.setObjectDelta(change.getObjectDelta()); shadowChangeDescription.setResource(resourceType.asPrismObject()); shadowChangeDescription.setOldShadow(change.getOldShadow()); shadowChangeDescription.setCurrentShadow(change.getCurrentShadow()); if (null == channel) { shadowChangeDescription .setSourceChannel(QNameUtil.qNameToUri(SchemaConstants.CHANGE_CHANNEL_LIVE_SYNC)); } else { shadowChangeDescription.setSourceChannel(channel); } return shadowChangeDescription; }
if ((change.getObjectDelta() != null && change.getObjectDelta().getChangeType() == ChangeType.DELETE)) { if (accountList.isEmpty()) { String oid = repositoryService.addObject(newShadow, null, parentResult); newShadow.setOid(oid); if (change.getObjectDelta() != null && change.getObjectDelta().getOid() == null) { change.getObjectDelta().setOid(oid); if (change.getObjectDelta() != null && change.getObjectDelta().getChangeType() == ChangeType.DELETE) { List<ItemDelta<?, ?>> deadDeltas = prismContext.deltaFor(ShadowType.class) .item(ShadowType.F_DEAD).replace(true)