2016-04-05 11:57:55 +02:00
/ * *
*
* /
package org.gcube.datatransfer.resolver.gis.geonetwork ;
2017-09-05 11:25:26 +02:00
import java.io.ByteArrayInputStream ;
import java.io.ByteArrayOutputStream ;
2016-04-05 11:57:55 +02:00
import java.io.IOException ;
import java.io.InputStream ;
import java.io.OutputStream ;
import java.io.StringReader ;
2017-09-05 11:25:26 +02:00
import java.util.ArrayList ;
import java.util.Arrays ;
import java.util.Enumeration ;
2016-04-05 11:57:55 +02:00
import java.util.HashMap ;
2017-09-05 11:25:26 +02:00
import java.util.List ;
2016-04-05 11:57:55 +02:00
import java.util.Map ;
import java.util.Timer ;
import java.util.TimerTask ;
import javax.servlet.ServletException ;
import javax.servlet.http.HttpServlet ;
import javax.servlet.http.HttpServletRequest ;
import javax.servlet.http.HttpServletResponse ;
import org.apache.commons.io.IOUtils ;
2016-06-09 11:36:25 +02:00
import org.gcube.common.scope.api.ScopeProvider ;
2017-08-30 17:59:30 +02:00
import org.gcube.datatransfer.resolver.GeonetworkRequestFilterParameters ;
import org.gcube.datatransfer.resolver.GeonetworkRequestFilterParameters.MODE ;
import org.gcube.datatransfer.resolver.GeonetworkRequestFilterParameters.VISIBILITY ;
2016-06-09 11:36:25 +02:00
import org.gcube.datatransfer.resolver.gis.GeonetworkAccessParameter ;
import org.gcube.datatransfer.resolver.gis.GeonetworkInstance ;
2017-09-05 11:25:26 +02:00
import org.gcube.datatransfer.resolver.gis.GeonetworkServiceInterface ;
2017-05-15 16:59:27 +02:00
import org.gcube.datatransfer.resolver.gis.exception.GeonetworkInstanceException ;
2016-09-07 15:07:46 +02:00
import org.gcube.datatransfer.resolver.gis.geonetwork.HTTPCallsUtils.HttpResponse ;
2017-09-05 11:25:26 +02:00
import org.gcube.datatransfer.resolver.gis.util.GetResponseRecordFilter ;
2016-06-09 11:36:25 +02:00
import org.gcube.spatial.data.geonetwork.configuration.Configuration ;
2017-09-05 11:25:26 +02:00
import org.gcube.spatial.data.geonetwork.model.Account ;
import org.gcube.spatial.data.geonetwork.model.Account.Type ;
2016-04-05 11:57:55 +02:00
import org.slf4j.Logger ;
import org.slf4j.LoggerFactory ;
2017-09-05 11:25:26 +02:00
import org.w3c.dom.Document ;
2016-04-05 11:57:55 +02:00
2016-05-12 18:22:44 +02:00
2016-04-05 11:57:55 +02:00
/ * *
* The Class GeonetworkResolver .
*
2016-05-12 18:22:44 +02:00
* Works as a proxy in order to authenticate HTTP POST calls on gCube Geonetwork servers discovered by SCOPE on gCube Information System
* Used by gCube Data Catalog for harvesting metadata
2016-04-05 11:57:55 +02:00
*
2016-05-12 18:22:44 +02:00
* @author Francesco Mangiacrapa francesco . mangiacrapa @isti.cnr.it
* May 12 , 2016
2016-04-05 11:57:55 +02:00
* /
public class GeonetworkResolver extends HttpServlet {
2016-04-26 17:23:38 +02:00
/ * *
*
* /
public static final String SRV_EN_MEF_EXPORT = " /srv/en/mef.export " ; //MEF Geonetwork service
/ * *
*
* /
public static final String UUID = " uuid " ;
2016-04-05 15:24:15 +02:00
/ * *
*
* /
public static final String APPLICATION_XML = " application/xml " ;
2016-04-05 11:57:55 +02:00
/ * *
*
* /
private static final long serialVersionUID = - 61097584153314181L ;
public static final String SCOPE = " scope " ;
2017-08-30 17:59:30 +02:00
public static final String REMAIN_PATH_PARAM = " remainPath " ;
public static final String RESET_CACHE_PARAM = " resetcache " ;
public static final String RESET_CACHED_SCOPE_PARAM = " resetcachedscope " ;
2016-04-05 11:57:55 +02:00
public static final String CSW_SERVER = " srv/en/csw " ;
2017-08-30 17:59:30 +02:00
// public static final String PARAMETER_FILTER_PUBLIC_IDS = UriResolverRewriteFilter.PARAMETER_FILTER_PUBLIC_IDS;
// public static final String PARAMETER_NO_AUTHENTICATION = UriResolverRewriteFilter.PARAMETER_NO_AUTHENTICATION;
2016-04-05 11:57:55 +02:00
/** The logger. */
private static final Logger logger = LoggerFactory . getLogger ( GeonetworkResolver . class ) ;
2017-05-15 16:59:27 +02:00
protected Map < String , GeonetworkInstance > cacheGNInstances ; //A cache: scope - GeonetworkInstance
2016-04-05 11:57:55 +02:00
private Timer timer ;
//THIRTY MINUTES
public static final long CACHE_RESET_TIME = 30 * 60 * 1000 ;
2017-05-16 15:43:41 +02:00
//TEN SECONDS
2016-04-05 11:57:55 +02:00
public static final long CACHE_RESET_DELAY = 10 * 1000 ;
/ * ( non - Javadoc )
* @see javax . servlet . GenericServlet # init ( )
* /
@Override
public void init ( ) throws ServletException {
super . init ( ) ;
timer = new Timer ( true ) ;
timer . schedule ( new TimerTask ( ) {
@Override
public void run ( ) {
2017-05-15 15:02:01 +02:00
logger . info ( " Resetting Geonetwork configuratiors cache... " ) ;
2017-05-16 15:42:57 +02:00
purgeCacheGeonetworkInstances ( ) ;
2016-04-05 11:57:55 +02:00
}
} , CACHE_RESET_DELAY , CACHE_RESET_TIME ) ;
}
/ * ( non - Javadoc )
* @see javax . servlet . http . HttpServlet # doGet ( javax . servlet . http . HttpServletRequest , javax . servlet . http . HttpServletResponse )
2016-05-12 18:22:44 +02:00
* This call is not authenticated
2016-04-05 11:57:55 +02:00
* /
@Override
protected void doGet ( HttpServletRequest req , HttpServletResponse resp ) throws ServletException , IOException {
2017-08-30 17:59:30 +02:00
logger . info ( " doGET running... query string: " + req . getQueryString ( ) ) ;
2016-04-26 17:23:38 +02:00
String scopeValue = req . getParameter ( SCOPE ) ;
2017-08-30 17:59:30 +02:00
String remainValue = req . getParameter ( REMAIN_PATH_PARAM ) ;
String mode = req . getParameter ( GeonetworkRequestFilterParameters . MODE . class . getSimpleName ( ) ) ;
String visibility = req . getParameter ( GeonetworkRequestFilterParameters . VISIBILITY . class . getSimpleName ( ) ) ;
2018-07-20 12:57:00 +02:00
String owner = req . getParameter ( GeonetworkRequestFilterParameters . OWNER_PARAM ) ;
2017-08-30 17:59:30 +02:00
String resetCache = req . getParameter ( RESET_CACHE_PARAM ) ;
String resetScope = req . getParameter ( RESET_CACHED_SCOPE_PARAM ) ;
2016-04-05 11:57:55 +02:00
2017-05-16 17:50:41 +02:00
String originalScope = ScopeProvider . instance . get ( ) ;
2018-07-20 12:57:00 +02:00
if ( scopeValue = = null | | scopeValue . equals ( " " ) ) {
2016-04-05 11:57:55 +02:00
logger . debug ( " Scope not found " ) ;
2018-07-20 12:57:00 +02:00
sendError ( resp , HttpServletResponse . SC_BAD_REQUEST , SCOPE + " not found or empty " ) ;
2016-04-05 11:57:55 +02:00
return ;
}
2017-08-30 17:59:30 +02:00
MODE theMode ;
VISIBILITY theVisibility ;
theMode = GeonetworkRequestFilterParameters . MODE . valueOf ( mode ) ;
theVisibility = GeonetworkRequestFilterParameters . VISIBILITY . valueOf ( visibility ) ;
2016-04-06 10:31:44 +02:00
if ( resetCache ! = null & & Boolean . parseBoolean ( resetCache ) ) {
2017-05-16 15:42:57 +02:00
purgeCacheGeonetworkInstances ( ) ;
2016-04-06 10:31:44 +02:00
}
if ( resetScope ! = null & & Boolean . parseBoolean ( resetScope ) ) {
2017-05-16 15:42:57 +02:00
resetGeonetoworkInstanceCacheForScope ( scopeValue ) ;
2016-04-06 10:31:44 +02:00
}
2017-08-30 17:59:30 +02:00
logger . info ( " SCOPE: " + scopeValue ) ;
logger . info ( " MODE is: " + theMode ) ;
logger . info ( " VISIBILITY is: " + theVisibility ) ;
2018-07-20 12:57:00 +02:00
logger . info ( GeonetworkRequestFilterParameters . OWNER_PARAM + " is: " + owner ) ;
2017-08-30 17:59:30 +02:00
2016-04-05 11:57:55 +02:00
try {
2018-04-23 17:07:57 +02:00
GeonetworkInstance gnInstance = getGeonetworkInstanceForScope ( scopeValue ) ;
2017-05-16 15:42:57 +02:00
2018-07-20 12:57:00 +02:00
// if(gnInstance==null){
// logger.info("GeonetworkInstance not istanciable via geonetwork library.. using ");
// ServerParameters serverParams = getGeonetworkCachedServerParameters(scopeValue);
// gnInstance = gntwAccess.getGeonetworkInstance();
// }
2017-05-16 17:50:41 +02:00
ScopeProvider . instance . set ( scopeValue ) ;
2016-04-05 11:57:55 +02:00
HTTPCallsUtils httpUtils = new HTTPCallsUtils ( ) ;
2016-07-25 19:26:07 +02:00
Configuration config = gnInstance . getGeonetworkPublisher ( ) . getConfiguration ( ) ;
String geonetworkUrl = config . getGeoNetworkEndpoint ( ) ;
2016-04-26 17:23:38 +02:00
// boolean authorized = GNAuthentication.login(httpUtils, geonetworkParams.getUrl(), geonetworkParams.getUser(), geonetworkParams.getPassword());
// logger.trace("Authorized on "+geonetworkParams +" ? "+authorized);
String newQueryString = purgeScopeFromQueryString ( scopeValue , req . getQueryString ( ) ) ;
logger . trace ( " Purged query string from " + scopeValue + " is: " + newQueryString ) ;
2016-07-25 19:26:07 +02:00
String baseURL = remainValue = = null | | remainValue . isEmpty ( ) ? geonetworkUrl + " / " + CSW_SERVER : geonetworkUrl + " / " + CSW_SERVER + remainValue ;
2016-04-26 17:23:38 +02:00
logger . trace ( " New base URL " + baseURL ) ;
newQueryString = purgeRemainFromQueryString ( remainValue , newQueryString ) ;
logger . trace ( " Purged query string from " + remainValue + " is: " + newQueryString ) ;
String gnGetlURL = newQueryString = = null | | newQueryString . isEmpty ( ) ? baseURL : baseURL + " ? " + newQueryString ;
2016-04-05 11:57:55 +02:00
logger . info ( " Sending get request to URL: " + gnGetlURL ) ;
2016-09-07 15:07:46 +02:00
HttpResponse response = httpUtils . get ( gnGetlURL ) ;
switch ( response . getStatus ( ) ) {
case HttpServletResponse . SC_OK :
logger . info ( " Response return Content-Type: " + httpUtils . getLastContentType ( ) ) ;
resp . setContentType ( httpUtils . getLastContentType ( ) ) ;
InputStream in = IOUtils . toInputStream ( response . getResponse ( ) ) ;
OutputStream out = resp . getOutputStream ( ) ;
try {
int bytes = IOUtils . copy ( in , out ) ;
if ( bytes = = 0 )
logger . warn ( " ResponseBody is empty, returning empty resp " ) ;
} catch ( Exception e ) {
logger . error ( " Error on copy response: " , e ) ;
} finally {
IOUtils . closeQuietly ( in ) ;
}
break ;
case HttpServletResponse . SC_FORBIDDEN :
sendError ( resp , response . getStatus ( ) , " Sorry, you are not authorized to perform this request " ) ;
break ;
default :
sendError ( resp , response . getStatus ( ) , " Sorry, an error occurred on resolving geonetwork request with scope " + scopeValue ) ;
2016-04-05 11:57:55 +02:00
}
} catch ( Exception e ) {
logger . error ( " Exception: " , e ) ;
2016-04-26 17:23:38 +02:00
String error = " Sorry, an error occurred on resolving geonetwork request with scope " + scopeValue + " . Please, contact support! " ;
2016-04-05 11:57:55 +02:00
sendError ( resp , HttpServletResponse . SC_INTERNAL_SERVER_ERROR , error ) ;
return ;
2017-05-16 17:50:41 +02:00
} finally {
if ( originalScope ! = null ) {
ScopeProvider . instance . set ( originalScope ) ;
logger . info ( " scope provider set to orginal scope: " + originalScope ) ;
} else {
ScopeProvider . instance . reset ( ) ;
logger . info ( " scope provider reset " ) ;
}
2016-04-05 11:57:55 +02:00
}
}
2018-07-20 12:57:00 +02:00
/ * *
* Purge remain from query string .
*
* @param remain_value the scope
* @param queryString the query string
* @return the string
* /
private static String purgeRemainFromQueryString ( String remain_value , String queryString ) {
// SCOPE is: /gcube/devsec/devVRE
// [INFO ] 2016-04-05 15:01:42,808 org.gcube.datatransfer.resolver.gis.geonetwork.GeonetworkResolver -
// Query String is: scope=/gcube/devsec/devVRE&version=2.0.2&request=GetCapabilities&service=CSW
int start = queryString . indexOf ( REMAIN_PATH_PARAM + " = " ) ;
if ( start > = 0 ) {
int end = queryString . indexOf ( " & " , start ) ;
if ( end = = - 1 & & queryString . length ( ) = = ( REMAIN_PATH_PARAM + " = " + remain_value ) . length ( ) ) { //SCOPE IS THE UNIQUE PARAMETER INTO QUETY STRING
logger . debug ( " Scope is the unique parameter, returning empty query string " ) ;
return " " ;
} else if ( end < queryString . length ( ) )
return queryString . substring ( end + 1 , queryString . length ( ) ) ;
}
return queryString ;
}
/ * *
* Purge scope from query string .
*
* @param scope_value the scope
* @param queryString the query string
* @return the string
* /
private static String purgeScopeFromQueryString ( String scope_value , String queryString ) {
// SCOPE is: /gcube/devsec/devVRE
// [INFO ] 2016-04-05 15:01:42,808 org.gcube.datatransfer.resolver.gis.geonetwork.GeonetworkResolver -
// Query String is: scope=/gcube/devsec/devVRE&version=2.0.2&request=GetCapabilities&service=CSW
int start = queryString . indexOf ( SCOPE + " = " ) ;
if ( start > = 0 ) {
int end = queryString . indexOf ( " & " , start ) ;
if ( end = = - 1 & & queryString . length ( ) = = ( SCOPE + " = " + scope_value ) . length ( ) ) { //SCOPE IS THE UNIQUE PARAMETER INTO QUETY STRING
logger . debug ( " Scope is the unique parameter, returning empty query string " ) ;
return " " ;
} else if ( end < queryString . length ( ) )
return queryString . substring ( end + 1 , queryString . length ( ) ) ;
}
return queryString ;
}
2016-04-05 11:57:55 +02:00
/ * ( non - Javadoc )
* @see javax . servlet . http . HttpServlet # doPost ( javax . servlet . http . HttpServletRequest , javax . servlet . http . HttpServletResponse )
2016-05-12 18:22:44 +02:00
* This call is authenticated
2016-04-05 11:57:55 +02:00
* /
2017-09-05 18:01:09 +02:00
@SuppressWarnings ( " resource " )
2016-04-05 11:57:55 +02:00
@Override
protected void doPost ( HttpServletRequest req , HttpServletResponse resp ) throws ServletException , IOException {
2016-04-26 17:23:38 +02:00
/ * MultiReadHttpServletRequest req2 ;
if ( req instanceof MultiReadHttpServletRequest )
req2 = ( MultiReadHttpServletRequest ) req ; * /
2017-03-24 17:38:36 +01:00
String originalScope = ScopeProvider . instance . get ( ) ;
2016-04-26 17:23:38 +02:00
logger . info ( " doPost running... " ) ;
2016-04-05 11:57:55 +02:00
String scope = req . getParameter ( SCOPE ) ;
2017-08-30 17:59:30 +02:00
String remainValue = req . getParameter ( REMAIN_PATH_PARAM ) ;
String mode = req . getParameter ( GeonetworkRequestFilterParameters . MODE . class . getSimpleName ( ) ) ;
String visibility = req . getParameter ( GeonetworkRequestFilterParameters . VISIBILITY . class . getSimpleName ( ) ) ;
2018-07-20 12:57:00 +02:00
String theOwner = req . getParameter ( GeonetworkRequestFilterParameters . OWNER_PARAM ) ;
2017-09-05 11:25:26 +02:00
//boolean filterPublicMetadata = false;
2016-06-21 18:09:18 +02:00
boolean noAuthenticationB = false ;
2016-04-05 11:57:55 +02:00
2017-08-30 17:59:30 +02:00
MODE theMode ;
VISIBILITY theVisibility ;
2018-07-20 12:57:00 +02:00
if ( scope = = null | | scope . equals ( " " ) ) {
2016-04-05 11:57:55 +02:00
logger . debug ( " Scope not found " ) ;
2018-07-20 12:57:00 +02:00
sendError ( resp , HttpServletResponse . SC_BAD_REQUEST , SCOPE + " not found or empty " ) ;
2016-04-05 11:57:55 +02:00
return ;
}
2017-08-30 17:59:30 +02:00
theMode = GeonetworkRequestFilterParameters . MODE . valueOf ( mode ) ;
theVisibility = GeonetworkRequestFilterParameters . VISIBILITY . valueOf ( visibility ) ;
2016-06-21 18:09:18 +02:00
2017-09-05 11:25:26 +02:00
logger . info ( SCOPE + " is: " + scope ) ;
logger . info ( GeonetworkRequestFilterParameters . MODE . class . getSimpleName ( ) + " is: " + theMode ) ;
logger . info ( GeonetworkRequestFilterParameters . VISIBILITY . class . getSimpleName ( ) + " is: " + theVisibility ) ;
2018-07-20 12:57:00 +02:00
logger . info ( GeonetworkRequestFilterParameters . OWNER_PARAM + " is: " + theOwner ) ;
2016-04-05 11:57:55 +02:00
2017-09-05 11:25:26 +02:00
try {
2016-04-05 11:57:55 +02:00
2017-05-15 14:45:20 +02:00
GeonetworkServiceInterface gntwAccess = new GeonetworkAccessParameter ( scope ) ;
2016-06-09 11:36:25 +02:00
GeonetworkInstance gnInstance = gntwAccess . getGeonetworkInstance ( ) ;
ScopeProvider . instance . set ( scope ) ;
logger . info ( " set scope provider " + scope ) ;
Configuration config = gnInstance . getGeonetworkPublisher ( ) . getConfiguration ( ) ;
2017-09-05 11:25:26 +02:00
Account account = config . getScopeConfiguration ( ) . getAccounts ( ) . get ( Type . CKAN ) ;
logger . info ( " CKAN user owner is: " + account . getUser ( ) ) ;
2016-06-09 11:36:25 +02:00
2018-07-20 12:57:00 +02:00
logger . info ( " Parameters.. " ) ;
2016-04-26 17:23:38 +02:00
for ( Enumeration < String > e = req . getParameterNames ( ) ; e . hasMoreElements ( ) ; ) {
String p = e . nextElement ( ) ;
2018-07-20 12:57:00 +02:00
logger . debug ( " param " + p + " value " + Arrays . toString ( req . getParameterValues ( p ) ) ) ;
2016-04-26 17:23:38 +02:00
}
2016-04-26 17:25:15 +02:00
//DEBUG BODY
2016-04-26 17:23:38 +02:00
// String readBody = IOUtils.toString(req.getReader());
// logger.debug("doPost read body request: "+readBody);
ByteArrayOutputStream byteArray = new ByteArrayOutputStream ( ) ;
2016-07-21 18:59:38 +02:00
String geonetworkUrl = config . getGeoNetworkEndpoint ( ) ;
2016-04-26 17:23:38 +02:00
// SPECIFIC HANDLER FOR GEONETWORK REQUEST: /srv/en/mef.export
String gnCSWlURL ;
if ( remainValue ! = null & & remainValue . compareTo ( SRV_EN_MEF_EXPORT ) = = 0 ) {
logger . info ( " In case of mef.export, perfoming a custom handler " ) ;
2016-07-21 18:59:38 +02:00
gnCSWlURL = geonetworkUrl + SRV_EN_MEF_EXPORT ;
2016-04-26 17:23:38 +02:00
String [ ] uuidValues = req . getParameterValues ( UUID ) ;
if ( uuidValues ! = null ) {
String data = null ;
for ( String uuid : uuidValues ) {
data = UUID + " = " + uuid ;
}
if ( data ! = null ) {
2016-06-16 15:03:03 +02:00
logger . debug ( " Writing " + data + " into byte array " ) ;
2016-04-26 17:23:38 +02:00
byteArray . write ( data . getBytes ( ) ) ;
} else
IOUtils . copy ( req . getReader ( ) , byteArray ) ;
} else
IOUtils . copy ( req . getReader ( ) , byteArray ) ;
} else {
2016-07-21 18:59:38 +02:00
gnCSWlURL = remainValue = = null | | remainValue . isEmpty ( ) ? geonetworkUrl + " / " + CSW_SERVER : geonetworkUrl + " / " + CSW_SERVER + remainValue ;
2016-04-26 17:23:38 +02:00
IOUtils . copy ( req . getReader ( ) , byteArray ) ;
}
2017-09-05 11:25:26 +02:00
//filterPublicMetadata = theVisibility.equals(VISIBILITY.PRV)?true:false;
HTTPCallsUtils httpUtils = new HTTPCallsUtils ( ) ;
//PRIVATE LAYERS
if ( theVisibility . equals ( VISIBILITY . PRV ) ) {
logger . debug ( " Visibility: " + VISIBILITY . PRV + " getting private layers.. " ) ;
//VRE LAYERS
if ( theMode . equals ( MODE . VRE ) ) {
2018-07-20 12:57:00 +02:00
logger . debug ( " Getting " + MODE . VRE + " layers.. " ) ;
2017-09-05 11:25:26 +02:00
//HARVESTED LAYERS
} else {
2018-07-20 12:57:00 +02:00
logger . debug ( " Getting " + MODE . HARVEST + " layers, I'm using the owner: ' " + theOwner + " ' passed as parameter to filter layer/s returned.. " ) ;
if ( theOwner = = null | | theOwner . isEmpty ( ) ) {
String error = " Harvest owner is missing. It is not possible to filter layers for the request " + MODE . HARVEST + " in the scope: " + scope + " , without a valid owner as input " ;
logger . error ( error ) ;
sendError ( resp , HttpServletResponse . SC_BAD_REQUEST , error ) ;
return ;
}
2017-09-05 11:25:26 +02:00
}
if ( account . getUser ( ) ! = null ) {
2018-07-20 12:57:00 +02:00
boolean authorized = GNAuthentication . login ( httpUtils , geonetworkUrl , account . getUser ( ) , account . getPassword ( ) ) ;
2017-09-05 11:25:26 +02:00
logger . trace ( " Authorized on " + geonetworkUrl + " ? " + authorized ) ;
} else
logger . info ( " Skipping authentication, ckan user (the owner) is null " ) ;
2016-06-16 15:03:03 +02:00
2017-09-05 11:25:26 +02:00
//PUBLIC LAYERS
} else {
logger . debug ( " Visibility: " + VISIBILITY . PUB + " getting public layers.. " ) ;
//VRE LAYERS
if ( theMode . equals ( MODE . VRE ) ) {
logger . debug ( " Getting " + MODE . VRE + " layers, the VRE account: " + account . getUser ( ) + " will be used as owner user for filtering... Is it right? " ) ;
2018-07-20 12:57:00 +02:00
theOwner = account . getUser ( ) ;
2017-09-05 11:25:26 +02:00
//HARVESTED LAYERS
} else {
2018-07-20 12:57:00 +02:00
logger . debug ( " Getting " + MODE . HARVEST + " layers, I'm using the owner: ' " + theOwner + " ' passed as parameter to filter layer/s returned.. " ) ;
if ( theOwner = = null | | theOwner . isEmpty ( ) ) {
String error = " Harvest owner is missing. It is not possible to filter layers for the request " + MODE . HARVEST + " in the scope: " + scope + " , without a valid owner as input " ;
logger . error ( error ) ;
sendError ( resp , HttpServletResponse . SC_BAD_REQUEST , error ) ;
return ;
}
2017-09-05 11:25:26 +02:00
}
}
2016-06-16 15:03:03 +02:00
2016-04-11 14:36:40 +02:00
logger . info ( " Sending CSW POST request to URL: " + gnCSWlURL ) ;
2017-09-05 18:01:09 +02:00
logger . debug ( " Content-Type: " + req . getContentType ( ) ) ;
2016-04-26 17:23:38 +02:00
//DEBUG
2018-07-20 12:57:00 +02:00
//logger.debug("POST - BODY : "+byteArray.toString());
2016-04-26 17:23:38 +02:00
InputStream in = httpUtils . post ( gnCSWlURL , new ByteArrayInputStream ( byteArray . toByteArray ( ) ) , req . getContentType ( ) , req . getParameterMap ( ) ) ;
//END DEBUG
2017-09-05 18:01:09 +02:00
logger . debug ( " Response return Content-Type: " + httpUtils . getLastContentType ( ) ) ;
2016-04-05 15:24:15 +02:00
resp . setContentType ( httpUtils . getLastContentType ( ) ) ;
2016-04-05 11:57:55 +02:00
OutputStream out = resp . getOutputStream ( ) ;
2016-04-26 17:23:38 +02:00
if ( in = = null ) {
logger . warn ( " Input stream returned is null, sending " + HttpServletResponse . SC_NOT_FOUND ) ;
resp . sendError ( HttpServletResponse . SC_NOT_FOUND ) ;
return ;
}
2017-09-05 11:25:26 +02:00
2016-04-05 11:57:55 +02:00
try {
2016-06-16 15:03:03 +02:00
2017-09-05 18:01:09 +02:00
ReusableInputStream reus = new ReusableInputStream ( in ) ;
2017-09-05 11:25:26 +02:00
if ( theVisibility . equals ( VISIBILITY . PRV ) ) {
2018-07-20 12:57:00 +02:00
logger . info ( " Private VISIBILITY performing so getting public file identifiers to apply filtering.. " ) ;
FilterGetRecords filterGetRecords = new FilterGetRecords ( byteArray . toString ( ) ) ;
if ( filterGetRecords . getFoundPublicIds ( ) ! = null & & filterGetRecords . getFoundPublicIds ( ) . size ( ) > 0 ) {
logger . info ( " I'm removing list of public IDs with " + filterGetRecords . getFoundPublicIds ( ) . size ( ) + " item/s. Is it right? " ) ;
in = GetResponseRecordFilter . overrideResponseIdsByListIds ( reus , filterGetRecords . getFoundPublicIds ( ) , " Replaced a public UUID, please ignore " ) ;
2017-09-05 11:25:26 +02:00
}
2018-07-20 12:57:00 +02:00
} else {
2017-09-05 18:01:09 +02:00
2018-07-20 12:57:00 +02:00
logger . info ( " Public VISIBILITY perfoming check on ownership... " ) ;
2017-09-05 11:25:26 +02:00
Document doc = GetResponseRecordFilter . inputStreamToW3CDocument ( reus ) ;
List < String > fileIdentifiers = GetResponseRecordFilter . getTextContentStringsForTagName ( doc , " gmd:fileIdentifier " ) ;
2018-07-20 12:57:00 +02:00
List < String > noMatchingOwner = new ArrayList < String > ( ) ;
2017-09-05 11:25:26 +02:00
for ( String fileId : fileIdentifiers ) {
2018-07-20 12:57:00 +02:00
String own = GetResponseRecordFilter . getMetaCategoryByFileIdentifier ( fileId , config . getGeoNetworkEndpoint ( ) , config . getAdminAccount ( ) . getUser ( ) , config . getAdminAccount ( ) . getPassword ( ) ) ;
//String own = GetResponseRecordFilter.getMetaOwnerNameByFileIdentifier(fileId, config.getGeoNetworkEndpoint(),config.getAdminAccount().getUser(), config.getAdminAccount().getPassword());
if ( own . compareTo ( theOwner ) ! = 0 ) {
logger . debug ( " Owner of file Identifier " + fileId + " not matching the owner passed: " + theOwner + " , removing it.. " ) ;
noMatchingOwner . add ( fileId ) ;
2017-09-05 11:25:26 +02:00
}
}
2018-07-20 12:57:00 +02:00
if ( noMatchingOwner . size ( ) > 0 ) {
logger . info ( " Removing " + noMatchingOwner . size ( ) + " layer/s not macthing the owner: " + theOwner ) ;
in = GetResponseRecordFilter . overrideResponseIdsByListIds ( reus , noMatchingOwner , " Replaced UUID owned by another user, please ignore " ) ;
2017-09-05 18:01:09 +02:00
} else {
2018-07-20 12:57:00 +02:00
logger . info ( " No replace on UUIDs was applied for the owner: " + theOwner ) ;
2017-09-05 18:01:09 +02:00
in = reus ;
2017-09-05 11:25:26 +02:00
}
2016-06-16 15:03:03 +02:00
}
2017-09-05 12:15:51 +02:00
ReusableInputStream reusIs = new ReusableInputStream ( in ) ;
int bytes = IOUtils . copy ( reusIs , out ) ;
2017-09-05 18:01:09 +02:00
//logger.trace("POST - RETURN : "+IOUtils.toString(reusIs));
2016-06-16 18:12:05 +02:00
2016-04-05 11:57:55 +02:00
if ( bytes = = 0 )
logger . warn ( " ResponseBody is empty, returning empty resp " ) ;
} catch ( Exception e ) {
logger . error ( " Error on copy response: " , e ) ;
} finally {
IOUtils . closeQuietly ( in ) ;
}
} catch ( IllegalArgumentException e ) {
logger . error ( " IllegalArgumentException: " , e ) ;
sendError ( resp , HttpServletResponse . SC_BAD_REQUEST , " Illegal argument to carry out the request! " ) ;
return ;
} catch ( Exception e ) {
logger . error ( " Exception: " , e ) ;
String error = " Sorry, an error occurred on resolving geonetwork request with scope " + scope + " . Please, contact support! " ;
sendError ( resp , HttpServletResponse . SC_INTERNAL_SERVER_ERROR , error ) ;
return ;
2016-06-09 11:36:25 +02:00
} finally {
2017-03-24 17:38:36 +01:00
if ( originalScope ! = null ) {
2016-09-07 15:07:46 +02:00
ScopeProvider . instance . set ( originalScope ) ;
2017-03-24 17:38:36 +01:00
logger . info ( " scope provider set to orginal scope: " + originalScope ) ;
2016-09-07 15:07:46 +02:00
} else {
ScopeProvider . instance . reset ( ) ;
logger . info ( " scope provider reset " ) ;
}
2017-09-05 11:25:26 +02:00
}
2016-04-05 11:57:55 +02:00
}
2017-05-15 16:59:27 +02:00
2016-04-05 11:57:55 +02:00
/ * *
2017-05-15 16:59:27 +02:00
* Gets the geonetwork instance for scope .
2016-04-05 11:57:55 +02:00
*
* @param scope the scope
2017-05-15 16:59:27 +02:00
* @return the geonetwork instance for scope
2016-04-05 11:57:55 +02:00
* @throws Exception the exception
* /
2017-05-15 16:59:27 +02:00
protected GeonetworkInstance getGeonetworkInstanceForScope ( String scope ) throws Exception {
2016-04-05 11:57:55 +02:00
2017-05-15 16:59:27 +02:00
if ( cacheGNInstances = = null )
2017-05-16 15:42:57 +02:00
purgeCacheGeonetworkInstances ( ) ;
2016-04-05 11:57:55 +02:00
2017-05-15 16:59:27 +02:00
logger . info ( " Attempt to get geonetwork instance from GeonetworkInstance cache for scope: " + scope ) ;
GeonetworkInstance geoInstance = cacheGNInstances . get ( scope ) ;
2016-04-05 11:57:55 +02:00
2017-05-15 16:59:27 +02:00
if ( geoInstance = = null ) {
logger . info ( " Cache having null GeonetworkInstance for scope " + scope + " , reading by Geonetwork library... " ) ;
2016-04-05 11:57:55 +02:00
try {
2017-05-15 16:59:27 +02:00
geoInstance = discoveryGeonetworkInstance ( scope ) ;
cacheGNInstances . put ( scope , geoInstance ) ;
logger . info ( " Updated GeonetworkInstance Cache adding couple: Scope " + scope + " - GeonetworkInstance " + geoInstance ) ;
2016-04-05 11:57:55 +02:00
} catch ( Exception e ) {
2017-05-15 16:59:27 +02:00
logger . error ( " An error occurred on reading GeonetworkInstance for scope " + scope , e ) ;
throw new Exception ( " Sorry, An error occurred on reading GeonetworkInstance for scope " + scope ) ;
2016-04-05 11:57:55 +02:00
}
} else
2017-05-15 16:59:27 +02:00
logger . info ( " GeonetworkInstance cache for scope: " + scope + " is not null using it: " + geoInstance ) ;
2016-04-05 11:57:55 +02:00
2017-05-15 16:59:27 +02:00
return geoInstance ;
2016-04-05 11:57:55 +02:00
}
2017-05-15 16:59:27 +02:00
/ * *
* Discovery geonetwork instance .
*
* @param scope the scope
* @return the geonetwork instance
* @throws GeonetworkInstanceException the geonetwork instance exception
* /
private GeonetworkInstance discoveryGeonetworkInstance ( String scope ) throws GeonetworkInstanceException {
GeonetworkAccessParameter gntwAccess = new GeonetworkAccessParameter ( scope ) ;
return gntwAccess . getGeonetworkInstance ( true , null ) ;
}
2016-04-06 10:31:44 +02:00
2017-05-16 15:42:57 +02:00
2016-04-06 10:31:44 +02:00
/ * *
2017-05-16 15:42:57 +02:00
* Reset geonetowork instance cache for scope .
2016-04-06 10:31:44 +02:00
*
* @param scope the scope
* /
2017-05-16 15:42:57 +02:00
private void resetGeonetoworkInstanceCacheForScope ( String scope ) {
2017-05-15 16:59:27 +02:00
if ( cacheGNInstances ! = null & & cacheGNInstances . get ( scope ) ! = null ) {
cacheGNInstances . remove ( scope ) ;
2016-04-06 10:31:44 +02:00
logger . info ( " Reset of " + scope + " in Cache Geonetwork server params perfomed! " ) ;
} else
logger . info ( " Reset of " + scope + " in Cache Geonetwork skipped, scope not exists! " ) ;
}
2017-05-16 15:42:57 +02:00
2016-04-05 11:57:55 +02:00
/ * *
2017-05-16 15:42:57 +02:00
* Purge cache geonetwork instances .
2016-04-05 11:57:55 +02:00
* /
2017-05-16 15:42:57 +02:00
private void purgeCacheGeonetworkInstances ( ) {
2017-05-15 16:59:27 +02:00
cacheGNInstances = new HashMap < String , GeonetworkInstance > ( ) ;
2017-05-16 12:06:43 +02:00
logger . info ( " Reset of GeonetworkInstance cache perfomed! " ) ;
2016-04-05 11:57:55 +02:00
}
/ * *
* Send error .
*
* @param response the response
* @param status the status
* @param message the message
* @throws IOException Signals that an I / O exception has occurred .
* /
protected void sendError ( HttpServletResponse response , int status , String message ) throws IOException
{
// response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
response . setStatus ( status ) ;
logger . info ( " error message: " + message ) ;
logger . info ( " writing response... " ) ;
StringReader sr = new StringReader ( message ) ;
IOUtils . copy ( sr , response . getOutputStream ( ) ) ;
// response.getWriter().write(resultMessage.toString());
logger . info ( " response writed " ) ;
response . flushBuffer ( ) ;
}
/ * *
* Url redirect .
*
* @param req the req
* @param response the response
* @param redirectTo the redirect to
* @throws IOException Signals that an I / O exception has occurred .
* /
protected void urlRedirect ( HttpServletRequest req , HttpServletResponse response , String redirectTo ) throws IOException {
response . sendRedirect ( response . encodeRedirectURL ( redirectTo ) ) ;
return ;
}
}