好設計,遷移不費勁
阿新 • • 發佈:2017-06-12
filepath quota metadata sage comm div prop extend ssa
擴展存儲文件的實現類
改動ioc註入:
前言
盡管java的口號:Write Once, Run Anywhere ,但現實非常殘酷。不同的操作系統、不同的容器總是讓我們:Write Once,Debug Anywhere。所以關鍵還是要看設計。好的設計能降低遷移成本。
近期須要將roller遷移到百度雲中,發現roller設計的真不錯。很easy就看遷移到雲中了。
遷移的主要是數據,roller使用mysql,而百度雲也提高mysql。這個基本不須要考慮遷移。主要是roller的圖片上傳功能:
1、怎樣將已經上傳的圖片遷移到百度的bcs中?
2、怎樣以最小的代價讓將上傳圖片的功能遷移到百度bcs中?
添加一個切換開關:roller.properties
baiduyun.accessKey=dtjTg3L9xm baiduyun.secretKey=9V1L9mul9IVb baiduyun.bucket=hello enabled.use.baiduyun=true
擴展存儲文件的實現類
package org.apache.roller.weblogger.business; import java.io.InputStream; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.roller.weblogger.config.WebloggerConfig; import org.apache.roller.weblogger.pojos.FileContent; import org.apache.roller.weblogger.pojos.MediaFile; import org.apache.roller.weblogger.pojos.Weblog; import org.apache.roller.weblogger.util.RollerMessages; import com.baidu.inf.iis.bcs.BaiduBCS; import com.baidu.inf.iis.bcs.auth.BCSCredentials; import com.baidu.inf.iis.bcs.model.Empty; import com.baidu.inf.iis.bcs.model.ObjectMetadata; import com.baidu.inf.iis.bcs.model.X_BS_ACL; import com.baidu.inf.iis.bcs.request.PutObjectRequest; /** * Manages contents of the file uploaded to Roller weblogs. * * This base implementation writes file content to a file system. */ public class BaiduYunFileContentManagerImpl extends FileContentManagerImpl { private static Log log = LogFactory.getLog(BaiduYunFileContentManagerImpl.class); private String host = "bcs.duapp.com"; private String accessKey = ""; private String secretKey = ""; private String bucket = ""; private BaiduBCS baiduBCS = null; /** * Create file content manager. */ public BaiduYunFileContentManagerImpl() { accessKey = WebloggerConfig.getProperty("baiduyun.accessKey"); secretKey = WebloggerConfig.getProperty("baiduyun.secretKey"); bucket = WebloggerConfig.getProperty("baiduyun.bucket"); BCSCredentials credentials = new BCSCredentials(accessKey, secretKey); baiduBCS = new BaiduBCS(credentials, host); baiduBCS.setDefaultEncoding("UTF-8"); // Default UTF-8 } /** * @see org.apache.roller.weblogger.model.FileContentManager#getFileContent(weblog, java.lang.String) */ public FileContent getFileContent(Weblog weblog, String fileId) throws FileNotFoundException, FilePathException { log.info("=====================get file content:" + fileId); final InputStream is = baiduBCS.getObject(bucket, getObjectStoragePath(weblog, fileId)).getResult().getContent(); return new FileContent(weblog, fileId, null) { private InputStream ins = is; @Override public InputStream getInputStream() { return ins; } }; } private String getObjectStoragePath(Weblog weblog ,String fileId) { return ‘/‘ + weblog.getHandle() + ‘/‘ + fileId; } public void saveFileContent(Weblog weblog, MediaFile mediaFile) throws FileNotFoundException, FilePathException, FileIOException { log.info("==========saveFileContent start ->" + mediaFile.getId()); ObjectMetadata objectMetadata = new ObjectMetadata(); objectMetadata.setContentType(mediaFile.getContentType()); objectMetadata.setContentLength(mediaFile.getLength()); PutObjectRequest request = new PutObjectRequest(bucket, getObjectStoragePath(weblog, mediaFile.getId()), mediaFile.getInputStream(), objectMetadata); ObjectMetadata result = baiduBCS.putObject(request).getResult(); log.info(result); baiduBCS.putObjectPolicy(bucket, getObjectStoragePath(weblog, mediaFile.getId()),X_BS_ACL.PublicRead); log.info("==========saveFileContent end"); } /** * @see org.apache.roller.weblogger.model.FileContentManager#deleteFile(weblog, java.lang.String) */ public void deleteFile(Weblog weblog, String fileId) throws FileNotFoundException, FilePathException, FileIOException { log.info("==========deleteFile start:" + fileId); Empty result = baiduBCS.deleteObject(bucket, getObjectStoragePath(weblog, fileId)).getResult(); baiduBCS.deleteObject(bucket, getObjectStoragePath(weblog, fileId) + "_sm").getResult(); log.info(result); log.info("==========deleteFile start"); } /** * @see org.apache.roller.weblogger.model.FileContentManager#overQuota(weblog) */ public boolean overQuota(Weblog weblog) { return false; } @Override public boolean canSave(Weblog weblog, String fileName, String contentType, long size, RollerMessages messages) { return true; } }
改動ioc註入:
JPAWebloggerModule.java
if(WebloggerConfig.getBooleanProperty("enabled.use.baiduyun")) { binder.bind(FileContentManager.class).to( BaiduYunFileContentManagerImpl.class); } else { binder.bind(FileContentManager.class).to( FileContentManagerImpl.class); }
最後想說的是這種方法參數設計不太好,應該把MediaFile作為參數。而非用其個別字段(fileId和inputstream)
public void saveFileContent(Weblog weblog, String fileId, InputStream is) throws FileNotFoundException, FilePathException, FileIOException;
這樣,roller就能夠把百度bcs作為存儲圖片的server了。
好設計,遷移不費勁