Waiting for DeleteForgeAppAsync to proceed - autodesk-forge

I am using the Forge .NET SDK. To clear all appbundles and activities under my Forge App account I call :
await _designAutomation.DeleteForgeAppAsync("me");
Right afterwards I need to (re)create a new nickname for my Forge App then (re)create the needed AppBundle and Activity :
await _designAutomation.ForgeAppsApi.CreateNicknameAsync("me", new NicknameRecord { Nickname = NICKNAME });
await EnsureAppBundle();
await EnsureActivity();
Quite often one of three calls above fails because the Forge App is still being deleted, so for instance there is a conflict for the nickname creation, or the AppBundle/Activity cannot be created.
The Forge documentation at https://forge.autodesk.com/en/docs/design-automation/v3/reference/http/forgeapps-id-DELETE/ says : This may take up to 2 minutes. During this time the app will not be able to make successful requests.
Would not the asynchronous call to DeleteForgeAppAsync have to wait for the deletion to be complete ?
Thanks for your help.
Maxime

You could handle this scenario by doing retries on 409 response following a forge app deletion.
If you want to add more logic around 409 retries you could always also inspect the body.

Per documentation here you’d need to wait a few for the delete action to take effect despite the SDK API appears to be synchronous:
This may take up to 2 minutes. During this time the app will not be able to make successful requests.

Related

Postman interceptor request running forever

I am trying to intercept a website - https://www.kroger.com/pl/chicken/05002. In the chrome network tab, I see the request as below, with the details of the products nicely listed as JSON
I copied the cURL as bash and imported it as raw text in Postman. It ran forever without any response. Then I used the intercept feature and still it is running forever.
When both the requests are exactly same, why is it running in Chrome and not in Postman? What am i missing? Any help is appreciated, thanks in advance.
This is probably happening because they don't want you to do what you are trying to do. Note the "filter.verified" param in the URL.
You may want to try reaching out to them for an external API token - especially if you are creating an app or extension to compare competitive prices with the intention of distributing said app or extension - regardless of if it is for financial compensation or not.
Ethically questionable workaround (which would defintely need to be improved upon - this is simply an example of how you could solve your problem...):
GET https://www.kroger.com/search?query=chicken&searchType=default_search&fulfillment=all
const html = cheerio(responseBody);
var results = [];
html.find('div[class="AutoGrid-cell min-w-0"] > div').each(function (i, e)
{
results.push({
"Item": e.children[e.children.length-3].children[0].children[0].children[0]["data"],
"Price": e.children[e.children.length-4].children[0].attribs["value"]
})
});
console.log(results);
If you are unable to obtain an API token from them, this would probably be a legal way to accomplish what you want.

How to handle "Unexpected EOF at target" error from API calls?

I'm creating a Forge application which needs to get version information from a BIM 360 hub. Sometimes it works, but sometimes (usually after the code has already been run once this session) I get the following error:
Exception thrown: 'Autodesk.Forge.Client.ApiException' in mscorlib.dll
Additional information: Error calling GetItem: {
"fault":{
"faultstring":"Unexpected EOF at target",
"detail": {
"errorcode":"messaging.adaptors.http.flow.UnexpectedEOFAtTarget"
}
}
}
The above error will be thrown from a call to an api, such as one of these:
dynamic item = await itemApi.GetItemAsync(projectId, itemId);
dynamic folder = await folderApi.GetFolderAsync(projectId, folderId);
var folders = await projectApi.GetProjectTopFoldersAsync(hubId, projectId);
Where the apis are initialized as follows:
ItemsApi itemApi = new ItemsApi();
itemApi.Configuration.AccessToken = Credentials.TokenInternal;
The Ids (such as 'projectId', 'itemId', etc.) don't seem to be any different when this error is thrown and when it isn't, so I'm not sure what is causing the error.
I based my application on the .Net version of this tutorial: http://learnforge.autodesk.io/#/datamanagement/hubs/net
But I adapted it so I can retrieve multiple nodes asynchronously (for example, all of the nodes a user has access to) without changing the jstree. I did this to allow extracting information in the background without disrupting the user's workflow. The main change I made was to add another Route on the server side that calls "GetTreeNodeAsync" (from the tutorial) asynchronously on the root of the tree and then calls it on each of the returned children, then each of their children, and so on. The function waits until all of the nodes are processed using Task.WhenAll, then returns data from each of the nodes to the client;
This means that there could be many api calls running asynchronously, and there might be duplicate api calls if a node was already opened in the jstree and then it's information is requested for the background extraction, or if the background extraction happens more than once. This seems to be when the error is most likely to happen.
I was wondering if anyone else has encountered this error, and if you know what I can do to avoid it, or how to recover when it is caught. Currently, after this error occurs, it seems that every other api call will throw this error as well, and the only way I've found to fix it is to rerun the code (I use Visual Studio so I just rerun the server and client, and my browser launches automatically)
Those are sporadic errors from our apigee router due to latency issues in the authorization process that we are currently looking into internally.
When they occur please cease all your upcoming requests, wait for a few minutes and retry again. Take a look at stuff like this or this to help you out.
And our existing reports calling out similar errors seem to point to concurrency as one of the factors leading up to the issue so you might also want to limit your concurrent requests and see if that mitigate the issue.

Autodesk Forge register job conflict

When POSTing to https://developer.api.autodesk.com/viewingservice/v1/register I sometiems receive the following error:
{
Diagnostic: The request is rejected as it conflicts with a previous request that is in-progress.,
registerKeys: {},
Result: Conflict
}
How can I find out which job is already in progress so that I can track its progress and get its result?
First, this is the old API, you need to consider using the ModelDerivtive API instead (ie https://developer.autodesk.com/en/docs/model-derivative/v2)
Like Xiaodond said there is no API to collect all jobs currently processing on your account. You need to request each URN manifest to determine how many jobs runs on this model as know you can translate to SVF, but also export to other formats such as obj, stl, ... when it is possible. Manifest end point and documentation here - https://developer.autodesk.com/en/docs/model-derivative/v2/reference/http/urn-manifest-GET/
Last, we are working on a webhook solution which will be a better solution as a Webhook will call you back when a job is starting and completes. Webhooks aren't yet available at the time of this post, but you should be notified via the developer newsletter when it will be on production.
Hope that helps,

How to find out the availability status of a Web API from a Windows Store application

I have a Line-of-Business (LoB) Windows 8.1 Store application I developed for a client. The client side-loads it on several Windows 10 tablets. They use it in an environment where WiFi is spotty at best and they would like to get some sort of notification inside the app, regardless of what page they are on, notification that will let them know that they've lost connectivity to the network. I have created a method on my Web API that is not hitting the repository (database). Instead, it quickly returns some static information regarding my Web API, such as version, date and time of the invocation and some trademark stuff that I'm required to return. I thought of calling this method at precise intervals of time and when there's no response, assume that the Web API connectivity is lost. In my main page, the first one displayed when the application is started, I have the following stuff in the constructor of my view model:
_webApiStatusTimer = new DispatcherTimer();
_webApiStatusTimer.Tick += OnCheckWebApiStatusEvent;
_webApiStatusTimer.Interval = new TimeSpan(0, 0, 30);
_webApiStatusTimer.Start();
Then, the event handler is implemented like this:
private async void OnCheckWebApiStatusEvent(object sender, object e)
{
// stop the timer
_webApiStatusTimer.Stop();
// refresh the search
var webApiInfo = await _webApiClient.GetWebApiInfo();
// add all returned records in the list
if (webApiInfo == null)
{
var messageDialog = new MessageDialog(#"The application has lost connection with the back-end Web API!");
await messageDialog.ShowAsync();
// restart the timer
_webApiStatusTimer.Start();
}
}
When the Web API connection is lost, I get a nice popup message that informs me that the Web API is no longer available. The problem I have is that after a while, especially if I navigate away from the first page but not necessary, I get an UnauthorizedAccessException in my application.
I use the DispatcherTimer since my understanding is that this is compatible with
UI threads, but obviously, I still do something wrong. Anyone cares to set me on the right path?
Also, if you did something similar and found a much better approach, I'd love to hear about your solution.
Thanks in advance,
Eddie
First, If you are using Windows Store Apps, then you could possibly use a Background task to check poll for the status of the web api instead of putting this responsibility on your view model, its not the viewmodels concern
Second, if you are connecting from your Windows store app to your API then one successful authentication/ authorization for the first time, how and where do you store the token (assuming you are using token authentication). If you are (and ideally you should), is there a timer that you start which is set to the token expiration time? Is your local storage getting flushed somehow and loosing the aurthorization data?
Need more information.

VimeoUpload not re-authenticating After Deletion of App Access on Vimeo.com

I was able to connect and upload videos using the library but when I deleted the app connection on Vimeo.com (as a test) the app didn't authorize again.
the upload looks like it's working but nothing is uploaded as the app is no longer connected.
I deleted the app on the phone and restarted but it still won't re-authorize the app.
This comes up in the output:
Vimeo upload state : Executing
Vimeo upload state : Finished
Invalid http status code for download task.
And this is in OldVimeoUpload.swift: ( didn't include the actual access code!)
import Foundation
class OldVimeoUpload: VimeoUpload
{
static var VIMEO_ACCESS_TOKEN :String! // = "there's a string of numbers here"
static let sharedInstance = OldVimeoUpload(backgroundSessionIdentifier: "") { () -> String? in
return VIMEO_ACCESS_TOKEN // See README for details on how to obtain and OAuth token
}
// MARK: - Initialization
override init(backgroundSessionIdentifier: String, authTokenBlock: AuthTokenBlock)
{
super.init(backgroundSessionIdentifier: backgroundSessionIdentifier, authTokenBlock: authTokenBlock)
}
}
It looks like the access token number is commented out. I deleted the 2 forward slashes to see if that would fix it but it didn't.
I spoke too soon.
It sounds like you went to developer.vimeo.com and created an auth token. Used it to upload videos. And then went back to developer.vimeo.com and deleted the auth token.
The app / VimeoUpload will not automatically re-authenticated in this situation. You've killed the token and the app cannot request a new one for you. You'll need to create a new auth token and plug it into the app.
If this is not accurate and you're describing a different issue let us know.
If you inspect the error that's thrown from the failing request I'm guessing you'll see it's a 401 unauthorized related to using an invalid token.
Edit:
Disconnecting your app (as described in your comment below) has the same effect as deleting your auth token from developer.vimeo.com.
Also, VimeoUpload accepts a hardcoded auth token (as you see from the README and your code sample). It will not automatically re-authenticate, probably ever.
If you'd like to handle authentication in your app check out VimeoNetworking or VIMNetworking. Either of those libraries can be used to create a variety of authentication flows / scenarios. Still, if a logged in user disconnects or deletes their token, you will need them to deliberately re-authenticate (i.e. you will need to build that flow yourself). In that case, the user has explicitly stated that they don't want the app to be able to access information on their behalf. It would go against our security contract with them to automatically re-authenticate somehow.
Does that make sense?