提交 1705a242 编写于 作者: O o2sword

新版应用市场开发2

上级 842947d7
package com.x.base.core.project.tools;
import java.io.File;
import java.nio.ByteBuffer;
import java.nio.charset.Charset;
import java.util.List;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;
import net.lingala.zip4j.ZipFile;
import net.lingala.zip4j.model.ExtraDataRecord;
import net.lingala.zip4j.model.FileHeader;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;
import java.io.*;
import java.nio.ByteBuffer;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
/**
* zip工具类
* @author sword
*/
public class ZipTools {
private static final int BUFFER_SIZE = 2 * 1024;
public static void unZip(File source, List<String> subs, File dist, boolean asNew, Charset charset) {
try{
ZipFile zipFile = new ZipFile(source);
......@@ -27,7 +35,6 @@ public class ZipTools {
return;
}
String name = fileHeader.getFileName();
//System.out.println(name);
if (name.length() < 2) {
continue;
}
......@@ -74,4 +81,109 @@ public class ZipTools {
}
return false;
}
/**
* 压缩成ZIP 方法1
* @param sourceFile 待压缩文件夹
* @param out 压缩包输出流
* @param fileList 压缩的文件列表,可以为null
* @return boolean
*/
public static boolean toZip(File sourceFile, OutputStream out, List<String> fileList) {
try (ZipOutputStream zos = new ZipOutputStream(out)){
compress(sourceFile, zos, "", fileList);
return true;
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
/**
* 压缩成ZIP 方法2
* @param srcFiles 需要压缩的文件列表
* @param out 压缩文件输出流
* @throws RuntimeException 压缩失败会抛出运行时异常
*/
public static void toZip(List<File> srcFiles , OutputStream out)throws RuntimeException {
ZipOutputStream zos = null ;
try {
zos = new ZipOutputStream(out);
for (File srcFile : srcFiles) {
byte[] buf = new byte[BUFFER_SIZE];
zos.putNextEntry(new ZipEntry(srcFile.getName()));
int len;
FileInputStream in = new FileInputStream(srcFile);
while ((len = in.read(buf)) != -1){
zos.write(buf, 0, len);
}
zos.closeEntry();
in.close();
}
} catch (Exception e) {
throw new RuntimeException("zip error from ZipUtils",e);
}finally{
if(zos != null){
try {
zos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
/**
* 递归压缩方法
* @param sourceFile 源文件
* @param zos zip输出流
* @param name 压缩后的名称
* @throws Exception
*/
private static void compress(File sourceFile, ZipOutputStream zos, String name, List<String> fileList) throws Exception{
byte[] buf = new byte[BUFFER_SIZE];
if(sourceFile.isFile()){
// 向zip输出流中添加一个zip实体,构造器中name为zip实体的文件的名字
if(StringUtils.isBlank(name)) {
name = sourceFile.getName();
}
if(sourceFile != null){
if(name.startsWith(File.separator)) {
fileList.add(name.substring(1));
}else{
fileList.add(name);
}
}
zos.putNextEntry(new ZipEntry(name));
// copy文件到zip输出流中
int len;
FileInputStream in = new FileInputStream(sourceFile);
while ((len = in.read(buf)) != -1){
zos.write(buf, 0, len);
}
zos.closeEntry();
in.close();
} else {
File[] listFiles = sourceFile.listFiles();
if(listFiles == null || listFiles.length == 0){
if(StringUtils.isNotBlank(name)) {
zos.putNextEntry(new ZipEntry(name + File.separator ));
zos.closeEntry();
}
}else {
for (File file : listFiles) {
compress(file, zos, name + File.separator + file.getName(), fileList);
}
}
}
}
public static void main(String[] args) throws Exception{
File zipFile = new File("/Users/chengjian/dev/tmp/test.zip");
List<String> list = new ArrayList<>();
ZipTools.toZip(new File("/Users/chengjian/dev/tmp/test"), new FileOutputStream(zipFile), list);
System.out.println(1);
}
}
package com.x.program.center.jaxrs.market;
import com.x.base.core.container.EntityManagerContainer;
import com.x.base.core.container.factory.EntityManagerContainerFactory;
import com.x.base.core.entity.enums.CommonStatus;
import com.x.base.core.project.annotation.FieldDescribe;
import com.x.base.core.project.gson.GsonPropertyObject;
import com.x.base.core.project.http.ActionResult;
import com.x.base.core.project.http.EffectivePerson;
import com.x.base.core.project.jaxrs.WrapBoolean;
import com.x.base.core.project.logger.Logger;
import com.x.base.core.project.logger.LoggerFactory;
import com.x.program.center.core.entity.InstallLog;
import org.apache.commons.lang3.StringUtils;
import org.glassfish.jersey.media.multipart.FormDataContentDisposition;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
class ActionInstallOffline extends BaseAction {
private static Logger logger = LoggerFactory.getLogger(ActionInstallOffline.class);
ActionResult<Wo> execute(EffectivePerson effectivePerson, byte[] bytes, String fileName, FormDataContentDisposition disposition) throws Exception {
try (EntityManagerContainer emc = EntityManagerContainerFactory.instance().create()) {
ActionResult<Wo> result = new ActionResult<>();
if (StringUtils.isEmpty(fileName)) {
fileName = this.fileName(disposition);
}
Application2 app = null;
logger.info("{}发起安装或更新应用:{}", effectivePerson.getDistinguishedName(), fileName);
Wo wo = new Wo();
wo.setValue(false);
if ((null != bytes) && (bytes.length > 0)) {
InstallData installData = this.install(app, bytes);
wo.setValue(true);
emc.beginTransaction(InstallLog.class);
InstallLog installLog = emc.find(app.getId(), InstallLog.class);
boolean exist = true;
if (installLog == null) {
installLog = new InstallLog();
installLog.setId(app.getId());
exist = false;
}
installLog.setName(app.getName());
installLog.setVersion(app.getVersion());
installLog.setCategory(app.getCategory());
installLog.setStatus(CommonStatus.VALID.getValue());
installLog.setData(gson.toJson(installData));
installLog.setInstallPerson(effectivePerson.getDistinguishedName());
installLog.setInstallTime(new Date());
installLog.setUnInstallPerson(null);
installLog.setUnInstallTime(null);
if (!exist) {
emc.persist(installLog);
}
emc.commit();
}
result.setData(wo);
return result;
}
}
public static class Wo extends WrapBoolean {
}
public static class InstallWo extends GsonPropertyObject {
@FieldDescribe("流程应用")
private List<String> processPlatformList = new ArrayList<>();
@FieldDescribe("门户应用")
private List<String> portalList = new ArrayList<>();
@FieldDescribe("统计应用")
private List<String> queryList = new ArrayList<>();
@FieldDescribe("内容管理应用")
private List<String> cmsList = new ArrayList<>();
@FieldDescribe("服务管理应用")
private List<String> serviceModuleList = new ArrayList<>();
public List<String> getProcessPlatformList() {
return processPlatformList;
}
public void setProcessPlatformList(List<String> processPlatformList) {
this.processPlatformList = processPlatformList;
}
public List<String> getPortalList() {
return portalList;
}
public void setPortalList(List<String> portalList) {
this.portalList = portalList;
}
public List<String> getQueryList() {
return queryList;
}
public void setQueryList(List<String> queryList) {
this.queryList = queryList;
}
public List<String> getCmsList() {
return cmsList;
}
public void setCmsList(List<String> cmsList) {
this.cmsList = cmsList;
}
public List<String> getServiceModuleList() {
return serviceModuleList;
}
public void setServiceModuleList(List<String> serviceModuleList) {
this.serviceModuleList = serviceModuleList;
}
}
}
package com.x.program.center.jaxrs.market;
import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.x.base.core.project.connection.ActionResponse;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.StringUtils;
import com.google.gson.Gson;
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.entity.enums.CommonStatus;
import com.x.base.core.project.Applications;
import com.x.base.core.project.x_cms_assemble_control;
import com.x.base.core.project.x_portal_assemble_designer;
import com.x.base.core.project.x_processplatform_assemble_designer;
import com.x.base.core.project.x_query_assemble_designer;
import com.x.base.core.project.annotation.FieldDescribe;
import com.x.base.core.project.bean.NameValuePair;
import com.x.base.core.project.config.Collect;
import com.x.base.core.project.config.Config;
import com.x.base.core.project.config.Nodes;
import com.x.base.core.project.connection.CipherConnectionAction;
import com.x.base.core.project.connection.ActionResponse;
import com.x.base.core.project.connection.ConnectionAction;
import com.x.base.core.project.exception.ExceptionAccessDenied;
import com.x.base.core.project.exception.ExceptionEntityNotExist;
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.jaxrs.WoId;
import com.x.base.core.project.jaxrs.WrapBoolean;
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.base.core.project.tools.FileTools;
import com.x.base.core.project.tools.JarTools;
import com.x.base.core.project.tools.ListTools;
import com.x.cms.core.entity.element.wrap.WrapCms;
import com.x.portal.core.entity.wrap.WrapPortal;
import com.x.processplatform.core.entity.element.wrap.WrapProcessPlatform;
import com.x.program.center.Business;
import com.x.program.center.ThisApplication;
import com.x.program.center.WrapModule;
import com.x.program.center.core.entity.Application;
import com.x.program.center.core.entity.InstallLog;
import com.x.program.center.core.entity.wrap.WrapAgent;
import com.x.program.center.core.entity.wrap.WrapInvoke;
import com.x.program.center.core.entity.wrap.WrapServiceModule;
import com.x.query.core.entity.wrap.WrapQuery;
import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.StringUtils;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
class ActionInstallOrUpdate extends BaseAction {
......@@ -73,48 +39,49 @@ class ActionInstallOrUpdate extends BaseAction {
if (StringUtils.isNotEmpty(token)) {
try {
ActionResponse response = ConnectionAction.get(
Config.collect().url(COLLECT_MARKET_INFO + id),
Config.collect().url(COLLECT_MARKET_INSTALL_INFO + id),
ListTools.toList(new NameValuePair(Collect.COLLECT_TOKEN, token)));
app = response.getData(Application2.class);
} catch (Exception e) {
logger.warn("get market info form o2cloud error: {}.", e.getMessage());
}
}
if(app != null){
if(app == null){
throw new ExceptionEntityNotExist(id);
}
logger.print("{}发起安装或更新应用:{}", effectivePerson.getDistinguishedName(), app.getName());
if(!BooleanUtils.isTrue(app.getHasInstallPermission())){
throw new ExceptionAccessDenied(Config.collect().getName());
}
logger.info("{}发起安装或更新应用:{}", effectivePerson.getDistinguishedName(), app.getName());
Wo wo = new Wo();
wo.setValue(false);
if (StringUtils.isNotEmpty(token)) {
byte[] bytes = ConnectionAction.getBinary(
Config.collect().url(Collect.ADDRESS_COLLECT_APPLICATION_DOWN + "/" + id),
ListTools.toList(new NameValuePair(Collect.COLLECT_TOKEN, token)));
if ((null != bytes) && (bytes.length > 0)) {
InstallData installData = this.install(id, bytes);
wo.setValue(true);
emc.beginTransaction(InstallLog.class);
InstallLog installLog = emc.find(id, InstallLog.class);
boolean exist = true;
if (installLog == null) {
installLog = new InstallLog();
installLog.setId(app.getId());
exist = false;
}
installLog.setName(app.getName());
installLog.setVersion(app.getVersion());
installLog.setCategory(app.getCategory());
installLog.setStatus(CommonStatus.VALID.getValue());
installLog.setData(gson.toJson(installData));
installLog.setInstallPerson(effectivePerson.getDistinguishedName());
installLog.setInstallTime(new Date());
installLog.setUnInstallPerson(null);
installLog.setUnInstallTime(null);
if (!exist) {
emc.persist(installLog);
}
emc.commit();
byte[] bytes = ConnectionAction.getBinary(
Config.collect().url(Collect.ADDRESS_COLLECT_APPLICATION_DOWN + "/" + id),
ListTools.toList(new NameValuePair(Collect.COLLECT_TOKEN, token)));
if ((null != bytes) && (bytes.length > 0)) {
InstallData installData = this.install(app, bytes);
wo.setValue(true);
emc.beginTransaction(InstallLog.class);
InstallLog installLog = emc.find(id, InstallLog.class);
boolean exist = true;
if (installLog == null) {
installLog = new InstallLog();
installLog.setId(app.getId());
exist = false;
}
installLog.setName(app.getName());
installLog.setVersion(app.getVersion());
installLog.setCategory(app.getCategory());
installLog.setStatus(CommonStatus.VALID.getValue());
installLog.setData(gson.toJson(installData));
installLog.setInstallPerson(effectivePerson.getDistinguishedName());
installLog.setInstallTime(new Date());
installLog.setUnInstallPerson(null);
installLog.setUnInstallTime(null);
if (!exist) {
emc.persist(installLog);
}
emc.commit();
}
result.setData(wo);
......@@ -122,164 +89,6 @@ class ActionInstallOrUpdate extends BaseAction {
}
}
private InstallData install(String id, byte[] bytes) throws Exception {
InstallData installData = new InstallData();
File tempFile = new File(Config.base(), "local/temp/install");
FileTools.forceMkdir(tempFile);
FileUtils.cleanDirectory(tempFile);
File zipFile = new File(tempFile.getAbsolutePath(), id + ".zip");
FileUtils.writeByteArrayToFile(zipFile, bytes);
File dist = new File(tempFile.getAbsolutePath(), "data");
FileTools.forceMkdir(dist);
JarTools.unjar(zipFile, new ArrayList<>(), dist, true);
// 过滤必要的文件
// File[] files = dist.listFiles(new FileFilter() {
// public boolean accept(File pathname) {
// return true;
// }
// });
File[] files = dist.listFiles(path -> true);
if (null != files) {
for (File file : files) {
if (!file.isDirectory()) {
if (file.getName().toLowerCase().endsWith(".xapp")) {
String json = FileUtils.readFileToString(file, DefaultCharset.charset);
Gson gson = new Gson();
JsonElement jsonElement = gson.fromJson(json, JsonElement.class);
WrapModule module = this.convertToWrapIn(jsonElement, WrapModule.class);
this.installModule(module);
installData.setWrapModule(module);
} else if (file.getName().toLowerCase().endsWith(".app.zip")) {
logger.print("开始安装自定义应用:{}", file.getName());
this.installCustomApp(file.getName(), FileUtils.readFileToByteArray(file));
installData.setCustomApp(file.getName());
logger.print("完成自定义应用安装:{}", file.getName());
} else if (file.getName().toLowerCase().endsWith(".zip")) {
logger.print("开始安装静态资源");
try {
Business.dispatch(false, file.getName(), "", FileUtils.readFileToByteArray(file));
installData.setStaticResource(file.getName());
} catch (Exception e) {
logger.print("模块安装成功但静态资源安装失败:{}", e.getMessage());
}
}
}
}
}
FileUtils.cleanDirectory(tempFile);
return installData;
}
private InstallWo installModule(WrapModule module) throws Exception {
InstallWo wo = new InstallWo();
logger.print("开始安装应用");
if (module.getProcessPlatformList() != null) {
for (WrapProcessPlatform obj : module.getProcessPlatformList()) {
wo.getProcessPlatformList().add(
ThisApplication.context().applications().putQuery(x_processplatform_assemble_designer.class,
Applications.joinQueryUri("input", "cover"), obj).getData(WoId.class).getId());
obj.setIcon(null);
obj.setApplicationDictList(null);
obj.setFileList(null);
obj.setFormList(null);
obj.setProcessList(null);
obj.setScriptList(null);
}
}
if (module.getCmsList() != null) {
for (WrapCms obj : module.getCmsList()) {
wo.getCmsList().add(ThisApplication.context().applications()
.putQuery(x_cms_assemble_control.class, Applications.joinQueryUri("input", "cover"), obj)
.getData(WoId.class).getId());
obj.setAppIcon(null);
obj.setAppDictList(null);
obj.setCategoryInfoList(null);
obj.setFileList(null);
obj.setFormList(null);
obj.setScriptList(null);
}
}
if (module.getPortalList() != null) {
for (WrapPortal obj : module.getPortalList()) {
wo.getPortalList().add(ThisApplication.context().applications()
.putQuery(x_portal_assemble_designer.class, Applications.joinQueryUri("input", "cover"), obj)
.getData(WoId.class).getId());
obj.setIcon(null);
obj.setFileList(null);
obj.setPageList(null);
obj.setScriptList(null);
obj.setWidgetList(null);
}
}
if (module.getQueryList() != null) {
for (WrapQuery obj : module.getQueryList()) {
wo.getQueryList().add(ThisApplication.context().applications()
.putQuery(x_query_assemble_designer.class, Applications.joinQueryUri("input", "cover"), obj)
.getData(WoId.class).getId());
obj.setIcon(null);
obj.setRevealList(null);
obj.setViewList(null);
obj.setStatementList(null);
obj.setViewList(null);
obj.setTableList(null);
}
}
if (module.getServiceModuleList() != null) {
for (WrapServiceModule obj : module.getServiceModuleList()) {
wo.getServiceModuleList()
.add(CipherConnectionAction.put(false, Config.url_x_program_center_jaxrs("input", "cover"), obj)
.getData(WoId.class).getId());
if (obj.getAgentList() != null) {
for (WrapAgent agent : obj.getAgentList()) {
agent.setText(null);
}
}
if (obj.getInvokeList() != null) {
for (WrapInvoke invoke : obj.getInvokeList()) {
invoke.setText(null);
}
}
}
}
return wo;
}
private void installCustomApp(String fileName, byte[] bytes) throws Exception {
Nodes nodes = Config.nodes();
for (String node : nodes.keySet()) {
if (nodes.get(node).getApplication().getEnable()) {
logger.print("socket deploy custom app{} to {}:{}", fileName, node, nodes.get(node).nodeAgentPort());
try (Socket socket = new Socket(node, nodes.get(node).nodeAgentPort())) {
socket.setKeepAlive(true);
socket.setSoTimeout(10000);
try (DataOutputStream dos = new DataOutputStream(socket.getOutputStream());
DataInputStream dis = new DataInputStream(socket.getInputStream())) {
Map<String, Object> commandObject = new HashMap<>();
commandObject.put("command", "redeploy:customZip");
commandObject.put("credential", Crypto.rsaEncrypt("o2@", Config.publicKey()));
dos.writeUTF(XGsonBuilder.toJson(commandObject));
dos.flush();
dos.writeUTF(fileName);
dos.flush();
try (ByteArrayInputStream bis = new ByteArrayInputStream(bytes)) {
byte[] onceBytes = new byte[1024];
int length = 0;
while ((length = bis.read(onceBytes, 0, onceBytes.length)) != -1) {
dos.write(onceBytes, 0, length);
dos.flush();
}
}
}
}
}
}
}
public static class Wo extends WrapBoolean {
}
......
......@@ -5,8 +5,10 @@ import java.io.DataOutputStream;
import java.net.Socket;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.x.base.core.project.tools.ListTools;
import org.apache.commons.lang3.StringUtils;
import com.x.base.core.container.EntityManagerContainer;
......@@ -62,13 +64,13 @@ class ActionUninstall extends BaseAction {
logger.print("{}发起卸载应用:{}", effectivePerson.getDistinguishedName(), app.getName());
Wo wo = new Wo();
InstallData installData = gson.fromJson(installLog.getData(), InstallData.class);
WrapModule module = installData.getWrapModule();
if(module!=null) {
this.uninstall(module);
}
if(StringUtils.isNotEmpty(installData.getCustomApp())){
this.uninstallCustomApp(installData.getCustomApp());
List<WrapModule> moduleList = installData.getWrapModuleList();
if(ListTools.isNotEmpty(moduleList)) {
for(WrapModule module : moduleList){
this.uninstall(module);
}
}
emc.beginTransaction(InstallLog.class);
installLog.setStatus(CommonStatus.INVALID.getValue());
installLog.setUnInstallPerson(effectivePerson.getDistinguishedName());
......@@ -175,4 +177,4 @@ class ActionUninstall extends BaseAction {
public static class Wo extends WrapBoolean {
}
}
\ No newline at end of file
}
package com.x.program.center.jaxrs.market;
import com.google.gson.Gson;
import com.google.gson.JsonElement;
import com.x.base.core.project.*;
import com.x.base.core.project.annotation.FieldDescribe;
import com.x.base.core.project.bean.NameValuePair;
import com.x.base.core.project.cache.Cache;
import com.x.base.core.project.config.Collect;
import com.x.base.core.project.config.Config;
import com.x.base.core.project.config.Nodes;
import com.x.base.core.project.connection.ActionResponse;
import com.x.base.core.project.connection.CipherConnectionAction;
import com.x.base.core.project.connection.ConnectionAction;
import com.x.base.core.project.gson.GsonPropertyObject;
import com.x.base.core.project.gson.XGsonBuilder;
import com.x.base.core.project.http.EffectivePerson;
import com.x.base.core.project.jaxrs.StandardJaxrsAction;
import com.x.base.core.project.jaxrs.WoId;
import com.x.base.core.project.logger.Logger;
import com.x.base.core.project.logger.LoggerFactory;
import com.x.base.core.project.tools.*;
import com.x.cms.core.entity.element.wrap.WrapCms;
import com.x.portal.core.entity.wrap.WrapPortal;
import com.x.processplatform.core.entity.element.wrap.WrapProcessPlatform;
import com.x.program.center.Business;
import com.x.program.center.ThisApplication;
import com.x.program.center.WrapModule;
import java.util.Date;
import com.x.program.center.core.entity.InstallTypeEnum;
import com.x.program.center.core.entity.wrap.WrapAgent;
import com.x.program.center.core.entity.wrap.WrapInvoke;
import com.x.program.center.core.entity.wrap.WrapServiceModule;
import com.x.query.core.entity.wrap.WrapQuery;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;
import java.io.*;
import java.net.Socket;
import java.util.*;
abstract class BaseAction extends StandardJaxrsAction {
protected static String COLLECT_MARKET_CATEGORY = "/o2_collect_assemble/jaxrs/application2/list/category";
protected static String COLLECT_MARKET_LIST_INFO = "/o2_collect_assemble/jaxrs/application2/list/paging/{page}/size/{size}";
protected static String COLLECT_MARKET_INFO = "/o2_collect_assemble/jaxrs/application2/";
protected static String COLLECT_UNIT_IS_VIP = "/o2_collect_assemble/jaxrs/unit/is/vip";
private static Logger logger = LoggerFactory.getLogger(BaseAction.class);
protected static final String COLLECT_MARKET_CATEGORY = "/o2_collect_assemble/jaxrs/application2/list/category";
protected static final String COLLECT_MARKET_LIST_INFO = "/o2_collect_assemble/jaxrs/application2/list/paging/{page}/size/{size}";
protected static final String COLLECT_MARKET_INFO = "/o2_collect_assemble/jaxrs/application2/";
protected static final String COLLECT_MARKET_INSTALL_INFO = "/o2_collect_assemble/jaxrs/application2/install/";
protected static final String COLLECT_UNIT_IS_VIP = "/o2_collect_assemble/jaxrs/unit/is/vip";
private static final String APP_SETUP_NAME = "setup.json";
protected Cache.CacheCategory cacheCategory = new Cache.CacheCategory(InstallData.class);
......@@ -28,35 +61,253 @@ abstract class BaseAction extends StandardJaxrsAction {
return false;
}
protected InstallData install(Application2 app, byte[] bytes) throws Exception {
InstallData installData = new InstallData();
String id = StringTools.uniqueToken();
File tempFile = new File(Config.base(), "local/temp/install/"+ id);
FileTools.forceMkdir(tempFile);
if(app != null){
id = app.getId();
}
File zipFile = new File(tempFile.getAbsolutePath(), id + ".zip");
FileUtils.writeByteArrayToFile(zipFile, bytes);
File dist = new File(tempFile.getAbsolutePath(), "data");
FileTools.forceMkdir(dist);
ZipTools.unZip(zipFile, new ArrayList<>(), dist, true, null);
if(app == null) {
File[] setupFile = dist.listFiles(pathname -> pathname.getName().equals(APP_SETUP_NAME));
if(setupFile == null || setupFile.length == 0){
throw new ExceptionErrorInstallPackage();
}
String json = FileUtils.readFileToString(setupFile[0], DefaultCharset.charset);
Application2 offlineApp = gson.fromJson(json, Application2.class);
if(StringUtils.isBlank(offlineApp.getId()) || StringUtils.isBlank(offlineApp.getName())){
throw new ExceptionErrorInstallPackage();
}
String token = Business.loginCollect();
if (StringUtils.isNotEmpty(token)) {
try {
ActionResponse response = ConnectionAction.get(
Config.collect().url(COLLECT_MARKET_INSTALL_INFO + offlineApp.getId()),
ListTools.toList(new NameValuePair(Collect.COLLECT_TOKEN, token)));
app = response.getData(Application2.class);
} catch (Exception e) {
logger.warn("get market info form o2cloud error: {}.", e.getMessage());
}
}
if(app == null){
app = offlineApp;
}
}
File[] files = dist.listFiles(pathname -> !pathname.getName().toLowerCase().endsWith(".ds_store"));
if(files == null || files.length == 0){
return installData;
}
for (File file : files) {
if (file.isDirectory()) {
if(file.getName().toLowerCase().equals(InstallTypeEnum.CUSTOM.getValue())){
File[] subFiles = file.listFiles(pathname -> !pathname.getName().toLowerCase().endsWith(".ds_store"));
if(subFiles!=null && subFiles.length > 0){
try (ByteArrayOutputStream out = new ByteArrayOutputStream()){
List<String> list = new ArrayList<>();
boolean flag = ZipTools.toZip(file, out, list);
if(flag){
logger.info("开始部署[{}]的customApp", app.getName());
this.installCustomApp(app.getId() + "-custom.zip", out.toByteArray());
logger.info("完成部署[{}]的customApp,安装内容:{}", app.getName(), gson.toJson(list));
installData.setCustomList(list);
}
}
}
}else if(file.getName().toLowerCase().equals(InstallTypeEnum.XAPP.getValue())){
File[] subFiles = file.listFiles(pathname -> pathname.isFile());
if(subFiles!=null && subFiles.length > 0){
List<WrapModule> moduleList = new ArrayList<>();
for(File subFile : subFiles){
if (subFile.getName().toLowerCase().endsWith(".xapp")) {
logger.info("开始部署[{}]", subFile.getName());
String json = FileUtils.readFileToString(subFile, DefaultCharset.charset);
Gson gson = new Gson();
JsonElement jsonElement = gson.fromJson(json, JsonElement.class);
WrapModule module = this.convertToWrapIn(jsonElement, WrapModule.class);
this.installModule(module);
moduleList.add(module);
logger.info("完成部署[{}]", subFile.getName());
}
}
installData.setWrapModuleList(moduleList);
}
}else if(file.getName().toLowerCase().equals(InstallTypeEnum.WEB.getValue())){
File[] subFiles = file.listFiles(pathname -> !pathname.getName().toLowerCase().endsWith(".ds_store"));
if(subFiles!=null && subFiles.length > 0){
try (ByteArrayOutputStream out = new ByteArrayOutputStream()){
List<String> list = new ArrayList<>();
boolean flag = ZipTools.toZip(file, out, list);
if(flag){
logger.info("开始部署[{}]的web资源", app.getName());
Business.dispatch(false, app.getId() + "-web.zip", "", out.toByteArray());
logger.info("完成部署[{}]的web资源", app.getName());
installData.setWebList(list);
}
}
}
}else if(file.getName().toLowerCase().equals(InstallTypeEnum.DATA.getValue())){
File[] subFiles = file.listFiles();
if(subFiles!=null && subFiles.length > 0){
//todo
}
}
}
}
try {
FileUtils.cleanDirectory(tempFile);
} catch (Exception e) {
if(logger.isDebugEnabled()) {
logger.debug(e.getMessage());
}
}
return installData;
}
protected ActionInstallOffline.InstallWo installModule(WrapModule module) throws Exception {
ActionInstallOffline.InstallWo wo = new ActionInstallOffline.InstallWo();
if (module.getProcessPlatformList() != null) {
for (WrapProcessPlatform obj : module.getProcessPlatformList()) {
wo.getProcessPlatformList().add(
ThisApplication.context().applications().putQuery(x_processplatform_assemble_designer.class,
Applications.joinQueryUri("input", "cover"), obj).getData(WoId.class).getId());
obj.setIcon(null);
obj.setApplicationDictList(null);
obj.setFileList(null);
obj.setFormList(null);
obj.setProcessList(null);
obj.setScriptList(null);
}
}
if (module.getCmsList() != null) {
for (WrapCms obj : module.getCmsList()) {
wo.getCmsList().add(ThisApplication.context().applications()
.putQuery(x_cms_assemble_control.class, Applications.joinQueryUri("input", "cover"), obj)
.getData(WoId.class).getId());
obj.setAppIcon(null);
obj.setAppDictList(null);
obj.setCategoryInfoList(null);
obj.setFileList(null);
obj.setFormList(null);
obj.setScriptList(null);
}
}
if (module.getPortalList() != null) {
for (WrapPortal obj : module.getPortalList()) {
wo.getPortalList().add(ThisApplication.context().applications()
.putQuery(x_portal_assemble_designer.class, Applications.joinQueryUri("input", "cover"), obj)
.getData(WoId.class).getId());
obj.setIcon(null);
obj.setFileList(null);
obj.setPageList(null);
obj.setScriptList(null);
obj.setWidgetList(null);
}
}
if (module.getQueryList() != null) {
for (WrapQuery obj : module.getQueryList()) {
wo.getQueryList().add(ThisApplication.context().applications()
.putQuery(x_query_assemble_designer.class, Applications.joinQueryUri("input", "cover"), obj)
.getData(WoId.class).getId());
obj.setIcon(null);
obj.setRevealList(null);
obj.setViewList(null);
obj.setStatementList(null);
obj.setViewList(null);
obj.setTableList(null);
}
}
if (module.getServiceModuleList() != null) {
for (WrapServiceModule obj : module.getServiceModuleList()) {
wo.getServiceModuleList()
.add(CipherConnectionAction.put(false, Config.url_x_program_center_jaxrs("input", "cover"), obj)
.getData(WoId.class).getId());
if (obj.getAgentList() != null) {
for (WrapAgent agent : obj.getAgentList()) {
agent.setText(null);
}
}
if (obj.getInvokeList() != null) {
for (WrapInvoke invoke : obj.getInvokeList()) {
invoke.setText(null);
}
}
}
}
return wo;
}
protected void installCustomApp(String fileName, byte[] bytes) throws Exception {
Nodes nodes = Config.nodes();
for (String node : nodes.keySet()) {
if (nodes.get(node).getApplication().getEnable()) {
logger.info("socket deploy custom app{} to {}:{}", fileName, node, nodes.get(node).nodeAgentPort());
try (Socket socket = new Socket(node, nodes.get(node).nodeAgentPort())) {
socket.setKeepAlive(true);
socket.setSoTimeout(10000);
try (DataOutputStream dos = new DataOutputStream(socket.getOutputStream());
DataInputStream dis = new DataInputStream(socket.getInputStream())) {
Map<String, Object> commandObject = new HashMap<>();
commandObject.put("command", "redeploy:customZip");
commandObject.put("credential", Crypto.rsaEncrypt("o2@", Config.publicKey()));
dos.writeUTF(XGsonBuilder.toJson(commandObject));
dos.flush();
dos.writeUTF(fileName);
dos.flush();
try (ByteArrayInputStream bis = new ByteArrayInputStream(bytes)) {
byte[] onceBytes = new byte[1024];
int length = 0;
while ((length = bis.read(onceBytes, 0, onceBytes.length)) != -1) {
dos.write(onceBytes, 0, length);
dos.flush();
}
}
}
}
}
}
}
public static class InstallData extends GsonPropertyObject {
private WrapModule WrapModule;
private List<WrapModule> wrapModuleList;
private String staticResource;
private List<String> webList;
private String customApp;
private List<String> customList;
public WrapModule getWrapModule() {
return WrapModule;
public List<WrapModule> getWrapModuleList() {
return wrapModuleList;
}
public void setWrapModule(WrapModule wrapModule) {
WrapModule = wrapModule;
public void setWrapModuleList(List<WrapModule> wrapModuleList) {
this.wrapModuleList = wrapModuleList;
}
public String getStaticResource() {
return staticResource;
public List<String> getWebList() {
return webList;
}
public void setStaticResource(String staticResource) {
this.staticResource = staticResource;
public void setWebList(List<String> webList) {
this.webList = webList;
}
public String getCustomApp() {
return customApp;
public List<String> getCustomList() {
return customList;
}
public void setCustomApp(String customApp) {
this.customApp = customApp;
public void setCustomList(List<String> customList) {
this.customList = customList;
}
}
......@@ -140,6 +391,11 @@ abstract class BaseAction extends StandardJaxrsAction {
@FieldDescribe("修改时间.")
private Date updateTime;
/**
* 是否有下载安装权限
*/
Boolean hasInstallPermission;
public String getId() {
return id;
}
......@@ -347,6 +603,14 @@ abstract class BaseAction extends StandardJaxrsAction {
public void setUpdateTime(Date updateTime) {
this.updateTime = updateTime;
}
public Boolean getHasInstallPermission() {
return hasInstallPermission;
}
public void setHasInstallPermission(Boolean hasInstallPermission) {
this.hasInstallPermission = hasInstallPermission;
}
}
}
package com.x.program.center.jaxrs.market;
import com.x.base.core.project.exception.PromptException;
class ExceptionErrorInstallPackage extends PromptException {
private static final long serialVersionUID = -9050250987376957535L;
ExceptionErrorInstallPackage() {
super("错误的安装包.");
}
}
package com.x.program.center.jaxrs.market;
import java.util.List;
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.PathParam;
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;
......@@ -25,6 +11,16 @@ 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;
import org.glassfish.jersey.media.multipart.FormDataContentDisposition;
import org.glassfish.jersey.media.multipart.FormDataParam;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.*;
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 java.util.List;
@Path("market")
@JaxrsDescribe("应用市场")
......@@ -212,4 +208,24 @@ public class MarketAction extends StandardJaxrsAction {
asyncResponse.resume(ResponseFactory.getEntityTagActionResultResponse(request, result));
}
@JaxrsMethodDescribe(value = "离线安装应用.", action = ActionInstallOffline.class)
@POST
@Path("install/offline")
@Consumes(MediaType.MULTIPART_FORM_DATA)
@Produces(HttpMediaType.APPLICATION_JSON_UTF_8)
public void installOffline(@Suspended final AsyncResponse asyncResponse, @Context HttpServletRequest request,
@FormDataParam(FILE_FIELD) final byte[] bytes,
@JaxrsParameterDescribe("附件名称") @FormDataParam(FILENAME_FIELD) String fileName,
@JaxrsParameterDescribe(".zip文件") @FormDataParam(FILE_FIELD) final FormDataContentDisposition disposition) {
ActionResult<ActionInstallOffline.Wo> result = new ActionResult<>();
EffectivePerson effectivePerson = this.effectivePerson(request);
try {
result = new ActionInstallOffline().execute(effectivePerson, bytes, fileName, disposition);
} catch (Exception e) {
logger.error(e, effectivePerson, request, null);
result.error(e);
}
asyncResponse.resume(ResponseFactory.getEntityTagActionResultResponse(request, result));
}
}
......@@ -34,10 +34,12 @@ public class InstallLog extends SliceJpaObject {
private static final String TABLE = PersistenceProperties.InstallLog.table;
@Override
public String getId() {
return id;
}
@Override
public void setId(String id) {
this.id = id;
}
......@@ -49,6 +51,7 @@ public class InstallLog extends SliceJpaObject {
/* 以上为 JpaObject 默认字段 */
@Override
public void onPersist() throws Exception {
}
......@@ -82,7 +85,7 @@ public class InstallLog extends SliceJpaObject {
@FieldDescribe("安装概要内容.")
@Lob
@Basic(fetch = FetchType.EAGER)
@Column(length = JpaObject.length_4K, name = ColumnNamePrefix + data_FIELDNAME)
@Column(length = JpaObject.length_10M, name = ColumnNamePrefix + data_FIELDNAME)
private String data;
public static final String installPerson_FIELDNAME = "installPerson";
......@@ -182,4 +185,4 @@ public class InstallLog extends SliceJpaObject {
public void setUnInstallTime(Date unInstallTime) {
this.unInstallTime = unInstallTime;
}
}
\ No newline at end of file
}
package com.x.program.center.core.entity;
/**
*
* @author sword
*/
public enum InstallTypeEnum {
DATA("data", "初始化数据"),
CUSTOM("custom", "自定义服务"),
XAPP("xapp", "平台安装包"),
WEB("web", "前端资源");
private String value;
private String name;
private InstallTypeEnum(String value, String name) {
this.value = value;
this.name = name;
}
public static InstallTypeEnum getByValue(String value) {
for (InstallTypeEnum e : InstallTypeEnum.values()) {
if (e.getValue().equals(value)) {
return e;
}
}
return null;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value == null ? null : value.trim();
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name == null ? null : name.trim();
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册