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