001package org.opengion.plugin.cloud;
002
003import java.io.InputStream;
004import java.text.SimpleDateFormat;
005import java.util.ArrayList;
006import java.util.HashMap;
007import java.util.List;
008import java.util.Map;
009
010import javax.servlet.http.HttpSession;
011
012import org.opengion.fukurou.util.Closer;
013import org.opengion.fukurou.util.FileUtil;
014import org.opengion.fukurou.util.StringUtil;
015import org.opengion.hayabusa.common.HybsSystem;
016import org.opengion.hayabusa.common.HybsSystemException;
017import org.opengion.hayabusa.io.StorageAPI;
018
019import com.microsoft.azure.storage.CloudStorageAccount;
020import com.microsoft.azure.storage.blob.BlobOutputStream;
021import com.microsoft.azure.storage.blob.BlobProperties;
022import com.microsoft.azure.storage.blob.CloudBlob;
023import com.microsoft.azure.storage.blob.CloudBlobClient;
024import com.microsoft.azure.storage.blob.CloudBlobContainer;
025import com.microsoft.azure.storage.blob.CloudBlockBlob;
026import com.microsoft.azure.storage.blob.ListBlobItem;
027
028/**
029 * azure用のクラウドストレージ操作実装
030 *
031 * システムリソースのCLOUD_STORAGE_AZURE_KEYに、Azureのキー情報を登録する必要があります。
032 *
033 * @og.group クラウド
034 * @og.rev 5.9.29.1 (2018/02/09) 新規作成
035 *
036 * @version 5.0
037 * @author T.OTA
038 * @sinse JDK7.0
039 */
040public class StorageAPI_azure implements StorageAPI {
041        // 認証文字列
042        private CloudBlobContainer blobContainer = null;
043
044        public StorageAPI_azure(String container, HttpSession hsession){
045                String storageConnectionString = HybsSystem.sys("CLOUD_STORAGE_AZURE_KEY");
046                if(StringUtil.isNull(storageConnectionString)){
047                        String errMsg = "Azure用認証キーがシステムリソースに登録されていません。";
048                        throw new HybsSystemException(errMsg);
049                }
050
051                try{
052                        CloudStorageAccount account = CloudStorageAccount.parse(storageConnectionString);
053                        CloudBlobClient serviceClient = account.createCloudBlobClient();
054                        blobContainer = serviceClient.getContainerReference(container);
055                        // コンテナが存在しない場合は作成する
056                        blobContainer.createIfNotExists();
057                }catch(Exception e){
058                        StringBuilder sbErrMsg = new StringBuilder();
059                        sbErrMsg.append("コンテナの作成に失敗しました。container:");
060                        sbErrMsg.append(container);
061                        throw new HybsSystemException(sbErrMsg.toString());
062                }
063        }
064
065        /**
066         * アップロード
067         *
068         * @param partInputStream       アップロード対象のストリーム
069         * @param updFolder             アップロードフォルタ名
070         * @param updFileName           アップロードファイル名
071         * @param hsession                      セッション
072         */
073        @Override
074        public void add(InputStream partInputStream, String updFolder, String updFileName, HttpSession hsession) {
075                BlobOutputStream blobOutputStream = null;
076                try {
077                        // アップロード処理
078                        CloudBlockBlob blob = blobContainer.getDirectoryReference(updFolder).getBlockBlobReference(updFileName);
079                        blobOutputStream = blob.openOutputStream();
080
081                        byte buffer[]  = new byte[4096];
082                        int size;
083
084                        while((size = partInputStream.read(buffer)) != -1){
085                                blobOutputStream.write(buffer,0,size);
086                                blobOutputStream.flush();
087                        }
088
089                } catch (Exception e) {
090                        StringBuilder sbErrMsg = new StringBuilder();
091                        sbErrMsg.append("ストレージへのファイルアップロードに失敗しました。updFolder:");
092                        sbErrMsg.append(updFolder);
093                        sbErrMsg.append(" updFileName:");
094                        sbErrMsg.append(updFileName);
095                        sbErrMsg.append(" errInfo:");
096                        sbErrMsg.append(e);
097                        throw new HybsSystemException(sbErrMsg.toString());
098                } finally {
099                        // クローズ処理
100                        Closer.ioClose(blobOutputStream);
101                        Closer.ioClose(partInputStream);
102                }
103        }
104
105        /**
106         * ダウンロード
107         *
108         * @param filePath      ダウンロード対象のファイルパス
109         * @param hsession      セッション
110         * @return ストリーム
111         */
112        @Override
113        public InputStream get(String filePath, HttpSession hsession) {
114                CloudBlockBlob blob = null;
115                InputStream is = null;
116                // ダウンロード
117                try {
118                        blob = blobContainer.getBlockBlobReference(filePath);
119                        is = blob.openInputStream();
120                } catch (Exception e) {
121                        StringBuilder sbErrMsg = new StringBuilder();
122                        sbErrMsg.append("ストレージからのファイルダウンロードに失敗しました。filePath:");
123                        sbErrMsg.append(filePath);
124                        sbErrMsg.append(" errInfo:");
125                        sbErrMsg.append(e);
126                        throw new HybsSystemException(sbErrMsg.toString());
127                }
128
129                return is;
130        }
131
132        /**
133         * コピー
134         *
135         * @param oldFilePath   コピー元ファイルパス
136         * @param newFilePath   コピー先ファイルパス
137         * @param hsession              セッション
138         */
139        @Override
140        public void copy(String oldFilePath, String newFilePath, HttpSession hsession) {
141                // コピー処理
142                InputStream is = null;
143
144                try {
145                        CloudBlockBlob oldblob = blobContainer.getBlockBlobReference(oldFilePath);
146                        CloudBlockBlob newblob = blobContainer.getBlockBlobReference(newFilePath);
147                        newblob.startCopy(oldblob);
148                } catch (Exception e) {
149                        StringBuilder sbErrMsg = new StringBuilder();
150                        sbErrMsg.append("ストレージのファイルコピー処理に失敗しました。oldFilePath:");
151                        sbErrMsg.append(oldFilePath);
152                        sbErrMsg.append(" newFilePath:");
153                        sbErrMsg.append(newFilePath);
154                        sbErrMsg.append(" errInfo:");
155                        sbErrMsg.append(e);
156                        throw new HybsSystemException(sbErrMsg.toString());
157                }finally{
158                        // クローズ処理
159                        Closer.ioClose(is);
160                }
161        }
162
163        /**
164         * 削除
165         *
166         * @param filePath      削除ファイルのパス
167         * @param hsession      セッション
168         */
169        @Override
170        public void delete(String filePath, HttpSession hsession) {
171                // 削除
172                try {
173                        CloudBlockBlob blob = blobContainer.getBlockBlobReference(filePath);
174                        blob.delete();
175                } catch (Exception e) {
176                        StringBuilder sbErrMsg = new StringBuilder();
177                        sbErrMsg.append("ストレージのファイル削除に失敗しました。filePath:");
178                        sbErrMsg.append(filePath);
179                        sbErrMsg.append(" errInfo:");
180                        sbErrMsg.append(e);
181                        throw new HybsSystemException(sbErrMsg.toString());
182                }
183        }
184
185        /**
186         * ファイル名変更
187         *
188         * @param filePath              ファイルパス
189         * @param oldFileName   変更前ファイル名
190         * @param newFileName   変更後ファイル名
191         * @param useBackup     変更後ファイル名が既に存在する場合のバックアップ作成フラグ
192         * @param hsession              セッション
193         */
194        public void rename(String filePath, String oldFileName, String newFileName, final boolean useBackup,
195                        HttpSession hsession) {
196                String newFilePath = filePath + newFileName;
197                String oldFilePath = filePath + oldFileName;
198
199                // 変更先のファイルが存在した場合の処理
200                if (exists(newFilePath, hsession)) {
201                        // バックアップ作成する場合
202                        if (useBackup) {
203                                // バックアップファイル名は、元のファイル名(拡張子含む) + "_" + 現在時刻のlong値 + "." +
204                                // 元のファイルの拡張子
205                                String bkupPath = filePath + "_backup/" + newFileName + "_" + System.currentTimeMillis()
206                                                + FileUtil.EXTENSION_SEPARATOR + FileUtil.getExtension(newFileName);
207                                // バックアップフォルダに移動
208                                copy(newFilePath, bkupPath, hsession);
209                        }
210                }
211
212                // コピー
213                copy(oldFilePath, newFilePath, hsession);
214                // 削除
215                delete(oldFilePath, hsession);
216        }
217
218        /**
219         * ファイル存在チェック
220         *
221         * @param filePath                      ファイルパス
222         * @param hsession              セッション
223         * @return                              true:存在 false:存在しない
224         */
225//      @Override
226        public boolean exists(String filePath, HttpSession hsession) {
227                boolean blnRtn = true;
228                try {
229                        CloudBlockBlob blob = blobContainer.getBlockBlobReference(filePath);
230                        if (!blob.exists()) {
231                                // ファイルが取得できなかった場合は、falseを設定
232                                blnRtn = false;
233                        }
234                } catch (Exception e) {
235                        StringBuilder sbErrMsg = new StringBuilder();
236                        sbErrMsg.append("ストレージのファイル取得に失敗しました。filePath:");
237                        sbErrMsg.append(filePath);
238                        sbErrMsg.append(" errInfo:");
239                        sbErrMsg.append(e);
240                        throw new HybsSystemException(sbErrMsg.toString());
241                }
242
243                return blnRtn;
244        }
245
246        /**
247         * ファイル一覧取得
248         *
249         * @param startsWith    パスの前方一致
250         * @param hsession              セッション
251         * @return                              ファイルパス一覧
252         */
253        @Override
254        public String[] list(String startsWith, HttpSession hsession) {
255                // 認証
256                List<String> rtnList = new ArrayList<String>();
257                try{
258                        // 一覧の取得
259                        for(ListBlobItem item: blobContainer.listBlobs(startsWith)){
260                                if(item instanceof CloudBlob){
261                                // 名称を格納
262                                rtnList.add(((CloudBlob)item).getName());
263                                }
264                        }
265                } catch (Exception e){
266                        StringBuilder sbErrMsg = new StringBuilder();
267                        sbErrMsg.append("ファイル一覧の取得に失敗しました。startsWith:");
268                        sbErrMsg.append(startsWith);
269                        sbErrMsg.append(" errInfo:");
270                        sbErrMsg.append("e");
271                        throw new HybsSystemException(sbErrMsg.toString());
272                }
273                return rtnList.toArray(new String[rtnList.size()]);
274        }
275
276        /**
277         * ファイル情報取得
278         *
279         * @param path                  ファイルパス
280         * @param hsession              セッション
281         * @return                              ファイル情報格納Map
282         */
283//      @Override
284        public Map<String, String> getInfo(String path, HttpSession hsession) {
285                Map<String, String> rtnMap = new HashMap<String,String>();
286
287                CloudBlob blob = null;
288                try{
289                        // ファイルオブジェクトの取得
290                        blob = blobContainer.getBlobReferenceFromServer(path);
291                }catch(Exception e){
292                        StringBuilder sbErrMsg = new StringBuilder();
293                        sbErrMsg.append("ファイルの取得に失敗しました。path:");
294                        sbErrMsg.append(path);
295                        sbErrMsg.append(" errInfo:");
296                        sbErrMsg.append(e);
297                        throw new HybsSystemException(sbErrMsg.toString());
298                }
299                SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddhhmmss");
300
301                BlobProperties properties =  blob.getProperties();
302                // ファイルサイズ
303                rtnMap.put(FILEINFO_SIZE, String.valueOf(properties.getLength()));
304                // 最終更新時刻
305                rtnMap.put(FILEINFO_LASTMODIFIED, sdf.format(properties.getLastModified()));
306
307                return rtnMap;
308        }
309}