RE: Re: Re: Re: Dynamic Redirector

2013-04-28 Thread Grant
 I haven't dug into this code, but I suspect you aren't manipulating
 References properly. I advise printing out the intermediate steps of your
 Reference computation to see where it goes wrong.

That's just it, I don't think it is even selecting my Redirector as the target 
for the endpoint, b/c it is not even calling getTargetRef due to the child 
endpoints.  Is there something else on Redirector or in my attachment I should 
be overriding so that it stops trying to match once it resolves the parent?

 
 Also, the template argument to Redirector is ignored if you override
 getTargetRef.
 


Hmm, that doesn't seem to be the case for me, since my code is almost an exact 
copy the parent class.


 --tim
 
 On Sat, Apr 27, 2013 at 6:03 PM, Grant gsingers at apache dot org wrote:
 
   I don't understand what you mean by the handling of the {rr} template.
   The approach I suggested, overriding getTargetRef, ignores the template
   argument entirely.
  
 
  In my old code, I had:
  URI = hardcoded URI to resource
  Redirector redir = new Redirector(router.getContext(), URI + {rr},
Redirector.MODE_SERVER_OUTBOUND);
  router.attach(, redir, Template.MODE_STARTS_WITH);
 
  So, when I pass in http://foo:port/a/b/c, it redirects to URI/a/b/c
 
  In my new code, I pass in the target template simply as {rr} and then iin
  the getTargetRef, I do:
  protected Reference getTargetRef(Request request, Response response) {
  URI serviceURI = serviceLocator.getServiceURI(service); //THIS looks
  up the location of the service
  // Create the template
  Template rt = new Template(this.targetTemplate);
  rt.setLogger(getLogger());
 
  // Return the formatted target URI
  if (new Reference(this.targetTemplate).isRelative()) {
// Be sure to keep the resource's base reference.
//Reference baseRef = new Reference(serviceURI.uri);
if (log.isInfoEnabled()) {
  log.info(dynRedir from {} to {}, request.getResourceRef(),
  serviceURI.uri);
}
String format = rt.format(request,
response);
try {
  return new Reference(new URI(serviceURI.uri.toString() + format));
} catch (URISyntaxException e) {
  log.error(Exception, e);
  throw new RuntimeException(e);
}
  }
 
  return new Reference(rt.format(request, response));
}
  ///
 
  I attach my DynamicRedirector at, for example, /a.  When I pass in
  http://foo:port/a/b/c;, I want it to select my DynamicRedirector due to
  the /a (I'm using STARTS_WITH mode) part and then redirect to the target
  by passing along b/c (i.e. the {rr} part) such that the new URL would be
  something like http://dynamicHost:port/b/c;, based on what my
  serviceLocator returns.  Like I said, it works great if I'm just matching
  at /a, but it doesn't handle the /b/c part.  AFAICT, the handle()
  methods in Restlet are continuing to resolve down to the last endpoint
  (i.e. b/c) even though it has a match at /a.
 
  I will see if I can work up a standalone test example to demonstrate it.
 
  --
 
  http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447dsMessageId=3054458
 

--
http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447dsMessageId=3054489


Re: Re: Re: Re: Dynamic Redirector

2013-04-28 Thread Tim Peierls
On Sun, Apr 28, 2013 at 11:42 AM, Grant gsing...@apache.org wrote:

  I haven't dug into this code, but I suspect you aren't manipulating
  References properly. I advise printing out the intermediate steps of your
  Reference computation to see where it goes wrong.

 That's just it, I don't think it is even selecting my Redirector as the
 target for the endpoint, b/c it is not even calling getTargetRef due to the
 child endpoints.  Is there something else on Redirector or in my attachment
 I should be overriding so that it stops trying to match once it resolves
 the parent?


I don't know what you mean by parent or child endpoints.

If getTargetRef isn't being called, it's because the routing is wrong. If
you want the application or component to send *all* requests to the
redirector, use attachDefault:

router.attachDefault(new MyRedirector(getContext(), ... other args ...);


 Also, the template argument to Redirector is ignored if you
 override getTargetRef.

 Hmm, that doesn't seem to be the case for me, since my code is almost an
 exact copy the parent class.


The point of overriding getTargetRef is to give you the freedom to
determine the target in arbitrary ways, which can be independent of the
template. Here's the code for Redirector:

https://github.com/restlet/restlet-framework-java/blob/master/modules/org.restlet/src/org/restlet/routing/Redirector.java

You can see that the template is only used in getTargetRef. Your overridden
getTargetRef need not use that template. You can just do something like
this:

public class MyRedirector extends Redirector {
final FunctionReference, Reference targetMapper;
public MyRedirector(Context context, FunctionReference, Reference
targetMapper, int mode) {
super(context, ignored, mode);
this.targetMapper = targetMapper;
}
protected Reference getTargetRef(Request request, Response response) {
return targetMapper.apply(request.getOriginalRef());
}
}

I'm using Guava's Function type as a shorthand here, to illustrate how the
template can be made irrelevant to the redirection logic, but you can
obviously write this any way you want.

--tim

--
http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447dsMessageId=3054490

RE: Re: Re: Re: Re: Dynamic Redirector

2013-04-28 Thread Grant
 On Sun, Apr 28, 2013 at 11:42 AM, Grant gsingers at apache dot org wrote:
 
   I haven't dug into this code, but I suspect you aren't manipulating
   References properly. I advise printing out the intermediate steps of your
   Reference computation to see where it goes wrong.
 
  That's just it, I don't think it is even selecting my Redirector as the
  target for the endpoint, b/c it is not even calling getTargetRef due to the
  child endpoints.  Is there something else on Redirector or in my attachment
  I should be overriding so that it stops trying to match once it resolves
  the parent?
 
 
 I don't know what you mean by parent or child endpoints.
 
 If getTargetRef isn't being called, it's because the routing is wrong. If
 you want the application or component to send *all* requests to the
 redirector, use attachDefault:
 
 router.attachDefault(new MyRedirector(getContext(), ... other args ...);
 
 

Yes, this is my suspicion too.  Here's what I mean by parent and child.

I am attaching my DynRedirector at:
http://foo:port/a

I am, at run time, making a call to http://foo:port/a/b.  Thus, /b is my 
child endpoint and /a is my parent endpoint (ie the one that _is_ the 
Redirector).  Not sure if this is the right nomenclature for Restlet, so please 
correct me.

I can see that the Restlet that owns the DynRedirector is getting selected, but 
then it is not able to find it's next route b/c /b was never officially 
attached since it is (in my mind) supposed to be handled by the {rr} part.  I 
suspect my issue is in how I am handling the {rr} part when I am attaching the 
DynamicRedirector to the owning Restlet.

--
http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447dsMessageId=3054494


Re: Re: Re: Re: Re: Dynamic Redirector

2013-04-28 Thread Tim Peierls
On Sun, Apr 28, 2013 at 12:58 PM, Grant gsing...@apache.org wrote:

 I am attaching my DynRedirector at:
 http://foo:port/a


What's the code for this? It could be a Component level routing:

VirtualHost host = component.getDefaultHost();
host.attach(/a, new DynRedirector(... args ...));

or an Application level routing:

host.attach(/a, new MyApplication());
...
// In MyApplication.createInboundRoot:
router.attachDefault(new DynRedirector(... args ...));

If it doesn't fall into one of these two camps, it's a good bet that your
problem lies there.



 I am, at run time, making a call to http://foo:port/a/b.  Thus, /b is
 my child endpoint and /a is my parent endpoint (ie the one that _is_
 the Redirector).  Not sure if this is the right nomenclature for Restlet,
 so please correct me.


I would have said that you want all requests for resources at URIs with a
prefix of http://foo:port/a to be handled by an instance of DynRedirector.


I can see that the Restlet that owns the DynRedirector is getting selected,
 but then it is not able to find it's next route b/c /b was never
 officially attached since it is (in my mind) supposed to be handled by the
 {rr} part.  I suspect my issue is in how I am handling the {rr} part when I
 am attaching the DynamicRedirector to the owning Restlet.


Again, if DynRedirector.getTargetRef isn't being called at all, then the
template argument passed to DynRedirector isn't being used, so handled by
the {rr} part doesn't mean anything.

I think you're confusing the path provided to attach, which can be a
template pattern, with the template pattern passed to the Redirector. The
former is used during routing, the latter is made available to getTargetRef
to be used in determining a target reference from values in the current
request and response.

--tim

--
http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447dsMessageId=3054497

RE: Re: Dynamic Redirector

2013-04-27 Thread Grant
Hmm, digging in on this a bit more, I'm not sure it fully works for what I'm 
trying to do.  The issue seems to be in the handling of the {rr} template.

In other words, if I'm just redirecting a single URI to another (i.e. 
http://foo/a to http://bar/b), this approach works, but if I want to redirect 
all children URIs to the respective children URIs of the target.

That is, if I have I request
http://foo:port/a/b/c
and I want to attach at http://foo:port/a and redirect to http://bar:port/b/c 
(by rewriting the target reference), it doesn't seem to work if I create a 
MyRedirector (my derivation of Redirector) that has an attach point of 
http://foo:port/a and a target template of {rr} whereas before in my static 
redirector I was doing http://bar:port/{rr} and everything was good.

Thanks,
Grant

--
http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447dsMessageId=3054455


Re: Re: Dynamic Redirector

2013-04-27 Thread Tim Peierls
I don't understand what you mean by the handling of the {rr} template.
The approach I suggested, overriding getTargetRef, ignores the template
argument entirely.

--tim

On Sat, Apr 27, 2013 at 2:54 PM, Grant gsing...@apache.org wrote:

 Hmm, digging in on this a bit more, I'm not sure it fully works for what
 I'm trying to do.  The issue seems to be in the handling of the {rr}
 template.

 In other words, if I'm just redirecting a single URI to another (i.e.
 http://foo/a to http://bar/b), this approach works, but if I want to
 redirect all children URIs to the respective children URIs of the target.

 That is, if I have I request
 http://foo:port/a/b/c
 and I want to attach at http://foo:port/a and redirect to http://bar:port/b/c
 (by rewriting the target reference), it doesn't seem to work if I create a
 MyRedirector (my derivation of Redirector) that has an attach point of
 http://foo:port/a and a target template of {rr} whereas before in my
 static redirector I was doing http://bar:port/{rr} and everything was
 good.

 Thanks,
 Grant

 --

 http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447dsMessageId=3054455


--
http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447dsMessageId=3054456

RE: Re: Re: Dynamic Redirector

2013-04-27 Thread Grant
 I don't understand what you mean by the handling of the {rr} template.
 The approach I suggested, overriding getTargetRef, ignores the template
 argument entirely.
 

In my old code, I had:
URI = hardcoded URI to resource 
Redirector redir = new Redirector(router.getContext(), URI + {rr},
  Redirector.MODE_SERVER_OUTBOUND);
router.attach(, redir, Template.MODE_STARTS_WITH);

So, when I pass in http://foo:port/a/b/c, it redirects to URI/a/b/c

In my new code, I pass in the target template simply as {rr} and then iin the 
getTargetRef, I do:
protected Reference getTargetRef(Request request, Response response) {
URI serviceURI = serviceLocator.getServiceURI(service); //THIS looks up the 
location of the service
// Create the template
Template rt = new Template(this.targetTemplate);
rt.setLogger(getLogger());

// Return the formatted target URI
if (new Reference(this.targetTemplate).isRelative()) {
  // Be sure to keep the resource's base reference.
  //Reference baseRef = new Reference(serviceURI.uri);
  if (log.isInfoEnabled()) {
log.info(dynRedir from {} to {}, request.getResourceRef(), 
serviceURI.uri);
  }
  String format = rt.format(request,
  response);
  try {
return new Reference(new URI(serviceURI.uri.toString() + format));
  } catch (URISyntaxException e) {
log.error(Exception, e);
throw new RuntimeException(e);
  }
}

return new Reference(rt.format(request, response));
  }
///

I attach my DynamicRedirector at, for example, /a.  When I pass in 
http://foo:port/a/b/c;, I want it to select my DynamicRedirector due to the 
/a (I'm using STARTS_WITH mode) part and then redirect to the target by 
passing along b/c (i.e. the {rr} part) such that the new URL would be 
something like http://dynamicHost:port/b/c;, based on what my serviceLocator 
returns.  Like I said, it works great if I'm just matching at /a, but it 
doesn't handle the /b/c part.  AFAICT, the handle() methods in Restlet are 
continuing to resolve down to the last endpoint (i.e. b/c) even though it has 
a match at /a.

I will see if I can work up a standalone test example to demonstrate it.

--
http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447dsMessageId=3054458


Re: Re: Re: Dynamic Redirector

2013-04-27 Thread Tim Peierls
I haven't dug into this code, but I suspect you aren't manipulating
References properly. I advise printing out the intermediate steps of your
Reference computation to see where it goes wrong.

Also, the template argument to Redirector is ignored if you override
getTargetRef.

--tim

On Sat, Apr 27, 2013 at 6:03 PM, Grant gsing...@apache.org wrote:

  I don't understand what you mean by the handling of the {rr} template.
  The approach I suggested, overriding getTargetRef, ignores the template
  argument entirely.
 

 In my old code, I had:
 URI = hardcoded URI to resource
 Redirector redir = new Redirector(router.getContext(), URI + {rr},
   Redirector.MODE_SERVER_OUTBOUND);
 router.attach(, redir, Template.MODE_STARTS_WITH);

 So, when I pass in http://foo:port/a/b/c, it redirects to URI/a/b/c

 In my new code, I pass in the target template simply as {rr} and then iin
 the getTargetRef, I do:
 protected Reference getTargetRef(Request request, Response response) {
 URI serviceURI = serviceLocator.getServiceURI(service); //THIS looks
 up the location of the service
 // Create the template
 Template rt = new Template(this.targetTemplate);
 rt.setLogger(getLogger());

 // Return the formatted target URI
 if (new Reference(this.targetTemplate).isRelative()) {
   // Be sure to keep the resource's base reference.
   //Reference baseRef = new Reference(serviceURI.uri);
   if (log.isInfoEnabled()) {
 log.info(dynRedir from {} to {}, request.getResourceRef(),
 serviceURI.uri);
   }
   String format = rt.format(request,
   response);
   try {
 return new Reference(new URI(serviceURI.uri.toString() + format));
   } catch (URISyntaxException e) {
 log.error(Exception, e);
 throw new RuntimeException(e);
   }
 }

 return new Reference(rt.format(request, response));
   }
 ///

 I attach my DynamicRedirector at, for example, /a.  When I pass in
 http://foo:port/a/b/c;, I want it to select my DynamicRedirector due to
 the /a (I'm using STARTS_WITH mode) part and then redirect to the target
 by passing along b/c (i.e. the {rr} part) such that the new URL would be
 something like http://dynamicHost:port/b/c;, based on what my
 serviceLocator returns.  Like I said, it works great if I'm just matching
 at /a, but it doesn't handle the /b/c part.  AFAICT, the handle()
 methods in Restlet are continuing to resolve down to the last endpoint
 (i.e. b/c) even though it has a match at /a.

 I will see if I can work up a standalone test example to demonstrate it.

 --

 http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447dsMessageId=3054458


--
http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447dsMessageId=3054459

Re: Dynamic Redirector

2013-04-16 Thread Tim Peierls
Subclass Redirector, overriding getTargetRef(Request, Response) to return a
Reference that you determine dynamically from the request and response
parameters.

--tim

On Mon, Apr 15, 2013 at 10:06 PM, Grant gsing...@apache.org wrote:

 I have a front end API which I want to use to proxy/redirect requests to a
 backend service.  Up until now, I've been binding the APIs using the {rr}
 technique described in the documentation, but the main issue I have is that
 I am binding to the backend service's host/port at startup (in
 createInboundRoot) and I want to be able to dynamically set the host/port
 of the backend service at request time, as it is possible the service may
 be down or I want to load balance it.

 I'm on Restlet 2.1.5-RC1.

 Thanks,
 Grant

 --

 http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447dsMessageId=3053410


--
http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447dsMessageId=3053448

RE: Re: Dynamic Redirector

2013-04-16 Thread Grant
That works beautifully, thank you!

For the record, I used what was in getTargetRef almost as is, except I replaced 
the baseRef with a dynamically discovered one (that I get from Zookeeper).

Thanks,
Grant

--
http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447dsMessageId=3053466