com.adobe.cq.testing.client.CQWorkflowClient Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of aem-cloud-testing-clients Show documentation
Show all versions of aem-cloud-testing-clients Show documentation
AEM related clients and testing utilities for AEM as a Cloud Service
/*
* Copyright 2017 Adobe Systems Incorporated
*
* 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.adobe.cq.testing.client;
import com.adobe.cq.testing.client.workflow.EventType;
import org.apache.http.HttpEntity;
import org.apache.http.HttpStatus;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.sling.testing.clients.ClientException;
import org.apache.sling.testing.clients.SlingClientConfig;
import org.apache.sling.testing.clients.SlingHttpResponse;
import org.apache.sling.testing.clients.util.FormEntityBuilder;
import org.codehaus.jackson.JsonNode;
import java.net.URI;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
/**
* Extends the Granite Workflow client with CQ Specific Workflow methods
*/
public class CQWorkflowClient extends WorkflowClient {
public static final String LAUNCHER_CONFIG = "/etc/workflow/launcher/config/";
public static final String ROOT_PATH_MODEL = "/etc/workflow/models/";
public static final String CQ_MODEL_PAGE_TEMPLATE = "/libs/cq/workflow/templates/model";
public static final String SAVE_SUFFIX = "/jcr:content.generate.json";
CQClient cqClient;
public CQWorkflowClient(CloseableHttpClient http, SlingClientConfig config) throws ClientException {
super(http, config);
this.cqClient = adaptTo(CQClient.class);
}
public CQWorkflowClient(URI serverUrl, String user, String password) throws ClientException {
super(serverUrl, user, password);
this.cqClient = adaptTo(CQClient.class);
}
/**
* Creates a new Model page in the default directory {@value #ROOT_PATH_MODEL}.
*
* @param modelName name of the model
* @param modelTitle title to be given to this model
* @param expectedStatusRange expected HTTP status
* @return the response
* @throws ClientException if the request fails
*/
public SlingHttpResponse createNewModelPage(String modelName, String modelTitle, int... expectedStatusRange)
throws ClientException {
// create the model page
return cqClient.createPage(modelName, modelTitle, ROOT_PATH_MODEL, CQ_MODEL_PAGE_TEMPLATE, expectedStatusRange);
}
/**
* Saves a model.
*
* @param modelPath Name of the model to save
* @param expectedStatus list of expected http status codes
* @return the response
* @throws ClientException if the request fails
*/
public SlingHttpResponse saveModel(String modelPath, int... expectedStatus) throws ClientException {
return doPost(modelPath + SAVE_SUFFIX, null, expectedStatus);
}
/**
* Adds a new workflow launcher. This method only allows some parameters.
*
* @param workflowId the workflow URI
* @param path the path it binds to
* @param nodeType the node type it affects
* @param eventType the event type to the node
* @throws ClientException if the call to the backend fails
*/
public void createWorkflowLauncher(String workflowId, String path, String nodeType, EventType eventType) throws ClientException {
HttpEntity form = FormEntityBuilder.create()
.addParameter("_charset_", "utf-8")
.addParameter("add", "true")
.addParameter("eventType", String.valueOf(eventType))
.addParameter("nodetype", nodeType)
.addParameter("glob", path)
.addParameter("condition", "")
.addParameter("workflow", workflowId)
.addParameter("enabled", "true")
.addParameter("runModes", "author")
.addParameter(":status", "browser")
.addParameter("description", "")
.addParameter("excludeList", "")
.build();
doPost("/libs/cq/workflow/launcher", form, HttpStatus.SC_OK);
}
/**
* Edit one property of an existing workflow launcher identified by the launcher configuration name
* The rest of the properties on the workflow launcher stay the same
*
* @param launcherId the launcher configuration string
* @param propName The name of the property about to be changed
* @param value The value of the property about to be changed
* @throws ClientException if the request fails
*/
public void editWorkflowLauncher(String launcherId, String propName, String value)
throws ClientException {
Map wv = new HashMap<>();
wv.put(propName, value);
editWorkflowLauncher(launcherId, wv);
}
/**
* Edit an existing workflow launcher identified by the launcher configuration name with a set of properties to change
* The rest of the properties on the workflow launcher stay the same
*
* @param launcherId the launcher configuration string
* @param propMap A map with properties names and values to be changed on the workflow
* @throws ClientException if the request fails
*/
public void editWorkflowLauncher(String launcherId, Map propMap)
throws ClientException {
FormEntityBuilder form = FormEntityBuilder.create();
form.addParameter("_charset_", "utf-8");
form.addParameter(":status", "browser");
form.addParameter("edit", LAUNCHER_CONFIG + launcherId);
Map launcher = getWorkflowLauncher(launcherId);
for (String launcherProp : launcher.keySet()) {
// skip if the value will be edited, populate with the existing one otherwise
if (!propMap.containsKey(launcherProp)) {
form.addParameter(launcherProp, launcher.get(launcherProp));
}
}
// add the provided properties
for (String propName : propMap.keySet()) {
form.addParameter(propName, propMap.get(propName));
}
// Add exclude list property if not provided
if (!propMap.keySet().contains("excludeList"))
form.addParameter("excludeList", "");
// save the launcher
doPost("/libs/cq/workflow/launcher", form.build(), HttpStatus.SC_OK);
}
/**
* Returns a {@link Map} with properties of the workflow launcher
*
* @param launcherId the URI of the launcher
* @return a {@link Map} with properties
* @throws ClientException if the request fails
*/
public Map getWorkflowLauncher(String launcherId) throws ClientException {
JsonNode launchers = this.doGetJson("/etc/workflow/launcher/config", 1);
JsonNode launcherNode = launchers.get(launcherId);
if (null == launcherNode)
return null;
Map launcher = new HashMap<>();
Iterator it = launcherNode.getFieldNames();
while (it.hasNext()) {
String propName = it.next();
launcher.put(propName, launcherNode.get(propName).getValueAsText());
}
return launcher;
}
/**
* Enables or disables the workflow launcher
*
* @param launcherId the id of the launcher
* @param enabled "true" to enable, "false" to disable
* @throws ClientException if the request fails
*/
public void enableDisableWorkflowLauncher(String launcherId, boolean enabled) throws ClientException {
editWorkflowLauncher(launcherId, "enabled", enabled ? "true" : "false");
}
/**
* Finds out if the Transient feature flag is enabled for a workflow.
*
* @param workflowModel
* the path of the workflow model. These are stored at
* /etc/workflow/models/
. The model path to be
* provided can be relative (or absolute) to this path
* @return True
if the workflow is transient in nature,
* False
otherwise.
* @throws ClientException
* if it fails to find the specified workflow model.
*/
public boolean isWorkflowTransient(String workflowModel)
throws ClientException {
workflowModel = workflowModel.startsWith("/etc/workflow/models/") ? workflowModel
: "/etc/workflow/models/" + workflowModel;
workflowModel = workflowModel.endsWith("/jcr:content") ? workflowModel
: workflowModel+"/jcr:content" ;
JsonNode json = this.adaptTo(JsonClient.class).doGetJson(workflowModel, 0);
return (!json.path("transient").isMissingNode()) && (json.get("transient").getValueAsText().equalsIgnoreCase("true"));
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy