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