ExternalResourceUtils.java
/*
* GovWay - A customizable API Gateway
* https://govway.org
*
* Copyright (c) 2005-2024 Link.it srl (https://link.it).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 3, as published by
* the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
package org.openspcoop2.utils.transport.http;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.naming.directory.Attribute;
import javax.naming.directory.Attributes;
import org.apache.commons.lang.StringUtils;
import org.openspcoop2.utils.Utilities;
import org.openspcoop2.utils.UtilsException;
import org.openspcoop2.utils.io.Base64Utilities;
import org.openspcoop2.utils.resources.FileSystemUtilities;
import org.openspcoop2.utils.transport.TransportUtils;
import org.openspcoop2.utils.transport.ldap.LdapClientFactory;
import org.openspcoop2.utils.transport.ldap.LdapClientInterface;
import org.openspcoop2.utils.transport.ldap.LdapEngineType;
import org.openspcoop2.utils.transport.ldap.LdapQuery;
import org.openspcoop2.utils.transport.ldap.LdapUtility;
/**
* ExternalResourceUtils
*
* @author Andrea Poli (apoli@link.it)
* @author $Author$
* @version $Rev$, $Date$
*/
public class ExternalResourceUtils {
private ExternalResourceUtils() {}
public static byte[] readResource(String resource, ExternalResourceConfig externalConfig) throws UtilsException {
return readResourceReturnHttpResponse(resource, externalConfig).getContent();
}
public static HttpResponse readResourceReturnHttpResponse(String resource, ExternalResourceConfig externalConfig) throws UtilsException {
HttpResponse res = null;
try {
if(!TransportUtils.isRemoteResource(resource.trim())) {
try {
File f = new File(resource);
if(f.exists()) {
byte[] content = FileSystemUtilities.readBytesFromFile(f);
HttpResponse response = new HttpResponse();
response.setResultHTTPOperation(200);
response.setContent(content);
return response;
}
}catch(Exception t) {
// ignore
}
throw new UtilsException("Unsupported protocol");
}
if(TransportUtils.isLdapResource(resource)) {
return readLdapResource(resource, externalConfig);
}
HttpRequest req = new HttpRequest();
req.setMethod(HttpRequestMethod.GET);
if(externalConfig.getHeaders()!=null && !externalConfig.getHeaders().isEmpty()) {
for (Map.Entry<String,String> entry : externalConfig.getHeaders().entrySet()) {
if(entry.getKey()!=null && entry.getValue()!=null) {
req.addHeader(entry.getKey(),entry.getValue());
}
}
}
resource = resource.trim();
if(externalConfig.getQueryParameters()!=null && !externalConfig.getQueryParameters().isEmpty()) {
resource = TransportUtils.buildUrlWithParameters(TransportUtils.convertToMapListValues(externalConfig.getQueryParameters()), resource);
}
if(externalConfig.getForwardProxyUrl()!=null && StringUtils.isNotEmpty(externalConfig.getForwardProxyUrl())) {
String forwardProxyUrl = externalConfig.getForwardProxyUrl();
String remoteLocation = externalConfig.isForwardProxyBase64() ? Base64Utilities.encodeAsString(resource.getBytes()) : resource;
if(externalConfig.getForwardProxyHeader()!=null && StringUtils.isNotEmpty(externalConfig.getForwardProxyHeader())) {
req.addHeader(externalConfig.getForwardProxyHeader(), remoteLocation);
}
else if(externalConfig.getForwardProxyQueryParameter()!=null && StringUtils.isNotEmpty(externalConfig.getForwardProxyQueryParameter())) {
Map<String, List<String>> queryParameters = new HashMap<>();
TransportUtils.addParameter(queryParameters,externalConfig.getForwardProxyQueryParameter(), remoteLocation);
forwardProxyUrl = TransportUtils.buildUrlWithParameters(queryParameters, forwardProxyUrl, false, null);
}
else {
throw new UtilsException("Forward Proxy configuration error: header and query parameter not found");
}
req.setUrl(forwardProxyUrl);
}
else {
req.setUrl(resource);
}
if(req.getUrl().startsWith("https")) {
req.setHostnameVerifier(externalConfig.isHostnameVerifier());
req.setTrustAllCerts(externalConfig.isTrustAllCerts());
if(externalConfig.getTrustStore()!=null) {
req.setTrustStore(externalConfig.getTrustStore());
}
if(externalConfig.getKeyStore()!=null) {
req.setKeyStore(externalConfig.getKeyStore());
req.setKeyAlias(externalConfig.getKeyAlias());
req.setKeyPassword(externalConfig.getKeyPassword());
}
}
req.setConnectTimeout(externalConfig.getConnectTimeout());
req.setReadTimeout(externalConfig.getReadTimeout());
req.setUsername(externalConfig.getBasicUsername());
req.setPassword(externalConfig.getBasicPassword());
res = HttpUtilities.httpInvoke(req);
}catch(Exception t) {
throw new UtilsException("Retrieve external resource '"+resource+"' failed: "+t.getMessage(),t);
}
validateResponse(res, resource, externalConfig);
return res;
}
private static HttpResponse readLdapResource(String resource, ExternalResourceConfig externalConfig) throws UtilsException {
try {
LdapClientInterface clientLdap = LdapClientFactory.getClient(LdapEngineType.SPRING_FRAMEWORK);
clientLdap.uri(LdapUtility.getBaseUrlFromURI(resource));
if(externalConfig.getBasicUsername()!=null && externalConfig.getBasicPassword()!=null) {
clientLdap.username(externalConfig.getBasicUsername());
clientLdap.password(externalConfig.getBasicPassword());
}
LdapQuery parsedQuery = LdapUtility.getQueryFromURI(resource);
if(parsedQuery==null) {
throw new UtilsException("parse failed");
}
String parsedAttribute = null;
if(parsedQuery.getAttributes()!=null && !parsedQuery.getAttributes().isEmpty()) {
parsedAttribute = parsedQuery.getAttributes().get(0);
}
if(parsedAttribute==null) {
throw new UtilsException("parse attribute failed");
}
List<Attributes> list = clientLdap.search(parsedQuery);
if(list == null || list.isEmpty()) {
throw new UtilsException("results not found");
}
if(list.size()>1) {
throw new UtilsException("more than one result found ("+list.size()+")");
}
Attributes attrs = list.get(0);
if(attrs==null || attrs.size()<=0) {
throw new UtilsException("attributes empty");
}
Attribute a = attrs.get(parsedAttribute);
if(a==null) {
throw new UtilsException("attribute '"+parsedAttribute+"' not found");
}
Object o = a.get();
if(o==null) {
throw new UtilsException("attribute '"+parsedAttribute+"' null");
}
byte [] content = null;
if(o instanceof byte[]) {
content = (byte[]) o;
}
else if(o instanceof String) {
content = ((String) o).getBytes();
}
else {
throw new UtilsException("attribute '"+parsedAttribute+"' with unknown type: "+o.getClass().getName());
}
HttpResponse response = new HttpResponse();
response.setResultHTTPOperation(200);
response.setContent(content);
return response;
}catch(Exception t) {
throw new UtilsException("Retrieve external resource '"+resource+"' failed: "+t.getMessage(),t);
}
}
private static void validateResponse(HttpResponse res, String resource, ExternalResourceConfig externalConfig) throws UtilsException {
try {
List<Integer> returnCodeValid = externalConfig.getReturnCode();
if(returnCodeValid==null) {
returnCodeValid = new ArrayList<>();
}
if(returnCodeValid.isEmpty()) {
returnCodeValid.add(200);
}
boolean isValid = false;
for (Integer rt : returnCodeValid) {
if(rt!=null && rt.intValue() == res.getResultHTTPOperation()) {
isValid = true;
break;
}
}
byte[] response = res.getContent();
if(isValid) {
if(response==null || response.length<=0) {
throw new UtilsException("Empty response (http code: "+res.getResultHTTPOperation()+")");
}
}
else {
String error = null;
if(response.length<=(2048)) {
error = Utilities.convertToPrintableText(response, 2048);
if(error!=null && error.contains("Visualizzazione non riuscita")) {
error = null;
}
}
if(error==null) {
error="";
}
else {
error = ": "+error;
}
throw new UtilsException("(http code: "+res.getResultHTTPOperation()+")"+error);
}
}catch(Exception t) {
throw new UtilsException("Retrieve external resource '"+resource+"' failed: "+t.getMessage(),t);
}
}
}