AWS Lambdaでシーオーリポーツを使う
製品開発担当の大です。こんにちは。
今日は「Amazon S3にシーオーリポーツドキュメントがアップロードされたらPDF化して保存する」という例をご紹介します。
AWS Lambda
もうお気づきの方もいらっしゃると思いますが、これはAWS Lambdaのよくあるユースケースとして紹介されている「写真がアップロードされたらサムネイルを自動的に作成する」という例とほとんど同じです(笑)AWS Lambdaにはさまざまなトリガーが用意されており、S3の監視も設定するだけで行えます。とても楽ちんです。
今回はPDFを保存する先もS3にする(ただしシーオーリポーツドキュメントをアップロードするバケットとは別のバケットにする)ので、ロールを作成してLambda関数からS3に書き込みができるように設定しておきます。単純なサンプルのため、すでに用意されているポリシーの中からAmazonS3FullAccessとAWSLambdaBasicExecutionRoleを選びました。
ソースコード
Lambdaに登録する関数の本体はこのようになっています。シンプルですね。尚、依存関係として、aws-lambda-java-core、aws-lambda-java-events、aws-java-sdk-s3とシーオーリポーツを使用しています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | public class Handler implements RequestHandler<S3Event, String> { private static final String DST_BUCKET = "****-pdf" ; @Override public String handleRequest(S3Event event, Context context) { // イベント発生元のバケットとキーからシーオーリポーツドキュメントを取得します var record = event.getRecords().get( 0 ); var srcBucket = record.getS3().getBucket().getName(); var srcKey = record.getS3().getObject().getUrlDecodedKey(); var s3Client = AmazonS3ClientBuilder.defaultClient(); var s3Object = s3Client.getObject( new GetObjectRequest(srcBucket, srcKey)); var os = new ByteArrayOutputStream(); try (var is = s3Object.getObjectContent()) { // シーオーリポーツドキュメントを元にPDFデータを作成します createPdf(is, os); } catch (IOException ex) { throw new RuntimeException(ex); } var pdfData = os.toByteArray(); // PDFデータを保存用のS3バケットに書き出します if (pdfData.length > 0 ) { var meta = new ObjectMetadata(); meta.setContentLength(pdfData.length); meta.setContentType( "application/pdf" ); var is = new ByteArrayInputStream(pdfData); s3Client.putObject(DST_BUCKET, srcKey.replace( ".rsi" , ".pdf" ), is, meta); } return "OK" ; } private void createPdf(InputStream is, OutputStream os) { var job = new CrStreamOutJob(CorDocumentType.PDF, os); var draw = new CrDraw(); try (var bin = CrBinaryDocument.open(draw, is)) { job.start(draw); bin.printPages(); job.end(); } catch (CrException ex) { job.abort(); throw ex; } finally { draw.deleteInstance(); } } } |
これをAWS Lambdaのハンドラとして登録します。さきほど作成したロールもここで登録します。
パッケージング
今回はmaven shade pluginを使用してパッケージングし、Lambdaに登録しました。
シーオーリポーツのjarはmaven外なので、systemスコープにしてshadeに含めてもらうようにします。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | < build > < resources > < resource > < directory >${project.basedir}/src/main/resources</ directory > </ resource > < resource > < directory >${project.basedir}</ directory > < includes > < include >lib/*.jar</ include > </ includes > </ resource > </ resources > < plugins > < plugin > < groupId >org.apache.maven.plugins</ groupId > < artifactId >maven-shade-plugin</ artifactId > < version >3.2.2</ version > < configuration > < createDependencyReducedPom >false</ createDependencyReducedPom > </ configuration > < executions > < execution > < phase >package</ phase > < goals > < goal >shade</ goal > </ goals > </ execution > </ executions > </ plugin > </ plugins > </ build > < dependencies > < dependency > < groupId >jp.co.hos</ groupId > < artifactId >coreports</ artifactId > < scope >system</ scope > < version >3.1.1</ version > < systemPath >${project.basedir}/lib/coreports.jar</ systemPath > </ dependency > 以下略 </ dependencies > |
パッケージされたjarをAWS Lambdaの「関数コード」としてアップロードします。
実行
S3バケットにシーオーリポーツドキュメントを追加すると……
別のバケットにPDFが作成されましたね!
ところで
AWSでのシーオーリポーツ for Java V3の使用は現在動作検証中です。検証が終わるまで今しばらくお待ちください……(終わったらここの表示が変わると思います……)