/******************************************************************************* * ============LICENSE_START==================================================== * * org.onap.aaf * * =========================================================================== * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. * * =========================================================================== * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * * ============LICENSE_END==================================================== * * * * ECOMP is a trademark and service mark of AT&T Intellectual Property. * * ******************************************************************************/ package org.onap.aaf.cadi.client; import java.io.IOException; import java.io.OutputStream; import java.net.URI; import java.util.Enumeration; import javax.servlet.ServletInputStream; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.onap.aaf.cadi.CadiException; import org.onap.aaf.cadi.SecuritySetter; import org.onap.aaf.inno.env.APIException; import org.onap.aaf.inno.env.Data.TYPE; import org.onap.aaf.inno.env.util.Pool; import org.onap.aaf.inno.env.util.Pool.Pooled; import org.onap.aaf.rosetta.env.RosettaDF; public abstract class Rcli { public static final String BLANK = ""; public static final String CONTENT_TYPE = "Content-Type"; public static final String ACCEPT = "Accept"; protected static final String POST = "POST"; protected static final String GET = "GET"; protected static final String PUT = "PUT"; protected static final String DELETE = "DELETE"; protected TYPE type; protected String apiVersion; protected int readTimeout = 5000; protected int connectionTimeout = 3000; protected URI uri; private String queryParams, fragment; public static Pool buffPool = new Pool(new Pool.Creator() { @Override public byte[] create() throws APIException { return new byte[1024]; } @Override public void destroy(byte[] t) { } @Override public boolean isValid(byte[] t) { return true; } @Override public void reuse(byte[] t) { } }); public Rcli() { super(); } public abstract void setSecuritySetter(SecuritySetter ss); public abstract SecuritySetter getSecuritySetter(); public Rcli forUser(SecuritySetter ss) { Rcli rv = clone(uri==null?this.uri:uri,ss); setSecuritySetter(ss); rv.type = type; rv.apiVersion = apiVersion; return rv; } protected abstract Rcli clone(URI uri, SecuritySetter ss); public abstract void invalidate() throws CadiException; public Rcli readTimeout(int millis) { readTimeout = millis; return this; } public Rcli connectionTimeout(int millis) { connectionTimeout = millis; return this; } public Rcli type(TYPE type) { this.type=type; return this; } public Rcli apiVersion(String apiVersion) { this.apiVersion = apiVersion; return this; } public boolean isApiVersion(String prospective) { return apiVersion.equals(prospective); } public String typeString(Class cls) { return "application/"+cls.getSimpleName()+"+"+type.name().toLowerCase()+ (apiVersion==null?BLANK:";version="+apiVersion); } protected abstract EClient client() throws CadiException; public Future create(String pathinfo, String contentType, final RosettaDF df, final T t) throws APIException, CadiException { final int idx = pathinfo.indexOf('?'); final String qp; if(idx>=0) { qp=pathinfo.substring(idx+1); pathinfo=pathinfo.substring(0,idx); } else { qp=queryParams; } EClient client = client(); client.setMethod(POST); client.addHeader(CONTENT_TYPE,contentType); client.setPathInfo(pathinfo); client.setQueryParams(qp); client.setFragment(fragment); client.setPayload(new EClient.Transfer() { @Override public void transfer(OutputStream os) throws IOException, APIException { df.newData().out(type).direct(t,os); } }); client.send(); queryParams = fragment = null; return client.futureCreate(df.getTypeClass()); } public Future create(String pathinfo, final RosettaDF df, final T t) throws APIException, CadiException { final int idx = pathinfo.indexOf('?'); final String qp; if(idx>=0) { qp=pathinfo.substring(idx+1); pathinfo=pathinfo.substring(0,idx); } else { qp=queryParams; } EClient client = client(); client.setMethod(POST); client.addHeader(CONTENT_TYPE,typeString(df.getTypeClass())); client.setPathInfo(pathinfo); client.setQueryParams(qp); client.setFragment(fragment); client.setPayload(new EClient.Transfer() { @Override public void transfer(OutputStream os) throws IOException, APIException { df.newData().out(type).direct(t,os); } }); client.send(); queryParams = fragment = null; return client.futureCreate(df.getTypeClass()); } public Future create(String pathinfo, Class cls, final RosettaDF df, final T t) throws APIException, CadiException { final int idx = pathinfo.indexOf('?'); final String qp; if(idx>=0) { qp=pathinfo.substring(idx+1); pathinfo=pathinfo.substring(0,idx); } else { qp=queryParams; } EClient client = client(); client.setMethod(POST); client.addHeader(CONTENT_TYPE,typeString(cls)); client.setPathInfo(pathinfo); client.setQueryParams(qp); client.setFragment(fragment); client.setPayload(new EClient.Transfer() { @Override public void transfer(OutputStream os) throws IOException, APIException { df.newData().out(type).direct(t,os); } }); client.send(); queryParams = fragment = null; return client.futureCreate(df.getTypeClass()); } public Future create(String pathinfo, Class cls) throws APIException, CadiException { final int idx = pathinfo.indexOf('?'); final String qp; if(idx>=0) { qp=pathinfo.substring(idx+1); pathinfo=pathinfo.substring(0,idx); } else { qp=queryParams; } EClient client = client(); client.setMethod(POST); client.addHeader(CONTENT_TYPE,typeString(cls)); client.setPathInfo(pathinfo); client.setQueryParams(qp); client.setFragment(fragment); client.setPayload(null); client.send(); queryParams = fragment = null; return client.futureCreate(cls); } public Future create(String pathinfo, String contentType) throws APIException, CadiException { final int idx = pathinfo.indexOf('?'); final String qp; if(idx>=0) { qp=pathinfo.substring(idx+1); pathinfo=pathinfo.substring(0,idx); } else { qp=queryParams; } EClient client = client(); client.setMethod(POST); client.addHeader(CONTENT_TYPE,contentType); client.setPathInfo(pathinfo); client.setQueryParams(qp); client.setFragment(fragment); client.setPayload(null); client.send(); queryParams = fragment = null; return client.futureCreate(Void.class); } public Future read(String pathinfo, String accept, String ... headers) throws APIException, CadiException { final int idx = pathinfo.indexOf('?'); final String qp; if(idx>=0) { qp=pathinfo.substring(idx+1); pathinfo=pathinfo.substring(0,idx); } else { qp=queryParams; } EClient client = client(); client.setMethod(GET); client.addHeader(ACCEPT, accept); for(int i=1;i Future read(String pathinfo, String accept, RosettaDF df, String ... headers) throws APIException, CadiException { final int idx = pathinfo.indexOf('?'); final String qp; if(idx>=0) { qp=pathinfo.substring(idx+1); pathinfo=pathinfo.substring(0,idx); } else { qp=queryParams; } EClient client = client(); client.setMethod(GET); client.addHeader(ACCEPT, accept); for(int i=1;i Future read(String pathinfo, RosettaDF df,String ... headers) throws APIException, CadiException { final int idx = pathinfo.indexOf('?'); final String qp; if(idx>=0) { qp=pathinfo.substring(idx+1); pathinfo=pathinfo.substring(0,idx); } else { qp=queryParams; } EClient client = client(); client.setMethod(GET); client.addHeader(ACCEPT, typeString(df.getTypeClass())); for(int i=1;i Future read(String pathinfo, Class cls, RosettaDF df) throws APIException, CadiException { final int idx = pathinfo.indexOf('?'); final String qp; if(idx>=0) { qp=pathinfo.substring(idx+1); pathinfo=pathinfo.substring(0,idx); } else { qp=queryParams; } EClient client = client(); client.setMethod(GET); client.addHeader(ACCEPT, typeString(cls)); client.setQueryParams(qp); client.setFragment(fragment); client.setPathInfo(pathinfo); client.setPayload(null); client.send(); queryParams = fragment = null; return client.futureRead(df,type); } public Future update(String pathinfo, String contentType, final RosettaDF df, final T t) throws APIException, CadiException { final int idx = pathinfo.indexOf('?'); final String qp; if(idx>=0) { qp=pathinfo.substring(idx+1); pathinfo=pathinfo.substring(0,idx); } else { qp=queryParams; } EClient client = client(); client.setMethod(PUT); client.addHeader(CONTENT_TYPE,contentType); client.setQueryParams(qp); client.setFragment(fragment); client.setPathInfo(pathinfo); client.setPayload(new EClient.Transfer() { @Override public void transfer(OutputStream os) throws IOException, APIException { df.newData().out(type).direct(t,os); } }); client.send(); queryParams = fragment = null; return client.future(t); } public Future updateRespondString(String pathinfo, final RosettaDF df, final T t) throws APIException, CadiException { final int idx = pathinfo.indexOf('?'); final String qp; if(idx>=0) { qp=pathinfo.substring(idx+1); pathinfo=pathinfo.substring(0,idx); } else { qp=queryParams; } EClient client = client(); client.setMethod(PUT); client.addHeader(CONTENT_TYPE, typeString(df.getTypeClass())); client.setQueryParams(qp); client.setFragment(fragment); client.setPathInfo(pathinfo); client.setPayload(new EClient.Transfer() { @Override public void transfer(OutputStream os) throws IOException, APIException { df.newData().out(type).direct(t,os); } }); client.send(); queryParams = fragment = null; return client.futureReadString(); } public Future update(String pathinfo, final RosettaDF df, final T t) throws APIException, CadiException { final int idx = pathinfo.indexOf('?'); final String qp; if(idx>=0) { qp=pathinfo.substring(idx+1); pathinfo=pathinfo.substring(0,idx); } else { qp=queryParams; } EClient client = client(); client.setMethod(PUT); client.addHeader(CONTENT_TYPE, typeString(df.getTypeClass())); client.setQueryParams(qp); client.setFragment(fragment); client.setPathInfo(pathinfo); client.setPayload(new EClient.Transfer() { @Override public void transfer(OutputStream os) throws IOException, APIException { df.newData().out(type).direct(t,os); } }); client.send(); queryParams = fragment = null; return client.future(t); } public Future update(String pathinfo, Class cls, final RosettaDF df, final T t) throws APIException, CadiException { final int idx = pathinfo.indexOf('?'); final String qp; if(idx>=0) { qp=pathinfo.substring(idx+1); pathinfo=pathinfo.substring(0,idx); } else { qp=queryParams; } EClient client = client(); client.setMethod(PUT); client.addHeader(CONTENT_TYPE, typeString(cls)); client.setQueryParams(qp); client.setFragment(fragment); client.setPathInfo(pathinfo); client.setPayload(new EClient.Transfer() { @Override public void transfer(OutputStream os) throws IOException, APIException { df.newData().out(type).direct(t,os); } }); client.send(); queryParams = fragment = null; return client.future(t); } /** * A method to update with a VOID * @param pathinfo * @param resp * @param expected * @return * @throws APIException * @throws CadiException */ public Future update(String pathinfo) throws APIException, CadiException { final int idx = pathinfo.indexOf('?'); final String qp; if(idx>=0) { qp=pathinfo.substring(idx+1); pathinfo=pathinfo.substring(0,idx); } else { qp=queryParams; } EClient client = client(); client.setMethod(PUT); client.addHeader(CONTENT_TYPE, typeString(Void.class)); client.setQueryParams(qp); client.setFragment(fragment); client.setPathInfo(pathinfo); // client.setPayload(new EClient.Transfer() { // @Override // public void transfer(OutputStream os) throws IOException, APIException { // } // }); client.send(); queryParams = fragment = null; return client.future(null); } public Future delete(String pathinfo, String contentType, final RosettaDF df, final T t) throws APIException, CadiException { final int idx = pathinfo.indexOf('?'); final String qp; if(idx>=0) { qp=pathinfo.substring(idx+1); pathinfo=pathinfo.substring(0,idx); } else { qp=queryParams; } EClient client = client(); client.setMethod(DELETE); client.addHeader(CONTENT_TYPE, contentType); client.setQueryParams(qp); client.setFragment(fragment); client.setPathInfo(pathinfo); client.setPayload(new EClient.Transfer() { @Override public void transfer(OutputStream os) throws IOException, APIException { df.newData().out(type).direct(t,os); } }); client.send(); queryParams = fragment = null; return client.future(t); } public Future delete(String pathinfo, Class cls, final RosettaDF df, final T t) throws APIException, CadiException { final int idx = pathinfo.indexOf('?'); final String qp; if(idx>=0) { qp=pathinfo.substring(idx+1); pathinfo=pathinfo.substring(0,idx); } else { qp=queryParams; } EClient client = client(); client.setMethod(DELETE); client.addHeader(CONTENT_TYPE, typeString(cls)); client.setQueryParams(qp); client.setFragment(fragment); client.setPathInfo(pathinfo); client.setPayload(new EClient.Transfer() { @Override public void transfer(OutputStream os) throws IOException, APIException { df.newData().out(type).direct(t,os); } }); client.send(); queryParams = fragment = null; return client.future(t); } public Future delete(String pathinfo, final RosettaDF df, final T t) throws APIException, CadiException { final int idx = pathinfo.indexOf('?'); final String qp; if(idx>=0) { qp=pathinfo.substring(idx+1); pathinfo=pathinfo.substring(0,idx); } else { qp=queryParams; } EClient client = client(); client.setMethod(DELETE); client.addHeader(CONTENT_TYPE, typeString(df.getTypeClass())); client.setQueryParams(qp); client.setFragment(fragment); client.setPathInfo(pathinfo); client.setPayload(new EClient.Transfer() { @Override public void transfer(OutputStream os) throws IOException, APIException { df.newData().out(type).direct(t,os); } }); client.send(); queryParams = fragment = null; return client.future(t); } public Future delete(String pathinfo, Class cls) throws APIException, CadiException { final int idx = pathinfo.indexOf('?'); final String qp; if(idx>=0) { qp=pathinfo.substring(idx+1); pathinfo=pathinfo.substring(0,idx); } else { qp=queryParams; } EClient client = client(); client.setMethod(DELETE); client.addHeader(CONTENT_TYPE, typeString(cls)); client.setQueryParams(qp); client.setFragment(fragment); client.setPathInfo(pathinfo); client.setPayload(null); client.send(); queryParams = fragment = null; return client.future((T)null); } public Future delete(String pathinfo, String contentType) throws APIException, CadiException { final int idx = pathinfo.indexOf('?'); final String qp; if(idx>=0) { qp=pathinfo.substring(idx+1); pathinfo=pathinfo.substring(0,idx); } else { qp=queryParams; } EClient client = client(); client.setMethod(DELETE); client.addHeader(CONTENT_TYPE, contentType); client.setQueryParams(qp); client.setFragment(fragment); client.setPathInfo(pathinfo); client.setPayload(null); client.send(); queryParams = fragment = null; return client.future(null); } public Future transfer(final HttpServletRequest req, final HttpServletResponse resp, final String pathParam, final int expected) throws CadiException, APIException { EClient client = client(); URI uri; try { uri = new URI(req.getRequestURI()); } catch (Exception e) { throw new CadiException("Invalid incoming URI",e); } String name; for(Enumeration en = req.getHeaderNames();en.hasMoreElements();) { name = en.nextElement(); client.addHeader(name,req.getHeader(name)); } client.setQueryParams(req.getQueryString()); client.setFragment(uri.getFragment()); client.setPathInfo(pathParam); String meth = req.getMethod(); client.setMethod(meth); if(!"GET".equals(meth)) { client.setPayload(new EClient.Transfer() { @Override public void transfer(OutputStream os) throws IOException, APIException { final ServletInputStream is = req.getInputStream(); int read; // reuse Buffers Pooled pbuff = buffPool.get(); try { while((read=is.read(pbuff.content))>=0) { os.write(pbuff.content,0,read); } } finally { pbuff.done(); } } }); } client.send(); return client.future(resp, expected); } public String toString() { return uri.toString(); } /** * @param queryParams the queryParams to set * @return */ public Rcli setQueryParams(String queryParams) { this.queryParams = queryParams; return this; } /** * @param fragment the fragment to set * @return */ public Rcli setFragment(String fragment) { this.fragment = fragment; return this; } public URI getURI() { return uri; } }