Re: CRUD Operation for Calling ServerResouce with ClientProxy

2015-01-16 Thread Tim Peierls
On Fri, Jan 16, 2015 at 5:20 AM, Thierry Boileau 
wrote:

> Here is my first refactoring:
> public class GaeThingServerResource extends SelfInjectingServerResource
>  implements ThingResource {
> ...
>  @Override
>  public ThingItem doInit() {
>  id = Long.parseLong(getAttribute("thingitemid"));
>  // You may check that the resource really exist
> // setExisting(true or false);
>  }
> ...
> }
>

Side note: If GaeThingServerResource is to extend
SelfInjectingServerResource, then doInit should call super.doInit().

(I don't see any @Inject annotations, so currently there's no point in
extending SelfInjectingServerResource.)

--tim

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

Re: Trouble going from 2.2 to 2.3

2014-12-19 Thread Tim Peierls
It worked, thanks!

And for those out there wanting to have JUnit tests that involve HTTP
service with Restlet 2.3.x JEE edition, here's a handy trick:

Stick the following code in your test classes, either in each concrete
class or in a common abstract base:

@BeforeClass
public static void ensureHttpServer() {
org.restlet.engine.Engine.getInstance().getRegisteredServers().add(
new org.restlet.engine.connector.HttpServerHelper(null));
}

The key is that you only want to do this once, which is why it's annotated
@BeforeClass rather than just @Before. Then you can create and start your
Restlet Component and Application(s) with @Before and stop them and tear
them down in @After. I like to make the test class extend Application, but
there are a number of other patterns that work here.

Of course you could just run your tests with the JSE edition, but I'm
happier running my tests against the same exact jars that I deploy with.

--tim

On Fri, Dec 19, 2014 at 3:23 PM, Thierry Boileau 
wrote:
>
> Hi Tim,
>
> I think it is not called early enough. It should be done before the
> Component.getServers() method is called.
>
> --
> Thierry Boileau
>
> 2014-12-19 21:10 GMT+01:00 Tim Peierls :
>
>> I tried adding this line:
>>
>> Engine.getInstance().getRegisteredServers().add(
>> new org.restlet.engine.connector.HttpServerHelper(null));
>>
>> but it didn't seem to work -- maybe I didn't call it early enough. As far
>> as you know, though, that's all I should have to do?
>>
>> On Fri, Dec 19, 2014 at 3:08 PM, Thierry Boileau 
>> wrote:
>>>
>>> wow, I need vacations!
>>> The fix is exactly: register these default connectors.
>>>
>>> Best regards,
>>> Thierry Boileau
>>>
>>>
>>> 2014-12-19 21:02 GMT+01:00 Thierry Boileau :
>>>
>>>> Hi Tim,
>>>>
>>>> I'm afraid I've taken all alone the decision to remove these files as
>>>> they appeared useless to me. I feel really sorry about that.
>>>> I revert back these changes on the 2.3 and master branches: that is to
>>>> say the JEE edition provides these connectors. However, I wonder if we have
>>>> to register these connectors by default, what is your thinking about that?
>>>>
>>>> And unfortunately, I won't be able to package a 2.3.1 release soon, I
>>>> can achieve this on the 29th of December.
>>>>
>>>>
>>>> Best regards,
>>>> Thierry Boileau
>>>>
>>>>
>>>>
>>>> 2014-12-19 20:34 GMT+01:00 Tim Peierls :
>>>>
>>>>> The default connectors for various editions have changed between 2.2
>>>>> and 2.3 (actually between 2.3-RC1 and 2.3.0). JEE edition no longer
>>>>> registers HTTP or HTTPS server helpers; JSE still does.
>>>>>
>>>>> Assuming this was intentional and not an oversight, the change causes
>>>>> problems for me. For several versions now I've been able to maintain one
>>>>> build that works both as a standalone deployment and when embedded in a 
>>>>> WAR
>>>>> for deployment in a production server running Tomcat. I've used the JEE
>>>>> edition because of the dependency on 
>>>>> org.restlet.ext.servlet.ServerServlet.
>>>>>
>>>>> (Why use Tomcat at all? There are better connectors for production
>>>>> purposes. Short answer is that it plays well with AWS Elastic Beanstalk.)
>>>>>
>>>>> With this latest change, however, the standalone deployment no longer
>>>>> works. I get message: No available server connector supports the
>>>>> required protocols: 'HTTP' Please add the jar of a matching connector to
>>>>> your classpath.
>>>>> <https://github.com/restlet/restlet-framework-java/blob/09c78b4737c1eda45a276dc284d4ffee61f8efca/modules/org.restlet/src/org/restlet/engine/Engine.java#L650-L663>
>>>>>
>>>>> It's because no HttpServerHelper has been registered in these lines
>>>>> <https://github.com/restlet/restlet-framework-java/blob/09c78b4737c1eda45a276dc284d4ffee61f8efca/modules/org.restlet/src/org/restlet/engine/Engine.java#L896-L901>
>>>>> for JEE (the "jee" token was added to the #ifndef list only a few days
>>>>> ago). I'd be happy to add the jar of a matching connector if there was one
>>>>> that the JEE ed

Re: Trouble going from 2.2 to 2.3

2014-12-19 Thread Tim Peierls
I tried adding this line:

Engine.getInstance().getRegisteredServers().add(
new org.restlet.engine.connector.HttpServerHelper(null));

but it didn't seem to work -- maybe I didn't call it early enough. As far
as you know, though, that's all I should have to do?

On Fri, Dec 19, 2014 at 3:08 PM, Thierry Boileau 
wrote:
>
> wow, I need vacations!
> The fix is exactly: register these default connectors.
>
> Best regards,
> Thierry Boileau
>
>
> 2014-12-19 21:02 GMT+01:00 Thierry Boileau :
>
>> Hi Tim,
>>
>> I'm afraid I've taken all alone the decision to remove these files as
>> they appeared useless to me. I feel really sorry about that.
>> I revert back these changes on the 2.3 and master branches: that is to
>> say the JEE edition provides these connectors. However, I wonder if we have
>> to register these connectors by default, what is your thinking about that?
>>
>> And unfortunately, I won't be able to package a 2.3.1 release soon, I can
>> achieve this on the 29th of December.
>>
>>
>> Best regards,
>> Thierry Boileau
>>
>>
>>
>> 2014-12-19 20:34 GMT+01:00 Tim Peierls :
>>
>>> The default connectors for various editions have changed between 2.2 and
>>> 2.3 (actually between 2.3-RC1 and 2.3.0). JEE edition no longer registers
>>> HTTP or HTTPS server helpers; JSE still does.
>>>
>>> Assuming this was intentional and not an oversight, the change causes
>>> problems for me. For several versions now I've been able to maintain one
>>> build that works both as a standalone deployment and when embedded in a WAR
>>> for deployment in a production server running Tomcat. I've used the JEE
>>> edition because of the dependency on org.restlet.ext.servlet.ServerServlet.
>>>
>>> (Why use Tomcat at all? There are better connectors for production
>>> purposes. Short answer is that it plays well with AWS Elastic Beanstalk.)
>>>
>>> With this latest change, however, the standalone deployment no longer
>>> works. I get message: No available server connector supports the
>>> required protocols: 'HTTP' Please add the jar of a matching connector to
>>> your classpath.
>>> <https://github.com/restlet/restlet-framework-java/blob/09c78b4737c1eda45a276dc284d4ffee61f8efca/modules/org.restlet/src/org/restlet/engine/Engine.java#L650-L663>
>>>
>>> It's because no HttpServerHelper has been registered in these lines
>>> <https://github.com/restlet/restlet-framework-java/blob/09c78b4737c1eda45a276dc284d4ffee61f8efca/modules/org.restlet/src/org/restlet/engine/Engine.java#L896-L901>
>>> for JEE (the "jee" token was added to the #ifndef list only a few days
>>> ago). I'd be happy to add the jar of a matching connector if there was one
>>> that the JEE edition supported, but the obvious candidates, Jetty and
>>> Simple, don't seem to be available for that edition.
>>>
>>> I'd be happy to switch to the JSE edition, but then I wouldn't be able
>>> to compile against org.restlet.ext.servlet.
>>>
>>> There's an existing issue which is vaguely related:
>>>
>>> https://github.com/restlet/restlet-framework-java/issues/876
>>>
>>> I'm not filing my own issue yet, because I don't see it as a bug, but
>>> I'd like advice on what to do here. I'd prefer not to have to make separate
>>> builds -- it was a really nice property that I could run the same code and
>>> libraries either standalone or deployed as a WAR.
>>>
>>> --tim
>>>
>>
>>
>>
>> --
>> *Thierry Boileau, Mr B*
>> +1 (408) 387-3184 • tboil...@restlet.com
>>
>> <http://restlet.com/>
>> 6 Rue Rose Dieng-Kuntz • Nantes, 44300 • France
>>
>
>
>
> --
> *Thierry Boileau, Mr B*
> +1 (408) 387-3184 • tboil...@restlet.com
>
> <http://restlet.com/>
> 6 Rue Rose Dieng-Kuntz • Nantes, 44300 • France
>

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

Trouble going from 2.2 to 2.3

2014-12-19 Thread Tim Peierls
The default connectors for various editions have changed between 2.2 and
2.3 (actually between 2.3-RC1 and 2.3.0). JEE edition no longer registers
HTTP or HTTPS server helpers; JSE still does.

Assuming this was intentional and not an oversight, the change causes
problems for me. For several versions now I've been able to maintain one
build that works both as a standalone deployment and when embedded in a WAR
for deployment in a production server running Tomcat. I've used the JEE
edition because of the dependency on org.restlet.ext.servlet.ServerServlet.

(Why use Tomcat at all? There are better connectors for production
purposes. Short answer is that it plays well with AWS Elastic Beanstalk.)

With this latest change, however, the standalone deployment no longer
works. I get message: No available server connector supports the required
protocols: 'HTTP' Please add the jar of a matching connector to your
classpath.


It's because no HttpServerHelper has been registered in these lines

for JEE (the "jee" token was added to the #ifndef list only a few days
ago). I'd be happy to add the jar of a matching connector if there was one
that the JEE edition supported, but the obvious candidates, Jetty and
Simple, don't seem to be available for that edition.

I'd be happy to switch to the JSE edition, but then I wouldn't be able to
compile against org.restlet.ext.servlet.

There's an existing issue which is vaguely related:

https://github.com/restlet/restlet-framework-java/issues/876

I'm not filing my own issue yet, because I don't see it as a bug, but I'd
like advice on what to do here. I'd prefer not to have to make separate
builds -- it was a really nice property that I could run the same code and
libraries either standalone or deployed as a WAR.

--tim

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

Re: "segment" router or subrouter

2014-11-20 Thread Tim Peierls
I think you can do better. Here's an old conversation that might have some
hints:

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

Not all of this is relevant to you. Concentrate on the autowire part.

--tim

On Thu, Nov 20, 2014 at 11:01 AM, Koen Maes  wrote:

> Ok, I guess I better create a second Application and map that under /*
>
> Correct?
>
> --
>
> http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=3091601
>

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

Re: Re: Using JUnit with JacksonRepresentation

2014-08-11 Thread Tim Peierls
Sure sounds like that's the problem. For unit testing purposes, how about
getting the text of representation, turning that into a
StringRepresentation, and then constructing the JacksonRepresentation in
terms of the StringRepresentation? It's wasteful, but it would allow you to
proceed with your unit testing.

--tim


On Sun, Aug 10, 2014 at 4:48 PM, Alex Harvey  wrote:

> Hi,
>
> Thanks for the reply. Yes I tried calling Representation.getTest() on
> either side of the call and the JSON appears to be correctly formed.
>
> I did notice the following message in my output when running under JUnit.
>
> WARNING: The GAE edition is unable to get an InputStream out of an
> OutputRepresentation.
>
> This is a GAE application. Could this be the problem?
>
> Thanks,
>
> Alex
>
> --
>
> http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=3086557
>

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

Re: Using JUnit with JacksonRepresentation

2014-08-09 Thread Tim Peierls
Hard to be sure from what you've described, but it looks as though the
entity doesn't contain anything. Try getting the raw contents of the entity
in two places (1) before you post it and and (2) after you receive it but
before you parse it by passing it to the JacksonRepresentation constructor.
Does it look like valid JSON in both cases?

--tim


On Fri, Aug 8, 2014 at 5:13 PM, Alex Harvey  wrote:

> Hi,
>
> I'd like to be able to write some tests using JUnit to rest server
> resource classes. I'm encountering a problem when I try to pass a
> JacksonRepresentation in. My test class looks something a little like this:
>
> {
> TransactionResource resource = new MyResource();
> MyData data = new MyData(etc);
>
> Representation entity = new JacksonRepresentation(myData);
>
> entity.setMediaType(MediaType.APPLICATION_JSON);
>
> Representation response = resource.post(entity);
> }
>
> This is all fine as far as I know. But I receive an error in my
> ServerResource derived class when I try and deserialize the object using
> Jackson:
>
> MyData myData = new JacksonRepresentation<>(entity,
> MyData.class)
> .getObject();
>
> com.fasterxml.jackson.databind.JsonMappingException: No content to map due
> to end-of-input
>  at [Source: UNKNOWN; line: 1, column: 1]
> at
> com.fasterxml.jackson.databind.JsonMappingException.from(JsonMappingException.java:164)
> at
> com.fasterxml.jackson.databind.ObjectReader._initForReading(ObjectReader.java:1298)
> at
> com.fasterxml.jackson.databind.ObjectReader._bindAndClose(ObjectReader.java:1199)
> at
> com.fasterxml.jackson.databind.ObjectReader.readValue(ObjectReader.java:798)
> at
> org.restlet.ext.jackson.JacksonRepresentation.getObject(JacksonRepresentation.java:309)
>
> Is this the correct approach? Am I doing something wrong in my test case
> in setting up the call to my resource class?
>
> Thanks
>
> --
>
> http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=3086450
>

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

Re: Complexity in understanding

2014-08-08 Thread Tim Peierls
Restlet arranges to call the createInboundRoot method of any Application
when that application is started. You're defining a createInboundRoot
method for an Application subtype but you're not passing an instance of
that subtype.

As I wrote before, I recommend starting with a working tutorial example
that you *do* understand, and incrementally change it until it doesn't do
what you expect. You can get a lot done by just adapting existing working
code.

--tim


On Fri, Aug 8, 2014 at 9:20 AM, Shai Levit  wrote:

> Guess I am a bit confused in how Application application = new Application
> and InboundRoot and Restlet all relate. Should I have nested the Restlet
> inside the Application like this:?
>
> Application application = new Application(this.getContext()){
>
> @Override
>  public Restlet createInboundRoot(){
>
> Router router = new Router(this.getContext());
>
> Restlet mainpage = new Restlet(){
> @Override
> public void handle(Request request, Response
> response){
> StringBuilder stringBuilder = new
> StringBuilder();
> stringBuilder.append("");
> stringBuilder.append("Default
> Page of my TEST
> application");
> stringBuilder.append("
> Click on link
> ");
> //stringBuilder.append(" ");
> stringBuilder.append(" <\"/file\">
> ");
>
> response.setEntity(new
> StringRepresentation(stringBuilder.toString(),
> MediaType.TEXT_HTML));
> }
> };
>
> router.attach("", mainpage);
> return router;
> }
> component.getDefaultHost().attach(application);
> component.start();
>
> }
>
> Or am I missing some major / subtle point here ?
>
> Thanks for the help in advance
>
>
> On Thu, Aug 7, 2014 at 11:05 PM, Tim Peierls [via Restlet Discuss] <[hidden
> email] <http://user/SendEmail.jtp?type=node&node=7579258&i=0>> wrote:
>
>> Looks like you're attaching a vanilla Application instead of an instance
>> of PageTest.
>>
>>
>> On Thu, Aug 7, 2014 at 3:39 PM, Shai Levit <[hidden email]
>> <http://user/SendEmail.jtp?type=node&node=7579257&i=0>> wrote:
>>
>>> Hi Tim,
>>> Thank for the insight and so I am working on adding more complexity. So
>>> here
>>> is a simple code that should work, but for some reason I get this error:
>>> The filter org.restlet.engine.application.RangeFilter@24f2f2 was
>>> executed
>>> without a next Restlet attached to it.
>>> 2014-08-07  15:37:470:0:0:0:0:0:0:1 -   -   8400
>>>  GET /   -   500 486 0
>>>
>>> The full code is as follows:
>>>
>>> package org.simpler.test;
>>>
>>> import org.restlet.Application;
>>> import org.restlet.Component;
>>> import org.restlet.Request;
>>> import org.restlet.Response;
>>> import org.restlet.Restlet;
>>> import org.restlet.data.MediaType;
>>> import org.restlet.data.Protocol;
>>> import org.restlet.representation.StringRepresentation;
>>> import org.restlet.routing.Router;
>>>
>>> public class PageTest extends Application {
>>>
>>> public static void main(String[] args) throws Exception {
>>>
>>> Component component = new Component();
>>> component.getServers().add(Protocol.HTTP, 8400);
>>>
>>> Application application = new Application();
>>>
>>> component.getDefaultHost().attach(application);
>>> component.start();
>>>
>>> }
>>>
>>> @Override
>>> public Restlet createInboundRoot(){
>>>
>>> Router router = new Router(this.getContext());
>>>
>>> Restlet mainpage = new Restlet(){
>>> @Override
>>> public void handle(Request request, Response
>>> response){
>>> StringBuilder stringBuilder = new
>>> StringBuilder();
>>> stringBuilder.append("");
>>>
>>> stringBuilder.a

Re: Complexity in understanding

2014-08-07 Thread Tim Peierls
Looks like you're attaching a vanilla Application instead of an instance of
PageTest.


On Thu, Aug 7, 2014 at 3:39 PM, Shai Levit  wrote:

> Hi Tim,
> Thank for the insight and so I am working on adding more complexity. So
> here
> is a simple code that should work, but for some reason I get this error:
> The filter org.restlet.engine.application.RangeFilter@24f2f2 was executed
> without a next Restlet attached to it.
> 2014-08-07  15:37:470:0:0:0:0:0:0:1 -   -   8400
>  GET /   -   500 486 0
>
> The full code is as follows:
>
> package org.simpler.test;
>
> import org.restlet.Application;
> import org.restlet.Component;
> import org.restlet.Request;
> import org.restlet.Response;
> import org.restlet.Restlet;
> import org.restlet.data.MediaType;
> import org.restlet.data.Protocol;
> import org.restlet.representation.StringRepresentation;
> import org.restlet.routing.Router;
>
> public class PageTest extends Application {
>
> public static void main(String[] args) throws Exception {
>
> Component component = new Component();
> component.getServers().add(Protocol.HTTP, 8400);
>
> Application application = new Application();
>
> component.getDefaultHost().attach(application);
> component.start();
>
> }
>
> @Override
> public Restlet createInboundRoot(){
>
> Router router = new Router(this.getContext());
>
> Restlet mainpage = new Restlet(){
> @Override
> public void handle(Request request, Response
> response){
> StringBuilder stringBuilder = new
> StringBuilder();
> stringBuilder.append("");
> stringBuilder.append("Default
> Page of my TEST
> application");
> stringBuilder.append("
> Click on link
> ");
> //stringBuilder.append(" ");
> stringBuilder.append(" <\"/file\">
> ");
>
> response.setEntity(new
> StringRepresentation(stringBuilder.toString(),
> MediaType.TEXT_HTML));
> }
> };
>
> router.attach("", mainpage);
> return router;
> }
>
> }
>
>
>
> --
> View this message in context:
> http://restlet-discuss.1400322.n2.nabble.com/Complexity-in-understanding-tp7579254p7579256.html
> Sent from the Restlet Discuss mailing list archive at Nabble.com.
>
> --
>
> http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=3086393
>

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

Re: Complexity in understanding

2014-08-06 Thread Tim Peierls
>From a brief look at your code, it looks like you're mixing up Restlets
with ServerResources. Restlets are created and added to the routing
structure in createInboundRoot, and typically have a lifetime that spans
that of the application, while a new ServerResource instance is created for
every request that is routed to its class. (You probably don't want to
create a new Directory each time a RootRoute is created to handle a
request, but that's what would happen at the moment.)

You're also creating a Directory instance and not using it in
createInboundRoot. A Directory is a Restlet that you can attach to; just
creating it doesn't do anything.

I suggest working from a tutorial example that *does* work for you, and
modifying it incrementally until something happens that you don't
understand. Then you can ask why that change broke things.

--tim


On Wed, Aug 6, 2014 at 1:40 PM, Shai Levit  wrote:

> So I am working on a more complex format from the tutorials but running
> into some odd issues and/or confusions that I don't quite understand.
> To simplify things, I attached my code. There are 3 java files (Main,
> Tracer and RootRoute).
> I am trying to get a better understanding on Router, Directory,
> Application, Root, Restlet and context.
> The code compiles fine, but I get an error:
>
> The filter org.restlet.engine.application.RangeFilter@5c4ef185 was
> executed without a next Restlet attached to it.
> 2014-08-06  13:37:420:0:0:0:0:0:0:1 -   -   8183
>  GET /   -   500 486 0   10
> http://localhost:8183   Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_4)
> AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1985.125 Safari/537.36
>  -
>
> --
>
> http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=3086335

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

Re: How to remove URL form thread name?

2014-06-06 Thread Tim Peierls
I can find only two instances of ThreadFactory in the Restlet codebase,
neither of which add a URL. The one in TaskService just replaces "pool"
with "restlet" in whatever name the default factory uses. The
LoggingThreadFactory uses the name "Restlet-XXX" where XXX is the hashcode
of the thread being returned.

That's not to say that Restlet isn't doing this, just that it probably
isn't happening for threads created via ThreadFactory.

Can you pinpoint what kind of threads are named with URLs?


On Fri, Jun 6, 2014 at 2:48 PM, Paul Sprague  wrote:

> Hello,
>
> Restlet appears to be changing the thread name to include a URL. While
> useful in general we cannot do this for security reasons since some URLs
> will contain sensitive data in the form of URL template parameters in the
> path section.
>
> Does anyone know how to disable this feature?
>
> Thanks
> Paul
>
> --
>
> http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=3080063
>

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

Re: Re: Authenticator and Component XML configuration

2014-05-14 Thread Tim Peierls
I don't think the nested router works the way you expect. You might be able
to tweak it to work, but consider creating a separate authenticator (and
tracer) instance for each guarded resource. I've written this up several
times, but I can never find my old postings when I need them, so I've
created a new pastebin example from yours to demonstrate the idea:

https://pastebin.com/wHYH1ci8

It compiles, but obviously won't actually run.

--tim


On Wed, May 14, 2014 at 7:33 AM, Sergio  wrote:

> Hi again,
>
> I want to protect some resources under /apps/{appid}:
>
> /apps/{appId}/object
>
> To avoid flooding I have pasted my code here:
>
> http://pastebin.com/gqc2dbFS
>
> I use the tracer filter to print the details of the request. The requested
> URI is:
>
> "Resource URI : http://localhost:8080/apps/1";
>
> Which, as far as I understood, according to my createInBoundRoute() method
> should be routed to AppServerResource class after pass through the
> authenticator and the tracer. However I got a 404 error. If I remove the
> credentials from my client, I got a 401 error, also the tracer print the
> information of the request correctly, then I think the first router is
> working properly.
>
> How can I implement a
>
> router1 -> authenticator ->tracer -> router2
>
> routing scheme?
>
> I want the authenticator to only guard resources under /apps/{appId}.
>
> Thanks in advance,
> Sergio
>
> --
>
> http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=3078331
>

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

Re: Re: Authenticator and Component XML configuration

2014-05-14 Thread Tim Peierls
On Wed, May 14, 2014 at 4:46 AM, Sergio  wrote:

> Can I attach the authenticator to only some of the methods of my
> resources? I.e. protect only PUT, POST, and DELETE while keeping GET
> public? Maybe using roles?
>

You can do per-resource or even per-method authorization: Remember that
authentication and authorization are separate steps, and that you can make
authentication optional. You can attach an authenticator at an outer level
and then in specific methods you can examine the authenticated user (if
any) and its roles to determine whether to allow or forbid a method.

The authenticated user can be obtained via getClientInfo().getUser().

You can even combine these approaches:

  Authenticator -> Authorizer -> ... -> Resource method ->
per-resource/method authorization

This might be useful, for example, if you have a common level of
authorization for a group of resources, but you have specific additional
authorization requirements on certain resources.



> If not, I'm thinking about splitting my services in two families of
> resources /apps/ which will implement authentication and /info which will
> be public. Do you think it is a good solution?
>

It depends on whether your resources naturally decompose into mutable and
read-only resources. If they do, that's probably preferable.

In my work I confine resource-specific authorization to a few places where
it is much more natural to say something like "You must have the ADMIN role
to PUT this resource, but anyone can GET it" than to break things up into
separate resources. Most of the time, though, I try to keep read-only
resources under separate paths in my routing structure.

--tim

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

Re: Transparent reverse proxying using org.restlet.routing.Redirector

2014-04-25 Thread Tim Peierls
Could this be addressed by turning off the DecoderService? There's no need
to perform the decompression in the first place, is there?


On Fri, Apr 25, 2014 at 8:13 AM, Arjohn Kampman <
arjohn.kamp...@vound-software.com> wrote:

> Hi Jerome, others,
>
> We've figured out what is going wrong by monitoring the traffic with
> Wireshark. The problem is indeed, as suspected, related to gzip
> encoding. I'll try to explain with one of the traces that we've captured:
>
> 1. Client sends a request to the proxy with "Accept-Encoding: gzip".
> 2. The proxy forwards the request to the back-end server adding
> "Accept-Charset: *" and "Accept-Language: *", but otherwise identical.
> 3. The backend server responds with 127 bytes of gzip encoded data,
> expanding to 145 bytes when decompressed.
> 4. The proxy forwards the response to the client, but sends the 145
> bytes of uncompressed data. The proxy did remove the "Content-Encoding:
> gzip" header so that part is ok. HOWEVER: the response still indicates
> "Content-Length: 127".
> 5. The client receives the response from the proxy and returns the first
> 127 bytes to the calling code, resulting in premature end-of-stream errors.
>
> I think there are two options to fix this:
> 1) Let Redirector replace/remove the Content-Length header from the
> response
> 2) Let Redirector forward the compressed body as-is.
>
> We're very much in favor of the second option as that would benefit both
> the proxy (less processing overhead) and the client (less network
> traffic). Is this something that can be addressed sometime soon? Not
> sure where to start looking for supplying a patch myself.
>
> Regards,
> Arjohn
>
> --
>
> http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=3077059
>

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

Re: Shutdown via REST PUT request

2014-04-23 Thread Tim Peierls
You can call Component.stop() asynchronously with a delay, so that the PUT
handler has a chance to complete. (Although I think POST captures the
intent better: You're POSTing a request to shut down the component.)

It could be as simple as this:

@Post
public String postShutdown(final String shutdownMessage) {
Runnable task = new Runnable() {
public void run() {
try {
TimeUnit.SECONDS.sleep(5);
} catch (InterruptedException ex) {
log.warn("Swallowing interruption in order to shut down");
} finally {
log.info("Shutting down with message: " + shutdownMessage);
theComponent.stop(); // and whatever other cleanup is needed
}
}
};
new Thread(task).start();
return "Shutdown request posted; will shut down in 5 seconds";
}

--tim


On Wed, Apr 23, 2014 at 1:15 PM, Sean Johnston wrote:

> I've a standalone application that I'm trying to implement a shutdown for.
> Initially I had this as a very simple Socket listen. However, wanting to
> put a more proper API in place I'm looking at REST and RESTlet is looking
> good.
>
> I've got it mostly working. That is, I have something that handles
> authentication and responds to a PUT request on http://host:port/shutdown.
> However, whilst this shuts down the various bits of my application, it
> doesn't shut down the REST server itself so the JVM keeps on running.
>
> I tried calling #stop on the Application but that doesn't seem to do
> anything. I can get it to terminate by calling stop on the top level
> Component, but that doesn't exit gracefully as the originating PUT handler
> throws exceptions.
>
> Is there a way to gracefully shut everything down in response to a PUT
> request?
>
> --
> Sean - Its a conical sort of effort
>

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

Re: Re: Re: Transparent reverse proxying using org.restlet.routing.Redirector

2014-04-18 Thread Tim Peierls
I don't have time to look at this, unfortunately.

I have Basic auth working with outbound redirection. I *don't *change the
way the headers are removed, but I do remove the challenge response.

// From my Redirector subclass:
@Override
protected void outboundServerRedirect(
Reference targetRef, Request request, Response response) {

// Unset challenge response that authentication puts in.
request.setChallengeResponse(null);
 super.outboundServerRedirect(targetRef, request, response);
}

Before I did this, I believe I had internal connector errors similar to
what you describe.

--tim


On Fri, Apr 18, 2014 at 4:14 AM, Primož Kokol wrote:

> Hi again,
>
> My next try was to remove all original headers (like default
> implementation do) and then preserver only Authentication header.
>
> So I replaced this line:
>
>
> https://github.com/restlet/restlet-framework-java/blob/2.2/modules/org.restlet/src/org/restlet/routing/Redirector.java#L407
>
> with call to this method:
>
> private void preserveHeaders(Request request)
> {
> Series headers = (Series)
> request.getAttributes().get(HeaderConstants.ATTRIBUTE_HEADERS);
> Series newHeaders = new
> Series(Header.class);
>
> for (String headerName : headersToPreserve) {
> Header headerToPreserve =
> headers.getFirst(headerName);
> if (headerToPreserve != null) {
> newHeaders.add(headerToPreserve);
> }
> }
>
> request.getAttributes().put(HeaderConstants.ATTRIBUTE_HEADERS, newHeaders);
> }
>
> where
>
> headersToPreserve =
> Arrays.asList(HeaderConstants.HEADER_AUTHORIZATION)
>
> After this change, the response from proxy is always:
>
> HTTP/1.1 1002 Internal Connector Error
> Date: Fri, 18 Apr 2014 08:01:10 GMT
> Accept-Ranges: bytes
> Server: Restlet-Framework/2.1.4
> Content-Length: 484
> Content-Type: text/html; charset=UTF-8
>
> I am somehow abandoning the idea of using Restlet as a transparent reverse
> proxy, but anyway, I've attached a small example of test implementation if
> someone will have time and willpower to look at it.
>
> Tim, thank you for your support!
>
> Any advices on how could I achieve Digest/Basic authentication to work on
> backend server when in front of it is a proxy are still welcome.
>
> --
>
> http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=3076691

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

Re: Re: Transparent reverse proxying using org.restlet.routing.Redirector

2014-04-17 Thread Tim Peierls
I'm guessing you have to very selective about which headers you allow to
remain.


On Thu, Apr 17, 2014 at 3:08 PM, Primož Kokol wrote:

> Tim, thanks for advice.
>
> That is actually one of the first things I've tried.
>
> After extending Redirector and overriding serverRedirect  method so that
> line which clears the headers was removed 1002 Internal Connector Error was
> always returned as response (from proxy) so I thought this was not the
> right approach.
>
> Any idea what could be cause of 1002 Internal Connector Error in this case?
>
> --
>
> http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=3076674
>

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

Re: Transparent reverse proxying using org.restlet.routing.Redirector

2014-04-17 Thread Tim Peierls
The code that does the header removal is here:

https://github.com/restlet/restlet-framework-java/blob/2.2/modules/org.restlet/src/org/restlet/routing/Redirector.java#L405-L413

If you're confident that that's what you want, you can extend Redirector
and override serverRedirect to do everything it normally *except* remove
those headers.

--tim



On Wed, Apr 16, 2014 at 9:52 AM, Primož Kokol wrote:

> I am trying to create a transparent reverse proxy using
> org.restlet.routing.Redirector.
>
> For the sake of simplicity let's say all I want to do is to redirect all
> requests pointing at
>
> http://localhost:80
>
> to be dispatched to another unrelated server:
>
> http://localhost:8080
>
> I've wrote a simple reverse proxy using Redirector (MODE_SERVER_OUTBOUND
> mode) and it actually works as expected in the sense that it dispatches
> requests properly and also handles redirects.
>
> But now let's say that resources at http://localhost:8080 are protected
> with Digest authentication mechanism.
>
> Now the problem is that headers in requests and responses when handled by
> Redirector are removed which makes Digest authentication mechanism unusable.
>
> From docs WRT MODE_SERVER_OUTBOUND:
> 
> Note that in this mode, the headers of HTTP requests, stored in the
> request's attributes, are removed before dispatching. Also, when a HTTP
> response comes back the headers are also removed.
> 
>
> Is there any way to leave headers intact so that end server (
> http://localhost:8080) and clients could communicate as there is no proxy
> in between?
>
> --
>
> http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=3076621
>

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

Re: Re: Re: Dynamic Templates/Routing

2014-03-31 Thread Tim Peierls
Glad to hear it!

Restlet isn't really doing much for you in this case, but at least this way
you're in a perfect position to add new functionality or an alternative web
API if the restrictions you currently operate under are ever lifted
slightly.

--tim


On Mon, Mar 31, 2014 at 4:56 AM, Tim  wrote:

> Hi Tim,
>
> Thanks very much for taking the time to knock up the example, I've made a
> very rough implementation and it seems to do exactly what I was after!
>
> Tim.
>
> --
>
> http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=3075533
>

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

Re: Re: Dynamic Templates/Routing

2014-03-28 Thread Tim Peierls
On Fri, Mar 28, 2014 at 9:48 AM, Tim  wrote:

> I'm wondering about your suggestion above, would I have to implement my
> own code to match the templates and extract the parameters or could I take
> advantage of the framework's ability to do that?
>

You could take advantage of the framework. Here's a sketch:

public class YourApplication extends Application {
...
@Override public Restlet createInboundRoot() {
// A map from path template (e.g. /path/to/resource/{resid}) to
// metadata about the corresponding stored procedure.
Map pathTemplateToStoredProcInfo = *...
from db ...*;

Router router = new Router(getContext());
for (String pathTemplate : pathTemplateToStoredProcInfo.keySet()) {
YourStoredProcInfo storedProcInfo =
pathTemplateToStoredProcInfo.get(pathTemplate);
router.attach(pathTemplate,
createStoredProcHandler(storedProcInfo));
}
return router;
}

private Restlet createStoredProcHandler(YourStoredProcInfo
storedProcInfo) {
final YourQueryTemplate queryTemplate =
storedProcInfo.createQueryTemplate();
final YourResultHandler resultHandler =
storedProcInfo.createResultHandler();
return new Restlet() {
@Override public void handle(Request request, Response
response) {
// Combine queryTemplate with method, attributes, and
parameters from request.
YourQuery query = queryTemplate.createQuery(
request.getMethod(), // i.e., GET, POST, PUT, or
DELETE
request.getAttributes(), // e.g., { "resid" : "ABC123" }
request.getResourceRef().getQueryAsForm() // e.g.,
"?sortBy=date"
);
YourResults results = query.execute();
response.setStatus(resultHandler.getStatus(results));
if (response.getStatus().isSuccess()) {
Representation rep =
resultHandler.createRepresentation(results);
response.setEntity(rep);
} else {
// ... error handling
}
}
};
}
}

This of course just pushes the hard part into YourStoredProcInfo,
YourQueryTemplate, YourQuery, YourResultHandler, and YourResults, but this
way the hard parts are isolated from the Restlet framework code.

It also leaves out all sorts of details, like error handling, client-info,
caching, etc., but it wouldn't be hard to adapt this basic idea to include
them.


PS. I understand now what you mean about the coupling, hopefully but
> explanation answers your query.
>

I think so. Sounds like the legacy nature of the enterprise (and its
people!) is so restrictive that you are forced into a design that you
wouldn't consider under normal circumstances.

--tim

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

Re: Dynamic Templates/Routing

2014-03-27 Thread Tim Peierls
You don't need to use Restlet ServerResource for this. You can write a
custom Restlet with an initialization method that reads and caches the
mapping from path to procedure, and a handle(Request, Resource) method that
extracts path and parameters from the request and uses the cached mapping
to call the appropriate procedure.

Restlet ServerResources are more appropriate when the behavior of resources
is defined in code, rather than in a database:

public class MyResource extends ServerResource {
/** How to handle GET requests on this resource. */
@Get public String getSomeText() {
String id = getAttribute("id");
return lookupSomeTextFromId(id);
}
String lookupSomeTextFromId(String id) { ... }
}

so that the mapping from path to resource behavior can be set up with calls
to Router.attach:

public class MyApplication extends Application {
@Override public Restlet createInboundRoot() {
Router router = new Router(getContext());
...
router.attach("/path/to/my/resource/{id}", MyResource.class);
...
return router;
}
}

I think it's usually a very good idea to decouple the resource structure
and behavior from the data. I find it surprising that you would want to do
otherwise.

--tim



On Thu, Mar 27, 2014 at 1:33 PM, Tim  wrote:

> I'm a new RESTlet user and I was wondering if it's possible to route
> dynamically based on templates retrieved from a database in order to allow
> new templates to be added without changing any code? My plan is to have a
> table of URL templates together with their mappings, per request type, to
> stored procedure calls. The resource would then construct the stored
> procedure call based on which template was matched and map the parameters
> in the template to the procedure parameters.
>
> For example:
>
> URL Request Stored Procedure
> /customers  GET CustomersGet()
> POSTCustomerCreate(name...)
> /customers/{cus}GET CustomersGetById(cus)
> /invoices   GET InvoicesGet()
> /invoices/{inv} GET InvoicesGetById(inv)
>
> I wanted to have a single resource class that would be called for all
> templates that could, based on the template that matched and the request,
> look-up the stored procedure and construct the call to it dynamically by
> taking the parameters extracted by the framework and any supplied in the
> request body and matching them to the stored procedure parameters.
> Unfortunately I couldn't find a way to get the template that was matched.
>
> The background behind this is that I am trying to create a system whereby
> new web applications can be developed without changing any Java code,
> simply by implementing the relevant stored procedures in the database and
> changing the configuration (it's not a problem if a server restart is
> required). All resources, such as HTML pages, JPEGs, Freemarker templates
> etc. are stored in the backend database as BLOBs are are served from there
> so that they can be easily modified and new ones uploaded.
>
> Thanks in advance,
>
> Tim.
>
> --
>
> http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=3075356
>

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

Re: How to : use System.out or logger in Restlet

2014-03-19 Thread Tim Peierls
The code in createInboundRoot is called once at application startup, so any
logging in it is only called once.

It sounds like you're trying to get logging each time a request is handled.
For that you need to instrument the Restlets themselves, either in their
handle() methods or in more specific methods. For Filters, you can add
logging in the beforeHandle and afterHandle methods.

Incidentally, you can just use getLogger(). There's no need for
System.out.print.

--tim


On Wed, Mar 19, 2014 at 1:14 AM, saurabh narayan singh <
cenasaur...@gmail.com> wrote:

> Hi,
> i have restlet and i want to check the intermediate values in various
> methods, for instance refer to the code below
>
>  @Override
> public synchronized Restlet createInboundRoot(){
> Authenticator auth = new myAuthenticator();
> Validator val = new myValidator(getContext());
> Filter fil1 = new myFilter();
> Router r = new Router();
> r.attach("/hellowrld",HelloWorldResource.class);
> fil1.setNext(auth);
>
> /***See here***/
> System.out.println("hello world");
> Logger.getLogger(TestRestlet.class.getName()).log(Level.SEVERE, null, "
> Hello");
>
> auth.setNext(val);
> val.setNext(r);
> return fil1;
> }
>
> Now when i start the service, it prints and logs once, but after that,
> even if i reinvoke the restlet it won't print.
>
> Same is the case with Filter and validator, i was trying to check whether
> or not validatePresence is being called by inserting a S.O.P there, but no
> output.
>
> Q 1. Whats the reason behind this behavior ?
> Q 2. How do we overcome this, can we use any other Logger or am i looking
> at the wrong place ?
>
> Any help will be appreciated,
>
> Regards,
> Saurabh Narayan Singh
>
> --
>
> http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=3074802
>

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

Re: How to : Different validation check for different mappings but same filter

2014-03-12 Thread Tim Peierls
On Wed, Mar 12, 2014 at 3:18 AM, saurabh narayan singh <
cenasaur...@gmail.com> wrote:

> I have multiple mappings in the restlet which are supposed to pass through
> the same filter and authenticator, but for the different mappings i have to
> use validationPresence(attribute) for different attributes, refer the code
> below for better understanding of the question :
>
> @Override
> public synchronized Restlet createInboundRoot(){
> Authenticator auth = new myAuthenticator();
> Validator val = new myValidator(getContext());
> Filter fil1 = new myFilter();
> Router r = new Router();
> r.attach("/hellowrld",HelloWorldResource.class);
> r.attach("/hello",HelloWorldResource1.class);
> fil1.setNext(auth);
> auth.setNext(val);
> val.setNext(r);
> val.validatePresence("Name");
> return fil1;
> }
>
> but here both mappings will pass through validatePresence("Name"), what i
> want to achieve is pass "/hellowrld" thru one validator and "/hello" thru
> other one . What can i do for that ?
> Any help will be appreciated
>

In that case, you need a different Validator instance for each attachment.
It's probably best to define a helper method for this. That way your
createInboundRoot can be simplified as follows:

@Override
public synchronized /* see below */ Restlet createInboundRoot(){
Router router = new Router(getContext());
router.attach("/hellowrld", validateWith("Name2",
HelloWorldResource.class));
router.attach("/hello", validateWith("Name",
HelloWorldResource1.class));

Authenticator auth = new MyAuthenticator(getContext());
auth.setNext(router);

Filter filter = new MyFilter(getContext());
filter.setNext(auth);

return filter;
}

private Restlet validateWith(String key, ServerResource target) {
Validator validator = new MyValidator(getContext());
validator.validatePresence(key);
validator.setNext(target); // assuming Validator extends Filter
return validator;
}

Note that I've added Context arguments to the constructors. You don't have
to do this, but it's nice to have the option of retrieving context
information later without changing the wiring code.

Side issue: I'm pretty sure you *don't *need the synchronized keyword on
createInboundRoot. All the state you're accessing (apart from the Context,
which is already safe for concurrent access) is constructed in the method
itself and thus confined to one thread.

I use this technique to vary the authorization roles required by different
resources in the same application, e.g.:

router.attach("/path/to/guarded", authenticatorFor(InventoryResource.class,
ADMIN_ROLE, INVENTORY_ROLE));

--tim

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

Re: RESTLET - chaining a validator and filter, why does it surpasses the filter?

2014-03-11 Thread Tim Peierls
On Tue, Mar 11, 2014 at 3:29 AM, saurabh narayan singh <
cenasaur...@gmail.com> wrote:

> I have a restlet in which i want to chain a validator and filter one after
> the other in the code. The code goes something like this
>
> @Override
> public synchronized Restlet createInboundRoot()
> {
> Router router = new Router();
> Validator val = new  ParameterValidator(getContext());
>
> Filter fil = new MYFilter(getContext());
> router.attach("/HelloWorld", HW.class);
> fil.setNext(val);
> val.setNext(router);
> val.validate("Name",true,"^[a-z0-9A-Z]+$");
> return val;

*// Why not the following line instead?*

*// return fil;*
> }
> but this doesn't checks in the filter, just works on the validator and
> then comes out.
>

What happens if you return fil instead of val in the code above? As it
stands, you're leaving the filter out.

--tim

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

Re: Re: Restlet, jackson and @JsonTypeInfo

2014-01-27 Thread Tim Peierls
What arguments are you passing to @JsonTypeInfo?


On Mon, Jan 27, 2014 at 6:57 AM, Jon Finanger  wrote:

> I'm trying to figure out how to get the android client to automatically
> convert the representation into the correct Objecttype without using
> mapper.convertValue(...)
>
> When looking at the representation sent from the server i see that the
> type information is not present.
> [{"name":"site1","siteOwnerId":1,"siteId":1,"location":"vega1","lastOnline":null,"port":6194,"bindAddress":"","alarmFlag":false,"onlineStatus":true}...
>
> so no wonder it cant auto-convert. I've added @JsonTypeInfo to the remote
> interface and @Get("json") on the method, but see no effect of that.
>
> When choosing xml as the representation the typeinfo is present.
>
> --
>
> http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=3072127
>

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

Re: Restlet, jackson and @JsonTypeInfo

2014-01-07 Thread Tim Peierls
One problem is that the generic type formal parameter T doesn't convey
enough information for the annotation-based code to reconstruct the correct
result type. Try creating a type that embeds the actual value of the type
parameter, e.g., SiteDaoArrayList extends ArrayList (or
SiteDaoArrayList contains List), and using that type as the return
type of the @Get-annotated method.

--tim


On Tue, Jan 7, 2014 at 7:28 AM, Jon Finanger  wrote:

> I was able to convert the LinkedHashMap values to ArrayList using the
> ObjectMapper in my clientcode:
> ObjectMapper mapper =
> jacksonConverter.getObjectMapper();
> ArrayList sites =
> mapper.convertValue(tmp, new TypeReference>() {});
>
> But getting this with a simple annotation i'm not able to figure out yet.
>
> --
>
> http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=3071291
>

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

Re: Authenticator for multiple authentication schemes

2014-01-05 Thread Tim Peierls
Looking at older conversations about this, it might be a failure to
override the login form path. Failing that, I can only offer examples of
what works for me.

I had to extend CookieAuthenticator to provide standard challenge behavior.
I still use this extension (further extended for my purposes), but it might
not be necessary any more:

https://gist.github.com/Tembrel/8271777

Here's a Restlet application to serve login and logout resources and a
login form resource:

https://gist.github.com/Tembrel/8271674

LoginFormResource in my case just serves a Freemarker template
representation of a login form:

https://gist.github.com/Tembrel/8271929

The Freemarker template is something like this:

https://gist.github.com/Tembrel/8271952

HTH


On Fri, Jan 3, 2014 at 9:31 AM, Fabian Mandelbaum wrote:

> Hello there,
>
> I've updated to Reslet 2.2-M6, replaced my HTTP Basic Guard with
> CookieAuthenticator, and when trying to access a guarded resource, instead
> of the login dialog I got HTTP 401 and this on logs:
>
> 2014-01-03 11:25:24 0:0:0:0:0:0:0:1%0 - 0:0:0:0:0:0:0:1%0 9000 GET
> /res/dojo-release/dijit/themes/claro/images/tooltipGradient.png - 200 - 0
> 6 http://localhost:9000 Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9;
> rv:26.0) Gecko/20100101 Firefox/26.0
> http://localhost:9000/res/dojo-release/dijit/themes/claro/claro.css
>
> 2014-01-03 11:25:25 0:0:0:0:0:0:0:1%0 - 0:0:0:0:0:0:0:1%0 9000 GET
> /workspaces/ - 401 424 0 http://localhost:9000 Mozilla/5.0 (Macintosh;
> Intel Mac OS X 10.9; rv:26.0) Gecko/20100101 Firefox/26.0
> http://localhost:9000/
>
> Challenge scheme HTTP_Cookie not supported by the Restlet engine.
>
> 2014-01-03 11:25:25 0:0:0:0:0:0:0:1%0 - 0:0:0:0:0:0:0:1%0 9000 GET
> /favicon.ico - 401 424 0 http://localhost:9000 Mozilla/5.0 (Macintosh;
> Intel Mac OS X 10.9; rv:26.0) Gecko/20100101 Firefox/26.0 -
>
> Challenge scheme HTTP_Cookie not supported by the Restlet engine.
>
> 2014-01-03 11:25:25 0:0:0:0:0:0:0:1%0 - 0:0:0:0:0:0:0:1%0 9000 GET
> /favicon.ico - 401 424 0 http://localhost:9000 Mozilla/5.0 (Macintosh;
> Intel Mac OS X 10.9; rv:26.0) Gecko/20100101 Firefox/26.0 -
>
> Challenge scheme HTTP_Cookie not supported by the Restlet engine.
>
> What's going on? What am I doing wrong?
>
> Thanks in advance for your help.
>
>
>
>
> On Fri, Jan 3, 2014 at 7:53 AM, Fabián Mandelbaum 
> wrote:
>
>> Hello Tim,
>>
>> thanks for your answers.
>>
>> I've tried, using the example in the Restlet IN ACTION book as a guide,
>> what you proposed, the two chained authenticators, and it does not work.
>>
>> I've chained them like this:
>>
>> cookieauth -> httpauth -> guarded_resources
>>
>> I'll test with Restlet 2.2 today, though I don't know if we can switch
>> our stable project to the still unstable Restlet 2.2...
>>
>> BTW, Restlet ppl, any idea on when 2.2 will become 'final'? The roadmap
>> page on the Restlet website states Q3 2013... and that's about 3 months ago
>> now...
>>
>> Thanks.
>>
>>
>> On Thu, Jan 2, 2014 at 3:32 PM, Tim Peierls  wrote:
>>
>>> Not sure how much of this works in Restlet 2.1 -- I use
>>> CookieAuthenticator successfully with Restlet 2.2.
>>>
>>>
>>> On Thu, Jan 2, 2014 at 1:32 PM, Tim Peierls  wrote:
>>>
>>>> It should be possible to chain two different Authenticator instances,
>>>> with optional = true on the first, and multiAuthenticating = false on the
>>>> second. If the first one succeeds, the second should see
>>>> ClientInfo.isAuthenticated() == true and bypass its operation. If the first
>>>> one fails, the second one sees ClientInfo.isAuthenticated() == false and
>>>> does *not* bypass its operation.
>>>>
>>>> But before you try that, consider using 
>>>> CookieAuthenticator<http://restlet.org/learn/javadocs/2.2/jee/ext/org/restlet/ext/crypto/CookieAuthenticator.html>--
>>>>  much of the implementation is parameterized and/or overridable.
>>>>
>>>>
>>>> On Thu, Jan 2, 2014 at 7:29 AM, Fabian Mandelbaum <
>>>> fmandelb...@gmail.com> wrote:
>>>>
>>>>> Hello there,
>>>>>
>>>>> our Restlet-based application needs to have users authenticated using
>>>>> both cookies and http basic (hopefully to be switched to digest soon)
>>>>> authentication (Actually it's either cookies or http auth, but see below
>>>>> for auth flow). We also use our own verifier storing credentials on JCR 
>>>>> and
>>&g

Re: Authenticator for multiple authentication schemes

2014-01-02 Thread Tim Peierls
Not sure how much of this works in Restlet 2.1 -- I use CookieAuthenticator
successfully with Restlet 2.2.


On Thu, Jan 2, 2014 at 1:32 PM, Tim Peierls  wrote:

> It should be possible to chain two different Authenticator instances, with
> optional = true on the first, and multiAuthenticating = false on the
> second. If the first one succeeds, the second should see
> ClientInfo.isAuthenticated() == true and bypass its operation. If the first
> one fails, the second one sees ClientInfo.isAuthenticated() == false and
> does *not* bypass its operation.
>
> But before you try that, consider using 
> CookieAuthenticator<http://restlet.org/learn/javadocs/2.2/jee/ext/org/restlet/ext/crypto/CookieAuthenticator.html>--
>  much of the implementation is parameterized and/or overridable.
>
>
> On Thu, Jan 2, 2014 at 7:29 AM, Fabian Mandelbaum 
> wrote:
>
>> Hello there,
>>
>> our Restlet-based application needs to have users authenticated using
>> both cookies and http basic (hopefully to be switched to digest soon)
>> authentication (Actually it's either cookies or http auth, but see below
>> for auth flow). We also use our own verifier storing credentials on JCR and
>> set it as the defaultVerifier() for the app's context in
>> createInboundRoot().
>>
>> I've seen that the ChallengeAuthenticator class only accepts one
>> authentication method on its constructor so, a priori, one cannot have a
>> Guard that uses more than one auth method.
>>
>> The authentication workflow with the Guard/Authenticator our app needs
>> would be something like this:
>>
>> 1) If cookie is present, verify it
>> 2) if cookie verification passes, all OK, continue processing request
>> 3) if cookie verification fails, use HTTP authentication
>>
>> Is this possible with Restlet 2.1?
>>
>> I'd appreciate any guide/pointer/idea you may have. Thanks in advance.
>>
>> --
>> Fabián Mandelbaum
>> IS Engineer
>>
>
>

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

Re: Authenticator for multiple authentication schemes

2014-01-02 Thread Tim Peierls
It should be possible to chain two different Authenticator instances, with
optional = true on the first, and multiAuthenticating = false on the
second. If the first one succeeds, the second should see
ClientInfo.isAuthenticated() == true and bypass its operation. If the first
one fails, the second one sees ClientInfo.isAuthenticated() == false and
does *not* bypass its operation.

But before you try that, consider using
CookieAuthenticator--
much of the implementation is parameterized and/or overridable.


On Thu, Jan 2, 2014 at 7:29 AM, Fabian Mandelbaum wrote:

> Hello there,
>
> our Restlet-based application needs to have users authenticated using both
> cookies and http basic (hopefully to be switched to digest soon)
> authentication (Actually it's either cookies or http auth, but see below
> for auth flow). We also use our own verifier storing credentials on JCR and
> set it as the defaultVerifier() for the app's context in
> createInboundRoot().
>
> I've seen that the ChallengeAuthenticator class only accepts one
> authentication method on its constructor so, a priori, one cannot have a
> Guard that uses more than one auth method.
>
> The authentication workflow with the Guard/Authenticator our app needs
> would be something like this:
>
> 1) If cookie is present, verify it
> 2) if cookie verification passes, all OK, continue processing request
> 3) if cookie verification fails, use HTTP authentication
>
> Is this possible with Restlet 2.1?
>
> I'd appreciate any guide/pointer/idea you may have. Thanks in advance.
>
> --
> Fabián Mandelbaum
> IS Engineer
>

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

Re: Configuration of resources in Restlet Router

2013-12-19 Thread Tim Peierls
On Thu, Dec 19, 2013 at 11:27 AM, Stephane Fellah wrote:

> I am currently building a Restlet application where I need to build the
> router from a configuration file. The router has different endpoints using
> the SAME resource but configured with different settings defined in a
> configuration file. Usually routers are defined using template route with
> target resource class. This would not work in my case, as the resource
> needs to be initialized with the different settings. I can see one way to
> solve this problem : using a Filter that set the initialization parameters
> in the context, the filter with then forward to the target resource. The
> target resource will read the initialization parameters from context in the
> doInit(). Is it the best practice to handle this use case ? Should I use
> Restlet or Finder instead of Filter.
>

That's a reasonable way to go.

Another way that avoids passing values via the Context is to use custom
Finder that creates and initializes the resource in an overridden
create(Class, Request, Response), either by calling
super.create(targetClass, request, response) and setting the initialization
parameters on the returned value, or by re-implementing create(Class,
Request, Response) entirely.

--tim

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

Re: Restlet gets funding to accelerate APISpark growth!

2013-11-13 Thread Tim Peierls
Very exciting!


On Wed, Nov 13, 2013 at 3:12 PM, Jerome Louvel  wrote:

> Hi all,
>
> Finally, we can share those news:
>
> http://blog.restlet.com/2013/11/13/restlet-gets-funding-to-accelerate-apispark-growth/
>
> From an open source point of view, this will give us extra resources to
> move the R&D on the framework forward. In the short term, Thierry Boileau
> will dedicate fixed time every week to complete version 2.2 and start
> working on the 3.0 milestone.
>
> Their is also a great synergy with APISpark which is fully built on top of
> the Restlet Framework and lets you export your web APIs as Restlet
> Framework source code, to prevent lock-in.
>
> As this is a usual concern in such events, no change in our open source
> licensing scheme is expected following this funds raising :)
>
> Best regards,
> Jerome
>
>

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

Re: Re: Re: Re: How to use CookieAuthenticator?

2013-07-12 Thread Tim Peierls
On Fri, Jul 12, 2013 at 9:32 AM, Johanneke Lamberink
wrote:

> But what would I put in there? Let's call it a sessionID, regardless of
> the actual content. The only way this will give the protection I need
> requires some sort of state on the server, doesn't it?
>

You could store some information about the request that is likely to be
true of subsequent legitimate requests by the same client but not of a
forged one, like the client's IP address. That doesn't require state on the
server. It's by no means perfect, but it would force attackers to work
harder to spoof client requests.



> So I guess my question is, is it possible to protect against this specific
> attack while maintaining a stateless server? Or did we already forfeit that
> when we started setting cookies?
>

Aren't these three levels of protection sufficient?

   - Difficulty of obtaining a valid cookie in the first place.
   - Difficulty of using a valid cookie before it expires.
   - Difficulty of spoofing client-specific info.

If an attacker is able to get to a client's cookie store, is not bothered
by the expiration time limit, and can make requests with ClientInfo that
matches the real client, then it's highly likely that the client is already
deeply compromised, so keeping track of sessions on the server side doesn't
really help: The attacker could just issue its requests in a valid session.

So my answer is no, I don't think you give up security in any significant
way by having a stateless server. If it still bothers you, though, why not
isolate a small stateful service exclusively to address authentication
concerns, leaving the rest of your server stateless?

--tim

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

Re: Re: Re: How to use CookieAuthenticator?

2013-07-12 Thread Tim Peierls
You can override the formatCredentials and parseCredentials methods to
store custom information in the (encrypted) cookie value.

On Fri, Jul 12, 2013 at 9:12 AM, Johanneke Lamberink
wrote:

> Thanks for the reply. Yes, treating old cookies as stale is what I do now.
> I was wondering if there is another way to prevent re-use of an old cookie.
>
> --
>
> http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=3060332
>

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

Re: Re: How to use CookieAuthenticator?

2013-07-12 Thread Tim Peierls
You can always have the Verifier treat cookies with creation times too far
in the past as stale. A legitimate client will be able to provide the
credentials again; an impostor with a stolen cookie won't.

--tim

On Fri, Jul 12, 2013 at 6:01 AM, Johanneke Lamberink
wrote:

> When a user requests a logout, the 'maxAge' of the cookie is set to 0,
> which will tell the browser to delete it.
>
> However, when a cookie was stolen, this stolen cookie still exists, and
> can still be used to log in. After all, the cookie contains all the
> information needed for logging in, no additional information is needed at
> all.
>
>
> But maybe I'm looking for a problem that doesn't exist?
>
> --
>
> http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=3060328
>

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

Re: Getting lot of Stream closed IOExceptions under heavy load

2013-07-08 Thread Tim Peierls
That's probably it, but also make sure that you aren't creating a new
ObjectMapper for each representation.

--tim

On Mon, Jul 8, 2013 at 9:05 AM, Martin Odhelius  wrote:

> I actually may have found what was causing this. I was using an
> JacksonRepresentation that used an ObjectMapper where
> JsonGenerator.Feature.AUTO_CLOSE_TARGET were not set to false.
>
> --
>
> http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=3060007
>

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

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

2013-04-28 Thread Tim Peierls
On Sun, Apr 28, 2013 at 12:58 PM, Grant  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=4447&dsMessageId=3054497

Re: Re: Re: Re: Dynamic Redirector

2013-04-28 Thread Tim Peierls
On Sun, Apr 28, 2013 at 11:42 AM, Grant  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 Function targetMapper;
public MyRedirector(Context context, Function
targetMapper, int mode) {
super(context, "", 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=4447&dsMessageId=3054490

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  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=4447&dsMessageId=3054458
>

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

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  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=4447&dsMessageId=3054455
>

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

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  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=4447&dsMessageId=3053410
>

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

Re: 2.2m1 which jars for json (or other formats)

2013-03-06 Thread Tim Peierls
I don't use jaxb, so my list is different. I do use the stuff in csv,
smile, and xml, so I expect to need those jars.

The one thing I didn't expect is the yaml jar, because I'm not using yaml
directly, but it turns out that dependency is from another library.

--tim

On Wed, Mar 6, 2013 at 1:15 PM, Jim Trainor wrote:

> I found I still needed org.restlet.ext.jaxb.jar.  If I only include
> com.fasterxml.jackson.jaxb.jar then I get xml conversion of jaxb classes
> but the xml schema is not included in the generated xml (i.e. the
> xmlns="..." attribute).  That causes jaxb clients to fail to deserialize
> the xml.  Including org.restlet.ext.jaxb.jar resolves that.
>
> More documentation about how to knit it all together would help.
>
> --
>
> http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=3050439
>

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

Re: CookieAuthenticator - Referencing to another URI after succesfull authentiaction (restlet 2.1.2)

2013-03-06 Thread Tim Peierls
In particular, here is the commit that fixes the problem:

https://github.com/restlet/restlet-framework-java/commit/e184e3586778ca3c799b456262f32bb0ac7d5706

On Wed, Mar 6, 2013 at 10:47 AM, Tim Peierls  wrote:

> It's possible that you're getting an older version of CookieAuthenticator
> that doesn't implement the targetUri feature. For details on how to add it
> yourself, see this discussion:
>
>
> http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=3038041
>
>
> On Wed, Mar 6, 2013 at 8:31 AM, Elad Kravi wrote:
>
>> Hi,
>> I am using Restlet 2.1.2.
>> After the first succesfull authentication with CookieAuthenticator
>> (sending the credentails in the request body) I want the server to forward
>> my request to another URL.
>> I have tries with adding query parameter but it didn't work. can someone
>> help?
>> Here is the request I'm sending:
>>
>> POST http://localhost:8008/login?targetUri=/business/bla HTTP/1.1
>> Relevant headers
>> username=me&password=me
>>
>> --
>>
>> http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=3050425
>>
>
>

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

Re: CookieAuthenticator - Referencing to another URI after succesfull authentiaction (restlet 2.1.2)

2013-03-06 Thread Tim Peierls
It's possible that you're getting an older version of CookieAuthenticator
that doesn't implement the targetUri feature. For details on how to add it
yourself, see this discussion:

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


On Wed, Mar 6, 2013 at 8:31 AM, Elad Kravi  wrote:

> Hi,
> I am using Restlet 2.1.2.
> After the first succesfull authentication with CookieAuthenticator
> (sending the credentails in the request body) I want the server to forward
> my request to another URL.
> I have tries with adding query parameter but it didn't work. can someone
> help?
> Here is the request I'm sending:
>
> POST http://localhost:8008/login?targetUri=/business/bla HTTP/1.1
> Relevant headers
> username=me&password=me
>
> --
>
> http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=3050425
>

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

Re: Unable to setup a filter

2013-02-27 Thread Tim Peierls
Hard to tell without code.

On Wed, Feb 27, 2013 at 6:16 AM, Julien Richard-Foy
wrote:

> Hi,
>
> I wrote a filter that adds some HTTP headers to all responses (using the
> `afterHandle` hook).
>
> The filter is created at startup (by Spring) and is put just between an
> authentication filter and the main router (SpringBeanRouter). (I mean, the
> “next” restlet of the authentication filter is my filter, and the “next”
> restlet of my filter is the Spring router)
>
> When I start the application I can get my resources, the authentication
> filter works perfectly but the `afterHandle` method of my filter is not
> called (by the way, the `beforeHandle` method is not called either).
>
> What did I miss in my configuration?
>
> Julien
>
> --
>
> http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=3049936
>

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

RE: Jackson extension performance question

2013-01-29 Thread Tim Peierls
You can have one ObjectMapper for all resources, and there is no need to use 
the Restlet Guice integration stuff. All you have to do is (somewhere) register 
a singleton LocalJacksonConverter with the Restlet Engine (and remove any 
existing JacksonConverter). See the method in my example annotated with @Inject.

Remove that method, the @Singleton class annotation, and the javax.inject 
imports from my example, and it should compile for you.

That's assuming you're using Jackson 2.x. If you're using Jackson 1.x, you'll 
have to adjust the imports and maybe some details of the ObjectMapper call.

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


Re: Restlet web sites are down for maintenance

2013-01-28 Thread Tim Peierls
On Mon, Jan 28, 2013 at 9:39 AM, Jerome Louvel  wrote:

>
>- Daisy wiki is being migrated to GitHub
>   - we generate static HTML pages on http://restlet.org instead
>   - easier to maintain via GitHub MarkDown files
>   - easier to contribute via GitHub Pull Requests
>
> That's great to hear!

--tim

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

Re: Restlet interfaces with generic types

2013-01-24 Thread Tim Peierls
I don't understand what you're trying to do, but the issue seems to be
fixed. I've added a follow-up on the issue in GitHub.

On Thu, Jan 24, 2013 at 10:06 AM, Konrad Güßbacher  wrote:

> Hi everyone,
>
> is there meanwhile a fit for this issue:
>
> https://github.com/restlet/restlet-framework-java/issues/426
>
> by Restlet folks or an invididual in the community?
>
> To avoid repetitve work on typed Restlet Resources and to enable rapid
> prototyping I am working on creating a generic vertical funnel through our
> layers ( persistence manager > restlet router url > restlet ServerResource
> > restlet Resource > client manager for entities > eventually even MVC
> model ) and I think I need this to solve it.
>
> Or would you have another idea how I can have a generic Resource and
> funnel any of my entities through it?
>
> Regards,
> Conrad
>
> --
>
> http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=3045753
>

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

RE: Jackson extension performance question

2013-01-18 Thread Tim Peierls
Sorry, that link should be:

http://tembrel.blogspot.com/2012/03/restlet-guice-extension-considered.html

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


RE: Jackson extension performance question

2013-01-18 Thread Tim Peierls
It's much better to re-use a single ObjectMapper instance, or a small set of 
differently configured ObjectMapper instances.

Here's an example of using dependency injection to provide a single 
ObjectMapper that is then re-used by JacksonRepresentations created by a JSON 
converter:

https://github.com/Tembrel/restlet-misc/blob/master/src/main/java/net/peierls/restlet/misc/LocalJacksonConverter.java

You can use the same approach in your resources by injecting a singleton 
ObjectMapper into your resources (see, for example, 
http://tembrel.blogspot.com/2012/03/restlet-guice-extension-considered.html) 
and using a custom extension of JacksonRepresentation that uses that 
ObjectMapper.

Note that I'm using Jackson 2.x with a Restlet Jackson extension that works 
with Jackson 1.9, which is why my extension of JacksonRepresentation doesn't 
simply override createObjectMapper().

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


Re: Re: another CookieAuthenticator mystery

2012-12-21 Thread Tim Peierls
I've fleshed this out, probably in too much detail:

I have a Component made up of several cooperating Applications. There is a
need for common authentication (MyAuthenticator extending
CookieAuthenticator) across all applications. Rather than have each
Application duplicate the login and logout handling logic, I have a
separate AuthApplication at /auth. Let's say I have a SearchApplication
under /search, with a resource that needs authentication and authorization
at /search/private, PrivateServerResource.

SearchApplication.createInboundRoot looks like this in part:

// I have helper functions to do this wiring, but inlined here:
Authorizer authorizer = new MyAuthorizer(...);
authorizer.setNext(PrivateServiceResource.class);
Authenticator authenticator = new MyAuthenticator(...);
authenticator.setNext(authorizer);

router.attach("/private", authenticator);

MyAuthenticator's loginFormPath is /auth/loginForm, so the challenge on an
attempt to access /search/private redirects to:

/auth/loginForm?targetUri=/search/private  (except the query value is
encoded)

The form that is returned from this POSTs the user-supplied credentials to:

/auth/login?targetUri=/search/private  (except the query value is
encoded)

So far so good. This last URI is handled by AuthApplication, which has a
createInboundRoot like this:

// The loginForm resource should not have authentication.
router.attach("/loginForm", LoginFormServerResource.class);
// handles the login form with Freemarker template

Authenticator authenticator = new MyAuthenticator(...);
authenticator.setNext(new Restlet() {
@Override public void handle(Request request, Response response) {
getLogger().fine("Handling no-op restlet");
}
});
router.attachDefault(authenticator);

The /auth/login?... URI is handled by the default route, and is detected by
CookieAuthenticator.isLoggingIn(req, rsp) and sent to
CookieAuthenticator.login(req, rsp), so that the user is redirected to the
targetUri in beforeHandle, without ever touching the next Restlet.
Similarly with logout.

My original observation was that even though the authenticator's next
(no-op) Restlet isn't used, if you omit the call to setNext above, you get
an error message.

--tim


On Fri, Dec 21, 2012 at 12:20 PM, Thierry Boileau wrote:

> Hi Tim,
>
> I've read your mail, and have a question about this :
> >an instance of my CookieAuthenticator extension around a
> >Restlet that does nothing. (If you leave out this vacuous Restlet, the
> >machinery complains about a Filter with no target.)
>
> Clearly, a filter is meant to transmit the request/response to a next
> Restlet.
> In this case, when a request is authenticated, I wonder what is the
> behaviour of the CookieAuthenticator.
> This is the end of the year, I'm a little bit tired, so my question may be
> confuse. :)
>
> Best regards,
> Thierry Boileau
>
> --
>
> http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=3038051
>

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

Re: Re: another CookieAuthenticator mystery

2012-12-21 Thread Tim Peierls
Sounds good, so if you haven't provided a login form, it more or less
reverts to ChallengeAuthenticator's behavior? (Except the scheme won't be
supported, so it won't actually work, but you'll have some clue as to
what's going on.)

--tim

On Fri, Dec 21, 2012 at 11:57 AM, Thierry Boileau wrote:

> Hello Tim,
>
> I'm sorry for the delay of my answer.
> It clearly appears to me that the promised feature were not implemented,
> and therefore were lacking from the initial contribution.
> Thanks a lot for reporting this issue, I've added your contribution, with
> a small adjustement : I test the "loginFormPath" value. When it is null, we
> cannot redirect, therefore it calls super#challenge(Response, boolean).
>
> Best regards,
> Thierry Boileau
>
> --
>
> http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=3038041
>

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

Re: Re: dependencies in 2.2-SNAPSHOT

2012-12-21 Thread Tim Peierls
Excellent, thanks!

On Fri, Dec 21, 2012 at 8:58 AM, Thierry Boileau wrote:

> Hello Tim,
>
> thanks for reporting these issues.
>
> I've updated the libraries:
>  - precised the stax2api version => 3.1.1
> I've updated the servlet library
>  - precised the available version of servlet api in maven central
> repository : 3.0-alpha-1 ...
>
> Best regards,
> Thierry Boileau
>
> --
>
> http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=3038000
>

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

Re: expect/continue handshake

2012-12-12 Thread Tim Peierls
More precisely: I started to make an abstract filter for server-side
handling of Expect-Continue:

@Override protected int beforeHandle(Request request, Response
response) {
for (Expectation expectation :
request.getClientInfo().getExpectations()) {
if (expectation.equals(Expectation.continueResponse())
&& acceptable(request, response)) {
response.setStatus(Status.INFO_CONTINUE);
response.setEntity(new EmptyRepresentation());
} else {
response.setStatus(Status.CLIENT_ERROR_EXPECTATION_FAILED);
response.setEntity(getErrorRepresentation(expectation,
request, response));
}
return Filter.STOP;
}
return Filter.CONTINUE;
}

protected abstract boolean acceptable(Request request, Response
response);

protected Representation getErrorRepresentation(
Expectation expectation, Request request, Response response) {

return new StringRepresentation(
"Server can't meet or does not support expectation: " +
expectation);
}

This appears to work fine when the expectation is not met (acceptable
returns false), but setting status to 100 and setting the entity to an
empty representation doesn't work. The HTTP 1.1
spec<http://www.w3.org/Protocols/rfc2616/rfc2616-sec8.html#sec8.2.3>says
that the server should send a 100 response and continue reading the
input stream, but I don't see a way to do that in basic Restlet terms.

--tim


On Wed, Dec 12, 2012 at 2:20 PM, Tim Peierls  wrote:

> On Wed, Dec 12, 2012 at 11:34 AM, Tim Peierls  wrote:
>
>>
>>> What about the server? How do I hook into it in order to be able to
>>> either
>>> send a 100 or reject the request if it is unable to process it?
>>>
>>
>> I'd start here:
>>
>>
>> http://www.restlet.org/documentation/2.1/jee/api/org/restlet/data/Expectation.html
>>
>
> Hmm, I just tried doing this, and it isn't as straightforward as I
> thought. You'd need to work at the Engine level, and it's not clear that it
> could be done even then.
>
> Hoping a member of the Restlet team will comment.
>
> --tim
>

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

Re: expect/continue handshake

2012-12-12 Thread Tim Peierls
On Wed, Dec 12, 2012 at 11:34 AM, Tim Peierls  wrote:

>
>> What about the server? How do I hook into it in order to be able to either
>> send a 100 or reject the request if it is unable to process it?
>>
>
> I'd start here:
>
>
> http://www.restlet.org/documentation/2.1/jee/api/org/restlet/data/Expectation.html
>

Hmm, I just tried doing this, and it isn't as straightforward as I thought.
You'd need to work at the Engine level, and it's not clear that it could be
done even then.

Hoping a member of the Restlet team will comment.

--tim

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

Re: expect/continue handshake

2012-12-12 Thread Tim Peierls
On Tue, Dec 11, 2012 at 5:21 PM, Ishaaq Chandy  wrote:

> Thanks for the reply Tim.
>
> That is a bit unfortunate that I can't use the annotation api for
> the client.
>

I didn't say you couldn't, but you should expect to be breaking new ground
if you do. The easiest way to do this would be to get the handshake stuff
working, then layer it on top of the annotation-based stuff.



> What about the server? How do I hook into it in order to be able to either
> send a 100 or reject the request if it is unable to process it?
>

I'd start here:

http://www.restlet.org/documentation/2.1/jee/api/org/restlet/data/Expectation.html

--tim

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

Re: Get all ServerResource objects and their routes from Applicaiton

2012-12-12 Thread Tim Peierls
Doesn't WadlApplication do something like this?

On Tue, Dec 11, 2012 at 10:29 PM, Paul Morris  wrote:

> I'm trying to figure out a way to at runtime get each ServerResource and
> its URI route from the org.restlet.Application API but can't seem to figure
> it out. Below is an example. So again I need the relative ref and the
> object (or even just its class).
>
> router.attach("/", tracer);
> router.attach("/accounts/", tracer);
> router.attach("/accounts/{accountId}", blocker);
>
> --
>
> http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=3035026
>

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

Re: expect/continue handshake

2012-12-11 Thread Tim Peierls
It might be easier to start by writing the client side of this using the
"classic" Restlet APIs and not the annotation-based API, setting the Expect
and Content-Length headers manually and checking the response for a 100
status.

--tim

On Mon, Dec 10, 2012 at 9:35 AM, Ishaaq Chandy  wrote:

> Hi all,
> I have a client app that is communicates using a ClientResource to a
> ServerResource. The latter is managed using the annotations mechanism -
> much
> like what is documented here:
>
> http://wiki.restlet.org/docs_2.0/13-restlet/27-restlet/328-restlet/285-restlet.html
>
> The client sends large payloads to the server via a PUT call and sometimes
> the server needs to push back. I think the ideal way to do this would be to
> use an HTTP Expect/Continue handshake so as to avoid the client sending
> across large amounts of data if the server isn't ready for it. However, I
> can't find any documentation or examples of how I can achieve this. Does
> anyone here have any pointers/suggestions?
>
> I am using restlet 2.0.x
>
> Thanks,
> Ishaaq
>
>
>
> --
> View this message in context:
> http://restlet-discuss.1400322.n2.nabble.com/expect-continue-handshake-tp7578505.html
> Sent from the Restlet Discuss mailing list archive at Nabble.com.
>
> --
>
> http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=3034546
>

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

Re: another CookieAuthenticator mystery

2012-12-10 Thread Tim Peierls
Here's a better candidate for the default implementation of
CookieAuthenticator.challenge:

@Override public void challenge(Response response, boolean stale) {
Reference ref = response.getRequest().getResourceRef();
String redirectQueryName = getRedirectQueryName();
String redirectQueryValue =
ref.getQueryAsForm().getFirstValue(redirectQueryName, "");

if ("".equals(redirectQueryValue)) {
redirectQueryValue = new Reference(getLoginFormPath())
.addQueryParameter(redirectQueryName, ref.toString())
.toString();
}

response.redirectSeeOther(redirectQueryValue);
}

If the redirect URI already contains a redirect query value we use it
directly, because it means we're creating a challenge after a failed login
attempt, so by using the redirect query value, we're restarting the whole
process. Otherwise, this is a first login attempt, so we create a new
reference to the login path with a redirect query.

For example, suppose the user tries to access a resource at /foo that
requires authentication/authorization. Since /foo does not contain a
targetUri query parameter, the if-test succeeds and this will result in a
challenge redirection to /login?targetUri=/foo. If that login attempt
fails, the authentication machinery now tries to authenticate
/login?targetUri=/foo. This time, redirectQueryValue will be /foo, the if
clause will be skipped, and the redirection will be to /foo, back to our
starting point.

This is slightly brittle because of the possibility that other resources
might use the redirect query name in queries, too, which would confuse this
logic. Consider using a name other than the default "targetUri" if this
worries you.

--tim

On Sun, Dec 9, 2012 at 4:44 PM, Tim Peierls  wrote:

> No one answered the question below, and I'd still like to get an answer,
> but in the meantime I got CookieAuthenticator to work by overriding
> challenge(Response, boolean) as follows.
>
> @Override public void challenge(Response response, boolean stale) {
> response.redirectSeeOther(
> new Reference(getLoginFormPath())
> .addQueryParameter(
> getRedirectQueryName(),
> response.getRequest().getResourceRef().toString()
> )
> .toString() // Interpret URI relative to this host.
> );
> }
>
> This would seem to be a good candidate for a default implementation of
> CookieAuthenticator.challenge(Response, boolean).
>
> Here's the rest of the story: I have an AuthApplication to which /auth
> requests are routed in my main component.
>
> // MainComponent initialization:
> host.attach("/auth", authApplication);
>
> That application routes /loginForm to a login form resource and routes
> everything else to an instance of my CookieAuthenticator extension around a
> Restlet that does nothing. (If you leave out this vacuous Restlet, the
> machinery complains about a Filter with no target.)
>
> // In AuthApplication.createInboundRoot:
> Authenticator authenticator = ... my CookieAuthenticator extension ...;
> authenticator.setNext(new Restlet() {
> @Override public void handle(Request request, Response response) {
> getLogger().debug("Null restlet");
> }
> });
>
> router.attach("/loginForm", LoginFormServerResource.class);
> router.attachDefault(authenticator);
>
> LoginFormServerResource is a straighforward use of Freemarker's
> TemplateRepresentation:
>
> @Get public Representation showLoginForm() {
> ImmutableMap dataModel = ImmutableMap.of(
> "targetUri", getQuery().getFirstValue("targetUri")
> );
> return new TemplateRepresentation(
> LOGIN_FORM_TEMPLATE, freemarkerConfiguration,
> dataModel, MediaType.TEXT_HTML
> );
> }
>
> The template has a form element with an action to post to the login
> resource, using the default values of CookieAuthenticator's
> identifierFormName and secretFormName properties ("login", "password"). A
> stripped-down example:
>
> 
> 
> 
> 
> 
>
> Because I've made authentication/authorization a separate Application, I
> had to set the cookie path to "/" in my CookieAuthenticator extension in
> order to have the credentials in the cookie apply to the entire URI-space
> of my Restlet Component.
>
> @Override protected CookieSetting getCredentialsCookie(Request
> request, Response response) {
> CookieSetting credentialsCookie =
> super.getCredentialsCoo

Re: another CookieAuthenticator mystery

2012-12-09 Thread Tim Peierls
No one answered the question below, and I'd still like to get an answer,
but in the meantime I got CookieAuthenticator to work by overriding
challenge(Response, boolean) as follows.

@Override public void challenge(Response response, boolean stale) {
response.redirectSeeOther(
new Reference(getLoginFormPath())
.addQueryParameter(
getRedirectQueryName(),
response.getRequest().getResourceRef().toString()
)
.toString() // Interpret URI relative to this host.
);
}

This would seem to be a good candidate for a default implementation of
CookieAuthenticator.challenge(Response, boolean).

Here's the rest of the story: I have an AuthApplication to which /auth
requests are routed in my main component.

// MainComponent initialization:
host.attach("/auth", authApplication);

That application routes /loginForm to a login form resource and routes
everything else to an instance of my CookieAuthenticator extension around a
Restlet that does nothing. (If you leave out this vacuous Restlet, the
machinery complains about a Filter with no target.)

// In AuthApplication.createInboundRoot:
Authenticator authenticator = ... my CookieAuthenticator extension ...;
authenticator.setNext(new Restlet() {
@Override public void handle(Request request, Response response) {
getLogger().debug("Null restlet");
}
});

router.attach("/loginForm", LoginFormServerResource.class);
router.attachDefault(authenticator);

LoginFormServerResource is a straighforward use of Freemarker's
TemplateRepresentation:

@Get public Representation showLoginForm() {
ImmutableMap dataModel = ImmutableMap.of(
"targetUri", getQuery().getFirstValue("targetUri")
);
return new TemplateRepresentation(
LOGIN_FORM_TEMPLATE, freemarkerConfiguration,
dataModel, MediaType.TEXT_HTML
);
}

The template has a form element with an action to post to the login
resource, using the default values of CookieAuthenticator's
identifierFormName and secretFormName properties ("login", "password"). A
stripped-down example:







Because I've made authentication/authorization a separate Application, I
had to set the cookie path to "/" in my CookieAuthenticator extension in
order to have the credentials in the cookie apply to the entire URI-space
of my Restlet Component.

@Override protected CookieSetting getCredentialsCookie(Request request,
Response response) {
CookieSetting credentialsCookie =
super.getCredentialsCookie(request, response);
credentialsCookie.setPath("/");
return credentialsCookie;
}

--tim


On Mon, Dec 3, 2012 at 3:38 PM, Tim Peierls  wrote:

> The class javadoc for CookieAuthenticator says:
>
> When the credentials are missing or stale, the challenge(Response,
>> boolean)<http://www.restlet.org/documentation/2.1/jee/ext/org/restlet/ext/crypto/CookieAuthenticator.html#challenge(org.restlet.Response,%20boolean)>
>>  method
>> is invoked by the parent class, and its default behavior is to redirect the
>> user's browser to the 
>> getLoginFormPath()<http://www.restlet.org/documentation/2.1/jee/ext/org/restlet/ext/crypto/CookieAuthenticator.html#getLoginFormPath()>
>>  URI,
>> adding the URI of the target resource as a query parameter of name
>> getRedirectQueryName()<http://www.restlet.org/documentation/2.1/jee/ext/org/restlet/ext/crypto/CookieAuthenticator.html#getRedirectQueryName()>
>> .
>
>
> But the javadoc for CookieAuthenticator.challenge(Response, boolean) says
> it must be overridden to return a login form representation, and in fact
> the implementation of challenge(Response, boolean) is to call
> super.challenge(response, stale), in both stable and unstable versions. The
> supertype version (ChallengeAuthenticator.challenge) sets the status to
> unauthorized and creates a challenge request from the challenge scheme and
> puts it in the response. This fails because the HTTP_Cookie scheme is not
> meant to be used in this way.
>
> My question is whether the class comment is the intent, and the current
> implementation of CookieAuthenticator.challenge is incomplete, or if the
> class comment is out of date. If the latter is the case, then can someone
> give an example of how to override challenge?
>
> --tim
>

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

another CookieAuthenticator mystery

2012-12-03 Thread Tim Peierls
The class javadoc for CookieAuthenticator says:

When the credentials are missing or stale, the challenge(Response,
boolean) boolean)> method is invoked by the parent class, and its default behavior
> is to redirect the user's browser to the 
> getLoginFormPath()
>  URI,
> adding the URI of the target resource as a query parameter of name
> getRedirectQueryName()
> .


But the javadoc for CookieAuthenticator.challenge(Response, boolean) says
it must be overridden to return a login form representation, and in fact
the implementation of challenge(Response, boolean) is to call
super.challenge(response, stale), in both stable and unstable versions. The
supertype version (ChallengeAuthenticator.challenge) sets the status to
unauthorized and creates a challenge request from the challenge scheme and
puts it in the response. This fails because the HTTP_Cookie scheme is not
meant to be used in this way.

My question is whether the class comment is the intent, and the current
implementation of CookieAuthenticator.challenge is incomplete, or if the
class comment is out of date. If the latter is the case, then can someone
give an example of how to override challenge?

--tim

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

dependencies in 2.2-SNAPSHOT

2012-12-03 Thread Tim Peierls
I wanted to try out 2.2-SNAPSHOT (from 2012-11-29) to see if recent changes
had made CookieAuthenticator ready for prime time, but I ran into a few
roadblocks:

The Jackson extension lists org.codehaus.woodstox / stax2-api / 4.1.0 as a
dependency in its pom, but I can't find that version anywhere.

The servlet extension lists javax.servlet / servlet-api / 3.0 as a
dependency in its pom, but the closest thing I could find was javax.servlet
/ javax.servlet-api / 3.0.1 -- note that the artifact name of the latter is
prefixed by "javax.". Are they the same thing?

--tim

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

Re: Re: Re: Params are null on server

2012-09-08 Thread Tim Peierls
On Fri, Sep 7, 2012 at 9:41 PM, William Ferguson <
william.fergu...@xandar.com.au> wrote:

> This isn't a problem for me and I'm not trying to start some flame war
> over a particular implementation. I'm trying to contribute back after
> blowing 2 weeks trying to decipher what I would have expected to have
> realised in 5 mins.
>

Gotcha. I won't respond point by point, then -- I don't want to start a
flame war, either! -- I'll just agree that the documentation should be
fixed so that others don't waste time as you did.

--tim

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

Re: Re: Params are null on server

2012-09-07 Thread Tim Peierls
On Thu, Sep 6, 2012 at 6:13 PM, William Ferguson <
william.fergu...@xandar.com.au> wrote:

> > As Jerome hinted, it would be great if someone who had such expectations
> > could think back to how those expectations arose and then offer tweaks to
> > the docs/javadocs that would prevent others from making the same
> > assumptions.
>
> I think they arise because you are told to craft an interface containing
> business methods, annotate them with HTTP methods and implement that on
> client and server.
>

Do the Restlet docs really say this? If so, those docs are sending a deeply
misleading message and should be fixed.



> But business methods don't (and shouldn't) have a restriction on them to
> only have a single parameter.
>

Right, but Restlet supports the uniform HTTP interface, not a more general
notion of Java interface. Sticking to a uniform interface is important for
interoperability with non-Java clients/components.



> Dynamic proxies have been used to marshall/unmarshall remote method calls
> for the last 10 years and I think most developers have come to expect a
> certain level of functionality from that.
>

Could it be that people are confusing Restlet with JAX-RS?



> Instead of modify the documentation to prevent others from expecting
> Restlet to handle multiple params, I'd be more inclined to modify the code
> to allow it to happen. I suspect it would also be the cheaper of the two
> options.
>

What do you mean by "cheaper of the two options"? Restlet as it stands is
pretty streamlined; it's hard to see how adding further magical behavior
could be anything but more expensive.

It would be nontrivial to "modify the code to allow it to happen". It's not
as if this functionality already exists and just needs to be enabled. There
are a lot of questions to answer: How would you map between generic Java
interfaces and the uniform HTTP interface and still preserve the option of
having non-Java clients and servers? And if someone else prefers a
different mapping mechanism, why should your mapping be enshrined in
Restlet?

Is JAX-RS closer to what you're looking for? Or why not simply write your
own business layer on top of the Restlet layer? That way you can control
how parameters are conveyed over HTTP (via URI template variable, HTTP
header, or as part of an entity) without having to settle for someone
else's notion of how to do it.

--tim

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

Re: Params are null on server

2012-09-06 Thread Tim Peierls
On Thu, Sep 6, 2012 at 5:59 AM, William Ferguson <
william.fergu...@xandar.com.au> wrote:

> again, the limitation on a single param is not obvious and I haven't seen
> it mentioned anywhere.
>

It comes up on this mailing list repeatedly. People read about the
client-side proxy capabilities and somehow assume that it does much more
than provide HTTP method aliases and conversion of request and response
entities. Restlet does so many things so well that it must be tempting to
jump to the conclusion that it does everything! :-)


I had expected that the DynamicProxy would have taken care of marshalling
> multiple params up into a single Representation object on the client and
> unmarshalling them at the other end.
>

As Jerome hinted, it would be great if someone who had such expectations
could think back to how those expectations arose and then offer tweaks to
the docs/javadocs that would prevent others from making the same
assumptions.

--tim

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

Re: Re: Re: POST and if-modified-since

2012-09-04 Thread Tim Peierls
On Tue, Sep 4, 2012 at 8:21 AM, Koen Maes  wrote:

> It is indeed a edge case where you have a POST and no get.


By "edge case", I was referring not to the practice of having POST-only
resources (which isn't at all unusual) but to the presence of an
If-Modified-Since header in a request to such a resource.

It just occurred to me that one reason browsers might include headers not
ordinarily associated with POST in a POST request is to cover the case of
POST being used for method tunneling. The rationale might be that since you
don't know the semantics of the tunneled method, it can't hurt to throw in
any and all headers that might apply. I don't buy that rationale, but it
would explain the browser behavior.

--tim

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

Re: Re: POST and if-modified-since

2012-09-04 Thread Tim Peierls
I'm sure everyone agrees that conditional GET and PUT are essential tools.
Restlet's support for these is one of the things that drew me to Restlet in
the first place.

But the original question was about conditional POST (if-modified-since
header in POST request). What does it mean? Unless you have defined your
own semantics for this, you'll want to ignore conditional headers in POST
requests, and my response describes a simple way to do so in Restlet in the
edge case where a resource does not support GET.

--tim

On Tue, Sep 4, 2012 at 5:13 AM, Koen Maes  wrote:

> I do not feel it is a mistake that browsers exhibit this behaviour, on the
> contrary.
>
> I have asked a similar question in this forum before, on how to work with
> ETag and wether I had to manage a cache of my own and verify with the
> server for 304's.
>
> The given behaviour, it turns out, I just don't have to care. I do a first
> GET request to the server, and the server responds back with an ETAG. Upon
> the next request to the same URL (and no params!), I do not have to keep
> the previous version around. The browser takes it from disk cache and sends
> the If-modified header to the server, receives the 304, and returns the
> entity from disk. No code needed, use the power of the browser.
>
> --
>
> http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=3003392
>

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

Re: POST and if-modified-since

2012-09-03 Thread Tim Peierls
The getInfo(Variant) method -- or getInfo() if not using content
negotiation -- is called to supply information to the conditional request
handling machinery, and the default implementation is, as you observed, to
do whatever GET would do, which in your case is to call the @Get handler.

Override these methods to return EmptyRepresentation, just as in your
workaround, and you won't have to provide a dummy @Get method.

It sounds like a mistake, though, that these headers are being included on
POST requests.

--tim


On Mon, Sep 3, 2012 at 10:37 AM, Stefan Deitmer  wrote:

> Using Restlet 2.1RC6 on Apache Tomcat 6.0.32.
>
> I've observed the following behavior:
>
> Web browsers sometimes send an "If-modified-since" header along with their
> POST requests. (1)
>
> Restlet in that case tries to call the @Get handler of the resource before
> calling the @Post handler, in our case resulting in a 405 /
> METHOD_NOT_ALLOWED, since our resource in question only has a @Post
> handler, and no @Get handler (2). While this might be unusual or even
> non-standard, I'm trying to understand the point of calling the (possibly
> rather expensive) @Get handler at all before the @Post handler. Is this on
> purpose? And if so, can this behavior be disabled?
>
>
>
> (1): I had this with a page that uses XmlHttpRequests to upload multiple
> image files on an older Safari version (4.1.3); it seems that the second
> and subsequent POSTs set the header, while the first doesn't.
>
> (2): We can work around the problem by implementing a dummy @Get handler
> which returns an EmptyRepresentation.
>
> --
> Stefan Deitmer
>
> --
>
> http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=3003192
>

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

Re: maven artifact for org.restlet.ext.slf4j

2012-09-03 Thread Tim Peierls
And don't forget to do something like this:

// Arrange for Restlet Engine to use SLF4J Facade.
// Has to be done early, before Engine is first touched.
System.setProperty("org.restlet.engine.loggerFacadeClass",
   "org.restlet.ext.slf4j.Slf4jLoggerFacade");


On Sun, Sep 2, 2012 at 5:54 PM, Tim Peierls  wrote:

> Code is here:
>
>
> https://github.com/restlet/restlet-framework-java/tree/master/modules/org.restlet.ext.slf4j
>
>
> J2EE maven artifacts here:
>
> http://maven.restlet.org/org/restlet/jee/org.restlet.ext.slf4j/
>
> I use this in Ivy:
>
>  rev="2.1-RC6" />
>
> and there's the obvious mapping to Maven POM form.
>
> It's not in every edition, though.
>
> --tim
>
>
> On Sun, Sep 2, 2012 at 1:02 PM, Stephen More wrote:
>
>> The docs state: A special subclass for SLF4J is even provided in the
>> "org.restlet.ext.slf4j" extension.
>>
>> http://wiki.restlet.org/docs_2.0/13-restlet/275-restlet/311-restlet/101-restlet.html
>>
>>
>> I am unable to see the slf4j extension in the maven repository:
>> http://maven.restlet.org/org/restlet/
>>
>>
>> Where can I find the "org.restlet.ext.slf4j" extension ?
>>
>> --
>>
>> http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=3002959
>>
>
>

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

Re: maven artifact for org.restlet.ext.slf4j

2012-09-02 Thread Tim Peierls
Code is here:

https://github.com/restlet/restlet-framework-java/tree/master/modules/org.restlet.ext.slf4j


J2EE maven artifacts here:

http://maven.restlet.org/org/restlet/jee/org.restlet.ext.slf4j/

I use this in Ivy:



and there's the obvious mapping to Maven POM form.

It's not in every edition, though.

--tim

On Sun, Sep 2, 2012 at 1:02 PM, Stephen More  wrote:

> The docs state: A special subclass for SLF4J is even provided in the
> "org.restlet.ext.slf4j" extension.
>
> http://wiki.restlet.org/docs_2.0/13-restlet/275-restlet/311-restlet/101-restlet.html
>
>
> I am unable to see the slf4j extension in the maven repository:
> http://maven.restlet.org/org/restlet/
>
>
> Where can I find the "org.restlet.ext.slf4j" extension ?
>
> --
>
> http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=3002959
>

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

Re: Re: error trapping with ServerResource

2012-09-02 Thread Tim Peierls
Why set the request entity rather than the response entity?

On Sun, Sep 2, 2012 at 9:46 AM, Stephen More  wrote:

> Server side code:
>
> String errorMessage = "CompanyId required";
> org.restlet.Request r = this.getRequest();
> r.setEntity( errorMessage, org.restlet.data.MediaType.TEXT_PLAIN );
> org.restlet.data.Status status = new org.restlet.data.Status(
> org.restlet.data.Status.CLIENT_ERROR_BAD_REQUEST, errorMessage );
> throw new org.restlet.resource.ResourceException( status );
>
> Client side code:
>
> catch( org.restlet.resource.ResourceException re )
> {
>   org.restlet.data.Status status = re.getStatus();
>   log.error( "Error: " + status.getDescription() );
>   log.error( "Error: " + status.getCode() );
> }
>
> Output:
>
> 2012-09-02 09:41:23,375 ERROR [AppTest:82] Error: Bad Request
> 2012-09-02 09:41:23,375 ERROR [AppTest:83] Error: 400
>
>
> I am still unable to see "CompanyId required" on the client... I am doing
> something wrong or is this a bug ?
>
> --
>
> http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=3002935
>

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

Re: Re: Re: Newbie Question -- implementing a simple say arithmetic interface

2012-08-22 Thread Tim Peierls
What's wrong with splitting on slash?  If you really don't like
manipulating the path directly, you can use Reference.get/setSegments. I've
modified the example I gave earlier to show this, and pasted it here:

https://pastebin.com/AXsN73NL

It's a JUnit test (that runs both component and client) that also has a
main (which just runs the component). This one actually compiles and passes
the test.

If I were doing this kind of thing a lot, I'd encapsulate the path-building
and path-parsing code.

--tim

On Tue, Aug 21, 2012 at 5:47 PM, Bubba 42  wrote:

> Thanks for the response Tim,
>
> I guess I should have specified without doing a String split on '/' :-)
>
> So I do agree with you that the /add/n0/n1.../nM is a bad application of
> hierarchical urls ...
>
> but for example we wanted to write an api which navigated say a graph
>
> where you had something like
>
> /traverse/e0/e1/.../eM where e0 ... eM are edges of a graph.
>
> Is there a clean programmatic way to work with such examples.
>
> Thanks.
>
> --
>
> http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=323
>

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

Re: Re: Newbie Question -- implementing a simple say arithmetic interface

2012-08-21 Thread Tim Peierls
On Tue, Aug 21, 2012 at 2:46 PM, Bubba 42  wrote:

> While I'm digging through this -- suppose I wanted to define the following
> API where (I know this is a bit RPC-ish):
> say I want to add number n0, n1, , nM ... I'd like to handle this via
> a URL scheme:
>
> /add/n0/n1/n2/.../nM
>
> Is there a clean way to implement this using Restlet?
>

Sure -- leaving aside the question whether this makes sense from an API
standpoint -- you could do something like this (not compiled or tester,
sure to have typos, using Guava in places for compactness):

public interface AddingResource {
@Get String add();
}

public class AddingServerResource implements AddingResource {
public String add() {
Iterable args = ON_SLASH.split(
getReference().getPath().replaceFirst(".*add/", ""));
long result = 0;
for (String arg : args) {
result += Long.valueOf(arg); // can throw NumberFormatException
}
return Long.toString(result);
}

private static final Splitter ON_SLASH = Splitter.on('/');
}

// ... In application's createInboundRoot:

Router router = ...;
router.attach("/add/", AddingServerResource.class)
.setMatchingMode(Template.MODE_STARTS_WITH);

// ... To use Restlet as a client of this:

public long addNumbers(long... numbers) {
FluentIterable args =
FluentIterable.from(numbers).transform(LONG_TO_STRING);
String uri = "add/" + WITH_SLASH.join(args);
AddingResource adder = client.getChild(uri, AddingResource.class);
return adder.add();
}

private ClientResource client = new ClientResource("
http://my.example.com/appbase/";);

private static final Joiner WITH_SLASH = Joiner.on('/');
private static final Function LONG_TO_STRING =
new Function() {
public String apply(Long n) {
return Long.toString(n);
}
};

I think, however, that if you're going to pass arbitrary numbers of
arguments, it's better to pass them as query or matrix parameters rather
than hierarchical components. I did something like this recently to pass
string arguments to an encoder with:

/path/to/resource?args=arg1,arg2,...,argN

arg1 through argN aren't really in a hierarchical relationship, so this
seems better to me than

/path/to/resource/arg1/arg2/.../argN

--tim

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

Re: Newbie Question -- implementing a simple say arithmetic interface

2012-08-20 Thread Tim Peierls
The trouble is that resource interfaces aren't general Java interfaces;
they must be compatible with HTTP methods.

You have two methods annotated with @Get("json"), neither of which is a
valid target for @Get. @Get should only annotate no-arg methods that return
an object reference, @Post should only annotate one-arg methods, and so on.

In addition, there should be at most one @Get operation per metadata
argument (and at most one with no argument) on a resource interface.

You can achieve something of the effect that you're looking for by
designing your resources' URIs so that what you model as arguments to your
get method are actually encoded as part of the URI, either as query
parameters or as components of the path.

And while I understand that you are just experimenting in your example, I
do recommend reading (if you haven't already) books on RESTful or
resource-oriented design.

Read this exchange for more details:

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


--tim


On Sun, Aug 19, 2012 at 10:48 PM, Bubba 42  wrote:

> Greetings guys,
>
> I've skimmed through the tutorials and seem to have been able to grasp how
> to stuff I'd consider intermediate however I'm still have trouble getting a
> simple REST API to work. To learn Restlet I decided to implement a simple
> interface
>
> I want to implement this interface:
>
> public interface ArithmaticResource {
>
>
>  @Get("json")
>
> public int add (int n0, int n1);
>
>
>  @Get("json")
>
> public int add (int n0, int n1, int n2);
>
>
> }
>
>
>
> However when I:
>
>
> final ClientResource cr = new ClientResource(
>
> "http://localhost:8182/restlet/arithmetic";);
>
> final ArithmaticResource resource = cr.wrap(ArithmaticResource.class);
>
> System.out.println("resource.add(1, 2) " + resource.add(1, 2));
>
> I get the following:
>
>
>   Unsupported Media Type (415) - Unsupported Media Type
>
>
> I suspect my understanding is lacking ... I'm really trying to use this
> like Cherry.py where I expose methods ... I guess that's probably not how
> to use Restlet.
>
>
> Would appreciate any help -- have been stuck on this for hours.
>
>
> Bubba424242
>

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

Re: Linking resources using headers?

2012-08-06 Thread Tim Peierls
The best way I know to manipulate the response object without giving up the
simplicity of object->variant conversion is to override the
Resource.toRepresentation method. An example of using this technique can be
found in the (0-rated) first answer to this question:

http://stackoverflow.com/questions/9015511/setting-etag-lastmodified-on-representation-sent-by-serverresource


In your case, you'd want to invent a HasLinks interface, e.g.:

interface HasLinks {
Iterable getLinks();
}

and implement it for all convertible object types that have links that you
want to expose. You can use the Link type from the Atom extension of
Restlet or just roll your own. (I did the former, but it was probably
overkill.)

Then have all of your ServerResource implementations (that might ever
return an object that implements HasLinks) extend a common base class that
has a clause like this in its toRepresentation implementation:

if (source instanceof HasLinks) {
for (Link link : (HasLinks) source) {
// Add custom header built from link.
}
}

Note that its perfectly OK to use this common base in more places than its
ever used, because of the instanceof check.

--tim


On Mon, Aug 6, 2012 at 1:13 PM, Norm Deane wrote:

> One of the recipes in the O'Reily RESTful Web Services Cookbook outlines a
> way to provide a format-independent means to convey resource links using
> HTTP Headers. Something like this...
>
> # Response
> HTTP/1.1 200 OK
> Content-Type: application/xml
> Link: ;
> rel="self;type=application/xml"
> Link: ;
> rel="related;type=application/xml"
>
> What would be the best way to do this within the Restlet framework? Right
> now my ServerResources don't do any direct manipulation of the Response and
> are pretty lightweight using the ConverterService to handle variant->object
> and object->variant conversions.
>
>
> Thanks,
>
> Norm
>
> --
>
> http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=2996982
>

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

Re: Re: Parameters for annotated resources with interface?

2012-07-26 Thread Tim Peierls
What I described is the only way to do it at the moment. The behavior you
are looking for is not there. You could add an RFE issue, if there isn't
one already.

On the client side, build the URI from the same template:

final Template ACCOUNT_TEMPLATE = new Template("/account/{id}");
...
ClientResource rootResource = new ClientResource(baseUri);
...
int id = ..;
String path = ACCOUNT_TEMPLATE.format(ImmutableMap.of("id", id));
AccountResource accountResource = rootResource.getChild(path,
AccountResource.class);
Account account = accountResource.get();

Restlet offers the convincing illusion -- too convincing! -- that you can
call any Java method on the client side and have it remotely call the same
method on the server. At its heart, though, it's just providing different
names for the four or five methods of the uniform interface.

--tim

On Thu, Jul 26, 2012 at 4:20 PM, Norm Deane wrote:

> That's not quite what I'm looking for Tim. I want the signature of the GET
> annotated method to have an int parameter and to have the restlet framework
> parse the value from the URI and pass it to my method.
>
> It seems that this behavior should be there but I can't find it.
>
> Also, on the client side if the client is using the interface defined for
> this resource and a proxy created by ClientResource.wrap how do they
> specify the int parameter to the get if they aren't defined on the GET
> annotated method.
>
> Norm
>
> --
>
> http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=2993258
>

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

Re: Parameters for annotated resources with interface?

2012-07-26 Thread Tim Peierls
Use a URI template when you attach the resource to the router

  router.attach("/account/{id}", AccountServerResource.class);

and extract the id as an attribute in the server resource Get method
implementation

  String idString = getRequestAttributes().get("id");
  if (idString == null) { ... }
  int id = Integer.valueOf(idString);
  if (!isValid(id)) { ... }
  return doSomethingToGetAccount(id);

You'll want to encapsulate common error handling more neatly than this.

--tim

On Thu, Jul 26, 2012 at 12:36 AM, Norm Deane wrote:

> Is it possible to do something like this...
>
> public interface AccountResource
> {
>@Get
>public Account get(int id);
> }
>
> public class AccountServerResource implements AccountResource
> {
>public Account get(int id)
>{
>  return doSomethingToGetAccount(id);
>}
> }
>
> If there is I'm missing it. I can't figure out how the framework would
> parse the id out of the request and pass it to the annotated method?
>
>
> Norm
>
> --
>
> http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=2993117
>

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

Re: Unable to retrieve URI query and path from link

2012-07-25 Thread Tim Peierls
I've used the following code successfully to proxy images. Overriding
getTargetRef involves more code, but it also gives you direct control over
the redirection. (This code works, but I'd love to hear from experts
whether there is a better way. Also, I'm not sure, but I think it interacts
badly with caching when Apache httpd is in front of it. Does that ring a
bell?)

@Override public Restlet createInboundRoot() {
Router router = new Router(getContext());
router.attachDefault(new Filter(getContext(),
new Redirector(getContext(), "", MODE_SERVER_OUTBOUND) {
@Override
protected Reference getTargetRef(Request request, Response
response) {
String rr = request.getResourceRef().getRemainingPart(true);
// Strip initial slash, if present.
if (rr.startsWith("/")) {
rr = rr.substring(1);
}
return new Reference(rr);
}
}
) {
// We only redirect to URIs that look like images.
@Override protected int beforeHandle(Request request, Response response) {
String rr = request.getResourceRef().getRemainingPart(true);
if (!IMG_PATTERN.matcher(rr).find()) {
response.setStatus(CLIENT_ERROR_UNSUPPORTED_MEDIA_TYPE, "Not an image
type");
return Filter.STOP;
}
return Filter.CONTINUE;
}
});
return router;
}

--tim


On Wed, Jul 25, 2012 at 9:02 AM, Laurens Rietveld <
laurens.rietv...@gmail.com> wrote:

> I'm currently dealing with the following scenario: I want to forward users
> to
> a different site using the Redirector class. The site to forward the user
> to
> is included in the url: e.g.
> http://localhost/restlet/http://www.google.com?q=just-a-query.
>
> I'm not using TYPE_URI_ALL because I want to process the path and query
> separately. I use the TYPE_URI_PATH and TYPE_URI_QUERY for this. Problem
> is:
> the url used above does not match this pattern. Below is the code I use.
> I'm
> clearly overlooking something, as this is not a strange scenario. Could
> someone help me out? (ps. I use the 2.2-snapshot version)
>
> Router router = new Router(getContext());
> Redirector redirector = new Redirector(getContext(), "{uriPath}?{query}",
> Redirector.MODE_CLIENT_FOUND);
> TemplateRoute route = router.attach("/restlet/{uriPath}?{query}",
> redirector);
> Map routeVariables = route.getTemplate().getVariables();
> routeVariables.put("uriPath", new Variable(Variable.TYPE_URI_PATH));
> routeVariables.put("query", new Variable(Variable.TYPE_URI_QUERY));
>
>
>
> --
> View this message in context:
> http://restlet-discuss.1400322.n2.nabble.com/Unable-to-retrieve-URI-query-and-path-from-link-tp7578244.html
> Sent from the Restlet Discuss mailing list archive at Nabble.com.
>
> --
>
> http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=2992932
>

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

Re: Restlet 2.1 to use jetty 8?

2012-07-22 Thread Tim Peierls
I think there's an issue for the Jackson upgrade. (I'm sure I've had a
conversation with a Restlet team member about this, anyway.)

--tim

On Sun, Jul 22, 2012 at 1:59 PM, Tal Liron wrote:

> I was about to do this myself, but thanks very much. :) :)
>
> Why not have 2.1 use Jetty 8?
>
> Related: I recommend updating the Jackson plugin to use the 2.0 line. The
> API is the same, but there is a namespace change. If you update it, it
> would allow users to upgrade the jar without problems. Otherwise, they will
> be stuck in 1.0.
>
> > Hi Tal,
> >
> > Good news, I updated the 2.1 branch today with Jetty 7.6.5 version and
> > 2.2/master with Jetty 8.1.5 !
>
> --
>
> http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=2992264
>

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

Re: Handling exceptions/errors when using Restlet for Client and Server....

2012-07-11 Thread Tim Peierls
On Wed, Jul 11, 2012 at 8:04 PM, Richard Berger wrote:

> Do you think that this problem has persisted this long due to the lack of
> clients built with Restlet (vs. the much larger number of servers built
> with Restlet)?
>

That's not really a fair question: You're leading the witness, counsel. :-)


The concept of tunneling exception information via the Status is
meaningless unless both client and server are Restlet-based, and one of the
wonderful things about Restlet is that it doesn't impose that kind of
coupling on the developer. Clients can't in general assume a particular
structure of the error response entity; all they can really count on is the
status code and associated reason phrase. If the client has specific
knowledge of how a given server serves its error responses, Restlet has all
the tools necessary to take advantage of that knowledge.

Still, since the client proxying machinery can do such a neat job of
creating the illusion of a remote Java call in the case that you *do* have
Restlet on both sides, it seems a shame that the illusion doesn't
extend quite as neatly to exceptions. There might be an issue already to
address this; I can't find it just at the moment.


Thanks again for providing the workaround!!
>

You're welcome!

--tim

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

Re: Handling exceptions/errors when using Restlet for Client and Server....

2012-07-11 Thread Tim Peierls
I've updated the snippet in https://pastebin.com/3nzsjFi1 to demonstrate a
potential workaround using a custom StatusService and special client-side
handling. This example just deals with a StringRepresentation to pass a
custom error status description, but the technique could be generalized to
use an arbitrary custom error representation.

The use of the client proxy mechanism is orthogonal to this workaround, but
since this snippet was originally about how ResourceExceptions passed
through this mechanism don't preserve full error information, I've kept it
in.

The heart of the problem, as I see it, is that the ClientInvocationHandler
throws away important information when handling errors. Until that's
changed, the best you can do is to explicitly manage the error entity, as
in the workaround in the snippet. It's not pretty, but it works.

--tim

On Tue, Jul 10, 2012 at 8:36 PM, Richard Berger wrote:

> And one further note, wrapping the client resource does not seem to change
> the results.
>
> That is to say, going from:
>   ClientResource commitsResource = new ClientResource(getContext(),
> commitsRef);
>   commitsRep = commitsResource.get();
>
> To:
> ClientResource clientResource = new ClientResource(commitsRef);
> CommitmentsResource commitsResource =
> clientResource.wrap(CommitmentsResource.class);
> Representation commitsRep = null;
> commitsRep = commitsResource.represent();
>
> Changes nothing
> RB
>
> On Tue, Jul 10, 2012 at 4:22 PM, Richard Berger <[hidden 
> email]
> > wrote:
>
>> Yes, I only see this problem when I go through my Restlet client, not
>> when using a browser.   In order to make sure the API I am developing is
>> usable by real client developers, I figured I should also build a client.
>>  I chose Restlet as the technology for that client - perhaps that wasn't
>> the best possible choice (if no one else does that).
>>
>> Thanks for the response...
>> RB
>>
>>
>> On Tue, Jul 10, 2012 at 2:09 PM, Bjorn Roche [via Restlet Discuss] <[hidden
>> email] > wrote:
>>
>>> I can't help you directly, but I can say that I use restlet server (but
>>> not client) and I am pretty sure I DON'T have this problem. Is this a bug
>>> in the client that it can't access the http status message? That is what
>>> I'm gathering from the thread you linked as well.
>>>
>>> bjorn
>>>
>>> On Jul 10, 2012, at 1:18 PM, Richard Berger wrote:
>>>
>>> > My question is similar to that raised at:
>>> >
>>> http://restlet-discuss.1400322.n2.nabble.com/Sending-server-side-exceptions-error-codes-back-to-client-td7219795.html#a7229629
>>> >
>>> http://restlet-discuss.1400322.n2.nabble.com/Sending-server-side-exceptions-error-codes-back-to-client-td7219795.html#a7229629
>>> > , but since that has not been answered and this seems like a really
>>> basic
>>>
>>> > issue, I thought I would try posting again.
>>> >
>>> > The question is simply this - how to get the details of an
>>> error/exception
>>> > that occurs on the Restlet server back to my Restlet client?
>>> >
>>> > I can see how to do this if my client were just a browser (I could
>>> construct
>>> > an HTML page on the server and return it).
>>> >
>>> > I thought that it would be pretty simple - set the Status code and
>>> Status
>>> > description.  But as the discussion above points out, that doesn't
>>> work.
>>> >
>>> > I then thought that I could just set the Status code and send back a
>>> String
>>> > Representation of the error message.  But that doesn't work either.
>>>  In
>>> > particular, if I have:
>>> >  msg = "error xyz occurred";
>>> >  this.setStatus(Status.SERVER_ERROR_INTERNAL, msg);
>>> >  StringRepresentation result = new StringRepresentation(msg,
>>> > MediaType.TEXT_PLAIN);
>>> >  return result;
>>> > The client side call:
>>> >  commitsRep = commitsResource.get();
>>> > Sets commitsRep == null (!).  Note: it is only set to null when the
>>> status
>>> > != 200.
>>> >
>>> > So, I could set the status to 200 and then return the
>>> StringRepresentation
>>> > and then on the client, check to see if I have a StringRepresentation
>>> (which
>>> > would be an error) or some other type (which would be a success).
>>> >
>>> > But surely there has got to be an easier way - what am I missing?  (I
>>> have
>>> > created my own StatusService on the server, I have thrown my own
>>> exception,
>>> > but no joy).
>>> >
>>> > Thanks in advance for any hep - and thanks to Tim P for collecting all
>>> the
>>> > links in the thread above - but those weren't enough for me to work
>>> around
>>> > the problem.
>>> >
>>> > RB
>>> >
>>> > --
>>> > View this message in context:
>>> http://restlet-discuss.1400322.n2.nabble.com/Handling-exceptions-errors-when-using-Restlet-for-Client-and-Server-tp7578190.html
>>> > Sent from the Restlet Discuss mailing list archive at Nabble.com.
>>> >
>>> > ---

Re: Empty server response in 2.1 RC5

2012-07-11 Thread Tim Peierls
It should be mentioned in the migration guide, but it isn't a bug, it's a
change in the method signature.

--tim

On Tue, Jul 10, 2012 at 10:41 PM, Robert Brewer  wrote:

> Ioannis Mavroukakis wrote:
> > Hi Robert, you say "most" so that makes me assume some of them work.
> > What are the functional differences between the ones that do work and the
> > ones that don't ?
>
> I tracked down the problem to some code I used to add an additional HTTP
> header. I found the code here:
>
> http://blog.arc90.com/2008/09/15/custom-http-response-headers-with-restlet/
>
> Here is the offending code:
>
> Form responseHeaders =
> (Form)
> getResponse().getAttributes().get(HeaderConstants.ATTRIBUTE_HEADERS);
> if (responseHeaders == null) {
>   responseHeaders = new Form();
>   getResponse().getAttributes().put(HeaderConstants.ATTRIBUTE_HEADERS,
> responseHeaders);
> }
> // The following line causes server to send empty replies on Restlet 2.1
> RC5
> responseHeaders.add("Access-Control-Allow-Origin", "*");
>
> I switched to the method explained here:
>
>
> http://restlet-discuss.1400322.n2.nabble.com/Adding-response-headers-in-restlet-2-1-x-td7240340.html
>
> and now things work OK. Should I open a bug for the previous method? At
> the very least it should be mentioned in the 2.1 migration guide.
>
> --
>
> http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=2982983
>

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

Re: Dynamic URI generation to Resource?

2012-06-30 Thread Tim Peierls
You can use the Template class to build URIs from patterns like the ones
you use to attach resources to the router.

To avoid having to maintain these patterns in several places, I register
all the templates of an application as constants (using an enum) that I can
use in attach statements and when building URIs. Here's a simplified
example:

public enum AppPattern {

USER("/users/{user}"),
USER_ORDERS("/users/{user}/orders"),
USER_ORDER("/users/{user}/order/{order}"),

;

public String pattern() {
return template.getPattern();
}

public String format(String... args) {
return template.format(valueMapFromArgs(args) );
}

AppPattern(String pattern) {
this.template = new Template(pattern);
}

private Template template;

private Map valueMapFromArgs(String[] args) { ... }
}

import static org.example.MyApp.AppPattern.*;

router.attach(USER.pattern(), UserResource.class);
router.attach(USER_ORDERS.pattern(), UserOrdersResource.class);
router.attach(USER_ORDER.pattern(), UserOrderResource.class);
...
String userId = ...;
String orderId = ...;
String orderUri = USER_ORDER.format("user", userId, "order", orderId);

--tim

On Sat, Jun 30, 2012 at 1:05 PM, Larry Sanders  wrote:

> Is there a way to generate the URI to a resource from within another
> resource for an application?
>
> For example, in the restlet tutorial we have the following bindings:
> --
> // Attach the resources to the router
> router.attach("/users/{user}", UserResource.class);
> router.attach("/users/{user}/orders", OrdersResource.class);
> router.attach("/users/{user}/orders/{order}", OrderResource.class);
> --
>
> Let's assume that I want a Users (plural) resource that provides summary
> data on users and provides URIs to UserResources.
>
> So, there'd be:
> router.attach("/users", UsersResource.class)
>
> In that class, when I return the collection of URIs to a particular User,
> do I have to build that URI manually (getting the base URI of the request
> and hardcoding "/users/" + username, etc?
>
> It seems like there should be a way to programmatically generate the URIs.
>
> Any pointers are welcomed.  Thanks.
>
> --
>
> http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=2974129
>

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

Re: Re: Re: Restlet Method Call with multiple parameters?

2012-06-22 Thread Tim Peierls
This isn't currently supported in Restlet. You could make a feature request
if you could nail down the behavior precisely.

I don't see what's wrong with defining a type for a collection of entities
with a location. It's a resource in your application, so having a class to
represent it sounds like a very reasonable thing.

--tim

On Fri, Jun 22, 2012 at 4:12 AM, Philipp E.  wrote:

> thats a valid question, if one would be building a truly restful service,
> there should be need for a second parameter.
>
> Most of my calls use one parameter, but I have one Put call, that updates
> the Location of a Collection of Entities, that can not be broken of in
> seperate calls.
>
> @Put
> public void storeLocationUpdates(Entity[] entities, Location location);
>
> Sure, I could this use a wrapper class to work around the problem, but I
> would be nicer if I could just pass both parameters.
>
>
>
> > Ah, makes sense.
> >
> > But why would you expect to be able to send two parameters in a POST?
> >
> > --tim
> >
> > On Thu, Jun 21, 2012 at 11:32 AM, Philipp E. 
> wrote:
> >
> > > Hello Tim,
> > >
> > > this is a workaround for Android, information about it is available
> here:
> > >
> > >
> http://wiki.restlet.org/docs_2.0/13-restlet/275-restlet/266-restlet.html
> > >
> > > > Why do you explicitly clear the list of registered converters and
> > > > explicitly add the Jackson and XML converters?
> > > >
> > > > On Thu, Jun 21, 2012 at 8:30 AM, Philipp E.  com>
> > > wrote:
> > > >
> > > > > I've been playing around with Restlet(2.1 rc5) in the last week to
> get
> > > an
> > > > > Android Client to communicate with a Restlet server using Java
> Objects
> > > > >
> > > > > After some quirks I can now send and receive POJO objects
> successfully,
> > > > > but it only works if I limit the number of parameters to one.
> > > > >
> > > > > When I try so attatch more than one parameter I get a 415 -
> Unsupported
> > > > > Media Type Error.
> > > > >
> > > > > Restlet Interface:
> > > > >
> > > > > public interface ParamTestRessource {
> > > > >
> > > > > @Post
> > > > > public void sendTwoParams(Long foo, String bla);
> > > > >
> > > > > }
> > > > > Client Code:
> > > > >
> > > > > Engine.getInstance().getRegisteredConverters().clear();
> > > > > Engine.getInstance().getRegisteredConverters().add(new
> > > JacksonConverter());
> > > > > Engine.getInstance().getRegisteredConverters().add(new
> XmlConverter());
> > > > >
> > > > > ClientResource cr = new ClientResource(serverURI+"paramTest");
> > > > > ParamTestRessource paramTest = cr.wrap(ParamTestRessource.class);
> > > > > paramTest.sendTwoParams(foo, bar);
> > > > > +matching ServerRessource and Route on the server side
> > > > >
> > > > > Exception on the Client:
> > > > >
> > > > > Unsupported Media Type (415) - Unsupported Media Type
> > > > > Exception on the Server:
> > > > >
> > > > > Unable to convert a [application/json,UTF-8] representation into an
> > > object
> > > > > of class java.lang.Long
> > > > > org.codehaus.jackson.map.JsonMappingException: Can not construct
> > > instance
> > > > > of java.lang.Long from String value 'asdf': not a valid Long value
> > > > >
> > > > > I also tried using different MIME types(for example @Post("xml"))
> > > > >
> > > > > Is there a special Converter I should use ? Or is this simply not
> > > > > supported in Restlet ?
> > > > >
> > > > > I know I can use
> ClientResource.getRequest().getAttributes().put(key,
> > > > > value) but thats not what I want.
> > > > >
> > > > > Thanks in advance for any help!
> > > > >
> > > > > --
> > > > >
> > > > >
> > >
> http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=2972431
> > > > >
> > >
> > > --
> > >
> > >
> http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=2972479
> > >
>
> --
>
> http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=2972584
>

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

Re: Re: Restlet Method Call with multiple parameters?

2012-06-21 Thread Tim Peierls
Ah, makes sense.

But why would you expect to be able to send two parameters in a POST?

--tim

On Thu, Jun 21, 2012 at 11:32 AM, Philipp E.  wrote:

> Hello Tim,
>
> this is a workaround for Android, information about it is available here:
>
> http://wiki.restlet.org/docs_2.0/13-restlet/275-restlet/266-restlet.html
>
> > Why do you explicitly clear the list of registered converters and
> > explicitly add the Jackson and XML converters?
> >
> > On Thu, Jun 21, 2012 at 8:30 AM, Philipp E. 
> wrote:
> >
> > > I've been playing around with Restlet(2.1 rc5) in the last week to get
> an
> > > Android Client to communicate with a Restlet server using Java Objects
> > >
> > > After some quirks I can now send and receive POJO objects successfully,
> > > but it only works if I limit the number of parameters to one.
> > >
> > > When I try so attatch more than one parameter I get a 415 - Unsupported
> > > Media Type Error.
> > >
> > > Restlet Interface:
> > >
> > > public interface ParamTestRessource {
> > >
> > > @Post
> > > public void sendTwoParams(Long foo, String bla);
> > >
> > > }
> > > Client Code:
> > >
> > > Engine.getInstance().getRegisteredConverters().clear();
> > > Engine.getInstance().getRegisteredConverters().add(new
> JacksonConverter());
> > > Engine.getInstance().getRegisteredConverters().add(new XmlConverter());
> > >
> > > ClientResource cr = new ClientResource(serverURI+"paramTest");
> > > ParamTestRessource paramTest = cr.wrap(ParamTestRessource.class);
> > > paramTest.sendTwoParams(foo, bar);
> > > +matching ServerRessource and Route on the server side
> > >
> > > Exception on the Client:
> > >
> > > Unsupported Media Type (415) - Unsupported Media Type
> > > Exception on the Server:
> > >
> > > Unable to convert a [application/json,UTF-8] representation into an
> object
> > > of class java.lang.Long
> > > org.codehaus.jackson.map.JsonMappingException: Can not construct
> instance
> > > of java.lang.Long from String value 'asdf': not a valid Long value
> > >
> > > I also tried using different MIME types(for example @Post("xml"))
> > >
> > > Is there a special Converter I should use ? Or is this simply not
> > > supported in Restlet ?
> > >
> > > I know I can use ClientResource.getRequest().getAttributes().put(key,
> > > value) but thats not what I want.
> > >
> > > Thanks in advance for any help!
> > >
> > > --
> > >
> > >
> http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=2972431
> > >
>
> --
>
> http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=2972479
>

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

Re: Restlet Method Call with multiple parameters?

2012-06-21 Thread Tim Peierls
Why do you explicitly clear the list of registered converters and
explicitly add the Jackson and XML converters?

On Thu, Jun 21, 2012 at 8:30 AM, Philipp E.  wrote:

> I've been playing around with Restlet(2.1 rc5) in the last week to get an
> Android Client to communicate with a Restlet server using Java Objects
>
> After some quirks I can now send and receive POJO objects successfully,
> but it only works if I limit the number of parameters to one.
>
> When I try so attatch more than one parameter I get a 415 - Unsupported
> Media Type Error.
>
> Restlet Interface:
>
> public interface ParamTestRessource {
>
> @Post
> public void sendTwoParams(Long foo, String bla);
>
> }
> Client Code:
>
> Engine.getInstance().getRegisteredConverters().clear();
> Engine.getInstance().getRegisteredConverters().add(new JacksonConverter());
> Engine.getInstance().getRegisteredConverters().add(new XmlConverter());
>
> ClientResource cr = new ClientResource(serverURI+"paramTest");
> ParamTestRessource paramTest = cr.wrap(ParamTestRessource.class);
> paramTest.sendTwoParams(foo, bar);
> +matching ServerRessource and Route on the server side
>
> Exception on the Client:
>
> Unsupported Media Type (415) - Unsupported Media Type
> Exception on the Server:
>
> Unable to convert a [application/json,UTF-8] representation into an object
> of class java.lang.Long
> org.codehaus.jackson.map.JsonMappingException: Can not construct instance
> of java.lang.Long from String value 'asdf': not a valid Long value
>
> I also tried using different MIME types(for example @Post("xml"))
>
> Is there a special Converter I should use ? Or is this simply not
> supported in Restlet ?
>
> I know I can use ClientResource.getRequest().getAttributes().put(key,
> value) but thats not what I want.
>
> Thanks in advance for any help!
>
> --
>
> http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=2972431
>

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

Re: PathTemplates confusion

2012-06-08 Thread Tim Peierls
Default router mode is Router.MODE_FIRST_MATCH, so just move your avatar
resource first.

You're ruling out having a file_id of "avatar", but presumably you're OK
with that.

--tim

On Fri, Jun 8, 2012 at 2:49 PM, Rodrigo Duarte Sousa <
rodrigodso...@gmail.com> wrote:

> Hi,
>
> I'm trying to implement two distinct resources, one should response at URL
> /media/{user_id}/{file_id} the other one should response at URL
> /media/{user_id}/avatar.
>
> Here is the createInboundRoot code:
>
> public synchronized Restlet createInboundRoot() {
>Router router = new Router(getContext());
>
>router.attach("/media/{user_id}/{file_id}",
> MediaResource.class);
>
>// POST /media/
>router.attach("/media/{user_id}", MediasResource.class);
>
>// GET/PUT/POST/DELETE /media//avatar
>router.attach("/media/{user_id}/avatar",
> AvatarResource.class);
>
>return router;
> }
>
> Any thoughts on this?
>
> Thanks in advance!
>
> Regards,
>
> Rodrigo
>
> --
>
> http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=2969868
>

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

Re: File extensions content negotiation for POST

2012-05-05 Thread Tim Peierls
Hard to tell from this information.

Are you using the application's metadata service or rolling your own code
to deal with extensions?

If so, does it work when you replace .tsv with ?media=tsv and .xls with
?media=xls ?

Are you using annotations (@Get, @Post) or overriding standard methods
(get, post)?

--tim


On Fri, May 4, 2012 at 7:27 PM, Lee Nave wrote:

> I've got a ServerResource all nicely set up to use the file extension from
> the URL path to determine how to format the response (tsv or xls).
>
> Now I need to implement the same for POST, so that the response format is
> determined by the extension of the request.  But it's not working, the
> request does not appear to get routed, I just get a 404 response.
>
> Any suggestions?
>
> --
>
> http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=2957757
>

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

Re: "Restlet in Action". Error in the listing 9.10.

2012-05-02 Thread Tim Peierls
On Wed, May 2, 2012 at 8:23 AM, Sultan Kosaev  wrote:

> I can't extend List.T he error I get from Eclipse is: "The type
> List cannot be the superclass of NewsList; a superclass must be a
> class"
>

Sorry, I meant that you have to extend a concrete type, like ArrayList.


>
> My question is, how do you pass the List to client-side if you needed
> this? (Please show an example with JacksonRepresentation).
>

You can't do this currently.



> I would be very grateful to you if you help me understand
>

Some of this is basic Java knowledge that really doesn't belong on this
list.


P.S.I know how to send single field with jackson representation, but I do
> not know how to pass arrays, such as List
>

List is not an array.

--tim

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

Re: "Restlet in Action". Error in the listing 9.10.

2012-05-02 Thread Tim Peierls
I doubt that anyone is delaying a reply under the belief that it isn't
important to you.

You can't use the construction List.class. (It's a limitation with
Java, not Restlet.) The easiest way to work around this limitation is to
make a non-generic subclass of List, e.g.,

public class NewsList extends List {
...
}

and use that instead.

--tim

On Wed, May 2, 2012 at 7:42 AM, Sultan Kosaev  wrote:

> Please reply.
> It is very important to me
>
> --
> View this message in context:
> http://restlet-discuss.1400322.n2.nabble.com/Restlet-in-Action-Error-in-the-listing-9-10-tp7519398p7519865.html
> Sent from the Restlet Discuss mailing list archive at Nabble.com.
>
> --
>
> http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=2956918
>

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

Re: [Restlet Android] Object representation selection (application/x-java-serialized-object vs. application/json)

2012-04-25 Thread Tim Peierls
Another way to do it is to replace the built-in converter with my custom
converter. See this message:

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

There has been some activity regarding scoring. Here's a recent issue
(which points back to an original older issue):

https://github.com/restlet/restlet-framework-java/issues/255

There have also been some bug fixes regarding scoring, but I don't have
pointers to those.

--tim

On Wed, Apr 25, 2012 at 8:06 PM, Richard Berger wrote:

> Engine.getInstance().getRegisteredConverters().add(0, new
> JacksonConverter());
>
> Worked for me - putting the JacksonConverter first seemed to restore the
> "automagic" :)
> RB
>
> --
>
> http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=2952958
>

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

Re: How to make a URI which passes two parameters using restlet : Restlet 2.1

2012-04-24 Thread Tim Peierls
Yeah, what Fabian said. ;-)

On Tue, Apr 24, 2012 at 5:10 PM, Fabian Mandelbaum wrote:

> Hello Dalia,
>
> I guess that's one of the tradeoffs Tim was referring to.
>
> You can always do something like this:
>
> router.attach("/patients/{patientID}", PatientServerResource.class);
>
> and then:
>
> public class PatientServerResource extends ServerResource {
>  @Get
>  Patient retrievePatient() {
>String patientID = (String) getRequestAttributes.get("patientID");
>// query db, or whatever you need to get the patient by its id
>Patient patient = PatientDAO.findById(patientID);
>return patient;
>  }
>
>  @Put
>  Patient createOrUpdatePatient(Patient newPatient) {
>String patientID = (String) getRequestAttributes.get("patientID");
>boolean isCreate = !PatientDAO.exists(patientID);
>Patient patient = newPatient;
>if (isCreate) {
>  patient.setId(computeIdForNewPatient(newPatient));
>} // else rest of the data is already set on newPatient
>PatientDAO.persist(patientID, patient);
>return patient;
>  }
> }
>
> I've coded the above out of the top of my head, cannot assure the
> thing will be compilable as is (it should be).
>
> You can also add more methods, for example support for DELETE to
> remove a patient, like this:
>
> @Delete
> public Patient removePatient(patientID) {
>  Patient patient = PatientDAO.findById(patientID);
>  PatientDAO.erase(patientID);
>  return Patient; // Usually DELETE requests expect no body on the
> response, check this...
> }
>
> You can also have another resource:
>
> router.attach("/patients", PatientCollectionServerResource.class);
>
> and PatientCollectionServerResource supports POST to create a new
> patient (no need to know/compute the ID for the patient in advance),
> and you can use PUT on PatientServerResource just for updating a
> patient (both approaches are RESTful).
>
> Bottomline, starting thinking about resources, the operations can all
> be modelled with POST (create), GET (read), PUT (update and create)
> and DELETE (delete). The book Tim pointed you to is very good, let me
> also add RESTful Web Services by Leonard Richardson and Sam Ruby (code
> examples are not in Java, but that doesn't really matter).
>
> Good luck!
>
> On Tue, Apr 24, 2012 at 5:26 PM, Dalia Sobhy 
> wrote:
> > Thanks Tim it helps alot, but for any update do I have to make the
> parameter
> > a separate resource??
> >
> > Is there any alternative?
> >
> > Another aspect could I make one class that adds and retrieves and
> updates a
> > patient based on patientID.
> >
> > I made it using three separate resources it's working but I believe that
> > this is nonsense. If for instance I have  about 20 methods for
> > handling/using patient as retrieve, update, add..etc. Do I have to do 20
> > resource classes is that logic???
> >
> > --
> > View this message in context:
> http://restlet-discuss.1400322.n2.nabble.com/How-to-make-a-URI-which-passes-two-parameters-using-restlet-Restlet-2-1-tp7493109p7497326.html
> > Sent from the Restlet Discuss mailing list archive at Nabble.com.
> >
> > --
> >
> http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=2951522
>
>
>
> --
> Fabián Mandelbaum
> IS Engineer
>
> --
>
> http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=2951533
>

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

Re: How to make a URI which passes two parameters using restlet : Restlet 2.1

2012-04-23 Thread Tim Peierls
It's not always possible or desirable to find a one-to-one correspondence
between object/method-oriented APIs and resource-oriented APIs. One of the
hardest things for me in adopting Restlet has been to stop thinking in
terms of method calls and to start thinking in terms of resources and
representations.

That said, your example is about updating the address of an existing
patient. Assuming there's more to a patient than just an address, you have
to decide whether you want to model the address as part of the patient
resource or as a separate resource. There are trade-offs here (explored
more fully in books like *RESTful Web Services Cookbook* by Subbu
Allamaraju) but let's assume the latter. In that case, you would identify
the resource corresponding to the address of a patient with a given
patientId with a URI, something like this:

/patient/{patientId}/address/

and you would want to support at least GET and PUT on this resource. The
interface in Restlet might look like this:

public interface PatientAddressResource {
@Get public Address getAddress();
@Put public Address putAddress(Address address);
}

where Address is a value type that can be converted to the representation
types you want to support.

A server-side implementation of this interface might look like this:

public class PatientAddressServerResource
extends ServerResource implements PatientAddressResource {

@Override public Address getAddress() {
String patientId = getQueryValue("patientId");
return doGetAddress(patientId);
}

@Override public Address putAddress(Address newAddress) {
String patientId = getQueryValue("patientId");
doReplaceAddress(patientId, newAddress);
return doGetAddress(patientId);
}

private Address doGetAddress(String patientId) {
// Locate the address information for the patient with the given id:
return ...;
}

private void doReplaceAddress(String patientId, Address newAddress) {
// Replace existing address with newAddress
...
}
}

Does that help?

--tim


On Mon, Apr 23, 2012 at 3:55 PM, Dalia Sobhy wrote:

> This is an example of a method:
>
> updatePatientAddressByID(String ID, String address)
>
> Any Help
>
> --
> View this message in context:
> http://restlet-discuss.1400322.n2.nabble.com/How-to-make-a-URI-which-passes-two-parameters-using-restlet-Restlet-2-1-tp7493109p7493109.html
> Sent from the Restlet Discuss mailing list archive at Nabble.com.
>
> --
>
> http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=2951260
>

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

Re: Content Range with Output Representation

2012-04-18 Thread Tim Peierls
Sure, that'll work, too. However, a reason to prefer the Guava approach
over SequenceInputStream is to preserve incremental iterability without
having to implement tricky iteration logic:

InputSupplier joinedInputs = ByteStreams.join(
FluentIterable.from(urls).transform(
new Function>() {
public InputSupplier apply(URL url) {
return Resources.newInputStreamSupplier(url);
}
}
)
);
InputRepresentation rep = new InputRepresentation(joinedInputs.get());


The transform and join calls are evaluated lazily. It would be much more
complicated to set up an Enumeration that manages opening and closing
InputStreams explicitly.

Note that FluentIterable is available as of Guava 12.0-rc1.

Side note: The InputSupplier and OutputSupplier abstractions in Guava would
be a great way to provide re-readable Restlet representations based on
InputStreams, OutputStreams, Readers, and Writers.

--tim

On Wed, Apr 18, 2012 at 12:48 PM, Thierry Boileau <
thierry.boil...@restlet.com> wrote:

> Hi Tim,
>
> thanks for the tips, I was a little bit lazy to look for convenient
> existing solutions... :)
> I've also discovered this class from the JDK1.6 :
> http://docs.oracle.com/javase/6/docs/api/java/io/SequenceInputStream.html
>
> Best regards,
> Thierry Boileau
>
>
> Guava has a method to join a sequence of input streams into one input
>> stream that might be useful here:
>>
>>
>> http://docs.guava-libraries.googlecode.com/git-history/v12.0/javadoc/com/google/common/io/ByteStreams.html#join(java.lang.Iterable)
>>
>> It actually works in terms of an Iterable (or array) of
>> InputSupplier. There is also a method to turn a URL into an
>> input stream supplier:
>>
>>
>> http://docs.guava-libraries.googlecode.com/git-history/v12.0/javadoc/com/google/common/io/Resources.html#newInputStreamSupplier(java.net.URL)
>>
>> --tim
>>
>>
>> On Wed, Apr 18, 2012 at 12:07 PM, Thierry Boileau <
>> thierry.boil...@restlet.com> wrote:
>>
>>> Hello Bjorn,
>>>
>>>
>>> >By messing with the code you sent, this seems to be a function of
>>> setting the representation size. If I set the size, it's fine, if not, it
>>> sends the whole thing regardless of content-range, which seems like a bug.
>>> Thanks for discovering a bug inside the RangeFilter class.
>>>
>>> Then, I've found that the problem is due to the usage of the
>>> OutputRepresentation in order to gather the several instances of
>>> InputStream. I propose you to use an InputRepresentation instead.
>>> First, I've set up a InputStream class that composes the several
>>> InputStream (this implementation is only a "quick" code):
>>>
>>> private static class CompositeInputStream extends InputStream {
>>> private Iterator urlIt = null;
>>> private InputStream is = null;
>>>
>>> public CompositeInputStream(Vector urls) throws IOException
>>> {
>>> urlIt = urls.iterator();
>>> if (urlIt.hasNext()) {
>>> is = urlIt.next().openStream();
>>> }
>>> }
>>>
>>> @Override
>>> public int read() throws IOException {
>>> // read each input stream until exhaustion
>>> int r = is.read();
>>>
>>> boolean goOn = (r == -1);
>>> while (goOn) {
>>> // choose the next one until exhaustion
>>> if (urlIt.hasNext()) {
>>> is = urlIt.next().openStream();
>>> r = is.read();
>>> goOn = (r == -1);
>>> } else {
>>> goOn = false;
>>> }
>>> }
>>>
>>> return r;
>>> }
>>> }
>>>
>>> Then, I simple return the InputRepresentation:
>>> return new InputRepresentation(new CompositeInputStream(urls));
>>>
>>> I hope this will help you.
>>>
>>> Best regards,
>>> Thierry Boileau
>>>
>>>
>>>
>>>
 On Apr 11, 2012, at 2:14 PM, Bjorn Roche wrote:


 On Apr 11, 2012, at 1:50 PM, Thierry Boileau wrote:

 Hi Bjorn,

 that's right, I primarily use the restlet 2.1 version, which does not
 support this constructor I think. I'm not sure this has an impact.


 Well when I use the setter I get the same thing (throws exception) as
 when I pass that value to the constructor.

 Also, it looks like the range is being ignored -- I am getting the full
 document back rather than part.


 By messing with the code you sent, this seems to be a function of
 setting the representation size. If I set the size, it's fine, if not, it
 sends the whole thing regardless of content-range, which seems like a bug.

 Can you send me build instructions (pom or ant file?) for your code if
 you have it? I am testing with curl, maybe there is an issue with one of
 our tests?


 I've figured out how to build (I am an idiot with building)... and I
 can't reproduce the exception.
>>

Re: Content Range with Output Representation

2012-04-18 Thread Tim Peierls
Guava has a method to join a sequence of input streams into one input
stream that might be useful here:

http://docs.guava-libraries.googlecode.com/git-history/v12.0/javadoc/com/google/common/io/ByteStreams.html#join(java.lang.Iterable)

It actually works in terms of an Iterable (or array) of
InputSupplier. There is also a method to turn a URL into an
input stream supplier:

http://docs.guava-libraries.googlecode.com/git-history/v12.0/javadoc/com/google/common/io/Resources.html#newInputStreamSupplier(java.net.URL)

--tim

On Wed, Apr 18, 2012 at 12:07 PM, Thierry Boileau <
thierry.boil...@restlet.com> wrote:

> Hello Bjorn,
>
>
> >By messing with the code you sent, this seems to be a function of setting
> the representation size. If I set the size, it's fine, if not, it sends the
> whole thing regardless of content-range, which seems like a bug.
> Thanks for discovering a bug inside the RangeFilter class.
>
> Then, I've found that the problem is due to the usage of the
> OutputRepresentation in order to gather the several instances of
> InputStream. I propose you to use an InputRepresentation instead.
> First, I've set up a InputStream class that composes the several
> InputStream (this implementation is only a "quick" code):
>
> private static class CompositeInputStream extends InputStream {
> private Iterator urlIt = null;
> private InputStream is = null;
>
> public CompositeInputStream(Vector urls) throws IOException {
> urlIt = urls.iterator();
> if (urlIt.hasNext()) {
> is = urlIt.next().openStream();
> }
> }
>
> @Override
> public int read() throws IOException {
> // read each input stream until exhaustion
> int r = is.read();
>
> boolean goOn = (r == -1);
> while (goOn) {
> // choose the next one until exhaustion
> if (urlIt.hasNext()) {
> is = urlIt.next().openStream();
> r = is.read();
> goOn = (r == -1);
> } else {
> goOn = false;
> }
> }
>
> return r;
> }
> }
>
> Then, I simple return the InputRepresentation:
> return new InputRepresentation(new CompositeInputStream(urls));
>
> I hope this will help you.
>
> Best regards,
> Thierry Boileau
>
>
>
>
>> On Apr 11, 2012, at 2:14 PM, Bjorn Roche wrote:
>>
>>
>> On Apr 11, 2012, at 1:50 PM, Thierry Boileau wrote:
>>
>> Hi Bjorn,
>>
>> that's right, I primarily use the restlet 2.1 version, which does not
>> support this constructor I think. I'm not sure this has an impact.
>>
>>
>> Well when I use the setter I get the same thing (throws exception) as
>> when I pass that value to the constructor.
>>
>> Also, it looks like the range is being ignored -- I am getting the full
>> document back rather than part.
>>
>>
>> By messing with the code you sent, this seems to be a function of setting
>> the representation size. If I set the size, it's fine, if not, it sends the
>> whole thing regardless of content-range, which seems like a bug.
>>
>> Can you send me build instructions (pom or ant file?) for your code if
>> you have it? I am testing with curl, maybe there is an issue with one of
>> our tests?
>>
>>
>> I've figured out how to build (I am an idiot with building)... and I
>> can't reproduce the exception.
>>
>>  bjorn
>>
>>
>> Finally, is it possible to avoid the range processing on just some calls
>> for greater efficiency?
>>
>> bjorn
>>
>> Best regards,
>> Thierry Boileau
>>
>> Thierry,
>>>
>>> The first thing I noticed in your code is that you are using the
>>> OutputRepresentation constructor that does not take an expectedSize
>>> argument, so I took that out and the exception goes away. At the moment my
>>> tests are still failing, so I'll look into that some more.
>>>
>>> bjorn
>>>
>>> On Apr 11, 2012, at 12:39 PM, Thierry Boileau wrote:
>>>
>>> Hi Bjorn,
>>>
>>> I send you a sample test code (server + client) based on your code that
>>> works for me. But I notice that my app sends only 15000 bytes... Can you
>>> tell us the metrics of your tests?
>>>
>>> Not 100% sure of the question.. do you mean container? I am not using
 jetting. My initialization code looks like this:
Component component = new Component();
component.getServers().add(Protocol.HTTP, PORT);
component.getDefaultHost().attach(new
 com.xonami.rest.server.ApiApplication());
component.start();

 Is that what you wanted?

>>> I wanted to know if the application is served using some "server"
>>> extensions such as jetty (org.restlet.ext.jetty.jar) or simple
>>> (org.restlet.ext.simple.jar), or inside a servlet container.
>>>
>>>
>>> also, in the code I sent it looks like it was not "hanging" but rather
 pausing for a moment 

Re: Conditional GET doesn't properly handle content negotiation?

2012-04-12 Thread Tim Peierls
I think it's a bug. There was a change to the JacksonConverter recently in
response to a similar-sounding report, but I don't know about the
GwtConverter. (That JacksonConverter fix is probably in 2.1-RC4.)

I remove or replace built-in converters with my own versions (that mostly
override standard impls) to avoid having to grapple with this kind of
thing. A better approach to content negotiation in Restlet is reportedly on
the way, and I'll re-examine things then.

--tim

On Thu, Apr 12, 2012 at 11:53 AM, Andy Dennie wrote:

> Here's my use case:
>
> I'm submitting a conditional GET (using If-None-Match, although I don't
> think that's relevant) request that also specifies a media type in the
> Accept header that doesn't match any of the media types supported by the
> target resource (i.e. it doesn't correspond to any of the media type
> extensions specified in the @Get annotation).
>
> When I don't specify a condition, I get the expected 406 response.
>  However, when I specify the condition, the code goes through
> ServerResource.doConditionalHandle() instead of doNegotiatedHandle().
>
> OK, now, please bear with me for a bit of code narrative :-)
>
> doConditionalHandle() checks isNegotatiated() and invokes
> doGetInfo(getPreferredVariant(getVariants(Method.GET)).
>
> getPreferredVariant() returns null, as it should in this case, so we drop
> into the other doGetInfo(), that is, the one with no args.  From there, we
> go into doHandle, because annotationInfo is non-null.  doHandle invokes the
> @Get-annotated method, which returns a non-null resultObject, which
> doHandle passes to toRepresentation(resultObject, variant), with
> variant=null.
>
> If you're still with me, here's where things start to go wrong...
>
> Resource.toRepresentation() calls ConverterService.toRepresentation(),
> which tries to select the best ConverterHelper.  As it happens, I'm using
> both the GwtConverter and JacksonConverter.  For reasons I don't
> understand, both of those converters return 0.5 from their score() methods
> when the target variant is null (GwtConverter does this if the source
> object is Serializable, JacksonConverter does it if the source object is
> not already an instanceof JacksonRepresentation).  This doesn't seem
> right to me; if the target is null, it seems like those converter classes
> should return -1.0 from their score() methods.
>
> But, as things stand, the GwtConverter wins (I guess it was first in some
> ordering), and thus instead of returning null,  toRepresentation returns an
> ObjectRepresentation that it got from GwtConverter.
>
> From here, we traverse back up the stack several levels to
> ServerResource.doConditionalHandle() again, which gets the
> ObjectRepresentation back from doGetInfo().  It does the following:
>
> if ((Method.GET.equals(getMethod()) || Method.HEAD
>.equals(getMethod()))
>&& resultInfo instanceof Representation) {
>result = (Representation) resultInfo;
>
> and since the if() statement is true, it proceeds to return the result,
> and the client gets back the "application/x-java-serialized-object+gwt"
> representation instead of a 406.
>
> SO... is this a bug, or am I doing something wrong?  Should those
> converters return -1.0 from their score() methods?  Or should
> doConditionalHandle() consider the possibility that despite getting a
> non-null Representation back from doGetInfo(), it needs to do content
> negotation anyway?
>
> Thanks in advance for any advice.
>
> -Andy
>
> --
>
> http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=2947774
>

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

Re: How send object from client to server

2012-04-10 Thread Tim Peierls
I'm probably misunderstanding your question, but here goes: You can't
really "send" objects in Restlet, you can only send representations. The
client resource proxy machinery makes it look as though you are sending an
object by calling a method that looks like the target method on the server
side, but in reality, it serializes the object (using Java serialization by
default) into bytes, and the server deserializes those bytes at the other
end.

There are several problems with the default use of Java serialization, the
biggest of which is that it limits client and server to being Java
programs, both compiled with the same represented types. (It's also
annoying to have to make everything java.io.Serializable.) If that isn't a
problem for you, then you're set, apart from having to get the details
right. I can't help you with those details beyond the suggestion I've
already made.

If the Java-only approach is too restrictive, then you can use alternative
serialization. What has worked very well for me is Jackson, which
eliminates the java.io.Serializable requirement and supports two
lower-level serialization formats: JSON and Smile, the latter being a
binary analogue of former. (Jackson also has growing support, via add-on
projects, for other serialization formats, like XML and CSV.)

With Jackson, I can have serve *and accept* JSON representations of my Java
data types. My clients are not limited to Java programs.

I can't point you to a simple example of how to accomplish this, though
I've written about various aspects of the process in this discussion group
and on my blog. The only advice I can give is to look at existing examples,
see how they work, and adapt them to your needs.

--tim

On Tue, Apr 10, 2012 at 10:02 AM, Sultan Kosaev  wrote:

> Alright. But for example, when you want to send an object of any class of
> the
> server, how do you do it? Through Serializable interface? Or how?
> For example, you can tell me the link, the book and i had read about it. I
> just don't know where i can still read about restlet, except book "RESTlet
> in the Action"
>
> Give mt any ideas. Because I do not know what to do, where to read
>
> --
> View this message in context:
> http://restlet-discuss.1400322.n2.nabble.com/How-send-object-from-client-to-server-tp7451974p7452965.html
> Sent from the Restlet Discuss mailing list archive at Nabble.com.
>
> --
>
> http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=2946871
>

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

Re: How send object from client to server

2012-04-10 Thread Tim Peierls
On Tue, Apr 10, 2012 at 9:37 AM, Sultan Kosaev  wrote:

> I don't understand. I modified your example on this page
>
> http://wiki.restlet.org/docs_2.1/13-restlet/21-restlet/318-restlet/303-restlet.html
> , but I can not send an object of Authentication class from client to
> server
>

Not *my* example! ;-)

If you can get that original example to work, then how about incrementally
modifying it towards your desired version? Eventually you'll reach a point
where it isn't working and you'll be able to narrow down exactly what
change caused it to stop working.

--tim

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

Re: How send object from client to server

2012-04-10 Thread Tim Peierls
Does your server-side resource implement the AuthorizationResource
interface?

There are all sorts of things that could be going wrong besides this. I
suggest that you start with the example in the Restlet wiki and adapt it to
your needs.

--tim

On Tue, Apr 10, 2012 at 12:59 AM, Sultan Kosaev  wrote:

> Hello. I don't understand how server can take an object sent by the
> client. For example.
> I have such an interface on the client side:
>
> /*
> public interface AuthorizationResource {
>@Post
>public void login(Authentication auth);
> }
> **/
>
> then i send to server the object of Authentication class:
>
> /**
> Authentication auth = new Authentication ("login", "password");
>
> resource.login(auth);
>
> ***/
>
> The Authentication class (Both classes are also available on the server
> and client):
> /**
> public class Authentication implements Serializable{
>
>private static final long serialVersionUID = 1L;
>
>public String login;
>public String password;
>
>public Authentication() {}
>
>public Authentication(String login, String password) {
> super();
>this.login = login;
>this.password = password;
>}
>
>public String getLogin() {
>return login;
>}
>
>public String getPassword() {
>return password;
>}
>
>public void setLogin(String login) {
>this.login = login;
>
>}
>
>public void setPassword(String password) {
>this.password = password;
>}
> }
> **/
>
> Then on the server side i want to get the object of Authentication class
>
> /**
>
> public class AuthenticationServerResource extends ServerResource {
>
>Authentication auth = new Authentication("defaultLogin",
> "defaultPassword");
>
>@Post
>public void login (Authentication auth) {
>this.auth = au;
>System.out.println(auth.getLogin());
>}
> }
>
> **/
>
> but nothing happens. The console doesn't output anything
>
> My questions, which is best way to serialize object? and is my way right?
>
> --
>
> http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=2946655
>

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

Re: Get language code from the executing thread

2012-03-28 Thread Tim Peierls
You can -- that's what Request.getCurrent() gives you. Be careful not to
over-use thread-local context, though, particularly if you use or intend to
use asynchronous request handling (connectors for which are available in
recent Restlet releases). I'm not sure what happens when you call
Request.getCurrent() -- or any of the other getCurrent() static methods --
during handling that doesn't take place on the original request thread.

In the long run, your code will be more robust if you don't rely on
assumptions about thread-local context.

--tim

On Wed, Mar 28, 2012 at 2:32 AM, Mutaz Qasem  wrote:

> Thanks Tim. Actually the Validator is initiated in a Mapper class and the
> mapper class is initiated in the Resource that is handling the request. I
> asked my question because in Python, wherever your code is, you are still
> able to use  local()  which returns a dictionary of the contextual
> information of any executing thread.
> Of course you can add and remove entries form the local() dictionary as you
> wish.
>
> I thought, instead of having a chain of passing contextual data to the
> Mapper and then to the validator and change my code a lot to a fit the new
> change. I could have something similar to python that holds the executing
> thread context.
>
>
> Regards
> Mutaz
>
> --
> View this message in context:
> http://restlet-discuss.1400322.n2.nabble.com/Get-language-code-from-the-executing-thread-tp7409075p7412529.html
> Sent from the Restlet Discuss mailing list archive at Nabble.com.
>
> --
>
> http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=2941495
>

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

Re: Get language code from the executing thread

2012-03-27 Thread Tim Peierls
I'm assuming that by "language code" you mean the value of the
Accepted-Languages header from the request.

You can use Request.getCurrent() to get the, um, current request, from
which you can retrieve the language(s). This works as long as you're in the
same thread that is handling the request, or if you're in a task that was
submitted to the TaskService from such a thread. (Not sure what happens in
async handling, though.)

But relying on static methods to supply values is something to avoid if
possible. Why not pass contextual information (like the accepted languages)
to the Validator instance at construction time? It looks especially nice
with the builder pattern:

Literal literal = Validator.builder()
.withAcceptedLanguages(getClientInfo().getAcceptedLanguages())
.build()
.validate(jsonObj.getString("textKey"));


--tim

On Tue, Mar 27, 2012 at 6:19 AM, Mutaz Qasem  wrote:

> Hi
>
> I have a resource
>
> public class SomeResource extends ServerResource{
>@Post("json")
>public Representation create(JsonRepresentation entity){
>
>JSONObject jsonObj = entity.getJsonObject();
>Literal literal = new
> Vlidator().validate(jsonObj.getString("textKey"));
>}
> }
>
> public class Vlidator{
> public Literal validate(String someText){
>  String langCode = getLanguageCode();
>  LiteralManager lm = new LiteralManager();
>  return lm.createLiteral(someText, langCode);
> }
> public String getLanguageCode(){
>// How to get the lang code??!!
>}
> }
>
> How can I implement getLanguageCode() method to retrieve the language code
> of the thread of the current request. Considering that Vlidator class is
> defined somewhere else outside the SomeResource class.
> Is that possible?
>
> Thanks
> Mutaz
>
> --
> View this message in context:
> http://restlet-discuss.1400322.n2.nabble.com/Get-language-code-from-the-executing-thread-tp7409075p7409075.html
> Sent from the Restlet Discuss mailing list archive at Nabble.com.
>
> --
>
> http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=2941092
>

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

  1   2   3   4   >