0

Autodesk のModel Derivative API.zipを使用して、ファイルをマニフェストに変換しようとしています。バケットを正常に作成し、チャンク アップロードを使用して zip をバケットに配置し、それぞれのエンドポイントを使用して翻訳ジョブを開始できます (すべてのエンドポイントが 200 を返します)。ジョブの翻訳進行状況を確認するようになると、「0% 完了」で停止し、最終的に の失敗メッセージが返されます。.svfTranslationWorker-InternalFailure

これはすべて、Node.js とスーパーエージェントのスタック上でプログラムによって行われ、HTTP リクエストが作成されます。Paw を使用して手動で翻訳することにより、ファイル自体が有効であることを確認できます。また、交換する古いツールで翻訳することもできます。

私のコードの特定のセクションについては、以下を参照してください。

Autodesk Translation ジョブ (エンドポイント)

translate: async function(accessToken, obj) {
    return await request.post('https://developer.api.autodesk.com/modelderivative/v2/designdata/job')
        .set("Authorization", "Bearer " + accessToken)
        .set("Content-Type", "application/json")
        .set('x-ads-force', true)
        .send({
            input: {
                urn: obj.base64Urn,
                compressedUrn: true,
                rootFilename: obj.parentFile
            },
            output: {
                formats: [
                    {
                        type: "thumbnail"
                    },
                    {
                        type: "svf",
                        views: ["2d", "3d"]
                    }
                ]
            }
        });
}

上記のコードでは、変数は次の値を持ちます。

  • obj.base64Urn次の関数を介して、オートデスクが提供する URN から動的に変換されます。

        base64Urn: function() {
            // https://tools.ietf.org/html/rfc7515#appendix-C
            return this.getDataValue("urn") != null ? (new Buffer(this.getDataValue("urn"))).toString('base64').replace(/=+$/g, "").replace(/\+/g, "-").replace(/[\/]/g, "_") : null;
        }
    
  • obj.parentFileの形をとる"160728 Small Test Project.rvt"

Autodesk Translation Progress (エンドポイント)

getTranslationProgressAndDerivatives: function(accessToken, obj) {
    return request.get('https://developer.api.autodesk.com/modelderivative/v2/designdata/' + obj.base64Urn + '/manifest')
        .set('Authorization', "Bearer " + accessToken);
}

もちろん、obj はある時点で Autodesk のサーバーに配置する必要があります。これは、次のコードによって実現されます。

Autodesk Put Object into Bucket (エンドポイント)

class HttpAutodeskPutObjectWriteStream extends stream.Writable {

    /**
     * Constructor sets all the properties for the instance.
     *
     * @param {string} accessToken - The OAuth2 access token needed for server authentication to engage with Autodesk's API.
     * @param {Obj} obj
     */
    constructor(accessToken, bucket) {
        super();
        this.accessToken = accessToken;
        this.obj = obj;
        this._bytesTransferred = 0;
        this._putHttpUrl = 'https://developer.api.autodesk.com/oss/v2/buckets/' + this.obj.name + '/objects/' + this.obj.name + '/resumable';
    }

    /**
     * Return a bytes transferred statement.
     *
     * @private
     *
     * @param chunk - The chunk currently being transferred.
     *
     * @returns {string}
     */
    _bytesTransferredStatement(chunk) {
        return `bytes ${this._bytesTransferred}-${this._bytesTransferred+chunk.byteLength-1}/${this.obj.zipFileSize}`;
    };

    /**
     * Writes data to the stream. Note the use of the serialize method in the request.
     *
     * @private
     *
     * @param chunk - The chunk currently being transferred.
     * @param encoding - The encoding of the chunk data.
     * @param callback - The function to be called on chunk completion (success or otherwise).
     *
     * @returns {Promise.<void>}
     */
    async _write(chunk, encoding, callback) {
        try {
            let stmt = this._bytesTransferredStatement(chunk);
            this._bytesTransferred += chunk.byteLength;

            let response = await request.put(this._putHttpUrl)
                .set("Authorization", "Bearer " + this.accessToken)
                .set("Session-Id", this.bucket.key)
                .set("Content-Length", chunk.byteLength)
                .set("Content-Range", stmt)
                .serialize(function(d) { return d; })
                .send(chunk.toString());

            if (response.status === 200) {
                this.urn = response.body.objectId;
            }
            callback(null);

        } catch (e) {
            callback(e);
        }
    };
}

次に、ここで呼び出されます。

put: function(accessToken, bucketEntity) {
    return new Promise(async (resolve, reject) => {
        const maximalChunkedTransferSize = 2*1024*1024; // 2MB (Minimum amount, Autodesk recommends 5MB).

        const objStorageLocation = (await config.get())[process.env.NODE_ENV].objStorageLocation;
        const pathToFile = path.join(__dirname, "../../", objStorageLocation, obj.name + ".zip");

        let readFileStream = fs.createReadStream(pathToFile, { highWaterMark: maximalChunkedTransferSize });

        let ws = new HttpAutodeskPutObjectWriteStream(accessToken, obj);
        readFileStream.pipe(ws);

        ws.on("finish", () => resolve(ws.urn));
        ws.on("error", () => reject());
    });
}

仕事に失敗したら…

失敗すると、これが翻訳進行エンドポイントから受け取る応答です。

{
    "type": "manifest",
    "hasThumbnail": "false",
    "status": "failed",
    "progress": "complete",
    "region": "US",
    "urn": "<redacted>",
    "version": "1.0",
    "derivatives": [
        {
            "name": "LMV Bubble",
            "hasThumbnail": "false",
            "status": "failed",
            "progress": "complete",
            "messages": [
                {
                    "type": "error",
                    "message": "Translation failure",
                    "code": "TranslationWorker-InternalFailure"
                }
            ],
            "outputType": "svf"
        }
    ]
}

ファイルを翻訳しようとしたときに 100% の失敗率になるような、明らかに間違ったことをしていますか?

4

1 に答える 1