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}