PASOE web transport: determining Handler URL in Handler clas

Posted by bronco on 09-Dec-2015 05:45

Hi, 

I'm trying to figure out what the handler url is in the handler class or to be more precise add is added to the handler url. When I add a handler I create a mapping, for example:

/ping --> PingWebHandler

If I use  IWebRequest:PathInfo then the /ping part is included as well. But I'm interested in what is *added* to /ping, since within the Handler I cannot make any assumptions about what the "mount point" is.

thanks.

Posted by mbanks on 09-Dec-2015 10:23

Would it work for your use case to use URI_FINAL_MATCH_GROUP?
 
request:GetContextValue("URI_FINAL_MATCH_GROUP")
 
For a request like
  http://localhost:8810/web/open/more/stuff
 
where the openedge.properties mapping is
 
  MyHandler: /open
 
URI_FINAL_MATCH_GROUP returns
 
   /more/stuff
 
-Mike
 
 
 

All Replies

Posted by Sanjeva Manchala on 09-Dec-2015 06:03

Hi,
 
You can specify the handler URLs at the time of creating/editing WebSpeed Service from PDS OE, these URLs are mapped to Handlers when we publish the service to PAS OE server. We can find this values in openedge.properties file under {DLCWRK}\oepas1\conf directory. Here is the sample hanlder information from openedge.properties when we publish the WebSpeed service to ROOT:
 
[oepas1.ROOT.WEB]
    adapterEnabled=1
    defaultCookieDomain=
    defaultCookiePath=
    defaultHandler=OpenEdge.Web.CompatibilityHandler
    handler1=DepartmentHandler: /SportsHandler/Department/{deptcode} ----> I have defined this for getting data (GET) from Handler
   handler2=DepartmentHandler: /SportsHandler/Department ----> I have defined this for Post/Update/Delete operation
    srvrAppMode=development
    srvrDebug=1
    wsRoot=/static/webspeed
 
If we publish the service as a WebApp, then these properties updated under separate WebApp as shown below:
[oepas1.<Web-App-Name>.WEB]
    adapterEnabled=1
    defaultCookieDomain=
    defaultCookiePath=
    defaultHandler=OpenEdge.Web.CompatibilityHandler
    handler1=DepartmentHandler: /SportsHandler/Department/{deptcode}
   handler2=DepartmentHandler: /SportsHandler/Department
    srvrAppMode=development
    srvrDebug=1
    wsRoot=/static/webspeed
 
When we invoke some URL from any client, then corresponding URL is validated with the values in openedge.properties file and proper response is shown in clinet.
 
Hope this helps,
Sanjeev.
 

Posted by Sanjeva Manchala on 09-Dec-2015 06:28

In your case,  “/ping” refers to that particular WebHandler (pingWebHandler). When you invoke any HTTP verb/method from REST client (say http://localhost:8810/web/ping), particular WebHanlder is called.
 
Hope this answers your question.
 
Thanks,
Sanjeev.
 

Posted by bronco on 09-Dec-2015 07:55

Well, not entirely. I'm trying to make a generic WebHandler which can mounted to any handler url. So /ping can be /foo or /foor/bar or whatever. Let's say I want to create a RestWebHandler. Inside the webhandler I want to be able to program something for /customer of /order of /customer/order. But since I have only the IWebRequest:PathInfo I don't know upfront if the RestWebHandler is mounted with /rest or /rest/web or /foor/bar. Imho, the handler url part shouldn't be in the PathInfo property (or there should another property).

Posted by Shelley Chase on 09-Dec-2015 08:03

There is a default web handler in the mapping file. Change that to be your class and all requests will come to your web handler. I am not sure if you will need to edit the mapping file or if you can do that through PDSOE.

Thanks

Shelley

Posted by bronco on 09-Dec-2015 08:06

So to clarify a bit more, inside the webhandler I want program something like:

case requestPath:

when "/customer" then ...

when "/order" then ...

otherwise ...

end case.

Now, how do I get requestPath? The only info I have is (afaik) PathInfo, but this includes the handler url part as well. What do I do if I don't want to force anyone to use a specific handler url?

 

 

Posted by Peter Judge on 09-Dec-2015 08:06

Take a look at the TransportPath and  WebAppPath  properties too. And there's always the URI.
Eg.
[15/12/09@08:59:09.051-0500] P-011612 T-010596 1 AS-10 -- (Procedure: 'HandleGet sports.ImageWebHandler' Line:145) TransportPath  /web
[15/12/09@08:59:09.051-0500] P-011612 T-010596 1 AS-10 -- (Procedure: 'HandleGet sports.ImageWebHandler' Line:146) ResolvedTransportPath  c:\devarea\pas\116\mediaresource\webapps\SportsSvc\img\Employee\7
[15/12/09@08:59:09.051-0500] P-011612 T-010596 1 AS-10 -- (Procedure: 'HandleGet sports.ImageWebHandler' Line:147) WebAppPath  /SportsSvc
[15/12/09@08:59:09.051-0500] P-011612 T-010596 1 AS-10 -- (Procedure: 'HandleGet sports.ImageWebHandler' Line:148) PathInfo  /img/Employee/7
[15/12/09@09:02:38.647-0500] P-014536 T-016268 1 AS-10 -- (Procedure: 'HandleGet sports.ImageWebHandler' Line:150) URI  localhost:8810/.../7
 
Don't forget about the GetPathParameter(<name>) method which gives you access to the parameters you set up when you create mapping .
Given
handler3=sports.ImageWebHandler: /img/Employee/{EmpNum}
You can get the value of the EmpNum token in a similar manner to
        /* URL is /web/img/Employee/{EmpNum} */
        iEmpNum = integer(poRequest:GetPathParameter('EmpNum':u)).
 
 
 
 
 
 

Posted by bronco on 09-Dec-2015 08:23

Here's the deal. I make the following call:

<hostname>:10000/app1/web/ping/bla/bla2?test=hoppa

WebAppPath: /app1

TransportPath: /web

PathInfo: /ping/bla/bla2

This last one because I said the /ping is handled by my PingWebHandler class. But I can say that /foo is handled by my PingWebHandler as well. In that case the PathInfo would be /foo/bla/bla2. To make things generic I'm not interesting in either the /ping of /foo part (this can be anything since it's a configuration thing), but in the /bla/bla2 part.

edit: rewrote the URL because a link was made out of it.

Posted by Irfan on 09-Dec-2015 08:46

In such cases where different URL's goes to same method, I generally use this code

poRequest:URI:TOSTRING () matches "*<stringname*"

based on the condition, I call a method that would do appropriate action by passing the poRequest to that method

Posted by bronco on 09-Dec-2015 09:00

That would be a solution, albeit an error prone one.

I think it would have been better solution if there was another property (in IWebRequest) called HandlerUrl en that the HandlerUrl part was *not* in PathInfo. A bit like express in node.js works. This way it would have been much easier to make generic code.

Posted by Peter Judge on 09-Dec-2015 09:04

 

This last one because I said the /ping is handled by my PingWebHandler class. But I can say that /foo is handled by my PingWebHandler as well. In that case the PathInfo would be /foo/bla/bla2. To make things generic I'm not interesting in either the /ping of /foo part (this can be anything since it's a configuration thing), but in the /bla/bla2 part.

Right now the unexpanded handler pattern/string is not available in the WebHandler. I had a quick chat with the developers and they say that it's feasible to make this info available (so add an idea or a bug).
 
The way I'd probably do it today would be to have an (abstract) type that does the work, and n derived handlers that knew which URL pattern they were responsible for handling. Something like the pseudo-stuff below.
 
Class GeneralHandler abstract
   Def prop URLPattern as char .
   Method handleget().
      Case this-object:URLPattern:
         When '/ping' then ...
   End method.
End class.
 
Class PingHandler inherits GeneralHandler
   Ctor PingHandler()
      This-object:URLPattern = '/ping'.
End class.
 
Class PongHandler inherits GeneralHandler
   Ctor PongHandler()
      This-object:URLPattern = '/pong'.
End class.
 
Openedge.properties
    handler1=PingHandler: /ping/{FirstToken}/slug/etc
    handler1=PongHandler: /pong/{FirstToken}/slug/etc
 
 
 

 

 
 

Posted by bronco on 09-Dec-2015 09:49

Thanks Peter, I will submit an enhancement request.

Posted by bronco on 09-Dec-2015 09:55

Answer to the original question: it is possible via workarounds, but not generically (yet). At least one workaround below in this thread.

EDIT: Mike Banks came up with the solution for my question. Above statement is no longer true.

Posted by mbanks on 09-Dec-2015 10:23

Would it work for your use case to use URI_FINAL_MATCH_GROUP?
 
request:GetContextValue("URI_FINAL_MATCH_GROUP")
 
For a request like
 
where the openedge.properties mapping is
 
  MyHandler: /open
 
URI_FINAL_MATCH_GROUP returns
 
   /more/stuff
 
-Mike
 
 
 

Posted by bronco on 10-Dec-2015 02:20

Yes! This is exactly what I'm looking for!

request:GetContextValue("URI_FINAL_MATCH_GROUP") is the correct answer. Thanks.

Posted by AdrianJones on 10-Dec-2015 05:05

is this documented anywhere?

Posted by mbanks on 10-Dec-2015 08:37

I'm afraid it may not be documented.

When a request is matched by the URI template in openedge.properties, the URI_FINAL_MATCH_GROUP contains the remaining parts of the URI that were not explicitly matched.

Posted by bronco on 10-Dec-2015 15:39

IMHO: the contents of URI_FINAL_MATCH_GROUP deserve a place in a) the documentation and b) IWebRequest.

What I noticed the in the PathParameterNames is name of URI_FINAL_MATCH_GROUP appears as  URI_FINAL_MATCH_GROUPFINAL_MATCH_GROUP, for which I logged an issue with techsupport. In ContextNames the name correctly is URI_FINAL_MATCH_GROUP. Speaking of which, what is the difference between PathParameterNames and ContextNames? They appear to be the same (apart from URI_FINAL_MATCH_GROUP).

Posted by mbanks on 10-Dec-2015 15:50

You should be able to get the path parameter without the URI prefix.  For example, GetPathParameter( "custnum" ) instead of GetContextValue( "URI_CUSTNUM" ).  The difference is that the path parameter names should be as defined in the URI template and the ones in the context have a URI prefix to set them apart from other context values.

Posted by Peter Judge on 11-Dec-2015 08:03

PathParameterNames will give you a list of the substitution tokens that you've set up in the handler URI
 
So if you have a handler for /Customers/{CustNum}/Orders/{ONum} then the PathParameterNames will return you CustNum,ONum.
 
The ContextNames property contains a list of all the available context/variables, which includes those used for the param names (which are prefixed by URI_). So in the absence of any others, you'll get URI_CUSTNUM,URI_ONUM  in the above example.
 
 
 
 

This thread is closed