    001package org.opengion.plugin.cloud;
    002
    003import java.io.ByteArrayInputStream;
    004import java.io.File;
    005import java.io.FileFilter;
    006import java.io.FileNotFoundException;
    007import java.io.IOException;
    008import java.io.InputStream;
    009import java.util.ArrayList;
    010import java.util.List;
    011
    012import org.opengion.fukurou.model.CloudFileOperation;
    013import org.opengion.fukurou.model.FileOperation;
    014import org.opengion.fukurou.model.FileOperationInfo;
    015import org.opengion.fukurou.util.StringUtil;
    016import org.opengion.hayabusa.common.HybsSystem;
    017import org.opengion.hayabusa.common.HybsSystemException;
    018
    019import com.microsoft.azure.storage.CloudStorageAccount;
    020import com.microsoft.azure.storage.blob.CloudBlob;
    021import com.microsoft.azure.storage.blob.CloudBlobClient;
    022import com.microsoft.azure.storage.blob.CloudBlobContainer;
    023import com.microsoft.azure.storage.blob.CloudBlobDirectory;
    024import com.microsoft.azure.storage.blob.CloudBlockBlob;
    025import com.microsoft.azure.storage.blob.ListBlobItem;
    026
    027/**
    028 * FileOperation_AZURE.javaは、Azureのストレージに対して、
    029 * ファイル操作を行うクラスです。
    030 *
    031 * @og.rev 5.10.8.0 (2019/02/01) 新規作成
    032 *
    033 * @version 5.0
    034 * @author  oota
    035 * @since   JDK7.0
    036 */
    037public class FileOperation_AZURE extends CloudFileOperation {
    038        private static final long serialVersionUID = 5108020190201L;
    039        /** クラス変数 */
    040        private final CloudBlobContainer azureContainer;
    041        private final String PLUGIN = "azure";
    042
    043        /**
    044         * コンストラクター
    045         *
    046         * 初期化処理です。
    047         * Azureの認証処理を行います。
    048         *
    049         * @param bucket バケット
    050         * @param inPath パス
    051         */
    052        public FileOperation_AZURE(final String bucket, final String inPath) {
    053                super( StringUtil.nval( bucket, HybsSystem.sys("CLOUD_BUCKET") ), inPath);
    054                setPlugin(PLUGIN);
    055
    056                String storageConnectionString = HybsSystem.sys("CLOUD_STORAGE_AZURE_KEY");
    057
    058                if (StringUtil.isNull(storageConnectionString)) {
    059                        String errMsg = "Azure用認証キー(CLOUD_STORAGE_AZURE_KEY)がシステムリソースに登録されていません。";
    060                        throw new HybsSystemException(errMsg);
    061                }
    062
    063                try {
    064                        CloudStorageAccount account = CloudStorageAccount.parse(storageConnectionString);
    065                        CloudBlobClient serviceClient = account.createCloudBlobClient();
    066                        azureContainer = serviceClient.getContainerReference(conBucket);
    067                        // コンテナが存在しない場合は作成する
    068                        azureContainer.createIfNotExists();
    069                } catch (Exception e) {
    070                        StringBuilder errMsg = new StringBuilder(HybsSystem.BUFFER_MIDDLE);
    071                        errMsg.append("コンテナの作成に失敗しました。container：").append(conBucket);
    072                        errMsg.append(" システムエラー情報：").append(e.getMessage());
    073                        throw new HybsSystemException(errMsg.toString());
    074                }
    075        }
    076
    077        /**
    078         * 書き込み処理
    079         *
    080         * InputStreamのデータを書き込みます。
    081         *
    082         * @param is 書き込みデータのInputStream
    083         * @throws IOException ファイル関連エラー情報
    084         */
    085        @Override
    086        public void write(final InputStream is) throws IOException {
    087                try {
    088                        CloudBlockBlob blob = azureContainer.getBlockBlobReference(conPath);
    089                        byte[] bytes = toByteArray(is);
    090                        ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
    091
    092                        blob.upload(bais, bytes.length);
    093                } catch (Exception e) {
    094                        StringBuilder errMsg = new StringBuilder(HybsSystem.BUFFER_MIDDLE);
    095                        errMsg.append("Azureストレージに書き込みが失敗しました。path：").append(conPath);
    096                        errMsg.append(" システムエラー情報：").append(e.getMessage());
    097                        throw new IOException(errMsg.toString());
    098                }
    099        }
    100
    101        /**
    102         * 読み込み処理
    103         *
    104         * データを読み込み、InputStreamとして、返します。
    105         *
    106         * @return 読み込みデータのInputStream
    107         * @throws FileNotFoundException ファイル非存在エラー情報
    108         */
    109        @Override
    110        public InputStream read() throws FileNotFoundException {
    111                CloudBlockBlob blob;
    112                InputStream is;
    113                try {
    114                        blob = azureContainer.getBlockBlobReference(conPath);
    115                        is = blob.openInputStream();
    116                } catch (Exception e) {
    117                        StringBuilder errMsg = new StringBuilder(HybsSystem.BUFFER_MIDDLE);
    118                        errMsg.append("Azureストレージから読み込みが失敗しました。path：").append(conPath);
    119                        errMsg.append(" システムエラー情報：").append(e.getMessage());
    120                        throw new FileNotFoundException(errMsg.toString());
    121                }
    122                return is;
    123        }
    124
    125        /**
    126         * 削除処理
    127         *
    128         * ファイルを削除します。
    129         *
    130         * @return 成否フラグ
    131         */
    132        @Override
    133        public boolean delete() {
    134                boolean flgRtn = false;
    135
    136                try {
    137                        azureContainer.getBlockBlobReference(conPath).delete();
    138                        flgRtn = true;
    139                } catch (Exception e) {
    140                        // エラーはスルーして、falseを返す
    141                }
    142
    143                return flgRtn;
    144        }
    145
    146        /**
    147         * コピー処理
    148         *
    149         * ファイルを指定先に、コピーします。
    150         *
    151         * @param afPath コピー先
    152         * @return 成否フラグ
    153         */
    154        @Override
    155        public boolean copy(final String afPath) {
    156                boolean flgRtn = false;
    157
    158                try {
    159                        CloudBlockBlob copyTrg = azureContainer.getBlockBlobReference(conPath);
    160                        CloudBlockBlob copySaki = azureContainer.getBlockBlobReference(afPath);
    161
    162                        copySaki.startCopy(copyTrg);
    163                        flgRtn = true;
    164                } catch (Exception e) {
    165                        // エラーはスルーして、falseを返す
    166                }
    167
    168                return flgRtn;
    169        }
    170
    171        /**
    172         * ファイルサイズ取得
    173         *
    174         * ファイルサイズを返します。
    175         *
    176         * @return ファイルサイズ
    177         */
    178        @Override
    179        public long length() {
    180                long rtn = 0;
    181
    182                try {
    183                        CloudBlob blob = azureContainer.getBlockBlobReference(conPath);
    184                        rtn = blob.getProperties().getLength();
    185                } catch (Exception e) {
    186                        // スルーして、0を返す
    187                }
    188                return rtn;
    189        }
    190
    191        /**
    192         * 最終更新時刻取得
    193         *
    194         * 最終更新時刻を取得します。
    195         *
    196         * @return 最終更新時刻
    197         */
    198        @Override
    199        public long lastModified() {
    200                long rtn = 0;
    201
    202                try {
    203                        CloudBlob blob = azureContainer.getBlockBlobReference(conPath);
    204                        rtn = blob.getProperties().getLastModified().getTime();
    205                } catch (Exception e) {
    206                        // スルーして、0を返す
    207                }
    208
    209                return rtn;
    210        }
    211
    212        /**
    213         * ファイル判定
    214         *
    215         * ファイルの場合は、trueを返します。
    216         *
    217         * @return ファイルフラグ
    218         */
    219        @Override
    220        public boolean isFile() {
    221                boolean blnRtn = false;
    222
    223                try {
    224                        CloudBlockBlob blob = azureContainer.getBlockBlobReference(conPath);
    225
    226                        if (blob.exists()) {
    227                                blnRtn = true;
    228                        }
    229                } catch (Exception e) {
    230                        // ここのエラーはスルーして、falseを返す
    231                }
    232
    233                return blnRtn;
    234        }
    235
    236        /**
    237         * ディレクトリ判定
    238         *
    239         * ディレクトリの場合は、trueを返します。
    240         *
    241         * @return ディレクトリフラグ
    242         */
    243        @Override
    244        public boolean isDirectory() {
    245                boolean blnRtn = false;
    246
    247                // 後尾に「/」をつけないこと
    248                for (ListBlobItem item : azureContainer.listBlobs(rTrim(conPath, '/'))) {
    249                        if (item instanceof CloudBlobDirectory) {
    250                                blnRtn = true;
    251                                break;
    252                        }
    253                }
    254
    255                return blnRtn;
    256        }
    257
    258        /**
    259         * ファイル一覧取得
    260         *
    261         * パスのファイルとディレクトリ一覧を取得します。
    262         *
    263         * @param filter フィルター情報
    264         * @return ファイルとティレクトリ一覧
    265         */
    266        @Override
    267        public File[] listFiles(final FileFilter filter) {
    268                if (!exists()) {
    269                        return new FileOperationInfo[0];
    270                }
    271
    272                String search = conPath;
    273                if (isDirectory()) {
    274                        search = setDirTail(conPath);
    275                }
    276
    277                List<File> rtnList = new ArrayList<File>();
    278
    279                for (ListBlobItem item : azureContainer.listBlobs(search)) {
    280                        if (item instanceof CloudBlob) {
    281                                // ファイルの情報を設定
    282                                CloudBlob blob = (CloudBlob) item;
    283                                FileOperationInfo fi = new FileOperationInfo(PLUGIN, conBucket, blob.getName());
    284                                fi.setLastModifiedValue(blob.getProperties().getLastModified().getTime());
    285                                fi.setSize(blob.getProperties().getLength());
    286                                fi.setFile(true);
    287                                rtnList.add(fi);
    288                        } else if (item instanceof CloudBlobDirectory) {
    289                                // ディレクトリの情報を設定
    290                                CloudBlobDirectory directory = (CloudBlobDirectory) item;
    291                                final String key = rTrim(directory.getPrefix(), '/');
    292                                FileOperationInfo fi = new FileOperationInfo(PLUGIN, conBucket, key);
    293                                fi.setDirectory(true);
    294                                rtnList.add(fi);
    295                        }
    296                }
    297
    298                File[] filterList = filter(rtnList, filter);
    299
    300                return filterList;
    301        }
    302
    303        /**
    304         * 親ディレクトリ取得
    305         *
    306         * 親のディレクトリを返します。
    307         *
    308         * @return 親のディレクトリ
    309         */
    310        @Override
    311        public FileOperation getParentFile() {
    312                return new FileOperation_AZURE(conBucket,getParent());
    313        }
    314
    315                /** 以下はローカル環境でのテスト用メソッドです。 */
    316//              /**
    317//               * ローカルでのテスト用コンストラクタ
    318//               *
    319//               * 要：super.bucketの値は固定値に変更してください。
    320//               *
    321//               * @param inPath
    322//               */
    323//              public FileOperation_AZURE(String bucket, String inPath, boolean test) {
    324//                      // super( StringUtil.nval( bucket, HybsSystem.sys("CLOUD_BUCKET") ), inPath);
    325//                      super( StringUtil.nval( bucket, "opengiontestbucket" ), inPath);
    326//                      conBucket = bucket;
    327//
    328//                      // ローカル環境で実行する場合の、proxy設定
    329//                      System.setProperty("https.proxyHost","mtc-px14");
    330//                      System.setProperty("https.proxyPort","8081");
    331//
    332//                      String storageConnectionString = "[接続文字列]";
    333//
    334//                      if (StringUtil.isNull(storageConnectionString)) {
    335//                              String errMsg = "Azure用認証キー(CLOUD_STORAGE_AZURE_KEY)がシステムリソースに登録されていません。";
    336//                              throw new HybsSystemException(errMsg);
    337//                      }
    338//
    339//                      try {
    340//                              CloudStorageAccount account = CloudStorageAccount.parse(storageConnectionString);
    341//                              CloudBlobClient serviceClient = account.createCloudBlobClient();
    342//                              azureContainer = serviceClient.getContainerReference(bucket);
    343//                              // コンテナが存在しない場合は作成する
    344//                              azureContainer.createIfNotExists();
    345//                      } catch (Exception e) {
    346//                              StringBuilder errMsg = new StringBuilder(HybsSystem.BUFFER_MIDDLE);
    347//                              errMsg.append("コンテナの作成に失敗しました。container：").append(bucket);
    348//                              errMsg.append(" システムエラー情報：").append(e.getMessage());
    349//                              throw new HybsSystemException(errMsg.toString());
    350//                      }
    351//              }
    352//
    353//              /** テスト用メソッド */
    354//              public static void main(String[] args) {
    355//      //              writeTest();
    356//      //              listTest();
    357//      //              methodTest();
    358//              }
    359//
    360//              public static void writeTest() {
    361//                      FileOperation file = new FileOperation_AZURE("", "sample/test.txt", true);
    362//
    363//                      try (InputStream is = new ByteArrayInputStream("sample".getBytes())) {
    364//                              file.write(is);
    365//                      } catch (Exception e) {
    366//                              System.out.println(e.getMessage());
    367//                      }
    368//              }
    369//
    370//              public static void listTest() {
    371//                      FileOperation file = new FileOperation_AZURE("", "sample", true);
    372//
    373//                      FileOperation[] list = file.listFiles();
    374//                      System.out.println(list.length);
    375//                      for (FileOperation f : list) {
    376//                              System.out.println(f.getPath());
    377//                      }
    378//              }
    379//
    380//              public static void methodTest() {
    381//                      FileOperation file = new FileOperation_AZURE("", "test", true);
    382//                      boolean rtn = false;
    383//                      rtn = file.isFile();
    384//
    385//                      System.out.println(rtn);
    386//              }
    387}