Hello Geert,

 

Thanks for the code so far.

 

The code is not working for me yet. I get a 404 not found message.

 

I'm using the code snippet that is posted here. =>
https://github.com/marklogic/roxy/issues/416

 

The conf:rewrite($method, $uri, $path) function returns this:
/MarkLogic/rest-api/endpoints/search-list-query.xqy?q=test

 

For these parameters:

.         $method = GET

.         $uri = /v1/search?q=test

.         $path = /v1/search

 

Is this the correct result?

 

I'm running it with MarkLogic version 8.0-2

 

I may need to roll back version ML 8.0-1.

 

 

 

From: [email protected]
[mailto:[email protected]] On Behalf Of Geert Josten
Sent: Tuesday, April 21, 2015 4:49 AM
To: MarkLogic Developer Discussion; Andrew Jacobs
Subject: Re: [MarkLogic Dev General] Roxy ML8 Hybrid App throws Undefined
Function Error in /src/roxy/rewrite.qxy for conf:rewrite()

 

Not very pretty, but this seems to work:

 

xquery version "1.0-ml";

declare namespace html = "http://www.w3.org/1999/xhtml";;

 

let $method := 'GET'

let $uri := '/web/scripts/d3js/crossfilter.v1.min.js'

let $path := $uri

return

xdmp:eval('

        import module namespace conf =
"http://marklogic.com/rest-api/endpoints/config";

          at "/MarkLogic/rest-api/endpoints/config.xqy";

import module namespace rest = "http://marklogic.com/appservices/rest"; 

  at "/MarkLogic/appservices/utils/rest.xqy";

import module namespace eput =
"http://marklogic.com/rest-api/lib/endpoint-util";

    at "/MarkLogic/rest-api/lib/endpoint-util.xqy";

        declare variable $method external;

        declare variable $uri external;

        declare variable $path external;

        

(: This is a hack, but allows us to maintain one rule set endpoints and
rewriter, 

    while pushing the finer-grained error handling to the endpoint level. :)

declare function conf:rewrite-rules(

) as map:map

{

    let $old-rules := eput:get-rest-options()

    return

        if (exists($old-rules))

        then $old-rules

        else

            let $all-methods :=
("GET","POST","PUT","DELETE","HEAD","OPTIONS")

            let $new-rules   := map:map()

            let $unsupported := map:map()

            return (

                for $rule in (

                    conf:get-default-request-rule(),

                    conf:get-config-indexes-request-rule(),

                    conf:get-config-namespaces-item-request-rule(),

                    conf:get-config-namespaces-request-rule(),

                    conf:get-config-properties-request-rule(),

                    conf:get-config-query-child-request-rule(), 

                    conf:get-config-query-list-request-rule(), 

                    conf:get-config-query-request-rule(),

                    conf:get-document-query-rule(),

                    conf:get-document-update-rule(),

                    conf:get-keyvalue-list-request-rule(),

                    conf:get-qbe-request-rule(),

                    conf:get-ping-request-rule(),

                    conf:get-rsrc-list-query-rule(),

                    conf:get-rsrc-item-query-rule(),

                    conf:get-rsrc-item-update-rule(),

                    conf:get-rsrc-exec-query-rule(),

                    conf:get-rsrc-exec-update-rule(),

                    conf:get-search-query-request-rule(),

                    conf:get-search-update-request-rule(),

                    conf:get-tfm-list-request-rule(),

                    conf:get-tfm-item-request-rule(),

                    conf:get-txn-request-rule(),

                    conf:get-values-request-rule(),

                    conf:get-sparql-protocol-rule(),

                    conf:get-graph-explore-rule(),

                    conf:get-graphstore-protocol-rule(),

                    conf:get-suggest-request-rule(),

                    conf:get-rules-list-rule(), 

                    conf:get-alert-rules-item-rule(),

                    conf:get-alert-match-rule(),

                    conf:get-extlib-root-request-rule(),

                    conf:get-extlib-request-rule()

                    )

                let $endpoint   := $rule/@endpoint/string(.)

                (: Note: depends on document order in rule :)

                let $uri-params := $rule/rest:uri-param/@name/string(.)

                let $methods    :=
$rule/rest:http/@method/tokenize(string(.)," ")

                for $match in $rule/@fast-match/tokenize(string(.), "\|")

                return (

                    for $method in $methods

                    return map:put($new-rules, $method||$match,
($endpoint,$uri-params)),

 

                    let $candidates :=

                        let $candidate-methods :=
map:get($unsupported,$match)

                        return

                            if (exists($candidate-methods))

                            then $candidate-methods

                            else $all-methods

                    return map:put(

                        $unsupported, $match, $candidates[not(. = $methods)]

                        )

                    ),

 

                for $match in map:keys($unsupported)

                for $method in map:get($unsupported,$match)

                return map:put(

                    $new-rules,

                    $method||$match,

                    "/MarkLogic/rest-api/endpoints/unsupported-method.xqy"

                    ),

 

                eput:set-rest-options($new-rules),

                $new-rules

                )

};

 

declare function conf:rewrite(

    $method   as xs:string,

    $uri      as xs:string,

    $old-path as xs:string

) as xs:string?

{

    let $rules      := conf:rewrite-rules()

    (: skip the empty step before the initial / :)

    let $raw-steps  := subsequence(tokenize($old-path,"/"), 2)

    let $raw-count  := count($raw-steps)

    (: check for an empty step after a trailing / :)

    let $extra-step := (subsequence($raw-steps,$raw-count,1) eq "")

    let $step-count :=

        if ($extra-step)

        then $raw-count - 1

        else $raw-count

    let $steps      :=

        if ($step-count eq 0)

        then ()

        else if ($extra-step)

        then subsequence($raw-steps, 1, $step-count)

        else $raw-steps

    (: generate the key for lookup in the rules map :)

    let $key        :=

        (: no rule :)

        if ($step-count eq 1)

        then ()

        (: default rule :)

        else if ($step-count eq 0)

        then ""

        else

            let $first-step := subsequence($steps,1,1)

            return

            (: as in /content/help :)

            if ($first-step eq "content")

            then ($first-step,"*")

            else if (not($first-step = ("v1","LATEST")))

            (: no rule :)

            then ()

            else

                let $second-step := subsequence($steps,2,1)

                return

                (: as in /v1/documents :)

                if ($step-count eq 2)

                then ("*",$second-step)

                else

                    let $third-step := subsequence($steps,3,1)

                    return

                    if ($second-step = ("ext"))

                    then

                    ("*",$second-step,"**")

                    else if ($second-step = ("config","alert","graphs"))
then

                        (: as in /v1/config/namespaces :)

                        if ($step-count eq 3)

                        then ("*", $second-step, $third-step)

                        (: /v1/config/options/NAME or
/v1/config/options/NAME/SUBNAME :)

                        else if ($step-count le 5)

                        then ("*", $second-step, $third-step, (4 to
$step-count) ! "*")

                        else ()

                    (: as in /v1/transactions/TXID :)

                    else if ($step-count eq 3)

                    then ("*", $second-step, "*")

                    (: catch all :)

                    else if ($step-count le 5)

                    then ("*", $second-step, $third-step, (4 to $step-count)
! "*")

                    (: no rule :)

                    else ()

    let $key-method :=

        if ($method eq "POST" and starts-with(

            head(xdmp:get-request-header("content-type")),
"application/x-www-form-urlencoded"

            ))

        then "GET"

        else $method

    let $value :=

        if (empty($key)) then ()

        else map:get($rules, string-join(($key-method,$key), "/"))

    let $value-count := count($value) 

    return

        (: fallback :)

        if ($value-count eq 0)

        then $uri

        else

            let $old-length := string-length($old-path)

            let $has-params := (string-length($uri) ne $old-length)

            let $new-path   :=

                (: append parameters to the rewritten path :)

                if ($has-params)

                then subsequence($value,1,1)||substring($uri,$old-length+1)

                else subsequence($value,1,1)

            return

                if ($value-count eq 1)

                then $new-path

                (: append parameters from rule to the rewritten path :)

                else string-join(

                    (

                        $new-path,

                        let $step-names := subsequence($value,2)

                        for $step-value at $i in

                            for $j in 2 to count($key)

                            let $place-holder := subsequence($key,$j,1)

                            return

                                if ($place-holder eq "*")

                                then subsequence($steps,$j,1)

                                else if ($place-holder eq "**")

                                (: using raw-steps picks up trailing slash
:)

                                then
string-join(subsequence($raw-steps,$j),"/")

                                else ()

                     

                        return (

                            if ($has-params or $i gt 1)

                                then "&"

                                else "?",

                            subsequence($step-names,$i,1),

                            "=",

                            $step-value

                            )

                        ),

                    ""

                    )

};

        

        (conf:rewrite($method, $uri, $path), $uri)[1]',

        (xs:QName("method"), $method,

         xs:QName("uri"), $uri,

         xs:QName("path"), $path))

 

In other words: replace the eval in roxy/rewrite.xqy with above one, and you
should be able to run against ML 8.0-2. Note though that this does not run
against 8.0-1.1, as it would try to redefine those functions which is not
allowed.

 

Cheers,

Geert

 

From: Geert Josten <[email protected]>
Reply-To: MarkLogic Developer Discussion <[email protected]>
Date: Tuesday, April 21, 2015 at 10:24 AM
To: MarkLogic Developer Discussion <[email protected]>
Subject: Re: [MarkLogic Dev General] Roxy ML8 Hybrid App throws Undefined
Function Error in /src/roxy/rewrite.qxy for conf:rewrite()

 

Hi Gary,

 

Could you create a ticket here:  https://github.com/marklogic/roxy
<https://github.com/marklogic/roxy/blob/dev/src/roxy/rewrite.xqy> 

 

A number of people have reported this issue which started to appear since
release 8.0-2. I'll try to look into it. It looks like we will need to
preserve some code from the old rewrite module. Otherwise it should work..

 

Cheers,

Geert

 

From: Yinyan guy <[email protected]>
Reply-To: MarkLogic Developer Discussion <[email protected]>
Date: Tuesday, April 21, 2015 at 5:23 AM
To: MarkLogic Developer Discussion <[email protected]>
Subject: Re: [MarkLogic Dev General] Roxy ML8 Hybrid App throws Undefined
Function Error in /src/roxy/rewrite.qxy for conf:rewrite()

 

Hi Gary, 

I have seen this error a couple of days ago and I am aware that there are
some enhancements in ML8 with respect to rewrite function. Hence you can
file a bug request for this or switch to ML7.

Hope this helps.

regards,

Puneet

  _____  

From: [email protected]
To: [email protected]
Date: Mon, 20 Apr 2015 22:46:31 -0400
Subject: [MarkLogic Dev General] Roxy ML8 Hybrid App throws Undefined
Function Error in /src/roxy/rewrite.qxy for conf:rewrite()

I have a Roxy ML8 Hybrid App that's throwing an Undefined Function Error in
/src/roxy/rewrite.qxy for conf:rewrite().

 

I see the error is on line 42 of /src/roxy/rewrite.xqy. =>
https://github.com/marklogic/roxy/blob/dev/src/roxy/rewrite.xqy

 

Unfortunately, I have no time to troubleshoot this.

 

It looks like the root cause is related to the new ML8 rewrite.xml file.

 

Has anyone seen this?

 

 

Also, I believe there's an invalid reference to a global variable called
@uri on line 391 in /src/roxy/lib/request.xqy. =>
https://github.com/marklogic/roxy/blob/dev/src/roxy/lib/request.xqy

 

 

 

Gary Russo

Enterprise NoSQL Architect

http://garyrusso.wordpress.com <http://garyrusso.wordpress.com/> 

 


_______________________________________________ General mailing list
[email protected] Manage your subscription at:
http://developer.marklogic.com/mailman/listinfo/general

_______________________________________________
General mailing list
[email protected]
Manage your subscription at: 
http://developer.marklogic.com/mailman/listinfo/general

Reply via email to