diff options
Diffstat (limited to 'webservice/src/main/java/app/market/webservice/dataManager')
3 files changed, 546 insertions, 0 deletions
diff --git a/webservice/src/main/java/app/market/webservice/dataManager/AppFileController.java b/webservice/src/main/java/app/market/webservice/dataManager/AppFileController.java new file mode 100644 index 0000000..8a24a58 --- /dev/null +++ b/webservice/src/main/java/app/market/webservice/dataManager/AppFileController.java @@ -0,0 +1,255 @@ +/* + * Copyright (c) 2019 TOYOTA MOTOR CORPORATION + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package app.market.webservice.dataManager; + +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.net.URLDecoder; +import java.net.URLEncoder; + +import javax.imageio.ImageIO; +import javax.servlet.ServletContext; +import javax.servlet.http.HttpServletResponse; + +import org.apache.commons.codec.digest.DigestUtils; +import org.apache.commons.io.FileUtils; +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.multipart.MultipartFile; + +import app.market.LogUtil; +import app.market.common.comm; +import app.market.model.app.FileInfo; +import app.market.utils.constants.Constants; +import app.market.utils.json.JsonMapperUtils; +import app.market.utils.property.KeysConstants; +import app.market.utils.webservice.ApiParam; +import app.market.utils.webservice.ErrorCode; +import app.market.utils.webservice.ErrorCodeEnum; +import app.market.utils.webservice.WebServiceURI; +import app.market.webservice.WebserviceRestBaseController; + + +@RestController +public class AppFileController extends WebserviceRestBaseController { + + private static Logger logger = LoggerFactory.getLogger(AppFileController.class); + + @Autowired + ServletContext context; + + /** + * upload application file + * @param inputFile + * @param md5 + * @param appDeviceType + * @param appId + * @param orgFileName + * @return + */ + @RequestMapping(value = WebServiceURI.REST_APP_FILE_PARM_FILENAME_TYPEID_APPID_LF, headers = ("content-type=multipart/*"), method = RequestMethod.POST) + public String upload(@RequestParam(ApiParam.API_APP_PARAM_MULTIPARTFILE) MultipartFile inputFile + ,@RequestParam(ApiParam.API_APP_PARAM_FILE_HASH) String hashcode + ,@PathVariable(ApiParam.API_APP_PARAM_APPDEVICETYPEID) String appDeviceType + ,@PathVariable(ApiParam.API_APP_PARAM_APPID) String appId + ,@PathVariable(ApiParam.API_APP_PARAM_FILE_NAME) String orgFileName + , HttpServletResponse response) { + logger.debug("upload"); + + FileInfo fileInfo = new FileInfo(); + String responseStr = null; + + if (inputFile.isEmpty() || StringUtils.isEmpty(hashcode)) { + return comm.getResponseError(response, Constants.STATUS_BAD_REQUEST, + new ErrorCode(ErrorCodeEnum.MISSING_RESOURCE,KeysConstants.MISSING_NECESSARY_QUERYPARAM)); + } + + if(!orgFileName.endsWith(Constants.FILE_TYPE)){ + return comm.getResponseError(response, Constants.STATUS_UNSUPPORT, + new ErrorCode(ErrorCodeEnum.UNSUPPORT_FILE,KeysConstants.APP_FILE_TYPE_IS_UNSUPPORTED)); + } + + //md5 check file + try { + String md5Hex = DigestUtils.md5Hex(inputFile.getInputStream()); + if (!md5Hex.equalsIgnoreCase(hashcode)) { + return comm.getResponseError(response, Constants.STATUS_BAD_FILE, + new ErrorCode(ErrorCodeEnum.MD5_FAILED,KeysConstants.APP_UPLOAD_MD5)); + } + } catch (IOException e) { + return comm.getResponseError(response, Constants.STATUS_BAD_REQUEST, + new ErrorCode(ErrorCodeEnum.MISSING_RESOURCE,KeysConstants.STATUS_BAD_REQUEST)); + } + + try { + orgFileName = URLDecoder.decode(orgFileName, "utf-8"); + String destFileName = FileUtil.createFileName(orgFileName); + String destFilePath = FileUtil.getUploadPath(FileUtil.getAppPath(appDeviceType, appId)); + + //save appFile + String destPath = destFilePath + destFileName; + File destFile = new File(destFilePath + destFileName); + inputFile.transferTo(destFile); + + //uncompress appFile + String uncompressFilePath = FileUtil.uncompress(destPath); + logger.debug("uncompressFilePath=" + uncompressFilePath); + + //check uncompress file + if(StringUtils.isEmpty(uncompressFilePath)){ + return comm.getResponseError(response, Constants.STATUS_BAD_REQUEST, + new ErrorCode(ErrorCodeEnum.BAD_FAILED,KeysConstants.APP_FILE_UNCOMPRESS_FAILED)); + } + + if (StringUtils.isNotEmpty(uncompressFilePath)) { + // get info in config.xml + FileUtil.parseConfigInfo(uncompressFilePath, fileInfo); + + //check customer appid + if(StringUtils.isEmpty(fileInfo.getConfigAppId()) + || StringUtils.isEmpty(fileInfo.getConfigVersionName())){ + return comm.getResponseError(response, Constants.STATUS_BAD_REQUEST, + new ErrorCode(ErrorCodeEnum.BAD_FAILED,KeysConstants.APP_FILE_READ_FAILED)); + } + + // save icon image of appFile + String iconPath = ""; + if (StringUtils.isNotEmpty(fileInfo.getIconPath())) { + iconPath = FileUtil.saveAppIcon(uncompressFilePath, fileInfo.getIconPath()); + fileInfo.setIconPath(iconPath);///resource/appIcon/b4a527c0-0bfc-4ca1-99da-cdd4850ceb43_icon.svg + } + + // remove temp directory of uncompress + FileUtil.removeFile(uncompressFilePath); + } + String relativeFilePath = FileUtil.getAppPath(appDeviceType, appId) + destFileName; + fileInfo.setFileName(orgFileName); + fileInfo.setFileSize(inputFile.getSize()); + fileInfo.setFilePath(relativeFilePath); + fileInfo.setFileHashCode(hashcode); + + responseStr = JsonMapperUtils.writeValueAsString(fileInfo); + } catch (Exception e) { + responseStr = comm.getResponseException(response, e); + } + + logger.debug("upload end"); + return responseStr; + } + + /** + * download + * @param fileName + * @param appType + * @param appId + * @return + * @throws IOException + */ + @RequestMapping(value = WebServiceURI.REST_APP_FILE_PARM_FILEPATH_LF, method = RequestMethod.GET) + public ResponseEntity<byte[]> download(@RequestParam(ApiParam.API_APP_PARAM_FILE_PATH) String filePath) throws IOException { + + String downloadPath = FileUtil.getUploadPath(filePath); + String orgFileName = FileUtil.getOrgFileName(filePath); + + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_OCTET_STREAM); + headers.setContentDispositionFormData("attachment", URLEncoder.encode(orgFileName,"UTF-8")); + + byte[] body = null; + ResponseEntity<byte[]> responseEntity = null; + + try { + File file = new File(downloadPath); + body = FileUtils.readFileToByteArray(file); + + responseEntity = new ResponseEntity<byte[]>(body, headers, HttpStatus.OK); + } catch (IOException e) { + LogUtil.printCatchLog(logger, e); + responseEntity = new ResponseEntity<byte[]>(body, headers, HttpStatus.INTERNAL_SERVER_ERROR); + e.printStackTrace(); + } + return responseEntity; + } + + /** + * upload image + * @param inputFile + * @param orgFileName + * @param response + * @return + * @throws IOException + */ + @RequestMapping(value = WebServiceURI.REST_APP_IMAGE_LF, headers = ("content-type=multipart/*"), method = RequestMethod.POST) + public String imageUpload(@RequestParam(ApiParam.API_APP_PARAM_MULTIPARTFILE) MultipartFile inputFile + ,@RequestParam(value=ApiParam.API_APP_PARAM_FILE_NAME,required = false) String orgFileName + , HttpServletResponse response){ + logger.debug("imageUpload"); + + FileInfo fileInfo = new FileInfo(); + String responseStr = null; + + //check image + if (inputFile.isEmpty()) { + return comm.getResponseError(response, Constants.STATUS_BAD_REQUEST, + new ErrorCode(ErrorCodeEnum.MISSING_RESOURCE,KeysConstants.MISSING_NECESSARY_QUERYPARAM)); + } + try { + //check image + String contentType = inputFile.getContentType(); + String imageStr = contentType.substring(Constants.IMAGE_INT,contentType.lastIndexOf(Constants.PATH_SEPARATOR)); + if(!orgFileName.endsWith(Constants.IMAGE_SVG) && !orgFileName.endsWith(Constants.IMAGE_PNG) + &&!imageStr.equals(Constants.IMAGE_TYPE)) { + return comm.getResponseError(response, Constants.STATUS_BAD_REQUEST, + new ErrorCode(ErrorCodeEnum.MISSING_RESOURCE,KeysConstants.UPLOAD_PICTURES_ONLY)); + } + if(inputFile.getSize() > (Constants.IMAGE_SIZE)) { + return comm.getResponseError(response, Constants.STATUS_BAD_REQUEST, + new ErrorCode(ErrorCodeEnum.MISSING_RESOURCE,KeysConstants.THE_PICTURE_SIZES)); + } + if(StringUtils.isEmpty(orgFileName)){ + orgFileName = inputFile.getOriginalFilename(); + } + String destFilePath = FileUtil.getImagePath(orgFileName); + + File destFile = new File(destFilePath); + inputFile.transferTo(destFile); + + String fullImagePath = FileUtil.getImageAccessPath(destFilePath); + fileInfo.setIconPath(fullImagePath); + + responseStr = JsonMapperUtils.writeValueAsString(fileInfo); + } catch (Exception e) { + responseStr = comm.getResponseException(response, e); + } + + logger.debug("imageUpload end"); + return responseStr; + } + +} diff --git a/webservice/src/main/java/app/market/webservice/dataManager/FileUtil.java b/webservice/src/main/java/app/market/webservice/dataManager/FileUtil.java new file mode 100644 index 0000000..5018e89 --- /dev/null +++ b/webservice/src/main/java/app/market/webservice/dataManager/FileUtil.java @@ -0,0 +1,248 @@ +/* + * Copyright (c) 2019 TOYOTA MOTOR CORPORATION + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package app.market.webservice.dataManager; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.UnsupportedEncodingException; +import java.util.UUID; + +import org.apache.commons.lang3.StringUtils; +import org.dom4j.Document; +import org.dom4j.Element; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import app.market.PropertyUtil; + +import app.market.model.app.FileInfo; +import app.market.utils.RuntimeUtil; +import app.market.utils.Utils; +import app.market.utils.constants.Constants; +import app.market.utils.datetime.DateTimeUtils; + +public class FileUtil { + private static Logger logger = LoggerFactory.getLogger(FileUtil.class);// TODO DJ log确认要不要打,要打的话按照等级来做,catch中error,有可能出错的地方warn,其他的info + + /** + * + * @param type + * @param appId + * @return + */ + public static String getUploadPath(String path) { + String dir = ""; + + String uploadPath = PropertyUtil.getFileManagerPropertites("upload_path"); + if (StringUtils.isEmpty(uploadPath)) { + uploadPath = Constants.UPLOAD_PATH_DEFAULT; + } + + dir = uploadPath + path; + File file = new File(dir); + if (!file.exists()) { + file.mkdirs(); + } + + return dir; + } + + /** + * relative path + * @param type + * @param appId + * @return + */ + public static String getAppPath(String type, String appId){ + if (Utils.strIsEmpty(type)) { + type = Constants.UPLOAD_PATH_TYPE_DEFAULT; + } + if (Utils.strIsEmpty(appId)) { + appId = Constants.UPLOAD_PATH_APP_DEFAULT; + } + + String path = Constants.UPLOAD_APP_FILE_PATH + Constants.PATH_SEPARATOR + + type + Constants.PATH_SEPARATOR + + appId + Constants.PATH_SEPARATOR; + return path; + } + + /*** + * + * @param orgfilename + * @return + */ + public static String createFileName(String orgfilename) { + String fileName = UUID.randomUUID().toString(); + + if(StringUtils.isNotEmpty(orgfilename)){ + fileName += Constants.FILE_SEPARATOR + orgfilename; + } + + return fileName; + } + + /*** + * generate file name + * @param path + * @return orgfileName + */ + public static String getOrgFileName(String path) { + String orgfileName = path; + //String fileName = path.substring(path.lastIndexOf(Constants.PATH_SEPARATOR) + 1); + String fileName = Utils.getFileNameFromPath(path); + if(fileName != null){ + try { + int separatorIndex = UUID.randomUUID().toString().length() + Constants.FILE_SEPARATOR.length(); + orgfileName = fileName.substring(separatorIndex); + } catch (Exception e) { + logger.debug("getOrgFileName:"+e.getMessage()); + } + } + return orgfileName; + } + + public static String encodeStr(String str) { + try { + return new String(str.getBytes(Constants.CHARACTER_ISO), Constants.CHARACTER_UTF8); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + return null; + } + } + + /** + * Uncompress File + * @param filePath:Compress File's Ordinary Path + * @return uncompressPath: Be Uncompressed File's Temperature Save Path + * @throws Exception + */ + public static String uncompress(String filePath) throws Exception { + String ret = null; + String nowTime =DateTimeUtils.getCurrectDate(DateTimeUtils.DATE_FORMAT_YYYYMMDDHHMMSS); + String uncompressPath= getUploadPath(Constants.UPLOAD_APP_UNCOMPRESS_PATH) + Constants.PATH_SEPARATOR + nowTime; + + String cmd = "unzip " + filePath + " -d " + uncompressPath; + + if(RuntimeUtil.linuxCmdExec(cmd)) { + ret = uncompressPath; + } + return ret; + } + + /** + * XML File Parse + * @param path:Be Uncompressed File's Temperature Save Path + * @param fileInfo + */ + public static void parseConfigInfo(String path, FileInfo fileInfo) { + String configId =""; + String configVersionName=""; + String configAppName = ""; + String iconPath = ""; + try { + Document doc = XmlFactory.parse(path + Constants.UPLOAD_APP_UNCOMPRESS_FILE_CONFIG); + Element root = doc.getRootElement(); + + configId = root.attributeValue(Constants.CONFIG_APP_PARAM_ID); + configVersionName = root.attributeValue(Constants.CONFIG_APP_PARAM_VERSION); + configAppName = root.elementText(Constants.CONFIG_APP_PARAM_NAME); + if (root.element(Constants.CONFIG_APP_PARAM_ICON) != null) { + iconPath = root.element(Constants.CONFIG_APP_PARAM_ICON).attributeValue(Constants.CONFIG_APP_PARAM_SRC); + } + + logger.debug("iconPath="+iconPath); + } catch (Exception e) { + logger.debug("getConfigInfo"+e.getMessage()); + } + fileInfo.setConfigAppId(configId); + fileInfo.setConfigVersionName(configVersionName); + fileInfo.setConfigAppName(configAppName); + fileInfo.setIconPath(iconPath); + } + + /** + * save icon path + * @param path:Be Uncompressed File's Temperature Save Path + * @param iconPath:icon's name in config.xml file + * @throws FileNotFoundException + * @return Icon's Save Path to server + */ + public static String saveAppIcon(String path, String iconPath) throws FileNotFoundException { + String ret = ""; + String orgPath = path + Constants.PATH_SEPARATOR + iconPath; + String destPath = getImagePath(iconPath); + + logger.debug("destPath=" + destPath); + logger.debug("orgPath=" + orgPath); + + String cmd = "cp " + orgPath + " " + destPath; + logger.debug("cp_cmd=" + cmd); + + if(RuntimeUtil.linuxCmdExec(cmd)) { + ret = FileUtil.getImageAccessPath(destPath);//http:\\\\localhost:8080\\resource/appIcon/xxxxx.png + logger.debug("cp_ret=" + ret); + } + return ret; + } + + /** + * get icon path + * @param filename:Icon's name + * @return Relative Path :appIcon/xxxxx.png + */ + public static String getImagePath(String filename) { + //get image file name + if(filename.contains(Constants.PATH_SEPARATOR)) { + //filename = filename.substring(filename.lastIndexOf(Constants.PATH_SEPARATOR) + 1); + filename = Utils.getFileNameFromPath(filename); + } + + String imagePath = getUploadPath(Constants.UPLOAD_APP_RES_PATH_ICON); + + String fullPath = imagePath + Constants.PATH_SEPARATOR + createFileName(filename); + return fullPath; + } + + /** + * getImageAccessPath + * @param fullFilePath + * @return + */ + public static String getImageAccessPath(String fullFilePath) { + String basePath = getUploadPath(""); + String httpPathHeader = PropertyUtil.getFileManagerPropertites("upload_icon_path"); + String path = fullFilePath.replace(basePath, httpPathHeader); + + logger.debug("getImageAccessPath=" + path); + return path; + } + + /** + * + * @param filePath:Be Uncompressed File's Temperature Save Path + * @return result + */ + public static int removeFile(String filePath) { + String cmd = "rm -rf " + filePath; + int ret = 0; + System.out.println(cmd); + if(RuntimeUtil.linuxCmdExec(cmd)) { + ret = 1; + } + return ret; + } +} diff --git a/webservice/src/main/java/app/market/webservice/dataManager/XmlFactory.java b/webservice/src/main/java/app/market/webservice/dataManager/XmlFactory.java new file mode 100644 index 0000000..489a6da --- /dev/null +++ b/webservice/src/main/java/app/market/webservice/dataManager/XmlFactory.java @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2019 TOYOTA MOTOR CORPORATION + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package app.market.webservice.dataManager; + +import java.net.URL; + +import org.dom4j.Document; +import org.dom4j.DocumentException; +import org.dom4j.io.SAXReader; + +public class XmlFactory { + + public Document parse(URL url) throws DocumentException { + SAXReader reader = new SAXReader(); + Document document = reader.read(url); + return document; + } + + // load local xml file + public static Document parse(String path) { + SAXReader reader = new SAXReader(); + Document document = null; + try { + document = reader.read(path); + } catch (DocumentException e) { + e.printStackTrace(); + } + return document; + } +} |