1 /*******************************************************************************
\r
2 * ============LICENSE_START====================================================
\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
11 * * http://www.apache.org/licenses/LICENSE-2.0
\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
20 * * ECOMP is a trademark and service mark of AT&T Intellectual Property.
\r
22 ******************************************************************************/
\r
23 package org.onap.aaf.cadi.client;
\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
30 import javax.servlet.ServletInputStream;
\r
31 import javax.servlet.http.HttpServletRequest;
\r
32 import javax.servlet.http.HttpServletResponse;
\r
34 import org.onap.aaf.cadi.CadiException;
\r
35 import org.onap.aaf.cadi.SecuritySetter;
\r
37 import org.onap.aaf.inno.env.APIException;
\r
38 import org.onap.aaf.inno.env.Data.TYPE;
\r
39 import org.onap.aaf.inno.env.util.Pool;
\r
40 import org.onap.aaf.inno.env.util.Pool.Pooled;
\r
41 import org.onap.aaf.rosetta.env.RosettaDF;
\r
43 public abstract class Rcli<CT> {
\r
44 public static final String BLANK = "";
\r
45 public static final String CONTENT_TYPE = "Content-Type";
\r
46 public static final String ACCEPT = "Accept";
\r
48 protected static final String POST = "POST";
\r
49 protected static final String GET = "GET";
\r
50 protected static final String PUT = "PUT";
\r
51 protected static final String DELETE = "DELETE";
\r
52 protected TYPE type;
\r
53 protected String apiVersion;
\r
54 protected int readTimeout = 5000;
\r
55 protected int connectionTimeout = 3000;
\r
57 private String queryParams, fragment;
\r
58 public static Pool<byte[]> buffPool = new Pool<byte[]>(new Pool.Creator<byte[]>() {
\r
60 public byte[] create() throws APIException {
\r
61 return new byte[1024];
\r
65 public void destroy(byte[] t) {
\r
69 public boolean isValid(byte[] t) {
\r
74 public void reuse(byte[] t) {
\r
83 public abstract void setSecuritySetter(SecuritySetter<CT> ss);
\r
84 public abstract SecuritySetter<CT> getSecuritySetter();
\r
87 public Rcli<CT> forUser(SecuritySetter<CT> ss) {
\r
88 Rcli<CT> rv = clone(uri==null?this.uri:uri,ss);
\r
89 setSecuritySetter(ss);
\r
91 rv.apiVersion = apiVersion;
\r
95 protected abstract Rcli<CT> clone(URI uri, SecuritySetter<CT> ss);
\r
97 public abstract void invalidate() throws CadiException;
\r
99 public Rcli<CT> readTimeout(int millis) {
\r
100 readTimeout = millis;
\r
104 public Rcli<CT> connectionTimeout(int millis) {
\r
105 connectionTimeout = millis;
\r
109 public Rcli<CT> type(TYPE type) {
\r
114 public Rcli<CT> apiVersion(String apiVersion) {
\r
115 this.apiVersion = apiVersion;
\r
119 public boolean isApiVersion(String prospective) {
\r
120 return apiVersion.equals(prospective);
\r
124 public String typeString(Class<?> cls) {
\r
125 return "application/"+cls.getSimpleName()+"+"+type.name().toLowerCase()+
\r
126 (apiVersion==null?BLANK:";version="+apiVersion);
\r
129 protected abstract EClient<CT> client() throws CadiException;
\r
132 public<T> Future<T> create(String pathinfo, String contentType, final RosettaDF<T> df, final T t) throws APIException, CadiException {
\r
133 final int idx = pathinfo.indexOf('?');
\r
136 qp=pathinfo.substring(idx+1);
\r
137 pathinfo=pathinfo.substring(0,idx);
\r
141 EClient<CT> client = client();
\r
142 client.setMethod(POST);
\r
143 client.addHeader(CONTENT_TYPE,contentType);
\r
144 client.setPathInfo(pathinfo);
\r
145 client.setQueryParams(qp);
\r
146 client.setFragment(fragment);
\r
147 client.setPayload(new EClient.Transfer() {
\r
149 public void transfer(OutputStream os) throws IOException, APIException {
\r
150 df.newData().out(type).direct(t,os);
\r
154 queryParams = fragment = null;
\r
155 return client.futureCreate(df.getTypeClass());
\r
158 public<T> Future<T> create(String pathinfo, final RosettaDF<T> df, final T t) throws APIException, CadiException {
\r
159 final int idx = pathinfo.indexOf('?');
\r
162 qp=pathinfo.substring(idx+1);
\r
163 pathinfo=pathinfo.substring(0,idx);
\r
167 EClient<CT> client = client();
\r
168 client.setMethod(POST);
\r
169 client.addHeader(CONTENT_TYPE,typeString(df.getTypeClass()));
\r
170 client.setPathInfo(pathinfo);
\r
171 client.setQueryParams(qp);
\r
172 client.setFragment(fragment);
\r
173 client.setPayload(new EClient.Transfer() {
\r
175 public void transfer(OutputStream os) throws IOException, APIException {
\r
176 df.newData().out(type).direct(t,os);
\r
180 queryParams = fragment = null;
\r
181 return client.futureCreate(df.getTypeClass());
\r
184 public<T> Future<T> create(String pathinfo, Class<?> cls, final RosettaDF<T> df, final T t) throws APIException, CadiException {
\r
185 final int idx = pathinfo.indexOf('?');
\r
188 qp=pathinfo.substring(idx+1);
\r
189 pathinfo=pathinfo.substring(0,idx);
\r
194 EClient<CT> client = client();
\r
195 client.setMethod(POST);
\r
196 client.addHeader(CONTENT_TYPE,typeString(cls));
\r
197 client.setPathInfo(pathinfo);
\r
198 client.setQueryParams(qp);
\r
199 client.setFragment(fragment);
\r
200 client.setPayload(new EClient.Transfer() {
\r
202 public void transfer(OutputStream os) throws IOException, APIException {
\r
203 df.newData().out(type).direct(t,os);
\r
207 queryParams = fragment = null;
\r
208 return client.futureCreate(df.getTypeClass());
\r
211 public<T> Future<T> create(String pathinfo, Class<T> cls) throws APIException, CadiException {
\r
212 final int idx = pathinfo.indexOf('?');
\r
215 qp=pathinfo.substring(idx+1);
\r
216 pathinfo=pathinfo.substring(0,idx);
\r
221 EClient<CT> client = client();
\r
222 client.setMethod(POST);
\r
223 client.addHeader(CONTENT_TYPE,typeString(cls));
\r
224 client.setPathInfo(pathinfo);
\r
225 client.setQueryParams(qp);
\r
226 client.setFragment(fragment);
\r
227 client.setPayload(null);
\r
229 queryParams = fragment = null;
\r
230 return client.futureCreate(cls);
\r
233 public Future<Void> create(String pathinfo, String contentType) throws APIException, CadiException {
\r
234 final int idx = pathinfo.indexOf('?');
\r
237 qp=pathinfo.substring(idx+1);
\r
238 pathinfo=pathinfo.substring(0,idx);
\r
243 EClient<CT> client = client();
\r
244 client.setMethod(POST);
\r
245 client.addHeader(CONTENT_TYPE,contentType);
\r
246 client.setPathInfo(pathinfo);
\r
247 client.setQueryParams(qp);
\r
248 client.setFragment(fragment);
\r
249 client.setPayload(null);
\r
251 queryParams = fragment = null;
\r
252 return client.futureCreate(Void.class);
\r
256 public Future<String> read(String pathinfo, String accept, String ... headers) throws APIException, CadiException {
\r
257 final int idx = pathinfo.indexOf('?');
\r
260 qp=pathinfo.substring(idx+1);
\r
261 pathinfo=pathinfo.substring(0,idx);
\r
266 EClient<CT> client = client();
\r
267 client.setMethod(GET);
\r
268 client.addHeader(ACCEPT, accept);
\r
270 for(int i=1;i<headers.length;i=i+2) {
\r
271 client.addHeader(headers[i-1],headers[i]);
\r
273 client.setQueryParams(qp);
\r
274 client.setFragment(fragment);
\r
276 client.setPathInfo(pathinfo);
\r
278 client.setPayload(null);
\r
280 queryParams = fragment = null;
\r
281 return client.futureReadString();
\r
284 public<T> Future<T> read(String pathinfo, String accept, RosettaDF<T> df, String ... headers) throws APIException, CadiException {
\r
285 final int idx = pathinfo.indexOf('?');
\r
288 qp=pathinfo.substring(idx+1);
\r
289 pathinfo=pathinfo.substring(0,idx);
\r
294 EClient<CT> client = client();
\r
295 client.setMethod(GET);
\r
296 client.addHeader(ACCEPT, accept);
\r
297 for(int i=1;i<headers.length;i=i+2) {
\r
298 client.addHeader(headers[i-1],headers[i]);
\r
300 client.setQueryParams(qp);
\r
301 client.setFragment(fragment);
\r
302 client.setPathInfo(pathinfo);
\r
304 client.setPayload(null);
\r
306 queryParams = fragment = null;
\r
307 return client.futureRead(df,type);
\r
310 public<T> Future<T> read(String pathinfo, RosettaDF<T> df,String ... headers) throws APIException, CadiException {
\r
311 final int idx = pathinfo.indexOf('?');
\r
314 qp=pathinfo.substring(idx+1);
\r
315 pathinfo=pathinfo.substring(0,idx);
\r
320 EClient<CT> client = client();
\r
321 client.setMethod(GET);
\r
322 client.addHeader(ACCEPT, typeString(df.getTypeClass()));
\r
323 for(int i=1;i<headers.length;i=i+2) {
\r
324 client.addHeader(headers[i-1],headers[i]);
\r
326 client.setQueryParams(qp);
\r
327 client.setFragment(fragment);
\r
328 client.setPathInfo(pathinfo);
\r
330 client.setPayload(null);
\r
332 queryParams = fragment = null;
\r
333 return client.futureRead(df,type);
\r
336 public<T> Future<T> read(String pathinfo, Class<?> cls, RosettaDF<T> df) throws APIException, CadiException {
\r
337 final int idx = pathinfo.indexOf('?');
\r
340 qp=pathinfo.substring(idx+1);
\r
341 pathinfo=pathinfo.substring(0,idx);
\r
346 EClient<CT> client = client();
\r
347 client.setMethod(GET);
\r
348 client.addHeader(ACCEPT, typeString(cls));
\r
349 client.setQueryParams(qp);
\r
350 client.setFragment(fragment);
\r
351 client.setPathInfo(pathinfo);
\r
353 client.setPayload(null);
\r
355 queryParams = fragment = null;
\r
356 return client.futureRead(df,type);
\r
359 public<T> Future<T> update(String pathinfo, String contentType, final RosettaDF<T> df, final T t) throws APIException, CadiException {
\r
360 final int idx = pathinfo.indexOf('?');
\r
363 qp=pathinfo.substring(idx+1);
\r
364 pathinfo=pathinfo.substring(0,idx);
\r
369 EClient<CT> client = client();
\r
370 client.setMethod(PUT);
\r
371 client.addHeader(CONTENT_TYPE,contentType);
\r
372 client.setQueryParams(qp);
\r
373 client.setFragment(fragment);
\r
374 client.setPathInfo(pathinfo);
\r
375 client.setPayload(new EClient.Transfer() {
\r
377 public void transfer(OutputStream os) throws IOException, APIException {
\r
378 df.newData().out(type).direct(t,os);
\r
382 queryParams = fragment = null;
\r
383 return client.future(t);
\r
386 public<T> Future<String> updateRespondString(String pathinfo, final RosettaDF<T> df, final T t) throws APIException, CadiException {
\r
387 final int idx = pathinfo.indexOf('?');
\r
390 qp=pathinfo.substring(idx+1);
\r
391 pathinfo=pathinfo.substring(0,idx);
\r
396 EClient<CT> client = client();
\r
397 client.setMethod(PUT);
\r
398 client.addHeader(CONTENT_TYPE, typeString(df.getTypeClass()));
\r
399 client.setQueryParams(qp);
\r
400 client.setFragment(fragment);
\r
401 client.setPathInfo(pathinfo);
\r
402 client.setPayload(new EClient.Transfer() {
\r
404 public void transfer(OutputStream os) throws IOException, APIException {
\r
405 df.newData().out(type).direct(t,os);
\r
409 queryParams = fragment = null;
\r
410 return client.futureReadString();
\r
414 public<T> Future<T> update(String pathinfo, final RosettaDF<T> df, final T t) throws APIException, CadiException {
\r
415 final int idx = pathinfo.indexOf('?');
\r
418 qp=pathinfo.substring(idx+1);
\r
419 pathinfo=pathinfo.substring(0,idx);
\r
424 EClient<CT> client = client();
\r
425 client.setMethod(PUT);
\r
426 client.addHeader(CONTENT_TYPE, typeString(df.getTypeClass()));
\r
427 client.setQueryParams(qp);
\r
428 client.setFragment(fragment);
\r
429 client.setPathInfo(pathinfo);
\r
430 client.setPayload(new EClient.Transfer() {
\r
432 public void transfer(OutputStream os) throws IOException, APIException {
\r
433 df.newData().out(type).direct(t,os);
\r
437 queryParams = fragment = null;
\r
438 return client.future(t);
\r
441 public<T> Future<T> update(String pathinfo, Class<?> cls, final RosettaDF<T> df, final T t) throws APIException, CadiException {
\r
442 final int idx = pathinfo.indexOf('?');
\r
445 qp=pathinfo.substring(idx+1);
\r
446 pathinfo=pathinfo.substring(0,idx);
\r
451 EClient<CT> client = client();
\r
452 client.setMethod(PUT);
\r
453 client.addHeader(CONTENT_TYPE, typeString(cls));
\r
454 client.setQueryParams(qp);
\r
455 client.setFragment(fragment);
\r
456 client.setPathInfo(pathinfo);
\r
457 client.setPayload(new EClient.Transfer() {
\r
459 public void transfer(OutputStream os) throws IOException, APIException {
\r
460 df.newData().out(type).direct(t,os);
\r
464 queryParams = fragment = null;
\r
465 return client.future(t);
\r
469 * A method to update with a VOID
\r
474 * @throws APIException
\r
475 * @throws CadiException
\r
477 public<T> Future<Void> update(String pathinfo) throws APIException, CadiException {
\r
478 final int idx = pathinfo.indexOf('?');
\r
481 qp=pathinfo.substring(idx+1);
\r
482 pathinfo=pathinfo.substring(0,idx);
\r
487 EClient<CT> client = client();
\r
488 client.setMethod(PUT);
\r
489 client.addHeader(CONTENT_TYPE, typeString(Void.class));
\r
490 client.setQueryParams(qp);
\r
491 client.setFragment(fragment);
\r
492 client.setPathInfo(pathinfo);
\r
493 // client.setPayload(new EClient.Transfer() {
\r
495 // public void transfer(OutputStream os) throws IOException, APIException {
\r
499 queryParams = fragment = null;
\r
500 return client.future(null);
\r
503 public<T> Future<T> delete(String pathinfo, String contentType, final RosettaDF<T> df, final T t) throws APIException, CadiException {
\r
504 final int idx = pathinfo.indexOf('?');
\r
507 qp=pathinfo.substring(idx+1);
\r
508 pathinfo=pathinfo.substring(0,idx);
\r
513 EClient<CT> client = client();
\r
514 client.setMethod(DELETE);
\r
515 client.addHeader(CONTENT_TYPE, contentType);
\r
516 client.setQueryParams(qp);
\r
517 client.setFragment(fragment);
\r
518 client.setPathInfo(pathinfo);
\r
519 client.setPayload(new EClient.Transfer() {
\r
521 public void transfer(OutputStream os) throws IOException, APIException {
\r
522 df.newData().out(type).direct(t,os);
\r
526 queryParams = fragment = null;
\r
527 return client.future(t);
\r
530 public<T> Future<T> delete(String pathinfo, Class<?> cls, final RosettaDF<T> df, final T t) throws APIException, CadiException {
\r
531 final int idx = pathinfo.indexOf('?');
\r
534 qp=pathinfo.substring(idx+1);
\r
535 pathinfo=pathinfo.substring(0,idx);
\r
540 EClient<CT> client = client();
\r
541 client.setMethod(DELETE);
\r
542 client.addHeader(CONTENT_TYPE, typeString(cls));
\r
543 client.setQueryParams(qp);
\r
544 client.setFragment(fragment);
\r
545 client.setPathInfo(pathinfo);
\r
546 client.setPayload(new EClient.Transfer() {
\r
548 public void transfer(OutputStream os) throws IOException, APIException {
\r
549 df.newData().out(type).direct(t,os);
\r
553 queryParams = fragment = null;
\r
554 return client.future(t);
\r
557 public<T> Future<T> delete(String pathinfo, final RosettaDF<T> df, final T t) throws APIException, CadiException {
\r
558 final int idx = pathinfo.indexOf('?');
\r
561 qp=pathinfo.substring(idx+1);
\r
562 pathinfo=pathinfo.substring(0,idx);
\r
567 EClient<CT> client = client();
\r
568 client.setMethod(DELETE);
\r
569 client.addHeader(CONTENT_TYPE, typeString(df.getTypeClass()));
\r
570 client.setQueryParams(qp);
\r
571 client.setFragment(fragment);
\r
572 client.setPathInfo(pathinfo);
\r
573 client.setPayload(new EClient.Transfer() {
\r
575 public void transfer(OutputStream os) throws IOException, APIException {
\r
576 df.newData().out(type).direct(t,os);
\r
581 queryParams = fragment = null;
\r
582 return client.future(t);
\r
586 public<T> Future<T> delete(String pathinfo, Class<T> cls) throws APIException, CadiException {
\r
587 final int idx = pathinfo.indexOf('?');
\r
590 qp=pathinfo.substring(idx+1);
\r
591 pathinfo=pathinfo.substring(0,idx);
\r
596 EClient<CT> client = client();
\r
597 client.setMethod(DELETE);
\r
598 client.addHeader(CONTENT_TYPE, typeString(cls));
\r
599 client.setQueryParams(qp);
\r
600 client.setFragment(fragment);
\r
601 client.setPathInfo(pathinfo);
\r
602 client.setPayload(null);
\r
604 queryParams = fragment = null;
\r
605 return client.future((T)null);
\r
608 public Future<Void> delete(String pathinfo, String contentType) throws APIException, CadiException {
\r
609 final int idx = pathinfo.indexOf('?');
\r
612 qp=pathinfo.substring(idx+1);
\r
613 pathinfo=pathinfo.substring(0,idx);
\r
618 EClient<CT> client = client();
\r
619 client.setMethod(DELETE);
\r
620 client.addHeader(CONTENT_TYPE, contentType);
\r
621 client.setQueryParams(qp);
\r
622 client.setFragment(fragment);
\r
623 client.setPathInfo(pathinfo);
\r
624 client.setPayload(null);
\r
626 queryParams = fragment = null;
\r
627 return client.future(null);
\r
630 public Future<Void> transfer(final HttpServletRequest req, final HttpServletResponse resp, final String pathParam, final int expected) throws CadiException, APIException {
\r
631 EClient<CT> client = client();
\r
634 uri = new URI(req.getRequestURI());
\r
635 } catch (Exception e) {
\r
636 throw new CadiException("Invalid incoming URI",e);
\r
639 for(Enumeration<String> en = req.getHeaderNames();en.hasMoreElements();) {
\r
640 name = en.nextElement();
\r
641 client.addHeader(name,req.getHeader(name));
\r
643 client.setQueryParams(req.getQueryString());
\r
644 client.setFragment(uri.getFragment());
\r
645 client.setPathInfo(pathParam);
\r
646 String meth = req.getMethod();
\r
647 client.setMethod(meth);
\r
648 if(!"GET".equals(meth)) {
\r
649 client.setPayload(new EClient.Transfer() {
\r
651 public void transfer(OutputStream os) throws IOException, APIException {
\r
652 final ServletInputStream is = req.getInputStream();
\r
655 Pooled<byte[]> pbuff = buffPool.get();
\r
657 while((read=is.read(pbuff.content))>=0) {
\r
658 os.write(pbuff.content,0,read);
\r
667 return client.future(resp, expected);
\r
670 public String toString() {
\r
671 return uri.toString();
\r
675 * @param queryParams the queryParams to set
\r
678 public Rcli<CT> setQueryParams(String queryParams) {
\r
679 this.queryParams = queryParams;
\r
685 * @param fragment the fragment to set
\r
688 public Rcli<CT> setFragment(String fragment) {
\r
689 this.fragment = fragment;
\r
693 public URI getURI() {
\r