Browse Source

Merge branch 'fix/invoke' into 'wrdp'

优化invoke执行,尽量走缓存

See merge request o2oa/o2oa!2062
o2null 5 years ago
parent
commit
19e0744720

+ 149 - 147
o2server/x_processplatform_service_processing/src/main/java/com/x/processplatform/service/processing/jaxrs/work/BaseAction.java

@@ -23,152 +23,154 @@ import com.x.query.core.entity.Item;
 
 abstract class BaseAction extends StandardJaxrsAction {
 
-    protected boolean cascadeDeleteWorkBeginButNotCommit(Business business, Work work) throws Exception {
-        if (business.work().listWithJob(work.getJob()).size() > 1) {
-            List<String> taskIds = business.entityManagerContainer().idsEqual(Task.class, Task.work_FIELDNAME,
-                    work.getId());
-            if (ListTools.isNotEmpty(taskIds)) {
-                business.entityManagerContainer().beginTransaction(Task.class);
-                business.entityManagerContainer().delete(Task.class, taskIds);
-            }
-            business.entityManagerContainer().beginTransaction(Work.class);
-            business.entityManagerContainer().remove(work, CheckRemoveType.all);
-            business.entityManagerContainer().commit();
-            return false;
-        } else {
-            deleteTask(business, work.getJob());
-            deleteTaskCompleted(business, work.getJob());
-            deleteRead(business, work.getJob());
-            deleteReadCompleted(business, work.getJob());
-            deleteReview(business, work.getJob());
-            deleteAttachment(business, work.getJob());
-            deleteWorkLog(business, work.getJob());
-            deleteItem(business, work.getJob());
-            deleteDocumentVersion(business, work.getJob());
-            deleteRecord(business, work.getJob());
-            deleteWork(business, work);
-            return true;
-        }
-    }
-
-    private void deleteTask(Business business, String job) throws Exception {
-        List<String> ids = business.entityManagerContainer().idsEqual(Task.class, Task.job_FIELDNAME, job);
-        if (ListTools.isNotEmpty(ids)) {
-            business.entityManagerContainer().beginTransaction(Task.class);
-            for (Task o : business.entityManagerContainer().list(Task.class, ids)) {
-                business.entityManagerContainer().remove(o);
-                MessageFactory.task_delete(o);
-            }
-        }
-    }
-
-    private void deleteTaskCompleted(Business business, String job) throws Exception {
-        List<String> ids = business.entityManagerContainer().idsEqual(TaskCompleted.class, TaskCompleted.job_FIELDNAME,
-                job);
-        if (ListTools.isNotEmpty(ids)) {
-            business.entityManagerContainer().beginTransaction(TaskCompleted.class);
-            for (TaskCompleted o : business.entityManagerContainer().list(TaskCompleted.class, ids)) {
-                business.entityManagerContainer().remove(o);
-                MessageFactory.taskCompleted_delete(o);
-            }
-        }
-    }
-
-    private void deleteRead(Business business, String job) throws Exception {
-        List<String> ids = business.entityManagerContainer().idsEqual(Read.class, Read.job_FIELDNAME, job);
-        if (ListTools.isNotEmpty(ids)) {
-            business.entityManagerContainer().beginTransaction(Read.class);
-            for (Read o : business.entityManagerContainer().list(Read.class, ids)) {
-                business.entityManagerContainer().remove(o);
-                MessageFactory.read_delete(o);
-            }
-        }
-    }
-
-    private void deleteReadCompleted(Business business, String job) throws Exception {
-        List<String> ids = business.entityManagerContainer().idsEqual(ReadCompleted.class, ReadCompleted.job_FIELDNAME,
-                job);
-        if (ListTools.isNotEmpty(ids)) {
-            business.entityManagerContainer().beginTransaction(ReadCompleted.class);
-            for (ReadCompleted o : business.entityManagerContainer().list(ReadCompleted.class, ids)) {
-                business.entityManagerContainer().remove(o);
-                MessageFactory.readCompleted_delete(o);
-            }
-        }
-    }
-
-    private void deleteReview(Business business, String job) throws Exception {
-        List<String> ids = business.entityManagerContainer().idsEqual(Review.class, Review.job_FIELDNAME, job);
-        if (ListTools.isNotEmpty(ids)) {
-            business.entityManagerContainer().beginTransaction(Review.class);
-            business.entityManagerContainer().delete(Review.class, ids);
-        }
-    }
-
-    private void deleteAttachment(Business business, String job) throws Exception {
-        List<String> ids = business.entityManagerContainer().idsEqual(Attachment.class, Attachment.job_FIELDNAME, job);
-        if (ListTools.isNotEmpty(ids)) {
-            business.entityManagerContainer().beginTransaction(Attachment.class);
-            Attachment obj;
-            for (String id : ids) {
-                obj = business.entityManagerContainer().find(id, Attachment.class);
-                if (null != obj) {
-                    StorageMapping mapping = ThisApplication.context().storageMappings().get(Attachment.class,
-                            obj.getStorage());
-                    if (null != mapping) {
-                        obj.deleteContent(mapping);
-                    }
-                    business.entityManagerContainer().remove(obj, CheckRemoveType.all);
-                }
-            }
-        }
-    }
-
-    private void deleteWorkLog(Business business, String job) throws Exception {
-        List<String> ids = business.entityManagerContainer().idsEqual(WorkLog.class, WorkLog.job_FIELDNAME, job);
-        if (ListTools.isNotEmpty(ids)) {
-            business.entityManagerContainer().beginTransaction(WorkLog.class);
-            business.entityManagerContainer().delete(WorkLog.class, ids);
-        }
-    }
-
-    private void deleteItem(Business business, String job) throws Exception {
-        List<String> ids = business.entityManagerContainer().idsEqual(Item.class, Item.bundle_FIELDNAME, job);
-        if (ListTools.isNotEmpty(ids)) {
-            business.entityManagerContainer().beginTransaction(Item.class);
-            business.entityManagerContainer().delete(Item.class, ids);
-        }
-    }
-
-    private void deleteWork(Business business, Work work) throws Exception {
-        business.entityManagerContainer().beginTransaction(Work.class);
-        List<String> ids = business.entityManagerContainer().idsEqualAndNotEqual(Work.class, Work.job_FIELDNAME,
-                work.getJob(), Work.id_FIELDNAME, work.getId());
-        if (ListTools.isNotEmpty(ids)) {
-            for (Work o : business.entityManagerContainer().list(Work.class, ids)) {
-                business.entityManagerContainer().remove(o);
-                MessageFactory.work_delete(o);
-            }
-        }
-        business.entityManagerContainer().remove(work);
-        MessageFactory.work_delete(work);
-    }
-
-    private void deleteDocumentVersion(Business business, String job) throws Exception {
-        List<String> ids = business.entityManagerContainer().idsEqual(DocumentVersion.class,
-                DocumentVersion.job_FIELDNAME, job);
-        if (ListTools.isNotEmpty(ids)) {
-            business.entityManagerContainer().beginTransaction(DocumentVersion.class);
-            business.entityManagerContainer().delete(DocumentVersion.class, ids);
-        }
-    }
-
-    private void deleteRecord(Business business, String job) throws Exception {
-        List<String> ids = business.entityManagerContainer().idsEqual(Record.class, Record.job_FIELDNAME, job);
-        if (ListTools.isNotEmpty(ids)) {
-            business.entityManagerContainer().beginTransaction(Record.class);
-            business.entityManagerContainer().delete(Record.class, ids);
-        }
-    }
+	protected boolean cascadeDeleteWorkBeginButNotCommit(Business business, Work work) throws Exception {
+		if (business.work().listWithJob(work.getJob()).size() > 1) {
+			List<String> taskIds = business.entityManagerContainer().idsEqual(Task.class, Task.work_FIELDNAME,
+					work.getId());
+			if (ListTools.isNotEmpty(taskIds)) {
+				business.entityManagerContainer().beginTransaction(Task.class);
+				for (Task o : business.entityManagerContainer().list(Task.class, taskIds)) {
+					business.entityManagerContainer().remove(o);
+					MessageFactory.task_delete(o);
+				}
+			}
+			business.entityManagerContainer().beginTransaction(Work.class);
+			business.entityManagerContainer().remove(work, CheckRemoveType.all);
+			return false;
+		} else {
+			deleteTask(business, work.getJob());
+			deleteTaskCompleted(business, work.getJob());
+			deleteRead(business, work.getJob());
+			deleteReadCompleted(business, work.getJob());
+			deleteReview(business, work.getJob());
+			deleteAttachment(business, work.getJob());
+			deleteWorkLog(business, work.getJob());
+			deleteItem(business, work.getJob());
+			deleteDocumentVersion(business, work.getJob());
+			deleteRecord(business, work.getJob());
+			deleteWork(business, work);
+			return true;
+		}
+	}
+
+	private void deleteTask(Business business, String job) throws Exception {
+		List<String> ids = business.entityManagerContainer().idsEqual(Task.class, Task.job_FIELDNAME, job);
+		if (ListTools.isNotEmpty(ids)) {
+			business.entityManagerContainer().beginTransaction(Task.class);
+			for (Task o : business.entityManagerContainer().list(Task.class, ids)) {
+				business.entityManagerContainer().remove(o);
+				MessageFactory.task_delete(o);
+			}
+		}
+	}
+
+	private void deleteTaskCompleted(Business business, String job) throws Exception {
+		List<String> ids = business.entityManagerContainer().idsEqual(TaskCompleted.class, TaskCompleted.job_FIELDNAME,
+				job);
+		if (ListTools.isNotEmpty(ids)) {
+			business.entityManagerContainer().beginTransaction(TaskCompleted.class);
+			for (TaskCompleted o : business.entityManagerContainer().list(TaskCompleted.class, ids)) {
+				business.entityManagerContainer().remove(o);
+				MessageFactory.taskCompleted_delete(o);
+			}
+		}
+	}
+
+	private void deleteRead(Business business, String job) throws Exception {
+		List<String> ids = business.entityManagerContainer().idsEqual(Read.class, Read.job_FIELDNAME, job);
+		if (ListTools.isNotEmpty(ids)) {
+			business.entityManagerContainer().beginTransaction(Read.class);
+			for (Read o : business.entityManagerContainer().list(Read.class, ids)) {
+				business.entityManagerContainer().remove(o);
+				MessageFactory.read_delete(o);
+			}
+		}
+	}
+
+	private void deleteReadCompleted(Business business, String job) throws Exception {
+		List<String> ids = business.entityManagerContainer().idsEqual(ReadCompleted.class, ReadCompleted.job_FIELDNAME,
+				job);
+		if (ListTools.isNotEmpty(ids)) {
+			business.entityManagerContainer().beginTransaction(ReadCompleted.class);
+			for (ReadCompleted o : business.entityManagerContainer().list(ReadCompleted.class, ids)) {
+				business.entityManagerContainer().remove(o);
+				MessageFactory.readCompleted_delete(o);
+			}
+		}
+	}
+
+	private void deleteReview(Business business, String job) throws Exception {
+		List<String> ids = business.entityManagerContainer().idsEqual(Review.class, Review.job_FIELDNAME, job);
+		if (ListTools.isNotEmpty(ids)) {
+			business.entityManagerContainer().beginTransaction(Review.class);
+			business.entityManagerContainer().delete(Review.class, ids);
+		}
+	}
+
+	private void deleteAttachment(Business business, String job) throws Exception {
+		List<String> ids = business.entityManagerContainer().idsEqual(Attachment.class, Attachment.job_FIELDNAME, job);
+		if (ListTools.isNotEmpty(ids)) {
+			business.entityManagerContainer().beginTransaction(Attachment.class);
+			Attachment obj;
+			for (String id : ids) {
+				obj = business.entityManagerContainer().find(id, Attachment.class);
+				if (null != obj) {
+					StorageMapping mapping = ThisApplication.context().storageMappings().get(Attachment.class,
+							obj.getStorage());
+					if (null != mapping) {
+						obj.deleteContent(mapping);
+					}
+					business.entityManagerContainer().remove(obj, CheckRemoveType.all);
+				}
+			}
+		}
+	}
+
+	private void deleteWorkLog(Business business, String job) throws Exception {
+		List<String> ids = business.entityManagerContainer().idsEqual(WorkLog.class, WorkLog.job_FIELDNAME, job);
+		if (ListTools.isNotEmpty(ids)) {
+			business.entityManagerContainer().beginTransaction(WorkLog.class);
+			business.entityManagerContainer().delete(WorkLog.class, ids);
+		}
+	}
+
+	private void deleteItem(Business business, String job) throws Exception {
+		List<String> ids = business.entityManagerContainer().idsEqual(Item.class, Item.bundle_FIELDNAME, job);
+		if (ListTools.isNotEmpty(ids)) {
+			business.entityManagerContainer().beginTransaction(Item.class);
+			business.entityManagerContainer().delete(Item.class, ids);
+		}
+	}
+
+	private void deleteWork(Business business, Work work) throws Exception {
+		business.entityManagerContainer().beginTransaction(Work.class);
+		List<String> ids = business.entityManagerContainer().idsEqualAndNotEqual(Work.class, Work.job_FIELDNAME,
+				work.getJob(), Work.id_FIELDNAME, work.getId());
+		if (ListTools.isNotEmpty(ids)) {
+			for (Work o : business.entityManagerContainer().list(Work.class, ids)) {
+				business.entityManagerContainer().remove(o);
+				MessageFactory.work_delete(o);
+			}
+		}
+		business.entityManagerContainer().remove(work);
+		MessageFactory.work_delete(work);
+	}
+
+	private void deleteDocumentVersion(Business business, String job) throws Exception {
+		List<String> ids = business.entityManagerContainer().idsEqual(DocumentVersion.class,
+				DocumentVersion.job_FIELDNAME, job);
+		if (ListTools.isNotEmpty(ids)) {
+			business.entityManagerContainer().beginTransaction(DocumentVersion.class);
+			business.entityManagerContainer().delete(DocumentVersion.class, ids);
+		}
+	}
+
+	private void deleteRecord(Business business, String job) throws Exception {
+		List<String> ids = business.entityManagerContainer().idsEqual(Record.class, Record.job_FIELDNAME, job);
+		if (ListTools.isNotEmpty(ids)) {
+			business.entityManagerContainer().beginTransaction(Record.class);
+			business.entityManagerContainer().delete(Record.class, ids);
+		}
+	}
 
 }

+ 95 - 76
o2server/x_program_center/src/main/java/com/x/program/center/jaxrs/invoke/ActionExecute.java

@@ -1,6 +1,5 @@
 package com.x.program.center.jaxrs.invoke;
 
-import java.util.Date;
 import java.util.Objects;
 import java.util.Optional;
 import java.util.regex.Matcher;
@@ -12,7 +11,6 @@ import javax.script.ScriptContext;
 import javax.script.SimpleScriptContext;
 import javax.servlet.http.HttpServletRequest;
 
-import com.x.base.core.project.cache.CacheManager;
 import org.apache.commons.lang3.BooleanUtils;
 import org.apache.commons.lang3.StringUtils;
 
@@ -21,7 +19,8 @@ import com.x.base.core.container.EntityManagerContainer;
 import com.x.base.core.container.factory.EntityManagerContainerFactory;
 import com.x.base.core.project.cache.Cache.CacheCategory;
 import com.x.base.core.project.cache.Cache.CacheKey;
-import com.x.base.core.entity.annotation.CheckPersistType;
+import com.x.base.core.project.cache.CacheManager;
+import com.x.base.core.project.exception.ExceptionEntityNotExist;
 import com.x.base.core.project.http.ActionResult;
 import com.x.base.core.project.http.EffectivePerson;
 import com.x.base.core.project.jaxrs.WoContentType;
@@ -44,86 +43,104 @@ class ActionExecute extends BaseAction {
 
 	ActionResult<Object> execute(HttpServletRequest request, EffectivePerson effectivePerson, String flag,
 			JsonElement jsonElement) throws Exception {
-		try (EntityManagerContainer emc = EntityManagerContainerFactory.instance().create()) {
-			ActionResult<Object> result = new ActionResult<>();
-			Invoke invoke = emc.flag(flag, Invoke.class);
-			if (null == invoke) {
-				throw new ExceptionInvokeNotExist(flag);
-			}
-			if (!BooleanUtils.isTrue(invoke.getEnable())) {
-				throw new ExceptionNotEnable(invoke.getName());
-			}
-			if (StringUtils.isNotEmpty(invoke.getRemoteAddrRegex())) {
-				Matcher matcher = Pattern.compile(invoke.getRemoteAddrRegex()).matcher(request.getRemoteAddr());
-				if (!matcher.find()) {
-					throw new ExceptionInvalidRemoteAddr(request.getRemoteAddr(), invoke.getName());
-				}
-			}
-			emc.beginTransaction(Invoke.class);
-			invoke.setLastStartTime(new Date());
-			emc.commit();
-
-			CacheCategory cacheCategory = new CacheCategory(Invoke.class);
-			CacheKey cacheKey = new CacheKey(ActionExecute.class, invoke.getId());
-			CompiledScript compiledScript = null;
-			Optional<?> optional = CacheManager.get(cacheCategory, cacheKey);
-			if (optional.isPresent()) {
-				compiledScript = (CompiledScript)optional.get();
-			}else {
-				compiledScript = ScriptFactory.compile(invoke.getText());
-				CacheManager.put(cacheCategory, cacheKey, compiledScript);
-			}
 
-			ScriptContext scriptContext = new SimpleScriptContext();
-			Bindings bindings = scriptContext.getBindings(ScriptContext.ENGINE_SCOPE);
-			Resources resources = new Resources();
-			resources.setEntityManagerContainer(emc);
-			resources.setContext(ThisApplication.context());
-			resources.setOrganization(new Organization(ThisApplication.context()));
-			resources.setWebservicesClient(new WebservicesClient());
-			resources.setApplications(ThisApplication.context().applications());
-			bindings.put(ScriptFactory.BINDING_NAME_RESOURCES, resources);
-			bindings.put("requestText", gson.toJson(jsonElement));
-			bindings.put("request", request);
-			bindings.put("effectivePerson", effectivePerson);
-			bindings.put(ScriptFactory.BINDING_NAME_APPLICATIONS, ThisApplication.context().applications());
-			CustomResponse customResponse = new CustomResponse();
-			bindings.put("customResponse", customResponse);
-			Wo wo = new Wo();
-			try {
-				ScriptFactory.initialServiceScriptText().eval(scriptContext);
-				Object o = compiledScript.eval(scriptContext);
-				if (StringUtils.equals("seeOther", customResponse.type)) {
-					WoSeeOther woSeeOther = new WoSeeOther(Objects.toString(customResponse.value, ""));
-					result.setData(woSeeOther);
-				} else if (StringUtils.equals("temporaryRedirect", customResponse.type)) {
-					WoTemporaryRedirect woTemporaryRedirect = new WoTemporaryRedirect(
-							Objects.toString(customResponse.value, ""));
-					result.setData(woTemporaryRedirect);
-				} else {
-					if (null != customResponse.value) {
-						if (StringUtils.isNotEmpty(customResponse.contentType)) {
-							result.setData(new WoContentType(customResponse.value, customResponse.contentType));
-						} else if (customResponse.value instanceof WoText) {
-							result.setData(customResponse.value);
-						} else {
-							wo.setValue(customResponse.value);
-							result.setData(wo);
-						}
+		CacheCategory cacheCategory = new CacheCategory(Invoke.class);
+
+		Invoke invoke = this.get(cacheCategory, flag);
+
+		if (null == invoke) {
+			throw new ExceptionEntityNotExist(flag, Invoke.class);
+		}
+
+		if (!BooleanUtils.isTrue(invoke.getEnable())) {
+			throw new ExceptionNotEnable(invoke.getName());
+		}
+		
+		if (StringUtils.isNotEmpty(invoke.getRemoteAddrRegex())) {
+			Matcher matcher = Pattern.compile(invoke.getRemoteAddrRegex()).matcher(request.getRemoteAddr());
+			if (!matcher.find()) {
+				throw new ExceptionInvalidRemoteAddr(request.getRemoteAddr(), invoke.getName());
+			}
+		}
+		
+		ActionResult<Object> result = new ActionResult<>();
+		CompiledScript compiledScript = this.getCompiledScript(cacheCategory, invoke);
+		ScriptContext scriptContext = new SimpleScriptContext();
+		Bindings bindings = scriptContext.getBindings(ScriptContext.ENGINE_SCOPE);
+		Resources resources = new Resources();
+		// 此方法不用装载emc
+		// resources.setEntityManagerContainer(emc);
+		resources.setContext(ThisApplication.context());
+		resources.setOrganization(new Organization(ThisApplication.context()));
+		resources.setWebservicesClient(new WebservicesClient());
+		resources.setApplications(ThisApplication.context().applications());
+		bindings.put(ScriptFactory.BINDING_NAME_RESOURCES, resources);
+		bindings.put("requestText", gson.toJson(jsonElement));
+		bindings.put("request", request);
+		bindings.put("effectivePerson", effectivePerson);
+		bindings.put(ScriptFactory.BINDING_NAME_APPLICATIONS, ThisApplication.context().applications());
+		CustomResponse customResponse = new CustomResponse();
+		bindings.put("customResponse", customResponse);
+		Wo wo = new Wo();
+		try {
+			ScriptFactory.initialServiceScriptText().eval(scriptContext);
+			Object o = compiledScript.eval(scriptContext);
+			if (StringUtils.equals("seeOther", customResponse.type)) {
+				WoSeeOther woSeeOther = new WoSeeOther(Objects.toString(customResponse.value, ""));
+				result.setData(woSeeOther);
+			} else if (StringUtils.equals("temporaryRedirect", customResponse.type)) {
+				WoTemporaryRedirect woTemporaryRedirect = new WoTemporaryRedirect(
+						Objects.toString(customResponse.value, ""));
+				result.setData(woTemporaryRedirect);
+			} else {
+				if (null != customResponse.value) {
+					if (StringUtils.isNotEmpty(customResponse.contentType)) {
+						result.setData(new WoContentType(customResponse.value, customResponse.contentType));
+					} else if (customResponse.value instanceof WoText) {
+						result.setData(customResponse.value);
 					} else {
-						wo.setValue(o);
+						wo.setValue(customResponse.value);
 						result.setData(wo);
 					}
+				} else {
+					wo.setValue(o);
+					result.setData(wo);
 				}
-			} catch (Exception e) {
-				throw new ExceptionExecuteError(invoke.getName(), e);
 			}
-			emc.beginTransaction(Invoke.class);
-			invoke.setLastEndTime(new Date());
-			emc.check(invoke, CheckPersistType.all);
-			emc.commit();
-			return result;
+		} catch (Exception e) {
+			throw new ExceptionExecuteError(invoke.getName(), e);
 		}
+
+		return result;
+	}
+
+	private Invoke get(CacheCategory cacheCategory, String flag) throws Exception {
+		CacheKey cacheKey = new CacheKey(ActionExecute.class, flag);
+		Optional<?> optional = CacheManager.get(cacheCategory, cacheKey);
+		if (optional.isPresent()) {
+			return (Invoke) optional.get();
+		} else {
+			try (EntityManagerContainer emc = EntityManagerContainerFactory.instance().create()) {
+				Invoke invoke = emc.flag(flag, Invoke.class);
+				if (null != invoke) {
+					CacheManager.put(cacheCategory, cacheKey, invoke);
+				}
+				return invoke;
+			}
+		}
+	}
+
+	private CompiledScript getCompiledScript(CacheCategory cacheCategory, Invoke invoke) throws Exception {
+		CacheKey cacheKey = new CacheKey(ActionExecute.class, "CompiledScript", invoke.getId());
+		CompiledScript compiledScript = null;
+		Optional<?> optional = CacheManager.get(cacheCategory, cacheKey);
+		if (optional.isPresent()) {
+			compiledScript = (CompiledScript) optional.get();
+		} else {
+			compiledScript = ScriptFactory.compile(invoke.getText());
+			CacheManager.put(cacheCategory, cacheKey, compiledScript);
+		}
+		return compiledScript;
 	}
 
 	public static class CustomResponse {
@@ -154,6 +171,8 @@ class ActionExecute extends BaseAction {
 
 	public static class Wo extends WoValue {
 
+		private static final long serialVersionUID = -2253926744723217590L;
+
 	}
 
 	public static class Resources extends AbstractResources {

+ 171 - 0
o2server/x_program_center/src/main/java/com/x/program/center/jaxrs/invoke/ActionExecute2.java

@@ -0,0 +1,171 @@
+package com.x.program.center.jaxrs.invoke;
+
+import java.util.Date;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import javax.script.Bindings;
+import javax.script.CompiledScript;
+import javax.script.ScriptContext;
+import javax.script.SimpleScriptContext;
+import javax.servlet.http.HttpServletRequest;
+
+import com.x.base.core.project.cache.CacheManager;
+import org.apache.commons.lang3.BooleanUtils;
+import org.apache.commons.lang3.StringUtils;
+
+import com.google.gson.JsonElement;
+import com.x.base.core.container.EntityManagerContainer;
+import com.x.base.core.container.factory.EntityManagerContainerFactory;
+import com.x.base.core.project.cache.Cache.CacheCategory;
+import com.x.base.core.project.cache.Cache.CacheKey;
+import com.x.base.core.entity.annotation.CheckPersistType;
+import com.x.base.core.project.http.ActionResult;
+import com.x.base.core.project.http.EffectivePerson;
+import com.x.base.core.project.jaxrs.WoContentType;
+import com.x.base.core.project.jaxrs.WoSeeOther;
+import com.x.base.core.project.jaxrs.WoTemporaryRedirect;
+import com.x.base.core.project.jaxrs.WoText;
+import com.x.base.core.project.jaxrs.WoValue;
+import com.x.base.core.project.logger.Logger;
+import com.x.base.core.project.logger.LoggerFactory;
+import com.x.base.core.project.script.AbstractResources;
+import com.x.base.core.project.script.ScriptFactory;
+import com.x.base.core.project.webservices.WebservicesClient;
+import com.x.organization.core.express.Organization;
+import com.x.program.center.ThisApplication;
+import com.x.program.center.core.entity.Invoke;
+
+class ActionExecute2 extends BaseAction {
+
+	private static Logger logger = LoggerFactory.getLogger(ActionExecute2.class);
+
+	ActionResult<Object> execute(HttpServletRequest request, EffectivePerson effectivePerson, String flag,
+			JsonElement jsonElement) throws Exception {
+		try (EntityManagerContainer emc = EntityManagerContainerFactory.instance().create()) {
+			ActionResult<Object> result = new ActionResult<>();
+			Invoke invoke = emc.flag(flag, Invoke.class);
+			if (null == invoke) {
+				throw new ExceptionInvokeNotExist(flag);
+			}
+			if (!BooleanUtils.isTrue(invoke.getEnable())) {
+				throw new ExceptionNotEnable(invoke.getName());
+			}
+			if (StringUtils.isNotEmpty(invoke.getRemoteAddrRegex())) {
+				Matcher matcher = Pattern.compile(invoke.getRemoteAddrRegex()).matcher(request.getRemoteAddr());
+				if (!matcher.find()) {
+					throw new ExceptionInvalidRemoteAddr(request.getRemoteAddr(), invoke.getName());
+				}
+			}
+			emc.beginTransaction(Invoke.class);
+			invoke.setLastStartTime(new Date());
+			emc.commit();
+
+			CacheCategory cacheCategory = new CacheCategory(Invoke.class);
+			CacheKey cacheKey = new CacheKey(ActionExecute2.class, invoke.getId());
+			CompiledScript compiledScript = null;
+			Optional<?> optional = CacheManager.get(cacheCategory, cacheKey);
+			if (optional.isPresent()) {
+				compiledScript = (CompiledScript)optional.get();
+			}else {
+				compiledScript = ScriptFactory.compile(invoke.getText());
+				CacheManager.put(cacheCategory, cacheKey, compiledScript);
+			}
+
+			ScriptContext scriptContext = new SimpleScriptContext();
+			Bindings bindings = scriptContext.getBindings(ScriptContext.ENGINE_SCOPE);
+			Resources resources = new Resources();
+			resources.setEntityManagerContainer(emc);
+			resources.setContext(ThisApplication.context());
+			resources.setOrganization(new Organization(ThisApplication.context()));
+			resources.setWebservicesClient(new WebservicesClient());
+			resources.setApplications(ThisApplication.context().applications());
+			bindings.put(ScriptFactory.BINDING_NAME_RESOURCES, resources);
+			bindings.put("requestText", gson.toJson(jsonElement));
+			bindings.put("request", request);
+			bindings.put("effectivePerson", effectivePerson);
+			bindings.put(ScriptFactory.BINDING_NAME_APPLICATIONS, ThisApplication.context().applications());
+			CustomResponse customResponse = new CustomResponse();
+			bindings.put("customResponse", customResponse);
+			Wo wo = new Wo();
+			try {
+				ScriptFactory.initialServiceScriptText().eval(scriptContext);
+				Object o = compiledScript.eval(scriptContext);
+				if (StringUtils.equals("seeOther", customResponse.type)) {
+					WoSeeOther woSeeOther = new WoSeeOther(Objects.toString(customResponse.value, ""));
+					result.setData(woSeeOther);
+				} else if (StringUtils.equals("temporaryRedirect", customResponse.type)) {
+					WoTemporaryRedirect woTemporaryRedirect = new WoTemporaryRedirect(
+							Objects.toString(customResponse.value, ""));
+					result.setData(woTemporaryRedirect);
+				} else {
+					if (null != customResponse.value) {
+						if (StringUtils.isNotEmpty(customResponse.contentType)) {
+							result.setData(new WoContentType(customResponse.value, customResponse.contentType));
+						} else if (customResponse.value instanceof WoText) {
+							result.setData(customResponse.value);
+						} else {
+							wo.setValue(customResponse.value);
+							result.setData(wo);
+						}
+					} else {
+						wo.setValue(o);
+						result.setData(wo);
+					}
+				}
+			} catch (Exception e) {
+				throw new ExceptionExecuteError(invoke.getName(), e);
+			}
+			emc.beginTransaction(Invoke.class);
+			invoke.setLastEndTime(new Date());
+			emc.check(invoke, CheckPersistType.all);
+			emc.commit();
+			return result;
+		}
+	}
+
+	public static class CustomResponse {
+		protected String type = null;
+		protected Object value;
+		protected String contentType;
+
+		public void seeOther(String url) {
+			this.type = "seeOther";
+			this.value = url;
+		}
+
+		public void temporaryRedirect(String url) {
+			this.type = "temporaryRedirect";
+			this.value = url;
+		}
+
+		public void setBody(Object obj) {
+			this.value = obj;
+		}
+
+		public void setBody(Object obj, String contentType) {
+			this.value = obj;
+			this.contentType = contentType;
+		}
+
+	}
+
+	public static class Wo extends WoValue {
+
+	}
+
+	public static class Resources extends AbstractResources {
+		private Organization organization;
+
+		public Organization getOrganization() {
+			return organization;
+		}
+
+		public void setOrganization(Organization organization) {
+			this.organization = organization;
+		}
+
+	}
+}