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.apache.commons.lang3.StringUtils;
013import org.opengion.fukurou.util.Closer;
014import org.opengion.fukurou.util.FileUtil;
015import org.opengion.hayabusa.common.HybsSystem;
016import org.opengion.hayabusa.common.HybsSystemException;
017import org.opengion.hayabusa.io.StorageAPI;
018
019import oracle.cloud.storage.CloudStorage;
020import oracle.cloud.storage.CloudStorageConfig;
021import oracle.cloud.storage.CloudStorageFactory;
022import oracle.cloud.storage.exception.NoSuchContainerException;
023import oracle.cloud.storage.exception.NoSuchObjectException;
024import oracle.cloud.storage.model.Key;
025import oracle.cloud.storage.model.QueryOption;
026
027/**
028 * azure用のクラウドストレージ操作実装
029 *
030 * 以下のシステムリソースに設定が必要です。
031 * CLOUD_STORAGE_ORACLE_SERVICE_NAME
032 * CLOUD_STORAGE_ORACLE_USERNAME
033 * CLOUD_STORAGE_ORACLE_PASSWORD
034 * CLOUD_STORAGE_ORACLE_SERVICEURL
035 *
036 * @og.group クラウド
037 * @og.rev 5.9.33.0 (2018/06/01) 新規作成
038 *
039 * @version 5.0
040 * @author T.OTA
041 * @sinse JDK7.0
042 */
043public class StorageAPI_oracle implements StorageAPI {
044        // 認証文字列
045        // サービス名
046        private String serviceName = "";
047        // ユーザ名
048        private String userName = "";
049        // パスワード
050        private String password = "";
051        // サービスURL
052        private String serviceUrl = "";
053        // コンテナ名
054        private String containerNm = "";
055
056        // 下記oracle用
057         CloudStorage myConnection = null;;
058
059        /**
060         * コンストラクタ
061         *
062         * @param container
063         * @param hsession
064         */
065        public StorageAPI_oracle(String container, HttpSession hsession){
066                CloudStorageConfig myConfig = new CloudStorageConfig();
067
068                // リソースパラメータ設定
069                // サービス名
070                serviceName = HybsSystem.sys("CLOUD_STORAGE_ORACLE_SERVICE_NAME");
071                // ユーザ名
072                userName = HybsSystem.sys("CLOUD_STORAGE_ORACLE_USERNAME");
073                // パスワード
074                password = HybsSystem.sys("CLOUD_STORAGE_ORACLE_PASSWORD");
075                // サービスURL
076                serviceUrl = HybsSystem.sys("CLOUD_STORAGE_ORACLE_SERVICEURL");
077
078                initCheck();
079
080                // コンテナ名をクラス変数に保持
081                containerNm = container;
082
083                try {
084                        // 接続情報の設定
085                        myConfig.setServiceName(serviceName)
086                        .setUsername(userName)
087                        .setPassword(password.toCharArray())
088                        .setServiceUrl(serviceUrl);
089
090                        myConnection = CloudStorageFactory.getStorage(myConfig);
091
092                // コンテナの存在チェック
093                        try {
094                                myConnection.describeContainer(containerNm);
095                        }catch(NoSuchContainerException nce) {
096                                // コンテナが存在しない場合は、作成する
097                                myConnection.createContainer(container);
098                        }
099                }catch(Exception e) {
100                        throw new HybsSystemException(e);
101                }
102        }
103
104        /**
105         * 初期チェック
106         */
107        private void initCheck(){
108                // システムリソースに認証情報が登録されていない場合は、エラー
109                StringBuilder errString = new StringBuilder();
110                if(StringUtils.isEmpty(serviceName)){
111                        errString.append("CLOUD_STORAGE_ORACLE_SERVICE_NAME");
112                }
113                if(StringUtils.isEmpty(userName)){
114                        errString.append(",CLOUD_STORAGE_ORACLE_USERNAME");
115                }
116                if(StringUtils.isEmpty(password)){
117                        errString.append(",CLOUD_STORAGE_ORACLE_PASSWORD");
118                }
119                if(StringUtils.isEmpty(serviceUrl)){
120                        errString.append(",CLOUD_STORAGE_ORACLE_SERVICEURL");
121                }
122
123                if(errString.length() > 0){
124                        throw new HybsSystemException("クラウドストレージのキー情報("+errString.toString()+")がシステムリソースに登録されていません。");
125                }
126
127        }
128
129        /**
130         * ファイルパスの編集
131         * パスの先頭が「/」の場合は「/」の除去と、「//」を「/」に置換処理の追加。
132         *
133         * @param path
134         * @return
135         */
136        private String editPath(String path) {
137                // pathが空の場合は空文字を返す
138                if(StringUtils.isEmpty(path)) {
139                        return "";
140                }
141
142                // 先頭が「/」の場合は除去
143                if("/".equals(path.substring(0, 1))) {
144                        path = path.substring(1);
145                }
146                // 「//」は「/」に置換
147                path = path.replaceAll("//", "/");
148
149                return path;
150        }
151
152        /**
153         * アップロード
154         *
155         * @param partInputStream       アップロード対象のストリーム
156         * @param updFolder             アップロードフォルタ名
157         * @param updFileName           アップロードファイル名
158         * @param hsession                      セッション
159         */
160        @Override
161        public void add(InputStream partInputStream, String updFolder, String updFileName, HttpSession hsession) {
162                try {
163                        // パスをクラウド用に編集
164                        updFolder = editPath(updFolder);
165
166                        myConnection.storeObject(containerNm, updFolder + updFileName, "application/octet-stream", partInputStream);
167
168                } catch (Exception e) {
169                        StringBuilder sbErrMsg = new StringBuilder();
170                        sbErrMsg.append("ストレージへのファイルアップロードに失敗しました。updFolder:");
171                        sbErrMsg.append(updFolder);
172                        sbErrMsg.append(" updFileName:");
173                        sbErrMsg.append(updFileName);
174                        sbErrMsg.append(" errInfo:");
175                        sbErrMsg.append(e);
176                        throw new HybsSystemException(sbErrMsg.toString());
177                } finally {
178                        // クローズ処理
179                        Closer.ioClose(partInputStream);
180                }
181        }
182
183        /**
184         * ダウンロード
185         *
186         * @param filePath      ダウンロード対象のファイルパス
187         * @param hsession      セッション
188         * @return ストリーム
189         */
190        @Override
191        public InputStream get(String filePath, HttpSession hsession) {
192                InputStream is = null;
193                // ダウンロード
194                try {
195                        // パスをクラウド用に編集
196                        filePath = editPath(filePath);
197
198                        is = myConnection.retrieveObject(containerNm, filePath);
199
200                } catch (Exception e) {
201                        StringBuilder sbErrMsg = new StringBuilder();
202                        sbErrMsg.append("ストレージからのファイルダウンロードに失敗しました。filePath:");
203                        sbErrMsg.append(filePath);
204                        sbErrMsg.append(" errInfo:");
205                        sbErrMsg.append(e);
206                        throw new HybsSystemException(sbErrMsg.toString());
207                }
208
209                return is;
210        }
211
212        /**
213         * コピー
214         *
215         * @param oldFilePath   コピー元ファイルパス
216         * @param newFilePath   コピー先ファイルパス
217         * @param hsession              セッション
218         */
219        @Override
220        public void copy(String oldFilePath, String newFilePath, HttpSession hsession) {
221                InputStream is = null;
222                try {
223                        // パスをクラウド用に編集
224                        oldFilePath = editPath(oldFilePath);
225                        newFilePath = editPath(newFilePath);
226
227                        // コピー元から取得
228                        is = get(oldFilePath, hsession);
229                        // コピー先にアップロード
230                        add(is, newFilePath, "", hsession);
231
232                } catch (Exception e) {
233                        StringBuilder sbErrMsg = new StringBuilder();
234                        sbErrMsg.append("ストレージのファイルコピー処理に失敗しました。oldFilePath:");
235                        sbErrMsg.append(oldFilePath);
236                        sbErrMsg.append(" newFilePath:");
237                        sbErrMsg.append(newFilePath);
238                        sbErrMsg.append(" errInfo:");
239                        sbErrMsg.append(e);
240                        throw new HybsSystemException(sbErrMsg.toString());
241                }
242        }
243
244        /**
245         * 削除
246         *
247         * @param filePath      削除ファイルのパス
248         * @param hsession      セッション
249         */
250        @Override
251        public void delete(String filePath, HttpSession hsession) {
252                // 削除
253                try {
254                        // パスをクラウド用に編集
255                        filePath = editPath(filePath);
256
257                        // 削除処理
258                        myConnection.deleteObject(containerNm, filePath);
259                } catch (Exception e) {
260                        StringBuilder sbErrMsg = new StringBuilder();
261                        sbErrMsg.append("ストレージのファイル削除に失敗しました。filePath:");
262                        sbErrMsg.append(filePath);
263                        sbErrMsg.append(" errInfo:");
264                        sbErrMsg.append(e);
265                        throw new HybsSystemException(sbErrMsg.toString());
266                }
267        }
268
269        /**
270         * ファイル名変更
271         *
272         * @param filePath              ファイルパス
273         * @param oldFileName   変更前ファイル名
274         * @param newFileName   変更後ファイル名
275         * @param useBackup     変更後ファイル名が既に存在する場合のバックアップ作成フラグ
276         * @param hsession              セッション
277         */
278        public void rename(String filePath, String oldFileName, String newFileName, final boolean useBackup,
279                        HttpSession hsession) {
280                String newFilePath = filePath + newFileName;
281                String oldFilePath = filePath + oldFileName;
282
283                // 変更先のファイルが存在した場合の処理
284                if (exists(newFilePath, hsession)) {
285                        // バックアップ作成する場合
286                        if (useBackup) {
287                                // バックアップファイル名は、元のファイル名(拡張子含む) + "_" + 現在時刻のlong値 + "." +
288                                // 元のファイルの拡張子
289                                String bkupPath = filePath + "_backup/" + newFileName + "_" + System.currentTimeMillis()
290                                                + FileUtil.EXTENSION_SEPARATOR + FileUtil.getExtension(newFileName);
291                                // バックアップフォルダに移動
292                                copy(newFilePath, bkupPath, hsession);
293                        }
294                }
295
296                // コピー
297                copy(oldFilePath, newFilePath, hsession);
298                // 削除
299                delete(oldFilePath, hsession);
300        }
301
302        /**
303         * ファイル存在チェック
304         *
305         * @param filePath                      ファイルパス
306         * @param hsession              セッション
307         * @return                              true:存在 false:存在しない
308         */
309//      @Override
310        public boolean exists(String filePath, HttpSession hsession) {
311                boolean blnRtn = true;
312                try {
313                        // パスをクラウド用に編集
314                        filePath = editPath(filePath);
315
316                        try {
317                                myConnection.describeObject(containerNm, filePath);
318                        }catch(NoSuchObjectException noe) {
319                                // ファイル(オブジェクト)が存在しない場合
320                                blnRtn = false;
321                        }
322                } catch (Exception e) {
323                        StringBuilder sbErrMsg = new StringBuilder();
324                        sbErrMsg.append("ストレージのファイル取得に失敗しました。filePath:");
325                        sbErrMsg.append(filePath);
326                        sbErrMsg.append(" errInfo:");
327                        sbErrMsg.append(e);
328                        throw new HybsSystemException(sbErrMsg.toString());
329                }
330
331                return blnRtn;
332        }
333
334        /**
335         * ファイル一覧取得
336         *
337         * @param startsWith    パスの前方一致
338         * @param hsession              セッション
339         * @return                              ファイルパス一覧
340         */
341        @Override
342        public String[] list(String startsWith, HttpSession hsession) {
343                // 認証
344                List<String> rtnList = new ArrayList<String>();
345                try{
346                        // パスをクラウド用に編集
347                        startsWith = editPath(startsWith);
348
349                        Map<QueryOption, String> map = new HashMap<QueryOption, String>();
350                        map.put(QueryOption.PREFIX, startsWith);
351
352                        List<Key> list = myConnection.listObjects(containerNm, map);
353                        for(Key key: list) {
354                                rtnList.add(key.getKey());
355                        }
356
357                } catch (Exception e){
358                        StringBuilder sbErrMsg = new StringBuilder();
359                        sbErrMsg.append("ファイル一覧の取得に失敗しました。startsWith:");
360                        sbErrMsg.append(startsWith);
361                        sbErrMsg.append(" errInfo:");
362                        sbErrMsg.append("e");
363                        throw new HybsSystemException(sbErrMsg.toString());
364                }
365                return rtnList.toArray(new String[rtnList.size()]);
366        }
367
368        /**
369         * ファイル情報取得
370         *
371         * @param path                  ファイルパス
372         * @param hsession              セッション
373         * @return                              ファイル情報格納Map
374         */
375//      @Override
376        public Map<String, String> getInfo(String path, HttpSession hsession) {
377                Map<String, String> rtnMap = new HashMap<String,String>();
378
379                Key key = null;
380                try{
381                        // パスをクラウド用に編集
382                        path = editPath(path);
383
384                        // ファイルオブジェクトの取得
385                        key = myConnection.describeObject(containerNm, path);
386
387                }catch(Exception e){
388                        StringBuilder sbErrMsg = new StringBuilder();
389                        sbErrMsg.append("ファイルの取得に失敗しました。path:");
390                        sbErrMsg.append(path);
391                        sbErrMsg.append(" errInfo:");
392                        sbErrMsg.append(e);
393                        throw new HybsSystemException(sbErrMsg.toString());
394                }
395                SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddhhmmss");
396
397                // ファイルサイズ
398                rtnMap.put(FILEINFO_SIZE, String.valueOf(key.getSize()));
399                // 最終更新時刻
400                rtnMap.put(FILEINFO_LASTMODIFIED, sdf.format(key.getLastModified()));
401
402                return rtnMap;
403        }
404}