001package org.opengion.plugin.cloud;
002
003import java.io.File;
004import java.io.FileFilter;
005import java.io.FileNotFoundException;
006import java.io.IOException;
007import java.io.InputStream;
008import java.net.MalformedURLException;
009import java.util.ArrayList;
010import java.util.HashMap;
011import java.util.List;
012import java.util.Map;
013
014import org.apache.commons.lang3.StringUtils;
015import org.opengion.fukurou.model.CloudFileOperation;
016import org.opengion.fukurou.model.FileOperation;
017import org.opengion.fukurou.model.FileOperationInfo;
018import org.opengion.fukurou.util.Closer;
019import org.opengion.fukurou.util.StringUtil;
020import org.opengion.hayabusa.common.HybsSystem;
021import org.opengion.hayabusa.common.HybsSystemException;
022
023import oracle.cloud.storage.CloudStorage;
024import oracle.cloud.storage.CloudStorageConfig;
025import oracle.cloud.storage.CloudStorageFactory;
026import oracle.cloud.storage.exception.NoSuchContainerException;
027import oracle.cloud.storage.model.Key;
028import oracle.cloud.storage.model.QueryOption;
029import oracle.cloud.storage.model.QueryResult;
030
031/**
032 * FileOperation_ORACLE.javaは、Oracleクラウドのストレージに対して、
033 * ファイル操作を行うクラスです。
034 * 
035 * @og.rev 5.10.8.0 (2019/02/01) 新規作成
036 *
037 * @version 5.0
038 * @author oota
039 * @since JDK7.0
040 */
041public class FileOperation_ORACLE  extends CloudFileOperation {
042        private static final long serialVersionUID = 5108020190201L;
043        /** クラス変数 */
044        private final CloudStorage oracleStorage;
045        private final String PLUGIN = "oracle";
046        
047        /**
048         * コンストラクター
049         * 
050         * 初期化処理です。
051         * Oracleクラウドの認証処理を行います。
052         * 
053         * @param bucket バケット
054         * @param inPath パス
055         */
056        public FileOperation_ORACLE(final String bucket, final String inPath) {
057                super(StringUtil.nval( bucket, HybsSystem.sys("CLOUD_BUCKET") ),inPath);
058                setPlugin(PLUGIN);
059                
060                CloudStorageConfig config = new CloudStorageConfig();
061                
062                // リソースパラメータ設定
063                // サービス名
064                final String serviceName = HybsSystem.sys("CLOUD_STORAGE_ORACLE_SERVICE_NAME");
065                // ユーザ名
066                final String userName = HybsSystem.sys("CLOUD_STORAGE_ORACLE_USERNAME");
067                // パスワード
068                final String password = HybsSystem.sys("CLOUD_STORAGE_ORACLE_PASSWORD");
069                // サービスURL
070                final String serviceUrl = HybsSystem.sys("CLOUD_STORAGE_ORACLE_SERVICEURL");
071                
072                initCheck(serviceName, userName, password, serviceUrl);
073                
074                try {
075                        config.setServiceName(serviceName)
076                                .setUsername(userName)
077                                .setPassword(password.toCharArray())
078                                .setServiceUrl(serviceUrl);
079                        
080                        oracleStorage = CloudStorageFactory.getStorage(config);
081                        
082                        // コンテナの存在チェック
083                        try {
084                                oracleStorage.describeContainer(conBucket);
085                        }catch(NoSuchContainerException nce) {
086                                // コンテナが存在しない場合は、作成する
087                                oracleStorage.createContainer(conBucket);
088                        }
089                }catch(MalformedURLException me) {
090                        throw new HybsSystemException(me.getMessage());
091                }
092        }
093        
094        /**
095         * 初期チェック
096         * 
097         * パラメータの値チェックを行い、
098         * 未設定の場合はエラーを返します。
099         * 
100         * @param serviceName サービス名
101         * @param userName ユーザ名
102         * @param password パスワード
103         * @param serviceUrl サービスurl
104         */
105        private void initCheck(String serviceName, String userName, String password, String serviceUrl){
106                // システムリソースに認証情報が登録されていない場合は、エラー
107                StringBuilder errString = new StringBuilder();
108                if(StringUtils.isEmpty(serviceName)){
109                        errString.append("CLOUD_STORAGE_ORACLE_SERVICE_NAME");
110                }
111                if(StringUtils.isEmpty(userName)){
112                        errString.append(",CLOUD_STORAGE_ORACLE_USERNAME");
113                }
114                if(StringUtils.isEmpty(password)){
115                        errString.append(",CLOUD_STORAGE_ORACLE_PASSWORD");
116                }
117                if(StringUtils.isEmpty(serviceUrl)){
118                        errString.append(",CLOUD_STORAGE_ORACLE_SERVICEURL");
119                }
120
121                if(errString.length() > 0){
122                        throw new HybsSystemException("クラウドストレージのキー情報("+errString.toString()+")がシステムリソースに登録されていません。");
123                }
124
125        }
126        
127        /**
128         * 書き込み処理
129         * 
130         * InputStreamのデータを書き込みます。
131         * 
132         * @param is 書き込みデータのInputStream
133         * @throws IOException ファイル関連エラージョウホウ
134         */
135        @Override
136        public void write(InputStream is) throws IOException {
137                try {
138                        oracleStorage.storeObject(conBucket, conPath, "application/octet-stream", is);
139                }catch(Exception e) {
140                        StringBuilder errMsg = new StringBuilder(HybsSystem.BUFFER_MIDDLE);
141                        errMsg.append("Oracleストレージに書き込みが失敗しました。path:").append(conPath);
142                        errMsg.append(" システムエラー情報:").append(e.getMessage());
143                        throw new IOException(errMsg.toString());
144                }
145        }
146
147        /**
148         * 読み込み処理
149         * 
150         * データを読み込み、InputStreamとして、返します。
151         * 
152         * @return 読み込みデータのInputStream
153         * @throws FileNotFoundException ファイル非存在エラー情報
154         */
155        @Override
156        public InputStream read() throws FileNotFoundException {
157                InputStream is;
158                try {
159                        is = oracleStorage.retrieveObject(conBucket, conPath);
160                }catch(Exception e) {
161                        StringBuilder errMsg = new StringBuilder(HybsSystem.BUFFER_MIDDLE);
162                        errMsg.append("Oracleストレージから読み込みが失敗しました。path:").append(conPath);
163                        errMsg.append(" システムエラー情報:").append(e.getMessage());
164                        throw new FileNotFoundException(errMsg.toString());
165                }
166                return is;
167        }
168
169        /**
170         * 削除処理
171         * 
172         * ファイルを削除します。
173         * 
174         * @return 成否フラグ
175         */
176        @Override
177        public boolean delete() {
178                boolean flgRtn = false;
179                
180                try {
181                        oracleStorage.deleteObject(conBucket,  conPath);
182                        flgRtn = true;
183                }catch(Exception e) {
184                        // エラーはスルーして、falseを返す
185                }
186                
187                return flgRtn;
188        }
189
190        /**
191         * コピー処理
192         * 
193         * ファイルを指定先に、コピーします。
194         * 
195         * @param afPath コピー先
196         * @return 成否フラグ
197         */
198        @Override
199        public boolean copy(String afPath) {
200                boolean flgRtn = false;
201                InputStream is = null;
202                
203                try {
204                        is = read();
205                        FileOperation_ORACLE afFile = new FileOperation_ORACLE(conBucket,afPath);
206                        afFile.write(is);
207                        flgRtn = true;
208                }catch(IOException ie) {
209                        // エラーはスルーして、falseを返す
210                }finally {
211                        Closer.ioClose(is);
212                }
213                
214                return flgRtn;
215        }
216
217        /**
218         * ファイルサイズ取得
219         * 
220         * ファイルサイズを返します。
221         * 
222         * @return ファイルサイズ
223         */
224        @Override
225        public long length() {
226                long rtn = 0;
227                
228                try {
229                        rtn = oracleStorage.describeObject(conBucket, conPath).getSize();
230                }catch(Exception e) {
231                        // エラーはスルーして、0を返す
232                }
233                
234                return rtn;
235        }
236
237        /**
238         * 最終更新時刻の取得
239         * 
240         * 最終更新時刻を取得します。
241         * 
242         * @return 最終更新時刻
243         */
244        @Override
245        public long lastModified() {
246                long rtn = 0;
247                
248                try {
249                        rtn = oracleStorage.describeObject(conBucket, conPath).getLastModified().getTime();
250                }catch(Exception e) {
251                        // エラーはスルーして、0を返す
252                }
253                
254                return rtn;
255        }
256
257        /**
258         * ファイル判定
259         * 
260         * ファイルの場合は、trueを返します。
261         * 
262         * @return ファイルフラグ
263         */
264        @Override
265        public boolean isFile() {
266                boolean flgRtn = false;
267                
268                try {
269                        oracleStorage.describeObject(conBucket, conPath);
270                        flgRtn = true;
271                }catch(Exception e) {
272                        // ここでのエラーはスルーして、falseを返す
273                }
274                
275                return flgRtn;
276        }
277
278        /**
279         * ディレクトリ判定
280         * 
281         * ディレクトリの場合は、trueを返します。
282         * 
283         * @return ディレクトリフラグ
284         */
285        @Override
286        public boolean isDirectory() {
287                boolean blnRtn = false;
288                
289                if(StringUtil.isNull(conPath)) {
290                        return true;
291                }
292                
293                Map<QueryOption, String> map = new HashMap<QueryOption, String>();
294                map.put(QueryOption.PREFIX,  setDirTail(conPath));
295                
296                List<Key> list = oracleStorage.listObjects(conBucket, map);
297                if(list.size() > 0) {
298                        blnRtn = true;
299                }
300                
301                return blnRtn;
302        }
303
304        /**
305         * ファイル一覧取得
306         * 
307         * パスのファイルとディレクトリ一覧を取得します。
308         * 
309         * @return ファイルとティレクトリ一覧
310         */
311        @Override
312        public File[] listFiles(FileFilter filter){
313                if(!exists()) {
314                        return new File[0];
315                }
316                
317                String search = conPath;
318                if(isDirectory()) {
319                        search = setDirTail(conPath);
320                }
321                
322                List<File> rtnList = new ArrayList<File>();
323                
324                // 検索処理
325                QueryResult result = oracleStorage.listObjectsByPath(conBucket, "/", search, null);
326                
327                // ファイル情報の設定
328                for(Key trg: result.getKeys()) {
329                        String key = trg.getKey();
330                        
331                        FileOperationInfo fi = new FileOperationInfo(PLUGIN, conBucket, key);
332                        fi.setLastModifiedValue(trg.getLastModified().getTime());
333                        fi.setSize(trg.getSize());
334                        fi.setFile(true);
335                        rtnList.add(fi);
336                }
337                
338                // サブディレクトリ情報の設定
339                for(String path: result.getPaths()) {
340                        String key = rTrim(path, '/');
341                        
342                        FileOperationInfo fi = new FileOperationInfo(PLUGIN, conBucket, key);
343                        fi.setDirectory(true);
344                        rtnList.add(fi);
345                }
346                
347                File[] filterList = filter(rtnList, filter);
348                
349                return filterList;
350        }
351        
352        /**
353         * 親ディレクトリ情報取得
354         * 
355         * 親ディレクトリ情報を返します。
356         * 
357         * @return 親ディレクトリ情報
358         */
359        @Override
360        public FileOperation getParentFile() {
361                return new FileOperation_ORACLE(conBucket,getParent());
362        }
363        
364        /** 以下はローカル環境でのテスト用メソッドです。 */
365//              public FileOperation_ORACLE(String bucket, String inPath, boolean test) {
366//                      // super( StringUtil.nval( bucket, HybsSystem.sys("CLOUD_BUCKET") ), inPath);
367//                      super( StringUtil.nval( bucket, "opengiontestbucket" ), inPath);
368//                      conBucket = bucket;
369//                      
370//                      // proxy設定
371//                      System.setProperty("https.proxyHost","mtc-px14");
372//                  System.setProperty("https.proxyPort","8081");
373//                  
374//                      CloudStorageConfig config = new CloudStorageConfig();
375//                      // リソースパラメータ設定
376//                      final String serviceName = "[storage名]";
377//                      final String userName = "[userId]";
378//                      final String password = "[password]";
379//                      final String serviceUrl = "https://aucom-east-1.storage.oraclecloud.com";
380//                      
381//                      initCheck(serviceName, userName, password, serviceUrl);
382//                      
383//                      try {
384//                              config.setServiceName(serviceName)
385//                                      .setUsername(userName)
386//                                      .setPassword(password.toCharArray())
387//                                      .setServiceUrl(serviceUrl);
388//                              
389//                              oracleStorage = CloudStorageFactory.getStorage(config);
390//                              
391//                              // コンテナの存在チェック
392//                              try {
393//                                      oracleStorage.describeContainer(bucket);
394//                              }catch(NoSuchContainerException nce) {
395//                                      // コンテナが存在しない場合は、作成する
396//                                      oracleStorage.createContainer(bucket);
397//                              }
398//                      }catch(MalformedURLException me) {
399//                              throw new HybsSystemException(me.getMessage());
400//                      }
401//              }
402//              
403//              /** テスト用メソッド */
404//              public static void main(String[] args) {
405//      //              writeTest();
406//                      listTest();
407//      //              methodTest();
408//              }
409//      
410//              public static void writeTest() {
411//                      FileOperation file = new FileOperation_ORACLE("", "sample/test.txt", true);
412//      
413//                      try (InputStream is = new ByteArrayInputStream("sample".getBytes())) {
414//                              file.write(is);
415//                      } catch (Exception e) {
416//                              System.out.println(e.getMessage());
417//                      }
418//              }
419//      
420//              public static void listTest() {
421//                      FileOperation file = new FileOperation_ORACLE("", "sample", true);
422//      
423//                      FileOperation[] list = file.listFiles();
424//                      System.out.println(list.length);
425//                      for (FileOperation f : list) {
426//                              System.out.println(f.getPath());
427//                      }
428//              }
429//      
430//              public static void methodTest() {
431//                      FileOperation file = new FileOperation_ORACLE("", "test", true);
432//                      boolean rtn = false;
433//                      rtn = file.isFile();
434//      
435//                      System.out.println(rtn);
436//              }
437}