Java tutorial
/* * 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.resources; import com.evolveum.midpoint.prism.PrismObject; import com.evolveum.midpoint.schema.CapabilityUtil; import com.evolveum.midpoint.schema.GetOperationOptions; import com.evolveum.midpoint.schema.SelectorOptions; import com.evolveum.midpoint.schema.result.OperationResult; import com.evolveum.midpoint.schema.result.OperationResultStatus; import com.evolveum.midpoint.schema.util.ResourceTypeUtil; import com.evolveum.midpoint.security.api.AuthorizationConstants; import com.evolveum.midpoint.task.api.Task; import com.evolveum.midpoint.util.exception.*; 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.component.data.TablePanel; import com.evolveum.midpoint.web.component.util.ListDataProvider; import com.evolveum.midpoint.web.component.util.LoadableModel; import com.evolveum.midpoint.web.page.admin.resources.dto.ResourceController; import com.evolveum.midpoint.web.page.admin.resources.dto.ResourceDto; import com.evolveum.midpoint.web.page.admin.resources.dto.ResourceObjectTypeDto; import com.evolveum.midpoint.web.page.admin.server.dto.OperationResultStatusIcon; import com.evolveum.midpoint.web.util.OnePageParameterEncoder; import com.evolveum.midpoint.xml.ns._public.common.common_3.ProvisioningScriptHostType; import com.evolveum.midpoint.xml.ns._public.common.common_3.ResourceType; import com.evolveum.midpoint.xml.ns._public.resource.capabilities_3.ScriptCapabilityType; import org.apache.commons.lang.StringUtils; import org.apache.wicket.AttributeModifier; import org.apache.wicket.RestartResponseException; import org.apache.wicket.ajax.AjaxRequestTarget; import org.apache.wicket.extensions.markup.html.repeater.data.sort.SortOrder; import org.apache.wicket.extensions.markup.html.repeater.data.table.IColumn; import org.apache.wicket.extensions.markup.html.repeater.data.table.PropertyColumn; import org.apache.wicket.extensions.markup.html.repeater.util.SortableDataProvider; import org.apache.wicket.markup.html.WebMarkupContainer; import org.apache.wicket.markup.html.basic.Label; import org.apache.wicket.markup.html.form.Form; import org.apache.wicket.markup.html.list.ListItem; import org.apache.wicket.markup.html.list.ListView; import org.apache.wicket.model.AbstractReadOnlyModel; import org.apache.wicket.model.IModel; import org.apache.wicket.model.PropertyModel; import org.apache.wicket.request.mapper.parameter.PageParameters; import javax.xml.bind.JAXBElement; import java.util.ArrayList; import java.util.Collection; import java.util.List; /** * @author lazyman * @author Michal Serbak */ @PageDescriptor(url = "/admin/resource", encoder = OnePageParameterEncoder.class, action = { @AuthorizationAction(actionUri = PageAdminResources.AUTH_RESOURCE_ALL, label = PageAdminResources.AUTH_RESOURCE_ALL_LABEL, description = PageAdminResources.AUTH_RESOURCE_ALL_DESCRIPTION), @AuthorizationAction(actionUri = AuthorizationConstants.NS_AUTHORIZATION + "#resource", label = "PageResource.auth.resource.label", description = "PageResource.auth.resource.description") }) public class PageResource extends PageAdminResources { private static final Trace LOGGER = TraceManager.getTrace(PageResource.class); private static final String DOT_CLASS = PageResource.class.getName() + "."; private static final String OPERATION_IMPORT_FROM_RESOURCE = DOT_CLASS + "importFromResource"; private static final String TEST_CONNECTION = DOT_CLASS + "testConnection"; private static final String ID_BUTTON_DELETE_TOKEN = "deleteSyncToken"; private IModel<ResourceDto> model; public PageResource() { model = new LoadableModel<ResourceDto>() { @Override protected ResourceDto load() { return loadResourceDto(); } }; initLayout(); } private ResourceDto loadResourceDto() { if (!isResourceOidAvailable()) { getSession().error(getString("pageResource.message.oidNotDefined")); throw new RestartResponseException(PageResources.class); } Collection<SelectorOptions<GetOperationOptions>> options = SelectorOptions .createCollection(ResourceType.F_CONNECTOR, GetOperationOptions.createResolve()); PrismObject<ResourceType> resource = loadResource(options); return new ResourceDto(resource, getPrismContext(), resource.asObjectable().getConnector(), initCapabilities(resource.asObjectable())); } private void initLayout() { Form mainForm = new Form("mainForm"); add(mainForm); SortableDataProvider<ResourceObjectTypeDto, String> provider = new ListDataProvider<ResourceObjectTypeDto>( this, new PropertyModel<List<ResourceObjectTypeDto>>(model, "objectTypes")); provider.setSort("displayName", SortOrder.ASCENDING); TablePanel objectTypes = new TablePanel<ResourceObjectTypeDto>("objectTypesTable", provider, initObjectTypesColumns()); objectTypes.setShowPaging(true); objectTypes.setOutputMarkupId(true); mainForm.add(objectTypes); initResourceColumns(mainForm); initConnectorDetails(mainForm); createCapabilitiesList(mainForm); initButtons(mainForm); } private void initResourceColumns(Form mainForm) { mainForm.add(new Label("resourceOid", new PropertyModel<Object>(model, "oid"))); mainForm.add(new Label("resourceName", new PropertyModel<Object>(model, "name"))); mainForm.add(new Label("resourceType", new PropertyModel<Object>(model, "type"))); mainForm.add(new Label("resourceVersion", new PropertyModel<Object>(model, "version"))); mainForm.add(new Label("resourceProgress", new PropertyModel<Object>(model, "progress"))); } private IModel<String> createTestConnectionStateTooltip(final String expression) { return new AbstractReadOnlyModel<String>() { @Override public String getObject() { PropertyModel<OperationResultStatus> pModel = new PropertyModel<OperationResultStatus>(model, expression); OperationResultStatus status = pModel.getObject(); if (status == null) { return ""; } return PageResource.this .getString(OperationResultStatus.class.getSimpleName() + "." + status.name()); } }; } private Label createImageLabel(String id, IModel<String> title, IModel<String> cssClass) { Label label = new Label(id); label.add(AttributeModifier.replace("class", cssClass)); label.add(AttributeModifier.replace("title", title)); return label; } private void initConnectorDetails(Form mainForm) { WebMarkupContainer container = new WebMarkupContainer("connectors"); container.setOutputMarkupId(true); mainForm.add(container); container.add(createImageLabel("overallStatus", createTestConnectionStateTooltip("state.overall"), new AbstractReadOnlyModel<String>() { @Override public String getObject() { return OperationResultStatusIcon .parseOperationalResultStatus(model.getObject().getState().getOverall()).getIcon(); } })); container.add(createImageLabel("confValidation", createTestConnectionStateTooltip("state.confValidation"), new AbstractReadOnlyModel<String>() { @Override public String getObject() { return OperationResultStatusIcon .parseOperationalResultStatus(model.getObject().getState().getConfValidation()) .getIcon(); } })); container.add(createImageLabel("conInitialization", createTestConnectionStateTooltip("state.conInitialization"), new AbstractReadOnlyModel<String>() { @Override public String getObject() { return OperationResultStatusIcon .parseOperationalResultStatus(model.getObject().getState().getConInitialization()) .getIcon(); } })); container.add(createImageLabel("conConnection", createTestConnectionStateTooltip("state.conConnection"), new AbstractReadOnlyModel<String>() { @Override public String getObject() { return OperationResultStatusIcon .parseOperationalResultStatus(model.getObject().getState().getConConnection()) .getIcon(); } })); container.add(createImageLabel("conSchema", createTestConnectionStateTooltip("state.conSchema"), new AbstractReadOnlyModel<String>() { @Override public String getObject() { return OperationResultStatusIcon .parseOperationalResultStatus(model.getObject().getState().getConSchema()) .getIcon(); } })); } private List<String> initCapabilities(ResourceType resource) { OperationResult result = new OperationResult("Load resource capabilities"); List<String> capabilitiesName = new ArrayList<String>(); try { List<Object> capabilitiesList = ResourceTypeUtil.getEffectiveCapabilities(resource); if (capabilitiesList != null && !capabilitiesList.isEmpty()) { for (int i = 0; i < capabilitiesList.size(); i++) { capabilitiesName.add(getCapabilityName(capabilitiesList.get(i))); } } } catch (Exception ex) { result.recordFatalError("Couldn't load resource capabilities for resource'" + new PropertyModel<Object>(model, "name") + ".", ex); } return capabilitiesName; } private String getCapabilityName(Object capability) { if (capability instanceof JAXBElement) { capability = ((JAXBElement) capability).getValue(); } StringBuilder sb = new StringBuilder(); String className = capability.getClass().getSimpleName(); if (className.endsWith("CapabilityType")) { sb.append(className.substring(0, className.length() - "CapabilityType".length())); } else { sb.append(className); } if (capability instanceof ScriptCapabilityType) { ScriptCapabilityType script = (ScriptCapabilityType) capability; sb.append(": "); List<ProvisioningScriptHostType> hosts = new ArrayList<>(); for (ScriptCapabilityType.Host host : script.getHost()) { hosts.add(host.getType()); } sb.append(StringUtils.join(hosts, ", ")); } return sb.toString(); } private List<IColumn<ResourceObjectTypeDto, String>> initObjectTypesColumns() { List<IColumn<ResourceObjectTypeDto, String>> columns = new ArrayList<IColumn<ResourceObjectTypeDto, String>>(); columns.add(new PropertyColumn(createStringResource("pageResource.objectTypes.displayName"), "displayName", "displayName")); columns.add(new PropertyColumn(createStringResource("pageResource.objectTypes.nativeObjectClass"), "nativeObjectClass")); columns.add(new PropertyColumn(createStringResource("pageResource.objectTypes.help"), "help")); columns.add(new PropertyColumn(createStringResource("pageResource.objectTypes.type"), "type")); return columns; } private void createCapabilitiesList(Form mainForm) { ListView<String> listCapabilities = new ListView<String>("listCapabilities", createCapabilitiesModel(model)) { @Override protected void populateItem(ListItem<String> item) { item.add(new Label("capabilities", item.getModel())); } }; mainForm.add(listCapabilities); } private IModel<List<String>> createCapabilitiesModel(final IModel<ResourceDto> model) { return new LoadableModel<List<String>>(false) { @Override protected List<String> load() { ResourceDto resource = model.getObject(); return resource.getCapabilities(); } }; } private void initButtons(Form mainForm) { AjaxButton back = new AjaxButton("back", createStringResource("pageResource.button.back")) { @Override public void onClick(AjaxRequestTarget target) { setResponsePage(PageResources.class); } }; mainForm.add(back); AjaxButton test = new AjaxButton("test", createStringResource("pageResource.button.test")) { @Override public void onClick(AjaxRequestTarget target) { testConnectionPerformed(target); } }; mainForm.add(test); AjaxButton importAccounts = new AjaxButton("importAccounts", createStringResource("pageResource.button.importAccounts")) { @Override public void onClick(AjaxRequestTarget target) { importFromResourcePerformed(target); } }; mainForm.add(importAccounts); AjaxButton link = new AjaxButton("editResource", createStringResource("pageResource.editResource")) { @Override public void onClick(AjaxRequestTarget target) { PageParameters parameters = new PageParameters(); parameters.add(OnePageParameterEncoder.PARAMETER, model.getObject().getOid()); setResponsePage(PageResourceEdit.class, parameters); } }; mainForm.add(link); AjaxButton deleteToken = new AjaxButton(ID_BUTTON_DELETE_TOKEN, createStringResource("pageResource.deleteSyncToken")) { @Override public void onClick(AjaxRequestTarget target) { deleteSyncTokenPerformed(target, model); } }; mainForm.add(deleteToken); } private void testConnectionPerformed(AjaxRequestTarget target) { ResourceDto dto = model.getObject(); if (dto == null || StringUtils.isEmpty(dto.getOid())) { error(getString("pageResource.message.oidNotDefined")); target.add(getFeedbackPanel()); return; } Task task = createSimpleTask(TEST_CONNECTION); OperationResult result = new OperationResult(TEST_CONNECTION); try { result = getModelService().testResource(dto.getOid(), task); ResourceController.updateResourceState(dto.getState(), result); // this provides some additional tests, namely a test for schema handling section getModelService().getObject(ResourceType.class, dto.getOid(), null, task, result); } catch (ObjectNotFoundException ex) { result.recordFatalError("Failed to test resource connection", ex); } catch (ConfigurationException e) { result.recordFatalError("Failed to test resource connection", e); } catch (SchemaException e) { result.recordFatalError("Failed to test resource connection", e); } catch (CommunicationException e) { result.recordFatalError("Failed to test resource connection", e); } catch (SecurityViolationException e) { result.recordFatalError("Failed to test resource connection", e); } // a bit of hack: result of TestConnection contains a result of getObject as a subresult // so in case of TestConnection succeeding we recompute the result to show any (potential) getObject problems if (result.isSuccess()) { result.recomputeStatus(); } WebMarkupContainer connectors = (WebMarkupContainer) get("mainForm:connectors"); target.add(connectors); if (!result.isSuccess()) { showResult(result); target.add(getFeedbackPanel()); } } private void importFromResourcePerformed(AjaxRequestTarget target) { ResourceDto dto = model.getObject(); LOGGER.debug("Import accounts from resource {} ({}), object class {}", new Object[] { dto.getName(), dto.getOid(), dto.getDefaultAccountObjectClass() }); OperationResult result = new OperationResult(OPERATION_IMPORT_FROM_RESOURCE); try { Task task = createSimpleTask(OPERATION_IMPORT_FROM_RESOURCE); getModelService().importFromResource(dto.getOid(), dto.getDefaultAccountObjectClass(), task, result); } catch (Exception ex) { LoggingUtils.logException(LOGGER, "Error occurred during accounts import from resource {} ({}), class {}", ex, dto.getName(), dto.getOid(), dto.getDefaultAccountObjectClass()); result.recordFatalError("Error occurred during importing accounts from resource.", ex); } result.computeStatus(); showResult(result); target.add(getFeedbackPanel()); } }