Skip to content

Commit

Permalink
Entering repository cache at few more places (e.g. in provisioning wh…
Browse files Browse the repository at this point in the history
…en handling object found by iterative search).

Caching system configuration in model.
Allowing caching with non-null but harmless options in repo cache.
  • Loading branch information
mederly committed Dec 9, 2014
1 parent 1cdf2c4 commit e36b0ff
Show file tree
Hide file tree
Showing 7 changed files with 82 additions and 28 deletions.
Expand Up @@ -122,7 +122,7 @@ public static <T> T findRootOptions(Collection<SelectorOptions<T>> options) {
return null;
}

private boolean isRoot() {
public boolean isRoot() {
if (selector == null) {
return true;
}
Expand Down
Expand Up @@ -21,8 +21,7 @@
import javax.annotation.PostConstruct;
import javax.xml.namespace.QName;

import com.evolveum.midpoint.model.impl.importer.ImportAccountsFromResourceTaskHandler;
import com.evolveum.midpoint.prism.PrismProperty;
import com.evolveum.midpoint.repo.cache.RepositoryCache;
import com.evolveum.midpoint.util.logging.LoggingUtils;

import com.evolveum.prism.xml.ns._public.types_3.PolyStringType;
Expand Down Expand Up @@ -635,7 +634,8 @@ private boolean scanForUnfinishedOperations(Task task, String resourceOid, Recon
for (PrismObject<ShadowType> shadow : shadows) {
OperationResult provisioningResult = new OperationResult(OperationConstants.RECONCILIATION+".finishOperation");
try {

RepositoryCache.enter();

ProvisioningOperationOptions options = ProvisioningOperationOptions.createCompletePostponed(false);
Utils.clearRequestee(task);
provisioningService.finishOperation(shadow, options, task, provisioningResult);
Expand All @@ -651,6 +651,8 @@ private boolean scanForUnfinishedOperations(Task task, String resourceOid, Recon
} catch(Exception e) {
LoggingUtils.logException(LOGGER, "Failed to record finish operation failure with shadow: " + ObjectTypeUtil.toShortString(shadow.asObjectable()), e);
}
} finally {
RepositoryCache.exit();
}

incrementAndRecordProgress(task, opResult);
Expand Down
Expand Up @@ -466,11 +466,29 @@ public static String getPolicyDesc(ObjectSynchronizationType synchronizationPoli
return synchronizationPolicy.toString();
}

public static PrismObject<SystemConfigurationType> cachedSystemConfiguration = null;
public static long cachedSystemConfigurationRetrieveTimestamp = 0;
private static final long CACHED_SYSTEM_CONFIGURATION_TTL = 120000L; // just to avoid stalled data if version is not incremented for any reason

public static PrismObject<SystemConfigurationType> getSystemConfiguration(RepositoryService repositoryService, OperationResult result) throws SchemaException {
PrismObject<SystemConfigurationType> systemConfiguration = null;
if (cachedSystemConfiguration != null && cachedSystemConfigurationRetrieveTimestamp + CACHED_SYSTEM_CONFIGURATION_TTL >= System.currentTimeMillis()) {
String currentVersion;
try {
currentVersion = repositoryService.getVersion(SystemConfigurationType.class, SystemObjectsType.SYSTEM_CONFIGURATION.value(), result);
} catch (ObjectNotFoundException e) {
// see below
LOGGER.warn("System configuration object was not found (should not happen!)");
return null;
}
if (currentVersion != null || currentVersion.equals(cachedSystemConfiguration.getVersion())) {
LOGGER.trace("Using cached system configuration object; version = {}", currentVersion);
return cachedSystemConfiguration.clone();
}
}
try {
systemConfiguration = repositoryService.getObject(SystemConfigurationType.class, SystemObjectsType.SYSTEM_CONFIGURATION.value(),
SelectorOptions.createCollection(GetOperationOptions.createAllowNotFound()), result);
systemConfiguration = repositoryService.getObject(SystemConfigurationType.class, SystemObjectsType.SYSTEM_CONFIGURATION.value(),
SelectorOptions.createCollection(GetOperationOptions.createAllowNotFound()), result);
} catch (ObjectNotFoundException e) {
// just go on ... we will return and continue
// This is needed e.g. to set up new system configuration is the old one gets deleted
Expand All @@ -481,6 +499,8 @@ public static PrismObject<SystemConfigurationType> getSystemConfiguration(Reposi
LOGGER.warn("System configuration object is null (should not happen!)");
return null;
}
cachedSystemConfiguration = systemConfiguration.clone();
cachedSystemConfigurationRetrieveTimestamp = System.currentTimeMillis();
return systemConfiguration;
}
}
11 changes: 5 additions & 6 deletions provisioning/provisioning-impl/pom.xml
Expand Up @@ -55,6 +55,11 @@
<artifactId>repo-api</artifactId>
<version>3.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.evolveum.midpoint.repo</groupId>
<artifactId>repo-cache</artifactId>
<version>3.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.evolveum.midpoint.repo</groupId>
<artifactId>system-init</artifactId>
Expand Down Expand Up @@ -109,12 +114,6 @@
<version>3.1-SNAPSHOT</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.evolveum.midpoint.repo</groupId>
<artifactId>repo-cache</artifactId>
<version>3.1-SNAPSHOT</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.evolveum.midpoint.repo</groupId>
<artifactId>task-quartz-impl</artifactId>
Expand Down
Expand Up @@ -32,6 +32,7 @@

import com.evolveum.midpoint.common.refinery.RefinedAssociationDefinition;
import com.evolveum.midpoint.prism.PrismContainerValue;
import com.evolveum.midpoint.repo.cache.RepositoryCache;
import com.evolveum.midpoint.xml.ns._public.common.common_3.AttributeFetchStrategyType;
import com.evolveum.midpoint.xml.ns._public.resource.capabilities_3.AddRemoveAttributeValuesCapabilityType;

Expand Down Expand Up @@ -985,16 +986,22 @@ public SearchResultMetadata searchResourceObjects(final ConnectorInstance connec
ResultHandler<ShadowType> innerResultHandler = new ResultHandler<ShadowType>() {
@Override
public boolean handle(PrismObject<ShadowType> shadow) {
// in order to utilize the cache right from the beginning...
RepositoryCache.enter();
try {
shadow = postProcessResourceObjectRead(connector, resourceType, shadow, objectClassDef, fetchAssociations, parentResult);
} catch (SchemaException e) {
throw new TunnelException(e);
} catch (CommunicationException e) {
throw new TunnelException(e);
} catch (GenericFrameworkException e) {
throw new TunnelException(e);
try {
shadow = postProcessResourceObjectRead(connector, resourceType, shadow, objectClassDef, fetchAssociations, parentResult);
} catch (SchemaException e) {
throw new TunnelException(e);
} catch (CommunicationException e) {
throw new TunnelException(e);
} catch (GenericFrameworkException e) {
throw new TunnelException(e);
}
return resultHandler.handle(shadow);
} finally {
RepositoryCache.exit();
}
return resultHandler.handle(shadow);
}
};

Expand Down
Expand Up @@ -103,7 +103,7 @@ public static String debugDump() {
@Override
public <T extends ObjectType> PrismObject<T> getObject(Class<T> type, String oid,
Collection<SelectorOptions<GetOperationOptions>> options, OperationResult parentResult) throws ObjectNotFoundException, SchemaException {
if (!isCacheable(type) || options != null) {
if (!isCacheable(type) || !nullOrHarmlessOptions(options)) {
log("Cache: PASS {} ({})", oid, type.getSimpleName());
return repository.getObject(type, oid, options, parentResult);
}
Expand Down Expand Up @@ -153,7 +153,7 @@ public <T extends ObjectType> String addObject(PrismObject<T> object, RepoAddOpt
@Override
public <T extends ObjectType> SearchResultList<PrismObject<T>> searchObjects(Class<T> type, ObjectQuery query,
Collection<SelectorOptions<GetOperationOptions>> options, OperationResult parentResult) throws SchemaException {
if (!isCacheable(type) || options != null) {
if (!isCacheable(type) || !nullOrHarmlessOptions(options)) {
log("Cache: PASS ({})", type.getSimpleName());
return repository.searchObjects(type, query, options, parentResult);
}
Expand Down Expand Up @@ -234,8 +234,30 @@ public <T extends ObjectType> void deleteObject(Class<T> type, String oid, Opera
@Override
public <F extends FocusType> PrismObject<F> searchShadowOwner(
String shadowOid, Collection<SelectorOptions<GetOperationOptions>> options, OperationResult parentResult) throws ObjectNotFoundException {
// TODO cache?
return repository.searchShadowOwner(shadowOid, options, parentResult);
// TODO cache the search operation?
PrismObject<F> ownerObject = repository.searchShadowOwner(shadowOid, options, parentResult);
if (ownerObject != null && nullOrHarmlessOptions(options)) {
cacheObject(getCache(), ownerObject);
}
return ownerObject;
}

private boolean nullOrHarmlessOptions(Collection<SelectorOptions<GetOperationOptions>> options) {
if (options == null || options.isEmpty()) {
return true;
}
if (options.size() > 1) {
return false;
}
SelectorOptions<GetOperationOptions> selectorOptions = options.iterator().next();
if (!selectorOptions.isRoot()) {
return false;
}
GetOperationOptions options1 = selectorOptions.getOptions();
if (options1 == null || options1.equals(new GetOperationOptions()) || options1.equals(GetOperationOptions.createAllowNotFound())) {
return true;
}
return false;
}

@Override
Expand Down
Expand Up @@ -214,7 +214,7 @@ private void assertUser(String name, Task task, OperationResult result) throws c
//assertEquals("Wrong number of assignments", 4, user.getAssignment().size());
}

@Test(enabled = false)
@Test
public void test120BigReconciliation() throws Exception {
final String TEST_NAME = "test120BigReconciliation";
TestUtil.displayTestTile(this, TEST_NAME);
Expand All @@ -239,16 +239,20 @@ public void test120BigReconciliation() throws Exception {
// OperationResult subresult = result.getLastSubresult();
// TestUtil.assertInProgress("reconciliation launch result", subresult);

waitForTaskFinish(task, true, 20000 + NUM_LDAP_ENTRIES*2000);
waitForTaskFinish(task, true, 20000 + NUM_LDAP_ENTRIES*2000, 10000L);

// THEN
TestUtil.displayThen(TEST_NAME);

int userCount = modelService.countObjects(UserType.class, null, null, task, result);
display("Users", userCount);
assertEquals("Unexpected number of users", NUM_LDAP_ENTRIES+4, userCount);
assertEquals("Unexpected number of users", NUM_LDAP_ENTRIES+1, userCount);

assertUser("u1", task, result);
display("e0(u0)", findUserByUsername("e0(u0)"));
display("e1(u1)", findUserByUsername("e1(u1)"));

assertUser("e0(u0)", task, result);
assertUser("e1(u1)", task, result);
}

private void loadEntries(String prefix) throws LDIFException, IOException {
Expand Down

0 comments on commit e36b0ff

Please sign in to comment.