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]<mailto:[email protected]>>
Reply-To: MarkLogic Developer Discussion 
<[email protected]<mailto:[email protected]>>
Date: Tuesday, April 21, 2015 at 10:24 AM
To: MarkLogic Developer Discussion 
<[email protected]<mailto:[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]<mailto:[email protected]>>
Reply-To: MarkLogic Developer Discussion 
<[email protected]<mailto:[email protected]>>
Date: Tuesday, April 21, 2015 at 5:23 AM
To: MarkLogic Developer Discussion 
<[email protected]<mailto:[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]<mailto:[email protected]>
To: [email protected]<mailto:[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]<mailto:[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