Autodesk ForgeのウェブサイトがURL含めて最近大幅に変わっていて、チュートリアルも更新されています。今までは、NodeJSとかC#とかのチュートリアルしかなかったのですが、GoとかPHPなんかも増えています。JavaのSDKも少し前に出ていたらしいけれど、Servletをサンプルがしっかり公開されています。素晴らしい。
最近、Play Frameworkを触っていることもあってServletは避けたいなということで、Javaのライブラリを使ってScalaでサンプルを書いてみました。
forge-api-java-client
公式サイトはコチラです。基本的には、ForgeのREST APIのラッパーなのですが、同期的なAPIになっていたり、セッションの自動更新機能が実装されていたりで、結構使いやすい印象です(少なくともNodeJSよりは)。
ちなみに公式サイトのサンプルは、Servletのサンプルとは少し違った使い方で、単独アプリケーションであればこちらを参考にするのが正解と思います。
scalaプロジェクトの準備
例のごとくScalaプロジェクトを立ち上げて、build.sbtに依存関係を記載します。SBTを使った場合、だと、公式サイトに載っている参照だけだと失敗するので注意が必要です。
resolvers += Resolver.mavenLocal
// https://mvnrepository.com/artifact/com.autodesk/forge-java-sdk
libraryDependencies += "com.autodesk" % "forge-java-sdk" % "1.0.1"
libraryDependencies += "com.typesafe" % "config" % "1.3.2"
// https://mvnrepository.com/artifact/com.sun.jersey/jersey-core
libraryDependencies += "com.sun.jersey" % "jersey-core" % "1.9.1"
Forge APIの使い方
Forgeには、DataManagement API、ModelDerivative API、DesignAutomation APIなど色々とありますが、とりあえずはDataManagement APIを試してみます。その中でもOAuthとOSSへのアクセスをやってみます。
使い方としては、まず、2-Legged、3-LeggedなどのOAuth認証を、Forgeアプリで作成したIDとSecretから生成し、それを使って各種APIを介して、Forgeの機能にアクセスします。
ここで使われるのがBucketAPIとObjectAPIです。簡単化のために、接続用のクラスを作成します。なお、設定ファイルのアクセスにはTypesafe.configを利用します。
package forge
import java.io.File
import com.typesafe.config.ConfigFactory
import com.autodesk.client.ApiResponse
import com.autodesk.client.api.{BucketsApi, HubsApi, ObjectsApi}
import com.autodesk.client.auth.OAuth2TwoLegged
import com.autodesk.client.model._
import com.autodesk.client.model.PostBucketsPayload
import java.util
class Forge(scope:String) {
val configuration = ConfigFactory.load()
val clientId = configuration.getString("forge.CLIENT_ID")
val secret = configuration.getString("forge.CLIENT_SECRET")
val scopeInternal = configuration.getStringList("forge.scope.internal")
val scopePublic = configuration.getStringList("forge.scope.public")
// 最後の引数はトークンの自動更新
val oauth2TwoLegged = new OAuth2TwoLegged(clientId, secret, if (scope == "internal") scopeInternal else scopePublic , true)
val twoLeggedCredentials = oauth2TwoLegged.authenticate
def createBucket(payload: PostBucketsPayload, xAdsRegion:String)(implicit bucketsApi: BucketsApi) : ApiResponse[Bucket] = {
bucketsApi.createBucket(payload, "", oauth2TwoLegged, twoLeggedCredentials)
}
def getBuckets (region:String, limit:Integer, startAt:String)(implicit bucketsApi: BucketsApi) : ApiResponse[Buckets] = {
bucketsApi.getBuckets(region, limit, startAt, oauth2TwoLegged, twoLeggedCredentials)
}
def getBucketDetail(bucketkey: String)(implicit bucketsApi: BucketsApi): ApiResponse[Bucket] = {
bucketsApi.getBucketDetails(bucketkey, oauth2TwoLegged, twoLeggedCredentials)
}
def getObjects(bucketKey:String, limit:Int, beginsWith:String, startAt:String )(implicit objectsApi: ObjectsApi):ApiResponse[BucketObjects] = {
objectsApi.getObjects(bucketKey, limit, beginsWith, startAt, oauth2TwoLegged, twoLeggedCredentials)
}
def uploadObject(bucketKey:String, objectName:String, contentLength:Int, body:File, contentDisposition:String, ifMatch:String)(implicit objectsApi:ObjectsApi): ApiResponse[ObjectDetails] = {
objectsApi.uploadObject(bucketKey, objectName, contentLength, body, contentDisposition, ifMatch, oauth2TwoLegged, twoLeggedCredentials)
}
}
設定ファイルは例えば、以下のように設定します。
forge {
CLIENT_ID = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
CLIENT_SECRET = "xxxxxxxxxxxxxxxxxx"
scope {
internal = ["bucket:create", "bucket:read","bucket:create", "data:read", "data:create", "data:write"]
public = ["viewables:read"]
}
}
Bucketの生成・取得、Objectのアップロード・取得
上記のクラスを使って、それぞれの機能にアクセスしてみます。implicitを使っているので、少しはすっきりしているかと思います。
package forge
import com.autodesk.client.api.{BucketsApi, ObjectsApi}
import com.autodesk.client.model.PostBucketsPayload
import java.io.File
object ForgeTest {
def main(args: Array[String]) {
import scala.collection.JavaConversions._
val forge = new Forge("internal")
implicit val bucketsApi = new BucketsApi
implicit val objectsApi = new ObjectsApi
try {
// Backetを作る。Key既存のものと被らないように。
val payload = new PostBucketsPayload
payload.setBucketKey("test_bucket_key_180903")
payload.setPolicyKey(PostBucketsPayload.PolicyKeyEnum.TRANSIENT)
val createBucketResponse= forge.createBucket(payload, "")
println(createBucketResponse.getData.getBucketKey)
// Fileのアップロード
val file = new File("upload\\HelloWallIfc4.ifc")
val name = file.getName
val uploadObjectRes = forge.uploadObject(payload.getBucketKey, name, file.length().toInt, file, null, null)
println(uploadObjectRes.getStatusCode)
// Bucketをすべて取得する
val getBucketsResponse = forge.getBuckets(null, null, null)
getBucketsResponse.getData.getItems.foreach(bucket =>{
val getBucketsResponse =forge.getBucketDetail(bucket.getBucketKey)
println(getBucketsResponse.getData)
val getObjectsResponse = forge.getObjects(getBucketsResponse .getData.getBucketKey, 10, null, null)
getObjectsResponse.getData.getItems.foreach(obj => {
println(obj)
})
})
} catch {
case e: Exception =>
System.err.println("Exception when calling Forge APIs")
e.printStackTrace()
}
}
}
上記を実行すると以下のような出力が得られます。
class Bucket {
bucketKey: test_bucket_key_180903
bucketOwner: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
createdDate: 1535847337066
permissions: [class Permission {
authId: hxDJCnkcqjba9bUkuAUs7nm6DjZIE8HY
access: full
}]
policyKey: transient
}
class ObjectDetails {
bucketKey: test_bucket_key_180903
objectId: urn:adsk.objects:os.object:test_bucket_key_180903/HelloWallIfc4.ifc
objectKey: HelloWallIfc4.ifc
sha1: [B@5ef6ae06
size: 6033
contentType: null
location: https://developer.api.autodesk.com/oss/v2/buckets/test_bucket_key_180903/objects/HelloWallIfc4.ifc
}
#おわりに
NodeJSの場合は、簡単ではありますが非常にメンテナンス性が悪い印象がありました。こちらのAPIはまだ今後アップデートがありそうですが、結構使いやすいので、こちらをメインに使おうかなと考えています。