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