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の使用は現在動作検証中です。検証が終わるまで今しばらくお待ちください……(終わったらここの表示が変わると思います……)




