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);