Credential Expiration

Hey all,

I'm hoping someone can point me in the right direction. I have a window service that uses the projectwise APi to login, connect to a datasource, preform various operations to get data from projectwise, including copying files out of the system, then it logs off. 

This generally works, but we're having an intermittent problem where it seems our service is being presented with a dialog and thus ceases operation. 

The reason I know this is that here is what the stack looks like for the thread in our service that halts because of this dialog.

win32u.dll!NtUserWaitMessage+0x14
USER32.dll!DialogBoxIndirectParamAorW+0x403
USER32.dll!DialogBoxIndirectParamAorW+0x1b3
USER32.dll!SoftModalMessageBox+0x228b
USER32.dll!MessageBoxW+0x348
USER32.dll!MessageBoxTimeoutW+0xd5
USER32.dll!MessageBoxW+0x4e
DMACTRL.dll!aaApi_ShowMessageBox+0x111
dmawin.dll!aaOApi_GetVersionLockCount+0x5bb
dmsapicl.dll!dmsNetRegisterDisconnectCallback+0x34
dmsapicl.dll!dmsNetConnectsReConnect+0x10c0
dmsapicl.dll!dmsExecSelectExt+0xb6
dmsapicl.dll!dmsExecSelect+0x126
dmscli.dll!aaApi_SqlSelect+0xb5
0x0000000000000000
[Native Frame: IL Method without Metadata]
[Managed to Unmanaged Transition]
D:\ILG_Services\Close\ProjectWise.dll!ProjectWise.PWInterface.GetDatabaseServerName+0x4a
D:\ILG_Services\Close\ProjectWise.dll!ProjectWise.ExportProject.SetDocumentXMLNodes+0xbcb

Doing some debugging in windbg with a memory dump from our process, I see this string in the thread memory that is likely the message that's presented in the dialog we can't see.

We've changed the credential policy for the account we use to "no expiration". We've also changed the setting to Not show dialogs. Nether seems to have worked here.  We do have quite few data sources and this service will connect to each of them if there is data to export, but it will only operate on one at time. 

I've opened a case with support today, but havne't heard back yet. I'd appreciate any suggestions on where to look next to get this taken care of. It's really hindering our processing of these projects.

Thanks 

Parents
  • We're still trying to figure out what might be going on here. Support says they're looking for a solution internally.

    I've verified that all our data sources have No Expiration set for the account in question.

    We've been unable to make this happen reliably outside of the service it happens in, which is making it very hard to troubleshoot. Sometimes this process takes a long time as there are lots of documents to go through for some projects. Which is why we made sure to use the NoExpiration setting for the PW user we're using.

    The pseudocode for how we use the API is as follows. We have a wrapper class made up of static dllimport declarations to the SDK and also wrappers that end up calling static members. 

    aaApi_Initialize(0)

    aaApi_AdminLogin(specifying PW Logical account and a datasource)

    activedatasource = aaApi_GetActiveDatasource(); //used later to logoff.

    //do make other api calls like these. These are sometimes wrapped in a c# class, sometimes called more directly via dllimport. 

    aaApi_GetProjectNamePath2
    aaApi_GetDocumentCount
    aaApi_SelectProject
    aaApi_GetProjectStringProperty
    aaApi_SelectDocument
    aaApi_GetDocumentNumericProperty
    aaApi_SelectUser
    aaApi_GetUserStringProperty

    //after we're done, we dispose of our wrapper object using Dispose() in our class. The dispose method calls.

    aaApi_LogoutByHandle(activedatasource);

    aaApi_Uninitialize();

    //Then the whole thing repeats again for another project, if needed. 

  • David,

    I don't have a solution for you, I'm just curious.

    Is there a reason why your customization could not be run on a schedule, rather than as a service?  And if that might work for you, you might also consider using PowerShell (via PWPS_DAB) as that might be a bit easier to maintain or tweak.

    As for your service, in our group we have used the PWSession Class found in MostOfDavesClasses in several services and haven't experience the problem you are having.  Perhaps the approached used by that Class might be worth exploring.

    You can get MostOfDavesClasses from here:
    https://github.com/DaveBrumbaugh/MostOfDavesClasses-CSharp-Wrappers-For-ProjectWise 

    You will need to distribute the included .dll's in order to use all of the methods.

    Here's a snippet showing how we have used it in a service:

    try
    {
        using (PWSession pws = new PWSession(sDatasource, sUserName, sUnencryptedPassword))
        {
            foreach (DataRow drSub in drSubmissions)
            {
    			...
            } // for each document in drSubmission
    }
    catch (Exception ex)
    {
        SomeLoggingClass.WriteLog("Error: {0}\n{1}", ex.Message, ex.StackTrace);
    }

  • Hey Dan,

    thanks for the reply. Much appreciated! That GitHub repo looks to be very useful and I've been reviewing it. We are handling login\logout very similarly. 

    After some more experimentation, it seems the issue boils down to this. Our service can be engaging in long running operations that don't involve interaction with projectwise. The way it's coded now is that when it begins an operation, it logs into the datasource and performs some operations, but after that there could be gaps of time (perhaps 10's of minutes) where the connection to projectwise is not used. 

    In my experimentation, if you log on with the API, then sit idle for more than 13-15 minutes, the connection to projectwise is terminated by the server. Meaning, the TCP connection on port 5800 is lost as the server sent a RST, ACK packet. . After that, if you try to proceed with an operation, assuming you're logged in, it will fail.

    We would expect the connection to remain open, but for some reason the server is terminating it if it's idle. 

    So it seems given this behavior we need to re-code the projecwise interaction to login-->do projectwise specific operations-->logout and repeat when necessary.  

    Unless, there is a more nuanced way that would involve less re-coding. Maybe some sort of "keep alive" algorithm we could employ. Or is there a server side setting controlling this?

    Lastly, support did tell me that you can get rid of the login dialog if you use aaAPI_SetModuleFlags. That works fine, but obviously doesn't solve the connection issue. 

  • David,

    There are some settings that can be changed on the server (dmskrnl.cfg file), but they would affect all connections, or at least all ProjectWise Explorer connections.  I'm not sure what effect changing these settings would have on a connection opened via an API call.  If your PW Administrators are OK with changing those settings (or if you have a development system), you could tweak some of those settings to see if doing so resolves your timeout issue.

    Search the ProjectWise Administrator help for "timeout", or just go to ProjectWise Administrator > Managing ProjectWise Servers and Services > Server Configuration Settings (dmskrnl.cfg) > Section Defines General Server Configuration Information.

    The two settings most likely to be affecting your code are TimeOut and UserLoginTokenTimeout, but there might be others.

    Answer Verified By: David Hahn 

  • Hey Dan,

    Thanks for this. yea, the TimeOut setting seems to be the setting that effects the behavior with our code. 

    Another option might be to utilize SSO instead of a logical PW login. SSO logins seem to behave differently in that if the connection is timed out, it will be established again without calling Login again. What might be the downfall of using SSO in this context?

  • I can't say that I am aware of any downfalls of SSO for services.  Obviously, since the OS user is signing into ProjectWise and running as a service, that OS user needs to be able to run as a service, and probably needs to have a ProjectWise working directory already created since the user would be prompted to create it on login, which of course isn't an option for user attempting to login from a service.

Reply Children
No Data