[11:14:14 CDT(-0500)] <EricDalquist> athena: looks like you're handling pull 44?
[11:15:21 CDT(-0500)] <athena> hey eric
[11:15:22 CDT(-0500)] <athena> yes
[11:15:29 CDT(-0500)] <athena> think they're going to refactor that using the existing library
[11:15:42 CDT(-0500)] <athena> i've also written a factory for those jaxb elements
[11:15:48 CDT(-0500)] <athena> so they're less painful and verbose to create in xml
[11:15:56 CDT(-0500)] <EricDalquist> cool
[11:16:50 CDT(-0500)] <athena> by the way, did you ever experiment with ways to call a portal REST service from a portlet?
[11:16:59 CDT(-0500)] <EricDalquist> yes
[11:17:01 CDT(-0500)] <EricDalquist> it is possible
[11:17:03 CDT(-0500)] <EricDalquist> but gross
[11:17:14 CDT(-0500)] <athena> i seem to remember you writing a portlet that called the portal's portlet list service
[11:17:15 CDT(-0500)] <athena> gotcha
[11:17:19 CDT(-0500)] <EricDalquist> yeah
[11:17:29 CDT(-0500)] <athena> did your portlet re-use the portal session?
[11:17:34 CDT(-0500)] <EricDalquist> yes
[11:17:37 CDT(-0500)] <EricDalquist> so here is the concept"
[11:18:35 CDT(-0500)] <EricDalquist> you create a servlet (spring spring servlet controller). This servlet does a cross-context lookup for the portal context then creates a request dispatcher for that context with the rest API uri
[11:19:36 CDT(-0500)] <EricDalquist> the servlet uses a response wrapper to capture ALL of the output (to prevent mucking with the portlet's response)
[11:20:00 CDT(-0500)] <EricDalquist> the servlet then sets the response data in some sort of request attribute data structure
[11:20:17 CDT(-0500)] <EricDalquist> your portlet code can create a request dispatcher to talk to that custom servlet
[11:20:23 CDT(-0500)] <EricDalquist> so ...
[11:20:26 CDT(-0500)] <athena> that makes sense
[11:20:49 CDT(-0500)] <athena> would it make sense for us to have a reusable library for that logic?
[11:21:11 CDT(-0500)] <EricDalquist> PortletController -> PortletRequestDispatcher.include -> PortalProxyingServlet -> PortalContextLookup -> RequestDisptacher.include ->
[11:21:20 CDT(-0500)] <EricDalquist> if we want to encourage this
[11:21:21 CDT(-0500)] <EricDalquist> yes
[11:21:25 CDT(-0500)] <athena> well
[11:21:26 CDT(-0500)] <EricDalquist> we would have to do a resuable lib
[11:21:30 CDT(-0500)] <EricDalquist> it would be insane otherwise
[11:21:33 CDT(-0500)] <athena> yeah.
[11:21:39 CDT(-0500)] <athena> i guess the question is whether we want to encourage it
[11:21:42 CDT(-0500)] <EricDalquist> we would also need to standardize on the data returned
[11:21:45 CDT(-0500)] <EricDalquist> yeah
[11:21:52 CDT(-0500)] <EricDalquist> I'm not sure what our alternatives are :/
[11:22:00 CDT(-0500)] <EricDalquist> this is good because it never leaves tomcat
[11:22:03 CDT(-0500)] <athena> but it seems like there's a legitimate use case for wanting to query the portal's person directory, permission store, etc.
[11:22:11 CDT(-0500)] <EricDalquist> so you avoid self-call issues
[11:22:19 CDT(-0500)] <athena> and seems like REST services are a reasonable way to do it
[11:22:19 CDT(-0500)] <EricDalquist> the other option
[11:22:24 CDT(-0500)] <EricDalquist> is we create a resuable library
[11:22:28 CDT(-0500)] <EricDalquist> that just does direct API calls
[11:22:43 CDT(-0500)] <EricDalquist> just a sec ...
[11:23:09 CDT(-0500)] <athena> would a library that does direct API calls really work? wouldn't we need to recreate all the XML config?
[11:23:37 CDT(-0500)] <EricDalquist> no
[11:23:50 CDT(-0500)] <EricDalquist> so what we would do is define truly public APIs
[11:24:05 CDT(-0500)] <EricDalquist> this API jar would live in tomcat/shared/lib
[11:24:19 CDT(-0500)] <EricDalquist> when uPortal starts up it would bootstrap this API jar by injecting an implementation
[11:24:32 CDT(-0500)] <EricDalquist> wait
[11:24:36 CDT(-0500)] <EricDalquist> ignore that 2nd line
[11:24:46 CDT(-0500)] <EricDalquist> so we would create an API jar and it would live in shared/lib
[11:25:04 CDT(-0500)] <athena> gotcha
[11:25:09 CDT(-0500)] <athena> yeah, that makes sense
[11:25:11 CDT(-0500)] <EricDalquist> then the portal would provide impls of this API as PortalContext attributes
[11:25:18 CDT(-0500)] <athena> of course, that requires a bunch of planning and design effort
[11:25:27 CDT(-0500)] <athena> that i bet we don't actually have the resources to do right now
[11:25:42 CDT(-0500)] <EricDalquist> so you could do:
[11:25:43 CDT(-0500)] <EricDalquist> PersonDir pd = (PersonDir)portalContext.getAttribute("org.jasig.portal.personDirectory");
[11:25:46 CDT(-0500)] <EricDalquist> right
[11:25:52 CDT(-0500)] <athena> though that does sound like a nice architectural plan
[11:25:53 CDT(-0500)] <EricDalquist> but it would provide isolation from portlets
[11:25:58 CDT(-0500)] <EricDalquist> and be sane to support
[11:25:59 CDT(-0500)] <athena> yeah
[11:26:09 CDT(-0500)] <EricDalquist> the danger with all of this is if we don't commit to doing that work
[11:26:14 CDT(-0500)] <EricDalquist> we WILL hate ourselves in 2 years
[11:26:19 CDT(-0500)] <EricDalquist> and it will be painful
[11:26:53 CDT(-0500)] <athena> yeah
[11:27:02 CDT(-0500)] <athena> and it would be really nice to have person directory and group support for our portlets
[11:27:45 CDT(-0500)] <EricDalquist> so you mean getting attributes for users other than the curent user
[11:27:50 CDT(-0500)] <EricDalquist> and doing more than role checking?
[11:27:56 CDT(-0500)] <EricDalquist> because if we expose that
[11:28:03 CDT(-0500)] <EricDalquist> we really need to get permissioning in place as well
[11:28:11 CDT(-0500)] <EricDalquist> or we're going to have security problems
[11:29:04 CDT(-0500)] <athena> well, we already have a REST feed that does that
[11:29:07 CDT(-0500)] <athena> and it does check user permissions
[11:29:18 CDT(-0500)] <athena> that's how the uMobile native app's directory works
[11:29:19 CDT(-0500)] <EricDalquist> yup
[11:29:31 CDT(-0500)] <athena> it contacts the /people.json service using it's existing portal session
[11:29:53 CDT(-0500)] <athena> and that filters results by VIEW_USER and VIEW_USER_ATTRIBUTE
[11:30:08 CDT(-0500)] <athena> so drew's use case is to do something similar, but from a portlet
[11:30:29 CDT(-0500)] <athena> seems like a reasonable use case for messaging portlets, etc. as well
[11:30:36 CDT(-0500)] <EricDalquist> yup
[11:31:03 CDT(-0500)] <EricDalquist> so our API via request attribute approach could still call the controllers
[11:31:14 CDT(-0500)] <athena> yeah - it sounds like that would work today
[11:31:16 CDT(-0500)] <EricDalquist> especially if the controller doesn't actually need the req/req
[11:31:18 CDT(-0500)] <EricDalquist> req/res
[11:31:35 CDT(-0500)] <athena> i think it does, so that it can check the session?
[11:32:52 CDT(-0500)] <EricDalquist> hrm
[11:33:04 CDT(-0500)] <EricDalquist> what is the controller for that rest feed?
[11:35:17 CDT(-0500)] <athena> PeopleRESTController.java
[11:35:59 CDT(-0500)] <EricDalquist> hrm
[11:36:04 CDT(-0500)] <EricDalquist> yeah that needs req and res
[11:39:52 CDT(-0500)] <athena> yeah - i think most of our services would
[11:40:10 CDT(-0500)] <athena> if they didn't need a session we could just make a normal call and skip all the session handling stuff
[11:44:27 CDT(-0500)] <drewwills> hey folks – sorry, was in a mtg
[11:50:17 CDT(-0500)] <drewwills> I can enhance the rest controllers to optionally permit localhost traffic
[11:50:25 CDT(-0500)] <drewwills> w/o a session
[11:50:37 CDT(-0500)] <EricDalquist> that won't work
[11:50:40 CDT(-0500)] <EricDalquist> at least not portably
[11:50:57 CDT(-0500)] <EricDalquist> for example our portal isntances can't talk to themselves on localhost
[11:50:57 CDT(-0500)] <EricDalquist> or on the portal's host name
[11:51:09 CDT(-0500)] <drewwills> and btw I really like the path of leveraging the REST apis b/c we're already putting so much good investment there
[11:51:10 CDT(-0500)] <EricDalquist> as an artifact of how our hardware load balancer networking gear works
[11:51:29 CDT(-0500)] <EricDalquist> did you read the logs of our chat drewwills?
[11:51:35 CDT(-0500)] <drewwills> i did
[11:52:14 CDT(-0500)] <drewwills> i aslo like the requestDispatcher – as opposed to httpClient – method
[11:52:48 CDT(-0500)] <drewwills> and fwiw our immediate use cases are slightly less ugly b/c I'll be making these calls from spring WEB wvc
[11:53:32 CDT(-0500)] <drewwills> i think... catching up w/ myself here... thinking and typing at the same time
[11:54:20 CDT(-0500)] <drewwills> can't a portllet get a cross-context requestDispatcher anyway?
[11:55:02 CDT(-0500)] <EricDalquist> well remember the httpclient method is NOT portable
[11:55:02 CDT(-0500)] <EricDalquist> and not something we can include/distribute due to that
[11:55:14 CDT(-0500)] <EricDalquist> ok
[11:55:36 CDT(-0500)] <EricDalquist> so a portlet can't directly do cross-context
[11:55:41 CDT(-0500)] <EricDalquist> but it can via a servlet in the same webapp
[11:56:01 CDT(-0500)] <EricDalquist> PortletController -> PortletRequestDispatcher.include -> PortalProxyingServlet -> PortalContextLookup -> RequestDisptacher.include -> RestController
[11:56:21 CDT(-0500)] <drewwills> roger
[11:56:26 CDT(-0500)] <EricDalquist> we could encapsulate "-> PortletRequestDispatcher.include -> PortalProxyingServlet -> PortalContextLookup -> RequestDisptacher.include -> RestController" in a stand alone library
[11:57:17 CDT(-0500)] <EricDalquist> we would also need to figure out what data type would be returned
[11:57:27 CDT(-0500)] <drewwills> so when that request comes in, what does the session look like from the persspective of the rest controller portal-side?
[11:57:37 CDT(-0500)] <drewwills> is it the user's actual httpsession?
[11:57:38 CDT(-0500)] <EricDalquist> it is the user's portal session
[11:57:45 CDT(-0500)] <drewwills> rock & roll
[11:57:52 CDT(-0500)] <EricDalquist> I think we could encapsulate this enough to have it be a plain old API
[11:58:03 CDT(-0500)] <EricDalquist> give me 10 minutes to chat with JimH here in my office
[11:58:03 CDT(-0500)] <drewwills> that would automatically filter appropriately, correct?
[11:58:05 CDT(-0500)] <EricDalquist> and we can talk more about it
[11:58:16 CDT(-0500)] <drewwills> i need to hit a mtg too
[11:58:20 CDT(-0500)] <drewwills> bb in 1 hr or less
[13:07:58 CDT(-0500)] <drewwills> back from my mtg, if there's more ground to cover
[13:08:16 CDT(-0500)] <EricDalquist1> yes
[13:08:20 CDT(-0500)] <EricDalquist1> but I just sat down to eat
[13:08:25 CDT(-0500)] <EricDalquist1> give me 15 minutes or so
[13:08:27 CDT(-0500)] <EricDalquist1> and we cn chat a bit more
[13:08:40 CDT(-0500)] <drewwills> lol, i'd like to give you more than 15 min to eat
[13:08:54 CDT(-0500)] <drewwills> i know i'm demending, but I do have standards
[13:10:43 CDT(-0500)] <EricDalquist1>
[13:26:04 CDT(-0500)] <EricDalquist> ok drewwills
[13:26:16 CDT(-0500)] <EricDalquist> as long as our firewall doesn't decide to block everything again
[13:26:19 CDT(-0500)] <EricDalquist> I should be all set
[13:30:21 CDT(-0500)] <drewwills> great
[13:31:32 CDT(-0500)] <EricDalquist> so a few things that need to get figured out:
[13:31:32 CDT(-0500)] <EricDalquist> what is the result data format
[13:31:32 CDT(-0500)] <EricDalquist> how much API do we encode in the utility library
[13:32:20 CDT(-0500)] <EricDalquist> a very simple util library could look like:
[13:32:20 CDT(-0500)] <EricDalquist> Object callPortalApi(PortletRequest, PortletResponse, String uri, Map<String, String[]> parameters)
[13:32:31 CDT(-0500)] <EricDalquist> and just hide all of the gross stuff
[13:32:32 CDT(-0500)] <drewwills> yep
[13:32:49 CDT(-0500)] <EricDalquist> the portlet would then just have to configure the generic "portal call proxy servlet" in web.xml
[13:32:55 CDT(-0500)] <EricDalquist> and configure the portal's webappname
[13:33:02 CDT(-0500)] <drewwills> could even be "public JsonNode"
[13:33:02 CDT(-0500)] <EricDalquist> though we could add that as a request property
[13:33:10 CDT(-0500)] <EricDalquist> which I would vote for
[13:33:19 CDT(-0500)] <EricDalquist> publicJsonNode?
[13:33:44 CDT(-0500)] <drewwills> instead of Object, we could have a more specific return type... which could be JsonNode
[13:33:51 CDT(-0500)] <EricDalquist> right
[13:33:58 CDT(-0500)] <EricDalquist> though that then forces the choice of JSON library on the portlet
[13:34:08 CDT(-0500)] <EricDalquist> so if we do that we say pick Jackson
[13:34:15 CDT(-0500)] <EricDalquist> then they are forced to use Jackson
[13:34:22 CDT(-0500)] <EricDalquist> not sure if that is an issue or not
[13:34:33 CDT(-0500)] <EricDalquist> maybe reasonable since jackson is what Spring3 uses for all its json stuff
[13:34:43 CDT(-0500)] <EricDalquist> and that is what most of our portlets use or will use for a framework
[13:35:08 CDT(-0500)] <drewwills> or we could add a Class parameter to the method and expose the features of the RestTemplate.getForObject or whatever
[13:43:23 CDT(-0500)] <EricDalquist> sorry .. lost network again
[13:43:25 CDT(-0500)] <EricDalquist> just a minute
[13:43:48 CDT(-0500)] <drewwills> sure
[13:45:27 CDT(-0500)] <drewwills> and maybe i'm missing something... how do we hit a uri through a RequestDispatcher while using a RestTemplate anyway? I don't think I have that peice of the puzzle in my head atm
[13:46:16 CDT(-0500)] <EricDalquist> you can't
[13:46:21 CDT(-0500)] <EricDalquist> we have to write all that handling logic
[13:46:32 CDT(-0500)] <EricDalquist> so the way this works is:
[13:47:03 CDT(-0500)] <drewwills> oh noes
[13:47:20 CDT(-0500)] <drewwills> i was getting quite fond of that RestTemplate interface
[13:47:20 CDT(-0500)] <EricDalquist> 1. PortletController creates a PortletRequestDispatcher to ServletController
[13:47:44 CDT(-0500)] <EricDalquist> 2. PortletController calls prd.include(PortletRequest, PortletResponse)
[13:48:16 CDT(-0500)] <EricDalquist> 3. ServletController uses ServletContext.getContext("/uPortal") to get uPortal's ServletContext object
[13:48:51 CDT(-0500)] <EricDalquist> 4. ServletController creates a RequestDispatcher using uportalsServletContext.createRequestDispatcher("/rest/uri");
[13:49:43 CDT(-0500)] <EricDalquist> 5. ServletController calls rd.include(request, responseWrapper) //That is a HttpServletResponseWrapper that captures EVERYTHING so the response data written doesn't break the portlet's response
[13:50:21 CDT(-0500)] <EricDalquist> 6. ServletController grabs the String or byte[]+encoding data written out by the portal's rest UI
[13:50:51 CDT(-0500)] <EricDalquist> 6. ServletController converts this to some pre-defined data structure (JsonNode?) and stores it in a well named request attribute
[13:51:06 CDT(-0500)] <EricDalquist> 7. PortletController pulls the data out of the well named request attribute
[13:51:07 CDT(-0500)] <EricDalquist> tada
[13:51:13 CDT(-0500)] <drewwills> oh jeez
[13:51:14 CDT(-0500)] <EricDalquist> wonderfully gross
[13:51:46 CDT(-0500)] <drewwills> this is much easier to follow and implement: JsonNode json = restTemplate.getForObject("http://localhost:8080/ssp-platform/api/people.json?searchTerms\[\]= &username= ", JsonNode.class, params);
[13:51:46 CDT(-0500)] <EricDalquist> and remember the portlet is already one request dispatcher deep (that is how uportal/pluto renders portlets, via a cross context request dispatcher)
[13:51:51 CDT(-0500)] <EricDalquist> yes
[13:51:54 CDT(-0500)] <EricDalquist> but that will break
[13:51:59 CDT(-0500)] <drewwills> yeah i remeber localhost
[13:52:05 CDT(-0500)] <EricDalquist> if you try that on our servers they drop off the network
[13:52:32 CDT(-0500)] <EricDalquist> as an artifact of the networking magic that goes on with hardware load balancers
[13:52:54 CDT(-0500)] <EricDalquist> so an alternative is to put work into defining a uPortal specifc API
[13:53:00 CDT(-0500)] <EricDalquist> we create a -api JAR
[13:53:06 CDT(-0500)] <EricDalquist> that gets deployed to shared/lib
[13:53:23 CDT(-0500)] <EricDalquist> then provide impls of those APIs as PortalContext attributes
[13:53:30 CDT(-0500)] <EricDalquist> so you'd do something like:
[13:53:34 CDT(-0500)] <drewwills> yes actually this was the Academus approach
[13:54:02 CDT(-0500)] <EricDalquist> PersonLookupService please = (PersonLookupService)portalContext.getAttribute("org.jasig.portal.api.personLookup")
[13:54:17 CDT(-0500)] <EricDalquist> which isn't unreasonable
[13:54:21 CDT(-0500)] <drewwills> public static void setInternalApiMajic(); // called from portal
[13:54:25 CDT(-0500)] <EricDalquist> no
[13:54:35 CDT(-0500)] <EricDalquist> not the shared/injected static API approach
[13:54:47 CDT(-0500)] <EricDalquist> the portlets get the API reference from the PortalContext interface which is part of the portlet spec
[13:55:01 CDT(-0500)] <EricDalquist> and only hold it for the duration of the portlet's lifecycle
[13:55:12 CDT(-0500)] <EricDalquist> it at least prevents classloader leakage
[13:55:38 CDT(-0500)] <EricDalquist> the shared API may actually be more maintainable
[13:55:46 CDT(-0500)] <EricDalquist> since then we have a concrete class structure
[13:55:54 CDT(-0500)] <drewwills> how much would you have to put in the shared classloader? just the interface(s)?
[13:56:00 CDT(-0500)] <EricDalquist> just the interfaces
[13:56:17 CDT(-0500)] <EricDalquist> the rest api approach could be bad unless we add unit tests for every rest API that asserts the output data format
[13:56:21 CDT(-0500)] <EricDalquist> and commit to never changing it
[13:56:38 CDT(-0500)] <EricDalquist> the shared API approach makes that requirement more apparent
[13:56:46 CDT(-0500)] <EricDalquist> as we would have a specifically defined public APUI
[13:59:00 CDT(-0500)] <drewwills> i suppose under-the-hood we could have the same code do the heavy lifting for both the REST & Java APIs, e.g. PersonLookupHelperImpl
[13:59:05 CDT(-0500)] <EricDalquist> yup
[13:59:10 CDT(-0500)] <EricDalquist> so we get the API impl
[13:59:27 CDT(-0500)] <EricDalquist> then refactor the rest api to use the same service
[14:00:19 CDT(-0500)] <drewwills> i haven't looked, but i bet you will find the REST api already closer to that atm than you would have, say, 2005
[14:00:43 CDT(-0500)] <EricDalquist> oh I'm sure
[14:00:46 CDT(-0500)] <drewwills> i'm looking at PeopleRESTController
[14:00:58 CDT(-0500)] <EricDalquist> this will all also get easier once we get moved completely to spring-security
[14:01:01 CDT(-0500)] <EricDalquist> for authn and authz
[14:01:02 CDT(-0500)] <drewwills> and it seems to hold tolerably to the One Responsibility Rule
[14:01:10 CDT(-0500)] <EricDalquist> then we have less concern over req/res access
[14:01:23 CDT(-0500)] <EricDalquist> as access state will be managed in a ThreadLocal by spring-security
[14:01:28 CDT(-0500)] <drewwills> doing controller-y things, and delegating the deeper things to other classes
[14:01:57 CDT(-0500)] <drewwills> athena?
[14:02:10 CDT(-0500)] <drewwills> anyone else want to comment on direction?
[14:03:03 CDT(-0500)] <peterjhart> no
[14:03:10 CDT(-0500)] <drewwills> i need to head to lunch... bb in a bit
[14:03:14 CDT(-0500)] <EricDalquist> k
[14:03:20 CDT(-0500)] <EricDalquist> I'll be here for ~3 more hours
[14:47:16 CDT(-0500)] <athena> back - was at lunch
[14:52:33 CDT(-0500)] <athena> ok
[14:52:37 CDT(-0500)] <athena> read over the above
[14:52:45 CDT(-0500)] <athena> so first of all, we actually do need the REST services for other things
[14:52:48 CDT(-0500)] <athena> specifically umobile
[14:52:54 CDT(-0500)] <athena> but potentially also useful for other applications
[14:53:09 CDT(-0500)] <athena> so i think regardless of whether we create another API or not we still need to standardize those REST services
[14:53:17 CDT(-0500)] <athena> also, i'd recommend that we don't cast to JsonNode3
[14:53:29 CDT(-0500)] <athena> that takes some freedom away from the client projects
[14:53:35 CDT(-0500)] <athena> since i might want the results back as a map
[14:53:47 CDT(-0500)] <athena> or i might want to create a lightweight java pojo to bind to
[14:54:09 CDT(-0500)] <athena> we should support those kind of choices from the client
[14:54:20 CDT(-0500)] <athena> maybe the solution would be to have the expected type as a parameter
[14:54:29 CDT(-0500)] <athena> and then we can use then when calling objectMapper.readValue
[14:54:39 CDT(-0500)] <athena> makes the API friendlier but doesn't take that flexibility away from the client
[14:58:01 CDT(-0500)] <EricDalquist> athena: so you're saying that no matter what we need to standardize our REST APIs
[14:58:27 CDT(-0500)] <EricDalquist> and because of that we might as well do the dispatcher chaining trick to just use those
[14:59:16 CDT(-0500)] <athena> yes
[14:59:20 CDT(-0500)] <EricDalquist> ok
[14:59:22 CDT(-0500)] <EricDalquist> I'm fine with that
[14:59:26 CDT(-0500)] <athena> unless someone really has time to create those new standalone APIs
[14:59:31 CDT(-0500)] <athena> i mean i think that would be a terrific move
[14:59:37 CDT(-0500)] <EricDalquist> but I think we need to add more tests that assert the output format
[14:59:43 CDT(-0500)] <athena> but from talking to drew, it doesn't sound to me like he has time to do that as part of his project
[14:59:46 CDT(-0500)] <EricDalquist> so that refactoring doesn't break integrations
[14:59:50 CDT(-0500)] <athena> yes, that sounds like a great idea
[15:00:00 CDT(-0500)] <athena> and i think we probably already need to start doing that anyway
[15:00:06 CDT(-0500)] <athena> so that sounds like a great idea to me
[15:00:26 CDT(-0500)] <athena> and since umobile uses these services, i can probably help out
[15:02:28 CDT(-0500)] <athena> so how much of this can we abstract away from the portlet's implementation?
[15:02:45 CDT(-0500)] <EricDalquist> quite a bit
[15:02:46 CDT(-0500)] <athena> can it just be a target url, some parameters, and an expected return type?
[15:03:05 CDT(-0500)] <EricDalquist> so one thing I think we need to do is add a portlet request property that tells the portlet the portal's context path
[15:03:08 CDT(-0500)] <EricDalquist> which would be easy enough to do
[15:03:19 CDT(-0500)] <athena> oh that's be pretty cool
[15:03:26 CDT(-0500)] <EricDalquist> we have to have that really
[15:03:29 CDT(-0500)] <EricDalquist> or people will go nuts
[15:03:33 CDT(-0500)] <EricDalquist> and it is easy to add
[15:03:35 CDT(-0500)] <athena> some of the portlet's already have a config string in them
[15:03:43 CDT(-0500)] <athena> that in umobile gets copied from the filter file
[15:04:02 CDT(-0500)] <athena> so we could go that approach, but using something more automagic would be even better
[15:04:09 CDT(-0500)] <EricDalquist> then we create an API that looks like "public Object callPortalRestApi(PortletRequest, PortletResponse, String uri, Map<String, String[]> params)
[15:04:28 CDT(-0500)] <EricDalquist> not sure what we do for return type stil