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とシーオーリポーツを使用しています。
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に含めてもらうようにします。
<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の使用は現在動作検証中です。検証が終わるまで今しばらくお待ちください……(終わったらここの表示が変わると思います……)