Hi Gabriel

Hi Sergey,
Thanks for the fix, I'll test it later. BTW, what's a "patch point"?

Those users who are submitting patches are getting patch points and may 
eventually become committers.
Submitting patches is a typical procedure for accumulating the points. However, I've seen quite a few users essentially working with us by spending their time on helping to reproduce the reported issues - IMHO such contributions should result in additional points being accumulated - perhaps something like a 'contribution' point could a better definition though...

cheers, Sergey


Gabriel, please reopen this JIRA if you can still see this issue after
2.2.3 gets released
https://issues.apache.org/jira/browse/CXF-2355
if you have some time then please try if the latest ServletController fix
on the trunk  resolves the issue for you

IMHO your contribution worth a patch point.
thanks, Sergey

----- Original Message ----- From: "Sergey Beryozkin" <
[email protected]>
To: "Sergey Beryozkin" <[email protected]>; <[email protected]>
Sent: Thursday, July 23, 2009 6:20 PM

Subject: Re: Problem with matrix params, works with one, but not with two
(or more) params


 Fix will go in shortly. Basically, I believe that in some cases pathInfo
actually has only the last matrix param stripped, as opposed to all of them
by HttpServletRequest. In our tests it's always all matrix parameters on the
last segment that are stripped.

So I updated the ServletController a bit and it should get is all fixed

thanks, Sergey

----- Original Message ----- From: "Sergey Beryozkin" <
[email protected]>
To: "Sergey Beryozkin" <[email protected]>; <[email protected]>
Sent: Thursday, July 23, 2009 4:49 PM
Subject: Re: Problem with matrix params, works with one, but not with two
(or more) params




sorry it is getMatrixParameterIndex(reqPrefix, pathInfo.length());

which is probably fails in your case, wonder why It does work for me ?
Will look more into it...

cheers, Sergey


----- Original Message ----- From: "Sergey Beryozkin" <
[email protected]>
To: <[email protected]>
Sent: Thursday, July 23, 2009 4:43 PM
Subject: Re: Problem with matrix params, works with one, but not with two
(or more) params


 Hi Gabriel

This is really helpful - thanks for spending your time on it.

So let me clarify one thing. In the case when it does not work, when we
have queries like


http://localhost:8080/__services/bridging/widgets/renderwidget/id/1/type/2/size/3/locale/4/properties;numResults=1;foo=bar

you said that 'pathInfo' was equal to


"__services/bridging/widgets/renderwidget/id/1/type/2/size/3/locale/4/properties;numResults=1"

?

The thing that the only place in that function where pathInfo gets
initialized is here :

       String pathInfo = request.getPathInfo() == null ? "" :


So it appears it is HttpServletRequest drops the the last matrix
parameter ?

can you confirm it please ?

thanks, Sergey

 Hi Sergey,
Sorry, I've just seen this post.

I did that change, that as far as I can see is just to add "@Path("/")"
to
the class, but it didn't work. Anyway the problem seems to be here:

  private String getBaseURL(HttpServletRequest request) {
      String reqPrefix = request.getRequestURL().toString();
      String pathInfo = request.getPathInfo() == null ? "" :
request.getPathInfo();
      //fix for CXF-898
      if (!"/".equals(pathInfo) || reqPrefix.endsWith("/")) {
          // needs to be done given that pathInfo is decoded
          // TODO : it's unlikely servlet path will contain encoded
values
so we're most
          // likely safe however we need to ensure if it happens then
this
code works properly too
          reqPrefix = UrlUtils.pathDecode(reqPrefix);
          // pathInfo drops matrix parameters attached to a last path
segment
          int offset = 0;
          int index = getMatrixParameterIndex(reqPrefix,
pathInfo.length());
          if (index >= pathInfo.length()) {
              offset = reqPrefix.length() - index;
          }
          reqPrefix = reqPrefix.substring(0, reqPrefix.length() -
pathInfo.length() - offset); // MARK 1
      }
      return reqPrefix;
  }

  private int getMatrixParameterIndex(String reqPrefix, int
pathInfoLength) {
      int index = reqPrefix.lastIndexOf(';');
      int lastIndex = -1;
      while (index >= pathInfoLength) {
          lastIndex = index;
          reqPrefix = reqPrefix.substring(0, index);
          index = reqPrefix.lastIndexOf(';');
      }
      return lastIndex;
  }

At "// MARK 1" the values are

reqPrefix =

http://localhost:8080/__services/bridging/widgets/renderwidget/id/1/type/2/size/3/locale/4/properties;numResults=1;foo=bar
pathInfo
=
/bridging/widgets/renderwidget/id/1/type/2/size/3/locale/4/properties;numResults=1
offset = 21
index = 101

And the result of executing that line is:

reqPrefix = http://localhost:80

So there's the problem.

On the other breakpoint

rawPath
=
/__services/bridging/widgets/renderwidget/id/1/type/2/size/3/locale/4/properties;numResults=1;foo=bar

And when I entered into "HttpUtils.getPathToMatch(message, true)" I get
to:

  public static String getPathToMatch(String path, String address,
boolean
addSlash) {

      int ind = path.indexOf(address);
      if (ind == 0) {
          path = path.substring(ind + address.length());
      }
      if (addSlash && !path.startsWith("/")) {
          path = "/" + path;
      }

      return path;
  }

The value of "ind" is != 0, so it doesn't enter into the first if and
the
result is:

path
=
/__services/bridging/widgets/renderwidget/id/1/type/2/size/3/locale/4/properties;numResults=1;foo=bar

With one param the at the first breakpoint I get this

reqPrefix = http://localhost:8080/__services
pathInfo
= /bridging/widgets/renderwidget/id/1/type/2/size/3/locale/4/properties

And at the second one:

It enters into the if since "ind == 0" and

rawPath =
/renderwidget/id/1/type/2/size/3/locale/4/properties;numResults=1

Hope this helps,

Best,

Gabriel

On Tue, Jul 14, 2009 at 10:27 AM, Sergey Beryozkin <
[email protected]>wrote:

 Hi Gabriel

I'd like to ask you for one more favor and do a bit more debugging.

here's what I did.

Service class :

@Path("/")

public class WidgetsService {


@GET



@Path("/renderwidget/id/{widgetID}/type/{widgetType}/size/{size}/locale/{locale}/{properties}")

public int getWidgetId(@PathParam("widgetID") Long widgetID,

@PathParam("widgetType") Integer widgetType,

@PathParam("size") Long containerSize,

@PathParam("locale") String locale,

@PathParam("properties") PathSegment props) {

return 1;

}



}


Client code :

@Test

public void testgetWidgetIdWithTwoMatrixParam() {

WebClient wc = WebClient.create("
http://localhost:9081/__services/bridging/widgets";);

wc.accept("text/plain");



wc.path("/renderwidget/id/{widgetID}/type/{widgetType}/size/{size}/locale/{locale}/{properties}",

1, 2, 3, "en_US", "props").matrix("a", "b").matrix("c", "d");

int status = wc.get(Integer.class);

assertEquals(1, status);

}

cxfservlet : /__services/*

jaxrs:server/@address= "/bridging/widgets"

It all works nicely, request URI looks like this :

GET

/__services/bridging/widgets/renderwidget/id/1/type/2/size/3/locale/en_US/props;a=b;c=d

Would it be possible for you, whenever you get a chnace, to put 2
breakpoints, one in

org.apache.cxf.transport.servlet.ServletController.getBaseURL();

and another one in

JAXRSInInterceptor, on the line which reads

String rawPath = HttpUtils.getPathToMatch(message, true);

and let me know at what point of time '/__services/bridging/widgets/'
gets
in the way...Hopefully we can get to the botom of it :-)

thanks, Sergey












----- Original Message ----- From: "Gabriel Guardincerri" <
[email protected]>
To: <[email protected]>
Sent: Monday, July 13, 2009 6:18 PM
Subject: Re: Problem with matrix params, works with one, but not with
two
(or more) params



 On Mon, Jul 13, 2009 at 5:54 AM, Sergey Beryozkin <
[email protected]

>wrote:





/__services/bridging/widgets/renderwidget2/id/1007/type/1/size/1/locale/en_US/properties;numResults=1;foo=bar

so "/__services/bridging/widgets/" is an extra bit which was not
available
at the URITemplate creation time and it would explain why the match
is
failing.



Nice catch!



 Can you please post a sample root resource class, as well as the
value of
jaxrs:server/@address.
Is it something like this :



More or less, we don't have a class path, just

public class Widgets {

 @GET



@Path("/renderwidget/id/{widgetID}/type/{widgetType}/size/{size}/locale/{locale}/{properties}")
 WSWidget renderWidget2(@PathParam("widgetID") Long widgetID,
         @PathParam("widgetType") Integer widgetType,
         @PathParam("size") Long containerSize,
         @PathParam("locale") String locale,
         @PathParam("properties") PathSegment props)
         throws RemoteBridgeException;

}




 and jaxrs:server/@adress="/bridging"


 it is /bridging/widgets



 and CXFServlet url pattern is "/__services/*"  ?


 yes that's the pattern


 Or is it jaxrs:server/@adress="__services/bridging" and CXFServlet
url

pattern = "/*" ?

What are absolute working/broken URIs (lets assume 'webAppName' is
the
name
of the web application, and localhost:8080), is it something like :

working :


http://localhost:8080/webAppName/__services/bridging/widgets/renderwidget2/id/1007/type/1/size/1/locale/en_US/properties;numResults=1
broken :


http://localhost:8080/webAppName/__services/bridging/widgets/renderwidget2/id/1007/type/1/size/1/locale/en_US/properties;numResults=1;foo=bar



We are testing without webAppName just

http://localhost:8080/__services/...

And both absolute URIs have the same beginning.



 By the way is it a double underscore in '__services' ?


 I just a way to be sure that we won't have conflicts with other
URIs that
the server may have



 thanks, Sergey



 Hi Sergey,


I'm sorry again for the delay.

Debugging it I couldn't understand why it isn't working. But here
is
what
I
found:

With the working URL



"renderwidget2/id/1007/type/1/size/1/locale/en_US/properties;numResults=1":

1) At line 144 of URITemplate

143 Matcher m = templateRegexPattern.matcher(uri);
144        if (!m.matches()) {
145            if (uri.contains(";")) {

The value of the variables are:

uri =


/renderwidget2/id/1007/type/1/size/1/locale/en_US/properties;numResults=1
m =



java.util.regex.Matcher[pattern=/renderwidget2/id/([^/]+?)/type/([^/]+?)/size/([^/]+?)/locale/([^/]+?)/([^/]+?)(/.*)?
region=0,73



lastmatch=/renderwidget2/id/1007/type/1/size/1/locale/en_US/properties;numResults=1]
template =



/renderwidget2/id/{widgetID}/type/{widgetType}/size/{size}/locale/{locale}/{properties}
templateRegexPattern =



/renderwidget2/id/([^/]+?)/type/([^/]+?)/size/([^/]+?)/locale/([^/]+?)/([^/]+?)(/.*)?

And m.matches() returns true, so that if is skipped and the method
returns
true. After that our implementation of the service is called.

With the NOT working URL



"renderwidget2/id/1007/type/1/size/1/locale/en_US/properties;numResults=1;foo=bar":

At that same line 144, the variable values are:

uri =



/__services/bridging/widgets/renderwidget2/id/1007/type/1/size/1/locale/en_US/properties;numResults=1;foo=bar
m =



java.util.regex.Matcher[pattern=/renderwidget2/id/([^/]+?)/type/([^/]+?)/size/([^/]+?)/locale/([^/]+?)/([^/]+?)(/.*)?
region=0,109 lastmatch=]
template =



/renderwidget2/id/{widgetID}/type/{widgetType}/size/{size}/locale/{locale}/{properties}
templateRegexPattern =



/renderwidget2/id/([^/]+?)/type/([^/]+?)/size/([^/]+?)/locale/([^/]+?)/([^/]+?)(/.*)?

But m.matches() returns false. So we enter in the if. We also enter
in
the
if of line 145 "if (uri.contains(";"))".
Then the uri is rebuilded, and at line 162:

160                uri = sb.toString();
161                m = templateRegexPattern.matcher(uri);
162                if (!m.matches()) {
163                    return false;

The value of the variables are:

uri =



/__services/bridging/widgets/renderwidget2/id/1007/type/1/size/1/locale/en_US/properties;numResults=1;foo=bar
m =



java.util.regex.Matcher[pattern=/renderwidget2/id/([^/]+?)/type/([^/]+?)/size/([^/]+?)/locale/([^/]+?)/([^/]+?)(/.*)?
region=0,109 lastmatch=]

That are the same values that we had at the beginning. So again
m.matches()
returns false, so we enter to that if on line 162, and the method
returns
false.

I really don't know which is the problem, since as far as I can see
both
uri
should match the pattern. Also I don't know what that first if
should
do,
since we get the same uri.

I hope that this help, if you need any other test, please feel free
to
ping
me.

Best,

Gabriel


Sergey Beryozkin-2 wrote:


 I did few more tests today (with/without CXFServlet, with
PathSegments)
and I still can't reproduce it so I will give up for a
moment.
But I'm still nervous you managed to hit a problem somehow - can
you
please give me a favor and help to get to the bottom of it ?
It should take 30 mins max of your time, download



http://www.apache.org/dyn/closer.cgi?path=%2Fcxf%2F2.2.2%2Fapache-cxf-2.2.2-src.zip

and put a breakpoint in URITemplate.match()

A better news is that after trying to reproduce it,  I added a new
method
to WebClient  which can make it simpler for users to deal
with template parameters, such that they can avoid dealing with
UriBuilder
directly.
So you can do
WebClient client = WebClient.create("http://widgets";);



cleint.path("("/renderwidget/id/{widgetID}/type/{widgetType}/size/{size}/locale/{locale}/{properties}",
             idValue, widgetTypeValue, 1, "en_US",
"properties;1=2").get(Widget.class)

cheers, Sergey


----- Original Message ----- From: "Gabriel Guardincerri" <
[email protected]>
To: <[email protected]>
Sent: Wednesday, July 01, 2009 10:35 PM
Subject: Problem with matrix params, works with one, but not with
two
(or
more) params



 Hello,


I'm having a problem where matrix parameters are not recognized
past
the
first parameter.  When I have one matrix parameter, the method
below
is
invoked and the PathSegment.getMatrixParameters() returns the
single
result.

However, if I append a second matrix parameter (or more), the
service
method is not invoked at all and I receive the following error
message:

"No operation matching request".

Service interface:

@GET



@Path("/renderwidget/id/{widgetID}/type/{widgetType}/size/{size}/locale/{locale}/{properties}")
 WSWidget renderWidget(@PathParam("widgetID") Long widgetID,
        @PathParam("widgetType") Integer widgetType,
        @PathParam("size") Long containerSize,
        @PathParam("locale") String locale,
        @PathParam("properties") PathSegment props)
        throws RemoteBridgeException;

Working
URL:


/renderwidget/id/1007/type/1/size/1/locale/en_US/properties;numResults=1

Broken:
URL:



/renderwidget/id/1007/type/1/size/1/locale/en_US/properties;numResults=1;foo=bar

The reason I'm trying to use matrix parameters is that I have an
arbitrary map of name/value for a widget class.  I can't try to
parse
them out individually using @MatrixParam, because they vary by
widget
class and are not known at the service level.

Thanks for your help.
--
View this message in context:



http://www.nabble.com/Problem-with-matrix-params%2C-works-with-one%2C-but-not-with-two-%28or-more%29-params-tp24297533p24297533.html
Sent from the cxf-user mailing list archive at Nabble.com.





 --

View this message in context:


http://www.nabble.com/Problem-with-matrix-params%2C-works-with-one%2C-but-not-with-two-%28or-more%29-params-tp24297533p24413449.html
Sent from the cxf-user mailing list archive at Nabble.com.














Reply via email to