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