Filtering only on POST (SINK) requests?

Poster Content
nk4um Moderator
Posts: 901
April 27, 2011 17:22
Hi Gary - good that you''re sorted.  The error reporting is correct in that the res:/service/ really was not resolving/recursing.  If you look up the stack trace you''d see the active:groovy endpoint was making the request in the context of the active:groovy runtime (which had your rootspace in the scope, then the PO, then the fileset).

FYI we wrote the pluggable-overlay as a basic tool which issues a request to the pre-process/post-process implementations.  Its this issuing of additional requests that needs care.   For this reason, we added a StandardOverlayImpl base class to standard-module - which makes it relatively painless to implement your own "direct" overlays (ie no sub-requests to an impl, just do whatever you want for the pre/request/post processing).  (If you look in the newsletters I explained how it is used to show the details of the RDBMS transaction overlay).

As for active:sqlBatch.  It won''t resolve SINK requests.  Its interface is SOURCE.  As shown in the docs http://docs.netkernel.org/book/view/book:mod-db:book/doc:mod-db:batch - all DB tools are SOURCE.

You are stepping into semantic territory - but the mindset is that even though you are doing a DB update (batch or update) you are sourcing the resource which is the update state (the result of the actions on the DB).

As you no doubt can sense - it feels like we could make a more seamless integration between the relational database model and the ROC domain - and this is definitely true - they are natural complements.  However we are unfortunately stuck with the JDBC driver - and this leaves a lot to be desired in its abstraction which ultimately means we have to live with SOURCEable active:sql tool set.

If we had the time and luxury, we would definitely write a new ROC-DBC abstraction with a driver model written to the native DB protocols and cleanly mapping the set-theoretic RDBMS to the set-theoretic ROC world.  Unfortunately this is a lot of work and will have to wait for a rainy day.

Hope this helps.

P.
Like · Post Reply
nk4um User
Posts: 92
April 27, 2011 15:44That worked - now have another problem
Hi Peter,

Thanks - that worked.  I think what confused me was that the error message always stated that the URI resolution failure was on the res:/service/... and not on the groovy request.

My next problem is another Request Resolution Failure, but on SINK active:sqlBatch.  I have now flipped the verb, but not all the resources I am using appear to know how to handle it.

Gary
Like · Post Reply
nk4um Moderator
Posts: 901
April 27, 2011 14:27
Hi Gary,

Sorry I should have anticpated this - I wasn''t paying attention this morning.

Here''s what happening.

1. The pluggable overlay request is for active:groovy+operator@res:/service/....
2. This request gets issued into the PO-space.
3. I didn''t spot that your PO-space does not contain an import of active:groovy (and its also not mapped out through from the mapper-space (which does!)).  So it doesn''t resolve there. So it tries the superstack - which is outside the PO (you have groovy imported in your rootspace).
4. Groovy (in the rootspace) now requests the operator res:/service/...
5. Becuase of the fileset we added this now correctly resolves *inside* the PO-space.  But, it then goes through the PO again - which starts the recursion, which can never end.

So the solution is to import lang:groovy near the fileset import we added.  As I was getting to - I can see that it would get simpler and eliminate these kind of inward/outward resolution cycles if you pop the fileset, groovy and layer1 in a lib space and then import that space everywhere you think you need it.

Sorry for the confusion.  The pluggable overlay is very powerful - but it does require that you hold tight to scope and are careful to ensure that all the services/resources you think you need are in the correct spacial scope.

Please let me know if this makes and sense and sorts you out.

P.
Like · Post Reply
nk4um User
Posts: 92
April 27, 2011 14:16Not working
I have tried putting it in all spaces.  I did not quite get what you meant by the PO Space, since I thought that is where you put it.  When I use your example, I get a Stack Overflow Exception.  If you look carefully, you will see that the rootspace was originally copied from the tutorial.  In the tutorial, the fileset for the Class was in the Mapped space.  Does it work differently for classes.  I took the tututorial and just tried to make a few changes to fit my needs.  I have a much larger rootspace I need to convert once I get this working.
When I put the fileset in the space for the PO - the Request Resolution Tool resolves to the resource, but I get the stack overflow.
I have been trying to get the POST to SINK to work now since last week trying to follow a combination of the tutorial and Gregoire''s examples.  I am tempted to just create my own ''VERB'' convention to getCustomer and saveCustomer in the URI - as that is all I am really trying to do.  However, I do want to get the overlay feature to work because at the least I would use it for other purposes.
Like · Post Reply
nk4um Moderator
Posts: 901
April 27, 2011 08:09
Of course I''ve screwed up - I should have mapped res:/services/ into the PO-space since that''s where your PO-script is.  But you get the idea.
Like · Post Reply
nk4um Moderator
Posts: 901
April 27, 2011 08:07res:/resources/*
Hi Gary,

The problem you have is that the fileset res:/resources/ is inside the mapper''s space - it is therefore encapsulated and not available to the space hosting the mapper declaration.  Which is where your preProcess request is being issued.

Here''s one solution that will get it working for you (notice my PJR comment)...

<rootspacepublic="true">
  <pluggable-overlay>
    <preProcess>
      <identifier>active:groovy</identifier>
      <argumentname="operator">res:/service/RestToRocVerb.gy</argument>
      <argumentname="operand">arg:request</argument>
    </preProcess>
    <space>
      <!--Exposed in this space by PJR-->
      <fileset>
        <regex>res:/service/.*</regex>
      </fileset>
      <mapper>
        <!-- <config>res:/tutorial/rest/part4/part4b/mapperConfig.xml</config> -->
        <config>
          <endpoint>
            <grammar>res:/service/
              <groupname="service">
                <regextype="alphanum" />
              </group>
              <optional>/
                <groupname="id">
                  <regextype="anything" />
                </group>
              </optional>
            </grammar>
            <verbs>SOURCE</verbs>
            <request>
              <identifier>active:groovy</identifier>
              <argumentname="operator">res:/service/[[arg:service]].gy</argument>
              <argumentname="id" method="as-string" tolerant="true">[[arg:id]]</argument>
            </request>
          </endpoint>
        </config>
        <space>
          <fileset>
            <regex>res:/resources/.*</regex>
          </fileset>
          <fileset>
            <regex>res:/service/.*</regex>
          </fileset>
          <fileset>
            <regex>res:/etc/ConfigRDBMS.xml</regex>
          </fileset>
          <import>
            <uri>urn:org:netkernel:ext:layer1</uri>
          </import>
          <import>
            <private />
            <uri>urn:org:netkernel:lang:groovy</uri>
          </import>
          <import>
            <uri>urn:org:netkernel:mod:db</uri>
          </import>
        </space>
      </mapper>
    </space>
  </pluggable-overlay>
  <import>
    <private />
    <uri>urn:org:netkernel:ext:layer1</uri>
  </import>
  <import>
    <private />
    <uri>urn:org:netkernel:lang:groovy</uri>
  </import>
  <import>
    <!-- Import the common library so that this space gets exposed to HTTP requests -->
    <uri>urn:org:netkernel:tutorial:rest:dynamic-import-impl</uri>
  </import>
</rootspace>


If you use the space explorer you''ll see you actually have an arrangment of spaces like this...

rootspace -> pluggable-overlay-space -> mapper space

The PO will issue its request into the PO-space. The mapper space had the fileset (but it wasn''t mapping it out - so it remain internally private).

When you have several common library''s of resources/services - it sometimes pays to create a library rootspace and import that to each space where you think you''ll need it (makes no difference to resolution/exec, but makes things easier to read/review).

Cheers,

Peter

PS Did the other thread with the mapper representation stuff work for you?
Like · Post Reply
nk4um User
Posts: 92
April 26, 2011 23:00Similar issue
I am trying to do roughly the same thing as Gregoire, but have a slightly different problem.
I am having a URI resolution error - from the pre-processor.  The preprocess is unable to find my groovy script defined in the space <fileset>.  If I comment out the preprocess and submit a browser request to run the same groovy script - it sources the script and runs it just fine.

<rootspacepublic="true">
  <pluggable-overlay>
    <preProcess>
      <identifier>active:groovy</identifier>
      <argumentname="operator">res:/service/RestToRocVerb.gy</argument>
      <argumentname="operand">arg:request</argument>
    </preProcess>
    <space>
      <mapper>
        <!-- <config>res:/tutorial/rest/part4/part4b/mapperConfig.xml</config> -->
        <config>
          <endpoint>
            <grammar>res:/service/
              <groupname="service">
                <regextype="alphanum" />
              </group>
              <optional>/
                <groupname="id">
                  <regextype="anything" />
                </group>
              </optional>
            </grammar>
            <verbs>SOURCE</verbs>
            <request>
              <identifier>active:groovy</identifier>
              <argumentname="operator">res:/service/[[arg:service]].gy</argument>
              <argumentname="id" method="as-string" tolerant="true">[[arg:id]]</argument>
            </request>
          </endpoint>
        </config>
        <space>
          <fileset>
            <regex>res:/resources/.*</regex>
          </fileset>
          <fileset>
            <regex>res:/service/.*</regex>
          </fileset>
          <fileset>
            <regex>res:/etc/ConfigRDBMS.xml</regex>
          </fileset>
          <import>
            <uri>urn:org:netkernel:ext:layer1</uri>
          </import>
          <import>
            <private />
            <uri>urn:org:netkernel:lang:groovy</uri>
          </import>
          <import>
            <uri>urn:org:netkernel:mod:db</uri>
          </import>
        </space>
      </mapper>
    </space>
  </pluggable-overlay>
  <import>
    <private />
    <uri>urn:org:netkernel:ext:layer1</uri>
  </import>
  <import>
    <private />
    <uri>urn:org:netkernel:lang:groovy</uri>
  </import>
  <import>
    <!-- Import the common library so that this space gets exposed to HTTP requests -->
    <uri>urn:org:netkernel:tutorial:rest:dynamic-import-impl</uri>
  </import>
</rootspace>
Like · Post Reply
nk4um User
Posts: 168
March 31, 2011 17:32Success!
Hi Peter,

I managed to inherit from HttpAccessorImpl. It was indeed very easy.

The good thing is that thanks to you, I will be able to work on my REST services for the few days/weeks. Thank you for the time taken today on this topic.

The bad thing is that, if I''m not mistaken, I now have to use this accessor for all HTTP methods to one resource (in my example "res:/clients"). Until now I was more on the idea to use XQuery to "get" XML files, and Groovy to "post" them.

But with this accessor, I guess I will have to do everything in Groovy, no?

A workaround could be to create bogus "internal" endpoints like "res:/clients-get" and call them from my GET accessor (effectively doing a kind of loop to return to "module.xml"). Not very elegant but I don''t see any other way to have a single matching grammar and different languages based on HTTP verb.

Thanks for your PS. I hope to be able to work with NetKernel faster than with other toolkits someday. Last year I had a 3 months training on J2EE and I was not convinced by the power/complexity ratio.

Regards,
Gregoire
Like · Post Reply
nk4um Moderator
Posts: 901
March 31, 2011 14:48
Hi Gregoire,

Let us know how you get on with the HTTPAccessorImpl base class.  I think it will be a simple solution.

However, Tony and I discussed the verb translation overlay pattern. There''s nothing implicit to an overlay that says it can''t do what you expected.  Its just that the pluggable-overlay wasn''t designed with verb-translation in mind.

After the conference is out the way we''ll look into creating a dedicated REST verb translator overlay which will resolve all SOURCE requests and translate them to the inner request.

Personally I have misgivings about verb translation - since strictly the HTTPBridge really is formally requiring a SOURCEd resource (HTTP is on the outside, ROC is on the inside).  I''ll discuss this a bit in the newsletter tomorrow.

Anyway let us know if you need any more help.

Peter

PS In general it seems like you''re really getting the hang of NK/ROC of late!
Like · Post Reply
nk4um User
Posts: 168
March 31, 2011 13:52
Hi!

Thanks for the explanation! I now understand what happens. Can I give you my point of view over the technical issue?

As a NetKernel end-user, the first thing I had to learn is how to tell NetKernel what external addresses it should recognize (I filled a grammar tag), and what to do upon this (and there, a request tag). So, writing a "module.xml" file was the first step I needed to do to ask NetKernel to do something for me.

So, a "module.xml" seems to be all there is to know. The remaining task is to write some scripts that would return a resource. And what is great about NK is that you can use the more practical language for any given task. Since my first need was to look into XML data, I started with XQuery. When came the time of writing some XML files, I used Groovy, because it was like Java but without the need to recompile.

Then, I understood that REST is not just about clean addresses (without those ugly "?" and "&" that you get in PHP). I realized recently that I was thinking more in terms of services and not of resources (I had, for example, a /customers/create endpoint, whereas REST suggests that creations should take the form of a POST request to /customers). I needed to change my addressing scheme and to allow the full set of HTTP verbs. Becoming RESTful is a nice goal, so the added work was not a problem.

What I wrote above about "module.xml" still applies. I see it as the central part of my modules, and so, I had hoped that there would be a tag to specify which HTTP verb was allowed for each endpoint.

But NetKernel is a generic architecture, and that idea of a <http-verb> tag would be HTTP-centric (though, to a end-user like me, it wouldn''t be a problem to have a few HTTP specific tags, I understand that it may scratch the whole ROC picture).

So, this is where I had to choose between the "part4a" and "part4b" of the tutorial. To sum up, the choice was between wiring the logic in a script (not nice!), or adding complexity to my "module.xml" with a "pluggable overlay". I chose the second option, for the reasons given above about the central role of "module.xml".

But finally, you tell me that NetKernel cannot execute the overlay-ed "preprocess" code if it cannot SOURCE the inner resource. Ok.

But this is where my end-user point of view may be useful. To me, the "principle of least surprise" must apply. As an end-user, I expected that the "<verbs>" tag was about limiting "my" inner requests to "my" choice of NetKernel verbs. I didn''t imagine that this tag was used by NetKernel itself to learn if there was a resource to be SOURCEd in the inner side of the overlay.

I would suggest, if that is programmatically possible, to assume that inner resources are always SOURCE-able. Then the "pre-process" code would always execute, and that would be up to the responsibility of the user to correctly use the <verbs> tag to filter the various requests.

Anyway, thanks for the explanation, I''ll try to see how I can overload this Java class.

Cheers,
Gregoire
Like · Post Reply
nk4um Moderator
Posts: 901
March 31, 2011 10:38
OK I understand what''s going on.  You are correct that if you remove the SOURCE verb from the mapper config - then all requests will fail to be resolved.

What you''re doing is a pretty rare corner case whereby you don''t ever want a GET interface on your REST service.  The problem is verb translation its really not a good pattern. (I''ve talked about why extensively on the newsletters over the years - but the essence is that inside NK you are in the ROC domain - http is on the edge of the system - the HTTPBridge really really is trying to SOURCE a resource to satisfy the HTTP request - no matter what the HTTP method/verb).

Anyway the http bridge issues a SOURCE, the way any overlay works is that it must be able to resolve the request in the mapped space before the overlay actually gets fired up.  If you don''t match SOURCE inside, then the pluggable-overlay never gets executed and the verb translation never takes place. Hence why removing SOURCE means none of the verb types will resolve.

I think a better solution to what you''re trying to do is to extend the HTTPAccessorImpl...

http://wiki.netkernel.org/wink/wiki/NetKernel/News/1/50/October_15th_2010#HTTP_Updates

This provides convenience methods for onPost(), onPut() etc etc.  Since it is an accessor it doesn''t need all this mapping/overlay stuff.  Just extend it and add it to your space as an accessor declaration.

Its frustrating but REST is not the complete picture and trying to do Verb translation patterns like this only highlight why its not actually full ROC.

Hope this gets you moving again.

Peter
Like · Post Reply
nk4um User
Posts: 168
March 31, 2011 09:46
Hi!

Ok, I think we agree on the expected behavior.

To be sure that I am not facing a space oddity, I just reinstalled NKSE 4.1.1, the updates and the REST tutorial. Then I commented out the "part4a" in "module.xml" and retried all requests with my fresh NetKernel instance. They are all routed correctly.

But, when I remove the SOURCE verb from "tutorial/rest/part4/part4b/mapperConfig.xml", all requests (i.e. GET, POST, PUT and DELETE) fail with the "SOURCE" error on the resource, where I would expect that only the GET requests fail.

Is this what you see, too?

Thanks!
Gregoire
Like · Post Reply
nk4um Moderator
Posts: 901
March 31, 2011 09:08
No I didn''t say the SOURCE verb is mandatory (just that particular example verb mapper implementation defaults to SOURCE if the method is not matched).

Try this...

<endpoint>
    <grammar>res:/tutorial/rest/part4/customer/
      <group name="customer-id">
        <regex type="alphanum"/>
      </group>
    </grammar>
    <verbs>SINK,DELETE,NEW,EXISTS</verbs>
    <request>
      <identifier>active:java</identifier>
      <argument name="class">tutorial.rest.part4.part4b.CustomerAccessor</argument>
      <argument name="id">arg:customer-id</argument>
    </request>
  </endpoint>

It no longer resolves the GET (SOURCE) request.
Like · Post Reply
nk4um User
Posts: 168
March 31, 2011 09:02
Hi Peter!

Thanks for your answers. I have commented out the "part4a" in order to test "part4b". Sorry for Randy! :-)

More seriously, you seem to tell that the SOURCE verb is mandatory, don''t you? If so, that''s exactly what I don''t understand. I expected the HTTPVerbTranslationAccessor to do a "GET to SOURCE", "POST to SINK" (etc.) conversion.

Let''s imagine that I only want to allow POST requests on a resource. How could I do that? If the SOURCE verb is mandatory (but why would it be?), then I assume that this will also allow GET requests to be catched? No?

Gregoire
Like · Post Reply
nk4um Moderator
Posts: 901
March 31, 2011 08:36
Actually I just read the accompanying documentation for the tutorial 4 and it is not a bug.  It says this...


===HTTP Method to ROC Verb translation===

To use the second approach to handling HTTP method, the HTTP method to ROC verb translator,
use XML comments to block out the first mapper overlay, leaving the
pluggable overlay able to resolve the request.
Once you say the changes to the module.xml file, NetKernel will recommission the module
(because it is marked ''''dynamic'''').


It is deliberately implementing two versions of the same interface and expects you to follow the instruction to comment out the first part4a piece so that the test harness will work against the second path4b example.

Either way it works fine.  I''ll have to go and apologise to Randy now - the tutorial is not bugged.

P.
Like · Post Reply
nk4um Moderator
Posts: 901
March 31, 2011 08:31
Gregoire,

I think you have found a small bug in the tutorial.  I noticed that the grammar  for part4a and part4b are the same.  Therefore part4a will always be used since it appears first.  The grammars look like this...

    <grammar>res:/tutorial/rest/part4/customer/
      <group name="customer-id">
        <regex type="alphanum"/>
      </group>
    </grammar>

If you edit the file /tutorial/rest/part4/part4b/mapperConfig.xml and change the grammar to

    <grammar>res:/tutorial/rest/part4b/customer/
      <group name="customer-id">
        <regex type="alphanum"/>
      </group>
    </grammar>

Your request will be going through the pluggable-overlay and then into the part4b implementation...

http://localhost:8080/tutorial/rest/part4b/customer/test

I can then confirm that VERB mapping is occuring correctly - and also that removing the SOURCE verb on the endpoint declaration causes the request to be unresolvable.

I''ll fix the tutorial and bang some heads together for you!

P.
Like · Post Reply
nk4um Moderator
Posts: 901
March 31, 2011 08:20REST Tutorial part 4b
Hi Gregoire,

Just to double check that there is no inconsistency since the REST tutorial is now quite old - I installed and ran the part 4b example.

http://localhost:8080/tutorial/rest/part4/customer/test

I used the Firefox 4 REST client add-on (https://addons.mozilla.org/en-US/firefox/addon/restclient/) to send  GET,POST,PUT,DELETE and they were all correctly routed to the endpoint and the appropriate responses returned.

Let us know the answers the questions above - I think there must just be a misconfiguration or untested assumption somewhere in your spacial arrangment.

P
Like · Post Reply
nk4um Moderator
Posts: 901
March 31, 2011 07:55
Hi Gregoire,

Sorry for the slow response - we''re completely flat out preparing for the conference. Can you please answer some questions.

1. Have you put debug in the overlay.HTTPVerbTranslationAccessor class?  Is it definitely matching this condition else if (httpMethod.equals("POST")) - I notice that the default if for whatever reason no method matches then it will always do a SOURCE and log a warning.

2. Have you turned on the visualizer and traced through the request being issued from the pluggable-overlay.  Is it what you expect?

3. Have you tried the request trace tool with a SINK verb against the mapped space with the SINK grammar?  Does it resolve correctly for you?

I don''t think there is anything fundamentally wrong here but the answers to these questions will help us sort you out.

Peter
Like · Post Reply
nk4um User
Posts: 168
March 31, 2011 07:28Same thing with the tutorial
Hi!

I tried to disable "part4a" in the "module.xml" of the REST tutorial, and to remove "SOURCE" from the verbs in "tutorial/rest/part4/part4b/mapperConfig.xml". Then I issued a POST request to "http://localhost:8080/tutorial/rest/part4/customer/42" using cURL:

curl -k http://localhost:8080/tutorial/rest/part4/customer/22


Result:

Request Resolution Failure
SOURCE res:/tutorial/rest/part4/customer/22 as IBinaryStreamRepresentation


So the problem is easy to reproduce.

I would really like to know if this is a bug and how to bypass it.

Thanks!
Gregoire
Like · Post Reply
nk4um User
Posts: 168
March 30, 2011 13:08A bug?
Could this inner SOURCE request be a bug?
Like · Post Reply
nk4um User
Posts: 168
March 30, 2011 09:59
Hum, forget the previous comment, it was a cache-retated issue with my browser.

The endpoint which responds is always the SOURCE one, be the request a GET or a POST. This seems logical since my initial problem was the inner "SOURCE res:/clients" instead of a SINK.
Like · Post Reply
nk4um User
Posts: 168
March 30, 2011 09:37
It appears that the chosen endpoint is the last, just as if the "verbs" clause was ignored.
Like · Post Reply
nk4um User
Posts: 168
March 30, 2011 09:24Filtering only on POST (SINK) requests?
Hi!

I want to create a REST server, and so I need to be able to distinguish between HTTP verbs for one given grammar. I decided to follow the REST tutorial''s "part4b" design, which uses a pluggable overlay.

It has led me to this in my module.xml :

<pluggable-overlay>
  <preProcess>
    <identifier>active:java</identifier>
    <argumentname="class">overlay.HTTPVerbTranslationAccessor</argument>
    <argumentname="request">arg:request</argument>
  </preProcess>
  <space>
    <mapper>
      <config>
        <endpoint>
          <grammar>res:/clients</grammar>
          <verbs>SINK</verbs>
          <request>
            <identifier>active:groovy</identifier>
            <argumentname="operator">res:/resources/scripts/creation.gy</argument>
            <representation>org.w3c.dom.Document</representation>
          </request>
        </endpoint>
      </config>
      <space>
        <fileset>
          <regex>res:/resources/.*</regex>
        </fileset>
        <fileset>
          <regex>res:/overlay/.*</regex>
        </fileset>
        <import>
          <uri>urn:org:netkernel:ext:layer1</uri>
        </import>
        <import>
          <private />
          <uri>urn:org:netkernel:lang:groovy</uri>
        </import>
      </space>
    </mapper>
  </space>
</pluggable-overlay>


As you can see (and this is where I modified the tutorial''s example), I want this endpoint to respond only to "SINK" requests.

But issuing an HTTP POST request to this endpoint returns :

Request Resolution Failure
SOURCE res:/clients as IBinaryStreamRepresentation


Strange… So I tried to add the SOURCE verb to my grammar and this solves the problem, but I don''t understand why the inner request is not a "SINK res:/clients", since the HTTPVerbTranslationAccessor.java supposedly converts all outer HTTP POSTs to inner SINKs :

package overlay;

import org.netkernel.layer0.nkf.INKFRequest;
import org.netkernel.layer0.nkf.INKFRequestContext;
import org.netkernel.layer0.nkf.INKFRequestReadOnly;
import org.netkernel.module.standard.endpoint.StandardAccessorImpl;


public class HTTPVerbTranslationAccessor extends StandardAccessorImpl
  {

  public void onSource(INKFRequestContext context) throws Exception
    {
    INKFRequestReadOnly outerRequest;
    INKFRequest innerRequest;
    String httpMethod;

    // Get the outer request and then create an inner request in which the HTTP method
    // directs which ROC verb to use. We also attach the HTTP method as the argument httpMethod.
    outerRequest = context.source("arg:request", INKFRequestReadOnly.class);
    innerRequest = context.createRequest(outerRequest.getIdentifier());

    //Source the HTTP verb from the http request and use a corresponding ROC verb
    httpMethod = context.source("httpRequest:/method", String.class);
    if (httpMethod.equals("GET"))
      {
      innerRequest.setVerb(INKFRequestReadOnly.VERB_SOURCE);
      }
    else if (httpMethod.equals("HEAD"))
      {
      innerRequest.setVerb(INKFRequestReadOnly.VERB_SOURCE);
      }
    else if (httpMethod.equals("DELETE"))
        {
        innerRequest.setVerb(INKFRequestReadOnly.VERB_DELETE);
        }
    else if (httpMethod.equals("POST"))
        {
        innerRequest.setVerb(INKFRequestReadOnly.VERB_SINK);
        innerRequest.addPrimaryArgument(context.source("httpRequest:/body"));
        }
    else if (httpMethod.equals("PUT"))
        {
        innerRequest.setVerb(INKFRequestReadOnly.VERB_SINK);
        innerRequest.addPrimaryArgument(context.source("httpRequest:/body"));
        }
    else
        {
        innerRequest.setVerb(INKFRequestReadOnly.VERB_SOURCE);
        context.logRaw(INKFRequestContext.LEVEL_DEBUG, "Unsupported HTTP method [" + httpMethod + "]");
        }

    // Return the new, fabricated request to be used by the pluggable overlay as its request to the
    // wrapped space.
    context.createResponseFrom(innerRequest);
    }
  }


As I wrote above, I would have said that the above code would issue a SINK, which would have been suitable for my "verbs" clause.

So, let''s suppose that this is the normal behavior.

But then, how can I use different scripts for "GET" and "POST"? The first idea is to create another endpoint with the SOURCE verb :

<config>
  <endpoint>
    <grammar>res:/clients</grammar>
    <verbs>SOURCE</verbs>
    <request>
      <identifier>active:groovy</identifier>
      <argumentname="operator">res:/resources/scripts/get-clients.gy</argument>
      <representation>org.w3c.dom.Document</representation>
    </request>
  </endpoint>
  <endpoint>
    <grammar>res:/clients</grammar>
    <verbs>SINK</verbs>
    <request>
      <identifier>active:groovy</identifier>
      <argumentname="operator">res:/resources/scripts/creation.gy</argument>
      <representation>org.w3c.dom.Document</representation>
    </request>
  </endpoint>
</config>


But then, it appears that the "get-clients.gy" script is never called, and that this GET request is dealt with "creation.gy" (the script for SINK).

Does this mean that I must write a single script to deal with all verbs?

Thanks!
Gregoire
Like · Post Reply