Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ public class Constants {
// Synapse service statuses
public static final String ACTIVE_STATUS = "active";
public static final String INACTIVE_STATUS = "inactive";
public static final String TRIGGER_STATUS = "trigger";

// Constant on pax logging
public static final String PAX_LOGGING_CONFIGURATION_PID = "org.ops4j.pax.logging";
Expand Down Expand Up @@ -165,6 +166,7 @@ public class Constants {
public static final String AUDIT_LOG_TYPE_ROOT_LOG_LEVEL = "root_log_level";
public static final String AUDIT_LOG_TYPE_MESSAGE_PROCESSOR = "message_processor";
public static final String AUDIT_LOG_TYPE_INBOUND_ENDPOINT = "inbound_endpoint";
public static final String AUDIT_LOG_TYPE_TASK = "task";
public static final String AUDIT_LOG_TYPE_CARBON_APPLICATION = "carbon_application";
public static final String AUDIT_LOG_TYPE_CONNECTOR = "connector";

Expand Down Expand Up @@ -202,6 +204,7 @@ public class Constants {
public static final String AUDIT_LOG_ACTION_CREATED = "created";
public static final String AUDIT_LOG_ACTION_DELETED = "deleted";
public static final String AUDIT_LOG_ACTION_UPDATED = "updated";
public static final String AUDIT_LOG_ACTION_TRIGGERED = "triggered";

public static final String DOMAIN_SEPARATOR;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
import org.apache.synapse.config.SynapseConfiguration;
import org.apache.synapse.config.xml.inbound.InboundEndpointSerializer;
import org.apache.synapse.core.axis2.Axis2MessageContext;
import org.apache.synapse.inbound.DynamicControlOperationResult;
import org.apache.synapse.util.DynamicControlOperationResult;
import org.apache.synapse.inbound.InboundEndpoint;
import org.json.JSONArray;
import org.json.JSONObject;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,20 +19,29 @@

package org.wso2.micro.integrator.management.apis;

import com.google.gson.JsonObject;
import org.apache.axiom.om.OMAttribute;
import org.apache.axiom.om.OMElement;
import org.apache.axis2.engine.AxisConfiguration;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.synapse.MessageContext;
import org.apache.synapse.Startup;
import org.apache.synapse.SynapseConstants;
import org.apache.synapse.config.SynapseConfiguration;
import org.apache.synapse.core.SynapseEnvironment;
import org.apache.synapse.core.axis2.Axis2MessageContext;
import org.apache.synapse.util.DynamicControlOperationResult;
import org.apache.synapse.startup.quartz.StartUpController;
import org.apache.synapse.task.TaskDescription;
import org.apache.synapse.task.TaskDescriptionSerializer;
import org.json.JSONObject;
import org.wso2.carbon.inbound.endpoint.internal.http.api.APIResource;
import org.wso2.micro.core.util.AuditLogger;
import org.wso2.micro.integrator.management.apis.security.handler.SecurityUtils;
import org.wso2.micro.integrator.security.user.api.UserStoreException;

import java.io.IOException;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
Expand All @@ -44,11 +53,18 @@
import java.util.stream.Collectors;
import javax.xml.namespace.QName;

import static org.wso2.micro.integrator.management.apis.Constants.ACTIVE_STATUS;
import static org.wso2.micro.integrator.management.apis.Constants.INACTIVE_STATUS;
import static org.wso2.micro.integrator.management.apis.Constants.NAME;
import static org.wso2.micro.integrator.management.apis.Constants.SEARCH_KEY;
import static org.wso2.micro.integrator.management.apis.Constants.STATUS;
import static org.wso2.micro.integrator.management.apis.Constants.TRIGGER_STATUS;
import static org.wso2.micro.integrator.management.apis.Constants.USERNAME_PROPERTY;

public class TaskResource extends APIResource {

private static final String TASK_NAME = "taskName";
private static Log log = LogFactory.getLog(TaskResource.class);

public TaskResource(String urlTemplate){
super(urlTemplate);
Expand All @@ -58,6 +74,7 @@ public TaskResource(String urlTemplate){
public Set<String> getMethods() {
Set<String> methods = new HashSet<>();
methods.add(Constants.HTTP_GET);
methods.add(Constants.HTTP_POST);
return methods;
}

Expand All @@ -72,17 +89,69 @@ public boolean invoke(MessageContext messageContext) {
String param = Utils.getQueryParameter(messageContext, TASK_NAME);
String searchKey = Utils.getQueryParameter(messageContext, SEARCH_KEY);

if (Objects.nonNull(param)) {
populateTaskData(messageContext, param);
} else if (Objects.nonNull(searchKey) && !searchKey.trim().isEmpty()) {
populateSearchResults(messageContext, searchKey.toLowerCase());
if (messageContext.isDoingGET()) {
if (Objects.nonNull(param)) {
populateTaskData(messageContext, param);
} else if (Objects.nonNull(searchKey) && !searchKey.trim().isEmpty()) {
populateSearchResults(messageContext, searchKey.toLowerCase());
} else {
populateTasksList(messageContext);
}
} else {
populateTasksList(messageContext);
String userName = (String) messageContext.getProperty(USERNAME_PROPERTY);
org.apache.axis2.context.MessageContext axisMsgCtx =
((Axis2MessageContext) messageContext).getAxis2MessageContext();
try {
if (SecurityUtils.canUserEdit(userName)) {
handlePost(messageContext, axisMsgCtx);
} else {
Utils.sendForbiddenFaultResponse(axisMsgCtx);
}
} catch (UserStoreException e) {
log.error("Error occurred while retrieving the user data", e);
Utils.setJsonPayLoad(axisMsgCtx, Utils.createJsonErrorObject("Error occurred while retrieving the user data"));
}
}

axis2MessageContext.removeProperty(Constants.NO_ENTITY_BODY);
return true;
}

private void handlePost(MessageContext msgCtx, org.apache.axis2.context.MessageContext axisMsgCtx) {

Comment on lines +119 to +121
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Log Improvement Suggestion No: 1

Suggested change
private void handlePost(MessageContext msgCtx, org.apache.axis2.context.MessageContext axisMsgCtx) {
private void handlePost(MessageContext msgCtx, org.apache.axis2.context.MessageContext axisMsgCtx) {
log.info("Processing POST request for task management");

JSONObject response = null;
try {
JsonObject payload = Utils.getJsonPayload(axisMsgCtx);
if (payload.has(NAME)) {
String taskName = payload.get(NAME).getAsString();
SynapseConfiguration configuration = msgCtx.getConfiguration();
Startup task = configuration.getStartup(taskName);
if (task != null) {
String performedBy = Constants.ANONYMOUS_USER;
if (msgCtx.getProperty(USERNAME_PROPERTY) != null) {
performedBy = msgCtx.getProperty(USERNAME_PROPERTY).toString();
}
JSONObject info = new JSONObject();
info.put(TASK_NAME, taskName);
if (payload.has(STATUS)) {
response = handleStatusUpdate(task, performedBy, info, msgCtx, payload);
} else {
response = Utils.createJsonError("Unsupported operation", axisMsgCtx, Constants.BAD_REQUEST);
}
} else {
response = Utils.createJsonError("Specified task ('" + taskName + "') not found",
axisMsgCtx, Constants.BAD_REQUEST);
}
} else {
response = Utils.createJsonError("Unsupported operation", axisMsgCtx, Constants.BAD_REQUEST);
}
Utils.setJsonPayLoad(axisMsgCtx, response);
} catch (IOException e) {
log.error("Error when parsing JSON payload", e);
Utils.setJsonPayLoad(axisMsgCtx, Utils.createJsonErrorObject("Error when parsing JSON payload"));
}
}

private static List<Startup> getSearchResults(MessageContext messageContext, String searchKey) {
SynapseConfiguration configuration = messageContext.getConfiguration();
return configuration.getStartups().stream()
Expand All @@ -103,7 +172,7 @@ private void setResponseBody(Collection<Startup> tasks, MessageContext messageCo
JSONObject jsonBody = Utils.createJSONList(tasks.size());
for (Startup task : tasks) {
JSONObject taskObject = new JSONObject();
taskObject.put(Constants.NAME, task.getName());
taskObject.put(NAME, task.getName());
jsonBody.getJSONArray(Constants.LIST).put(taskObject);
}
Utils.setJsonPayLoad(axis2MessageContext, jsonBody);
Expand Down Expand Up @@ -145,7 +214,7 @@ private JSONObject convertTaskToJsonObject(TaskDescription task) {

JSONObject taskObject = new JSONObject();

taskObject.put(Constants.NAME, task.getName());
taskObject.put(NAME, task.getName());

String triggerType = "cron";

Expand Down Expand Up @@ -209,7 +278,7 @@ private JSONObject getTaskAsJson(TaskDescription task) {

JSONObject taskObject = new JSONObject();

taskObject.put(Constants.NAME, task.getName());
taskObject.put(NAME, task.getName());
taskObject.put("taskGroup", task.getTaskGroup());
taskObject.put("implementation", task.getTaskImplClassName());
String triggerType = "simple";
Expand All @@ -227,4 +296,66 @@ private JSONObject getTaskAsJson(TaskDescription task) {

return taskObject;
}

/**
* Handles the activation or deactivation of a schedule task based on the provided status.
*
* @param performedBy The user performing the operation, used for audit logging.
* @param info A JSON object containing additional audit information.
* @param messageContext The current Synapse {@link MessageContext} for accessing the configuration.
* @param payload A {@link JsonObject} containing the task name and desired status.
*
* @return A {@link JSONObject} indicating the result of the operation. If successful, contains
* a confirmation message. If unsuccessful, contains an error message with appropriate
* HTTP error codes.
*/
private JSONObject handleStatusUpdate(Startup task, String performedBy, JSONObject info,
MessageContext messageContext, JsonObject payload) {
String name = payload.get(NAME).getAsString();
String status = payload.get(STATUS).getAsString();

org.apache.axis2.context.MessageContext axis2MessageContext =
((Axis2MessageContext) messageContext).getAxis2MessageContext();
JSONObject jsonResponse = new JSONObject();
StartUpController controllerTask = null;
if (task instanceof StartUpController) {
controllerTask = (StartUpController)task;
} else {
return Utils.createJsonError("Task could not be found",
axis2MessageContext, Constants.NOT_FOUND);
}

if (INACTIVE_STATUS.equalsIgnoreCase(status)) {
DynamicControlOperationResult result = controllerTask.deactivate();
if (result.isSuccess()) {
jsonResponse.put(Constants.MESSAGE_JSON_ATTRIBUTE, name + " : is deactivated");
AuditLogger.logAuditMessage(performedBy, Constants.AUDIT_LOG_TYPE_TASK,
Constants.AUDIT_LOG_ACTION_DISABLED, info);
} else {
jsonResponse = Utils.createJsonError(result.getMessage(), axis2MessageContext, Constants.INTERNAL_SERVER_ERROR);
}
} else if (ACTIVE_STATUS.equalsIgnoreCase(status)) {
DynamicControlOperationResult result = controllerTask.activate();
if (result.isSuccess()) {
jsonResponse.put(Constants.MESSAGE_JSON_ATTRIBUTE, name + " : is activated");
AuditLogger.logAuditMessage(performedBy, Constants.AUDIT_LOG_TYPE_TASK,
Constants.AUDIT_LOG_ACTION_ENABLE, info);
} else {
jsonResponse = Utils.createJsonError(result.getMessage(), axis2MessageContext, Constants.INTERNAL_SERVER_ERROR);
}
} else if (TRIGGER_STATUS.equalsIgnoreCase(status)) {
DynamicControlOperationResult result = controllerTask.trigger();
if (result.isSuccess()) {
jsonResponse.put(Constants.MESSAGE_JSON_ATTRIBUTE, name + " : is triggered");
AuditLogger.logAuditMessage(performedBy, Constants.AUDIT_LOG_TYPE_TASK,
Constants.AUDIT_LOG_ACTION_TRIGGERED, info);
} else {
jsonResponse = Utils.createJsonError(result.getMessage(), axis2MessageContext, Constants.INTERNAL_SERVER_ERROR);
}
} else {
jsonResponse = Utils.createJsonError("Provided state is not valid", axis2MessageContext, Constants.BAD_REQUEST);
}

return jsonResponse;
}
}
Loading