Update AAF Version 1.0.0
[aaf/cadi.git] / client / src / main / java / com / att / cadi / client / Rcli.java
1 /*******************************************************************************\r
2  * ============LICENSE_START====================================================\r
3  * * org.onap.aaf\r
4  * * ===========================================================================\r
5  * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.\r
6  * * ===========================================================================\r
7  * * Licensed under the Apache License, Version 2.0 (the "License");\r
8  * * you may not use this file except in compliance with the License.\r
9  * * You may obtain a copy of the License at\r
10  * * \r
11  *  *      http://www.apache.org/licenses/LICENSE-2.0\r
12  * * \r
13  *  * Unless required by applicable law or agreed to in writing, software\r
14  * * distributed under the License is distributed on an "AS IS" BASIS,\r
15  * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
16  * * See the License for the specific language governing permissions and\r
17  * * limitations under the License.\r
18  * * ============LICENSE_END====================================================\r
19  * *\r
20  * * ECOMP is a trademark and service mark of AT&T Intellectual Property.\r
21  * *\r
22  ******************************************************************************/\r
23 package com.att.cadi.client;\r
24 \r
25 import java.io.IOException;\r
26 import java.io.OutputStream;\r
27 import java.net.URI;\r
28 import java.util.Enumeration;\r
29 \r
30 import javax.servlet.ServletInputStream;\r
31 import javax.servlet.http.HttpServletRequest;\r
32 import javax.servlet.http.HttpServletResponse;\r
33 \r
34 import com.att.cadi.CadiException;\r
35 import com.att.cadi.SecuritySetter;\r
36 import com.att.inno.env.APIException;\r
37 import com.att.inno.env.Data.TYPE;\r
38 import com.att.inno.env.util.Pool;\r
39 import com.att.inno.env.util.Pool.Pooled;\r
40 import com.att.rosetta.env.RosettaDF;\r
41 \r
42 public abstract class Rcli<CT> {\r
43         public static final String BLANK = "";\r
44         public static final String CONTENT_TYPE = "Content-Type";\r
45         public static final String ACCEPT = "Accept";\r
46 \r
47         protected static final String POST = "POST";\r
48         protected static final String GET = "GET";\r
49         protected static final String PUT = "PUT";\r
50         protected static final String DELETE = "DELETE";\r
51         protected TYPE type;\r
52         protected String apiVersion;\r
53         protected int readTimeout = 5000;\r
54         protected int connectionTimeout = 3000;\r
55         protected URI uri;\r
56         private String queryParams, fragment;\r
57         public static Pool<byte[]> buffPool = new Pool<byte[]>(new Pool.Creator<byte[]>() {\r
58                 @Override\r
59                 public byte[] create() throws APIException {\r
60                         return new byte[1024];\r
61                 }\r
62 \r
63                 @Override\r
64                 public void destroy(byte[] t) {\r
65                 }\r
66 \r
67                 @Override\r
68                 public boolean isValid(byte[] t) {\r
69                         return true;\r
70                 }\r
71 \r
72                 @Override\r
73                 public void reuse(byte[] t) {\r
74                 }\r
75         });\r
76 \r
77 \r
78         public Rcli() {\r
79                 super();\r
80         }\r
81 \r
82         public abstract void setSecuritySetter(SecuritySetter<CT> ss);\r
83         public abstract SecuritySetter<CT> getSecuritySetter();\r
84 \r
85 \r
86         public Rcli<CT> forUser(SecuritySetter<CT> ss) {\r
87                 Rcli<CT> rv = clone(uri==null?this.uri:uri,ss);\r
88                 setSecuritySetter(ss);\r
89                 rv.type = type;\r
90                 rv.apiVersion = apiVersion;\r
91                 return rv;\r
92         }\r
93         \r
94         protected abstract Rcli<CT> clone(URI uri, SecuritySetter<CT> ss);\r
95         \r
96         public abstract void invalidate() throws CadiException;\r
97 \r
98         public Rcli<CT> readTimeout(int millis) {\r
99                 readTimeout = millis;\r
100                 return this;\r
101         }\r
102 \r
103         public Rcli<CT> connectionTimeout(int millis) {\r
104                 connectionTimeout = millis;\r
105                 return this;\r
106         }\r
107 \r
108         public Rcli<CT> type(TYPE type) {\r
109                 this.type=type;\r
110                 return this;\r
111         }\r
112 \r
113         public Rcli<CT> apiVersion(String apiVersion) {\r
114                 this.apiVersion = apiVersion;\r
115                 return this;\r
116         }\r
117         \r
118         public boolean isApiVersion(String prospective) {\r
119                 return apiVersion.equals(prospective);\r
120         }\r
121 \r
122 \r
123         public String typeString(Class<?> cls) {\r
124                 return "application/"+cls.getSimpleName()+"+"+type.name().toLowerCase()+\r
125                                 (apiVersion==null?BLANK:";version="+apiVersion);\r
126         }\r
127 \r
128         protected abstract EClient<CT> client() throws CadiException;\r
129 \r
130 \r
131         public<T> Future<T> create(String pathinfo, String contentType, final RosettaDF<T> df, final T t) throws APIException, CadiException {\r
132                 final int idx = pathinfo.indexOf('?');\r
133                 final String qp; \r
134                 if(idx>=0) {\r
135                         qp=pathinfo.substring(idx+1);\r
136                         pathinfo=pathinfo.substring(0,idx);\r
137                 } else {\r
138                         qp=queryParams;\r
139                 }\r
140                 EClient<CT> client = client();\r
141                 client.setMethod(POST);\r
142                 client.addHeader(CONTENT_TYPE,contentType);\r
143                 client.setPathInfo(pathinfo);\r
144                 client.setQueryParams(qp);\r
145                 client.setFragment(fragment);\r
146                 client.setPayload(new EClient.Transfer() {\r
147                         @Override\r
148                         public void transfer(OutputStream os) throws IOException, APIException {\r
149                                 df.newData().out(type).direct(t,os);\r
150                         }\r
151                 });\r
152                 client.send();\r
153                 queryParams = fragment = null;\r
154                 return client.futureCreate(df.getTypeClass());\r
155         }\r
156 \r
157         public<T> Future<T> create(String pathinfo, final RosettaDF<T> df, final T t) throws APIException, CadiException {\r
158                 final int idx = pathinfo.indexOf('?');\r
159                 final String qp; \r
160                 if(idx>=0) {\r
161                         qp=pathinfo.substring(idx+1);\r
162                         pathinfo=pathinfo.substring(0,idx);\r
163                 } else {\r
164                         qp=queryParams;\r
165                 }\r
166                 EClient<CT> client = client();\r
167                 client.setMethod(POST);\r
168                 client.addHeader(CONTENT_TYPE,typeString(df.getTypeClass()));\r
169                 client.setPathInfo(pathinfo);\r
170                 client.setQueryParams(qp);\r
171                 client.setFragment(fragment);\r
172                 client.setPayload(new EClient.Transfer() {\r
173                         @Override\r
174                         public void transfer(OutputStream os) throws IOException, APIException {\r
175                                 df.newData().out(type).direct(t,os);\r
176                         }\r
177                 });\r
178                 client.send();\r
179                 queryParams = fragment = null;\r
180                 return client.futureCreate(df.getTypeClass());\r
181         }\r
182 \r
183         public<T> Future<T> create(String pathinfo, Class<?> cls, final RosettaDF<T> df, final T t) throws APIException, CadiException {\r
184                 final int idx = pathinfo.indexOf('?');\r
185                 final String qp; \r
186                 if(idx>=0) {\r
187                         qp=pathinfo.substring(idx+1);\r
188                         pathinfo=pathinfo.substring(0,idx);\r
189                 } else {\r
190                         qp=queryParams;\r
191                 }\r
192 \r
193                 EClient<CT> client = client();\r
194                 client.setMethod(POST);\r
195                 client.addHeader(CONTENT_TYPE,typeString(cls));\r
196                 client.setPathInfo(pathinfo);\r
197                 client.setQueryParams(qp);\r
198                 client.setFragment(fragment);\r
199                 client.setPayload(new EClient.Transfer() {\r
200                         @Override\r
201                         public void transfer(OutputStream os) throws IOException, APIException {\r
202                                 df.newData().out(type).direct(t,os);\r
203                         }\r
204                 });\r
205                 client.send();\r
206                 queryParams = fragment = null;\r
207                 return client.futureCreate(df.getTypeClass());\r
208         }\r
209 \r
210         public<T> Future<T> create(String pathinfo, Class<T> cls) throws APIException, CadiException {\r
211                 final int idx = pathinfo.indexOf('?');\r
212                 final String qp; \r
213                 if(idx>=0) {\r
214                         qp=pathinfo.substring(idx+1);\r
215                         pathinfo=pathinfo.substring(0,idx);\r
216                 } else {\r
217                         qp=queryParams;\r
218                 }\r
219 \r
220                 EClient<CT> client = client();\r
221                 client.setMethod(POST);\r
222                 client.addHeader(CONTENT_TYPE,typeString(cls));\r
223                 client.setPathInfo(pathinfo);\r
224                 client.setQueryParams(qp);\r
225                 client.setFragment(fragment);\r
226                 client.setPayload(null);\r
227                 client.send();\r
228                 queryParams = fragment = null;\r
229                 return client.futureCreate(cls);\r
230         }\r
231 \r
232         public Future<Void> create(String pathinfo, String contentType) throws APIException, CadiException {\r
233                 final int idx = pathinfo.indexOf('?');\r
234                 final String qp; \r
235                 if(idx>=0) {\r
236                         qp=pathinfo.substring(idx+1);\r
237                         pathinfo=pathinfo.substring(0,idx);\r
238                 } else {\r
239                         qp=queryParams;\r
240                 }\r
241 \r
242                 EClient<CT> client = client();\r
243                 client.setMethod(POST);\r
244                 client.addHeader(CONTENT_TYPE,contentType);\r
245                 client.setPathInfo(pathinfo);\r
246                 client.setQueryParams(qp);\r
247                 client.setFragment(fragment);\r
248                 client.setPayload(null);\r
249                 client.send();\r
250                 queryParams = fragment = null;\r
251                 return client.futureCreate(Void.class);\r
252         }\r
253 \r
254 \r
255         public Future<String> read(String pathinfo, String accept, String ... headers) throws APIException, CadiException {\r
256                 final int idx = pathinfo.indexOf('?');\r
257                 final String qp; \r
258                 if(idx>=0) {\r
259                         qp=pathinfo.substring(idx+1);\r
260                         pathinfo=pathinfo.substring(0,idx);\r
261                 } else {\r
262                         qp=queryParams;\r
263                 }\r
264 \r
265                 EClient<CT> client = client();\r
266                 client.setMethod(GET);\r
267                 client.addHeader(ACCEPT, accept);\r
268                 \r
269                 for(int i=1;i<headers.length;i=i+2) {\r
270                         client.addHeader(headers[i-1],headers[i]);\r
271                 }\r
272                 client.setQueryParams(qp);\r
273                 client.setFragment(fragment);\r
274 \r
275                 client.setPathInfo(pathinfo);\r
276                 \r
277                 client.setPayload(null);\r
278                 client.send();\r
279                 queryParams = fragment = null;\r
280                 return client.futureReadString();\r
281         }\r
282 \r
283         public<T> Future<T> read(String pathinfo, String accept, RosettaDF<T> df, String ... headers) throws APIException, CadiException {\r
284                 final int idx = pathinfo.indexOf('?');\r
285                 final String qp; \r
286                 if(idx>=0) {\r
287                         qp=pathinfo.substring(idx+1);\r
288                         pathinfo=pathinfo.substring(0,idx);\r
289                 } else {\r
290                         qp=queryParams;\r
291                 }\r
292 \r
293                 EClient<CT> client = client();\r
294                 client.setMethod(GET);\r
295                 client.addHeader(ACCEPT, accept);\r
296                 for(int i=1;i<headers.length;i=i+2) {\r
297                         client.addHeader(headers[i-1],headers[i]);\r
298                 }\r
299                 client.setQueryParams(qp);\r
300                 client.setFragment(fragment);\r
301                 client.setPathInfo(pathinfo);\r
302                 \r
303                 client.setPayload(null);\r
304                 client.send();\r
305                 queryParams = fragment = null;\r
306                 return client.futureRead(df,type);\r
307         }\r
308 \r
309         public<T> Future<T> read(String pathinfo, RosettaDF<T> df,String ... headers) throws APIException, CadiException {\r
310                 final int idx = pathinfo.indexOf('?');\r
311                 final String qp; \r
312                 if(idx>=0) {\r
313                         qp=pathinfo.substring(idx+1);\r
314                         pathinfo=pathinfo.substring(0,idx);\r
315                 } else {\r
316                         qp=queryParams;\r
317                 }\r
318 \r
319                 EClient<CT> client = client();\r
320                 client.setMethod(GET);\r
321                 client.addHeader(ACCEPT, typeString(df.getTypeClass()));\r
322                 for(int i=1;i<headers.length;i=i+2) {\r
323                         client.addHeader(headers[i-1],headers[i]);\r
324                 }\r
325                 client.setQueryParams(qp);\r
326                 client.setFragment(fragment);\r
327                 client.setPathInfo(pathinfo);\r
328                 \r
329                 client.setPayload(null);\r
330                 client.send();\r
331                 queryParams = fragment = null;\r
332                 return client.futureRead(df,type);\r
333         }\r
334 \r
335         public<T> Future<T> read(String pathinfo, Class<?> cls, RosettaDF<T> df) throws APIException, CadiException {\r
336                 final int idx = pathinfo.indexOf('?');\r
337                 final String qp; \r
338                 if(idx>=0) {\r
339                         qp=pathinfo.substring(idx+1);\r
340                         pathinfo=pathinfo.substring(0,idx);\r
341                 } else {\r
342                         qp=queryParams;\r
343                 }\r
344 \r
345                 EClient<CT> client = client();\r
346                 client.setMethod(GET);\r
347                 client.addHeader(ACCEPT, typeString(cls));\r
348                 client.setQueryParams(qp);\r
349                 client.setFragment(fragment);\r
350                 client.setPathInfo(pathinfo);\r
351                 \r
352                 client.setPayload(null);\r
353                 client.send();\r
354                 queryParams = fragment = null;\r
355                 return client.futureRead(df,type);\r
356         }\r
357 \r
358         public<T> Future<T> update(String pathinfo, String contentType, final RosettaDF<T> df, final T t) throws APIException, CadiException {\r
359                 final int idx = pathinfo.indexOf('?');\r
360                 final String qp; \r
361                 if(idx>=0) {\r
362                         qp=pathinfo.substring(idx+1);\r
363                         pathinfo=pathinfo.substring(0,idx);\r
364                 } else {\r
365                         qp=queryParams;\r
366                 }\r
367 \r
368                 EClient<CT> client = client();\r
369                 client.setMethod(PUT);\r
370                 client.addHeader(CONTENT_TYPE,contentType);\r
371                 client.setQueryParams(qp);\r
372                 client.setFragment(fragment);\r
373                 client.setPathInfo(pathinfo);\r
374                 client.setPayload(new EClient.Transfer() {\r
375                         @Override\r
376                         public void transfer(OutputStream os) throws IOException, APIException {\r
377                                 df.newData().out(type).direct(t,os);\r
378                         }\r
379                 });\r
380                 client.send();\r
381                 queryParams = fragment = null;\r
382                 return client.future(t);\r
383         }\r
384         \r
385         public<T> Future<String> updateRespondString(String pathinfo, final RosettaDF<T> df, final T t) throws APIException, CadiException {\r
386                 final int idx = pathinfo.indexOf('?');\r
387                 final String qp; \r
388                 if(idx>=0) {\r
389                         qp=pathinfo.substring(idx+1);\r
390                         pathinfo=pathinfo.substring(0,idx);\r
391                 } else {\r
392                         qp=queryParams;\r
393                 }\r
394 \r
395                 EClient<CT> client = client();\r
396                 client.setMethod(PUT);\r
397                 client.addHeader(CONTENT_TYPE, typeString(df.getTypeClass()));\r
398                 client.setQueryParams(qp);\r
399                 client.setFragment(fragment);\r
400                 client.setPathInfo(pathinfo);\r
401                 client.setPayload(new EClient.Transfer() {\r
402                         @Override\r
403                         public void transfer(OutputStream os) throws IOException, APIException {\r
404                                 df.newData().out(type).direct(t,os);\r
405                         }\r
406                 });\r
407                 client.send();\r
408                 queryParams = fragment = null;\r
409                 return client.futureReadString();\r
410         }\r
411 \r
412 \r
413         public<T> Future<T> update(String pathinfo, final RosettaDF<T> df, final T t) throws APIException, CadiException {\r
414                 final int idx = pathinfo.indexOf('?');\r
415                 final String qp; \r
416                 if(idx>=0) {\r
417                         qp=pathinfo.substring(idx+1);\r
418                         pathinfo=pathinfo.substring(0,idx);\r
419                 } else {\r
420                         qp=queryParams;\r
421                 }\r
422 \r
423                 EClient<CT> client = client();\r
424                 client.setMethod(PUT);\r
425                 client.addHeader(CONTENT_TYPE, typeString(df.getTypeClass()));\r
426                 client.setQueryParams(qp);\r
427                 client.setFragment(fragment);\r
428                 client.setPathInfo(pathinfo);\r
429                 client.setPayload(new EClient.Transfer() {\r
430                         @Override\r
431                         public void transfer(OutputStream os) throws IOException, APIException {\r
432                                 df.newData().out(type).direct(t,os);\r
433                         }\r
434                 });\r
435                 client.send();\r
436                 queryParams = fragment = null;\r
437                 return client.future(t);\r
438         }\r
439         \r
440         public<T> Future<T> update(String pathinfo, Class<?> cls, final RosettaDF<T> df, final T t) throws APIException, CadiException {\r
441                 final int idx = pathinfo.indexOf('?');\r
442                 final String qp; \r
443                 if(idx>=0) {\r
444                         qp=pathinfo.substring(idx+1);\r
445                         pathinfo=pathinfo.substring(0,idx);\r
446                 } else {\r
447                         qp=queryParams;\r
448                 }\r
449 \r
450                 EClient<CT> client = client();\r
451                 client.setMethod(PUT);\r
452                 client.addHeader(CONTENT_TYPE, typeString(cls));\r
453                 client.setQueryParams(qp);\r
454                 client.setFragment(fragment);\r
455                 client.setPathInfo(pathinfo);\r
456                 client.setPayload(new EClient.Transfer() {\r
457                         @Override\r
458                         public void transfer(OutputStream os) throws IOException, APIException {\r
459                                 df.newData().out(type).direct(t,os);\r
460                         }\r
461                 });\r
462                 client.send();\r
463                 queryParams = fragment = null;\r
464                 return client.future(t);\r
465         }\r
466 \r
467         /**\r
468          * A method to update with a VOID\r
469          * @param pathinfo\r
470          * @param resp\r
471          * @param expected\r
472          * @return\r
473          * @throws APIException\r
474          * @throws CadiException\r
475          */\r
476         public<T> Future<Void> update(String pathinfo) throws APIException, CadiException {\r
477                 final int idx = pathinfo.indexOf('?');\r
478                 final String qp; \r
479                 if(idx>=0) {\r
480                         qp=pathinfo.substring(idx+1);\r
481                         pathinfo=pathinfo.substring(0,idx);\r
482                 } else {\r
483                         qp=queryParams;\r
484                 }\r
485 \r
486                 EClient<CT> client = client();\r
487                 client.setMethod(PUT);\r
488                 client.addHeader(CONTENT_TYPE, typeString(Void.class));\r
489                 client.setQueryParams(qp);\r
490                 client.setFragment(fragment);\r
491                 client.setPathInfo(pathinfo);\r
492 //              client.setPayload(new EClient.Transfer() {\r
493 //                      @Override\r
494 //                      public void transfer(OutputStream os) throws IOException, APIException {\r
495 //                      }\r
496 //              });\r
497                 client.send();\r
498                 queryParams = fragment = null;\r
499                 return client.future(null);\r
500         }\r
501 \r
502         public<T> Future<T> delete(String pathinfo, String contentType, final RosettaDF<T> df, final T t) throws APIException, CadiException {\r
503                 final int idx = pathinfo.indexOf('?');\r
504                 final String qp; \r
505                 if(idx>=0) {\r
506                         qp=pathinfo.substring(idx+1);\r
507                         pathinfo=pathinfo.substring(0,idx);\r
508                 } else {\r
509                         qp=queryParams;\r
510                 }\r
511 \r
512                 EClient<CT> client = client();\r
513                 client.setMethod(DELETE);\r
514                 client.addHeader(CONTENT_TYPE, contentType);\r
515                 client.setQueryParams(qp);\r
516                 client.setFragment(fragment);\r
517                 client.setPathInfo(pathinfo);\r
518                 client.setPayload(new EClient.Transfer() {\r
519                         @Override\r
520                         public void transfer(OutputStream os) throws IOException, APIException {\r
521                                 df.newData().out(type).direct(t,os);\r
522                         }\r
523                 });\r
524                 client.send();\r
525                 queryParams = fragment = null;\r
526                 return client.future(t);\r
527         }\r
528 \r
529         public<T> Future<T> delete(String pathinfo, Class<?> cls, final RosettaDF<T> df, final T t) throws APIException, CadiException {\r
530                 final int idx = pathinfo.indexOf('?');\r
531                 final String qp; \r
532                 if(idx>=0) {\r
533                         qp=pathinfo.substring(idx+1);\r
534                         pathinfo=pathinfo.substring(0,idx);\r
535                 } else {\r
536                         qp=queryParams;\r
537                 }\r
538 \r
539                 EClient<CT> client = client();\r
540                 client.setMethod(DELETE);\r
541                 client.addHeader(CONTENT_TYPE, typeString(cls));\r
542                 client.setQueryParams(qp);\r
543                 client.setFragment(fragment);\r
544                 client.setPathInfo(pathinfo);\r
545                 client.setPayload(new EClient.Transfer() {\r
546                         @Override\r
547                         public void transfer(OutputStream os) throws IOException, APIException {\r
548                                 df.newData().out(type).direct(t,os);\r
549                         }\r
550                 });\r
551                 client.send();\r
552                 queryParams = fragment = null;\r
553                 return client.future(t);\r
554         }\r
555 \r
556         public<T> Future<T> delete(String pathinfo, final RosettaDF<T> df, final T t) throws APIException, CadiException {\r
557                 final int idx = pathinfo.indexOf('?');\r
558                 final String qp; \r
559                 if(idx>=0) {\r
560                         qp=pathinfo.substring(idx+1);\r
561                         pathinfo=pathinfo.substring(0,idx);\r
562                 } else {\r
563                         qp=queryParams;\r
564                 }\r
565 \r
566                 EClient<CT> client = client();\r
567                 client.setMethod(DELETE);\r
568                 client.addHeader(CONTENT_TYPE, typeString(df.getTypeClass()));\r
569                 client.setQueryParams(qp);\r
570                 client.setFragment(fragment);\r
571                 client.setPathInfo(pathinfo);\r
572                 client.setPayload(new EClient.Transfer() {\r
573                         @Override\r
574                         public void transfer(OutputStream os) throws IOException, APIException {\r
575                                 df.newData().out(type).direct(t,os);\r
576                         }\r
577                 });\r
578 \r
579                 client.send();\r
580                 queryParams = fragment = null;\r
581                 return client.future(t);\r
582         }\r
583 \r
584 \r
585         public<T> Future<T> delete(String pathinfo, Class<T> cls) throws APIException, CadiException {\r
586                 final int idx = pathinfo.indexOf('?');\r
587                 final String qp; \r
588                 if(idx>=0) {\r
589                         qp=pathinfo.substring(idx+1);\r
590                         pathinfo=pathinfo.substring(0,idx);\r
591                 } else {\r
592                         qp=queryParams;\r
593                 }\r
594 \r
595                 EClient<CT> client = client();\r
596                 client.setMethod(DELETE);\r
597                 client.addHeader(CONTENT_TYPE, typeString(cls));\r
598                 client.setQueryParams(qp);\r
599                 client.setFragment(fragment);\r
600                 client.setPathInfo(pathinfo);\r
601                 client.setPayload(null);\r
602                 client.send();\r
603                 queryParams = fragment = null;\r
604                 return client.future((T)null);\r
605         }\r
606 \r
607         public Future<Void> delete(String pathinfo, String contentType) throws APIException, CadiException {\r
608                 final int idx = pathinfo.indexOf('?');\r
609                 final String qp; \r
610                 if(idx>=0) {\r
611                         qp=pathinfo.substring(idx+1);\r
612                         pathinfo=pathinfo.substring(0,idx);\r
613                 } else {\r
614                         qp=queryParams;\r
615                 }\r
616 \r
617                 EClient<CT> client = client();\r
618                 client.setMethod(DELETE);\r
619                 client.addHeader(CONTENT_TYPE, contentType);\r
620                 client.setQueryParams(qp);\r
621                 client.setFragment(fragment);\r
622                 client.setPathInfo(pathinfo);\r
623                 client.setPayload(null);\r
624                 client.send();\r
625                 queryParams = fragment = null;\r
626                 return client.future(null);\r
627         }\r
628 \r
629         public Future<Void> transfer(final HttpServletRequest req, final HttpServletResponse resp, final String pathParam, final int expected) throws CadiException, APIException {\r
630                 EClient<CT> client = client();\r
631                 URI uri;\r
632                 try {\r
633                         uri = new URI(req.getRequestURI());\r
634                 } catch (Exception e) {\r
635                         throw new CadiException("Invalid incoming URI",e);\r
636                 }\r
637                 String name;\r
638                 for(Enumeration<String> en = req.getHeaderNames();en.hasMoreElements();) {\r
639                         name = en.nextElement();\r
640                         client.addHeader(name,req.getHeader(name));\r
641                 }\r
642                 client.setQueryParams(req.getQueryString());\r
643                 client.setFragment(uri.getFragment());\r
644                 client.setPathInfo(pathParam);\r
645                 String meth = req.getMethod();\r
646                 client.setMethod(meth);\r
647                 if(!"GET".equals(meth)) {\r
648                         client.setPayload(new EClient.Transfer() {\r
649                                 @Override\r
650                                 public void transfer(OutputStream os) throws IOException, APIException {\r
651                                         final ServletInputStream is = req.getInputStream();\r
652                                         int read;\r
653                                         // reuse Buffers\r
654                                         Pooled<byte[]> pbuff = buffPool.get();\r
655                                         try { \r
656                                                 while((read=is.read(pbuff.content))>=0) {\r
657                                                         os.write(pbuff.content,0,read);\r
658                                                 }\r
659                                         } finally {\r
660                                                 pbuff.done();\r
661                                         }\r
662                                 }\r
663                         });\r
664                 }\r
665                 client.send();\r
666                 return client.future(resp, expected);\r
667         }\r
668 \r
669         public String toString() {\r
670                 return uri.toString();\r
671         }\r
672 \r
673         /**\r
674          * @param queryParams the queryParams to set\r
675          * @return \r
676          */\r
677         public Rcli<CT> setQueryParams(String queryParams) {\r
678                 this.queryParams = queryParams;\r
679                 return this;\r
680         }\r
681         \r
682 \r
683         /**\r
684          * @param fragment the fragment to set\r
685          * @return \r
686          */\r
687         public Rcli<CT> setFragment(String fragment) {\r
688                 this.fragment = fragment;\r
689                 return this;\r
690         }\r
691 \r
692         public URI getURI() {\r
693                 return uri;\r
694         }\r
695 \r
696 }\r