9 Replies Latest reply on May 12, 2016 12:59 PM by gregor

    Delayed connection \ Reconnecting to PI database using PIAPI

    gsauer

      In order to increase the robustness of my proprietary interface I have been unable to establish a delayed connection or re-connection to PI database.  The interface is written in C++ and uses the PIAPI.  The interface itself works fine in normal operation which means with the database running and trust properly established it can connect, buffers and updates data without any problem:

       

       

      A simplified version of the steps followed are:

          1)  The interface stops and then restarts the PIBUFSS (this is to make sure the interface itself is loaded after the the buffering subsystem.

          2)   It then uses LoadLibrary(L"PIAPI32"); and gets handles to all of the functions to be used.

          3)   It then calls piut_setappidentity(...)

          4)   It then calls piut_setprocname(...)

          5)   It then calls piut_connect(...)

          6)  Followed by piut_login(Username, Password, &valid);

          7)  Read the PI points from the database:

                while (true) {

                       int32 rc = pipt_nextptwsourcelong(m_InterfaceName, &pt);

                       if (rc != 0) {

                       break;

                  }

           8)  Send updates

       

       

      To test the a delayed connection I disable the trust for the interface. I then follow steps 1) and 2) above.  Thereafter I call

      piut_netnodeinfo

      in order to check the connection which returns FALSE due to the trust failure.

      The interface then repeats waiting  a minute and doing a retry attempt by 1) FreeLibrary (on the PIAPI32) and then 2) a stop / start of the PIBUFSS then checking the connection with PIUT_NETNODEINFO.

       

      After enabling the trust, I can see that the connection seems to be ok.  I can even call PIBUFSS -cfg and see that the connections to primary and secondary database are registered but I am unable to complete the sequences 3) -> 8) above.

       

      I have to restart the interface, then everything runs.

       

      Any ideas? - and thanks for suggestions

        • Re: Delayed connection \ Reconnecting to PI database using PIAPI
          gregor

          Hello George,

           

          Please see our FAQ Q7 and note that PI API is explicitly excluded from being supported. If this is a recent development, I strongly suggest using AF SDK. With bulk calls you may even achieve better performance compared to PI API.

          Besides that I have some thoughts for troubleshooting that may help.

          Is your interface running as a service? Why don't you use a service dependency on PI Buffer Subsystem Service to ensure PI Buffer Subsystem is running when your interface starts?

          You say your interface uses a trust which is confirmed by step 5 piut_connect() but what is the reason for # 6 piut_login()? We recommend against using explicit user login because username and password are transferred unencrypted. If step # 5 is successful why would you want to connect again?

            • Re: Delayed connection \ Reconnecting to PI database using PIAPI
              gsauer

              Gregor,

              Thanks for your reply.  The PI API was chosen for the interface for a number of reasons.  First and foremost was that the PIBUFSS was supported at the time of development, not sure if PI SDK supports buffering today as I was told it was going to be at a later date.  The interface is incorporated in an application with quite a number of already existing other interfaces with an existing code base written in C++.  Mixing managed and unmanaged code was not desirable.

               

              The application with the interface is run as a service and it does have number of other dependencies which are as important for the drivers to work properly.  Turns out by controlling the start and stop of PIBUFSS service alleviated a number of problems (and was simple to do)

               

              I'm (still) pretty fresh with OSIsoft PI and find the security and authentication issues with mapping, identities and trust pretty confusing.  (I just recently found out that the PI-API does not support Windows Integrated Security (WIS) and only PI credentials.  I appreciate your comment and will investigate further.  Thanks

               

              George Sauer

              Technology & Innovation

              Oil and Gas Division

                         (E O SOL TI)

              Siemens A/S, Trondheim - Norway

              george.sauer@siemens.com<mailto:george.sauer@siemens.com>

              office (+47 93 21 05 06)

              mobile (+47 93 21 05 06)

              home (+47 72 59 09 77)

                • Re: Delayed connection \ Reconnecting to PI database using PIAPI
                  gregor

                  Hello George,

                   

                  Thank you for explaining why you've choosen PI API and please recognize and recall the smile in my face when reading further

                   

                  Since many years we tell our users that developing against PI API is not supported. Strictly spoken, I could argue that PI API was a bad choice because it's unsupported but we try to leave nobody behind which means that we will try to support you with your connection issue even you are using an officially unsupported Developer Technology. I however like to use the opportunity to strongly discourage from developing against PI API these days.

                   

                  PI SDK is announced to become deprecated too. It supports PI Buffer Subsystem as AF SDK does and I don't recall there was ever a problem with PI SDK supporting PI Buffer Subsystem. I believe to remember that PI SDK was never able to buffer through PI Buffer Server, the precursor of PI Buffer Subsystem.

                   

                  I read your initial post again and understand that you don't experience any issues with a valid PI trust in place. You also state that you are confused by the authentication options. The fact that Windows Integrated Security (WIS) is not supported is another argument against PI API. It's old technology and I expect we will be fading it out as soon as all PI Interfaces have been inherited by a PI Connector. Explicit login is considered a serious security vulnerability. Since a few years the PI Data Archive installs with Explicit login being disabled by default. This leaves the PI Trust as the only valid authentication option. Please do not use piut_login()

                   

                  Piut_setappidentity() is used to submit the application GUID and is a requirement when the GUID is supposed to be checked against the license file. It may make sense to take it off scope for testing purposes.

                  Piut_setprocname() is used to set an up to 8 characters long application name which again proofs PI API being a dinosaur. I don't expect any issues from using this function but for testing purposes you may want to remove it.

                   

                  Again, please remove # 6.

                   

                  You may want to look into using piut_setservernode() as an alternative to piut_connect()

                   

                  You mentioned that you are unloading PIAPI32.dll after a failed connection attempt. Loading a library at runtime is an alternative but unloading it as a part of the error handling is not necessary, I believe. 

                   

                  When you still experience connection issues or am uncertain, I suggest using pigetmsg.exe to continuously monitor the logs on the Interface node and the PI Data Archive node. Please see KB 324OSI8 for details.

                  1 of 1 people found this helpful
                    • Re: Delayed connection \ Reconnecting to PI database using PIAPI
                      gsauer

                      Gregor,

                       

                      Thanks for your time.

                       

                      The reason the piut_login() was to used to verify access level (PIREADWRITE)  as described in the help file documentation:

                      PI Connect

                       

                      Before making any other PI API calls, applications running on distributed nodes should connect with the pi Server in order to properly initialize the connection. This is accomplished with the functions piut_connect<mk:@MSITStore:C:\PCS7gateway\Diverse\PI%20help%20files\piapi.chm::/Functions/piut_connect.htm> or piut_setservernode<mk:@MSITStore:C:\PCS7gateway\Diverse\PI%20help%20files\piapi.chm::/Functions/piut_setservernode.htm>. piut_connect attempts a connection with the default PI home node and is passed a process name.

                       

                      If the connection is successful, the home node process name is set to the specified name. piut_setservernode attempts a connection with the specified node.

                       

                      If the connection is successful, the process name is set either to a system generated name or to the name previously specified with piut_setprocname<mk:@MSITStore:C:\PCS7gateway\Diverse\PI%20help%20files\piapi.chm::/Functions/piut_setprocname.htm>. A PINet version compatibility check is performed immediately after connection; if the versions are not compatible, the connection is aborted.

                       

                      After the initial connection, the piut_login<mk:@MSITStore:C:\PCS7gateway\Diverse\PI%20help%20files\piapi.chm::/Functions/piut_login.htm> call should be made telling the client and server what level of access to the server data is permitted. The calling program may wish to keep the login parameters for additional connections.

                       

                       

                       

                      On other thing I don’t quite understand is when the trust is disabled for the primary database in a HA collective I would assume that the secondary would also be disabled automatically (because one is unable to set it’s value in the PI System Management Tools)  Not sure how all of this works but end up with the primary being disconnected and the secondary registered.

                       

                       

                       

                       

                       

                       

                       

                       

                      This entire investigation is due a power outage where both interface node, primary and secondary database went down.  When the power came back on and automatic startup, the interface node started up before the archive databases and my interface was unable to connect until it was manually stopped and restarted.  Customer finds this unacceptable (which I agree with).  Therefore I have been trying to emulate situations where the connection goes down and then up again.  (I realize that it would be possible to store the last known point list on the interface node and start buffering data based on that instead of waiting for the PI database to “declare” all the interface points, however I prefer the current design and prefer to try and improve on known problems.)  Still would like to be able to create a work around not being able to start the buffering subsystem when there are corrupt queue files.

                       

                      I will be continuing my investigation and am very appreciative for your smiling comments.

                       

                      George Sauer

                      Technology & Innovation

                      Oil and Gas Division

                                 (E O SOL TI)

                      Siemens A/S, Trondheim - Norway

                      george.sauer@siemens.com<mailto:george.sauer@siemens.com>

                      office (+47 93 21 05 06)

                      mobile (+47 93 21 05 06)

                      home (+47 72 59 09 77)

                        • Re: Delayed connection \ Reconnecting to PI database using PIAPI
                          cramsey

                          Hello George-

                           

                          Gregor has given you sound advice.

                           

                          You should not call piut_connect() or piut_login(); instead call piut_setservernode(). That will establish a connection and use the trust for all security access. That is the call we use in our UniInt interfaces.

                           

                          In the core API we have:

                          piut_connect - connects to the default server with either a trust or with default user/no password.

                          piut_login - connect via explicit username/password - no dialogs available.

                          piut_setservernode - same as piut_connect, but allows specification of the server to connect to.

                          • Re: Delayed connection \ Reconnecting to PI database using PIAPI
                            gregor

                            Hello George,

                             

                            You are right, in a PI Data Archive Collective, disabling a PI Trust should become replicated from Primary to Secondary members. I am pretty certain that PI Base is maintaining a change record that becomes transferred to secondary nodes and replayed by the local PI Base Subsystem. However, if there's an issue with replicating changes you should see this in PI Collective Manager.

                             

                            I am not certain about the PI Connect documentation. I was able to have the search return a link but received a page not found when trying it. My understanding however is that piut_login() is for making explicit user logins.

                             

                            Well, power outages are bad. I believe if a servers operation is considered critical, it should be reasonable to install a UPS that would gracefully shutdown the server in case battery becomes low on power. A corrupted buffer queue can be repaired and usually it's possible to recover the majority of events from the queue. The point however is that PI Buffer Subsystem in most cases is still able to take and buffer new events. If a connection to the  PI Data Archive is not possible, having a local list of point ID's to fall back to us a valid strategy also referred to as disconnected startup by OSIsoft Interfaces supporting this. It's still not the great solution. One can think of different strategies how to assume good status when recovering from an ungraceful shutdown but in the end preventing ungraceful shutdowns might be the very best option.

                              • Re: Delayed connection \ Reconnecting to PI database using PIAPI
                                gsauer

                                Gregor,

                                 

                                It seems I have finally resolved my delayed connection issues.  I have done many different things and followed a lot of the advise and suggestions I have received.

                                 

                                One specific thing I did was use piut_setservernode() instead of piut_connect() as suggested by Clint Ramsey – not sure how major an issue that was in the end.

                                 

                                What I did do was attempt a systematic approach:

                                 

                                1)     Disabled the buffering subsystem (PIBUFSS disabled and configuration removed from INI files)

                                 

                                2)     Stopped the PI database completely (PISRVSTOP.BAT)

                                 

                                3)     Start my interface application on separate computer (connection to PLCs were active, but no connection to PI obviously)

                                 

                                4)     Waited 5-10 minutes and then started the PI database (PISRVSTART.BAT)

                                 

                                5)     Connect was established automatically and data transfer and updates took place as expected.

                                 

                                My conclusion was there must have been something wrong with the way I was handling the PIBUFSS.  My conclusions:

                                 

                                1)     Turns out that stopping and restarting the PIBUFSS service is not a very good idea.  The PI error messages report problems with allocation of 2  shared memory areas.

                                 

                                2)     I still do a STOP/RESTART of PIBUFSS when my interface starts, but only once.  Turns out that it is pretty good at detection and recovery situations. (Thanks Barry Shang)

                                 

                                3)     However with the PIBUFSS in place I found it difficult to determine if there is a real connection to the database or not.  I have seen that piut_netserverinfo()  return with a valid connection indication when in fact I didn’t have one.  Instead of relying on that I created my own local variable to monitor connection status based on RC function return values from other calls.

                                 

                                4)     To summarize, I STOP and then RESTART the PIBUFSS before initialization of the PIAPI in order to ensure the proper dependencies.   I trust the PIBUFFSS to connect when and if the database is available.  I then monitor the connection status with an internal variable.  If no connection is available or improper authentication I do a cyclic retry every 60 seconds until it is.

                                 

                                5)     With in place I am able to start my interface application without the PI database up and running and it connects properly when the database becomes available.  After the connection and initialization of all points I trust the known functionality of the buffering system to do the proper buffering if the database is stopped for maintenance or what not.

                                 

                                I am satisfied with the improvements I have made to the interface.  There is however one additional thing I would like to do which I know you most likely won’t approve of.  That is an option in the interface to flush (delete) the buffering subsystem queue file(s)  upon startup.  I’ve seen 3 times that the queue files were corrupt and the interface was unable to start due the fact PIBUFSS was unable to recover without manual intervention.  My thinking is normally the number of queued events is small and if an abrupt termination of system causes the queue files to become corrupt it would be better to just delete the files and avoid any manual recovery steps.  I couldn’t find the location of the buffering files in the Windows registry.  Where can I programmatically locate where the buffering files are located?

                                 

                                I’m going to mark the issue as resolved and again want to thank you and everyone else who contributed.

                                 

                                George Sauer

                                Technology & Innovation

                                Oil and Gas Division

                                           (E O SOL TI)

                                Siemens A/S, Trondheim - Norway

                                george.sauer@siemens.com<mailto:george.sauer@siemens.com>

                                office (+47 93 21 05 06)

                                mobile (+47 93 21 05 06)

                                home (+47 72 59 09 77)

                      • Re: Delayed connection \ Reconnecting to PI database using PIAPI
                        bshang

                        I think it is sufficient to just do steps 5-8. PI API will try to recover the connection automatically (as long as we've passed the reconnection throttling period) so there's no need for the prior steps.