Return-Path: X-Original-To: apmail-hbase-dev-archive@www.apache.org Delivered-To: apmail-hbase-dev-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id ACF23768B for ; Mon, 18 Jul 2011 23:32:28 +0000 (UTC) Received: (qmail 64113 invoked by uid 500); 18 Jul 2011 23:32:26 -0000 Delivered-To: apmail-hbase-dev-archive@hbase.apache.org Received: (qmail 63959 invoked by uid 500); 18 Jul 2011 23:32:25 -0000 Mailing-List: contact dev-help@hbase.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@hbase.apache.org Delivered-To: mailing list dev@hbase.apache.org Received: (qmail 63945 invoked by uid 99); 18 Jul 2011 23:32:25 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 18 Jul 2011 23:32:25 +0000 X-ASF-Spam-Status: No, hits=0.7 required=5.0 tests=RCVD_IN_DNSWL_NONE,SPF_NEUTRAL X-Spam-Check-By: apache.org Received-SPF: neutral (nike.apache.org: local policy) Received: from [98.139.52.219] (HELO nm22.bullet.mail.ac4.yahoo.com) (98.139.52.219) by apache.org (qpsmtpd/0.29) with SMTP; Mon, 18 Jul 2011 23:32:14 +0000 Received: from [98.139.52.193] by nm22.bullet.mail.ac4.yahoo.com with NNFMP; 18 Jul 2011 23:31:53 -0000 Received: from [98.139.52.135] by tm6.bullet.mail.ac4.yahoo.com with NNFMP; 18 Jul 2011 23:31:53 -0000 Received: from [127.0.0.1] by omp1018.mail.ac4.yahoo.com with NNFMP; 18 Jul 2011 23:31:53 -0000 X-Yahoo-Newman-Property: ymail-3 X-Yahoo-Newman-Id: 310795.82300.bm@omp1018.mail.ac4.yahoo.com Received: (qmail 69164 invoked by uid 60001); 18 Jul 2011 23:31:53 -0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s1024; t=1311031913; bh=duv+qJy5kIFnHMd1k6oeE4d1KtRtmKuBIHHXw3lh6Fk=; h=X-YMail-OSG:Received:X-RocketYMMF:X-Mailer:References:Message-ID:Date:From:Reply-To:Subject:To:Cc:In-Reply-To:MIME-Version:Content-Type:Content-Transfer-Encoding; b=hkcpGRk/sHlJTeUHxrsUN76eEDYi1w8mDynnfuTHuyGXjdHXO1ZEBN043K3GTmd+UsEx4bksNqXkvhuiyDD77j+SVfXUeADnyzE349/JleP7xKj3qrqHYJT0saEN8FoSRgWvWYo6tAn40LOcNisF0P16HT9SML2PwIqSqMUGRDo= X-YMail-OSG: ni.vStkVM1lJHgDFEO0Go_HPY9ezvDlJ0lyC_L6QAuTaIJd ZKRSY1o4T3ZOSfv8ZXaMEqA646fGNWZtk2K2gXf0EXdTXVNzg8hpq6JqikH3 T6QK.N1xAY0tmB2aAPiUO13.LbScCY9Xgc.VdDSxQ2zT317EcmWmmGMkDAxt qkuPAEi767Sxyp61UIcZ0fT3LSqAINZq3_ADCxb1H3jlvnWyzOykVaN.dZS9 gpfy8WUkdeWZnr1mUmYJwKIwG2nS4D9y9DlLxUpGLdvPICVmmTb1IBYHlI61 S5oeOfkObhN4lyTkBYyiHS_vyI7uq2SOru2LaQEMguyPNdp7RsXEJiNo6idx yJyfOMvkWEN90EopFBrGCqLwFIlOeW7y.oSHbcY8EN1RXPoA6eJ7BWJ.BFmD l6383alKYQuec Received: from [173.200.187.194] by web65507.mail.ac4.yahoo.com via HTTP; Mon, 18 Jul 2011 16:31:53 PDT X-RocketYMMF: apurtell X-Mailer: YahooMailWebService/0.8.112.307740 References: Message-ID: <1311031913.69123.YahooMailNeo@web65507.mail.ac4.yahoo.com> Date: Mon, 18 Jul 2011 16:31:53 -0700 (PDT) From: Andrew Purtell Reply-To: Andrew Purtell Subject: Re: HBase rest RowSpec bug on startRow and endRow To: "user@hbase.apache.org" Cc: "dev@hbase.apache.org" In-Reply-To: MIME-Version: 1.0 Content-Type: text/plain; charset=iso-8859-1 Content-Transfer-Encoding: quoted-printable X-Virus-Checked: Checked by ClamAV on apache.org Allan,=0A=0AThanks for the bug report, analysis, and contribution. I will i= ncorporate you patches as part of HBASE-4116: https://issues.apache.org/jir= a/browse/HBASE-4116=0A=0A=A0=0ABest regards,=0A=0A=0A- Andy=0A=0A=0AProblem= s worthy of attack prove their worth by hitting back. - Piet Hein (via Tom = White)=0A=0A=0A----- Original Message -----=0A> From: allan yan =0A> To: user@hbase.apache.org=0A> Cc: dev@hbase.apache.org=0A> S= ent: Monday, July 18, 2011 2:49 PM=0A> Subject: HBase rest RowSpec bug on s= tartRow and endRow=0A> =0A> Hi,=0A> =0A> I don't know how to report issue t= o HBase team. So I just post it here. =0A> There might be a bug for REST we= b service to get rows with given startRow and =0A> endRow.=0A> =0A> For exa= mple, to get a list of rows with startRow=3Dtestrow1, endRow=3Dtestrow2, I= =A0 =0A> send GET request: =0A> =0A> curl http://localhost:8123/TestRowReso= urce/testrow1,testrow2/a:1=0A> =0A> And got StringIndexOutOfBoundsException= :=0A> =0A> 2011-07-18 14:25:49,977 ERROR [1378924033@qtp-310826391-0] log.S= lf4jLog(87): =0A> /TestRowResource/testrow1,testrow2/a:1=0A> java.lang.Ille= galArgumentException: java.lang.StringIndexOutOfBoundsException: =0A> Strin= g index out of range: -1=0A> =A0=A0=A0 at org.apache.hadoop.hbase.rest.RowS= pec.parseRowKeys(RowSpec.java:84)=0A> =A0=A0=A0 at org.apache.hadoop.hbase.= rest.RowSpec.(RowSpec.java:56)=0A> =A0=A0=A0 at =0A> org.apache.hadoo= p.hbase.rest.RowResource.(RowResource.java:71)=0A> =A0=A0=A0 at =0A> = org.apache.hadoop.hbase.rest.TableResource.getRowResource(TableResource.jav= a:278)=0A> =A0=A0=A0 at sun.reflect.NativeMethodAccessorImpl.invoke0(Native= Method)=0A> =A0=A0=A0 at =0A> sun.reflect.NativeMethodAccessorImpl.invoke(= NativeMethodAccessorImpl.java:39)=0A> =A0=A0=A0 at =0A> sun.reflect.Delegat= ingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)=0A> =A0= =A0=A0 at java.lang.reflect.Method.invoke(Method.java:597)=0A> =A0=A0=A0 at= =0A> com.sun.jersey.server.impl.uri.rules.SubLocatorRule.invokeSubLocator(= SubLocatorRule.java:165)=0A> =A0=A0=A0 at =0A> com.sun.jersey.server.impl.u= ri.rules.SubLocatorRule.accept(SubLocatorRule.java:97)=0A> =A0=A0=A0 at =0A= > com.sun.jersey.server.impl.uri.rules.RightHandPathRule.accept(RightHandPa= thRule.java:136)=0A> =A0=A0=A0 at =0A> com.sun.jersey.server.impl.uri.rules= .SubLocatorRule.accept(SubLocatorRule.java:121)=0A> =A0=A0=A0 at =0A> com.s= un.jersey.server.impl.uri.rules.RightHandPathRule.accept(RightHandPathRule.= java:136)=0A> =A0=A0=A0 at =0A> com.sun.jersey.server.impl.uri.rules.Resour= ceClassRule.accept(ResourceClassRule.java:86)=0A> =A0=A0=A0 at =0A> com.sun= .jersey.server.impl.uri.rules.RightHandPathRule.accept(RightHandPathRule.ja= va:136)=0A> =A0=A0=A0 at =0A> com.sun.jersey.server.impl.uri.rules.RootReso= urceClassesRule.accept(RootResourceClassesRule.java:74)=0A> =A0=A0=A0 at = =0A> com.sun.jersey.server.impl.application.WebApplicationImpl._handleReque= st(WebApplicationImpl.java:1357)=0A> =A0=A0=A0 at =0A> com.sun.jersey.serve= r.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.jav= a:1289)=0A> =A0=A0=A0 at =0A> com.sun.jersey.server.impl.application.WebApp= licationImpl.handleRequest(WebApplicationImpl.java:1239)=0A> =A0=A0=A0 at = =0A> com.sun.jersey.server.impl.application.WebApplicationImpl.handleReques= t(WebApplicationImpl.java:1229)=0A> =A0=A0=A0 at =0A> com.sun.jersey.spi.co= ntainer.servlet.WebComponent.service(WebComponent.java:420)=0A> =A0=A0=A0 a= t =0A> com.sun.jersey.spi.container.servlet.ServletContainer.service(Servle= tContainer.java:497)=0A> =A0=A0=A0 at =0A> com.sun.jersey.spi.container.ser= vlet.ServletContainer.service(ServletContainer.java:684)=0A> =A0=A0=A0 at j= avax.servlet.http.HttpServlet.service(HttpServlet.java:820)=0A> =A0=A0=A0 a= t org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:511)=0A= > =A0=A0=A0 at =0A> org.mortbay.jetty.servlet.ServletHandler$CachedChain.do= Filter(ServletHandler.java:1221)=0A> =A0=A0=A0 at =0A> org.apache.hadoop.hb= ase.rest.filter.GzipFilter.doFilter(GzipFilter.java:73)=0A> =A0=A0=A0 at = =0A> org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletH= andler.java:1212)=0A> =A0=A0=A0 at org.mortbay.jetty.servlet.ServletHandler= .handle(ServletHandler.java:399)=0A> =A0=A0=A0 at org.mortbay.jetty.servlet= .SessionHandler.handle(SessionHandler.java:182)=0A> =A0=A0=A0 at org.mortba= y.jetty.handler.ContextHandler.handle(ContextHandler.java:766)=0A> =A0=A0= =A0 at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:= 152)=0A> =A0=A0=A0 at org.mortbay.jetty.Server.handle(Server.java:326)=0A> = =A0=A0=A0 at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.= java:542)=0A> =A0=A0=A0 at =0A> org.mortbay.jetty.HttpConnection$RequestHan= dler.headerComplete(HttpConnection.java:928)=0A> =A0=A0=A0 at org.mortbay.j= etty.HttpParser.parseNext(HttpParser.java:549)=0A> =A0=A0=A0 at org.mortbay= .jetty.HttpParser.parseAvailable(HttpParser.java:212)=0A> =A0=A0=A0 at org.= mortbay.jetty.HttpConnection.handle(HttpConnection.java:404)=0A> =A0=A0=A0 = at =0A> org.mortbay.jetty.bio.SocketConnector$Connection.run(SocketConnecto= r.java:228)=0A> =A0=A0=A0 at =0A> org.mortbay.thread.QueuedThreadPool$PoolT= hread.run(QueuedThreadPool.java:582)=0A> Caused by: java.lang.StringIndexOu= tOfBoundsException: String index out of range: =0A> -1=0A> =A0=A0=A0 at jav= a.lang.String.substring(String.java:1937)=0A> =A0=A0=A0 at java.lang.String= .substring(String.java:1904)=0A> =A0=A0=A0 at org.apache.hadoop.hbase.rest.= RowSpec.parseRowKeys(RowSpec.java:78)=0A> =A0=A0=A0 ... 39 more=0A> =0A> Th= is was because in the RowSpec.java, parseRowKeys method, startRow value was= =0A> changed:=0A> --------------------------------------------------------= -------------------------=0A> =A0 =A0 =A0 startRow =3D sb.toString();=0A> = =A0 =A0 =A0 int idx =3D startRow.indexOf(',');=0A> =A0 =A0 =A0 if (idx !=3D= -1) {=0A> =A0 =A0 =A0 =A0 startRow =3D URLDecoder.decode(startRow.substrin= g(0, idx),=0A> =A0 =A0 =A0 =A0 =A0 HConstants.UTF8_ENCODING);=0A> =A0 =A0 = =A0 =A0 endRow =3D URLDecoder.decode(startRow.substring(idx + 1),=0A> =A0 = =A0 =A0 =A0 =A0 HConstants.UTF8_ENCODING);=0A> =A0 =A0 =A0 } else {=0A> =A0= =A0 =A0 =A0 startRow =3D URLDecoder.decode(startRow, HConstants.UTF8_ENCOD= ING);=0A> =A0 =A0 =A0 }=0A> -----------------------------------------------= ----------------------------------=0A> After change to this, it works:=0A> = ---------------------------------------------------------------------------= ------=0A> =A0 =A0 =A0 String row =3D sb.toString();=0A> =A0 =A0 =A0 int id= x =3D row.indexOf(',');=0A> =A0 =A0 =A0 if (idx !=3D -1) {=0A> =A0 =A0 =A0 = =A0 startRow =3D URLDecoder.decode(row.substring(0, idx),=0A> =A0 =A0 =A0 = =A0 =A0 HConstants.UTF8_ENCODING);=0A> =A0 =A0 =A0 =A0 endRow =3D URLDecode= r.decode(row.substring(idx + 1),=0A> =A0 =A0 =A0 =A0 =A0 HConstants.UTF8_EN= CODING);=0A> =A0 =A0 =A0 } else {=0A> =A0 =A0 =A0 =A0 startRow =3D URLDecod= er.decode(row, HConstants.UTF8_ENCODING);=0A> =A0 =A0 =A0 }=0A> -----------= ----------------------------------------------------------------------=0A> = =0A> I've also created a unit test method in TestRowResource.java,=0A> ----= ---------------------------------------------------------------------------= --=0A> =A0 @Test=0A> =A0 public void testStartEndRowGetPutXML() throws IOEx= ception, JAXBException {=0A> =A0=A0=A0 String[] rows =3D {ROW_1,ROW_2,ROW_3= };=0A> =A0=A0=A0 String[] values =3D {VALUE_1,VALUE_2,VALUE_3};=A0 =0A> =A0= =A0=A0 Response response =3D null;=0A> =A0=A0=A0 for(int i=3D0; i =A0=A0=A0 =A0=A0=A0 response =3D putValueXML(TABLE, rows[i], = COLUMN_1, values[i]);=0A> =A0=A0=A0 =A0=A0=A0 assertEquals(200, response.ge= tCode());=0A> =A0=A0=A0 =A0=A0=A0 checkValueXML(TABLE, rows[i], COLUMN_1, v= alues[i]);=0A> =A0=A0=A0 }=0A> =0A> =A0 =A0 response =3D getValueXML(TABLE,= rows[0], rows[2], COLUMN_1);=0A> =A0 =A0 assertEquals(200, response.getCod= e());=0A> =A0 =A0 CellSetModel cellSet =3D (CellSetModel)=0A> =A0 =A0 =A0 u= nmarshaller.unmarshal(new ByteArrayInputStream(response.getBody()));=0A> = =A0 =A0 assertEquals(2, cellSet.getRows().size());=0A> =A0 =A0 for(int i=3D= 0; i =A0 =A0 =A0=A0=A0 RowModel rowMo= del =3D cellSet.getRows().get(i);=0A> =A0 =A0 =A0=A0=A0 for(CellModel cell = : rowModel.getCells()){=0A> =A0 =A0 =A0=A0=A0 =A0=A0=A0 assertEquals(COLUMN= _1, Bytes.toString(cell.getColumn()));=0A> =A0 =A0 =A0=A0=A0 =A0=A0=A0 asse= rtEquals(values[i], Bytes.toString(cell.getValue()));=0A> =A0 =A0 =A0=A0=A0= }=A0=A0=A0 =0A> =A0 =A0 }=0A> =A0 =A0 =0A> =A0 =A0 for(String row : rows){= =0A> =A0 =A0 =A0=A0=A0 response =3D deleteRow(TABLE, row);=0A> =A0 =A0 =A0= =A0=A0 assertEquals(200, response.getCode());=0A> =A0 =A0 }=0A> =A0 }=0A> = =0A> =A0 private static Response getValueXML(String table, String startRow,= String =0A> endRow, String column)=0A> =A0=A0=A0 =A0 =A0 =A0 throws IOExce= ption {=0A> =A0=A0=A0 =A0 =A0 StringBuilder path =3D new StringBuilder();= =0A> =A0=A0=A0 =A0 =A0 path.append('/');=0A> =A0=A0=A0 =A0 =A0 path.append(= table);=0A> =A0=A0=A0 =A0 =A0 path.append('/');=0A> =A0=A0=A0 =A0 =A0 path.= append(startRow);=0A> =A0=A0=A0 =A0 =A0 path.append(",");=0A> =A0=A0=A0 =A0= =A0 path.append(endRow);=0A> =A0=A0=A0 =A0 =A0 path.append('/');=0A> =A0= =A0=A0 =A0 =A0 path.append(column);=0A> =A0=A0=A0 =A0 =A0 return getValueXM= L(path.toString());=0A> =A0 }=0A> -----------------------------------------= ----------------------------------------=0A> =0A> Thanks,=0A> Allan Yan=0A>