Browse Source

Merge branch 'fix/editConfig0821#326' into 'develop'

增加在线编辑配置文件

See merge request o2oa/o2oa!1449
o2null 5 years ago
parent
commit
4e6c65c201

+ 39 - 0
o2server/configSample/manifest.cfg

@@ -0,0 +1,39 @@
+{"node_127.0.0.1.json":"节点配置",
+ "appStyle.json":"应用样式配置",
+ "centerServer.json":"中心服务配置",
+ "clientInit.json":"客户端初始化配置",
+ "collect.json":"连接到云平台配置",
+ "communicate.json":"消息配置",
+ "components.json":"组件配置",
+ "dingding.json":"钉钉配置",
+ "dumpRestoreData.json":"导出导入数据配置",
+ "dumpRestoreStorage.json":"导出导入文件配置",
+ "exmail.json":"邮件配置",
+ "externalDataSources.json":"数据库配置",
+ "externalDataSources_db2.json":"db2数据库配置",
+ "externalDataSources_dm.json":"达梦数据库配置",
+ "externalDataSources_informix.json":"informix数据库配置",
+ "externalDataSources_kingbase.json":"金仓数据库配置",
+ "externalDataSources_mysql.json":"mysql数据库配置",
+ "externalDataSources_oracle.json":"oracle数据库配置",
+ "externalDataSources_postgresql.json":"postgresql数据库配置",
+ "externalDataSources_sqlserver.json":"sqlserver数据库配置",
+ "externalStorageSources.json":"文件存储配置",
+ "jpushConfig.json":"极光推送配置",
+ "logLevel.json":"日志配置",
+ "meeting.json":"openMeeting配置",
+ "messages.json":"消息发送配置",
+ "messageSendRule.js":"消息发送规则",
+ "mq.json":"消息队列配置",
+ "person.json":"个人信息配置",
+ "portal.json":"门户配置",
+ "processPlatform.json":"流程平台配置",
+ "pushConfig.json":"极光推送配置",
+ "qiyeweixin.json":"微信配置",
+ "query.json":"定时任务配置",
+ "token.json":"sso配置",
+ "vfs.json":"附件上传配置",
+ "welink.json":"华为WeLink配置",
+ "workTime.json":"工作时间配置",
+ "zhengwuDingding.json":"政务钉钉配置"
+}

+ 2 - 0
o2server/x_program_center/src/main/java/com/x/program/center/jaxrs/ActionApplication.java

@@ -20,6 +20,7 @@ import com.x.program.center.jaxrs.config.ConfigAction;
 import com.x.program.center.jaxrs.datastructure.DataStructureAction;
 import com.x.program.center.jaxrs.dingding.DingdingAction;
 import com.x.program.center.jaxrs.distribute.DistributeAction;
+import com.x.program.center.jaxrs.edit.EditConfigAction;
 import com.x.program.center.jaxrs.input.InputAction;
 import com.x.program.center.jaxrs.invoke.InvokeAction;
 import com.x.program.center.jaxrs.jest.JestAction;
@@ -72,6 +73,7 @@ public class ActionApplication extends AbstractActionApplication {
 		classes.add(OutputAction.class);
 		classes.add(InputAction.class);
 		classes.add(MarketAction.class);
+		classes.add(EditConfigAction.class);
 		return classes;
 	}
 }

+ 13 - 0
o2server/x_program_center/src/main/java/com/x/program/center/jaxrs/EditConfigJaxrsFilter.java

@@ -0,0 +1,13 @@
+package com.x.program.center.jaxrs;
+
+import javax.servlet.annotation.WebFilter;
+
+import com.x.base.core.project.jaxrs.CipherManagerJaxrsFilter;
+
+@WebFilter(urlPatterns = "/jaxrs/editconfig/*", asyncSupported = true)
+public class EditConfigJaxrsFilter extends CipherManagerJaxrsFilter {
+
+	
+	
+	
+}

+ 143 - 0
o2server/x_program_center/src/main/java/com/x/program/center/jaxrs/edit/ActionList.java

@@ -0,0 +1,143 @@
+package com.x.program.center.jaxrs.edit;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.File;
+import java.io.FileFilter;
+import java.net.Socket;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.io.filefilter.WildcardFileFilter;
+import org.apache.commons.lang3.StringUtils;
+
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
+import com.x.base.core.project.annotation.FieldDescribe;
+import com.x.base.core.project.config.Config;
+import com.x.base.core.project.gson.GsonPropertyObject;
+import com.x.base.core.project.gson.XGsonBuilder;
+import com.x.base.core.project.http.ActionResult;
+import com.x.base.core.project.http.EffectivePerson;
+import com.x.base.core.project.logger.Logger;
+import com.x.base.core.project.logger.LoggerFactory;
+import com.x.base.core.project.tools.Crypto;
+import com.x.base.core.project.tools.DefaultCharset;
+
+public class ActionList extends BaseAction {
+	private static Logger logger = LoggerFactory.getLogger(ActionList.class);
+	
+	ActionResult<Wo> execute(HttpServletRequest request, EffectivePerson effectivePerson) throws Exception {
+		ActionResult<Wo> result = new ActionResult<>();
+		File manifestFile = new File(Config.base(),"configSample/manifest.cfg");
+		Wo wo = new Wo();
+		if(manifestFile.exists()) {
+			if(manifestFile.isFile()) {
+				String json = FileUtils.readFileToString(manifestFile, DefaultCharset.charset);
+				
+				FileFilter fileFilter = new WildcardFileFilter("node_*.json");
+				File[] files = Config.dir_config().listFiles(fileFilter);
+				if (null != files && files.length > 0) {
+					String  strNode = "";
+					JsonParser parser = new JsonParser();
+					JsonObject jsonObj = parser.parse(json).getAsJsonObject();
+					jsonObj.remove("node_127.0.0.1.json");
+					
+					for (File o : files) {
+						String name = StringUtils.substringBetween(o.getName(), "node_", ".json");
+						jsonObj.addProperty(o.getName().toString(), name+ "应用节点配置" );
+					}
+					   wo.setConfig(jsonObj.toString());
+				} else {
+					   wo.setConfig(json);
+				}
+				
+				
+			}
+		}
+		
+		
+		SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+		wo.setTime(df.format(new Date()));
+		wo.setStatus("success");
+		result.setData(wo);
+		return result;
+	}
+	
+	synchronized private Wo executeCommand(String ctl , String nodeName ,int nodePort) throws Exception{
+		Wo wo = new Wo();
+		//wo.setNode(nodeName);
+		wo.setStatus("success");
+		try (Socket socket = new Socket(nodeName, nodePort)) {
+			socket.setKeepAlive(true);
+			socket.setSoTimeout(5000);
+			try (DataOutputStream dos = new DataOutputStream(socket.getOutputStream());
+				 DataInputStream dis = new DataInputStream(socket.getInputStream())){
+				Map<String, Object> commandObject = new HashMap<>();
+				commandObject.put("command", "command:"+ ctl);
+				commandObject.put("credential", Crypto.rsaEncrypt("o2@", Config.publicKey()));
+				dos.writeUTF(XGsonBuilder.toJson(commandObject));
+				dos.flush();
+				
+				if (ctl.indexOf("create encrypt")>-1) {
+					String createEncrypt = dis.readUTF();
+					logger.info(createEncrypt);
+				}
+			}
+		} catch (Exception ex) {
+			wo.setStatus("fail");
+			logger.warn("socket dispatch executeCommand to {}:{} error={}", nodeName, nodePort, ex.getMessage());
+		}
+		SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+		wo.setTime(df.format(new Date()));
+		return wo;
+	}
+   
+	public static class Wi  extends GsonPropertyObject{
+		
+	}
+	
+	public static class Wo extends GsonPropertyObject {
+		
+		@FieldDescribe("执行时间")
+		private String time;
+		
+		@FieldDescribe("执行结果")
+		private String status;
+		
+		@FieldDescribe("config文件列表")
+		private String config;
+
+		public String getTime() {
+			return time;
+		}
+		
+		public void setTime(String time) {
+			this.time = time;
+		}
+		
+		public String getStatus() {
+			return status;
+		}
+
+		public void setStatus(String status) {
+			this.status = status;
+		}
+		
+		public String getConfig() {
+			return config;
+		}
+
+		public void setConfig(String config) {
+			this.config = config;
+		}
+	}
+	
+	
+
+}

+ 149 - 0
o2server/x_program_center/src/main/java/com/x/program/center/jaxrs/edit/ActionOpen.java

@@ -0,0 +1,149 @@
+package com.x.program.center.jaxrs.edit;
+
+import java.io.ByteArrayInputStream;
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.InputStream;
+import java.net.Socket;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.apache.commons.io.FileUtils;
+
+import com.google.gson.Gson;
+import com.google.gson.JsonElement;
+import com.x.base.core.project.annotation.FieldDescribe;
+import com.x.base.core.project.config.Config;
+import com.x.base.core.project.config.Nodes;
+import com.x.base.core.project.gson.GsonPropertyObject;
+import com.x.base.core.project.gson.XGsonBuilder;
+import com.x.base.core.project.http.ActionResult;
+import com.x.base.core.project.http.EffectivePerson;
+import com.x.base.core.project.logger.Logger;
+import com.x.base.core.project.logger.LoggerFactory;
+import com.x.base.core.project.tools.Crypto;
+import com.x.base.core.project.tools.DefaultCharset;
+import com.x.program.center.jaxrs.command.ActionCommand.Wi;
+import com.x.program.center.jaxrs.command.ActionCommand.Wo;
+
+public class ActionOpen extends BaseAction {
+	private static Logger logger = LoggerFactory.getLogger(ActionOpen.class);
+	
+	ActionResult<Wo> execute(HttpServletRequest request, EffectivePerson effectivePerson,JsonElement jsonElement) throws Exception {
+		ActionResult<Wo> result = new ActionResult<>();
+		Wi wi = this.convertToWrapIn(jsonElement, Wi.class);
+		Wo wo = new Wo();
+		String fileName = wi.getFileName();
+	
+		File file = new File(Config.base(),"config/"+fileName);
+		wo.setSample(false);
+		 
+		if(!file.exists()) {
+		   file = new File(Config.base(),"configSample/"+fileName);
+		   wo.setSample(true);
+		}
+		
+		if(file.exists()) {
+			if(file.isFile()) {
+				String json = FileUtils.readFileToString(file, DefaultCharset.charset);
+				wo.setFileContent(json);
+			}
+		}
+		
+		SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+		wo.setTime(df.format(new Date()));
+		wo.setStatus("success");
+		result.setData(wo);
+		return result;
+	}
+	
+	public static class Wi  extends GsonPropertyObject{
+		/*
+		@FieldDescribe("服务器地址(*代表多台应用服务器)")
+		private String nodeName;
+		
+		@FieldDescribe("服务端口")
+		private String nodePort;
+		*/
+		@FieldDescribe("文件名")
+		private String fileName;
+		
+        /*
+		public String getNodeName() {
+			return nodeName;
+		}
+		public void setNodeName(String nodeName) {
+			this.nodeName = nodeName;
+		}
+		public String getNodePort() {
+			return nodePort;
+		}
+		public void setNodePort(String nodePort) {
+			this.nodePort = nodePort;
+		}*/
+		public String getFileName() {
+			return fileName;
+		}
+		public void setFileName(String fileName) {
+			this.fileName = fileName;
+		}
+	
+	}
+	
+	public static class Wo extends GsonPropertyObject {
+		
+		@FieldDescribe("执行时间")
+		private String time;
+		
+		@FieldDescribe("执行结果")
+		private String status;
+		
+		@FieldDescribe("config文件内容")
+		private String fileContent;
+		
+		@FieldDescribe("是否Sample")
+		private boolean isSample;
+		
+		public String getTime() {
+			return time;
+		}
+		
+		public void setTime(String time) {
+			this.time = time;
+		}
+		
+		public String getStatus() {
+			return status;
+		}
+
+		public void setStatus(String status) {
+			this.status = status;
+		}
+
+		public String getFileContent() {
+			return fileContent;
+		}
+
+		public void setFileContent(String fileContent) {
+			this.fileContent = fileContent;
+		}
+
+		public boolean isSample() {
+			return isSample;
+		}
+
+		public void setSample(boolean isSample) {
+			this.isSample = isSample;
+		}
+		
+	}
+	
+}

+ 225 - 0
o2server/x_program_center/src/main/java/com/x/program/center/jaxrs/edit/ActionSave.java

@@ -0,0 +1,225 @@
+package com.x.program.center.jaxrs.edit;
+
+import java.io.ByteArrayInputStream;
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.InputStream;
+import java.net.Socket;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.apache.commons.io.FileUtils;
+import org.glassfish.jersey.media.multipart.FormDataContentDisposition;
+
+import com.google.gson.Gson;
+import com.google.gson.JsonElement;
+import com.x.base.core.project.annotation.FieldDescribe;
+import com.x.base.core.project.config.Config;
+import com.x.base.core.project.config.Nodes;
+import com.x.base.core.project.gson.GsonPropertyObject;
+import com.x.base.core.project.gson.XGsonBuilder;
+import com.x.base.core.project.http.ActionResult;
+import com.x.base.core.project.http.EffectivePerson;
+import com.x.base.core.project.logger.Logger;
+import com.x.base.core.project.logger.LoggerFactory;
+import com.x.base.core.project.tools.Crypto;
+import com.x.base.core.project.tools.DefaultCharset;
+import com.x.program.center.jaxrs.command.ActionCommand.Wi;
+import com.x.program.center.jaxrs.command.ActionCommand.Wo;
+
+public class ActionSave extends BaseAction {
+	private static Logger logger = LoggerFactory.getLogger(ActionSave.class);
+	ActionResult<Wo> execute(HttpServletRequest request, EffectivePerson effectivePerson,JsonElement jsonElement) throws Exception {
+		ActionResult<Wo> result = new ActionResult<>();
+		Wi wi = this.convertToWrapIn(jsonElement, Wi.class);
+		Wo wo = new Wo();
+		String curServer = request.getLocalAddr();
+		
+		String fileName = wi.getFileName();
+		String data = wi.getFileContent();
+		
+		File file = new File(Config.base(),"config/"+fileName);
+		if(!file.exists()) {
+			file.createNewFile();
+		}
+		
+		if(file.exists()) {
+			if(file.isFile()) {
+			    FileUtils.writeStringToFile(file, data, DefaultCharset.charset);
+			}
+		}
+		
+		Nodes nodes = Config.nodes();
+		//同步config文件
+		for (String node : nodes.keySet()){
+			//其他服务器
+			if(!node.equalsIgnoreCase(curServer)) {
+				if(nodes.get(node).getApplication().getEnable() || nodes.get(node).getCenter().getEnable()){
+					boolean Syncflag = executeSyncFile("config/"+fileName , node ,nodes.get(node).nodeAgentPort());
+				}
+			}
+		}
+		
+		SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+		wo.setTime(df.format(new Date()));
+		wo.setStatus("success");
+		result.setData(wo);
+		
+		return result;
+	}
+	
+
+
+	
+	private boolean executeSyncFile(String syncFilePath , String nodeName ,int nodePort){
+		  boolean syncFileFlag = false;
+		  File syncFile;
+		  InputStream fileInputStream = null;
+		 
+		try (Socket socket = new Socket(nodeName, nodePort)) {
+			
+			syncFile = new File(Config.base(), syncFilePath);
+			fileInputStream= new FileInputStream(syncFile);
+			 
+			socket.setKeepAlive(true);
+			socket.setSoTimeout(5000);
+			DataOutputStream dos = null;
+			DataInputStream dis  = null;
+			try {
+				dos = new DataOutputStream(socket.getOutputStream());
+			    dis = new DataInputStream(socket.getInputStream());
+			    
+				Map<String, Object> commandObject = new HashMap<>();
+				commandObject.put("command", "syncFile:"+ syncFilePath);
+				commandObject.put("credential", Crypto.rsaEncrypt("o2@", Config.publicKey()));
+				dos.writeUTF(XGsonBuilder.toJson(commandObject));
+				dos.flush();
+				
+				dos.writeUTF(syncFilePath);
+				dos.flush();
+				
+		
+				logger.info("同步文件starting.......");
+				byte[] bytes = new byte[1024];
+				int length =0;
+				while((length = fileInputStream.read(bytes, 0, bytes.length)) != -1) {
+					dos.write(bytes, 0, length);
+					dos.flush();
+				}
+				logger.info("同步文件end.......");
+				
+			}finally {
+				dos.close();
+				dis.close();
+				socket.close();
+				fileInputStream.close();
+			}
+			
+			syncFileFlag = true;
+		} catch (Exception ex) {
+			logger.error(ex);
+			syncFileFlag = false;
+		}
+		return syncFileFlag;
+	}
+	
+	public static class Wi  extends GsonPropertyObject{
+		
+		@FieldDescribe("服务器地址(*代表多台应用服务器)")
+		private String nodeName;
+		
+		@FieldDescribe("服务端口")
+		private String nodePort;
+		
+		@FieldDescribe("文件名")
+		private String fileName;
+		
+		@FieldDescribe("config文件内容")
+		private String fileContent;
+
+		public String getNodeName() {
+			return nodeName;
+		}
+		public void setNodeName(String nodeName) {
+			this.nodeName = nodeName;
+		}
+		public String getNodePort() {
+			return nodePort;
+		}
+		public void setNodePort(String nodePort) {
+			this.nodePort = nodePort;
+		}
+		public String getFileName() {
+			return fileName;
+		}
+		public void setFileName(String fileName) {
+			this.fileName = fileName;
+		}
+		public String getFileContent() {
+			return fileContent;
+		}
+		public void setFileContent(String fileContent) {
+			this.fileContent = fileContent;
+		}
+		
+		
+	
+	}
+	
+	public static class Wo extends GsonPropertyObject {
+		
+		@FieldDescribe("执行时间")
+		private String time;
+		
+		@FieldDescribe("执行结果")
+		private String status;
+		
+		@FieldDescribe("config文件内容")
+		private String fileContent;
+		
+		@FieldDescribe("是否Sample")
+		private boolean isSample;
+		
+		public String getTime() {
+			return time;
+		}
+		
+		public void setTime(String time) {
+			this.time = time;
+		}
+		
+		public String getStatus() {
+			return status;
+		}
+
+		public void setStatus(String status) {
+			this.status = status;
+		}
+
+		public String getFileContent() {
+			return fileContent;
+		}
+
+		public void setFileContent(String fileContent) {
+			this.fileContent = fileContent;
+		}
+
+		public boolean isSample() {
+			return isSample;
+		}
+
+		public void setSample(boolean isSample) {
+			this.isSample = isSample;
+		}
+		
+	}
+	
+}

+ 42 - 0
o2server/x_program_center/src/main/java/com/x/program/center/jaxrs/edit/BaseAction.java

@@ -0,0 +1,42 @@
+package com.x.program.center.jaxrs.edit;
+
+import com.x.base.core.project.cache.ApplicationCache;
+import com.x.base.core.project.gson.GsonPropertyObject;
+import com.x.base.core.project.jaxrs.StandardJaxrsAction;
+import net.sf.ehcache.Ehcache;
+
+abstract class BaseAction extends StandardJaxrsAction {
+    public static Ehcache cacheLog = ApplicationCache.instance().getCache(CacheLogObject.class);
+
+    public static class CacheLogObject extends GsonPropertyObject {
+        private String userToken;
+
+        private String node;
+
+        private long lastPoint;
+        public long getLastPoint() {
+            return lastPoint;
+        }
+
+        public void setLastPoint(long lastPoint) {
+            this.lastPoint = lastPoint;
+        }
+
+        public String getNode() {
+            return node;
+        }
+
+        public void setNode(String node) {
+            this.node = node;
+        }
+
+        public String getUserToken() {
+            return userToken;
+        }
+
+        public void setUserToken(String userToken) {
+            this.userToken = userToken;
+        }
+    }
+
+}

+ 80 - 0
o2server/x_program_center/src/main/java/com/x/program/center/jaxrs/edit/EditConfigAction.java

@@ -0,0 +1,80 @@
+package com.x.program.center.jaxrs.edit;
+import javax.servlet.http.HttpServletRequest;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.container.AsyncResponse;
+import javax.ws.rs.container.Suspended;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.MediaType;
+
+import com.google.gson.JsonElement;
+import com.x.base.core.project.annotation.JaxrsDescribe;
+import com.x.base.core.project.annotation.JaxrsMethodDescribe;
+import com.x.base.core.project.http.ActionResult;
+import com.x.base.core.project.http.EffectivePerson;
+import com.x.base.core.project.http.HttpMediaType;
+import com.x.base.core.project.jaxrs.ResponseFactory;
+import com.x.base.core.project.jaxrs.StandardJaxrsAction;
+import com.x.base.core.project.logger.Logger;
+import com.x.base.core.project.logger.LoggerFactory;
+
+@Path("editconfig")
+@JaxrsDescribe("编辑配置文件")
+public class EditConfigAction<Wo> extends StandardJaxrsAction{
+	private static Logger logger = LoggerFactory.getLogger(EditConfigAction.class);
+	
+	@JaxrsMethodDescribe(value = "获取所有配置文件信息", action = ActionList.class)
+	@GET
+	@Path("list")
+	@Produces(HttpMediaType.APPLICATION_JSON_UTF_8)
+	@Consumes(MediaType.APPLICATION_JSON)
+	public void getList(@Suspended final AsyncResponse asyncResponse, @Context HttpServletRequest request) {
+		EffectivePerson effectivePerson = this.effectivePerson(request);
+		ActionResult<ActionList.Wo> result = new ActionResult<>();
+		try {
+			result = (ActionResult<ActionList.Wo>) new ActionList().execute(request,effectivePerson);
+		} catch (Exception e) {
+			e.printStackTrace();
+			result.error(e);
+		}
+		asyncResponse.resume(ResponseFactory.getEntityTagActionResultResponse(request, result));
+	}
+	
+	@JaxrsMethodDescribe(value = "打开config文件", action = ActionOpen.class)
+	@POST
+	@Path("open")
+	@Produces(HttpMediaType.APPLICATION_JSON_UTF_8)
+	@Consumes(MediaType.APPLICATION_JSON)
+	public void open(@Suspended final AsyncResponse asyncResponse, @Context HttpServletRequest request, JsonElement jsonElement) {		
+		EffectivePerson effectivePerson = this.effectivePerson(request);
+		ActionResult<ActionOpen.Wo> result = new ActionResult<>();
+		try {
+			result = new ActionOpen().execute(request,effectivePerson, jsonElement);
+		} catch (Exception e) {
+			e.printStackTrace();
+			result.error(e);
+		}
+		asyncResponse.resume(ResponseFactory.getEntityTagActionResultResponse(request, result));
+	}
+	
+	@JaxrsMethodDescribe(value = "保存config文件", action = ActionSave.class)
+	@POST
+	@Path("save")
+	@Consumes(MediaType.APPLICATION_JSON)
+	@Produces(HttpMediaType.APPLICATION_JSON_UTF_8)	
+	public void save(@Suspended final AsyncResponse asyncResponse, @Context HttpServletRequest request, JsonElement jsonElement) {
+		ActionResult<ActionSave.Wo> result = new ActionResult<>();
+		EffectivePerson effectivePerson = this.effectivePerson(request);
+		try {
+			result = new ActionSave().execute(request , effectivePerson, jsonElement);
+		} catch (Exception e) {
+			logger.error(e, effectivePerson, request, null);
+			result.error(e);
+		}
+		asyncResponse.resume(ResponseFactory.getEntityTagActionResultResponse(request, result));
+	}
+
+}