Skip to content

Commit

Permalink
Merge branch 'master' of github.com:Evolveum/midpoint
Browse files Browse the repository at this point in the history
  • Loading branch information
katkav committed Jul 30, 2014
2 parents e7b9f62 + 0c66a24 commit 179e6a9
Show file tree
Hide file tree
Showing 33 changed files with 344 additions and 176 deletions.
Expand Up @@ -16,32 +16,40 @@

package com.evolveum.midpoint.web.page.admin.configuration;

import com.evolveum.midpoint.model.api.ScriptExecutionException;
import com.evolveum.midpoint.model.api.ScriptExecutionResult;
import com.evolveum.midpoint.prism.PrismContext;
import com.evolveum.midpoint.schema.result.OperationResult;
import com.evolveum.midpoint.schema.result.OperationResultStatus;
import com.evolveum.midpoint.security.api.AuthorizationConstants;
import com.evolveum.midpoint.task.api.Task;
import com.evolveum.midpoint.util.exception.SchemaException;
import com.evolveum.midpoint.util.exception.SecurityViolationException;
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.AceEditor;
import com.evolveum.midpoint.web.component.AjaxSubmitButton;
import com.evolveum.midpoint.web.page.admin.configuration.dto.BulkActionDto;
import com.evolveum.midpoint.xml.ns._public.model.scripting_3.ScriptingExpressionType;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.markup.html.form.CheckBox;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.Model;
import org.apache.wicket.model.PropertyModel;

import javax.xml.bind.JAXBElement;

/**
* @author lazyman
*/
@PageDescriptor(url = "/admin/config/bulk", action = {
// @AuthorizationAction(actionUri = PageAdminConfiguration.AUTH_CONFIGURATION_ALL,
// label = PageAdminConfiguration.AUTH_CONFIGURATION_ALL_LABEL, description = PageAdminConfiguration.AUTH_CONFIGURATION_ALL_DESCRIPTION),
// @AuthorizationAction(actionUri = AuthorizationConstants.NS_AUTHORIZATION + "#bulkAction",
// label = "PageBulkAction.auth.bulkAction.label", description = "PageBulkAction.auth.bulkAction.description")
@AuthorizationAction(actionUri = AuthorizationConstants.AUTZ_NO_ACCESS_URL)
@AuthorizationAction(actionUri = PageAdminConfiguration.AUTH_CONFIGURATION_ALL,
label = PageAdminConfiguration.AUTH_CONFIGURATION_ALL_LABEL, description = PageAdminConfiguration.AUTH_CONFIGURATION_ALL_DESCRIPTION),
@AuthorizationAction(actionUri = AuthorizationConstants.NS_AUTHORIZATION + "#bulkAction",
label = "PageBulkAction.auth.bulkAction.label", description = "PageBulkAction.auth.bulkAction.description")
})
public class PageBulkAction extends PageAdminConfiguration {

Expand Down Expand Up @@ -87,12 +95,50 @@ protected void onSubmit(AjaxRequestTarget target, Form<?> form) {
}

private void startPerformed(AjaxRequestTarget target) {
model.getObject();

Task task = createSimpleTask(OPERATION_PERFORM_BULK);
OperationResult result = new OperationResult(OPERATION_PERFORM_BULK);

//TODO - continue here - we need to find a way to serialize XML String to JAXBElement<? extends ScriptingExpressionType> expression to continue
// getScriptingService().evaluateExpressionInBackground(, task, result);
BulkActionDto bulkActionDto = model.getObject();

ScriptingExpressionType expression = null;
try {
Object parsed = getPrismContext().parseAnyValue(bulkActionDto.getScript(), PrismContext.LANG_XML);
if (parsed == null) {
result.recordFatalError("No bulk action object was provided.");
}
if (parsed instanceof JAXBElement) {
parsed = ((JAXBElement) parsed).getValue();
}
if (parsed instanceof ScriptingExpressionType) {
expression = (ScriptingExpressionType) parsed;
} else {
result.recordFatalError("Provided XML text is not a bulk action object. An instance of {scripting-3}ScriptingExpressionType is expected; you have provided " + parsed.getClass() + " instead.");
}
} catch (SchemaException|RuntimeException e) {
result.recordFatalError("Couldn't parse bulk action object", e);
}

if (expression != null) {
if (bulkActionDto.isAsync()) {
try {
getScriptingService().evaluateExpressionInBackground(expression, task, result);
result.recordStatus(OperationResultStatus.IN_PROGRESS, task.getName() + " has been successfully submitted to execution");
} catch (SchemaException|SecurityViolationException e) {
result.recordFatalError("Couldn't submit bulk action to execution", e);
}
} else {
try {
ScriptExecutionResult executionResult = getScriptingService().evaluateExpression(expression, task, result);
result.recordStatus(OperationResultStatus.SUCCESS, "Action executed. Returned " + executionResult.getDataOutput().size() + " item(s). Console and data output available via 'Export to XML' function.");
result.addReturn("console", executionResult.getConsoleOutput());
result.addCollectionOfSerializablesAsReturn("data", executionResult.getDataOutput());
} catch (ScriptExecutionException|SchemaException|SecurityViolationException e) {
result.recordFatalError("Couldn't execute bulk action", e);
}
}
}

showResult(result);
target.add(getFeedbackPanel());
}
}
Expand Up @@ -391,6 +391,11 @@ public <T> T parseAnyValue(InputStream inputStream, String language) throws Sche
return xnodeProcessor.parseAnyValue(xnode);
}

public <T> T parseAnyValue(String dataString, String language) throws SchemaException {
XNode xnode = parseToXNode(dataString, language);
return xnodeProcessor.parseAnyValue(xnode);
}

//endregion

//region Parsing to XNode
Expand Down
Expand Up @@ -21,9 +21,6 @@

import javax.xml.bind.JAXBElement;

import com.evolveum.midpoint.prism.util.CloneUtil;

import org.apache.commons.collections.map.HashedMap;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.Validate;
import org.w3c.dom.Document;
Expand All @@ -37,7 +34,6 @@
import com.evolveum.midpoint.util.DebugDumpable;
import com.evolveum.midpoint.util.MiscUtil;
import com.evolveum.midpoint.util.exception.CommonException;
import com.evolveum.midpoint.util.exception.SchemaException;
import com.evolveum.midpoint.util.logging.Trace;
import com.evolveum.midpoint.util.logging.TraceManager;
import com.evolveum.midpoint.xml.ns._public.common.common_3.EntryType;
Expand Down Expand Up @@ -674,6 +670,10 @@ public void addCollectionOfSerializablesAsParam(String paramName, Collection<? e
addParam(paramName, paramValue != null ? new ArrayList(paramValue) : null);
}

public void addCollectionOfSerializablesAsReturn(String name, Collection<? extends Serializable> value) {
addReturn(name, value != null ? new ArrayList(value) : null);
}

public void addArbitraryCollectionAsParam(String paramName, Collection values) {
if (values != null) {
ArrayList<String> valuesAsStrings = new ArrayList<String>();
Expand Down
Expand Up @@ -30,7 +30,8 @@ public enum ModelAuthorizationAction implements DisplayableValue<String> {
DISCOVER_CONNECTORS("discoverConnectors", "Discover Connectors", "DISCOVER_CONNECTORS_HELP"),

ASSIGN("assign", "Assign", "ASSIGN_HELP"),
UNASSIGN("unassign", "Unassign", "UNASSIGN_HELP");
UNASSIGN("unassign", "Unassign", "UNASSIGN_HELP"),
EXECUTE_SCRIPT("executeScript", "Execute script", "EXECUTE_SCRIPT_HELP");

private String url;
private String label;
Expand Down
Expand Up @@ -14,7 +14,7 @@
* limitations under the License.
*/

package com.evolveum.midpoint.model.impl.scripting;
package com.evolveum.midpoint.model.api;

/**
* Wraps any exceptions that occur during execution of expressions. (ExpressionEvaluationException would be more appropriate, but this name is already used elsewhere.)
Expand Down
@@ -0,0 +1,50 @@
/*
* 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.api;

import com.evolveum.midpoint.prism.Item;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
* Result of a script execution.
*
* @author mederly
*/
public class ScriptExecutionResult {

private String consoleOutput;
private List<Item> dataOutput; // unmodifiable + always non-null

public ScriptExecutionResult(String consoleOutput, List<Item> dataOutput) {
this.consoleOutput = consoleOutput;
if (dataOutput == null) {
dataOutput = new ArrayList<>();
}
this.dataOutput = Collections.unmodifiableList(dataOutput);
}

public String getConsoleOutput() {
return consoleOutput;
}

public List<Item> getDataOutput() {
return dataOutput;
}
}
Expand Up @@ -16,26 +16,14 @@

package com.evolveum.midpoint.model.api;

import com.evolveum.midpoint.prism.PrismObject;
import com.evolveum.midpoint.prism.parser.QueryConvertor;
import com.evolveum.midpoint.prism.query.ObjectFilter;
import com.evolveum.midpoint.schema.GetOperationOptions;
import com.evolveum.midpoint.schema.SelectorOptions;
import com.evolveum.midpoint.schema.constants.SchemaConstants;
import com.evolveum.midpoint.schema.result.OperationResult;
import com.evolveum.midpoint.task.api.Task;
import com.evolveum.midpoint.util.exception.ObjectNotFoundException;
import com.evolveum.midpoint.util.exception.SchemaException;
import com.evolveum.midpoint.xml.ns._public.common.common_3.TaskType;
import com.evolveum.midpoint.xml.ns._public.model.scripting_3.ActionExpressionType;
import com.evolveum.midpoint.xml.ns._public.model.scripting_3.ExecuteScriptType;
import com.evolveum.midpoint.util.exception.SecurityViolationException;
import com.evolveum.midpoint.xml.ns._public.model.scripting_3.ScriptingExpressionType;
import com.evolveum.midpoint.xml.ns._public.model.scripting_3.SearchExpressionType;

import javax.xml.bind.JAXBElement;
import javax.xml.namespace.QName;
import java.util.Collection;
import java.util.List;

/**
* Interface of the Model subsystem that provides scripting (bulk actions) operations.
Expand All @@ -55,18 +43,34 @@ public interface ScriptingService {
* and assigns ScriptExecutionTaskHandler to it, to execute the script.
* @param parentResult
* @throws SchemaException
*
* TODO consider removing this method (it was meant as a simplified version of the method below)
*/
public void evaluateExpressionInBackground(QName objectType, ObjectFilter filter, String actionName, Task task, OperationResult parentResult) throws SchemaException;
public void evaluateExpressionInBackground(QName objectType, ObjectFilter filter, String actionName, Task task, OperationResult parentResult) throws SchemaException, SecurityViolationException;

/**
* Asynchronously executes any scripting expression.
*
* @param expression Expression to be executed.
* @param task Task in context of which the script should execute. The task should be "clean", i.e.
* (1) transient, (2) without any handler. This method puts the task into background,
* and assigns ScriptExecutionTaskHandler to it, to execute the script.
* @param task Task in context of which the script should execute.
* The task should be "clean", i.e. (1) transient, (2) without any handler.
* This method puts the task into background, and assigns ScriptExecutionTaskHandler
* to it, to execute the script.
* @param parentResult
* @throws SchemaException
*/
public void evaluateExpressionInBackground(JAXBElement<? extends ScriptingExpressionType> expression, Task task, OperationResult parentResult) throws SchemaException;
}
public void evaluateExpressionInBackground(ScriptingExpressionType expression, Task task, OperationResult parentResult) throws SchemaException, SecurityViolationException;

/**
* Synchronously executes any scripting expression (with no input data).
*
* @param expression Scripting expression to execute.
* @param task Task in context of which the script should execute (in foreground!)
* @param result Operation result
* @throws ScriptExecutionException
*
* TODO return ExecutionContext (requires moving the context to model api)
*/

public ScriptExecutionResult evaluateExpression(ScriptingExpressionType expression, Task task, OperationResult result) throws ScriptExecutionException, SchemaException, SecurityViolationException;
}
Expand Up @@ -15,17 +15,15 @@
*/
package com.evolveum.midpoint.model.impl;

import com.evolveum.midpoint.audit.api.AuditEventRecord;
import com.evolveum.midpoint.audit.api.AuditEventStage;
import com.evolveum.midpoint.audit.api.AuditEventType;
import com.evolveum.midpoint.audit.api.AuditService;
import com.evolveum.midpoint.model.api.ModelExecuteOptions;
import com.evolveum.midpoint.model.api.ModelPort;
import com.evolveum.midpoint.model.api.ScriptExecutionResult;
import com.evolveum.midpoint.model.api.ScriptingService;
import com.evolveum.midpoint.model.common.util.AbstractModelWebService;
import com.evolveum.midpoint.model.impl.controller.ModelController;
import com.evolveum.midpoint.model.impl.scripting.Data;
import com.evolveum.midpoint.model.impl.scripting.ExecutionContext;
import com.evolveum.midpoint.model.impl.scripting.ScriptExecutionException;
import com.evolveum.midpoint.model.api.ScriptExecutionException;
import com.evolveum.midpoint.model.impl.scripting.ScriptingExpressionEvaluator;
import com.evolveum.midpoint.prism.Item;
import com.evolveum.midpoint.prism.PrismContext;
Expand All @@ -41,18 +39,14 @@
import com.evolveum.midpoint.schema.constants.ObjectTypes;
import com.evolveum.midpoint.schema.constants.SchemaConstants;
import com.evolveum.midpoint.schema.result.OperationResult;
import com.evolveum.midpoint.schema.result.OperationResultStatus;
import com.evolveum.midpoint.schema.util.MiscSchemaUtil;
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.CommunicationException;
import com.evolveum.midpoint.util.exception.ConfigurationException;
import com.evolveum.midpoint.util.exception.ObjectAlreadyExistsException;
import com.evolveum.midpoint.util.exception.ObjectNotFoundException;
import com.evolveum.midpoint.util.exception.SchemaException;
import com.evolveum.midpoint.util.exception.SecurityViolationException;
import com.evolveum.midpoint.util.exception.SystemException;
import com.evolveum.midpoint.util.logging.LoggingUtils;
import com.evolveum.midpoint.util.logging.Trace;
import com.evolveum.midpoint.util.logging.TraceManager;
Expand Down Expand Up @@ -81,14 +75,12 @@
import com.evolveum.midpoint.xml.ns._public.model.model_3.ExecuteScriptsType;
import com.evolveum.midpoint.xml.ns._public.model.model_3.ModelPortType;
import com.evolveum.midpoint.xml.ns._public.model.scripting_3.ItemListType;
import com.evolveum.midpoint.xml.ns._public.model.scripting_3.ScriptingExpressionType;
import com.evolveum.prism.xml.ns._public.query_3.QueryType;
import com.evolveum.prism.xml.ns._public.types_3.PolyStringType;
import com.evolveum.prism.xml.ns._public.types_3.RawType;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;

import javax.xml.bind.JAXBElement;
Expand Down Expand Up @@ -118,7 +110,7 @@ public class ModelWebService extends AbstractModelWebService implements ModelPor
private ModelController modelController;

@Autowired
private ScriptingExpressionEvaluator scriptingExpressionEvaluator;
private ScriptingService scriptingService;

@Override
public void getObject(QName objectType, String oid, SelectorQualifiedGetOptionsType optionsType,
Expand Down Expand Up @@ -275,30 +267,30 @@ private List<JAXBElement<?>> parseScripts(ExecuteScriptsType parameters) throws
return scriptsToExecute;
}

private ExecuteScriptsResponseType doExecuteScripts(List<JAXBElement<?>> scriptsToExecute, ExecuteScriptsOptionsType options, Task task, OperationResult result) throws ScriptExecutionException, JAXBException, SchemaException {
private ExecuteScriptsResponseType doExecuteScripts(List<JAXBElement<?>> scriptsToExecute, ExecuteScriptsOptionsType options, Task task, OperationResult result) {
ExecuteScriptsResponseType response = new ExecuteScriptsResponseType();
ScriptOutputsType outputs = new ScriptOutputsType();
response.setOutputs(outputs);

try {
for (JAXBElement<?> script : scriptsToExecute) {

ExecutionContext outputContext = scriptingExpressionEvaluator.evaluateExpression(script, task, result);
ScriptExecutionResult executionResult = scriptingService.evaluateExpression((ScriptingExpressionType) script.getValue(), task, result);

SingleScriptOutputType output = new SingleScriptOutputType();
outputs.getOutput().add(output);

output.setTextOutput(outputContext.getConsoleOutput());
output.setTextOutput(executionResult.getConsoleOutput());
if (options == null || options.getOutputFormat() == null || options.getOutputFormat() == OutputFormatType.XML) {
output.setXmlData(prepareXmlData(outputContext.getFinalOutput()));
output.setXmlData(prepareXmlData(executionResult.getDataOutput()));
} else {
// temporarily we send serialized XML in the case of MSL output
ItemListType jaxbOutput = prepareXmlData(outputContext.getFinalOutput());
ItemListType jaxbOutput = prepareXmlData(executionResult.getDataOutput());
output.setMslData(prismContext.serializeAnyData(jaxbOutput, SchemaConstants.C_VALUE, PrismContext.LANG_XML));
}
}
result.computeStatusIfUnknown();
} catch (Exception e) { // FIXME little bit brutal treatment
} catch (ScriptExecutionException|JAXBException|SchemaException|RuntimeException|SecurityViolationException e) {
result.recordFatalError(e.getMessage(), e);
LoggingUtils.logException(LOGGER, "Exception while executing script", e);
}
Expand All @@ -307,10 +299,10 @@ private ExecuteScriptsResponseType doExecuteScripts(List<JAXBElement<?>> scripts
return response;
}

private ItemListType prepareXmlData(Data output) throws JAXBException, SchemaException {
private ItemListType prepareXmlData(List<Item> output) throws JAXBException, SchemaException {
ItemListType itemListType = new ItemListType();
if (output != null) {
for (Item item : output.getData()) {
for (Item item : output) {
RawType rawType = prismContext.toRawType(item);
itemListType.getItem().add(rawType);
}
Expand Down

0 comments on commit 179e6a9

Please sign in to comment.