September 23, 2021

Uploading File to BIM360/ACC from Design Automation Through CLI

Uploading File to ACC Diagram

This sample show how to upload end result to desired folder in ACC project, if we know the Project and Folder Id, we can use two-legged authentication to create storage and version the upload file.

This sample demonstrates the use of WebSocket API and digital signing the activity

We need to prepare URL that design automation can put a file.

1. Create storage

 var objectId = await GetBIM360UploadObjectId(oauth);

  public async Task<string> GetBIM360UploadObjectId(dynamic oAuth)
        {

            string uploadUrl = string.Empty;

            //Create Storage.
            var projectsApi = new ProjectsApi { Configuration = { AccessToken = oAuth.access_token } };
            //1. We know our Hub, Project, and FolderId upfront.
            StorageRelationshipsTargetData storageRelData =
                    new StorageRelationshipsTargetData(StorageRelationshipsTargetData.TypeEnum.Folders, Specifications.FOLDERID);
            CreateStorageDataRelationshipsTarget storageTarget =
                new CreateStorageDataRelationshipsTarget(storageRelData);
            CreateStorageDataRelationships storageRel = new CreateStorageDataRelationships(storageTarget);
            BaseAttributesExtensionObject attributes =
                new BaseAttributesExtensionObject(string.Empty, string.Empty, new JsonApiLink(string.Empty), null);
            CreateStorageDataAttributes storageAtt = new CreateStorageDataAttributes(Specifications.FILENAME, attributes);
            CreateStorageData storageData =
                new CreateStorageData(CreateStorageData.TypeEnum.Objects, storageAtt, storageRel);
            CreateStorage storage =
                new CreateStorage(new JsonApiVersionJsonapi(JsonApiVersionJsonapi.VersionEnum._0), storageData);



            dynamic postStorageAsync = await projectsApi.PostStorageAsync(Specifications.PROJECTID, storage);
            try
            {
                string id = postStorageAsync.data.id;
                return id;
            }
            catch (ApiException e)
            {
                throw e.InnerException;
            }
        }

2. Extract the bucket and object key from the storage id. And, prepare a URL.

var match = Regex.Match(objectId, ".*:.*:(.*)/(.*)");
            var bucketName = match.Groups[1].Value;
            var objectName = match.Groups[2].Value;
            var UploadUrl = $"https://developer.api.autodesk.com/oss/v2/buckets/{bucketName}/objects/{objectName}";
            

 

Now you can pass the upload URL along Authorization to Design Automation workItem.

XrefTreeArgument uploadArg = new XrefTreeArgument()
            {
                Verb = Verb.Put,
                Url = UploadUrl,
                Headers = new Dictionary<string, string>()
                {
                    { "Authorization", "Bearer " + oauth.access_token }
                }
            }

 

Note, we need another step, we need to create a first version of this newly created file to see the affect in Bim360\ACC hub.

This we will create a version, once we know the Design Automation task completed successful.

3. Create a version.

 if (wsresp.Data.Status == Status.Success)
            {
                var fileId = await bucketHandler.CreateVersionFileAsync(objectId);
                Console.WriteLine($"\tSuccessfully Versioned : {fileId}");                
            }

We need to pass the objectId that we recieved when we create storage.

 public async Task<string> CreateVersionFileAsync(string objectId)
        {

            OAuthHandler.Create(config);
            dynamic oauth = await OAuthHandler.GetInternalAsync();
            ItemsApi itemsApi = new ItemsApi();
            itemsApi.Configuration.AccessToken = oauth.access_token;
            var itemBody = new CreateItem
            (
                new JsonApiVersionJsonapi
                (
                    JsonApiVersionJsonapi.VersionEnum._0
                ),
                new CreateItemData
                (
                    CreateItemData.TypeEnum.Items,
                    new CreateItemDataAttributes
                    (
                        DisplayName: Specifications.FILENAME,
                        new BaseAttributesExtensionObject
                        (
                            Type: "items:autodesk.bim360:File",
                            Version: "1.0"
                        )
                    ),
                    new CreateItemDataRelationships
                    (
                        new CreateItemDataRelationshipsTip
                        (
                            new CreateItemDataRelationshipsTipData
                            (
                                CreateItemDataRelationshipsTipData.TypeEnum.Versions,
                                CreateItemDataRelationshipsTipData.IdEnum._1
                            )
                        ),
                        new CreateStorageDataRelationshipsTarget
                        (
                            new StorageRelationshipsTargetData
                            (
                                StorageRelationshipsTargetData.TypeEnum.Folders,
                                Id: Specifications.FOLDERID
                            )
                        )
                    )
                ),
                new List<CreateItemIncluded>
                {
                    new CreateItemIncluded
                    (
                        CreateItemIncluded.TypeEnum.Versions,
                        CreateItemIncluded.IdEnum._1,
                        new CreateStorageDataAttributes
                        (
                            Specifications.FILENAME,
                            new BaseAttributesExtensionObject
                            (
                                Type:"versions:autodesk.bim360:File",
                                Version:"1.0"
                            )
                        ),
                        new CreateItemRelationships(
                            new CreateItemRelationshipsStorage
                            (
                                new CreateItemRelationshipsStorageData
                                (
                                    CreateItemRelationshipsStorageData.TypeEnum.Objects,
                                    objectId
                                )
                            )
                        )
                    )
                }
            );

            string itemId = "";
            try
            {
                DynamicJsonResponse postItemJsonResponse = await itemsApi.PostItemAsync(Specifications.PROJECTID, itemBody);
                var uploadItem = postItemJsonResponse.ToObject<ItemCreated>();
                Console.WriteLine("Attributes of uploaded BIM 360 file");
                Console.WriteLine($"\n\t{uploadItem.Data.Attributes.ToJson()}");
                itemId = uploadItem.Data.Id;
            }
            catch (ApiException ex)
            {
                //we met a conflict

                ErrorContent errorContent = JsonConvert.DeserializeObject<ErrorContent>(ex.ErrorContent);
                if (errorContent.Errors?[0].Status == "409")//Conflict
                {
                    //Get ItemId of our file
                    itemId = await GetItemIdAsync(oauth);

                    //Lets create a new version
                    itemId = await UpdateVersionAsync(objectId, oauth, itemId);
                }

            }
            return itemId;
        }

 

Uploading endresult from DA to ACC

 

Uploading File to ACC from DA using command line

The source is available on Github - https://github.com/MadhukarMoogala/UploadUtilFor-ACC

 

 

 

Posted by

Madhukar Moogala

A technology agnostic, constant learner, and a Forge advocate who works primarily on AutoCAD and Forge Design Automation using both desktop and cloud programming techniques. He has been with Autodesk since 2013, started his career as C++ programmer, explored everything that has come in his way be it Lisp or Wix, passionate about modern technologies and loves troubleshooting. 


In his free time...

Related Posts