/*
* Copyright (c) 2010-2014 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.model.impl.controller;
import com.evolveum.midpoint.common.ProfilingConfigurationManager;
import com.evolveum.midpoint.common.SystemConfigurationHolder;
import com.evolveum.midpoint.model.api.context.ModelContext;
import com.evolveum.midpoint.model.api.context.ModelElementContext;
import com.evolveum.midpoint.model.api.context.ModelState;
import com.evolveum.midpoint.model.api.hooks.ChangeHook;
import com.evolveum.midpoint.model.api.hooks.HookOperationMode;
import com.evolveum.midpoint.model.api.hooks.HookRegistry;
import com.evolveum.midpoint.repo.api.RepositoryService;
import com.evolveum.midpoint.util.exception.ObjectNotFoundException;
import com.evolveum.midpoint.util.logging.LoggingUtils;
import com.evolveum.midpoint.xml.ns._public.common.common_3.*;
import org.apache.commons.configuration.Configuration;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
import com.evolveum.midpoint.common.LoggingConfigurationManager;
import com.evolveum.midpoint.common.configuration.api.MidpointConfiguration;
import com.evolveum.midpoint.prism.PrismObject;
import com.evolveum.midpoint.schema.result.OperationResult;
import com.evolveum.midpoint.task.api.Task;
import com.evolveum.midpoint.util.exception.SchemaException;
import com.evolveum.midpoint.util.logging.Trace;
import com.evolveum.midpoint.util.logging.TraceManager;
import javax.annotation.PostConstruct;
/**
* @author semancik
*
*/
@Component
public class SystemConfigurationHandler implements ChangeHook {
private static final Trace LOGGER = TraceManager.getTrace(SystemConfigurationHandler.class);
private static final String DOT_CLASS = SystemConfigurationHandler.class + ".";
public static final String HOOK_URI = "http://midpoint.evolveum.com/model/sysconfig-hook-1";
@Autowired
private HookRegistry hookRegistry;
@Autowired
@Qualifier("cacheRepositoryService")
private transient RepositoryService cacheRepositoryService;
@PostConstruct
public void init() {
hookRegistry.registerChangeHook(HOOK_URI, this);
}
private void applyLoggingConfiguration(LoggingConfigurationType loggingConfig, String version, OperationResult parentResult) {
if (loggingConfig != null) {
LoggingConfigurationManager.configure(loggingConfig, version, parentResult);
}
}
@Override
public <O extends ObjectType> HookOperationMode invoke(@NotNull ModelContext<O> context, @NotNull Task task, @NotNull OperationResult parentResult) {
ModelState state = context.getState();
if (state != ModelState.FINAL) {
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("sysconfig handler called in state = " + state + ", exiting.");
}
return HookOperationMode.FOREGROUND;
} else {
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("sysconfig handler called in state = " + state + ", proceeding.");
}
}
if (context.getFocusClass() != SystemConfigurationType.class) {
LOGGER.trace("invoke() EXITING: Changes not related to systemConfiguration");
return HookOperationMode.FOREGROUND;
}
ModelContext<SystemConfigurationType> confContext = (ModelContext<SystemConfigurationType>)context;
ModelElementContext<SystemConfigurationType> focusContext = confContext.getFocusContext();
boolean isDeletion = false; // is this config-related change a deletion?
PrismObject<SystemConfigurationType> object = focusContext.getObjectNew();
if (object == null) {
isDeletion = true;
object = focusContext.getObjectOld();
}
if (object == null) {
LOGGER.warn("Probably invalid projection context: both old and new objects are null"); // if the handler would not work because of this, for us to see the reason
}
LOGGER.trace("change relates to sysconfig, is deletion: {}", isDeletion);
OperationResult result = parentResult.createSubresult(DOT_CLASS + "invoke");
try {
if (isDeletion) {
LoggingConfigurationManager.resetCurrentlyUsedVersion(); // because the new config (if any) will have version number probably starting at 1 - so to be sure to read it when it comes
LOGGER.trace("invoke() EXITING because operation is DELETION");
return HookOperationMode.FOREGROUND;
}
/*
* Because we need to know actual version of the system configuration (generated by repo), we have to re-read
* current configuration. (At this moment, it is already stored there.)
*/
PrismObject<SystemConfigurationType> config = cacheRepositoryService.getObject(SystemConfigurationType.class,
SystemObjectsType.SYSTEM_CONFIGURATION.value(), null, result);
LOGGER.trace("invoke() SystemConfig from repo: {}, ApplyingLoggingConfiguration", config.getVersion());
SystemConfigurationHolder.setCurrentConfiguration(config.asObjectable());
applyLoggingConfiguration(ProfilingConfigurationManager.checkSystemProfilingConfiguration(config), config.asObjectable().getVersion(), result);
cacheRepositoryService.applyFullTextSearchConfiguration(config.asObjectable().getFullTextSearch());
result.recordSuccessIfUnknown();
} catch (ObjectNotFoundException e) {
String message = "Cannot read system configuration because it does not exist in repository: " + e.getMessage();
LoggingUtils.logException(LOGGER, message, e);
result.recordFatalError(message, e);
} catch (SchemaException e) {
String message = "Cannot read system configuration because of schema exception: " + e.getMessage();
LoggingUtils.logException(LOGGER, message, e);
result.recordFatalError(message, e);
}
return HookOperationMode.FOREGROUND;
}
@Override
public void invokeOnException(@NotNull ModelContext context, @NotNull Throwable throwable, @NotNull Task task, @NotNull OperationResult result) {
// do nothing
}
}