/*
* Copyright (c) 2010-2013 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.web.page.admin.configuration;
import com.evolveum.midpoint.gui.api.model.LoadableModel;
import com.evolveum.midpoint.gui.api.util.WebComponentUtil;
import com.evolveum.midpoint.model.api.ModelPublicConstants;
import com.evolveum.midpoint.model.api.WorkflowService;
import com.evolveum.midpoint.schema.LabeledString;
import com.evolveum.midpoint.schema.ProvisioningDiag;
import com.evolveum.midpoint.schema.RepositoryDiag;
import com.evolveum.midpoint.schema.constants.SchemaConstants;
import com.evolveum.midpoint.schema.result.OperationResult;
import com.evolveum.midpoint.security.api.AuthorizationConstants;
import com.evolveum.midpoint.security.api.MidPointPrincipal;
import com.evolveum.midpoint.task.api.Task;
import com.evolveum.midpoint.task.api.TaskManager;
import com.evolveum.midpoint.util.exception.SchemaException;
import com.evolveum.midpoint.util.exception.SecurityViolationException;
import com.evolveum.midpoint.util.logging.LoggingUtils;
import com.evolveum.midpoint.util.logging.Trace;
import com.evolveum.midpoint.util.logging.TraceManager;
import com.evolveum.midpoint.web.application.AuthorizationAction;
import com.evolveum.midpoint.web.application.PageDescriptor;
import com.evolveum.midpoint.web.component.AjaxButton;
import com.evolveum.midpoint.web.page.login.PageLogin;
import com.evolveum.midpoint.web.security.SecurityUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.wicket.RestartResponseException;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.list.ListItem;
import org.apache.wicket.markup.html.list.ListView;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.PropertyModel;
import java.io.Serializable;
import java.lang.management.ManagementFactory;
import java.lang.management.RuntimeMXBean;
import java.util.ArrayList;
import java.util.List;
/**
* @author lazyman
*/
@PageDescriptor(url = "/admin/config/about", action = {
@AuthorizationAction(actionUri = PageAdminConfiguration.AUTH_CONFIGURATION_ALL,
label = PageAdminConfiguration.AUTH_CONFIGURATION_ALL_LABEL, description = PageAdminConfiguration.AUTH_CONFIGURATION_ALL_DESCRIPTION),
@AuthorizationAction(actionUri = AuthorizationConstants.AUTZ_UI_CONFIGURATION_ABOUT_URL,
label = "PageAbout.auth.configAbout.label", description = "PageAbout.auth.configAbout.description")})
public class PageAbout extends PageAdminConfiguration {
private static final Trace LOGGER = TraceManager.getTrace(PageAbout.class);
private static final String DOT_CLASS = PageAbout.class.getName() + ".";
private static final String OPERATION_TEST_REPOSITORY = DOT_CLASS + "testRepository";
private static final String OPERATION_TEST_REPOSITORY_CHECK_ORG_CLOSURE = DOT_CLASS + "testRepositoryCheckOrgClosure";
private static final String OPERATION_GET_REPO_DIAG = DOT_CLASS + "getRepoDiag";
private static final String OPERATION_SUBMIT_REINDEX = DOT_CLASS + "submitReindex";
private static final String OPERATION_CLEANUP_ACTIVITI_PROCESSES = DOT_CLASS + "cleanupActivitiProcesses";
private static final String OPERATION_GET_PROVISIONING_DIAG = DOT_CLASS + "getProvisioningDiag";
private static final String ID_BUILD = "build";
private static final String ID_REVISION = "revision";
private static final String ID_PROPERTY = "property";
private static final String ID_VALUE = "value";
private static final String ID_LIST_SYSTEM_ITEMS = "listSystemItems";
private static final String ID_TEST_REPOSITORY = "testRepository";
private static final String ID_TEST_REPOSITORY_CHECK_ORG_CLOSURE = "testRepositoryCheckOrgClosure";
private static final String ID_REINDEX_REPOSITORY_OBJECTS = "reindexRepositoryObjects";
private static final String ID_TEST_PROVISIONING = "testProvisioning";
private static final String ID_CLEANUP_ACTIVITI_PROCESSES = "cleanupActivitiProcesses";
private static final String ID_IMPLEMENTATION_SHORT_NAME = "implementationShortName";
private static final String ID_IMPLEMENTATION_DESCRIPTION = "implementationDescription";
private static final String ID_IS_EMBEDDED = "isEmbedded";
private static final String ID_DRIVER_SHORT_NAME = "driverShortName";
private static final String ID_DRIVER_VERSION = "driverVersion";
private static final String ID_REPOSITORY_URL = "repositoryUrl";
private static final String ID_ADDITIONAL_DETAILS = "additionalDetails";
private static final String ID_DETAIL_NAME = "detailName";
private static final String ID_DETAIL_VALUE = "detailValue";
private static final String ID_PROVISIONING_ADDITIONAL_DETAILS = "provisioningAdditionalDetails";
private static final String ID_PROVISIONING_DETAIL_NAME = "provisioningDetailName";
private static final String ID_PROVISIONING_DETAIL_VALUE = "provisioningDetailValue";
private static final String ID_JVM_PROPERTIES = "jvmProperties";
private static final String[] PROPERTIES = new String[]{"file.separator", "java.class.path",
"java.home", "java.vendor", "java.vendor.url", "java.version", "line.separator", "os.arch",
"os.name", "os.version", "path.separator", "user.dir", "user.home", "user.name"};
private IModel<RepositoryDiag> repoDiagModel;
private IModel<ProvisioningDiag> provisioningDiagModel;
public PageAbout() {
repoDiagModel = new LoadableModel<RepositoryDiag>(false) {
@Override
protected RepositoryDiag load() {
return loadRepoDiagModel();
}
};
provisioningDiagModel = new LoadableModel<ProvisioningDiag>(false) {
@Override
protected ProvisioningDiag load() {
return loadProvisioningDiagModel();
}
};
initLayout();
}
private void initLayout() {
Label revision = new Label(ID_REVISION, createStringResource("PageAbout.midPointRevision"));
revision.setRenderBodyOnly(true);
add(revision);
Label build = new Label(ID_BUILD, createStringResource("PageAbout.build"));
build.setRenderBodyOnly(true);
add(build);
ListView<SystemItem> listSystemItems = new ListView<SystemItem>(ID_LIST_SYSTEM_ITEMS, getItems()) {
@Override
protected void populateItem(ListItem<SystemItem> item) {
SystemItem systemItem = item.getModelObject();
Label property = new Label(ID_PROPERTY, systemItem.getProperty());
property.setRenderBodyOnly(true);
item.add(property);
Label value = new Label(ID_VALUE, systemItem.getValue());
value.setRenderBodyOnly(true);
item.add(value);
}
};
add(listSystemItems);
addLabel(ID_IMPLEMENTATION_SHORT_NAME, "implementationShortName");
addLabel(ID_IMPLEMENTATION_DESCRIPTION, "implementationDescription");
addLabel(ID_IS_EMBEDDED, "isEmbedded");
addLabel(ID_DRIVER_SHORT_NAME, "driverShortName");
addLabel(ID_DRIVER_VERSION, "driverVersion");
addLabel(ID_REPOSITORY_URL, "repositoryUrl");
ListView<LabeledString> additionalDetails = new ListView<LabeledString>(ID_ADDITIONAL_DETAILS,
new PropertyModel<List<LabeledString>>(repoDiagModel, "additionalDetails")) {
@Override
protected void populateItem(ListItem<LabeledString> item) {
LabeledString labeledString = item.getModelObject();
Label property = new Label(ID_DETAIL_NAME, labeledString.getLabel());
property.setRenderBodyOnly(true);
item.add(property);
Label value = new Label(ID_DETAIL_VALUE, labeledString.getData());
value.setRenderBodyOnly(true);
item.add(value);
}
};
add(additionalDetails);
ListView<LabeledString> provisioningAdditionalDetails = new ListView<LabeledString>(ID_PROVISIONING_ADDITIONAL_DETAILS,
new PropertyModel<List<LabeledString>>(provisioningDiagModel, "additionalDetails")) {
@Override
protected void populateItem(ListItem<LabeledString> item) {
LabeledString labeledString = item.getModelObject();
Label property = new Label(ID_PROVISIONING_DETAIL_NAME, labeledString.getLabel());
property.setRenderBodyOnly(true);
item.add(property);
Label value = new Label(ID_PROVISIONING_DETAIL_VALUE, labeledString.getData());
value.setRenderBodyOnly(true);
item.add(value);
}
};
add(provisioningAdditionalDetails);
Label jvmProperties = new Label(ID_JVM_PROPERTIES, new LoadableModel<String>(false) {
@Override
protected String load() {
try {
RuntimeMXBean runtimeMxBean = ManagementFactory.getRuntimeMXBean();
List<String> arguments = runtimeMxBean.getInputArguments();
return StringUtils.join(arguments, "<br/>");
} catch (Exception ex) {
return PageAbout.this.getString("PageAbout.message.couldntObtainJvmParams");
}
}
});
jvmProperties.setEscapeModelStrings(false);
add(jvmProperties);
initButtons();
}
private void addLabel(String id, String propertyName) {
Label label = new Label(id, new PropertyModel<String>(repoDiagModel, propertyName));
label.setRenderBodyOnly(true);
add(label);
}
private void initButtons() {
AjaxButton testRepository = new AjaxButton(ID_TEST_REPOSITORY,
createStringResource("PageAbout.button.testRepository")) {
@Override
public void onClick(AjaxRequestTarget target) {
testRepositoryPerformed(target);
}
};
add(testRepository);
AjaxButton testRepositoryCheckOrgClosure = new AjaxButton(ID_TEST_REPOSITORY_CHECK_ORG_CLOSURE,
createStringResource("PageAbout.button.testRepositoryCheckOrgClosure")) {
@Override
public void onClick(AjaxRequestTarget target) {
testRepositoryCheckOrgClosurePerformed(target);
}
};
add(testRepositoryCheckOrgClosure);
AjaxButton reindexRepositoryObjects = new AjaxButton(ID_REINDEX_REPOSITORY_OBJECTS,
createStringResource("PageAbout.button.reindexRepositoryObjects")) {
@Override
public void onClick(AjaxRequestTarget target) {
reindexRepositoryObjectsPerformed(target);
}
};
add(reindexRepositoryObjects);
AjaxButton testProvisioning = new AjaxButton(ID_TEST_PROVISIONING,
createStringResource("PageAbout.button.testProvisioning")) {
@Override
public void onClick(AjaxRequestTarget target) {
testProvisioningPerformed(target);
}
};
add(testProvisioning);
AjaxButton cleanupActivitiProcesses = new AjaxButton(ID_CLEANUP_ACTIVITI_PROCESSES,
createStringResource("PageAbout.button.cleanupActivitiProcesses")) {
@Override
public void onClick(AjaxRequestTarget target) {
cleanupActivitiProcessesPerformed(target);
}
};
add(cleanupActivitiProcesses);
}
private RepositoryDiag loadRepoDiagModel() {
OperationResult result = new OperationResult(OPERATION_GET_REPO_DIAG);
RepositoryDiag diag = null;
try {
Task task = createSimpleTask(OPERATION_GET_REPO_DIAG);
diag = getModelDiagnosticService().getRepositoryDiag(task, result);
result.recordSuccessIfUnknown();
} catch (Exception ex) {
LoggingUtils.logUnexpectedException(LOGGER, "Couldn't get repo diagnostics", ex);
result.recordFatalError("Couldn't get repo diagnostics.", ex);
}
result.recomputeStatus();
if (!WebComponentUtil.isSuccessOrHandledError(result)) {
showResult(result);
}
return diag;
}
private ProvisioningDiag loadProvisioningDiagModel() {
OperationResult result = new OperationResult(OPERATION_GET_PROVISIONING_DIAG);
ProvisioningDiag diag = null;
try {
Task task = createSimpleTask(OPERATION_GET_PROVISIONING_DIAG);
diag = getModelDiagnosticService().getProvisioningDiag(task, result);
result.recordSuccessIfUnknown();
} catch (Exception ex) {
LoggingUtils.logUnexpectedException(LOGGER, "Couldn't get provisioning diagnostics", ex);
result.recordFatalError("Couldn't get provisioning diagnostics.", ex);
}
result.recomputeStatus();
if (!WebComponentUtil.isSuccessOrHandledError(result)) {
showResult(result);
}
return diag;
}
private IModel<List<SystemItem>> getItems() {
return new LoadableModel<List<SystemItem>>(false) {
@Override
protected List<SystemItem> load() {
List<SystemItem> items = new ArrayList<SystemItem>();
for (String property : PROPERTIES) {
items.add(new SystemItem(property, System.getProperty(property)));
}
return items;
}
};
}
private void testRepositoryPerformed(AjaxRequestTarget target) {
Task task = createSimpleTask(OPERATION_TEST_REPOSITORY);
OperationResult result = getModelDiagnosticService().repositorySelfTest(task);
showResult(result);
target.add(getFeedbackPanel());
}
private void testRepositoryCheckOrgClosurePerformed(AjaxRequestTarget target) {
OperationResult result = new OperationResult(OPERATION_TEST_REPOSITORY_CHECK_ORG_CLOSURE);
try {
Task task = createSimpleTask(OPERATION_TEST_REPOSITORY_CHECK_ORG_CLOSURE);
getModelDiagnosticService().repositoryTestOrgClosureConsistency(task, true, result);
} catch (SchemaException|SecurityViolationException e) {
result.recordFatalError(e);
} finally {
result.computeStatusIfUnknown();
}
showResult(result);
target.add(getFeedbackPanel());
}
private void reindexRepositoryObjectsPerformed(AjaxRequestTarget target) {
OperationResult result = new OperationResult(OPERATION_SUBMIT_REINDEX);
try {
TaskManager taskManager = getTaskManager();
Task task = taskManager.createTaskInstance();
MidPointPrincipal user = SecurityUtils.getPrincipalUser();
if (user == null) {
throw new RestartResponseException(PageLogin.class);
} else {
task.setOwner(user.getUser().asPrismObject());
}
getSecurityEnforcer().authorize(AuthorizationConstants.AUTZ_ALL_URL, null, null, null, null, null, result);
task.setChannel(SchemaConstants.CHANNEL_GUI_USER_URI);
task.setHandlerUri(ModelPublicConstants.REINDEX_TASK_HANDLER_URI);
task.setName("Reindex repository objects");
taskManager.switchToBackground(task, result);
result.setBackgroundTaskOid(task.getOid());
} catch (SecurityViolationException|SchemaException|RuntimeException e) {
result.recordFatalError(e);
} finally {
result.computeStatusIfUnknown();
}
showResult(result);
target.add(getFeedbackPanel());
}
private void testProvisioningPerformed(AjaxRequestTarget target) {
Task task = createSimpleTask(OPERATION_TEST_REPOSITORY);
OperationResult result = getModelDiagnosticService().provisioningSelfTest(task);
showResult(result);
target.add(getFeedbackPanel());
}
private void cleanupActivitiProcessesPerformed(AjaxRequestTarget target) {
OperationResult result = new OperationResult(OPERATION_CLEANUP_ACTIVITI_PROCESSES);
try {
WorkflowService workflowService = getWorkflowService();
workflowService.cleanupActivitiProcesses(result);
} catch (SecurityViolationException|SchemaException|RuntimeException e) {
result.recordFatalError(e);
} finally {
result.computeStatusIfUnknown();
}
showResult(result);
target.add(getFeedbackPanel());
}
/**
* It's here only because of some IDEs - it's not properly filtering resources during maven build.
* "describe" variable is not replaced.
*
* @return "unknown" instead of "git describe" for current build.
*/
@Deprecated
public String getDescribe() {
return getString("PageAbout.unknownBuildNumber");
}
private static class SystemItem implements Serializable {
private String property;
private String value;
private SystemItem(String property, String value) {
this.property = property;
this.value = value;
}
public String getProperty() {
return property;
}
public String getValue() {
return value;
}
}
}