From de3069468056f52631b447e42ee890a69ac98e9b Mon Sep 17 00:00:00 2001 From: strawmanbobi Date: Sun, 30 Dec 2018 22:41:37 +0800 Subject: [PATCH] adjusted redis-data and jedis version compatibility --- .idea/compiler.xml | 5 + decode-service.iml | 131 +++++++++++------- pom.xml | 55 ++++---- .../java/net/irext/decoder/SessionConfig.java | 16 --- .../net/irext/decoder/alioss/OSSHelper.java | 94 +++++++++++++ .../decoder/businesslogic/DecodeLogic.java | 101 ++++++++++++++ .../decoder/service/IRDecodeService.java | 15 +- .../net/irext/decoder/utils/FileUtils.java | 114 +++++++++++++++ .../java/net/irext/decoder/utils/MD5Util.java | 53 +++++++ 9 files changed, 492 insertions(+), 92 deletions(-) delete mode 100644 src/main/java/net/irext/decoder/SessionConfig.java create mode 100644 src/main/java/net/irext/decoder/alioss/OSSHelper.java create mode 100644 src/main/java/net/irext/decoder/utils/FileUtils.java create mode 100644 src/main/java/net/irext/decoder/utils/MD5Util.java diff --git a/.idea/compiler.xml b/.idea/compiler.xml index 4580c18..3bd4a52 100644 --- a/.idea/compiler.xml +++ b/.idea/compiler.xml @@ -13,4 +13,9 @@ + + + \ No newline at end of file diff --git a/decode-service.iml b/decode-service.iml index 245b128..ee786e6 100644 --- a/decode-service.iml +++ b/decode-service.iml @@ -25,58 +25,89 @@ - - - - - - - + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/pom.xml b/pom.xml index 8cbaa06..75bc8f1 100644 --- a/pom.xml +++ b/pom.xml @@ -12,10 +12,10 @@ Decoding IR binaries online - org.springframework.boot - spring-boot-starter-parent - 1.5.4.RELEASE - + org.springframework.boot + spring-boot-starter-parent + 2.1.1.RELEASE + @@ -25,37 +25,44 @@ - - org.springframework.boot - spring-boot-starter-security - - - org.mybatis.spring.boot - mybatis-spring-boot-starter - 1.3.0 - + + org.mybatis.spring.boot + mybatis-spring-boot-starter + 1.3.2 + org.springframework.boot spring-boot-starter-web + 2.1.1.RELEASE org.springframework.boot spring-boot-starter-data-redis - - - org.springframework.session - spring-session - 1.3.4.RELEASE - - - org.springframework.data - spring-data-redis - 2.1.3.RELEASE + 2.1.1.RELEASE mysql mysql-connector-java - runtime + 8.0.13 + + + commons-io + commons-io + 2.6 + + + com.aliyun.oss + aliyun-sdk-oss + 3.4.0 + + + org.springframework.boot + spring-boot-autoconfigure + 2.1.1.RELEASE + + + redis.clients + jedis diff --git a/src/main/java/net/irext/decoder/SessionConfig.java b/src/main/java/net/irext/decoder/SessionConfig.java deleted file mode 100644 index bb05a8e..0000000 --- a/src/main/java/net/irext/decoder/SessionConfig.java +++ /dev/null @@ -1,16 +0,0 @@ -package net.irext.decoder; - -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.data.redis.connection.jedis.JedisConnectionFactory; -import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession; -import org.springframework.session.web.context.AbstractHttpSessionApplicationInitializer; - -@Configuration -@EnableRedisHttpSession -public class SessionConfig extends AbstractHttpSessionApplicationInitializer { - @Bean - public JedisConnectionFactory connectionFactory() { - return new JedisConnectionFactory(); - } -} diff --git a/src/main/java/net/irext/decoder/alioss/OSSHelper.java b/src/main/java/net/irext/decoder/alioss/OSSHelper.java new file mode 100644 index 0000000..a5c9a16 --- /dev/null +++ b/src/main/java/net/irext/decoder/alioss/OSSHelper.java @@ -0,0 +1,94 @@ +package net.irext.decoder.alioss; + +import com.aliyun.oss.OSSClient; +import com.aliyun.oss.model.Bucket; +import com.aliyun.oss.model.OSSObject; +import com.aliyun.oss.model.ObjectMetadata; +import com.aliyun.oss.model.PutObjectResult; + +import java.io.File; +import java.io.FileInputStream; +import java.io.InputStream; + +/** + * Filename: OSSHelper.java + * Revised: Date: 2017-05-10 + * Revision: Revision: 1.0 + *

+ * Description: Aliyun OSS file operation helper + *

+ * Revision log: + * 2017-05-10: created by strawmanbobi + */ +public class OSSHelper { + + public static String BUCKET_NAME = "irext-debug"; + + private OSSClient mOSSClient; + + public OSSHelper() { + String END_POINT = "oss-cn-hangzhou.aliyuncs.com"; + String ACCESS_KEY = "T82nbipHSESmHzd8"; + String ACCESS_SECRET = "SOweQ8UVwCwPr2NC8EC89EOeKJc5Um"; + + mOSSClient = new OSSClient(END_POINT, ACCESS_KEY, ACCESS_SECRET); + } + + public boolean createBucket(String bucketName) { + Bucket bucket = mOSSClient.createBucket(bucketName); + return bucketName.equals(bucket.getName()); + } + + public final void deleteBucket(String bucketName) { + mOSSClient.deleteBucket(bucketName); + } + + public final String uploadObject2OSS(File file, String bucketName, String diskName) { + String resultStr = null; + try { + InputStream is = new FileInputStream(file); + String fileName = file.getName(); + Long fileSize = file.length(); + ObjectMetadata metadata = new ObjectMetadata(); + metadata.setContentLength(is.available()); + metadata.setCacheControl("no-cache"); + metadata.setHeader("Pragma", "no-cache"); + metadata.setContentEncoding("utf-8"); + metadata.setContentType(getContentType(fileName)); + metadata.setContentDisposition("filename/filesize=" + fileName + "/" + fileSize + "Byte."); + PutObjectResult putResult = mOSSClient.putObject(bucketName, diskName + fileName, is, metadata); + resultStr = putResult.getETag(); + } catch (Exception e) { + e.printStackTrace(); + } + return resultStr; + } + + public InputStream getOSS2InputStream(String bucketName, String diskName, String key) { + OSSObject ossObj = mOSSClient.getObject(bucketName, diskName + key); + return ossObj.getObjectContent(); + } + + public void deleteFile(String bucketName, String diskName, String key) { + mOSSClient.deleteObject(bucketName, diskName + key); + } + + private String getContentType(String fileName) { + String fileExtension = fileName.substring(fileName.lastIndexOf(".")); + if ("bmp".equalsIgnoreCase(fileExtension)) return "image/bmp"; + if ("gif".equalsIgnoreCase(fileExtension)) return "image/gif"; + if ("jpeg".equalsIgnoreCase(fileExtension) || + "jpg".equalsIgnoreCase(fileExtension) || + "png".equalsIgnoreCase(fileExtension)) + return "image/jpeg"; + if ("html".equalsIgnoreCase(fileExtension)) return "text/html"; + if ("txt".equalsIgnoreCase(fileExtension)) return "text/plain"; + if ("vsd".equalsIgnoreCase(fileExtension)) return "application/vnd.visio"; + if ("ppt".equalsIgnoreCase(fileExtension) || "pptx".equalsIgnoreCase(fileExtension)) + return "application/vnd.ms-powerpoint"; + if ("doc".equalsIgnoreCase(fileExtension) || "docx".equalsIgnoreCase(fileExtension)) + return "application/msword"; + if ("xml".equalsIgnoreCase(fileExtension)) return "text/xml"; + return "text/html"; + } +} diff --git a/src/main/java/net/irext/decoder/businesslogic/DecodeLogic.java b/src/main/java/net/irext/decoder/businesslogic/DecodeLogic.java index 56c9c63..7918e1b 100644 --- a/src/main/java/net/irext/decoder/businesslogic/DecodeLogic.java +++ b/src/main/java/net/irext/decoder/businesslogic/DecodeLogic.java @@ -1,7 +1,23 @@ package net.irext.decoder.businesslogic; +import net.irext.decoder.alioss.OSSHelper; +import net.irext.decoder.model.IRBinary; +import net.irext.decoder.model.RemoteIndex; +import net.irext.decoder.redisrepo.IIRBinaryRepository; +import net.irext.decoder.utils.FileUtils; +import net.irext.decoder.utils.MD5Util; +import org.apache.commons.io.IOUtils; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; +import javax.servlet.ServletContext; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; + /** * Filename: CollectCodeLogic * Revised: Date: 2018-12-08 @@ -15,8 +31,14 @@ import org.springframework.stereotype.Controller; @Controller public class DecodeLogic { + private static final String IR_BIN_FILE_PREFIX = "irda_"; + private static final String IR_BIN_FILE_SUFFIX = ".bin"; + private static DecodeLogic decodeLogic; + @Autowired + private ServletContext context; + public static DecodeLogic getInstance() { if (null == decodeLogic) { decodeLogic = new DecodeLogic(); @@ -28,7 +50,86 @@ public class DecodeLogic { } + public byte[] openIRBinary(IIRBinaryRepository irBinaryRepository, RemoteIndex remoteIndex) { + if (null == remoteIndex) { + return null; + } + try { + String checksum = remoteIndex.getBinaryMd5().toUpperCase(); + String remoteMap = remoteIndex.getRemoteMap(); + + IRBinary irBinary = irBinaryRepository.find(remoteIndex.getId()); + if (null != irBinary) { + byte[] binaries = irBinary.getBinary(); + if (null != binaries) { + System.out.println("binary content fetched from redis : " + binaries.length); + // validate binary content + String cachedChecksum = + MD5Util.byteArrayToHexString(MessageDigest.getInstance("MD5").digest(binaries)).toUpperCase(); + if (cachedChecksum.equals(checksum)) { + return binaries; + } + } + } + + // otherwise, read from file or OSS + String downloadPath = context.getRealPath("") + "bin_cache" + File.separator; + String fileName = IR_BIN_FILE_PREFIX + remoteMap + IR_BIN_FILE_SUFFIX; + String localFilePath = downloadPath + fileName; + + File binFile = new File(localFilePath); + FileInputStream fin = getFile(binFile, downloadPath, fileName, checksum); + if (null != fin) { + byte[] binaries = IOUtils.toByteArray(fin); + System.out.println("binary content get, save it to redis"); + irBinaryRepository.add(new IRBinary(remoteIndex.getId(), binaries)); + return binaries; + } + } catch (Exception ex) { + ex.printStackTrace(); + return null; + } + return null; + } + public int[] decode() { return null; } + + // helper methods + private FileInputStream getFile(File binFile, String downloadPath, String fileName, String checksum) { + try { + if (binFile.exists()) { + FileInputStream fileInputStream = new FileInputStream(binFile); + // validate binary content + byte []binaries = IOUtils.toByteArray(fileInputStream); + String fileChecksum = + MD5Util.byteArrayToHexString(MessageDigest.getInstance("MD5").digest(binaries)).toUpperCase(); + + if (fileChecksum.equals(checksum)) { + return new FileInputStream(binFile); + } + } + OSSHelper ossHelper = new OSSHelper(); + InputStream inputStream = ossHelper.getOSS2InputStream(OSSHelper.BUCKET_NAME, "", fileName); + // validate binary content + byte []binaries = IOUtils.toByteArray(inputStream); + String ossChecksum = + MD5Util.byteArrayToHexString(MessageDigest.getInstance("MD5").digest(binaries)).toUpperCase(); + if (ossChecksum.equals(checksum)) { + FileUtils.createDirs(downloadPath); + if (FileUtils.write(binFile, binaries)) { + return new FileInputStream(binFile); + } else { + System.out.println("fatal : write file to local path failed"); + } + } else { + System.out.println("fatal : checksum does not match even downloaded from OSS," + + " please contact the admin"); + } + } catch (Exception e) { + e.printStackTrace(); + } + return null; + } } diff --git a/src/main/java/net/irext/decoder/service/IRDecodeService.java b/src/main/java/net/irext/decoder/service/IRDecodeService.java index a79e687..2baf9a6 100644 --- a/src/main/java/net/irext/decoder/service/IRDecodeService.java +++ b/src/main/java/net/irext/decoder/service/IRDecodeService.java @@ -4,6 +4,8 @@ import net.irext.decoder.businesslogic.DecodeLogic; import net.irext.decoder.businesslogic.IndexLogic; import net.irext.decoder.mapper.RemoteIndexMapper; import net.irext.decoder.model.RemoteIndex; +import net.irext.decoder.redisrepo.IDecodeSessionRepository; +import net.irext.decoder.redisrepo.IIRBinaryRepository; import net.irext.decoder.request.CloseRequest; import net.irext.decoder.request.DecodeRequest; import net.irext.decoder.request.OpenRequest; @@ -13,6 +15,7 @@ import net.irext.decoder.response.Status; import net.irext.decoder.service.base.AbstractBaseService; import net.irext.decodesdk.bean.ACStatus; import net.irext.decodesdk.utils.Constants; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; /** @@ -31,6 +34,12 @@ public class IRDecodeService extends AbstractBaseService { private RemoteIndexMapper remoteIndexMapper; + @Autowired + private IIRBinaryRepository irBinaryRepository; + + @Autowired + private IDecodeSessionRepository decodeSessionRepository; + public IRDecodeService(RemoteIndexMapper remoteIndexMapper) { this.remoteIndexMapper = remoteIndexMapper; } @@ -41,11 +50,13 @@ public class IRDecodeService extends AbstractBaseService { int indexId = openRequest.getIndexId(); ServiceResponse response = new ServiceResponse(); - RemoteIndex index = IndexLogic.getInstance(remoteIndexMapper).getRemoteIndex(indexId); - if (null == index) { + RemoteIndex remoteIndex = IndexLogic.getInstance(remoteIndexMapper).getRemoteIndex(indexId); + if (null == remoteIndex) { response.setStatus(new Status(Constants.ERROR_CODE_NETWORK_ERROR, "")); return response; } + byte []binaryContent = DecodeLogic.getInstance().openIRBinary(irBinaryRepository, remoteIndex); + System.out.println("binary content fetched : " + binaryContent.length); return response; } catch (Exception e) { diff --git a/src/main/java/net/irext/decoder/utils/FileUtils.java b/src/main/java/net/irext/decoder/utils/FileUtils.java new file mode 100644 index 0000000..e0e792e --- /dev/null +++ b/src/main/java/net/irext/decoder/utils/FileUtils.java @@ -0,0 +1,114 @@ +package net.irext.decoder.utils; + +import java.io.*; + +/** + * Filename: FileUtils.java + * Revised: Date: 2017-04-14 + * Revision: Revision: 1.0 + *

+ * Description: File operations + *

+ * Revision log: + * 2017-04-14: created by strawmanbobi + */ +public class FileUtils { + + public static boolean write(File file, byte[] binaries) { + if (null == file) { + return false; + } + + if (null == binaries) { + System.out.println("fatal : content to write is null"); + return false; + } + FileOutputStream outputStream = null; + try { + outputStream = new FileOutputStream(file); + outputStream.write(binaries, 0, binaries.length); + outputStream.flush(); + return true; + } catch (IOException e) { + e.printStackTrace(); + } finally { + if (outputStream != null) { + try { + outputStream.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + return false; + } + + public static boolean createDirs(String path) { + File file = new File(path); + return file.exists() || file.mkdir(); + } + + public static byte[] getByteArrayFromFile(String fileName) { + File file; + try { + file = new File(fileName); + } catch (Exception e) { + e.printStackTrace(); + return null; + } + + if (!file.exists() || !file.isFile() || !file.canRead()) { + return null; + } + + byte[] byteArray = null; + + try { + FileInputStream fis = new FileInputStream(file); + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + + int count; + byte buffer[] = new byte[512]; + while ((count = fis.read(buffer)) > 0) { + baos.write(buffer, 0, count); + } + byteArray = baos.toByteArray(); + fis.close(); + baos.flush(); + baos.close(); + } catch (Exception e) { + e.printStackTrace(); + } + + return byteArray; + } + + private static void deleteAllFiles(File root) { + File files[] = root.listFiles(); + if (files != null) { + for (File f : files) { + if (f.isDirectory()) { + deleteAllFiles(f); + try { + if(!f.delete()) { + System.out.println("failed to delete file"); + } + } catch (Exception e) { + e.printStackTrace(); + } + } else { + if (f.exists()) { + deleteAllFiles(f); + try { + if(!f.delete()) { + System.out.println("failed to delete file"); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + } + } + } + } +} \ No newline at end of file diff --git a/src/main/java/net/irext/decoder/utils/MD5Util.java b/src/main/java/net/irext/decoder/utils/MD5Util.java new file mode 100644 index 0000000..c79acf0 --- /dev/null +++ b/src/main/java/net/irext/decoder/utils/MD5Util.java @@ -0,0 +1,53 @@ +package net.irext.decoder.utils; + +import java.security.MessageDigest; + +/** + * Filename: MD5Util.java + * Revised: Date: 2017-04-30 + * Revision: Revision: 1.0 + *

+ * Description: Crypto MD5 utility + *

+ * Revision log: + * 2017-04-30: created by strawmanbobi + */ +public class MD5Util { + + public static String byteArrayToHexString(byte b[]) { + StringBuffer resultSb = new StringBuffer(); + for (int i = 0; i < b.length; i++) + resultSb.append(byteToHexString(b[i])); + + return resultSb.toString(); + } + + private static String byteToHexString(byte b) { + int n = b; + if (n < 0) + n += 256; + int d1 = n / 16; + int d2 = n % 16; + return hexDigits[d1] + hexDigits[d2]; + } + + public static String MD5Encode(String origin, String charsetname) { + String resultString = null; + try { + resultString = new String(origin); + MessageDigest md = MessageDigest.getInstance("MD5"); + if (charsetname == null || "".equals(charsetname)) + resultString = byteArrayToHexString(md.digest(resultString + .getBytes())); + else + resultString = byteArrayToHexString(md.digest(resultString + .getBytes(charsetname))); + } catch (Exception exception) { + } + return resultString; + } + + private static final String hexDigits[] = {"0", "1", "2", "3", "4", "5", + "6", "7", "8", "9", "a", "b", "c", "d", "e", "f"}; + +}