public static <T> Collection<SelectorOptions<T>> updateRootOptions(Collection<SelectorOptions<T>> options, Consumer<T> updater, Supplier<T> newValueSupplier) { if (options == null) { options = new ArrayList<>(); } T rootOptions = findRootOptions(options); if (rootOptions == null) { rootOptions = newValueSupplier.get(); options.add(new SelectorOptions<>(rootOptions)); } updater.accept(rootOptions); return options; }
private boolean isRaw(Collection<SelectorOptions<GetOperationOptions>> options) { GetOperationOptions rootOptions = SelectorOptions.findRootOptions(options); return rootOptions == null ? false : GetOperationOptions.isRaw(rootOptions); }
private <T extends ObjectType> PrismObject<T> completeObject(Class<T> type, PrismObject<T> inObject, Collection<SelectorOptions<GetOperationOptions>> options, Task task, OperationResult result) throws SchemaException, ObjectNotFoundException, CommunicationException, ConfigurationException, ExpressionEvaluationException { if (ResourceType.class.equals(type)) { PrismObject<ResourceType> completeResource = resourceManager.getResource((PrismObject<ResourceType>) inObject, SelectorOptions.findRootOptions(options), task, result); return (PrismObject<T>) completeResource; } else if (ShadowType.class.equals(type)) { // should not happen, the shadow-related code is already in the ShadowCache throw new IllegalStateException("BOOOM!"); } else { //TODO: connectors etc.. } return inObject; }
private Collection<SelectorOptions<GetOperationOptions>> preProcessOptionsSecurity(Collection<SelectorOptions<GetOperationOptions>> options, Task task, OperationResult result) throws SchemaException, ObjectNotFoundException, ExpressionEvaluationException, CommunicationException, ConfigurationException, SecurityViolationException { GetOperationOptions rootOptions = SelectorOptions.findRootOptions(options); if (GetOperationOptions.isAttachDiagData(rootOptions) && !securityEnforcer.isAuthorized(AuthorizationConstants.AUTZ_ALL_URL, null, AuthorizationParameters.EMPTY, null, task, result)) { Collection<SelectorOptions<GetOperationOptions>> reducedOptions = CloneUtil.cloneCollectionMembers(options); SelectorOptions.findRootOptions(reducedOptions).setAttachDiagData(false); return reducedOptions; } else { return options; } }
public static boolean isFuturePointInTime(Collection<SelectorOptions<GetOperationOptions>> options) { PointInTimeType pit = GetOperationOptions.getPointInTimeType(SelectorOptions.findRootOptions(options)); return PointInTimeType.FUTURE.equals(pit); }
private ClusterStatusInformation getClusterStatusInformation(Collection<SelectorOptions<GetOperationOptions>> options, Class<? extends ObjectType> objectClass, boolean allowCached, OperationResult result) { boolean noFetch = GetOperationOptions.isNoFetch(SelectorOptions.findRootOptions(options)); boolean retrieveStatus; if (noFetch) { retrieveStatus = false; } else { if (objectClass.equals(TaskType.class)) { retrieveStatus = SelectorOptions.hasToLoadPath(TaskType.F_NODE_AS_OBSERVED, options); } else if (objectClass.equals(NodeType.class)) { retrieveStatus = true; // implement some determination algorithm if needed } else { throw new IllegalArgumentException("object class: " + objectClass); } } if (retrieveStatus) { return executionManager.getClusterStatusInformation(true, allowCached, result); } else { return null; } }
long stalenessOption = GetOperationOptions.getStaleness(SelectorOptions.findRootOptions(options)); PointInTimeType pit = GetOperationOptions.getPointInTimeType(SelectorOptions.findRootOptions(options)); if (pit == null) { if (stalenessOption > 0) {
private void attachDiagDataIfRequested(Item item, byte[] fullObject, Collection<SelectorOptions<GetOperationOptions>> options) { if (GetOperationOptions.isAttachDiagData(SelectorOptions.findRootOptions(options))) { item.setUserData(RepositoryService.KEY_DIAG_DATA, new RepositoryObjectDiagnosticData(getLength(fullObject))); } } }
@Override public PrismObject<TaskType> getTaskByIdentifier(String identifier, Collection<SelectorOptions<GetOperationOptions>> rawOptions, Task operationTask, OperationResult parentResult) throws SchemaException, ObjectNotFoundException, ConfigurationException, SecurityViolationException, ExpressionEvaluationException, CommunicationException { Collection<SelectorOptions<GetOperationOptions>> options = preProcessOptionsSecurity(rawOptions, operationTask, parentResult); PrismObject<TaskType> task = taskManager.getTaskTypeByIdentifier(identifier, options, parentResult); GetOperationOptions rootOptions = SelectorOptions.findRootOptions(options); task = task.cloneIfImmutable(); schemaTransformer.applySchemasAndSecurity(task, rootOptions, options,null, null, parentResult); return task; }
void attachDiagDataIfRequested(PrismValue value, byte[] fullObject, Collection<SelectorOptions<GetOperationOptions>> options) { if (GetOperationOptions.isAttachDiagData(SelectorOptions.findRootOptions(options))) { value.setUserData(RepositoryService.KEY_DIAG_DATA, new RepositoryObjectDiagnosticData(getLength(fullObject))); } }
public Collection<SelectorOptions<GetOperationOptions>> createGetOptions(SelectorQualifiedGetOptionsType optionsBean, boolean noFetch) { LOGGER.trace("optionsBean = {}, noFetch = {}", optionsBean, noFetch); Collection<SelectorOptions<GetOperationOptions>> rv = MiscSchemaUtil.optionsTypeToOptions(optionsBean, prismContext); if (noFetch) { if (rv == null) { return SelectorOptions.createCollection(GetOperationOptions.createNoFetch()); } GetOperationOptions root = SelectorOptions.findRootOptions(rv); if (root != null) { root.setNoFetch(true); } else { rv.add(SelectorOptions.create(GetOperationOptions.createNoFetch())); } } return rv; }
readOptions = new ArrayList<>(); GetOperationOptions root = SelectorOptions.findRootOptions(readOptions); if (root == null) { readOptions.add(SelectorOptions.create(GetOperationOptions.createAllowNotFound()));
@Override public <T extends ObjectType> SearchResultMetadata searchObjectsIterative(Class<T> type, ObjectQuery query, final ResultHandler<T> handler, final Collection<SelectorOptions<GetOperationOptions>> options, boolean strictlySequential, OperationResult parentResult) throws SchemaException { // TODO use cached query result if applicable log("Cache: PASS searchObjectsIterative ({})", type.getSimpleName()); final Cache cache = getCache(); ResultHandler<T> myHandler = (object, parentResult1) -> { cacheObject(cache, object, GetOperationOptions.isReadOnly(SelectorOptions.findRootOptions(options))); return handler.handle(object, parentResult1); }; Long startTime = repoOpStart(); try { return repositoryService.searchObjectsIterative(type, query, myHandler, options, strictlySequential, parentResult); } finally { repoOpEnd(startTime); } }
@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) || !nullOrHarmlessOptions(options)) { // local cache not interested in caching this object log("Cache: PASS {} ({})", oid, type.getSimpleName()); return getObjectTryGlobalCache(type, oid, options, parentResult); } boolean readOnly = GetOperationOptions.isReadOnly(SelectorOptions.findRootOptions(options)); Cache cache = getCache(); if (cache == null) { log("Cache: NULL {} ({})", oid, type.getSimpleName()); } else { PrismObject<T> object = (PrismObject) cache.getObject(oid); if (object != null) { log("Cache: HIT{} {} ({})", readOnly ? "" : "(clone)", oid, type.getSimpleName()); return cloneIfNecessary(object, readOnly); } log("Cache: MISS {} ({})", oid, type.getSimpleName()); } PrismObject<T> object = getObjectTryGlobalCache(type, oid, options, parentResult); cacheObject(cache, object, readOnly); return object; }
@Override public <T extends ObjectType> PrismObject<T> getObject(Class<T> type, String oid, Collection<SelectorOptions<GetOperationOptions>> options, OperationResult parentResult) throws SchemaException, ObjectNotFoundException { OperationResult result = parentResult.createMinorSubresult(DOT_INTERFACE + ".getObject"); result.addParam("objectType", type); result.addParam("oid", oid); result.addArbitraryObjectCollectionAsParam("options", options); result.addContext(OperationResult.CONTEXT_IMPLEMENTATION_CLASS, TaskManagerQuartzImpl.class); try { if (TaskType.class.isAssignableFrom(type)) { GetOperationOptions rootOptions = SelectorOptions.findRootOptions(options); if (GetOperationOptions.isRaw(rootOptions)) { //noinspection unchecked return (PrismObject<T>) repositoryService.getObject(TaskType.class, oid, options, result); } else { //noinspection unchecked return (PrismObject<T>) getTaskAsObject(oid, options, result); } } else if (NodeType.class.isAssignableFrom(type)) { //noinspection unchecked return (PrismObject<T>) repositoryService.getObject(NodeType.class, oid, options, result); // TODO add transient attributes just like in searchObject } else { throw new IllegalArgumentException("Unsupported object type: " + type); } } finally { result.computeStatusIfUnknown(); } }
@Override public <F extends FocusType> PrismObject<F> searchShadowOwner( String shadowOid, Collection<SelectorOptions<GetOperationOptions>> options, OperationResult parentResult) { // TODO cache the search operation? PrismObject<F> ownerObject; Long startTime = repoOpStart(); try { ownerObject = repositoryService.searchShadowOwner(shadowOid, options, parentResult); } finally { repoOpEnd(startTime); } if (ownerObject != null && nullOrHarmlessOptions(options)) { cacheObject(getCache(), ownerObject, GetOperationOptions.isReadOnly(SelectorOptions.findRootOptions(options))); } return ownerObject; }
private PrismObject<ShadowType> processNoFetchGet(ProvisioningContext ctx, PrismObject<ShadowType> repositoryShadow, Collection<SelectorOptions<GetOperationOptions>> options, XMLGregorianCalendar now, Task task, OperationResult parentResult) throws ObjectNotFoundException, SchemaException, CommunicationException, ConfigurationException, ExpressionEvaluationException, EncryptionException { LOGGER.trace("Processing noFetch get for {}", repositoryShadow); GetOperationOptions rootOptions = SelectorOptions.findRootOptions(options); if (!GetOperationOptions.isRaw(rootOptions)) { // Even with noFetch we still want to delete expired pending operations. And even delete // the shadow if needed. repositoryShadow = refreshShadowQick(ctx, repositoryShadow, now, task, parentResult); } if (repositoryShadow == null) { ObjectNotFoundException e = new ObjectNotFoundException("Resource object not found"); parentResult.recordFatalError(e); throw e; } PrismObject<ShadowType> resultShadow = futurizeShadow(ctx, repositoryShadow, null, options, now); shadowCaretaker.applyAttributesDefinition(ctx, resultShadow); return resultShadow; }
private boolean isCachedShadowValid(Collection<SelectorOptions<GetOperationOptions>> options, PrismObject<ShadowType> repositoryShadow, ResourceType resource) throws ConfigurationException { long stalenessOption = GetOperationOptions.getStaleness(SelectorOptions.findRootOptions(options)); if (stalenessOption == 0L) { return false; } CachingMetadataType cachingMetadata = repositoryShadow.asObjectable().getCachingMetadata(); if (cachingMetadata == null) { if (stalenessOption == Long.MAX_VALUE) { // We must return cached version but there is no cached version. throw new ConfigurationException("Cached version of "+repositoryShadow+" requested, but there is no cached value"); } return false; } if (stalenessOption == Long.MAX_VALUE) { return true; } XMLGregorianCalendar retrievalTimestamp = cachingMetadata.getRetrievalTimestamp(); if (retrievalTimestamp == null) { return false; } long retrievalTimestampMillis = XmlTypeConverter.toMillis(retrievalTimestamp); return (clock.currentTimeMillis() - retrievalTimestampMillis < stalenessOption); }
public <T extends ObjectType> PrismObject<T> getObjectAttempt(Class<T> type, String oid, Collection<SelectorOptions<GetOperationOptions>> options, OperationResult result) throws ObjectNotFoundException, SchemaException { LOGGER_PERFORMANCE.debug("> get object {}, oid={}", type.getSimpleName(), oid); PrismObject<T> objectType = null; Session session = null; try { session = baseHelper.beginReadOnlyTransaction(); objectType = getObjectInternal(session, type, oid, options, false, result); session.getTransaction().commit(); } catch (ObjectNotFoundException ex) { GetOperationOptions rootOptions = SelectorOptions.findRootOptions(options); baseHelper.rollbackTransaction(session, ex, result, !GetOperationOptions.isAllowNotFound(rootOptions)); throw ex; } catch (SchemaException ex) { baseHelper.rollbackTransaction(session, ex, "Schema error while getting object with oid: " + oid + ". Reason: " + ex.getMessage(), result, true); throw ex; } catch (DtoTranslationException | RuntimeException ex) { baseHelper.handleGeneralException(ex, session, result); } finally { baseHelper.cleanupSessionAndResult(session, result); } if (LOGGER.isTraceEnabled()) { LOGGER.trace("Get object:\n{}", objectType != null ? objectType.debugDump(3) : null); } return objectType; }
private <T extends ObjectType> PrismObject<T> getObjectTryGlobalCache(Class<T> type, String oid, Collection<SelectorOptions<GetOperationOptions>> options, OperationResult parentResult) throws SchemaException, ObjectNotFoundException { if (!supportsGlobalCaching(type, options)) { // caller is not interested in cached value, or global cache doesn't want to cache value return getObjectInternal(type, oid, options, parentResult); } CacheKey key = new CacheKey(type, oid); CacheObject<T> cacheObject = globalCache.get(key); PrismObject<T> object; if (cacheObject == null) { object = reloadObject(key, options, parentResult); } else { if (!shouldCheckVersion(cacheObject)) { log("Cache: Global HIT {}", key); object = cacheObject.getObject(); } else { if (hasVersionChanged(key, cacheObject, parentResult)) { object = reloadObject(key, options, parentResult); } else { // version matches, renew ttl cacheObject.setTimeToLive(System.currentTimeMillis() + cacheMaxTTL); log("Cache: Global HIT, version check {}", key); object = cacheObject.getObject(); } } } boolean readOnly = GetOperationOptions.isReadOnly(SelectorOptions.findRootOptions(options)); return cloneIfNecessary(object, readOnly); }