package org.gcube.portlets.user.uriresolvermanager.resolvers; import java.io.BufferedInputStream; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.net.HttpURLConnection; import java.net.URL; import java.util.Map; import org.gcube.portlets.user.uriresolvermanager.entity.GenericResolver; import org.gcube.portlets.user.uriresolvermanager.util.UrlEncoderUtil; import org.gcube.portlets.user.urlshortener.UrlShortener; import org.json.JSONObject; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * The Class GeoportalResolverCallBuilder. * * @author Francesco Mangiacrapa at ISTI-CNR francesco.mangiacrapa@isti.cnr.it * * Mar 27, 2023 */ public class GeoportalResolverCallBuilder extends GenericResolver { private static final int _60SEC = 60000; public static final Logger LOG = LoggerFactory.getLogger(GeoportalResolverCallBuilder.class); /** * Instantiates a new geoportal resolver call builder. * * @param resourceName the resource name * @param entryName the entry name */ public GeoportalResolverCallBuilder(String resourceName, String entryName) { super(resourceName, entryName); } /** * Gets the link. * * @param baseURI the base URI * @param parameters the parameters * @return the link * @throws Exception the exception */ @Override public String getLink(String baseURI, Map parameters) throws Exception { LOG.debug("called getLink: " + baseURI + " parameters: " + parameters); HttpURLConnection con = null; String theResponse = null; try { URL urlObj = new URL(baseURI); con = (HttpURLConnection) urlObj.openConnection(); con.setRequestMethod("POST"); con.setRequestProperty("Content-Type", "application/json; charset=UTF-8"); // con.setRequestProperty("Accept", "application/json"); con.setDoOutput(true); con.setReadTimeout(_60SEC); con.setConnectTimeout(_60SEC); JSONObject jObj = new org.json.JSONObject(); for (String key : parameters.keySet()) { jObj.put(key, parameters.get(key)); } // if (queryStringParameters != null) { // String queryString = UrlEncoderUtil.toQueryString(queryStringParameters); // jObj.put(CatalogueResolverQueryStringBuilder.QUERY_STRING_PARAMETER, queryString); // } String toJSON = jObj.toString(); LOG.info("Submitting JSON: " + toJSON); Integer code = null; try { OutputStream os = con.getOutputStream(); os.write(toJSON.getBytes("UTF-8")); os.close(); code = con.getResponseCode(); theResponse = readResponse(con.getInputStream()); if (!((200 <= code) && (code <= 208))) { throw new Exception("CatalogueResolver returned code: " + code + ". Response is: " + theResponse); } } catch (IOException e) { theResponse = readResponse(con.getInputStream()); LOG.error("CatalogueResolver returned code: " + code + ". Response is: " + theResponse); throw e; } } catch (Exception e) { LOG.error(GeoportalResolverCallBuilder.class.getSimpleName() + " error: ", e); throw e; } finally { try { if (con != null) con.disconnect(); } catch (Exception e) { // silent } } LOG.info("Got Link: " + theResponse); return theResponse; } /** * Short link. * * @param theLink the the link * @param parameters the parameters * @return the string * @throws Exception the exception */ @Override public String shortLink(String theLink, Map parameters) throws Exception { LOG.info("specific shortLink called"); String linkDecoded = theLink; String[] queryStringArray = theLink.split("\\?"); if (queryStringArray.length > 1) { String queryString = queryStringArray[1]; String queryStringEncoded = UrlEncoderUtil.encodeQuery(queryString); theLink = String.format("%s?%s", queryStringArray[0], queryStringEncoded); } // if (parameters != null) { // LOG.debug("Trying to read the parameter: " + CatalogueResolverQueryStringBuilder.QUERY_STRING_PARAMETER); // String queryStringParmeters = parameters.get(CatalogueResolverQueryStringBuilder.QUERY_STRING_PARAMETER); // if (queryStringParmeters != null) { // LOG.debug(CatalogueResolverQueryStringBuilder.QUERY_STRING_PARAMETER + " found"); // queryString = UrlEncoderUtil.encodeQuery(queryStringParmeters); // } // } try { // LOG.debug(CatalogueResolverQueryStringBuilder.QUERY_STRING_PARAMETER + " encoded is: " + queryString); // if (queryString != null) { // String queryStringEncoded = UrlEncoderUtil.encodeString(queryString); // theLink = String.format("%s?%s", theLink, queryStringEncoded); // } LOG.info("Encoded link is: " + theLink); LOG.info("Shortner starts.."); String shortLink = shortTheLink(theLink); LOG.info("Shorted link is: " + shortLink); if (shortLink != null && shortLink.equals(theLink)) { // here the short link and the input link are identical // so the shortening did not work // I'm returning the decoded link because it is directly consumable via browser LOG.debug("Shorted link is equal to input link, returning decoded link: " + linkDecoded); theLink = linkDecoded; } else { // here the link is really shorted LOG.debug("The link is really short, returning it"); theLink = shortLink; } } catch (Exception e) { LOG.warn("An error occurred during link shortening: ", e); // here I'm returning the decoded link in case of error on shortening it theLink = linkDecoded; } return theLink; } /** * Short the link. * * @param link the link * @return the string */ private String shortTheLink(String link) { String toReturnLink = link; try { UrlShortener shortener = new UrlShortener(); String shortedLink = shortener.shorten(link); LOG.info("Shorted link is: " + shortedLink); toReturnLink = shortedLink; } catch (Exception e) { LOG.warn("Returning source link, an error occurred during link shortening: ", e); } return toReturnLink; } /** * Read response. * * @param ris the ris * @return the string * @throws IOException Signals that an I/O exception has occurred. */ private String readResponse(InputStream ris) throws IOException { // Receive the response from the server InputStream in = new BufferedInputStream(ris); BufferedReader reader = new BufferedReader(new InputStreamReader(in)); StringBuilder result = new StringBuilder(); String line; while ((line = reader.readLine()) != null) { result.append(line); } return result.toString(); } }