328 lines
9.8 KiB
Java
328 lines
9.8 KiB
Java
/**
|
|
*
|
|
*/
|
|
package org.gcube.portlets.user.urlshortener;
|
|
|
|
/**
|
|
* @author Francesco Mangiacrapa francesco.mangiacrapa@isti.cnr.it
|
|
* @Jun 28, 2013
|
|
*
|
|
*/
|
|
import static org.gcube.resources.discovery.icclient.ICFactory.clientFor;
|
|
import static org.gcube.resources.discovery.icclient.ICFactory.queryFor;
|
|
|
|
import java.io.BufferedReader;
|
|
import java.io.IOException;
|
|
import java.io.InputStreamReader;
|
|
import java.io.OutputStreamWriter;
|
|
import java.net.HttpURLConnection;
|
|
import java.net.MalformedURLException;
|
|
import java.net.URL;
|
|
import java.util.List;
|
|
import java.util.Map;
|
|
|
|
import org.gcube.common.encryption.encrypter.StringEncrypter;
|
|
import org.gcube.common.resources.gcore.ServiceEndpoint;
|
|
import org.gcube.common.resources.gcore.ServiceEndpoint.AccessPoint;
|
|
import org.gcube.common.resources.gcore.ServiceEndpoint.Property;
|
|
import org.gcube.common.scope.api.ScopeProvider;
|
|
import org.gcube.resources.discovery.client.api.DiscoveryClient;
|
|
import org.gcube.resources.discovery.client.queries.impl.XQuery;
|
|
import org.json.JSONObject;
|
|
import org.json.JSONTokener;
|
|
import org.slf4j.Logger;
|
|
import org.slf4j.LoggerFactory;
|
|
|
|
|
|
/**
|
|
* The Class UrlShortener.
|
|
*
|
|
* @author Francesco Mangiacrapa at ISTI-CNR (francesco.mangiacrapa@isti.cnr.it)
|
|
*
|
|
* May 31, 2019
|
|
*/
|
|
public final class UrlShortener {
|
|
|
|
|
|
protected static final String APPLICATION_JSON = "application/json";
|
|
protected static final String LONG_DYNAMIC_LINK = "longDynamicLink";
|
|
protected static final String SHORTENER = "HTTP-URL-Shortener-DL";
|
|
protected static final String KEY = "key";
|
|
protected static final String DYNAMIC_LINK = "dynamic-link";
|
|
protected static final String SUFFIX = "suffix";
|
|
private static String shortnerServiceUrl = null;
|
|
private static String decryptedKEY = null;
|
|
private static String suffixOption = null;
|
|
private static String dynamicLink = null;
|
|
|
|
protected static Logger logger = LoggerFactory.getLogger(UrlShortener.class);
|
|
private String uriRequest;
|
|
private boolean isAvailable = false;
|
|
|
|
|
|
/**
|
|
* Instantiates a new url shortener.
|
|
* It uses the scope from {@link ScopeProvider#instance} to read the Runtime Resource {@link UrlShortener#SHORTENER}}
|
|
* @throws Exception the exception
|
|
*/
|
|
public UrlShortener() throws Exception{
|
|
this(ScopeProvider.instance.get());
|
|
}
|
|
|
|
|
|
/**
|
|
* Instantiates a new url shortener.
|
|
*
|
|
* @param scope the scope
|
|
* @throws Exception the exception
|
|
*/
|
|
private UrlShortener(String scope) throws Exception {
|
|
|
|
try{
|
|
logger.info("Trying to read the Runtime Resource with name {}, in the scope: {}",SHORTENER,scope);
|
|
|
|
if(scope==null || scope.isEmpty()){
|
|
String msg = "Scope is null or empty! You must set the scope into: "+ScopeProvider.instance.getClass();
|
|
throw new Exception(msg);
|
|
}
|
|
|
|
XQuery query = queryFor(ServiceEndpoint.class);
|
|
query.addCondition("$resource/Profile/Name/text() eq '"+SHORTENER+"'").setResult("$resource/Profile/AccessPoint");
|
|
DiscoveryClient<AccessPoint> client = clientFor(AccessPoint.class);
|
|
List<AccessPoint> endpoints = client.submit(query);
|
|
|
|
if (endpoints.size() == 0){
|
|
isAvailable = false;
|
|
logger.warn("Runtime Resource " +SHORTENER+ " not found");
|
|
throw new Exception("No Runtime Resource with name: "+SHORTENER+" is available in the scope: "+scope);
|
|
}
|
|
|
|
AccessPoint shortnerAP = endpoints.get(0);
|
|
|
|
if(shortnerAP!=null){
|
|
shortnerServiceUrl = shortnerAP.address();
|
|
//READING THE PROPERTIES
|
|
Map<String, Property> propertiesMap = shortnerAP.propertyMap();
|
|
if(propertiesMap==null || propertiesMap.size()==0) {
|
|
throw new Exception("You need to add the configurations as properties to "+SHORTENER);
|
|
}
|
|
|
|
//READING KEY
|
|
String encrKey = readPropertyValue(propertiesMap, KEY);
|
|
logger.debug("Read property with name {} and value {}", KEY, encrKey);
|
|
if(encrKey!=null) {
|
|
decryptedKEY = StringEncrypter.getEncrypter().decrypt(encrKey);
|
|
logger.debug("Decrypted {}: {}+++MASKED-KEY+++", KEY, decryptedKEY.substring(0, decryptedKEY.length()-10));
|
|
}
|
|
|
|
dynamicLink = readPropertyValue(propertiesMap, DYNAMIC_LINK);
|
|
logger.debug("Read property with name {} and value {}", DYNAMIC_LINK, dynamicLink);
|
|
suffixOption = readPropertyValue(propertiesMap, SUFFIX);
|
|
logger.debug("Read property with name {} and value {}", SUFFIX, suffixOption);
|
|
}
|
|
|
|
if(shortnerServiceUrl==null || decryptedKEY==null) {
|
|
String error = "The access point in the RR: "+SHORTENER+" for scope "+scope+" is not available correctly. Impossible to read the service URL or decrypt the password";
|
|
logger.warn(error);
|
|
throw new Exception(error);
|
|
}
|
|
|
|
logger.trace("The shortner service URL is: {}",shortnerServiceUrl);
|
|
String getParam = "";
|
|
|
|
//ACTIVE THIS AFTER RELEASE
|
|
if(decryptedKEY!=null && !decryptedKEY.isEmpty()){
|
|
getParam = "?"+KEY +"="+decryptedKEY;
|
|
//getParam = "?"+KEY +"=AIzaSyCRGq1oO76Xi-pQEMPbdGWIUGVwueVbE5Y";
|
|
}
|
|
|
|
uriRequest = shortnerServiceUrl+getParam;
|
|
logger.info("HTTP-URL-Shortener found in scope {}, uriRequest: {}... KEY MASKED",scope, uriRequest.substring(0,uriRequest.length()-10));
|
|
isAvailable = true;
|
|
|
|
}catch (Exception e) {
|
|
logger.error("An error occurred reading Runtime Resource for name: "+SHORTENER+", the scope is: "+scope, e);
|
|
isAvailable = false;
|
|
throw new Exception("No "+SHORTENER+" available!");
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* Read property value.
|
|
*
|
|
* @param propertiesMap the properties map
|
|
* @param key the key
|
|
* @return the string
|
|
* @throws Exception the exception
|
|
*/
|
|
public String readPropertyValue(Map<String, Property> propertiesMap, String key) throws Exception{
|
|
Property theProperty = propertiesMap.get(key)!=null?propertiesMap.get(key):null;
|
|
if(theProperty==null)
|
|
throw new Exception("You need to add the "+key+" Property in the "+SHORTENER);
|
|
|
|
return theProperty.value();
|
|
}
|
|
|
|
/**
|
|
* Shorten.
|
|
*
|
|
* @param longUrl the long url
|
|
* @return a shorten url
|
|
* @throws Exception the exception
|
|
*/
|
|
public String shorten(String longUrl) throws Exception{
|
|
|
|
if (longUrl == null) {
|
|
return longUrl;
|
|
}
|
|
|
|
try {
|
|
|
|
logger.debug("shorten the input longUrl: "+longUrl);
|
|
|
|
URL url = new URL(uriRequest);
|
|
|
|
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
|
|
connection.setDoOutput(true);
|
|
connection.setRequestMethod("POST");
|
|
connection.setRequestProperty("Content-Type", APPLICATION_JSON);
|
|
|
|
JSONObject jsonObj = new JSONObject();
|
|
//jsonObj.put(LONG_URL, longUrl);
|
|
String toLongURL = String.format("%s?link=%s",dynamicLink,longUrl);
|
|
jsonObj.put(LONG_DYNAMIC_LINK, toLongURL);
|
|
|
|
JSONObject jsonObjSuffix = null;
|
|
//suffixOption = null;
|
|
if(suffixOption!=null) {
|
|
jsonObjSuffix = new JSONObject(suffixOption);
|
|
}else {
|
|
//DEFAULT OPTION IS SHORT
|
|
jsonObjSuffix = new JSONObject();
|
|
jsonObjSuffix.put("option", "SHORT");
|
|
}
|
|
|
|
jsonObj.put("suffix", jsonObjSuffix);
|
|
// //ACTIVE THIS AFTER RELEASE
|
|
// if(paramKeyValue!=null && !paramKeyValue.isEmpty()){
|
|
// jsonObj.put(KEY, paramKeyValue);
|
|
// }
|
|
|
|
logger.debug("Performing POST request to URI: {}+++MASKED-KEY+++",uriRequest.substring(0,uriRequest.length()-10));
|
|
logger.debug("the body contains the JSON request: \n{}",jsonObj.toString(3));
|
|
OutputStreamWriter wr = new OutputStreamWriter(connection.getOutputStream());
|
|
wr.write(jsonObj.toString());
|
|
wr.flush();
|
|
BufferedReader rd = new BufferedReader(new InputStreamReader(connection.getInputStream()));
|
|
|
|
JSONTokener tokener = new JSONTokener(rd);
|
|
JSONObject jsonObject = new JSONObject(tokener);
|
|
logger.debug("response contains the json: "+jsonObject.toString());
|
|
|
|
wr.close();
|
|
rd.close();
|
|
return (String) jsonObject.get("shortLink"); //it is the SHORT URL
|
|
|
|
} catch (MalformedURLException e) {
|
|
logger.error("MalformedURLException error in UrlShortener", e);
|
|
return longUrl;
|
|
|
|
} catch (IOException e) {
|
|
logger.error("IOException error in UrlShortener", e);
|
|
return longUrl;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Checks if is available.
|
|
*
|
|
* @return true, if is available
|
|
*/
|
|
public boolean isAvailable() {
|
|
return isAvailable;
|
|
}
|
|
|
|
/**
|
|
* Gets the shortner server url.
|
|
*
|
|
* @return the shortner server url
|
|
*/
|
|
@Deprecated
|
|
public static String getShortnerServerUrl() {
|
|
return shortnerServiceUrl;
|
|
}
|
|
|
|
/**
|
|
* Gets the shortner service url.
|
|
*
|
|
* @return the shortner service url
|
|
*/
|
|
public static String getShortnerServiceUrl() {
|
|
return shortnerServiceUrl;
|
|
}
|
|
|
|
/**
|
|
* Gets the key.
|
|
*
|
|
* @return the key
|
|
*/
|
|
public static String getKey() {
|
|
return KEY;
|
|
}
|
|
|
|
/**
|
|
* Gets the param key value.
|
|
*
|
|
* @return the param key value
|
|
*/
|
|
public static String getParamKeyValue() {
|
|
return decryptedKEY;
|
|
}
|
|
|
|
/**
|
|
* Gets the uri request.
|
|
*
|
|
* @return the uri request
|
|
*/
|
|
public String getUriRequest() {
|
|
return uriRequest;
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
* Gets the suffix option.
|
|
*
|
|
* @return the suffix option
|
|
*/
|
|
public static String getSuffixOption() {
|
|
return suffixOption;
|
|
}
|
|
|
|
|
|
/**
|
|
* Gets the dynamic link.
|
|
*
|
|
* @return the dynamic link
|
|
*/
|
|
public static String getDynamicLink() {
|
|
return dynamicLink;
|
|
}
|
|
|
|
|
|
/* (non-Javadoc)
|
|
* @see java.lang.Object#toString()
|
|
*/
|
|
@Override
|
|
public String toString() {
|
|
StringBuilder builder = new StringBuilder();
|
|
builder.append("UrlShortener [uriRequest=");
|
|
builder.append(uriRequest);
|
|
builder.append(", isAvailable=");
|
|
builder.append(isAvailable);
|
|
builder.append("]");
|
|
return builder.toString();
|
|
}
|
|
|
|
} |