diff --git a/model/model-impl/src/test/java/com/evolveum/midpoint/model/impl/controller/DummySystemConfigurationChangeApplierImpl.java b/model/model-impl/src/test/java/com/evolveum/midpoint/model/impl/controller/DummySystemConfigurationChangeDispatcherImpl.java similarity index 58% rename from model/model-impl/src/test/java/com/evolveum/midpoint/model/impl/controller/DummySystemConfigurationChangeApplierImpl.java rename to model/model-impl/src/test/java/com/evolveum/midpoint/model/impl/controller/DummySystemConfigurationChangeDispatcherImpl.java index 4d929e1513d..072c13021b3 100644 --- a/model/model-impl/src/test/java/com/evolveum/midpoint/model/impl/controller/DummySystemConfigurationChangeApplierImpl.java +++ b/model/model-impl/src/test/java/com/evolveum/midpoint/model/impl/controller/DummySystemConfigurationChangeDispatcherImpl.java @@ -16,15 +16,24 @@ package com.evolveum.midpoint.model.impl.controller; -import com.evolveum.midpoint.repo.api.SystemConfigurationChangeApplier; +import com.evolveum.midpoint.repo.api.SystemConfigurationChangeDispatcher; +import com.evolveum.midpoint.repo.api.SystemConfigurationChangeListener; import com.evolveum.midpoint.schema.result.OperationResult; /** * @author mederly */ -public class DummySystemConfigurationChangeApplierImpl implements SystemConfigurationChangeApplier { +public class DummySystemConfigurationChangeDispatcherImpl implements SystemConfigurationChangeDispatcher { @Override - public void applySystemConfiguration(boolean ignoreVersion, boolean allowNotFound, OperationResult result) { + public void dispatch(boolean ignoreVersion, boolean allowNotFound, OperationResult result) { + } + + @Override + public void registerListener(SystemConfigurationChangeListener listener) { + } + + @Override + public void unregisterListener(SystemConfigurationChangeListener listener) { } } diff --git a/model/model-impl/src/test/resources/ctx-model-test-no-repo.xml b/model/model-impl/src/test/resources/ctx-model-test-no-repo.xml index 8064c04cc84..7a70b7f20d8 100644 --- a/model/model-impl/src/test/resources/ctx-model-test-no-repo.xml +++ b/model/model-impl/src/test/resources/ctx-model-test-no-repo.xml @@ -45,6 +45,6 @@ - + diff --git a/repo/repo-api/src/main/java/com/evolveum/midpoint/repo/api/SystemConfigurationChangeApplier.java b/repo/repo-api/src/main/java/com/evolveum/midpoint/repo/api/SystemConfigurationChangeApplier.java deleted file mode 100644 index 82baa586797..00000000000 --- a/repo/repo-api/src/main/java/com/evolveum/midpoint/repo/api/SystemConfigurationChangeApplier.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (c) 2010-2018 Evolveum - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.evolveum.midpoint.repo.api; - -import com.evolveum.midpoint.schema.result.OperationResult; -import com.evolveum.midpoint.util.exception.SchemaException; - -/** - * @author mederly - */ -public interface SystemConfigurationChangeApplier { - - void applySystemConfiguration(boolean ignoreVersion, boolean allowNotFound, OperationResult result) throws SchemaException; - -} diff --git a/repo/repo-api/src/main/java/com/evolveum/midpoint/repo/api/SystemConfigurationChangeDispatcher.java b/repo/repo-api/src/main/java/com/evolveum/midpoint/repo/api/SystemConfigurationChangeDispatcher.java new file mode 100644 index 00000000000..494715733e5 --- /dev/null +++ b/repo/repo-api/src/main/java/com/evolveum/midpoint/repo/api/SystemConfigurationChangeDispatcher.java @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2010-2018 Evolveum + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.evolveum.midpoint.repo.api; + +import com.evolveum.midpoint.schema.result.OperationResult; +import com.evolveum.midpoint.util.exception.SchemaException; + +/** + * Central point of dispatching notifications about changes to the system configuration object. + * + * @author mederly + */ +public interface SystemConfigurationChangeDispatcher { + + /** + * Dispatches information on system configuration object change. + * + * Basically this directly pushes information to lower layers (prism, schema, repo, etc), and calls registered + * listeners that originate in upper layers. + * + * @param ignoreVersion If false, the information is dispatched unconditionally. If true, we dispatch the notification only + * if the system configuration version was really changed. This is to easily support sources that + * "ping" sysconfig object in regular intervals, e.g. the cluster manager thread. + * @param allowNotFound If true, we take non-existence of sysconfig object more easily. To be used e.g. on system init or + * during tests execution. + */ + void dispatch(boolean ignoreVersion, boolean allowNotFound, OperationResult result) throws SchemaException; + + /** + * Registers a listener that will be updated on system configuration object changes. + */ + void registerListener(SystemConfigurationChangeListener listener); + + /** + * Unregisters a listener. + */ + void unregisterListener(SystemConfigurationChangeListener listener); + +} diff --git a/repo/repo-api/src/main/java/com/evolveum/midpoint/repo/api/SystemConfigurationChangeListener.java b/repo/repo-api/src/main/java/com/evolveum/midpoint/repo/api/SystemConfigurationChangeListener.java new file mode 100644 index 00000000000..69008ef88ff --- /dev/null +++ b/repo/repo-api/src/main/java/com/evolveum/midpoint/repo/api/SystemConfigurationChangeListener.java @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2010-2018 Evolveum + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.evolveum.midpoint.repo.api; + +import com.evolveum.midpoint.xml.ns._public.common.common_3.SystemConfigurationType; +import org.jetbrains.annotations.Nullable; + +/** + * Listener that needs to receive notifications related to system configuration object changes. + */ +public interface SystemConfigurationChangeListener { + /** + * Updates the listener's internal state with the configuration provided. + * + * @param value Current value of the system configuration object. It is 'null' if the object does not exist. + * Usually listeners keep their current state in such cases, but if needed, it will have the information + * about missing sysconfig object, so it could act accordingly. + * + * @return false if the update was not successful, so it needs to be repeated. The same effect is when + * a runtime exception is thrown. + */ + boolean update(@Nullable SystemConfigurationType value); +} diff --git a/repo/repo-common/src/main/java/com/evolveum/midpoint/repo/common/SystemConfigurationCacheableAdapter.java b/repo/repo-common/src/main/java/com/evolveum/midpoint/repo/common/SystemConfigurationCacheableAdapter.java index e27588958d3..074aedc6599 100644 --- a/repo/repo-common/src/main/java/com/evolveum/midpoint/repo/common/SystemConfigurationCacheableAdapter.java +++ b/repo/repo-common/src/main/java/com/evolveum/midpoint/repo/common/SystemConfigurationCacheableAdapter.java @@ -16,7 +16,7 @@ package com.evolveum.midpoint.repo.common; -import com.evolveum.midpoint.repo.api.SystemConfigurationChangeApplier; +import com.evolveum.midpoint.repo.api.SystemConfigurationChangeDispatcher; import com.evolveum.midpoint.schema.result.OperationResult; import com.evolveum.midpoint.util.logging.LoggingUtils; import com.evolveum.midpoint.util.logging.Trace; @@ -35,7 +35,7 @@ public class SystemConfigurationCacheableAdapter implements Cacheable { private static final Trace LOGGER = TraceManager.getTrace(SystemConfigurationCacheableAdapter.class); @Autowired private CacheRegistry cacheRegistry; - @Autowired private SystemConfigurationChangeApplier changeApplier; + @Autowired private SystemConfigurationChangeDispatcher changeDispatcher; @PostConstruct public void register() { @@ -46,9 +46,9 @@ public void register() { public void clearCache() { try { OperationResult result = new OperationResult(SystemConfigurationCacheableAdapter.class.getName() + ".clearCache"); - changeApplier.applySystemConfiguration(true, true, result); + changeDispatcher.dispatch(true, true, result); } catch (Throwable t) { - LoggingUtils.logUnexpectedException(LOGGER, "Couldn't apply updated system configuration", t); + LoggingUtils.logUnexpectedException(LOGGER, "Couldn't dispatch information about updated system configuration", t); } } diff --git a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/SqlRepositoryServiceImpl.java b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/SqlRepositoryServiceImpl.java index 36c83cdaf80..775a84e4a55 100644 --- a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/SqlRepositoryServiceImpl.java +++ b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/SqlRepositoryServiceImpl.java @@ -124,7 +124,7 @@ public class SqlRepositoryServiceImpl extends SqlBaseService implements Reposito @Autowired private MidpointConfiguration midpointConfiguration; @Autowired private PrismContext prismContext; @Autowired private RelationRegistry relationRegistry; - @Autowired private SystemConfigurationChangeApplier systemConfigurationChangeApplier; + @Autowired private SystemConfigurationChangeDispatcher systemConfigurationChangeDispatcher; private final ThreadLocal> conflictWatchersThreadLocal = new ThreadLocal<>(); @@ -826,11 +826,10 @@ public SearchResultMetadata searchObjectsIterative(Class< if (isCustomPagingOkWithPagedSeqIteration(query)) { iterationMethod = IterationMethodType.STRICTLY_SEQUENTIAL_PAGING; } else { - // TODO switch to LOGGER.error - throw new IllegalArgumentException("Iterative search was defined in the repository configuration, and strict sequentiality " + LOGGER.warn("Iterative search was defined in the repository configuration, and strict sequentiality " + "was requested. However, a custom paging precludes its application. Therefore switching to " + "simple paging iteration method. Paging requested: " + query.getPaging()); - //iterationMethod = IterationMethodType.SIMPLE_PAGING; + iterationMethod = IterationMethodType.SIMPLE_PAGING; } } else { iterationMethod = IterationMethodType.SIMPLE_PAGING; @@ -1145,7 +1144,7 @@ public FullTextSearchConfigurationType getFullTextSearchConfiguration() { @Override public void postInit(OperationResult result) throws SchemaException { LOGGER.debug("Executing repository postInit method"); - systemConfigurationChangeApplier.applySystemConfiguration(true, true, result); + systemConfigurationChangeDispatcher.dispatch(true, true, result); } @Override diff --git a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/SystemConfigurationChangeApplierImpl.java b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/SystemConfigurationChangeDispatcherImpl.java similarity index 82% rename from repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/SystemConfigurationChangeApplierImpl.java rename to repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/SystemConfigurationChangeDispatcherImpl.java index e2b352e8b24..1dd4f1b5c43 100644 --- a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/SystemConfigurationChangeApplierImpl.java +++ b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/SystemConfigurationChangeDispatcherImpl.java @@ -21,7 +21,8 @@ import com.evolveum.midpoint.prism.PrismContext; import com.evolveum.midpoint.prism.PrismObject; import com.evolveum.midpoint.repo.api.RepositoryService; -import com.evolveum.midpoint.repo.api.SystemConfigurationChangeApplier; +import com.evolveum.midpoint.repo.api.SystemConfigurationChangeDispatcher; +import com.evolveum.midpoint.repo.api.SystemConfigurationChangeListener; import com.evolveum.midpoint.schema.GetOperationOptions; import com.evolveum.midpoint.schema.RelationRegistry; import com.evolveum.midpoint.schema.SelectorOptions; @@ -43,22 +44,25 @@ import org.springframework.stereotype.Component; import java.util.Collection; +import java.util.HashSet; /** * @author mederly */ @Component -public class SystemConfigurationChangeApplierImpl implements SystemConfigurationChangeApplier { +public class SystemConfigurationChangeDispatcherImpl implements SystemConfigurationChangeDispatcher { - private static final Trace LOGGER = TraceManager.getTrace(SystemConfigurationChangeApplierImpl.class); + private static final Trace LOGGER = TraceManager.getTrace(SystemConfigurationChangeDispatcherImpl.class); @Autowired private RepositoryService repositoryService; @Autowired private PrismContext prismContext; @Autowired private RelationRegistry relationRegistry; + private static final Collection listeners = new HashSet<>(); + private String lastVersionApplied = null; - public synchronized void applySystemConfiguration(boolean ignoreVersion, boolean allowNotFound, + public synchronized void dispatch(boolean ignoreVersion, boolean allowNotFound, OperationResult result) throws SchemaException { LOGGER.trace("Applying system configuration: lastVersionApplied = {}, ignoreVersion = {}", lastVersionApplied, ignoreVersion); @@ -74,8 +78,9 @@ public synchronized void applySystemConfiguration(boolean ignoreVersion, boolean LOGGER.debug("System configuration not found"); result.muteLastSubresultError(); } else { - LOGGER.warn("System configuration not found"); + LOGGER.warn("System configuration not found", e); } + notifyListeners(null); lastVersionApplied = null; return; } @@ -93,6 +98,7 @@ public synchronized void applySystemConfiguration(boolean ignoreVersion, boolean // because this method is called also from the cluster management thread. lastVersionApplied = currentVersion; + notifyListeners(configuration); applyLoggingConfiguration(configurationObject, result); applyRemoteHostAddressHeadersConfiguration(configuration); applyPolyStringNormalizerConfiguration(configuration); @@ -107,6 +113,17 @@ public synchronized void applySystemConfiguration(boolean ignoreVersion, boolean } } + private void notifyListeners(SystemConfigurationType configuration) { + for (SystemConfigurationChangeListener listener : listeners) { + try { + listener.update(configuration); + } catch (Throwable t) { + LoggingUtils.logUnexpectedException(LOGGER, "Couldn't update system configuration listener {}", t, listener); + lastVersionApplied = null; + } + } + } + private void applyLoggingConfiguration(PrismObject configuration, OperationResult result) { try { LoggingConfigurationType loggingWithProfiling = ProfilingConfigurationManager @@ -170,4 +187,22 @@ private void applyOperationResultHandlingConfiguration(SystemConfigurationType c lastVersionApplied = null; } } + + @Override + public synchronized void registerListener(SystemConfigurationChangeListener listener) { + if (!listeners.contains(listener)) { + listeners.add(listener); + } else { + LOGGER.warn("Attempt to register already-registered listener: {}", listener); + } + } + + @Override + public synchronized void unregisterListener(SystemConfigurationChangeListener listener) { + if (listeners.contains(listener)) { + listeners.remove(listener); + } else { + LOGGER.warn("Attempt to unregister a listener that was not registered: {}", listener); + } + } } diff --git a/repo/task-quartz-impl/src/main/java/com/evolveum/midpoint/task/quartzimpl/TaskManagerQuartzImpl.java b/repo/task-quartz-impl/src/main/java/com/evolveum/midpoint/task/quartzimpl/TaskManagerQuartzImpl.java index 5a034bc25ef..61fb3f2fbc1 100644 --- a/repo/task-quartz-impl/src/main/java/com/evolveum/midpoint/task/quartzimpl/TaskManagerQuartzImpl.java +++ b/repo/task-quartz-impl/src/main/java/com/evolveum/midpoint/task/quartzimpl/TaskManagerQuartzImpl.java @@ -38,7 +38,7 @@ import com.evolveum.midpoint.prism.delta.builder.DeltaBuilder; import com.evolveum.midpoint.repo.api.PreconditionViolationException; import com.evolveum.midpoint.repo.api.RepoAddOptions; -import com.evolveum.midpoint.repo.api.SystemConfigurationChangeApplier; +import com.evolveum.midpoint.repo.api.SystemConfigurationChangeDispatcher; import com.evolveum.midpoint.schema.*; import com.evolveum.midpoint.task.api.*; import com.evolveum.midpoint.task.quartzimpl.handlers.PartitioningTaskHandler; @@ -125,7 +125,7 @@ public class TaskManagerQuartzImpl implements TaskManager, BeanFactoryAware { @Autowired private TaskManagerConfiguration configuration; @Autowired private LocalizationService localizationService; - @Autowired private SystemConfigurationChangeApplier systemConfigurationChangeApplier; + @Autowired private SystemConfigurationChangeDispatcher systemConfigurationChangeDispatcher; // instances of all the helper classes (see their definitions for their description) private ExecutionManager executionManager = new ExecutionManager(this); @@ -2239,7 +2239,7 @@ public boolean isLocalNodeClusteringEnabled() { return configuration.isLocalNodeClusteringEnabled(); } - public SystemConfigurationChangeApplier getSystemConfigurationChangeApplier() { - return systemConfigurationChangeApplier; + public SystemConfigurationChangeDispatcher getSystemConfigurationChangeDispatcher() { + return systemConfigurationChangeDispatcher; } } diff --git a/repo/task-quartz-impl/src/main/java/com/evolveum/midpoint/task/quartzimpl/cluster/ClusterManager.java b/repo/task-quartz-impl/src/main/java/com/evolveum/midpoint/task/quartzimpl/cluster/ClusterManager.java index 5649e0b7c26..f1e951d3820 100644 --- a/repo/task-quartz-impl/src/main/java/com/evolveum/midpoint/task/quartzimpl/cluster/ClusterManager.java +++ b/repo/task-quartz-impl/src/main/java/com/evolveum/midpoint/task/quartzimpl/cluster/ClusterManager.java @@ -249,7 +249,7 @@ public PrismObject getNodeById(String nodeIdentifier, OperationResult private void checkSystemConfigurationChanged(OperationResult parentResult) { OperationResult result = parentResult.createSubresult(CHECK_SYSTEM_CONFIGURATION_CHANGED); try { - taskManager.getSystemConfigurationChangeApplier().applySystemConfiguration(false, false, result); + taskManager.getSystemConfigurationChangeDispatcher().dispatch(false, false, result); result.computeStatus(); } catch (Throwable t) { LoggingUtils.logUnexpectedException(LOGGER, "Couldn't apply system configuration", t);