001package org.opengion.plugin.cloud; 002 003import java.io.InputStream; 004import java.text.SimpleDateFormat; 005import java.util.ArrayList; 006import java.util.HashMap; 007import java.util.List; 008import java.util.Map; 009 010import javax.servlet.http.HttpSession; 011 012import org.apache.commons.lang3.StringUtils; 013import org.opengion.fukurou.util.Closer; 014import org.opengion.fukurou.util.FileUtil; 015import org.opengion.hayabusa.common.HybsSystem; 016import org.opengion.hayabusa.common.HybsSystemException; 017import org.opengion.hayabusa.io.StorageAPI; 018 019import com.amazonaws.auth.AWSCredentials; 020import com.amazonaws.auth.AWSStaticCredentialsProvider; 021import com.amazonaws.auth.BasicAWSCredentials; 022import com.amazonaws.client.builder.AwsClientBuilder.EndpointConfiguration; 023import com.amazonaws.services.s3.AmazonS3; 024import com.amazonaws.services.s3.AmazonS3ClientBuilder; 025import com.amazonaws.services.s3.model.CopyObjectRequest; 026import com.amazonaws.services.s3.model.DeleteObjectRequest; 027import com.amazonaws.services.s3.model.ListObjectsV2Request; 028import com.amazonaws.services.s3.model.ListObjectsV2Result; 029import com.amazonaws.services.s3.model.ObjectMetadata; 030import com.amazonaws.services.s3.model.PutObjectRequest; 031import com.amazonaws.services.s3.model.S3Object; 032import com.amazonaws.services.s3.model.S3ObjectSummary; 033import com.microsoft.azure.storage.blob.BlobOutputStream; 034 035/** 036 * azure用のクラウドストレージ操作実装 037 * 038 * システムリソースのS3_ACCESS_KEY,S3_SECRET_KEY,S3_SERVICE_END_POINT,S3_REGIONに、AWSのキー情報を登録する必要があります。 039 * 040 * @og.group クラウド 041 * @og.rev (2018/02/15) 新規作成 042 * 043 * @version 5.0 044 * @author T.OTA 045 * @sinse JDK7.0 046 */ 047public class StorageAPI_aws implements StorageAPI { 048 // 認証文字列 049 // アクセスキー 050 private String s3AccessKey = ""; 051 // シークレットキー 052 private String s3SecretKey = ""; 053 // エンドポイント 054 private String s3ServiceEndPoint = ""; 055 // レギオン 056 private String s3Region = ""; 057 // バケット名(コンテナ名) 058 String s3bucket = ""; 059 060 AmazonS3 client = null; 061 062 /** 063 * コンストラクタ 064 * 065 * @param container 066 * @param hsession 067 */ 068 public StorageAPI_aws(String container, HttpSession hsession){ 069 // リソースパラメータ設定 070 // アクセスキー 071 s3AccessKey = HybsSystem.sys("CLOUD_STORAGE_S3_ACCESS_KEY"); 072 // シークレットキー 073 s3SecretKey = HybsSystem.sys("CLOUD_STORAGE_S3_SECRET_KEY"); 074 // エンドポイント 075 s3ServiceEndPoint = HybsSystem.sys("CLOUD_STORAGE_S3_SERVICE_END_POINT"); 076 // レギオン 077 s3Region = HybsSystem.sys("CLOUD_STORAGE_S3_REGION"); 078 // コンテナ名をs3bucketとして保持しておく 079 s3bucket = container; 080 081 // 初期チェック 082 initCheck(); 083 084 // AWSの認証情報 085 AWSCredentials credentials = new BasicAWSCredentials(s3AccessKey, s3SecretKey); 086 087 // エンドポイント設定 088 EndpointConfiguration endpointConfiguration = new EndpointConfiguration(s3ServiceEndPoint, s3Region); 089 090 // S3アクセスクライアントの生成 091 client = AmazonS3ClientBuilder.standard().withCredentials(new AWSStaticCredentialsProvider(credentials)) 092 .withEndpointConfiguration(endpointConfiguration).build(); 093 094 // S3に指定されたバケット(コンテナ)が存在しない場合は、作成する 095 if(!client.doesBucketExist(container)){ 096 client.createBucket(container); 097 } 098 } 099 100 /** 101 * 初期チェック 102 */ 103 private void initCheck(){ 104 // システムリソースに認証情報が登録されていない場合は、エラー 105 StringBuilder errString = new StringBuilder(); 106 if(StringUtils.isEmpty(s3AccessKey)){ 107 errString.append("CLOUD_STORAGE_S3_ACCESS_KEY"); 108 } 109 if(StringUtils.isEmpty(s3SecretKey)){ 110 errString.append(",CLOUD_STORAGE_S3_SECRET_KEY"); 111 } 112 if(StringUtils.isEmpty(s3ServiceEndPoint)){ 113 errString.append(",CLOUD_STORAGE_S3_SERVICE_END_POINT"); 114 } 115 if(StringUtils.isEmpty(s3Region)){ 116 errString.append(",CLOUD_STORAGE_S3_REGION"); 117 } 118 119 if(errString.length() > 0){ 120 throw new HybsSystemException("AWSのキー情報("+errString.toString()+")がシステムリソースに登録されていません。"); 121 } 122 123 } 124 125 /** 126 * アップロード 127 * 128 * @param partInputStream アップロード対象のストリーム 129 * @param updFolder アップロードフォルタ名 130 * @param updFileName アップロードファイル名 131 * @param hsession セッション 132 */ 133 @Override 134 public void add(InputStream partInputStream, String updFolder, String updFileName, HttpSession hsession) { 135 BlobOutputStream blobOutputStream = null; 136 try { 137 // アップロード処理 138 ObjectMetadata om = new ObjectMetadata(); 139 final PutObjectRequest putRequest = new PutObjectRequest(s3bucket, updFolder + updFileName, partInputStream,om); 140 // アップロード実行 141 client.putObject(putRequest); 142 143 } catch (Exception e) { 144 StringBuilder sbErrMsg = new StringBuilder(); 145 sbErrMsg.append("ストレージへのファイルアップロードに失敗しました。updFolder:"); 146 sbErrMsg.append(updFolder); 147 sbErrMsg.append(" updFileName:"); 148 sbErrMsg.append(updFileName); 149 sbErrMsg.append(" errInfo:"); 150 sbErrMsg.append(e); 151 throw new HybsSystemException(sbErrMsg.toString()); 152 } finally { 153 // クローズ処理 154 Closer.ioClose(blobOutputStream); 155 Closer.ioClose(partInputStream); 156 } 157 } 158 159 /** 160 * ダウンロード 161 * 162 * @param filePath ダウンロード対象のファイルパス 163 * @param hsession セッション 164 * @return ストリーム 165 */ 166 @Override 167 public InputStream get(String filePath, HttpSession hsession) { 168 InputStream is = null; 169 // ダウンロード 170 try { 171 S3Object object = client.getObject(s3bucket, filePath); 172 173 is = object.getObjectContent(); 174 } catch (Exception e) { 175 StringBuilder sbErrMsg = new StringBuilder(); 176 sbErrMsg.append("ストレージからのファイルダウンロードに失敗しました。filePath:"); 177 sbErrMsg.append(filePath); 178 sbErrMsg.append(" errInfo:"); 179 sbErrMsg.append(e); 180 throw new HybsSystemException(sbErrMsg.toString()); 181 } 182 183 return is; 184 } 185 186 /** 187 * コピー 188 * 189 * @param oldFilePath コピー元ファイルパス 190 * @param newFilePath コピー先ファイルパス 191 * @param hsession セッション 192 */ 193 @Override 194 public void copy(String oldFilePath, String newFilePath, HttpSession hsession) { 195 try { 196 final CopyObjectRequest copyRequest = new CopyObjectRequest(s3bucket, oldFilePath, s3bucket, newFilePath); 197 client.copyObject(copyRequest); 198 } catch (Exception e) { 199 StringBuilder sbErrMsg = new StringBuilder(); 200 sbErrMsg.append("ストレージのファイルコピー処理に失敗しました。oldFilePath:"); 201 sbErrMsg.append(oldFilePath); 202 sbErrMsg.append(" newFilePath:"); 203 sbErrMsg.append(newFilePath); 204 sbErrMsg.append(" errInfo:"); 205 sbErrMsg.append(e); 206 throw new HybsSystemException(sbErrMsg.toString()); 207 } 208 } 209 210 /** 211 * 削除 212 * 213 * @param filePath 削除ファイルのパス 214 * @param hsession セッション 215 */ 216 @Override 217 public void delete(String filePath, HttpSession hsession) { 218 // 削除 219 try { 220 final DeleteObjectRequest deleteRequest = new DeleteObjectRequest(s3bucket, filePath); 221 client.deleteObject(deleteRequest); 222 client.deleteObject(s3bucket, filePath); 223 } catch (Exception e) { 224 StringBuilder sbErrMsg = new StringBuilder(); 225 sbErrMsg.append("ストレージのファイル削除に失敗しました。filePath:"); 226 sbErrMsg.append(filePath); 227 sbErrMsg.append(" errInfo:"); 228 sbErrMsg.append(e); 229 throw new HybsSystemException(sbErrMsg.toString()); 230 } 231 } 232 233 /** 234 * ファイル名変更 235 * 236 * @param filePath ファイルパス 237 * @param oldFileName 変更前ファイル名 238 * @param newFileName 変更後ファイル名 239 * @param useBackup 変更後ファイル名が既に存在する場合のバックアップ作成フラグ 240 * @param hsession セッション 241 */ 242 public void rename(String filePath, String oldFileName, String newFileName, final boolean useBackup, 243 HttpSession hsession) { 244 String newFilePath = filePath + newFileName; 245 String oldFilePath = filePath + oldFileName; 246 247 // 変更先のファイルが存在した場合の処理 248 if (exists(newFilePath, hsession)) { 249 // バックアップ作成する場合 250 if (useBackup) { 251 // バックアップファイル名は、元のファイル名(拡張子含む) + "_" + 現在時刻のlong値 + "." + 252 // 元のファイルの拡張子 253 String bkupPath = filePath + "_backup/" + newFileName + "_" + System.currentTimeMillis() 254 + FileUtil.EXTENSION_SEPARATOR + FileUtil.getExtension(newFileName); 255 // バックアップフォルダに移動 256 copy(newFilePath, bkupPath, hsession); 257 } 258 } 259 260 // コピー 261 copy(oldFilePath, newFilePath, hsession); 262 // 削除 263 delete(oldFilePath, hsession); 264 } 265 266 /** 267 * ファイル存在チェック 268 * 269 * @param filePath ファイルパス 270 * @param hsession セッション 271 * @return true:存在 false:存在しない 272 */ 273// @Override 274 public boolean exists(String filePath, HttpSession hsession) { 275 boolean blnRtn = true; 276 try { 277 if (!client.doesObjectExist(s3bucket, filePath)) { 278 // ファイルが取得できなかった場合は、falseを設定 279 blnRtn = false; 280 } 281 } catch (Exception e) { 282 StringBuilder sbErrMsg = new StringBuilder(); 283 sbErrMsg.append("ストレージのファイル取得に失敗しました。filePath:"); 284 sbErrMsg.append(filePath); 285 sbErrMsg.append(" errInfo:"); 286 sbErrMsg.append(e); 287 throw new HybsSystemException(sbErrMsg.toString()); 288 } 289 290 return blnRtn; 291 } 292 293 /** 294 * ファイル一覧取得 295 * 296 * @param startsWith パスの前方一致 297 * @param hsession セッション 298 * @return ファイルパス一覧 299 */ 300 @Override 301 public String[] list(String startsWith, HttpSession hsession) { 302 // 認証 303 List<String> rtnList = new ArrayList<String>(); 304 try{ 305 ListObjectsV2Request request = new ListObjectsV2Request() 306 .withBucketName(s3bucket) 307 .withPrefix(startsWith); 308 ListObjectsV2Result list = client.listObjectsV2(request); 309 List<S3ObjectSummary> objects = list.getObjectSummaries(); 310 // 一覧の取得 311 for(S3ObjectSummary obj: objects){ 312 // 名称を格納 313 rtnList.add(obj.getKey()); 314 } 315 } catch (Exception e){ 316 StringBuilder sbErrMsg = new StringBuilder(); 317 sbErrMsg.append("ファイル一覧の取得に失敗しました。startsWith:"); 318 sbErrMsg.append(startsWith); 319 sbErrMsg.append(" errInfo:"); 320 sbErrMsg.append("e"); 321 throw new HybsSystemException(sbErrMsg.toString()); 322 } 323 return rtnList.toArray(new String[rtnList.size()]); 324 } 325 326 /** 327 * ファイル情報取得 328 * 329 * @param path ファイルパス 330 * @param hsession セッション 331 * @return ファイル情報格納Map 332 */ 333// @Override 334 public Map<String, String> getInfo(String path, HttpSession hsession) { 335 Map<String, String> rtnMap = new HashMap<String,String>(); 336 337 ObjectMetadata meta = null; 338 try{ 339 // ファイルオブジェクトの取得 340 meta = client.getObjectMetadata(s3bucket, path); 341 }catch(Exception e){ 342 StringBuilder sbErrMsg = new StringBuilder(); 343 sbErrMsg.append("ファイルの取得に失敗しました。path:"); 344 sbErrMsg.append(path); 345 sbErrMsg.append(" errInfo:"); 346 sbErrMsg.append(e); 347 throw new HybsSystemException(sbErrMsg.toString()); 348 } 349 SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddhhmmss"); 350 351 // ファイルサイズ 352 rtnMap.put(FILEINFO_SIZE, String.valueOf(meta.getContentLength())); 353 // 最終更新時刻 354 rtnMap.put(FILEINFO_LASTMODIFIED, sdf.format(meta.getLastModified())); 355 356 return rtnMap; 357 } 358}