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