• If this is your first visit, be sure to check out the FAQ by clicking the link above. You may have to register before you can post: click the register link above to proceed. To start viewing messages, select the forum that you want to visit from the selection below.

Announcement

Collapse
No announcement yet.

[HELPED]Creating a web service using Valence API's in RPG

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • [HELPED]Creating a web service using Valence API's in RPG

    Is there a way to tap into Valence API's to create an RPG program that acts as a web service? For example, a customer accesses our www site and wants to retrieve an order status. Can that web site make an ajax call to a Valence RPG program to get a json response with the order status?
    Last edited by rkanemeier; 02-12-2015, 03:43 PM.

  • #2
    I'm sort of seeing a solution using the "launch web address" method.

    Comment


    • #3
      Any ajax request can call the Valence RPG programs, it's doesn't need to be the Valence user interface. This is a frequent use of Valence. All you need to do is make sure you decide how you want to handle security. You would either need to add a directive in your Apache instance config to allow your Valence RPG program to be called directly with no security or generate a session id and integrate the Valence security with your website.

      Comment


      • #4
        Great news! Is there some literature on generating session id's? I read up on the no-security example and that seems very plausible.

        Comment


        • #5
          This is actually exactly what I've been doing over the last couple of months. Here is a recap of what I've been doing and how.

          In my case, there are several systems that need access to our IBM i's data. Since I had to expose this information to the ExtJs GUI through Valence, I thought, "hummm, why not just let the other systems use the same valence REST API's?" So that is exactly what I did. Here is an image of what I envisioned my architecture to look like in regards to doing this.

          Valence Architecture Design Example.jpg

          After this, I went about implementing it. The first hurdle I ran into was with the session id's and secure tokens that Valence uses to ensure there is not any unauthorized use of the interface. The approach I wanted to take here was to force any external system that wanted to invoke an API to have to call an unsecured Valence RPG program that would log them into Valence, generate a session id, and then return the session id for them to use in subsequent calls. However, since the people accessing my system are all internal, none of them wanted to do that, so I had to find a solution to bypass the normal security mechanism.

          The solution that Rob and I came up with was to create a row in VVSESSDATA, which is where the session id is stored, and then give that session id to the external system for communication. This actually had a nice consequence because I gave each external system a different session id and due to this I could easily see the system that was invoking the service since the sid value passed in the call is the session id I assigned them. When creating this row it is important to use a value of *NONE in the VVTOKEN field, so that Valence doesn't try to enforce the token security mechanism that it normally would enforce from a user in the browser.

          Code:
          insert into valence41.vvsessdata
          (  VVSESSID, 
             VVTS_LOGIN,      
             VVTS_ACT,        
             VVUSRID,         
             VVENVID,         
             VVMETHOD,        
             VVSPLAUTH,       
             VVMODE,          
             VVTOKEN,         
             VVLIBLIST,       
             VVIBMIUSER,      
             VVCLIENTIP,      
             VVNEXTPOLL,      
             VVLNGID,         
             VVLOCK,          
             VVLOGINID,       
             VVENVNAME
          )
          Values(
             'SESSION_ID_BEING_CREATED',
             current_timestamp,
             current_timestamp,
             1001, --This is the user # assigned for the user that the API calls will run under.  Create if needed via Portal Admin
             1001, --Any valid Valence Environment # as shown on the Portal Admin Environment screen
             'IBMI',
             '',
             'desktop',
             '*NONE',
             (SELECT VVENVLIBL FROM valencecpm.vvenvs WHERE VVENVID = 1001), -- the library list value from VVENVS
             'USERID', --This should be the IBM i Userid for the application.  
             '10.0.0.1',
             'RELOAD',
             'en',
             '0',
             '',
             ''
          );
          I did run into a problem though because Valence will delete the rows out of vvsessdata after a set number of minutes of inactivity. To resolve that problem I set up a ROBOT job that is invoked every hour that updates the VVSESSDATA table so that the VVTS_ACT field has the current timestamp. This causes Valence to believe that the session is still actively being used, even if it may not truly be. You could use any method to run the below SQL at a set internal, ROBOT was just the easiest for my situation.

          Code:
           RUNSQL SQLSTRING('update valence40/vvsessdata set VVTS_ACT = current_timest
          amp WHERE VVTOKEN = ''*NONE''')
          In the portal admin you need to ensure that the userid that you used in the VVSESSDATA row has authority to use the Valence application. In my case I set up a unique userid just for this case called APIUSER. That way I could easily control the things that it could or could not do.

          After that point everything is set can you can call the API as follows:

          Code:
          http://host:7041/valence/vvcall.pgm?sid=SESSION_ID_BEING_CREATED&pgm=RPGPGM&action=theActionInTheRPGPGM&parameter1=value1&parameter2=value2&app=theAppId
          Just to cover the parts here.

          sid: This is the session id you assigned for them to use
          pgm: This is the name of your RPG program
          action: This is the action in the RPG program that you're wanting to invoke.
          parameters: You can pass as many parameters as needed to satisfy the parameters needed by the RPG program's action.
          app: The application id # as indicated in VVAPPS

          Now a word on security.

          If you allow external network access to your IBM i, you need to be very careful, because if a malicious party were to get ahold of one of the SID's you create then they can invoke any of the call's that the user you put into the VVSESSDATA row is allowed to call. If you only have internal network traffic it is not as worrisome unless you have requirements to restrict this type of access as well. The bottom line is if you can get your external systems to first invoke a login request to generate a session id, and then force them to use that session id it is best. The reason being is that then the session id will expire if it isn't used and you limit the potential impact if it falls into the wrong hands.

          I hope this helps some. If you have any questions feel free to hit me up.
          Tim
          Last edited by timchase01; 02-12-2015, 05:18 PM.

          Comment


          • #6
            Great info. There's also some additional technical info on this subject in the Valence Guide at:

            http://service.cnxcorp.com/valence-4...e020_Accessing

            Comment


            • #7
              Thanks for your post Tim. However, this would specifically be for external use. However, we would use Apache configuration that would only allow access to a specific library that contains all the programs and data files needed to perform the "services". Also, the "service account" (profile) that would be used would have absolutely no authority on our system except to the library and programs that perform the services. The only access this profile would have would be *USE.

              Comment

              Working...
              X