diff --git a/.classpath b/.classpath index 0cad5db..6d7587a 100644 --- a/.classpath +++ b/.classpath @@ -25,7 +25,6 @@ - diff --git a/.settings/org.eclipse.wst.common.component b/.settings/org.eclipse.wst.common.component index aba33b6..bcc91bc 100644 --- a/.settings/org.eclipse.wst.common.component +++ b/.settings/org.eclipse.wst.common.component @@ -1,10 +1 @@ - - - - - - - - - - + diff --git a/Docker/adaguc-services-config.xml b/Docker/adaguc-services-config.xml index 6a292d3..92a658e 100644 --- a/Docker/adaguc-services-config.xml +++ b/Docker/adaguc-services-config.xml @@ -5,7 +5,22 @@ /adaguc/basedir 8080 + 8443 + /adaguc-services + + true + + /adaguc/security/truststore.ts + /root/.globus/certificates/ + changeit + + /adaguc/security/keystore.jks + password + JKS + tomcat + + /adaguc/adaguc-server-master/bin/adagucserver ADAGUC_PATH=/adaguc/adaguc-server-master/ diff --git a/Docker/start.sh b/Docker/start.sh index 4e416da..f63f0ce 100644 --- a/Docker/start.sh +++ b/Docker/start.sh @@ -172,4 +172,4 @@ then fi echo "Starting TOMCAT Server" && \ -java -jar /adaguc/adaguc-services.war \ No newline at end of file +java -jar /adaguc/adaguc-services.jar diff --git a/Docker/tomcat-server.xml b/Docker/tomcat-server.xml deleted file mode 100644 index 8e434d9..0000000 --- a/Docker/tomcat-server.xml +++ /dev/null @@ -1,156 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Dockerfile b/Dockerfile index fdd13ee..c25d696 100644 --- a/Dockerfile +++ b/Dockerfile @@ -29,6 +29,11 @@ RUN yum update -y && yum install -y \ maven \ openssl +# Install newer numpy +RUN curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py +RUN python get-pip.py +RUN pip install numpy netcdf4 six lxml + RUN mkdir /adaguc # Install adaguc-services from the context @@ -36,7 +41,7 @@ WORKDIR /adaguc/adaguc-services COPY /src/ /adaguc/adaguc-services/src/ COPY pom.xml /adaguc/adaguc-services/pom.xml RUN mvn package -RUN cp /adaguc/adaguc-services/target/adaguc-services-*.war /adaguc/adaguc-services.war +RUN cp /adaguc/adaguc-services/target/adaguc-services-*.jar /adaguc/adaguc-services.jar # Install adaguc-server from github WORKDIR /adaguc diff --git a/README.md b/README.md index f416dd7..9fec5ae 100644 --- a/README.md +++ b/README.md @@ -26,5 +26,7 @@ For creating a new package: 4) You can for example start this with java -jar demo-${VERSION}-SNAPSHOT.jar +# Versions +1.1.0 - Uses spring boot 2.0 diff --git a/adaguc-services-config.xml.example b/adaguc-services-config.xml.example index e74b113..1634999 100644 --- a/adaguc-services-config.xml.example +++ b/adaguc-services-config.xml.example @@ -9,6 +9,7 @@ 8090 + /adaguc-services @@ -49,10 +50,29 @@ USE_FONTCONFIG=False + + + + https://accounts.google.com/o/oauth2/auth + https://accounts.google.com/o/oauth2/token + *** + *** + email + images/google.png + Sign in with Google + + + true + + true + /data/adaguc-autowms/ + /data/adaguc-datasets/ + + true @@ -62,5 +82,15 @@ {ENV.ADAGUCSERVICES}/data/adaguc-services-base/catalog + + true + /data/adaguc-servicehealth/ + + + + true + /tmp/esgfsearch + https://esg-dn1.nsc.liu.se/esg-search/search? + \ No newline at end of file diff --git a/pom.xml b/pom.xml index 527c862..0962acb 100644 --- a/pom.xml +++ b/pom.xml @@ -5,8 +5,7 @@ nl.knmi.adagucservices adaguc-services - 1.0.13 - war + 1.2.0 adaguc-services Backend for adaguc-server and adaguc-viewer @@ -14,11 +13,9 @@ org.springframework.boot spring-boot-starter-parent - 1.5.2.BUILD-SNAPSHOT + 2.1.2.RELEASE - - UTF-8 UTF-8 @@ -45,6 +42,13 @@ org.springframework.boot spring-boot-starter-test + + + com.vaadin.external.google + android-json + + + test @@ -52,14 +56,10 @@ spring-boot-devtools true - - org.json - json - + com.fasterxml.jackson.datatype jackson-datatype-jsr310 - 2.4.0 de.grundid.opendatalab @@ -72,27 +72,23 @@ jackson-databind - - org.springframework.boot - spring-boot-starter-web - - org.springframework.boot spring-boot-starter-tomcat compile + + + com.vaadin.external.google + android-json + + - - org.reflections - reflections - 0.9.11 - + org.apache.commons commons-lang3 - 3.5 @@ -113,13 +109,8 @@ org.apache.httpcomponents httpclient - 4.5.2 - - - edu.ucar @@ -151,28 +142,6 @@ org.springframework.security spring-security-core - 4.2.4.RELEASE - - - - - com.github.maartenplieger - nl.knmi.adaguc.tools - 1.0.16 - - - com.github.maartenplieger - nl.knmi.adaguc.config - - 1.0.13 - @@ -201,13 +170,6 @@ org.springframework.boot spring-boot-maven-plugin - - org.apache.maven.plugins - maven-surefire-plugin - - false - - @@ -228,19 +190,14 @@ false - - jitpack.io - https://jitpack.io - artifacts.unidata.ucar.edu - https://artifacts.unidata.ucar.edu/content/repositories/unidata-releases/ + https://repo.boundlessgeo.com/main/ - spring-snapshots diff --git a/src/main/java/nl/knmi/adaguc/AdagucServicesApplication.java b/src/main/java/nl/knmi/adaguc/AdagucServicesApplication.java index e07fc7c..2f7ec47 100644 --- a/src/main/java/nl/knmi/adaguc/AdagucServicesApplication.java +++ b/src/main/java/nl/knmi/adaguc/AdagucServicesApplication.java @@ -2,24 +2,18 @@ import java.io.IOException; import java.security.Security; -import java.util.Enumeration; import java.util.Properties; -import org.apache.commons.lang3.StringUtils; import org.springframework.boot.Banner; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.builder.SpringApplicationBuilder; -import org.springframework.boot.web.support.SpringBootServletInitializer; - - +import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; import nl.knmi.adaguc.config.MainServicesConfigurator; import nl.knmi.adaguc.security.SecurityConfigurator; -import nl.knmi.adaguc.services.pywpsserver.PyWPSConfigurator; import nl.knmi.adaguc.services.pywpsserver.PyWPSInitializer; import nl.knmi.adaguc.tools.Debug; import nl.knmi.adaguc.tools.ElementNotFoundException; -import nl.knmi.adaguc.tools.Tools; @SpringBootApplication public class AdagucServicesApplication extends SpringBootServletInitializer{ @@ -31,6 +25,9 @@ protected SpringApplicationBuilder configure(SpringApplicationBuilder applicatio } catch (ElementNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); } Debug.println("Error"); return null; @@ -49,6 +46,8 @@ public static void main(String[] args) { } catch (ElementNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); + } catch (IOException e) { + Debug.errprintln(e.getMessage()); } } @@ -58,27 +57,58 @@ private static SpringApplicationBuilder configureApplication(SpringApplicationBu } catch (ElementNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); } return null; } - static Properties getProperties() throws ElementNotFoundException { + static Properties getProperties() throws ElementNotFoundException, IOException { Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider()); try { PyWPSInitializer.ConfigurePyWPS3(); - } catch (IOException e) { - throw new ElementNotFoundException("Unable to create config file for PyWPS"); + }catch (IOException e1) { + Debug.errprintln(e1.getMessage()); + System.exit(1); + } catch (ElementNotFoundException e) { + Debug.println("[INFO] Unable to create config file for PyWPS"); } Properties props = new Properties(); - if(MainServicesConfigurator.getServerPort()!=null)props.put("server.port", MainServicesConfigurator.getServerPort()); + if(SecurityConfigurator.getKeyStore()!=null)props.put("server.ssl.key-store", SecurityConfigurator.getKeyStore()); - if( SecurityConfigurator.getKeyStorePassword()!=null)props.put("server.ssl.key-store-password", SecurityConfigurator.getKeyStorePassword()); + /* + * server.port is the default spring tomcat connector, it can be both used for http and https + * server.http.port is the adaguc-services added connector, it is meant for http only. + * For backwards compatibility with previous releases, http.port is used for https and server.http.port is used for http * + */ +// Debug.println("MainServicesConfigurator.getServerPort()" + MainServicesConfigurator.getServerPort()); +// Debug.println("MainServicesConfigurator.getServerPortHTTPS()" + MainServicesConfigurator.getServerPortHTTPS()); + if(SecurityConfigurator.getEnableSSL()!=null && SecurityConfigurator.getEnableSSL().equals("true")) { + /* If SSL (HTTPS support) is enabled, configure http.port for https and optionaly server.http.port for http */ + props.put("server.ssl.enabled", true); + if(MainServicesConfigurator.getServerPort()!=null)props.put("server.http.port", MainServicesConfigurator.getServerPort()); + if(MainServicesConfigurator.getServerPortHTTPS()!=null)props.put("server.port", MainServicesConfigurator.getServerPortHTTPS()); else + if(MainServicesConfigurator.getServerPort()!=null)props.put("server.port", MainServicesConfigurator.getServerPort()); + } else { + /* If SSL (HTTPS support) is not enabled, configure as normal */ + props.put("server.ssl.enabled", false); + if(MainServicesConfigurator.getServerPort()!=null)props.put("server.port", MainServicesConfigurator.getServerPort()); + if(MainServicesConfigurator.getServerPort()!=null)props.put("server.http.port", MainServicesConfigurator.getServerPort()); + } + + if(MainServicesConfigurator.getContextPath()!=null)props.put("server.servlet.context-path", MainServicesConfigurator.getContextPath()); + if(SecurityConfigurator.getKeyStorePassword()!=null)props.put("server.ssl.key-store-password", SecurityConfigurator.getKeyStorePassword()); if(SecurityConfigurator.getKeyStoreType()!=null)props.put("server.ssl.keyStoreType",SecurityConfigurator.getKeyStoreType()); if(SecurityConfigurator.getKeyAlias()!=null)props.put("server.ssl.keyAlias", SecurityConfigurator.getKeyAlias()); if(SecurityConfigurator.getTrustStore()!=null)props.put("server.ssl.trust-store", SecurityConfigurator.getTrustStore()); if(SecurityConfigurator.getTrustStorePassword()!=null)props.put("server.ssl.trust-store-password", SecurityConfigurator.getTrustStorePassword()); props.put("server.ssl.client-auth", "want"); + + + + props.put("spring.http.multipart.max-file-size","100MB"); props.put("spring.http.multipart.max-request-size","100MB"); diff --git a/src/main/java/nl/knmi/adaguc/HttpServer.java b/src/main/java/nl/knmi/adaguc/HttpServer.java new file mode 100644 index 0000000..9780253 --- /dev/null +++ b/src/main/java/nl/knmi/adaguc/HttpServer.java @@ -0,0 +1,37 @@ +package nl.knmi.adaguc; + +import java.util.List; + +import org.apache.catalina.connector.Connector; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory; +import org.springframework.boot.web.servlet.server.ServletWebServerFactory; +import org.springframework.context.annotation.Bean; +import org.springframework.stereotype.Component; + +import nl.knmi.adaguc.tools.Debug; + +@Component +public class HttpServer { + @Bean + public ServletWebServerFactory servletContainer(@Value("${server.http.port:0}") int httpPort, @Value("${server.port}") int port) { + + TomcatServletWebServerFactory tomcat = new TomcatServletWebServerFactory(); + if (httpPort != 0 && (port!=httpPort)) { + Debug.println("configuring extra connector at port " + httpPort); + List tomcatConnectors = tomcat.getAdditionalTomcatConnectors(); + boolean portAlreadyUsed = false; + for(Connector tomcatConnector : tomcatConnectors) { + if (tomcatConnector.getPort()==httpPort) { + portAlreadyUsed = true; + } + } + if (portAlreadyUsed == false) { + Connector connector = new Connector(TomcatServletWebServerFactory.DEFAULT_PROTOCOL); + connector.setPort(httpPort); + tomcat.addAdditionalTomcatConnectors(connector); + } + } + return tomcat; + } +} \ No newline at end of file diff --git a/src/main/java/nl/knmi/adaguc/config/ConfigurationReader.java b/src/main/java/nl/knmi/adaguc/config/ConfigurationReader.java new file mode 100644 index 0000000..f736c74 --- /dev/null +++ b/src/main/java/nl/knmi/adaguc/config/ConfigurationReader.java @@ -0,0 +1,175 @@ +package nl.knmi.adaguc.config; + + +import java.io.IOException; +import java.util.HashSet; +import java.util.Set; + +import org.springframework.boot.context.event.ApplicationReadyEvent; +import org.springframework.context.event.EventListener; +import org.springframework.stereotype.Component; + +import nl.knmi.adaguc.security.SecurityConfigurator; +import nl.knmi.adaguc.services.adagucserver.ADAGUCConfigurator; +import nl.knmi.adaguc.services.autowms.AutoWMSConfigurator; +import nl.knmi.adaguc.services.basket.BasketConfigurator; +import nl.knmi.adaguc.services.datasetcatalog.DatasetCatalogConfigurator; +import nl.knmi.adaguc.services.esgfsearch.ESGFSearchConfigurator; +import nl.knmi.adaguc.services.joblist.JobListConfigurator; +import nl.knmi.adaguc.services.oauth2.OAuthConfigurator; +import nl.knmi.adaguc.services.pywpsserver.PyWPSConfigurator; +import nl.knmi.adaguc.services.servicehealth.ServiceHealthConfigurator; +import nl.knmi.adaguc.tools.Debug; +import nl.knmi.adaguc.tools.ElementNotFoundException; +import nl.knmi.adaguc.tools.MyXMLParser.XMLElement; +import nl.knmi.adaguc.tools.Tools; + +/** + * @author maartenplieger + * Configuration framework for reading one configuration file with multiple sections for pluggable configurators. + * New configurators must implement the nl.knmi.adaguc.config.ConfigurationInterface class. + * New configurators are automatically found in the project by using Reflection on classes which implement this interface. + * + */ +@Component +public class ConfigurationReader { + static public long readConfigPolInterval = 0; + static public boolean readConfigDone = false; + static public boolean refreshConfig =false; + + static private final long readConfigPolIntervalDuration = 10000; + static public String configFileLocationByEnvironment = "ADAGUC_SERVICES_CONFIG"; + static public String configFileNameInHomeByDefault = "adaguc-services-config.xml"; + + @EventListener(ApplicationReadyEvent.class) + public void doSomethingAfterStartup() { + try { + readConfig(); + } catch (ElementNotFoundException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (IOException e) { + Debug.errprintln(e.getMessage()); + } + } + + public ConfigurationReader(){ + } + + static private String _getHomePath(){ + return System.getProperty("user.home")+"/"; + } + + private static String _getConfigFile(){ + try{ + String configLocation = System.getenv(configFileLocationByEnvironment); + if(configLocation!=null){ + if(configLocation.length()>0){ + return configLocation; + } + } + }catch(Exception e){ + } + return _getHomePath()+configFileNameInHomeByDefault; + } + + static public synchronized void reset() { + readConfigPolInterval = 0; + } + + /** + * 1) Reads the configuration file periodically, re-reads the configuration file every readConfigPolIntervalDuration ms + * 2) When read, the doConfig method for all classes which implement ConfiguratorInterface is called + * @throws ConfigurationItemNotFoundException + * @throws ElementNotFoundException + * @throws IOException + * @throws Exception + */ + static public synchronized void readConfig() throws ElementNotFoundException, IOException{ + if (refreshConfig == false && readConfigDone == true)return; + /* Re-read the configuration file every 10 seconds. */ + if(readConfigPolInterval != 0){ + if(System.currentTimeMillis() foundValues = new HashSet(); + int start = 0, end = 0, index = -1; + do{ + index = configFile.substring(start).indexOf("{ENV."); + if(index>=0){ + start += index; + end = configFile.substring(start).indexOf("}"); + if(end >=0){ + end+=(start+1); + foundValues.add(configFile.substring(start, end)); + start=end; + }else{ + start+=5; /* In case } is missing, jump 5 places forward */ + } + } + }while(index !=-1); + for(String key : foundValues) { + String envKey = key.substring(5,key.length()-1); + String envValue = System.getenv(envKey); + if(envValue == null){ + throw new ElementNotFoundException("Environment variable ["+envKey+"] not set"); + } + configFile = configFile.replace(key,envValue); + } + // Debug.println("configfile=" + configFile); + + try { + configReader.parseString(configFile); + } catch (Exception e1) { + // TODO Auto-generated catch block + e1.printStackTrace(); + } + ///} + + + SecurityConfigurator.doConfig(configReader); + OAuthConfigurator.doConfig(configReader); + MainServicesConfigurator.doConfig(configReader); + ADAGUCConfigurator.doConfig(configReader); + BasketConfigurator.doConfig(configReader); + DatasetCatalogConfigurator.doConfig(configReader); + ESGFSearchConfigurator.doConfig(configReader); + JobListConfigurator.doConfig(configReader); + PyWPSConfigurator.doConfig(configReader); + AutoWMSConfigurator.doConfig(configReader); + ServiceHealthConfigurator.doConfig(configReader); +// +// Set> allClasses = +// reflections.getSubTypesOf(ConfiguratorInterface.class); +// +// Iterator> it = allClasses.iterator(); +// while(it.hasNext()){ +// Class a = it.next(); +// try { +// Debug.println("==> Calling get " + a.getName()); +// a.newInstance().doConfig(configReader); +//// a.newInstance().setConfigDone();; +// } catch (InstantiationException | IllegalAccessException e) { +// e.printStackTrace(); +// } +// } +// configReader = null; + } + + + + +} + diff --git a/src/main/java/nl/knmi/adaguc/config/ConfiguratorImpl.java b/src/main/java/nl/knmi/adaguc/config/ConfiguratorImpl.java new file mode 100644 index 0000000..0d764ba --- /dev/null +++ b/src/main/java/nl/knmi/adaguc/config/ConfiguratorImpl.java @@ -0,0 +1,13 @@ +package nl.knmi.adaguc.config; + +public class ConfiguratorImpl { + static boolean configDone = false; + + static public void setConfigDone() { + configDone = true; + } + + static public boolean getConfigDone() { + return configDone; + } +} diff --git a/src/main/java/nl/knmi/adaguc/config/ConfiguratorInterface.java b/src/main/java/nl/knmi/adaguc/config/ConfiguratorInterface.java new file mode 100644 index 0000000..603fd2f --- /dev/null +++ b/src/main/java/nl/knmi/adaguc/config/ConfiguratorInterface.java @@ -0,0 +1,22 @@ +package nl.knmi.adaguc.config; + +import nl.knmi.adaguc.tools.ElementNotFoundException; +import nl.knmi.adaguc.tools.MyXMLParser.XMLElement; + +/** + * @author maartenplieger + * New configurators must implement this class. New configurators are automatically found by using Reflection on classes which implement this interface. + * + */ +public interface ConfiguratorInterface { + + /** + * This method is called when the configuration is read. + * @param configReader The configuration file object + * @throws Exception + */ + public static void doConfig(XMLElement configReader) throws ElementNotFoundException { + } + +} + diff --git a/src/main/java/nl/knmi/adaguc/config/MainServicesConfigurator.java b/src/main/java/nl/knmi/adaguc/config/MainServicesConfigurator.java index b0d424a..2d9fc1f 100644 --- a/src/main/java/nl/knmi/adaguc/config/MainServicesConfigurator.java +++ b/src/main/java/nl/knmi/adaguc/config/MainServicesConfigurator.java @@ -1,5 +1,9 @@ package nl.knmi.adaguc.config; +import java.io.IOException; + +import org.springframework.beans.factory.annotation.Autowired; + import nl.knmi.adaguc.tools.ElementNotFoundException; import nl.knmi.adaguc.tools.MyXMLParser.XMLElement; @@ -13,36 +17,51 @@ public class MainServicesConfigurator implements ConfiguratorInterface{ private static String serverExternalURL=""; private static String userWorkspace="/tmp"; - private static String serverPort="443"; + private static String serverPort="8080"; + private static String serverPortHTTPS="443"; private static String baseDir="/tmp/"; + private static String contextPath="/"; - static ConfigurationReader configurationReader = new ConfigurationReader (); + @Autowired + static ConfigurationReader configurationReader; - public void doConfig(XMLElement configReader) throws ElementNotFoundException { + public static void doConfig(XMLElement configReader) throws ElementNotFoundException { serverExternalURL = configReader.getNodeValueMustNotBeUndefined("adaguc-services.external-home-url"); userWorkspace = configReader.getNodeValueMustNotBeUndefined("adaguc-services.userworkspace"); serverPort = configReader.getNodeValue("adaguc-services.server.port"); + serverPortHTTPS = configReader.getNodeValue("adaguc-services.server.porthttps"); baseDir = configReader.getNodeValueMustNotBeUndefined("adaguc-services.basedir"); + contextPath = configReader.getNodeValue("adaguc-services.server.contextpath"); } - public static String getServerExternalURL() throws ElementNotFoundException { - configurationReader.readConfig(); + public static String getServerExternalURL() throws ElementNotFoundException, IOException { + ConfigurationReader.readConfig(); return serverExternalURL; } - public static String getUserWorkspace() throws ElementNotFoundException{ - configurationReader.readConfig(); + public static String getUserWorkspace() throws ElementNotFoundException, IOException{ + ConfigurationReader.readConfig(); return userWorkspace; } - public static String getServerPort() throws ElementNotFoundException { - configurationReader.readConfig(); + public static String getServerPort() throws ElementNotFoundException, IOException { + ConfigurationReader.readConfig(); return serverPort; } - public static String getBaseDir() throws ElementNotFoundException { - configurationReader.readConfig(); + public static String getBaseDir() throws ElementNotFoundException, IOException { + ConfigurationReader.readConfig(); return baseDir; } + + public static String getContextPath() throws ElementNotFoundException, IOException { + ConfigurationReader.readConfig(); + return contextPath; + } + + public static Object getServerPortHTTPS() throws ElementNotFoundException, IOException { + ConfigurationReader.readConfig(); + return serverPortHTTPS; + } } \ No newline at end of file diff --git a/src/main/java/nl/knmi/adaguc/security/AuthenticatorImpl.java b/src/main/java/nl/knmi/adaguc/security/AuthenticatorImpl.java index 96ce708..deb35e4 100644 --- a/src/main/java/nl/knmi/adaguc/security/AuthenticatorImpl.java +++ b/src/main/java/nl/knmi/adaguc/security/AuthenticatorImpl.java @@ -1,34 +1,15 @@ package nl.knmi.adaguc.security; import java.io.IOException; -import java.security.InvalidKeyException; -import java.security.KeyManagementException; -import java.security.KeyStoreException; -import java.security.NoSuchAlgorithmException; -import java.security.NoSuchProviderException; -import java.security.SignatureException; -import java.security.UnrecoverableKeyException; -import java.security.cert.CertificateException; -import java.util.Enumeration; -import java.util.List; -import java.util.Map; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; -import org.apache.http.client.methods.CloseableHttpResponse; -import org.apache.http.client.methods.HttpGet; -import org.apache.http.impl.client.CloseableHttpClient; -import org.apache.http.util.EntityUtils; -import org.ietf.jgss.GSSException; import org.springframework.security.core.AuthenticationException; import nl.knmi.adaguc.security.PemX509Tools.X509Info; -import nl.knmi.adaguc.security.PemX509Tools.X509UserCertAndKey; import nl.knmi.adaguc.security.token.Token; import nl.knmi.adaguc.security.token.TokenManager; -import nl.knmi.adaguc.security.user.User; -import nl.knmi.adaguc.security.user.UserManager; import nl.knmi.adaguc.tools.Debug; import nl.knmi.adaguc.tools.ElementNotFoundException; import nl.knmi.adaguc.tools.HTTPTools; @@ -49,6 +30,17 @@ public synchronized void init(HttpServletRequest request) { if (request == null ) { return; } + + try{ + String userName = SecurityConfigurator.getUser(); + if (userName != null) { + request.getSession().setAttribute("user_identifier",userName); + request.getSession().setAttribute("services_access_token",userName); + request.getSession().setAttribute("emailaddress",userName); + } + }catch(Exception e){ + } + /* Get user from session */ String sessionId = null; HttpSession session = request.getSession(); @@ -57,12 +49,17 @@ public synchronized void init(HttpServletRequest request) { } if (sessionId!=null) { x509 = new PemX509Tools().new X509Info(sessionId, sessionId); - Debug.println("Got userid from session"); return; } /* Get user from header (Set by SSL client cert verification in NGINX)*/ try { +// Enumeration headerNames = request.getHeaderNames(); +// while(headerNames.hasMoreElements()) { +// String headerName = (String)headerNames.nextElement(); +// Debug.println("" + headerName); +// Debug.println("" + request.getHeader(headerName)); +// } String userHeader = SecurityConfigurator.getUserHeader(); if (userHeader != null) { String userIdFromHeader = request.getHeader(userHeader); @@ -74,6 +71,7 @@ public synchronized void init(HttpServletRequest request) { } } } catch (ElementNotFoundException e) { + } catch (IOException e) { } x509 = new PemX509Tools().getUserIdFromCertificate(request); diff --git a/src/main/java/nl/knmi/adaguc/security/PemX509Tools.java b/src/main/java/nl/knmi/adaguc/security/PemX509Tools.java index 361cfc8..aab9eba 100644 --- a/src/main/java/nl/knmi/adaguc/security/PemX509Tools.java +++ b/src/main/java/nl/knmi/adaguc/security/PemX509Tools.java @@ -175,9 +175,9 @@ public X509Info getUserIdFromCertificate(HttpServletRequest request){ } public String getUserIdFromSubjectDN (String subjectDN) { - String[] dnItems = subjectDN.split(", "); + String[] dnItems = subjectDN.split(","); for (int j = 0; j < dnItems.length; j++) { - int CNIndex = dnItems[j].indexOf("CN"); + int CNIndex = dnItems[j].trim().indexOf("CN"); if (CNIndex != -1) { return dnItems[j].substring("CN=".length() + CNIndex); @@ -515,29 +515,35 @@ public CloseableHttpClient getHTTPClientForPEMBasedClientAuth( ) throws KeyManagementException, UnrecoverableKeyException, NoSuchAlgorithmException, KeyStoreException, CertificateException, IOException, InvalidKeyException, NoSuchProviderException, SignatureException, GSSException{ KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType()); - /* Load the server JKS truststore */ - FileInputStream trustStoreStream = new FileInputStream(new File(trustStoreLocation)); - try { - trustStore.load(trustStoreStream, trustStorePassword); - } finally { + if (trustStoreLocation!= null && trustStorePassword != null) { + /* Load the server JKS truststore */ + FileInputStream trustStoreStream = new FileInputStream(new File(trustStoreLocation)); try { - trustStoreStream.close(); - } catch (Exception ignore) { + trustStore.load(trustStoreStream, trustStorePassword); + } finally { + try { + trustStoreStream.close(); + } catch (Exception ignore) { + } } + trustStoreStream.close(); + if(certAndKey!=null){ + trustStore.setKeyEntry("privateKeyAlias", certAndKey.getPrivateKey(), + trustStorePassword, new Certificate[] { certAndKey.getUserSlCertificate()}); + } + + SSLContext sslContext = + new SSLContextBuilder() + .loadTrustMaterial(trustStore, new TrustSelfSignedStrategy()) + .loadKeyMaterial(trustStore, trustStorePassword) + .build(); + return HttpClients.custom().setSSLContext(sslContext).setHostnameVerifier(AllowAllHostnameVerifier.INSTANCE).build(); + } else { + Debug.errprintln("Warning, truststore is null"); + return HttpClients.custom().setHostnameVerifier(AllowAllHostnameVerifier.INSTANCE).build(); } - trustStoreStream.close(); - if(certAndKey!=null){ - trustStore.setKeyEntry("privateKeyAlias", certAndKey.getPrivateKey(), - trustStorePassword, new Certificate[] { certAndKey.getUserSlCertificate()}); - } - - SSLContext sslContext = - new SSLContextBuilder() - .loadTrustMaterial(trustStore, new TrustSelfSignedStrategy()) - .loadKeyMaterial(trustStore, trustStorePassword) - .build(); - return HttpClients.custom().setSSLContext(sslContext).setHostnameVerifier(AllowAllHostnameVerifier.INSTANCE).build(); + } diff --git a/src/main/java/nl/knmi/adaguc/security/SecurityConfigurator.java b/src/main/java/nl/knmi/adaguc/security/SecurityConfigurator.java index 41faf30..36215c8 100644 --- a/src/main/java/nl/knmi/adaguc/security/SecurityConfigurator.java +++ b/src/main/java/nl/knmi/adaguc/security/SecurityConfigurator.java @@ -1,10 +1,12 @@ package nl.knmi.adaguc.security; +import java.io.IOException; import java.util.Vector; +import org.springframework.beans.factory.annotation.Autowired; + import lombok.Synchronized; import nl.knmi.adaguc.config.ConfigurationReader; -import nl.knmi.adaguc.services.oauth2.OAuthConfigurator.Oauth2Settings; import nl.knmi.adaguc.tools.Debug; import nl.knmi.adaguc.tools.ElementNotFoundException; import nl.knmi.adaguc.tools.MyXMLParser.XMLElement; @@ -25,7 +27,8 @@ public class SecurityConfigurator implements nl.knmi.adaguc.config.ConfiguratorInterface { - + @Autowired + static ConfigurationReader configurationReader; // private static boolean configDone = false; // // @Override @@ -43,19 +46,20 @@ public class SecurityConfigurator implements nl.knmi.adaguc.config.ConfiguratorI private static String userHeader=null; private static String caCertificate = null; private static String caPrivateKey = null; - + private static String enableSSL = null; + private static String user = null; + public static class ComputeNode { public String url = null; public String name = null; }; static Vector computeNodes = new Vector(); + - static ConfigurationReader configurationReader = new ConfigurationReader (); @Synchronized - @Override - public void doConfig(XMLElement configReader){ + public static void doConfig(XMLElement configReader){ if(configReader.getNodeValue ("adaguc-services.security")==null){ Debug.println("adaguc-services.security is not configured"); @@ -70,6 +74,8 @@ public void doConfig(XMLElement configReader){ computeNodes.clear(); keyAlias=configReader.getNodeValue("adaguc-services.security.keyalias"); userHeader=configReader.getNodeValue("adaguc-services.security.userheader"); + enableSSL=configReader.getNodeValue("adaguc-services.security.enablessl"); + user=configReader.getNodeValue("adaguc-services.security.user"); if (configReader.getNodeValue("adaguc-services.security.tokenapi")!=null){ caCertificate=configReader.getNodeValue("adaguc-services.security.tokenapi.cacertificate"); @@ -98,63 +104,68 @@ public void doConfig(XMLElement configReader){ Debug.println("No remote instances configured"); } - } else { - Debug.println("tokenapi is not enabled"); - } + } } - public static Vector getComputeNodes() throws ElementNotFoundException { - configurationReader.readConfig(); + public static Vector getComputeNodes() throws ElementNotFoundException, IOException { + ConfigurationReader.readConfig(); return computeNodes; } - public static String getCACertificate() throws ElementNotFoundException { + public static String getCACertificate() throws ElementNotFoundException, IOException { Debug.println("getCACertificate"); - configurationReader.readConfig(); + ConfigurationReader.readConfig(); Debug.println("getCACertificate="+caCertificate); return caCertificate; } - public static String getCAPrivateKey() throws ElementNotFoundException { - configurationReader.readConfig(); + public static String getCAPrivateKey() throws ElementNotFoundException, IOException { + ConfigurationReader.readConfig(); return caPrivateKey; } - public static String getTrustStorePassword() throws ElementNotFoundException { - configurationReader.readConfig(); + public static String getTrustStorePassword() throws ElementNotFoundException, IOException { + ConfigurationReader.readConfig(); return trustStorePassword; } - public static String getTrustStore() throws ElementNotFoundException { - configurationReader.readConfig(); + public static String getTrustStore() throws ElementNotFoundException, IOException { + ConfigurationReader.readConfig(); return trustStore; } - public static String getTrustRootsCADirectory() throws ElementNotFoundException { - configurationReader.readConfig(); + public static String getTrustRootsCADirectory() throws ElementNotFoundException, IOException { + ConfigurationReader.readConfig(); return trustRootsCADirectory; } - public static Object getKeyStore() throws ElementNotFoundException { - configurationReader.readConfig(); + public static Object getKeyStore() throws ElementNotFoundException, IOException { + ConfigurationReader.readConfig(); return keyStore; } - public static Object getKeyStorePassword() throws ElementNotFoundException { - configurationReader.readConfig(); + public static Object getKeyStorePassword() throws ElementNotFoundException, IOException { + ConfigurationReader.readConfig(); return keyStorePassword; } - public static Object getKeyStoreType() throws ElementNotFoundException { - configurationReader.readConfig(); + public static Object getKeyStoreType() throws ElementNotFoundException, IOException { + ConfigurationReader.readConfig(); return keyStoreType; } - public static Object getKeyAlias() throws ElementNotFoundException { - configurationReader.readConfig(); + public static Object getKeyAlias() throws ElementNotFoundException, IOException { + ConfigurationReader.readConfig(); return keyAlias; } - public static String getUserHeader() throws ElementNotFoundException { - configurationReader.readConfig(); + public static String getUserHeader() throws ElementNotFoundException, IOException { + ConfigurationReader.readConfig(); return userHeader; } + public static String getEnableSSL() throws ElementNotFoundException, IOException { + ConfigurationReader.readConfig(); + return enableSSL; + } + public static String getUser() throws ElementNotFoundException, IOException { + return user; + } } diff --git a/src/main/java/nl/knmi/adaguc/security/token/TokenManager.java b/src/main/java/nl/knmi/adaguc/security/token/TokenManager.java index 0957643..72df0bc 100644 --- a/src/main/java/nl/knmi/adaguc/security/token/TokenManager.java +++ b/src/main/java/nl/knmi/adaguc/security/token/TokenManager.java @@ -44,10 +44,10 @@ public synchronized static Token getToken(String id) throws IOException, Element } public String getTokenFromPath(String path){ - Pattern pattern = Pattern.compile("[0-9A-Fa-f]{8}-[0-9A-Fa-f]{4}-[4][0-9A-Fa-f]{3}-[89ABab][0-9A-Fa-f]{3}-[0-9A-Fa-f]{12}"); + Pattern pattern = Pattern.compile("\\/[0-9A-Fa-f]{8}-[0-9A-Fa-f]{4}-[4][0-9A-Fa-f]{3}-[89ABab][0-9A-Fa-f]{3}-[0-9A-Fa-f]{12}"); Matcher matcher = pattern.matcher(path); if (matcher.find()) { - return matcher.group(); + return matcher.group().substring(1); } return null; } diff --git a/src/main/java/nl/knmi/adaguc/security/user/User.java b/src/main/java/nl/knmi/adaguc/security/user/User.java index 9d9de8b..fa51d98 100644 --- a/src/main/java/nl/knmi/adaguc/security/user/User.java +++ b/src/main/java/nl/knmi/adaguc/security/user/User.java @@ -1,15 +1,16 @@ package nl.knmi.adaguc.security.user; import java.io.IOException; - +import java.security.PrivateKey; +import java.security.cert.X509Certificate; import lombok.Getter; -import nl.knmi.adaguc.tools.ElementNotFoundException; import nl.knmi.adaguc.config.MainServicesConfigurator; import nl.knmi.adaguc.security.PemX509Tools; import nl.knmi.adaguc.security.PemX509Tools.X509UserCertAndKey; import nl.knmi.adaguc.security.SecurityConfigurator; import nl.knmi.adaguc.tools.Debug; +import nl.knmi.adaguc.tools.ElementNotFoundException; import nl.knmi.adaguc.tools.Tools; public class User { @@ -49,6 +50,14 @@ public User(String _id) throws IOException, ElementNotFoundException { Tools.mksubdirs(homeDir); Tools.mksubdirs(dataDir); Debug.println("User Home Dir: "+homeDir); + try { + X509Certificate cert = PemX509Tools.readCertificateFromPEMFile( this.homeDir + "/cert.crt"); + PrivateKey key = PemX509Tools.readPrivateKeyFromPEM(this.homeDir + "/cert.key"); + this.userCert = (new PemX509Tools()).new X509UserCertAndKey(cert, key); + Debug.println("### Loaded certificates from disk ### for " + this.userId); + } catch (Exception e) { + Debug.errprintln("### No certificates loaded found on disk for " + this.userId + " ###"); + } } /** @@ -75,7 +84,7 @@ private synchronized void createNCResourceFile() } public void setCertificate(X509UserCertAndKey userCert) throws IOException, ElementNotFoundException { /* TODO could optinally write cert to user basket */ - + Debug.println("### setCertificate ### for " + this.userId); PemX509Tools.writeCertificateToPemFile(userCert.getUserSlCertificate(), this.homeDir + "/cert.crt"); PemX509Tools.writePrivateKeyToPemFile(userCert.getPrivateKey(), this.homeDir + "/cert.key"); diff --git a/src/main/java/nl/knmi/adaguc/security/user/UserManager.java b/src/main/java/nl/knmi/adaguc/security/user/UserManager.java index e227b4c..4629f5e 100644 --- a/src/main/java/nl/knmi/adaguc/security/user/UserManager.java +++ b/src/main/java/nl/knmi/adaguc/security/user/UserManager.java @@ -61,7 +61,7 @@ public synchronized static User getUser(AuthenticatorInterface authenticator) th return getUser(authenticator.getClientId()); } - public static String makeGetRequestWithUserFromServletRequest (HttpServletRequest servletRequest, String requestStr) throws ElementNotFoundException, AuthenticationException, IOException, KeyManagementException, UnrecoverableKeyException, InvalidKeyException, NoSuchAlgorithmException, KeyStoreException, CertificateException, NoSuchProviderException, SignatureException, GSSException { + public static String _makeGetRequestWithUserFromServletRequest (HttpServletRequest servletRequest, String requestStr) throws ElementNotFoundException, AuthenticationException, IOException, KeyManagementException, UnrecoverableKeyException, InvalidKeyException, NoSuchAlgorithmException, KeyStoreException, CertificateException, NoSuchProviderException, SignatureException, GSSException { String ts = SecurityConfigurator.getTrustStore(); char [] tsPass = SecurityConfigurator.getTrustStorePassword().toCharArray(); diff --git a/src/main/java/nl/knmi/adaguc/services/adagucserver/ADAGUCConfigurator.java b/src/main/java/nl/knmi/adaguc/services/adagucserver/ADAGUCConfigurator.java index 3c1b32a..4324fc0 100644 --- a/src/main/java/nl/knmi/adaguc/services/adagucserver/ADAGUCConfigurator.java +++ b/src/main/java/nl/knmi/adaguc/services/adagucserver/ADAGUCConfigurator.java @@ -1,6 +1,11 @@ package nl.knmi.adaguc.services.adagucserver; import nl.knmi.adaguc.tools.ElementNotFoundException; + +import java.io.IOException; + +import org.springframework.beans.factory.annotation.Autowired; + import nl.knmi.adaguc.config.ConfigurationReader; import nl.knmi.adaguc.tools.MyXMLParser.XMLElement; @@ -27,23 +32,26 @@ public class ADAGUCConfigurator implements nl.knmi.adaguc.config.ConfiguratorInterface { private static String ADAGUCExecutable="/usr/bin/adagucserver"; - static ConfigurationReader configurationReader = new ConfigurationReader (); + + @Autowired + static ConfigurationReader configurationReader; + private static String[] environmentVariables = { }; - public void doConfig(XMLElement configReader){ + public static void doConfig(XMLElement configReader){ ADAGUCExecutable=configReader.getNodeValue("adaguc-services.adaguc-server.adagucexecutable"); environmentVariables = configReader.getNodeValues("adaguc-services.adaguc-server.export"); } - public static String getADAGUCExecutable() throws ElementNotFoundException { - configurationReader.readConfig(); + public static String getADAGUCExecutable() throws ElementNotFoundException, IOException { + ConfigurationReader.readConfig(); return ADAGUCExecutable; } - public static String[] getADAGUCEnvironment() throws ElementNotFoundException { + public static String[] getADAGUCEnvironment() throws ElementNotFoundException, IOException { - configurationReader.readConfig(); + ConfigurationReader.readConfig(); return environmentVariables; } } \ No newline at end of file diff --git a/src/main/java/nl/knmi/adaguc/services/adagucserver/ADAGUCRequestMapper.java b/src/main/java/nl/knmi/adaguc/services/adagucserver/ADAGUCRequestMapper.java index f452e41..5165992 100644 --- a/src/main/java/nl/knmi/adaguc/services/adagucserver/ADAGUCRequestMapper.java +++ b/src/main/java/nl/knmi/adaguc/services/adagucserver/ADAGUCRequestMapper.java @@ -3,34 +3,22 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -import org.springframework.context.annotation.Bean; -import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; import org.springframework.web.bind.annotation.CrossOrigin; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.RestController; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.SerializationFeature; - import nl.knmi.adaguc.tools.Debug; import nl.knmi.adaguc.tools.JSONResponse; @RestController public class ADAGUCRequestMapper { - @Bean - public MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter() { - ObjectMapper mapper = new ObjectMapper(); - mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, true); - MappingJackson2HttpMessageConverter converter = - new MappingJackson2HttpMessageConverter(mapper); - return converter; - } + @ResponseBody @CrossOrigin @RequestMapping("wms") public void ADAGUCSERVERWMS(HttpServletResponse response, HttpServletRequest request){ - Debug.println("/wms"); + Debug.println("#### SERVLET /wms ####"); try { ADAGUCServer.runADAGUCWMS(request,response,null,null); } catch (Exception e) { diff --git a/src/main/java/nl/knmi/adaguc/services/adagucserver/ADAGUCServer.java b/src/main/java/nl/knmi/adaguc/services/adagucserver/ADAGUCServer.java index 8190606..8f0a7e1 100644 --- a/src/main/java/nl/knmi/adaguc/services/adagucserver/ADAGUCServer.java +++ b/src/main/java/nl/knmi/adaguc/services/adagucserver/ADAGUCServer.java @@ -5,7 +5,6 @@ import java.io.IOException; import java.io.OutputStream; import java.util.ArrayList; -import java.util.Enumeration; import java.util.List; import javax.servlet.ServletException; @@ -19,7 +18,6 @@ import nl.knmi.adaguc.security.user.UserManager; import nl.knmi.adaguc.tools.CGIRunner; import nl.knmi.adaguc.tools.Debug; -import nl.knmi.adaguc.tools.HTTPTools; import nl.knmi.adaguc.tools.Tools; diff --git a/src/main/java/nl/knmi/adaguc/services/auth/AuthRequestMapper.java b/src/main/java/nl/knmi/adaguc/services/auth/AuthRequestMapper.java index e842650..888103a 100644 --- a/src/main/java/nl/knmi/adaguc/services/auth/AuthRequestMapper.java +++ b/src/main/java/nl/knmi/adaguc/services/auth/AuthRequestMapper.java @@ -7,31 +7,18 @@ import org.json.JSONException; import org.json.JSONObject; -import org.springframework.context.annotation.Bean; import org.springframework.http.MediaType; -import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.RestController; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.SerializationFeature; - import nl.knmi.adaguc.security.PemX509Tools; import nl.knmi.adaguc.security.PemX509Tools.X509Info; import nl.knmi.adaguc.tools.JSONResponse; @RestController public class AuthRequestMapper { - @Bean - public MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter() { - ObjectMapper mapper = new ObjectMapper(); - mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, true); - MappingJackson2HttpMessageConverter converter = - new MappingJackson2HttpMessageConverter(mapper); - return converter; - } @ResponseBody @RequestMapping( path="user/getuserinfofromcert", diff --git a/src/main/java/nl/knmi/adaguc/services/autowms/AutoWMSConfigurator.java b/src/main/java/nl/knmi/adaguc/services/autowms/AutoWMSConfigurator.java index 00bade2..3d8f9ad 100644 --- a/src/main/java/nl/knmi/adaguc/services/autowms/AutoWMSConfigurator.java +++ b/src/main/java/nl/knmi/adaguc/services/autowms/AutoWMSConfigurator.java @@ -1,6 +1,11 @@ package nl.knmi.adaguc.services.autowms; import nl.knmi.adaguc.tools.ElementNotFoundException; + +import java.io.IOException; + +import org.springframework.beans.factory.annotation.Autowired; + import nl.knmi.adaguc.config.ConfigurationReader; import nl.knmi.adaguc.tools.MyXMLParser.XMLElement; @@ -16,8 +21,9 @@ public class AutoWMSConfigurator implements nl.knmi.adaguc.config.ConfiguratorIn private static boolean enabled=false; private static String adagucAutoWMS = null; private static String adagucDataset = null; - static ConfigurationReader configurationReader = new ConfigurationReader (); - public void doConfig(XMLElement configReader){ + @Autowired + static ConfigurationReader configurationReader; + public static void doConfig(XMLElement configReader){ if(configReader.getNodeValue("adaguc-services.autowms") == null){ return; } @@ -34,17 +40,17 @@ public void doConfig(XMLElement configReader){ } - public static String getAdagucDataset() throws ElementNotFoundException { - configurationReader.readConfig(); + public static String getAdagucDataset() throws ElementNotFoundException, IOException { + ConfigurationReader.readConfig(); return adagucDataset; } - public static String getAdagucAutoWMS() throws ElementNotFoundException { - configurationReader.readConfig(); + public static String getAdagucAutoWMS() throws ElementNotFoundException, IOException { + ConfigurationReader.readConfig(); return adagucAutoWMS; } - public static boolean getEnabled() throws ElementNotFoundException { - configurationReader.readConfig(); + public static boolean getEnabled() throws ElementNotFoundException, IOException { + ConfigurationReader.readConfig(); return enabled; } } \ No newline at end of file diff --git a/src/main/java/nl/knmi/adaguc/services/autowms/AutoWMSRequestMapper.java b/src/main/java/nl/knmi/adaguc/services/autowms/AutoWMSRequestMapper.java index 7958e28..8106d0f 100644 --- a/src/main/java/nl/knmi/adaguc/services/autowms/AutoWMSRequestMapper.java +++ b/src/main/java/nl/knmi/adaguc/services/autowms/AutoWMSRequestMapper.java @@ -1,9 +1,7 @@ package nl.knmi.adaguc.services.autowms; -import java.io.ByteArrayOutputStream; import java.io.File; import java.io.IOException; -import java.io.OutputStream; import java.net.URLEncoder; import java.util.Arrays; @@ -12,37 +10,20 @@ import org.apache.commons.io.FilenameUtils; import org.json.JSONArray; -import org.json.JSONException; import org.json.JSONObject; -import org.springframework.context.annotation.Bean; -import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; import org.springframework.web.bind.annotation.CrossOrigin; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.RestController; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.SerializationFeature; - -import nl.knmi.adaguc.tools.ElementNotFoundException; import nl.knmi.adaguc.config.MainServicesConfigurator; -import nl.knmi.adaguc.services.adagucserver.ADAGUCServer; import nl.knmi.adaguc.tools.Debug; +import nl.knmi.adaguc.tools.ElementNotFoundException; import nl.knmi.adaguc.tools.HTTPTools; import nl.knmi.adaguc.tools.JSONResponse; -import nl.knmi.adaguc.tools.Tools; @RestController public class AutoWMSRequestMapper { - @Bean - public MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter() { - ObjectMapper mapper = new ObjectMapper(); - mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, true); - MappingJackson2HttpMessageConverter converter = - new MappingJackson2HttpMessageConverter(mapper); - return converter; - } - @ResponseBody @CrossOrigin @RequestMapping("autowms") diff --git a/src/main/java/nl/knmi/adaguc/services/basket/Basket.java b/src/main/java/nl/knmi/adaguc/services/basket/Basket.java index 04318b3..5b5088b 100644 --- a/src/main/java/nl/knmi/adaguc/services/basket/Basket.java +++ b/src/main/java/nl/knmi/adaguc/services/basket/Basket.java @@ -1,6 +1,7 @@ package nl.knmi.adaguc.services.basket; import java.io.File; +import java.io.IOException; import java.time.Instant; import java.time.LocalDateTime; import java.time.ZoneId; @@ -33,21 +34,24 @@ public Basket(String dir, String name, String token) { } catch (ElementNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); } } - private BasketNode listFiles() throws ElementNotFoundException{ + private BasketNode listFiles() throws ElementNotFoundException, IOException{ BasketNode rootBn=new BasketNode(this.name, "root", null, null, null); return this.listFiles(rootBn, userDir); } - public static String GetRemotePrefix(User user) throws ElementNotFoundException { - return MainServicesConfigurator.getServerExternalURL() + "/opendap/"+user.makePosixUserId(user.getUserId()) + "/"; + public static String GetRemotePrefix(User user) throws ElementNotFoundException, IOException { + return MainServicesConfigurator.getServerExternalURL() + "/opendap/"+User.makePosixUserId(user.getUserId()) + "/"; } - private BasketNode listFiles(BasketNode bn, String dir) throws ElementNotFoundException { + private BasketNode listFiles(BasketNode bn, String dir) throws ElementNotFoundException, IOException { String externalURL=MainServicesConfigurator.getServerExternalURL(); File d=new File(dir); if (d.isDirectory()) { diff --git a/src/main/java/nl/knmi/adaguc/services/basket/BasketConfigurator.java b/src/main/java/nl/knmi/adaguc/services/basket/BasketConfigurator.java index a337353..b644302 100644 --- a/src/main/java/nl/knmi/adaguc/services/basket/BasketConfigurator.java +++ b/src/main/java/nl/knmi/adaguc/services/basket/BasketConfigurator.java @@ -1,14 +1,19 @@ package nl.knmi.adaguc.services.basket; import nl.knmi.adaguc.tools.ElementNotFoundException; + +import java.io.IOException; + +import org.springframework.beans.factory.annotation.Autowired; + import nl.knmi.adaguc.config.ConfigurationReader; import nl.knmi.adaguc.tools.MyXMLParser.XMLElement; public class BasketConfigurator implements nl.knmi.adaguc.config.ConfiguratorInterface{ private static boolean enabled=false; - static ConfigurationReader configurationReader = new ConfigurationReader (); - @Override - public void doConfig(XMLElement configReader) throws ElementNotFoundException { + @Autowired + static ConfigurationReader configurationReader; + public static void doConfig(XMLElement configReader) throws ElementNotFoundException { if(configReader.getNodeValue("adaguc-services.basket") == null){ return; } @@ -21,8 +26,8 @@ public void doConfig(XMLElement configReader) throws ElementNotFoundException { } } - public static boolean getEnabled() throws ElementNotFoundException { - configurationReader.readConfig(); + public static boolean getEnabled() throws ElementNotFoundException, IOException { + ConfigurationReader.readConfig(); return enabled; } diff --git a/src/main/java/nl/knmi/adaguc/services/basket/BasketNode.java b/src/main/java/nl/knmi/adaguc/services/basket/BasketNode.java index 3bf89b1..be9f2ba 100644 --- a/src/main/java/nl/knmi/adaguc/services/basket/BasketNode.java +++ b/src/main/java/nl/knmi/adaguc/services/basket/BasketNode.java @@ -1,7 +1,6 @@ package nl.knmi.adaguc.services.basket; import java.time.LocalDateTime; -import java.time.LocalTime; import java.util.ArrayList; import java.util.List; diff --git a/src/main/java/nl/knmi/adaguc/services/basket/BasketRequestMapper.java b/src/main/java/nl/knmi/adaguc/services/basket/BasketRequestMapper.java index bf30087..9c1f5eb 100644 --- a/src/main/java/nl/knmi/adaguc/services/basket/BasketRequestMapper.java +++ b/src/main/java/nl/knmi/adaguc/services/basket/BasketRequestMapper.java @@ -2,28 +2,11 @@ import java.io.File; import java.io.IOException; -import java.security.InvalidKeyException; -import java.security.KeyManagementException; -import java.security.KeyStoreException; -import java.security.NoSuchAlgorithmException; -import java.security.NoSuchProviderException; -import java.security.SignatureException; -import java.security.UnrecoverableKeyException; -import java.security.cert.CertificateException; -import java.util.Vector; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -import org.apache.http.client.methods.CloseableHttpResponse; -import org.apache.http.client.methods.HttpGet; -import org.apache.http.impl.client.CloseableHttpClient; -import org.apache.http.util.EntityUtils; -import org.ietf.jgss.GSSException; import org.json.JSONObject; -import org.springframework.context.annotation.Bean; -import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; -import org.springframework.security.core.AuthenticationException; import org.springframework.web.bind.annotation.CrossOrigin; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; @@ -38,31 +21,16 @@ import nl.knmi.adaguc.security.AuthenticatorFactory; import nl.knmi.adaguc.security.AuthenticatorInterface; -import nl.knmi.adaguc.security.PemX509Tools; -import nl.knmi.adaguc.security.SecurityConfigurator; -import nl.knmi.adaguc.security.PemX509Tools.X509UserCertAndKey; -import nl.knmi.adaguc.security.SecurityConfigurator.ComputeNode; -import nl.knmi.adaguc.security.user.User; import nl.knmi.adaguc.security.user.UserManager; import nl.knmi.adaguc.tools.Debug; -import nl.knmi.adaguc.tools.ElementNotFoundException; import nl.knmi.adaguc.tools.HTTPTools; import nl.knmi.adaguc.tools.JSONResponse; +@SuppressWarnings("deprecation") @RestController @RequestMapping("basket") @CrossOrigin public class BasketRequestMapper { - @Bean - public MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter() { - ObjectMapper mapper = new ObjectMapper(); - mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, true); - MappingJackson2HttpMessageConverter converter = - new MappingJackson2HttpMessageConverter(mapper); - return converter; - } - - @ResponseBody @RequestMapping("/list") public void listBasket(HttpServletResponse response, HttpServletRequest request) throws IOException{ diff --git a/src/main/java/nl/knmi/adaguc/services/datasetcatalog/DatasetCatalogConfigurator.java b/src/main/java/nl/knmi/adaguc/services/datasetcatalog/DatasetCatalogConfigurator.java index b6e4e18..6ea079e 100644 --- a/src/main/java/nl/knmi/adaguc/services/datasetcatalog/DatasetCatalogConfigurator.java +++ b/src/main/java/nl/knmi/adaguc/services/datasetcatalog/DatasetCatalogConfigurator.java @@ -1,15 +1,20 @@ package nl.knmi.adaguc.services.datasetcatalog; import nl.knmi.adaguc.tools.ElementNotFoundException; + +import java.io.IOException; + +import org.springframework.beans.factory.annotation.Autowired; + import nl.knmi.adaguc.config.ConfigurationReader; import nl.knmi.adaguc.tools.MyXMLParser.XMLElement; public class DatasetCatalogConfigurator implements nl.knmi.adaguc.config.ConfiguratorInterface{ private static boolean enabled=false; private static String catalogPath=null; - static ConfigurationReader configurationReader = new ConfigurationReader (); - @Override - public void doConfig(XMLElement configReader) throws ElementNotFoundException { + @Autowired + static ConfigurationReader configurationReader; + public static void doConfig(XMLElement configReader) throws ElementNotFoundException { if(configReader.getNodeValue("adaguc-services.basket") == null){ return; } @@ -26,13 +31,13 @@ public void doConfig(XMLElement configReader) throws ElementNotFoundException { } } - public static boolean getEnabled() throws ElementNotFoundException { - configurationReader.readConfig(); + public static boolean getEnabled() throws ElementNotFoundException , IOException{ + ConfigurationReader.readConfig(); return enabled; } - public static String getCatalogPath() throws ElementNotFoundException { - configurationReader.readConfig(); + public static String getCatalogPath() throws ElementNotFoundException, IOException { + ConfigurationReader.readConfig(); return catalogPath; } } diff --git a/src/main/java/nl/knmi/adaguc/services/datasetcatalog/DatasetCatalogRequestMapper.java b/src/main/java/nl/knmi/adaguc/services/datasetcatalog/DatasetCatalogRequestMapper.java index 602ecd1..f131ca7 100644 --- a/src/main/java/nl/knmi/adaguc/services/datasetcatalog/DatasetCatalogRequestMapper.java +++ b/src/main/java/nl/knmi/adaguc/services/datasetcatalog/DatasetCatalogRequestMapper.java @@ -9,8 +9,6 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -import org.springframework.context.annotation.Bean; -import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; import org.springframework.web.bind.annotation.CrossOrigin; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; @@ -20,25 +18,18 @@ import com.fasterxml.jackson.databind.SerializationFeature; import com.fasterxml.jackson.datatype.jsr310.JSR310Module; -import nl.knmi.adaguc.tools.ElementNotFoundException; import nl.knmi.adaguc.services.datasetcatalog.DatasetDescription.DataOrganisation; import nl.knmi.adaguc.services.datasetcatalog.DatasetDescription.DataSource; import nl.knmi.adaguc.tools.Debug; +import nl.knmi.adaguc.tools.ElementNotFoundException; import nl.knmi.adaguc.tools.JSONResponse; +@SuppressWarnings("deprecation") @RestController @RequestMapping("catalog") @CrossOrigin public class DatasetCatalogRequestMapper { - @Bean - public MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter() { - ObjectMapper mapper = new ObjectMapper(); - mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, true); - MappingJackson2HttpMessageConverter converter = - new MappingJackson2HttpMessageConverter(mapper); - return converter; - } @ResponseBody @RequestMapping("/list") diff --git a/src/main/java/nl/knmi/adaguc/services/datasetcatalog/DatasetDescription.java b/src/main/java/nl/knmi/adaguc/services/datasetcatalog/DatasetDescription.java index 861e9e7..76e882f 100644 --- a/src/main/java/nl/knmi/adaguc/services/datasetcatalog/DatasetDescription.java +++ b/src/main/java/nl/knmi/adaguc/services/datasetcatalog/DatasetDescription.java @@ -18,6 +18,7 @@ import lombok.Getter; import lombok.Setter; +@SuppressWarnings("deprecation") @Setter @Getter public class DatasetDescription implements Serializable{ diff --git a/src/main/java/nl/knmi/adaguc/services/esgfsearch/ESGFSearchConfigurator.java b/src/main/java/nl/knmi/adaguc/services/esgfsearch/ESGFSearchConfigurator.java index 1319595..b604ac7 100644 --- a/src/main/java/nl/knmi/adaguc/services/esgfsearch/ESGFSearchConfigurator.java +++ b/src/main/java/nl/knmi/adaguc/services/esgfsearch/ESGFSearchConfigurator.java @@ -1,5 +1,9 @@ package nl.knmi.adaguc.services.esgfsearch; +import java.io.IOException; + +import org.springframework.beans.factory.annotation.Autowired; + import lombok.Synchronized; import nl.knmi.adaguc.config.ConfigurationReader; import nl.knmi.adaguc.tools.ElementNotFoundException; @@ -24,11 +28,11 @@ public class ESGFSearchConfigurator implements nl.knmi.adaguc.config.Configurato private static String cacheLocation="/tmp/"; private static boolean enabled = false; - static ConfigurationReader configurationReader = new ConfigurationReader (); + @Autowired + static ConfigurationReader configurationReader; @Synchronized - @Override - public void doConfig(XMLElement configReader){ + public static void doConfig(XMLElement configReader){ if(configReader.getNodeValue ("adaguc-services.esgfsearch")==null){ return; } @@ -36,16 +40,16 @@ public void doConfig(XMLElement configReader){ enabled="true".equals(configReader.getNodeValue("adaguc-services.esgfsearch.enabled")); cacheLocation=configReader.getNodeValue("adaguc-services.esgfsearch.cachelocation"); } - public static String getEsgfSearchURL() throws ElementNotFoundException { - configurationReader.readConfig(); + public static String getEsgfSearchURL() throws ElementNotFoundException, IOException { + ConfigurationReader.readConfig(); return esgfSearchURL; } - public static boolean getEnabled() throws ElementNotFoundException { - configurationReader.readConfig(); + public static boolean getEnabled() throws ElementNotFoundException, IOException { + ConfigurationReader.readConfig(); return enabled; } - public static String getCacheLocation() throws ElementNotFoundException { - configurationReader.readConfig(); + public static String getCacheLocation() throws ElementNotFoundException, IOException { + ConfigurationReader.readConfig(); return cacheLocation; } diff --git a/src/main/java/nl/knmi/adaguc/services/esgfsearch/ESGFSearchRequestMapper.java b/src/main/java/nl/knmi/adaguc/services/esgfsearch/ESGFSearchRequestMapper.java index 4058bcc..31bdd88 100644 --- a/src/main/java/nl/knmi/adaguc/services/esgfsearch/ESGFSearchRequestMapper.java +++ b/src/main/java/nl/knmi/adaguc/services/esgfsearch/ESGFSearchRequestMapper.java @@ -9,16 +9,11 @@ import org.json.JSONObject; import org.springframework.beans.factory.DisposableBean; -import org.springframework.context.annotation.Bean; -import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; import org.springframework.web.bind.annotation.CrossOrigin; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.RestController; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.SerializationFeature; - import nl.knmi.adaguc.config.MainServicesConfigurator; import nl.knmi.adaguc.tools.Debug; import nl.knmi.adaguc.tools.ElementNotFoundException; @@ -44,17 +39,6 @@ public void destroy() { } - - @Bean - public MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter() { - ObjectMapper mapper = new ObjectMapper(); - mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, true); - MappingJackson2HttpMessageConverter converter = - new MappingJackson2HttpMessageConverter(mapper); - return converter; - } - - @ResponseBody @RequestMapping("/search") public void search(HttpServletResponse response, HttpServletRequest request) throws IOException{ @@ -119,7 +103,7 @@ public void getvariables(HttpServletResponse response, HttpServletRequest reques - public static synchronized Search getESGFSearchInstance() throws ElementNotFoundException { + public static synchronized Search getESGFSearchInstance() throws ElementNotFoundException, IOException { if(esgfSearch!=null)return esgfSearch; Debug.println("Creating new ESGF search instance with endpoint "+ESGFSearchConfigurator.getEsgfSearchURL()); diff --git a/src/main/java/nl/knmi/adaguc/services/joblist/JobListConfigurator.java b/src/main/java/nl/knmi/adaguc/services/joblist/JobListConfigurator.java index 6a46708..3317b0a 100644 --- a/src/main/java/nl/knmi/adaguc/services/joblist/JobListConfigurator.java +++ b/src/main/java/nl/knmi/adaguc/services/joblist/JobListConfigurator.java @@ -1,14 +1,19 @@ package nl.knmi.adaguc.services.joblist; import nl.knmi.adaguc.tools.ElementNotFoundException; + +import java.io.IOException; + +import org.springframework.beans.factory.annotation.Autowired; + import nl.knmi.adaguc.config.ConfigurationReader; import nl.knmi.adaguc.tools.MyXMLParser.XMLElement; public class JobListConfigurator implements nl.knmi.adaguc.config.ConfiguratorInterface{ private static boolean enabled=false; - static ConfigurationReader configurationReader = new ConfigurationReader (); - @Override - public void doConfig(XMLElement configReader) throws ElementNotFoundException { + @Autowired + static ConfigurationReader configurationReader; + public static void doConfig(XMLElement configReader) throws ElementNotFoundException { if(configReader.getNodeValue("adaguc-services.joblist") == null){ return; } @@ -21,8 +26,8 @@ public void doConfig(XMLElement configReader) throws ElementNotFoundException { } } - public static boolean getEnabled() throws ElementNotFoundException { - configurationReader.readConfig(); + public static boolean getEnabled() throws ElementNotFoundException, IOException { + ConfigurationReader.readConfig(); return enabled; } diff --git a/src/main/java/nl/knmi/adaguc/services/joblist/JobListRequestMapper.java b/src/main/java/nl/knmi/adaguc/services/joblist/JobListRequestMapper.java index 3ab9032..95c6b77 100644 --- a/src/main/java/nl/knmi/adaguc/services/joblist/JobListRequestMapper.java +++ b/src/main/java/nl/knmi/adaguc/services/joblist/JobListRequestMapper.java @@ -3,9 +3,9 @@ import java.io.File; import java.io.IOException; import java.net.URLDecoder; -import java.net.URLEncoder; import java.nio.file.Files; import java.nio.file.Paths; +import java.util.Arrays; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @@ -13,8 +13,6 @@ import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; -import org.springframework.context.annotation.Bean; -import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; import org.springframework.web.bind.annotation.CrossOrigin; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; @@ -25,33 +23,24 @@ import com.fasterxml.jackson.databind.SerializationFeature; import com.fasterxml.jackson.datatype.jsr310.JSR310Module; -import nl.knmi.adaguc.tools.ElementNotFoundException; import nl.knmi.adaguc.security.AuthenticatorFactory; import nl.knmi.adaguc.security.AuthenticatorInterface; import nl.knmi.adaguc.security.user.UserManager; -import nl.knmi.adaguc.services.basket.BasketConfigurator; -import nl.knmi.adaguc.services.pywpsserver.PyWPSConfigurator; import nl.knmi.adaguc.services.pywpsserver.PyWPSServer; +import nl.knmi.adaguc.services.xml2json.ServiceHelperRequestMapper; import nl.knmi.adaguc.tools.Debug; +import nl.knmi.adaguc.tools.ElementNotFoundException; import nl.knmi.adaguc.tools.HTTPTools; +import nl.knmi.adaguc.tools.HTTPTools.InvalidHTTPKeyValueTokensException; import nl.knmi.adaguc.tools.InvalidTokenException; import nl.knmi.adaguc.tools.JSONResponse; -import nl.knmi.adaguc.tools.MyXMLParser; -import nl.knmi.adaguc.tools.MyXMLParser.Options; import nl.knmi.adaguc.tools.Tools; -import nl.knmi.adaguc.tools.HTTPTools.InvalidHTTPKeyValueTokensException; +@SuppressWarnings("deprecation") @RestController @RequestMapping("joblist") @CrossOrigin public class JobListRequestMapper { - @Bean - public MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter() { - ObjectMapper mapper = new ObjectMapper(); - mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, true); - MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter(mapper); - return converter; - } private static JSONObject NewStatusLocation(String queryString, String statusLocation) throws InvalidTokenException, ElementNotFoundException, InvalidHTTPKeyValueTokensException, IOException { @@ -86,8 +75,11 @@ public void removeFromJobList(HttpServletResponse response, HttpServletRequest r AuthenticatorInterface authenticator = AuthenticatorFactory.getAuthenticator(request); String userDataDir = UserManager.getUser(authenticator).getDataDir(); String cleanPath = Tools.makeCleanPath(job); - String wpsSettingsName = cleanPath.replace(".xml", ".wpssettings"); + String wpsSettingsName = cleanPath.replace(".xml", ".ready.json"); File f = new File(userDataDir + "/WPS_Settings/" + wpsSettingsName); + f.delete(); + wpsSettingsName = cleanPath.replace(".xml", ".execute.json"); + f = new File(userDataDir + "/WPS_Settings/" + wpsSettingsName); Debug.println("removing:" + f.getPath()); if (f.delete()) { jsonResponse.setMessage(new JSONObject().put("message", "jobfile deleted")); @@ -115,7 +107,7 @@ public static void saveExecuteResponseToJob(String queryString, String executeRe // Tools.mksubdirs(userDataDir+"/WPS_Settings/"); String statusLocation=data.getString("statuslocation"); - String baseName = statusLocation.substring(statusLocation.lastIndexOf("/")).replace(".xml", ".wpssettings"); + String baseName = statusLocation.substring(statusLocation.lastIndexOf("/")).replace(".xml", ".execute.json"); AuthenticatorInterface authenticator = AuthenticatorFactory.getAuthenticator(request); String userDataDir = UserManager.getUser(authenticator).getDataDir(); String wpsSettingsFile = userDataDir+"/WPS_Settings/"; @@ -157,16 +149,29 @@ public void listJobs(HttpServletResponse response, HttpServletRequest request) t for (String fn : filesIndir) { File f = new File(dir + "/" + fn); // Debug.println("fn:"+fn+" "+f.isFile()+" ; + String readyFile = fn.replace("execute.json", "ready.json"); + // "+fn.endsWith("settings")); - if (f.isFile() && fn.endsWith("settings")) { + if (f.isFile() && fn.endsWith("execute.json")) { + + // if status==Accepted + if (Arrays.asList(filesIndir).contains(readyFile)) { + String fileString = new String(Files.readAllBytes(Paths.get(new File(dir + "/" + readyFile).getAbsolutePath()))); + // Debug.println("found: "+fn+" "+fileString.length()); + JSONObject job = new JSONObject(fileString); + jobArray.put(job); + continue; + } String fileString = new String(Files.readAllBytes(Paths.get(f.getAbsolutePath()))); // Debug.println("found: "+fn+" "+fileString.length()); JSONObject job = new JSONObject(fileString); - // if status==Accepted - String status = null; + JSONObject wpsPostData = null; try { + /* Extract the status */ status = job.getString("wpsstatus"); + /* Extract the orginal settings with which the process was started */ + wpsPostData = job.getJSONObject("wpspostdata"); } catch (JSONException e) { } if (status != null) { @@ -179,25 +184,40 @@ public void listJobs(HttpServletResponse response, HttpServletRequest request) t URLDecoder.decode(job.getString("querystring"), "utf-8"); } catch (Exception e) { } + Debug.println("Querying " + statusLocation); JSONObject newJobStatus = NewStatusLocation(queryString, statusLocation); if(newJobStatus!=null && newJobStatus.length() !=0) { - - // Debug.println("newJobStatus: " + newJobStatus.getString("percentage")); + /* Put the wps post data (the input settings with which the wps was run) back into the new object */ + if (wpsPostData!=null) { + newJobStatus.put("wpspostdata", wpsPostData); + } + try { + Debug.println("Joblist - started copyStatusLocationElements"); + JSONObject output = ServiceHelperRequestMapper.copyStatusLocationElements(request, HTTPTools.makeHTTPGetRequest(statusLocation)).toJSONObject(null); + if (output!=null) { + newJobStatus.put("output", output); + Debug.println("Joblist - finished copyStatusLocationElements"); + Debug.println(output.toString()); + } else { + Debug.errprintln("Unable to copyStatusLocationElements"); + } + }catch(Exception e) { + Debug.printStackTrace(e); + } String newWPSStatus = newJobStatus.getString("wpsstatus"); -// Debug.println("st:" + newWPSStatus + "<===" + status); + /* Save the new ready.json file */ if (newWPSStatus!=null && status!=null && !newWPSStatus.equals(status) && newWPSStatus.equals("PROCESSSUCCEEDED")) { - Debug.println("Do something"); - } - if (status.equalsIgnoreCase("PROCESSSTARTED") || ((newJobStatus != null) - && !status.equals(newJobStatus.getString("wpsstatus")))) { - // Tools.mksubdirs(userDataDir+"/WPS_Settings/"); String baseName = statusLocation.substring(statusLocation.lastIndexOf("/")) - .replace(".xml", ".wpssettings"); + .replace(".xml", ".ready.json"); String wpsSettingsFile = userDataDir + "/WPS_Settings/"; Tools.mksubdirs(wpsSettingsFile); wpsSettingsFile += baseName; Tools.writeFile(wpsSettingsFile, newJobStatus.toString()); - Debug.println("re-written " + wpsSettingsFile); + Debug.println("Written " + wpsSettingsFile); + } + /* Update the job information with info retrieved from the statusLocation */ + if (status.equalsIgnoreCase("PROCESSSTARTED") || ((newJobStatus != null) + && !status.equals(newJobStatus.getString("wpsstatus")))) { job = newJobStatus; } } @@ -219,4 +239,4 @@ public void listJobs(HttpServletResponse response, HttpServletRequest request) t jsonResponse.print(response); } -} +} \ No newline at end of file diff --git a/src/main/java/nl/knmi/adaguc/services/oauth2/OAuth2Handler.java b/src/main/java/nl/knmi/adaguc/services/oauth2/OAuth2Handler.java index 6dc9538..724cd97 100644 --- a/src/main/java/nl/knmi/adaguc/services/oauth2/OAuth2Handler.java +++ b/src/main/java/nl/knmi/adaguc/services/oauth2/OAuth2Handler.java @@ -218,7 +218,7 @@ public static class UserInfo { * @param response * @throws ElementNotFoundException */ - public static void doGet(HttpServletRequest request, HttpServletResponse response) throws ElementNotFoundException { + public static void doGet(HttpServletRequest request, HttpServletResponse response) throws ElementNotFoundException, IOException { // Check if we are dealing with getting JSON request for building up the // login form @@ -814,7 +814,7 @@ static boolean RSASSA_PKCS1_V1_5_VERIFY(String modulus_n, String exponent_e, Str * @return * @throws ElementNotFoundException */ - private static UserInfo getIdentifierFromJWTPayload(String JWT) throws ElementNotFoundException { + private static UserInfo getIdentifierFromJWTPayload(String JWT) throws ElementNotFoundException, IOException{ JSONObject id_token_json = null; try { id_token_json = (JSONObject) new JSONTokener(JWT).nextValue(); @@ -889,7 +889,7 @@ private static UserInfo getIdentifierFromJWTPayload(String JWT) throws ElementNo * @throws ElementNotFoundException */ private static void makeForm(HttpServletRequest request, HttpServletResponse response) - throws ElementNotFoundException { + throws ElementNotFoundException, IOException { JSONResponse jsonResponse = new JSONResponse(request); JSONObject form = new JSONObject(); diff --git a/src/main/java/nl/knmi/adaguc/services/oauth2/OAuth2RequestMapper.java b/src/main/java/nl/knmi/adaguc/services/oauth2/OAuth2RequestMapper.java index 7553f14..b5266cf 100644 --- a/src/main/java/nl/knmi/adaguc/services/oauth2/OAuth2RequestMapper.java +++ b/src/main/java/nl/knmi/adaguc/services/oauth2/OAuth2RequestMapper.java @@ -9,35 +9,23 @@ import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; -import org.springframework.context.annotation.Bean; -import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; import org.springframework.web.bind.annotation.CrossOrigin; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.RestController; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.SerializationFeature; - import nl.knmi.adaguc.config.MainServicesConfigurator; import nl.knmi.adaguc.security.SecurityConfigurator; import nl.knmi.adaguc.security.SecurityConfigurator.ComputeNode; +import nl.knmi.adaguc.tools.Debug; import nl.knmi.adaguc.tools.ElementNotFoundException; import nl.knmi.adaguc.tools.JSONResponse; @RestController public class OAuth2RequestMapper { - @Bean - public MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter() { - ObjectMapper mapper = new ObjectMapper(); - mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, true); - MappingJackson2HttpMessageConverter converter = - new MappingJackson2HttpMessageConverter(mapper); - return converter; - } - + @CrossOrigin @ResponseBody @RequestMapping( @@ -113,6 +101,19 @@ private boolean isIdUnknown(String id) { ) public void getId(HttpServletResponse response, HttpServletRequest request) throws JSONException, IOException, ElementNotFoundException{ JSONResponse jsonResponse = new JSONResponse(request); + Debug.println("getid"); + try{ + String userName = SecurityConfigurator.getUser(); + if (userName != null) { + Debug.println("Setting user to " + userName); + request.getSession().setAttribute("user_identifier",userName); + request.getSession().setAttribute("services_access_token",userName); + request.getSession().setAttribute("emailaddress",userName); + } + }catch(Exception e){ + Debug.println("No user name"); + } + String id = (String) request.getSession().getAttribute("user_identifier"); String servicesAccessToken = (String) request.getSession().getAttribute("services_access_token"); diff --git a/src/main/java/nl/knmi/adaguc/services/oauth2/OAuthConfigurator.java b/src/main/java/nl/knmi/adaguc/services/oauth2/OAuthConfigurator.java index 0bf0c24..0f5b26a 100644 --- a/src/main/java/nl/knmi/adaguc/services/oauth2/OAuthConfigurator.java +++ b/src/main/java/nl/knmi/adaguc/services/oauth2/OAuthConfigurator.java @@ -1,7 +1,10 @@ package nl.knmi.adaguc.services.oauth2; +import java.io.IOException; import java.util.Vector; +import org.springframework.beans.factory.annotation.Autowired; + import nl.knmi.adaguc.tools.ElementNotFoundException; import nl.knmi.adaguc.config.ConfigurationReader; import nl.knmi.adaguc.tools.Debug; @@ -10,109 +13,111 @@ public class OAuthConfigurator implements nl.knmi.adaguc.config.ConfiguratorInterface { - static ConfigurationReader configurationReader = new ConfigurationReader (); - public static class Oauth2Settings{ - // For building the web page: - public String description = null; - public String logo = null; - public String registerlink= null; - - //For server requests: - public String OAuthAuthLoc = null; - public String OAuthTokenLoc = null; - public String OAuthClientId = null; - public String OAuthClientScope = null; - - //Secret thing - public String OAuthClientSecret = null; - - - - public String id = null; - public String oauthCallbackURL = null; - public String getConfig() { - String config = "OAuthAuthLoc: "+OAuthAuthLoc+"\n"; - config += "OAuthTokenLoc: "+OAuthTokenLoc+"\n"; - config += "OAuthClientId: "+OAuthClientId+"\n"; - config += "OAuthClientScope: "+OAuthClientScope+"\n"; - return config; - } - } - - static Vector oauth2Providers = new Vector(); - - private static Oauth2Settings _getOauthSetting(String id){ - for(int j=0;j _getProviders(){ - Vector providers = new Vector(); - for(int j=0;j oauth2Providers = new Vector(); + + private static Oauth2Settings _getOauthSetting(String id){ + Debug.println("oauth2Providers.size = " + oauth2Providers.size()); + for(int j=0;j _getProviders(){ + Vector providers = new Vector(); + for(int j=0;j providers = null; - try { - providers = configReader.get("adaguc-services").get("oauth2").getList("provider"); - } catch (Exception e1) { - e1.printStackTrace(); - } - if(providers == null){ - Debug.errprintln("No Oauth2 providers configured"); - return; - } - for(int j=0;j getProviders() throws ElementNotFoundException { - configurationReader.readConfig(); - - return _getProviders(); - } + return providers; + } + + + public static void doConfig(XMLElement configReader){ + synchronized(oauth2Providers){ + oauth2Providers.clear(); + try { + configReader.get("adaguc-services").get("oauth2") ; + } catch (Exception e2) { + Debug.println("adaguc-services.oauth2 not configured"); + return; + } + + + Vector providers = null; + try { + providers = configReader.get("adaguc-services").get("oauth2").getList("provider"); + } catch (Exception e1) { + e1.printStackTrace(); + } + if(providers == null){ + Debug.errprintln("No Oauth2 providers configured"); + return; + } + for(int j=0;j getProviders() throws ElementNotFoundException, IOException { + ConfigurationReader.readConfig(); + + return _getProviders(); + } } \ No newline at end of file diff --git a/src/main/java/nl/knmi/adaguc/services/pywpsserver/PyWPSConfigurator.java b/src/main/java/nl/knmi/adaguc/services/pywpsserver/PyWPSConfigurator.java index 3a324cf..e080d4e 100644 --- a/src/main/java/nl/knmi/adaguc/services/pywpsserver/PyWPSConfigurator.java +++ b/src/main/java/nl/knmi/adaguc/services/pywpsserver/PyWPSConfigurator.java @@ -1,9 +1,12 @@ package nl.knmi.adaguc.services.pywpsserver; -import nl.knmi.adaguc.tools.ElementNotFoundException; +import java.io.IOException; + +import org.springframework.beans.factory.annotation.Autowired; + import nl.knmi.adaguc.config.ConfigurationReader; import nl.knmi.adaguc.config.ConfiguratorInterface; -import nl.knmi.adaguc.tools.Debug; +import nl.knmi.adaguc.tools.ElementNotFoundException; import nl.knmi.adaguc.tools.MyXMLParser.XMLElement; /** @@ -35,8 +38,9 @@ public class PyWPSConfigurator implements ConfiguratorInterface { private static String TempDir = null; private static String[] environmentVariables = { }; - static ConfigurationReader configurationReader = new ConfigurationReader (); - public void doConfig(XMLElement configReader) throws ElementNotFoundException { + @Autowired + static ConfigurationReader configurationReader; + public static void doConfig(XMLElement configReader) throws ElementNotFoundException { if(configReader.getNodeValue ("adaguc-services.pywps-server")==null){ // Debug.println("adaguc-services.pywps-server is not configured"); return; @@ -49,37 +53,37 @@ public void doConfig(XMLElement configReader) throws ElementNotFoundException { environmentVariables = configReader.getNodeValues("adaguc-services.pywps-server.export"); } - public static String getPyWPSExecutable() throws ElementNotFoundException { - configurationReader.readConfig(); + public static String getPyWPSExecutable() throws ElementNotFoundException, IOException { + ConfigurationReader.readConfig(); return PyWPSExecutable; } - public static String getTempDir() throws ElementNotFoundException { - configurationReader.readConfig(); + public static String getTempDir() throws ElementNotFoundException, IOException { + ConfigurationReader.readConfig(); return TempDir; } - public static String getPyWPSConfigTemplate() throws ElementNotFoundException { - configurationReader.readConfig(); + public static String getPyWPSConfigTemplate() throws ElementNotFoundException, IOException { + ConfigurationReader.readConfig(); return PyWPSConfigTemplate; } - public static String[] getPyWPSEnvironment() throws ElementNotFoundException { - configurationReader.readConfig(); + public static String[] getPyWPSEnvironment() throws ElementNotFoundException, IOException { + ConfigurationReader.readConfig(); return environmentVariables; } - public static String getPyWPSOutputDir() throws ElementNotFoundException { - configurationReader.readConfig(); + public static String getPyWPSOutputDir() throws ElementNotFoundException, IOException { + ConfigurationReader.readConfig(); return PyWPSOutputDir; } - public static String getPyWPSProcessesDir() throws ElementNotFoundException { - configurationReader.readConfig(); + public static String getPyWPSProcessesDir() throws ElementNotFoundException, IOException { + ConfigurationReader.readConfig(); return PyWPSProcessesDir; } - public static String getPyWPSConfig() throws ElementNotFoundException { + public static String getPyWPSConfig() throws ElementNotFoundException, IOException { String pyWPSConfigTemplate = PyWPSConfigurator.getPyWPSConfigTemplate(); return pyWPSConfigTemplate + "adaguc-services-pywps-config.cfg"; } diff --git a/src/main/java/nl/knmi/adaguc/services/pywpsserver/PyWPSRequestMapper.java b/src/main/java/nl/knmi/adaguc/services/pywpsserver/PyWPSRequestMapper.java index 82eb054..15164ff 100644 --- a/src/main/java/nl/knmi/adaguc/services/pywpsserver/PyWPSRequestMapper.java +++ b/src/main/java/nl/knmi/adaguc/services/pywpsserver/PyWPSRequestMapper.java @@ -5,31 +5,19 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -import org.springframework.context.annotation.Bean; -import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; import org.springframework.security.core.AuthenticationException; import org.springframework.web.bind.annotation.CrossOrigin; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.RestController; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.SerializationFeature; - -import nl.knmi.adaguc.tools.ElementNotFoundException; import nl.knmi.adaguc.tools.Debug; +import nl.knmi.adaguc.tools.ElementNotFoundException; import nl.knmi.adaguc.tools.JSONResponse; @RestController public class PyWPSRequestMapper { - @Bean - public MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter() { - ObjectMapper mapper = new ObjectMapper(); - mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, true); - MappingJackson2HttpMessageConverter converter = - new MappingJackson2HttpMessageConverter(mapper); - return converter; - } + @ResponseBody @CrossOrigin @RequestMapping("wps") diff --git a/src/main/java/nl/knmi/adaguc/services/pywpsserver/PyWPSServer.java b/src/main/java/nl/knmi/adaguc/services/pywpsserver/PyWPSServer.java index 133f3a5..44b7109 100644 --- a/src/main/java/nl/knmi/adaguc/services/pywpsserver/PyWPSServer.java +++ b/src/main/java/nl/knmi/adaguc/services/pywpsserver/PyWPSServer.java @@ -192,32 +192,33 @@ public static JSONObject statusLocationDataAsJSONElementToWPSStatusObject(String try { status=rootElement.get("wps:ExecuteResponse").get("wps:Status").get("wps:ProcessAccepted").getValue(); wpsStatus=WPSStatus.PROCESSACCEPTED; - } catch (Exception e) {Debug.println("Not ACCEPTED");}; + } catch (Exception e) {}; if (wpsStatus==null) { try { status=rootElement.get("wps:ExecuteResponse").get("wps:Status").get("wps:ProcessStarted").getValue(); wpsStatus=WPSStatus.PROCESSSTARTED; - } catch (Exception e) {Debug.println("Not STARTED");} + } catch (Exception e) {} } if (wpsStatus==null) { try { status=rootElement.get("wps:ExecuteResponse").get("wps:Status").get("wps:ProcessFailed").getValue(); wpsStatus=WPSStatus.PROCESSFAILED; - } catch (Exception e) {Debug.println("Not FAILED");} + } catch (Exception e) {} } if (wpsStatus==null) { try { status=rootElement.get("wps:ExecuteResponse").get("wps:Status").get("wps:ProcessPaused").getValue(); wpsStatus=WPSStatus.PROCESSPAUSED; - } catch (Exception e) {Debug.println("Not PAUSED");} + } catch (Exception e) {} } if (wpsStatus==null) { try { status=rootElement.get("wps:ExecuteResponse").get("wps:Status").get("wps:ProcessSucceeded").getValue(); wpsStatus=WPSStatus.PROCESSSUCCEEDED; - } catch (Exception e) {Debug.println("Not SUCCEEDED");} + } catch (Exception e) {} } + Debug.println("wpsStatus:" + wpsStatus); creationTime = rootElement.get("wps:ExecuteResponse").get("wps:Status").getAttrValue("creationTime"); String procId = rootElement.get("wps:ExecuteResponse").get("wps:Process").get("ows:Identifier").getValue(); @@ -243,10 +244,10 @@ public static JSONObject statusLocationDataAsJSONElementToWPSStatusObject(String String dataInputs=HTTPTools.getKVPItem(queryString, "DataInputs"); String responseForm=HTTPTools.getKVPItem(queryString, "ResponseForm"); if (dataInputs!=null) { - dataInputs=dataInputs.substring(1,dataInputs.length()-1); + dataInputs=dataInputs.substring(0,dataInputs.length()); } if (responseForm!=null) { - responseForm=responseForm.substring(1,responseForm.length()-1); + responseForm=responseForm.substring(0,responseForm.length()); } Debug.println("DataInputs: "+dataInputs+" , ResponseForm:"+responseForm); XMLElement wpsElement=new XMLElement(); @@ -293,7 +294,7 @@ private static void getUserJobInfo(String queryString, String userDataDir, Strin // Tools.mksubdirs(userDataDir+"/WPS_Settings/"); String statusLocation=data.getString("statuslocation"); - String baseName = statusLocation.substring(statusLocation.lastIndexOf("/")).replace(".xml", ".wpssettings"); + String baseName = statusLocation.substring(statusLocation.lastIndexOf("/")).replace(".xml", ".execute.json"); String wpsSettingsFile = userDataDir+"/WPS_Settings/"; Tools.mksubdirs(wpsSettingsFile); wpsSettingsFile+=baseName; diff --git a/src/main/java/nl/knmi/adaguc/services/servicehealth/ServiceHealthConfigurator.java b/src/main/java/nl/knmi/adaguc/services/servicehealth/ServiceHealthConfigurator.java index 6d7b6ea..ec87aa3 100644 --- a/src/main/java/nl/knmi/adaguc/services/servicehealth/ServiceHealthConfigurator.java +++ b/src/main/java/nl/knmi/adaguc/services/servicehealth/ServiceHealthConfigurator.java @@ -1,6 +1,11 @@ package nl.knmi.adaguc.services.servicehealth; import nl.knmi.adaguc.tools.ElementNotFoundException; + +import java.io.IOException; + +import org.springframework.beans.factory.annotation.Autowired; + import nl.knmi.adaguc.config.ConfigurationReader; import nl.knmi.adaguc.tools.MyXMLParser.XMLElement; @@ -16,8 +21,9 @@ public class ServiceHealthConfigurator implements nl.knmi.adaguc.config.Configur private static boolean enabled=false; // The directory that contains a file per service with the return code of updatedb private static String serviceHealthDirectory = null; - static ConfigurationReader configurationReader = new ConfigurationReader (); - public void doConfig(XMLElement configReader){ + @Autowired + static ConfigurationReader configurationReader; + public static void doConfig(XMLElement configReader){ if(configReader.getNodeValue("adaguc-services.servicehealth") == null){ return; } @@ -33,13 +39,13 @@ public void doConfig(XMLElement configReader){ } - public static String getServiceHealthDirectory() throws ElementNotFoundException { - configurationReader.readConfig(); + public static String getServiceHealthDirectory() throws ElementNotFoundException, IOException { + ConfigurationReader.readConfig(); return serviceHealthDirectory; } - public static boolean getEnabled() throws ElementNotFoundException { - configurationReader.readConfig(); + public static boolean getEnabled() throws ElementNotFoundException, IOException { + ConfigurationReader.readConfig(); return enabled; } } \ No newline at end of file diff --git a/src/main/java/nl/knmi/adaguc/services/servicehealth/ServiceHealthRequestMapper.java b/src/main/java/nl/knmi/adaguc/services/servicehealth/ServiceHealthRequestMapper.java index 53864f7..8573a78 100644 --- a/src/main/java/nl/knmi/adaguc/services/servicehealth/ServiceHealthRequestMapper.java +++ b/src/main/java/nl/knmi/adaguc/services/servicehealth/ServiceHealthRequestMapper.java @@ -1,44 +1,21 @@ package nl.knmi.adaguc.services.servicehealth; -import java.io.ByteArrayOutputStream; import java.io.File; import java.io.IOException; -import java.io.OutputStream; -import java.net.URLEncoder; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -import org.json.JSONArray; -import org.json.JSONException; import org.json.JSONObject; -import org.springframework.context.annotation.Bean; -import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.RestController; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.SerializationFeature; - -import nl.knmi.adaguc.tools.ElementNotFoundException; -import nl.knmi.adaguc.config.MainServicesConfigurator; -import nl.knmi.adaguc.services.adagucserver.ADAGUCServer; -import nl.knmi.adaguc.tools.Debug; -import nl.knmi.adaguc.tools.HTTPTools; import nl.knmi.adaguc.tools.JSONResponse; import nl.knmi.adaguc.tools.Tools; @RestController public class ServiceHealthRequestMapper { - @Bean - public MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter() { - ObjectMapper mapper = new ObjectMapper(); - mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, true); - MappingJackson2HttpMessageConverter converter = - new MappingJackson2HttpMessageConverter(mapper); - return converter; - } @ResponseBody @RequestMapping("servicehealth") diff --git a/src/main/java/nl/knmi/adaguc/services/tinyopendapserver/TinyDapRequestMapper.java b/src/main/java/nl/knmi/adaguc/services/tinyopendapserver/TinyDapRequestMapper.java index 971bcc8..faf5415 100644 --- a/src/main/java/nl/knmi/adaguc/services/tinyopendapserver/TinyDapRequestMapper.java +++ b/src/main/java/nl/knmi/adaguc/services/tinyopendapserver/TinyDapRequestMapper.java @@ -5,16 +5,11 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -import org.springframework.context.annotation.Bean; -import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; import org.springframework.web.bind.annotation.CrossOrigin; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.RestController; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.SerializationFeature; - import nl.knmi.adaguc.security.AuthenticatorFactory; import nl.knmi.adaguc.security.AuthenticatorInterface; import nl.knmi.adaguc.security.token.TokenManager; @@ -26,18 +21,11 @@ @RestController @CrossOrigin public class TinyDapRequestMapper { - @Bean - public MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter() { - ObjectMapper mapper = new ObjectMapper(); - mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, true); - MappingJackson2HttpMessageConverter converter = - new MappingJackson2HttpMessageConverter(mapper); - return converter; - } + @ResponseBody @RequestMapping("opendap/**") public void runTinyDap(HttpServletResponse response, HttpServletRequest request) throws IOException{ - // Debug.println("/opendap"); + Debug.println("#### SERVLET /opendap ####"); /* Three ways of authentication are possible: * 1) - browser session based * 2) - X509, for command line diff --git a/src/main/java/nl/knmi/adaguc/services/tinyopendapserver/TinyDapServer.java b/src/main/java/nl/knmi/adaguc/services/tinyopendapserver/TinyDapServer.java index 99aac49..7a3695d 100644 --- a/src/main/java/nl/knmi/adaguc/services/tinyopendapserver/TinyDapServer.java +++ b/src/main/java/nl/knmi/adaguc/services/tinyopendapserver/TinyDapServer.java @@ -208,7 +208,7 @@ public void parse(Variable variable, String variableDodsQuery) { }; - enum CDMTypes {String,Byte,UInt16,Int16,UInt32,Int32,Float32,Float64 }; + enum CDMTypes {String,Byte,UInt16,Int16,UInt32,Int32,UInt64, Int64, Float32,Float64 }; private static CDMTypes ncTypeToCDMType(String CDMType){ if(CDMType.equals("String"))return CDMTypes.String; @@ -218,11 +218,11 @@ private static CDMTypes ncTypeToCDMType(String CDMType){ if(CDMType.equals("short"))return CDMTypes.Int16; if(CDMType.equals("uint"))return CDMTypes.UInt32; if(CDMType.equals("int"))return CDMTypes.Int32; + if(CDMType.equals("ulong"))return CDMTypes.UInt64; + if(CDMType.equals("long"))return CDMTypes.Int64; if(CDMType.equals("float"))return CDMTypes.Float32; if(CDMType.equals("double"))return CDMTypes.Float64; - if(Debugger.DebugOpendap){ - Debug.errprintln("Unknown type "+CDMType); - } + Debug.errprintln("Unknown type "+CDMType); return null; } @@ -233,8 +233,11 @@ private static String CDMTypeToString(CDMTypes cdmType){ if(cdmType == CDMTypes.Int16)return "Int16"; if(cdmType == CDMTypes.UInt32)return "UInt32"; if(cdmType == CDMTypes.Int32)return "Int32"; + if(cdmType == CDMTypes.UInt64)return "Int32"; + if(cdmType == CDMTypes.Int64)return "Int32"; if(cdmType == CDMTypes.Float32)return "Float32"; if(cdmType == CDMTypes.Float64)return "Float64"; + Debug.errprintln("Unknown type "+cdmType); return null; } @@ -350,6 +353,10 @@ private static void writeVariableScalar(ByteArrayOutputStream bos, if(Debugger.DebugOpendap)Debug.println("Writing scalar int32"); writeInt(bos,variable.readScalarInt()); } + if(type == CDMTypes.Int64||type == CDMTypes.UInt64){ + if(Debugger.DebugOpendap)Debug.println("Writing scalar int32 based on int64"); + writeInt(bos,variable.readScalarInt()); + } if(type == CDMTypes.Float32){ if(Debugger.DebugOpendap)Debug.println("Writing scalar float32"); DataOutputStream dos = new DataOutputStream(bos); @@ -396,6 +403,8 @@ private static void writeVariableData(ByteArrayOutputStream bos, Variable variab if(type == CDMTypes.Int16)elsize=2; if(type == CDMTypes.UInt32)elsize=4; if(type == CDMTypes.Int32)elsize=4; + if(type == CDMTypes.UInt64)elsize=8; + if(type == CDMTypes.Int64)elsize=8; if(type == CDMTypes.Float32)elsize=4; if(type == CDMTypes.Float64)elsize=8; if(Debugger.DebugOpendap){ @@ -406,6 +415,9 @@ private static void writeVariableData(ByteArrayOutputStream bos, Variable variab if(type == CDMTypes.Int16 || type == CDMTypes.UInt16){ outSize*=2; } + if(type == CDMTypes.Int64 || type == CDMTypes.UInt64){ + outSize/=2; + } byte[] b = byteBuffer.array(); byte[] c = new byte[outSize]; @@ -424,6 +436,15 @@ private static void writeVariableData(ByteArrayOutputStream bos, Variable variab c[g*2+3]=b[g+1]; } } + + if(type==CDMTypes.UInt64||type == CDMTypes.Int64){ + for(int g=0;g processOutputs = rootElement.get("wps:ExecuteResponse").get("wps:ProcessOutputs").getList("wps:Output"); - for(int j=0;j processOutputs = rootElement.get("wps:ExecuteResponse").get("wps:ProcessOutputs").getList("wps:Output"); + for(int j=0;j 0 && reference.startsWith("http")) { + String mimeType= refObj.getAttrValue("mimeType"); + Debug.println("Processfolder is " + processFolder); + String destLoc = user.getDataDir() + "/" + "/" + processFolder; + String basketLocalFilename = FilenameUtils.getBaseName(reference) + "." + FilenameUtils.getExtension(reference); + Debug.println("basketLocalFilename: " + basketLocalFilename); + if (basketLocalFilename.equals(".")) { + basketLocalFilename = identifier; + if (mimeType.equals("application/x-netcdf")) { basketLocalFilename += ".nc"; } + if (mimeType.equals("image/png")) { basketLocalFilename += ".png"; } + if (mimeType.equals("text/plain")) { basketLocalFilename += ".txt"; } + if (mimeType.equals("application/zip")) { basketLocalFilename += ".zip"; } + if (mimeType.equals("application/json")) { basketLocalFilename += ".json"; } + if (mimeType.equals("application/yml")) { basketLocalFilename += ".yml"; } + if (mimeType.equals("text/csv")) { basketLocalFilename += ".csv"; } - } + } + Debug.println("basketLocalFilename: " + basketLocalFilename); + String fullPath = destLoc + "/" + basketLocalFilename; + if (new File(fullPath).exists() == false) { + Debug.println("Start copy " + reference); + // TODO: ADD SECURITY CHECKS + Tools.mksubdirs(destLoc); + char [] tsPass = SecurityConfigurator.getTrustStorePassword().toCharArray(); + String ts = SecurityConfigurator.getTrustStore(); + X509UserCertAndKey userCertificate = user.getCertificate(); + Tools.writeFile(fullPath, makeRequest(reference, userCertificate, ts, tsPass)); + } else { + Debug.println("Already copied " + reference + " with path [" + fullPath + ']'); + } + String basketRemoteURL = Basket.GetRemotePrefix(user) + processFolder + "/" + basketLocalFilename; + refObj.setAttr("href", basketRemoteURL); + } else { + Debug.errprintln("Warning reference is not set for " + identifier); + } + } + }catch(Exception e){ + Debug.errprintln(e.getMessage()); + } + + + } + return rootElement; } - private byte[] makeRequest(String requestStr, X509UserCertAndKey userCertificate, String ts, char[] tsPass) throws KeyManagementException, UnrecoverableKeyException, InvalidKeyException, NoSuchAlgorithmException, KeyStoreException, CertificateException, NoSuchProviderException, SignatureException, IOException, GSSException { + private static byte[] makeRequest(String requestStr, X509UserCertAndKey userCertificate, String ts, char[] tsPass) throws KeyManagementException, UnrecoverableKeyException, InvalidKeyException, NoSuchAlgorithmException, KeyStoreException, CertificateException, NoSuchProviderException, SignatureException, IOException, GSSException { try { /* First try without user certificate */ - Debug.println("First try without user certificate"); CloseableHttpClient httpClient = (new PemX509Tools()). getHTTPClientForPEMBasedClientAuth(ts, tsPass, null); CloseableHttpResponse httpResponse = httpClient.execute(new HttpGet(requestStr)); - return EntityUtils.toByteArray(httpResponse.getEntity()); + + byte[] a = EntityUtils.toByteArray(httpResponse.getEntity()); + + Debug.println("Status: " + httpResponse.getStatusLine().getStatusCode() + " Size: " + a.length); + + if (httpResponse.getStatusLine().getStatusCode() != HttpStatus.SC_OK) { + Debug.println("Status code not ok, attempting cert"); + throw new IOException("Request needs certificate"); + } + + /* Birdhouse WPS gives an exception when a certificate is needed, check it out */ + if (a.length < 2048) { + String test = new String(a); + if (test.indexOf("A valid X.509 client certificate is needed")!=-1) { + Debug.println("Request needs certificate"); + throw new IOException("Request needs certificate"); + } + } + return a; } catch (Exception e){ if (userCertificate!=null) { - /* Second, try with user certificate */ - Debug.println("Second, try with user certificate"); + /* Second, try with user certificate */ + Debug.println("Trying with cert and header"); CloseableHttpClient httpClient = (new PemX509Tools()). getHTTPClientForPEMBasedClientAuth(ts, tsPass, userCertificate); - CloseableHttpResponse httpResponse = httpClient.execute(new HttpGet(requestStr)); - return EntityUtils.toByteArray(httpResponse.getEntity()); + HttpGet request = new HttpGet(requestStr); + try{ + X509Info info = (new PemX509Tools()).getUserIdFromCertificate(userCertificate.getUserSlCertificate()) ; + Debug.println("Adding header CN=" + info.getCN()); + request.addHeader("x-ssl_client_s_dn", "CN=" + info.getCN()); + }catch(Exception e2) { + Debug.errprintln("Unable to add header: " + e2.getMessage()); + } + CloseableHttpResponse httpResponse = httpClient.execute(request); + Debug.println("StatusCode with certificate: " + httpResponse.getStatusLine().getStatusCode()); + return EntityUtils.toByteArray(httpResponse.getEntity()); + } else{ - Debug.println("Request without user certificate failed"); + Debug.println("Request without user certificate failed " +e.getMessage()); throw(e); } } diff --git a/src/main/java/nl/knmi/adaguc/tools/CGIRunner.java b/src/main/java/nl/knmi/adaguc/tools/CGIRunner.java new file mode 100644 index 0000000..e751c4e --- /dev/null +++ b/src/main/java/nl/knmi/adaguc/tools/CGIRunner.java @@ -0,0 +1,201 @@ +package nl.knmi.adaguc.tools; + +import java.io.IOException; +import java.io.OutputStream; +import java.util.Calendar; + +import javax.servlet.http.HttpServletResponse; + +public class CGIRunner { + + /** + * Runs a CGI program as executable on the system. Emulates the behavior of scripts in a traditional cgi-bin directory of apache http server. + * @param commands A string array with the executable and the arguments to this executable + * @param environmentVariables The environment variables used for this run + * @param directory The location to start the program, can be null or "" if not needed + * @param response Can be null, when given the content-type for the response will be set. + * @param outputStream A standard byte output stream in which the data of stdout is captured. Can for example be response.getOutputStream(). + * @param postData The data to post. + * @throws IOException + * @throws InterruptedException + * @throws Exception + */ + public static void runCGIProgram(String[] commands,String[] environmentVariables,String directory,final HttpServletResponse response,OutputStream outputStream,String postData) throws InterruptedException, IOException { + Debug.println("Working Directory: "+directory); + + class StderrPrinter implements ProcessRunner.StatusPrinterInterface{ + StringBuffer errorMessages = new StringBuffer(); + public void print(byte[] message,int bytesRead) { + errorMessages.append(new String(message,0,bytesRead)); + } + public void setError(String message) { + } + public String getError() { + return errorMessages.toString(); + } + @Override + public boolean hasData() { + // TODO Auto-generated method stub + return false; + } + } + class StdoutPrinter implements ProcessRunner.StatusPrinterInterface{ + boolean headersSent = false; + boolean foundLF = false; + boolean hasError = false; + OutputStream output = null; + StringBuffer header = new StringBuffer(); + public StdoutPrinter(OutputStream outputStream) { + output=outputStream; + } + + // boolean a = false; + public void print(byte[] message,int bytesRead) { + try { + _print(message,bytesRead); + } catch (IOException e) { + this.hasError = true; + //Debug.errprintln("Unable to write data: "+e.getMessage()); + } + } + + public void _print(byte[] message,int bytesRead) throws IOException { + //Try to extract HTML headers and Content-Type + if(hasError)return; + if(headersSent==false){ + int endHeaderIndex=0; + for(int j=0;j paramMap= request.getParameterMap(); + String [] value = null; + for (Entry entry : paramMap.entrySet()){ + String key = entry.getKey(); + if(key.equalsIgnoreCase(name)){ + value = entry.getValue(); + break; + } + } + + if(value==null||value[0]==null||value.length==0){ + throw new Exception("UnableFindParam " + name); + } + + String paramValue = value[0]; + paramValue = URLDecoder.decode(paramValue, "UTF-8"); + paramValue = validateInputTokens(paramValue); + return paramValue; + } + /** + * Returns a list of values of a key, but does checking on valid tokens for XSS attacks and decodes the URL. + * @param request The HTTPServlet containing the KVP's + * @param name Name of the key + * @return The values of the key in a String array + * @throws Exception (UnsupportedEncoding and InvalidHTTPKeyValueTokensException) + */ + public static String[] getHTTPParamList(HttpServletRequest request, String name) + throws Exception { + + StringBuffer url=request.getRequestURL(); + String queryString = request.getQueryString(); + if (queryString!=null) { + url.append('?').append(queryString); + } + List values=getKVPList(url.toString(), name); + + if (values.size()==0){ + throw new Exception("UnableFindParam " + name); + } + + return values.toArray(new String[0]); + } + + /** + * Get values for a multiple keys with the same name in a URL, + * e.g. ?variable=psl&variable=tas means: key="variable" value="psl,tas" (as list) + * @param url The URL containging the KVP encoded data + * @param key The key we want to search for + * @return value, null if not found. + * @throws InvalidHTTPKeyValueTokensException + * @throws Exception + */ + static public List getKVPList(String url, String key) throws InvalidHTTPKeyValueTokensException { + + String urlParts[] = url.split("\\?"); + String queryString = urlParts[urlParts.length - 1]; + List values = new ArrayList(); + // System.out.println("*********QU"+queryString); + String[] kvpparts = queryString.split("&"); + for (int j = 0; j < kvpparts.length; j++) { + // System.out.println("*********KV"+kvpparts[j]); + int firstEqualsSign = kvpparts[j].indexOf("="); + if(firstEqualsSign>=0){ + String foundKey = kvpparts[j].substring(0, firstEqualsSign); + String foundValue = kvpparts[j].substring(firstEqualsSign+1); + if (foundKey.equalsIgnoreCase(key)){ + String valueChecked = validateInputTokens(foundValue); + values.add(valueChecked); + } + } + } + return values; + + } + + /** + * Finds a KVP from the querystring. Returns null if not found. + * @param queryString + * @param string + * @return + * @throws InvalidHTTPKeyValueTokensException + * @throws Exception + */ + public static String getKVPItem(String queryString, String string) throws InvalidHTTPKeyValueTokensException { + List items = getKVPList(queryString, string); + if (items.size() == 0) + return null; + return items.get(0); + } + + + static public String makeCleanURL(String url) { + // DebugConsole.println("oldURL="+url); + if (url.length() == 0) + return url; + // Remove double && signs + String newURL = ""; + String urlParts[] = url.split("\\?"); + if (urlParts.length == 2) { + newURL = urlParts[0] + "?"; + } + boolean requireAmp = false; + String queryString = urlParts[urlParts.length - 1]; + // System.out.println("*********QU"+queryString); + String[] kvpparts = queryString.split("&"); + for (int j = 0; j < kvpparts.length; j++) { + // System.out.println("*********KV"+kvpparts[j]); + String kvp[] = kvpparts[j].split("="); + + if (kvp.length == 2) { + if (requireAmp) + newURL += "&"; + newURL += kvp[0] + "=" + kvp[1]; + requireAmp = true; + } + if (kvp.length == 1) { + if (kvp[0].length() != 0) { + newURL += kvp[0]; + if (urlParts.length == 1 && j == 0) { + newURL += "?"; + } + } + } + } + // return newURL; + + try { + // DebugConsole.println("+newURL: "+newURL); + String rootCatalog = new URL(newURL).toString(); + String path = new URL(rootCatalog).getFile(); + String hostPath = rootCatalog.substring(0, + rootCatalog.length() - path.length()); + + // DebugConsole.println("Catalog: "+rootCatalog); + // DebugConsole.println("hostPath: "+hostPath); + path = path.replace("//", "/"); + + newURL = hostPath + path; + // DebugConsole.println("newURL: "+newURL); + // DebugConsole.println("/newURL: "+newURL); + return newURL; + } catch (MalformedURLException e) { + return newURL; + } + + } + public static String makeHTTPGetRequest(String discoveryURL) throws UnsupportedOperationException, IOException { + CloseableHttpClient httpClient = HttpClients.createDefault(); + HttpGet httpGet = new HttpGet(discoveryURL); + CloseableHttpResponse httpResponse = httpClient.execute(httpGet); + + BufferedReader reader = new BufferedReader(new InputStreamReader( + httpResponse.getEntity().getContent())); + + String inputLine; + StringBuffer response = new StringBuffer(); + + while ((inputLine = reader.readLine()) != null) { + response.append(inputLine); + } + reader.close(); + + httpClient.close(); + + return response.toString(); + } + + public static RequestConfig requestConfigWithTimeout(int timeoutInMilliseconds) { + return RequestConfig.copy(RequestConfig.DEFAULT) + .setSocketTimeout(timeoutInMilliseconds) + .setConnectTimeout(timeoutInMilliseconds) + .setConnectionRequestTimeout(timeoutInMilliseconds) + .build(); + } + + public static String makeHTTPGetRequestWithTimeOut(String url, int timeOut) throws UnsupportedOperationException, IOException { + CloseableHttpClient httpClient = HttpClients.createDefault(); + + HttpGet httpGet = new HttpGet(url); + httpGet.setConfig(requestConfigWithTimeout(timeOut)); + CloseableHttpResponse httpResponse = httpClient.execute(httpGet); + + BufferedReader reader = new BufferedReader(new InputStreamReader( + httpResponse.getEntity().getContent())); + + String inputLine; + StringBuffer response = new StringBuffer(); + + while ((inputLine = reader.readLine()) != null) { + response.append(inputLine); + } + reader.close(); + + httpClient.close(); + + return response.toString(); + } + + + public static String makeHTTPGetRequestWithHeaders(String userInfoEndpoint, + KVPKey key) throws ClientProtocolException, IOException { + CloseableHttpClient httpClient = HttpClients.createDefault(); + HttpGet httpGet = new HttpGet(userInfoEndpoint); + + if(key!=null){ + SortedSet a = key.getKeys(); + for(String b : a){ + //System.out.println("Adding header "+b+"="+headers.getValue(b).firstElement()); + httpGet.addHeader(b,key.getValue(b).firstElement()); + Debug.println("addHeader ["+b+","+key.getValue(b).firstElement()+"]"); + } + } + + CloseableHttpResponse httpResponse = httpClient.execute(httpGet); + + BufferedReader reader = new BufferedReader(new InputStreamReader( + httpResponse.getEntity().getContent())); + + String inputLine; + StringBuffer response = new StringBuffer(); + + while ((inputLine = reader.readLine()) != null) { + response.append(inputLine); + } + reader.close(); + + httpClient.close(); + + return response.toString(); + } + + public static String getCookieValue(HttpServletRequest request, String name) { + Cookie[] cookies = request.getCookies(); + if (cookies != null) { + for (Cookie cookie : cookies) { + if (name.equals(cookie.getName())) { + return cookie.getValue(); + } + } + } + return null; + } + + public static void setCookieValue(HttpServletResponse response, String name, String value, int maxAge) { + Cookie cookie = new Cookie(name, value); + cookie.setPath("/"); + if(maxAge!=-1){ + cookie.setMaxAge(maxAge); + } + // cookie.setHttpOnly(true); + // cookie.setSecure(true); + response.addCookie(cookie); + } + + public static void removeCookie(HttpServletResponse response, String name) { + setCookieValue(response, name, null, 0); + } + + public static KVPKey parseQueryString(String url) { + KVPKey kvpKey = new KVPKey(); + String urlParts[] = url.split("\\?"); + String queryString = urlParts[urlParts.length - 1]; + String[] kvpparts = queryString.split("&"); + for (int j = 0; j < kvpparts.length; j++) { + int equalIndex = kvpparts[j].indexOf("="); + if(equalIndex > 0){ + String key = kvpparts[j].substring(0,equalIndex); + String value = kvpparts[j].substring(equalIndex+1); + String valueChecked; + try { + valueChecked = validateInputTokens(value); + kvpKey.addKVP(key,valueChecked); + } catch (Exception e) { + kvpKey.addKVP(key,e.getMessage()); + } + } + } + return kvpKey; + } + +} diff --git a/src/main/java/nl/knmi/adaguc/tools/InvalidTokenException.java b/src/main/java/nl/knmi/adaguc/tools/InvalidTokenException.java new file mode 100644 index 0000000..c06fa33 --- /dev/null +++ b/src/main/java/nl/knmi/adaguc/tools/InvalidTokenException.java @@ -0,0 +1,18 @@ +package nl.knmi.adaguc.tools; + +public class InvalidTokenException extends Exception { + String message = null; + /** + * + */ + private static final long serialVersionUID = 6797418585190698615L; + + public InvalidTokenException(String string) { + message = string; + } + + public String getMessage() { + return message; + } + +} diff --git a/src/main/java/nl/knmi/adaguc/tools/JSONResponse.java b/src/main/java/nl/knmi/adaguc/tools/JSONResponse.java new file mode 100644 index 0000000..4e079cb --- /dev/null +++ b/src/main/java/nl/knmi/adaguc/tools/JSONResponse.java @@ -0,0 +1,226 @@ +package nl.knmi.adaguc.tools; + +import java.io.IOException; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +/** + * @author Maarten Plieger - KNMI + * + * Helper class for creating json and jsonp responses + * + * Example usages: + + JSONResponse jsonResponse = new JSONResponse(request); + + try{ + jsonResponse.setMessage("bla"); + } catch(Exception e){ + jsonResponse.setException("nice error message",e); + } + + try { + jsonResponse.print(response); + } catch (Exception e1) { + + } + + * + */ +public class JSONResponse { + + public JSONResponse(HttpServletRequest request,String userId){ + setJSONP(request); + this.userId = userId; + + } + + public JSONResponse(HttpServletRequest request){ + setJSONP(request); + this.userId = null; + } + + + public JSONResponse(){ + } + + + public void setJSONP(HttpServletRequest request) { + try{ + jsonp=HTTPTools.getHTTPParam(request,"jsonp"); + }catch (Exception e) { + try{ + jsonp=HTTPTools.getHTTPParam(request,"callback"); + }catch (Exception e1) { + } + } + } + public String getMimeType() { + return mimetype; + } + public void setMimeType(String mimetype) { + this.mimetype = mimetype; + } + public void setJSONP(String jsonp) { + this.jsonp = jsonp; + + } + public void disableJSONP() { + this.jsonp = null; + + } + + private String userId = null; + private String message = ""; + private String mimetype = "application/json; charset=UTF-8"; + private String jsonp = null; + private int statusCode = 200; + private String redirectURL = null; + private String errorMessage = null; + boolean hasError = false; + public String getMessage(){ + if(message.length()==0){ + setErrorMessage("JSONResponse: no message set",statusCode); + } + if(jsonp!=null){ + if(jsonp.length()>0){ + return jsonp+"("+message+");"; + } + } + return message; + } + public void setMessage(String message){ + if(this.hasError){ + Debug.errprintln("Message can not be set because error has occured"); + }else{ + this.message = message; + } + } + + public JSONResponse setException(String string, Exception e2) { + setException(string,e2,null); + return this; + } + public void setException(String string, Exception e2, String url) { + // if(e2.getClass() == tools.HTTPTools.WebRequestBadStatusException.class){ + // this.statusCode = ((tools.HTTPTools.WebRequestBadStatusException)e2).getStatusCode(); + // } + this.statusCode = 400; + JSONObject error = new JSONObject(); + try { + error.put("error", string); + error.put("statuscode", this.statusCode); + //error.put("exception", e2.getMessage()); Disabled due to XSS issues + // Debug.printStackTrace(e2); + + if(redirectURL!=null){error.put("redirect", this.redirectURL);} + if(this.userId!=null){error.put("userid", this.userId);} + if(url!=null){ + error.put("url", url); + } + } catch (JSONException e) { + e.printStackTrace(); + } + + this.message = error.toString(); + this.hasError = true; + } + + public JSONResponse setErrorMessage(String errorMessage, int statusCode){ + setErrorMessage(errorMessage, statusCode,null,null,null); + return this; + } + public void setErrorMessage(String errorMessage, int statusCode,String redirectURL,String currentPage,String resource){ + JSONObject error = new JSONObject(); + this.errorMessage = errorMessage; + this.statusCode = statusCode; + this.redirectURL = redirectURL; + try { + error.put("error", this.errorMessage); + error.put("statuscode", this.statusCode); + if(redirectURL!=null){error.put("redirect", this.redirectURL);} + if(currentPage!=null){error.put("current", currentPage);} + if(resource!=null){error.put("resource", resource);} + if(this.userId!=null){error.put("userid", this.userId);} + } catch (JSONException e) { + e.printStackTrace(); + } + this.message = error.toString(); + this.hasError = true; + } + public int getStatusCode(){ + return statusCode; + } + + public void setMessage(JSONObject json) { + setMessage(json.toString()); + } + public void setMessage(JSONArray json) { + setMessage(json.toString()); + } + public boolean hasError(){ + return hasError; + } + + public void print(HttpServletResponse response) throws IOException{ + if (getMimeType() != null) { + response.setContentType(getMimeType()); + } +// Debug.println("statuscode = " + statusCode); + response.setStatus(statusCode); + byte[] msg = getMessage().getBytes(); + response.setHeader("Content-Length", String.valueOf(msg.length)); + response.getOutputStream().write(msg); + response.flushBuffer(); + } + public void printNE(HttpServletResponse response) throws IOException{ + try { + print(response); + } catch (Exception e1) { + + } + } + + public static class JSONResponseException extends Exception { + private static final long serialVersionUID = 1L; + + String result = null; + + public JSONResponseException(JSONResponse r) { + + this.result = r.getMessage(); + } + + + + + + public JSONResponseException(String errorMessage,int statusCode) { + JSONResponse r = new JSONResponse(); + r.setErrorMessage(errorMessage, statusCode); + result = r.getMessage(); + } + + public String getResult() { + return result; + } + + public String getMessage() { + return result; + } + } + + public void setException(JSONResponseException e) { + this.hasError = true; + this.message = e.getMessage(); + } + + public void setUserId(String id) { + this.userId = id; + } +} diff --git a/src/main/java/nl/knmi/adaguc/tools/JsonMessage.java b/src/main/java/nl/knmi/adaguc/tools/JsonMessage.java new file mode 100644 index 0000000..fec198b --- /dev/null +++ b/src/main/java/nl/knmi/adaguc/tools/JsonMessage.java @@ -0,0 +1,12 @@ +package nl.knmi.adaguc.tools; + +import lombok.Getter; + +@Getter +public class JsonMessage { + private String message; + public JsonMessage(String message) { + this.message=message; + } + +} \ No newline at end of file diff --git a/src/main/java/nl/knmi/adaguc/tools/KVPKey.java b/src/main/java/nl/knmi/adaguc/tools/KVPKey.java new file mode 100644 index 0000000..86a211f --- /dev/null +++ b/src/main/java/nl/knmi/adaguc/tools/KVPKey.java @@ -0,0 +1,41 @@ +package nl.knmi.adaguc.tools; + + +import java.util.SortedSet; +import java.util.TreeSet; +import java.util.Vector; + +public class KVPKey { + class KVP{ + public KVP(String key2, String value2) { + key=key2; + value=value2; + } + String key = null; + String value = null; + } + private Vector kvplist = new Vector (); + + public void addKVP(String key,String value){ + kvplist.add(new KVP(key,value)); + } + + public SortedSet getKeys(){ + SortedSet keys = new TreeSet(); + for(KVP k : kvplist){ + keys.add(k.key); + } + return keys; + } + public Vector getValue(String key){ + Vector values = new Vector(); + for(KVP k : kvplist){ + if(k.key.equalsIgnoreCase(key)){ + values.add(k.value); + } + } + return values; + + } + +} diff --git a/src/main/java/nl/knmi/adaguc/tools/LazyCaller.java b/src/main/java/nl/knmi/adaguc/tools/LazyCaller.java new file mode 100644 index 0000000..5d955aa --- /dev/null +++ b/src/main/java/nl/knmi/adaguc/tools/LazyCaller.java @@ -0,0 +1,58 @@ +package nl.knmi.adaguc.tools; + +import java.util.Vector; + + + +public class LazyCaller { + private class LazyObject{ + String name = null; + long age = 0; + } + static private Vector lazyObjects = new Vector(); + + public boolean isCallable(String id,int timeOutMs){ + long currentAge = DateFunctions.getCurrentDateInMillis(); + LazyObject fileObj = getLazyObject(id); + if(fileObj!=null){ + if(fileObj.age!=0&&fileObj.age+timeOutMs>currentAge){ + return false; + } + }else{ + fileObj = new LazyObject(); + lazyObjects.add(fileObj); + fileObj.name = id; + } + fileObj.age= currentAge; + return true; + }; + + static public void markDirty(String id){ + LazyObject fileObj = getLazyObject(id); + if(fileObj!=null){ + fileObj.age=0; + } + } + + static private LazyObject getLazyObject(String file){ + for(int j=0;j attributes = null; + private Vector xmlElements = null; + private String value = null; + private String name = null; + public XMLElement(){ + attributes = new Vector(); + xmlElements = new Vector(); + } + public XMLElement(String name) { + this(); + this.name=name; + } + + public String getValue(){ + return value; + } + + public Vector getElements(){ + return xmlElements; + } + + public Vector getAttributes(){ + return attributes; + } + + public String getName(){ + return name; + } + + public XMLElement get(String s,int index) throws Exception{ + int NR=0; + for(int j=0;j300){ + throw new WebRequestBadStatusException(statusCode); + } + Debug.errprintln("Status code: "+ connection.getResponseCode()); + Debug.errprintln(msg); + throw new IOException(msg); + }catch (SAXException e) { + // Debug.printStackTrace(e); + Debug.printStackTrace(e); + String msg="SAXException: "+e.getMessage()+" for URL "+url.toString(); + Debug.errprintln(msg); + throw new SAXException(msg); + } catch(Exception e){ + String msg="Exception: "+e.getMessage()+" for URL "+url.toString();; + Debug.errprintln(msg); + throw new Exception(msg); + } + } + + /** + * Function which does a POST request + * @param url The URL + * @param data The data to post + * @throws Exception + */ + public void parse(URL url,String data) throws Exception{ + //DebugConsole.println("Loading "+url+" with data \n"+data); + try{ + // Send data + URLConnection conn = url.openConnection(); + conn.setDoOutput(true); + OutputStreamWriter wr = new OutputStreamWriter(conn.getOutputStream()); + wr.write(data); + wr.flush(); + + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + DocumentBuilder db = dbf.newDocumentBuilder(); + + Document document = db.parse(conn.getInputStream()); + parse(document); + wr.close(); + + } catch (SAXException e) { + String msg="SAXException: "+e.getMessage(); + Debug.errprintln(msg); + throw new SAXException(msg); + } catch (IOException e) { + String msg="IOException: "+e.getMessage(); + Debug.errprintln(msg); + throw new IOException(msg); + }catch(Exception e){ + String msg="Exception: "+e.getMessage(); + Debug.errprintln(msg); + throw new Exception(msg); + } + Debug.println("Ready"); + } + + + private void _parseJSON(JSONObject jsonObject, Vector xmlElements, XMLElement child) throws Exception { + JSONArray keys = jsonObject.names (); + if (keys == null) return; + for (int i = 0; i < keys.length (); ++i) { + String key = keys.getString(i); + Object obj = jsonObject.get(key); + if (obj instanceof JSONObject) { + JSONObject subJsonObject = (JSONObject)(obj); + if (key.equals("attr")) { + JSONArray attrKeys = subJsonObject.names (); + for (int a = 0; a < attrKeys.length (); ++a) { + String attrKey = attrKeys.getString(a); + String attrValue = subJsonObject.getString(attrKey); + XMLAttribute attr=new XMLAttribute(); + attr.name=attrKey; + attr.value=attrValue; + child.attributes.add(attr); + } + } else { + XMLElement newChild = new XMLElement(); + xmlElements.add(newChild); + newChild.name = key; + _parseJSON(subJsonObject, newChild.xmlElements, newChild); + } + } else if (obj instanceof JSONArray) { + JSONArray array = (JSONArray) obj; + for(int j=0;j0){ + + child.value=nodeGetValue.trim(); + } + } + NodeList childNodes = fstNode.getChildNodes(); + if(childNodes.getLength()>0){ + child.parse(childNodes); + } + } + } + } + + public Vector getList(String s) { + Vector v = new Vector(); + for(int j=0;j0){ + for(int i=0;i\n"; + return data; + + } + + /** + * Carriage returns in a JSON object are not allowed and should be replaced with the "\n" sequence + * @param in the unencoded JSON string + * @return the encoded JSON string + */ + private String jsonEncode(String in){ + //Debug.println(in); + + in = in.replaceAll("\r\n", ":carriagereturn:"); + in = in.replaceAll("\n", ":carriagereturn:"); + in = in.replaceAll("\\\\", ""); + in = in.replaceAll("\"", "\\\\\""); + in = in.replaceAll(":carriagereturn:","\\\\n"); + // in = in.replaceAll("\\\\ ", " "); + // in = in.replaceAll("\\\\\\[", "["); + // in = in.replaceAll("\\\\\\]", "]"); + // in = in.replaceAll("\\\\\\_", "_"); + // in = in.replaceAll("\\\\\\:", ":"); + // in = in.replaceAll("\\\\\\-", "-"); + // in = in.replaceAll("\\\\\\+", "+"); + // in = in.replaceAll("\\\\\\.", "."); + // in = in.replaceAll("\\\\\\,", ","); + // in = in.replaceAll("\\\\\\'", "'"); + + + // Debug.println(in); + return in; + } + + /** + * Returns a String with the attributes of this XML element encoded to JSON + * @param el The XMLElement with attributes to convert to JSON formatted attributes + * @return String with JSON formatted data + */ + private String printJSONAttributes(XMLElement el,Options options){ + String data=""; + if(el.getAttributes().size()>0){ + data+="\"attr\":{"; + for(int j=0;j0)data+=","; + String name = el.getAttributes().get(j).name; + if(options == Options.STRIPNAMESPACES){ + name = name.substring(name.indexOf(":")+1); + } + name =jsonEncode(name); + data+="\""+name+"\":\""+jsonEncode(el.getAttributes().get(j).value)+"\""; + } + data+="}"; + } + return data; + } + + /** + * Print the XMLElement's value in a JSON formatted way + * @param el The XMLElement value to be printed in a JSON formatted way + * @return String with JSON formatted data + */ + private String printJSONValue(XMLElement el){ + if(el.getValue()!=null){ + if(el.getValue().length()>0){ + return "\"value\":\""+jsonEncode(el.getValue())+"\""; + } + } + return ""; + } + + /** + * Converts a list of XML elements all with the same name to a JSON string. + * @param vector The list of XML elements with the same name + * @param depth The depth of the XML elements + * @return JSON formatted string + */ + private String xmlElementstoJSON(Vector vector,int depth,Options options){ + String data = ""; + String name = vector.get(0).name; + + if(options == Options.STRIPNAMESPACES){ + name = name.substring(name.indexOf(":")+1); + } + name =jsonEncode(name); + //DebugConsole.println(name); + data+="\""+name+"\":"; + boolean isArray=false; + if(vector.size()>1)isArray=true; + + if(isArray){ + data+="[\n"; + } + for(int j=0;j0){ + data+=",\n"; + } + data+="{"; + data+=toJSON(vector.get(j),depth+1,options); + data+="}"; + } + if(isArray){ + data+="]\n"; + } + data+=""; + return data; + } + + /** + * Converts a XML element to JSON string and walks through all nested XML elements + * @param el The XML element to convert to a json string + * @param depth The current depth of the XML element + * @return JSON string + */ + private String toJSON(XMLElement el,int depth,Options options){ + String data = ""; + if(el==null)return data; + + boolean firstDataDone=false; + + //Print the json attributes + data+=printJSONAttributes(el,options); + if(el.attributes.size()>0)firstDataDone=true; + + //Make a Set of the XML elements names + Set set = new HashSet(); + for(int j=0;j0){ + if(firstDataDone){data+=",\n";}firstDataDone=true; + data+=jsonValue; + } + + + + return data; + } + + /** + * Returns The XML object as a well formatted XML string. + */ + public String toString(){ + String data =""; + data="\n"; + for(int j=0;j b = a.getList(elements[j]); + if(b.size()>0){ + String[] results = new String[b.size()]; + for(int i=0;i0){ + environmentVars = Tools.appendString(environmentVars, "CONTENT_LENGTH="+dataToPost.length()); + environmentVars = Tools.appendString(environmentVars, "REQUEST_METHOD=POST"); + + //environmentVars = Tools.appendString(environmentVars, "QUERY_STRING=SERVICE=WPS&REQUEST=EXECUTE&VERSION=1.0.0&IDENTIFIER=testcdo_dtdp"); + + } + } + + /*for(int j=0;j0){ + OutputStreamWriter wr = new OutputStreamWriter(child.getOutputStream()); + wr.write(dataToPost); + wr.flush(); + wr.close(); + //DebugConsole.println("Putting postdata\n"+dataToPost); + PrintWriter stdin = new PrintWriter(child.getOutputStream()); + stdin.print(dataToPost); + + stdin.close(); + } + } + brstdout = new BufferedInputStream( child.getInputStream() ); + brstderr = new BufferedInputStream( child.getErrorStream() ); + stdoutThread= new StatusPrinterThread(stdoutPrinter,brstdout); + stderrThread= new StatusPrinterThread(stderrPrinter,brstderr); + stdoutThread.start(); + stderrThread.start(); + + + + + //Wait for the process to complete + child.waitFor(); + + //Wait for the output monitoring threads to complete + stdoutThread.join(); + stderrThread.join(); + if (child != null) { + try{child.getOutputStream().close();}catch(Exception e){Debug.errprintln("Output stream was already closed");} + child.getInputStream().close(); + child.getErrorStream().close(); + child.destroy(); + } + + exitCode=child.exitValue(); + + + return exitCode; + } + public int exitValue(){ + return exitCode; + } + public void abort(){ + if(child != null){ + try { + child.getOutputStream().close(); + child.getInputStream().close(); + child.getErrorStream().close(); + } + catch (IOException e) { + String msg="Exception in ProcessRunner while aborting: "+e.getMessage(); + stderrPrinter.print(msg.getBytes(),msg.length()); + } + child.destroy(); + } + } +} \ No newline at end of file diff --git a/src/main/java/nl/knmi/adaguc/tools/StatusCode.java b/src/main/java/nl/knmi/adaguc/tools/StatusCode.java new file mode 100644 index 0000000..fe91038 --- /dev/null +++ b/src/main/java/nl/knmi/adaguc/tools/StatusCode.java @@ -0,0 +1,15 @@ +package nl.knmi.adaguc.tools; + +import lombok.Getter; + +@Getter +public class StatusCode { + private int statuscode=200; + private String msg; + + public StatusCode(int statusCode, String msg) { + this.statuscode=statusCode; + this.msg=msg; + } + public StatusCode(){} +} diff --git a/src/main/java/nl/knmi/adaguc/tools/Tools.java b/src/main/java/nl/knmi/adaguc/tools/Tools.java new file mode 100644 index 0000000..5bb1988 --- /dev/null +++ b/src/main/java/nl/knmi/adaguc/tools/Tools.java @@ -0,0 +1,425 @@ +package nl.knmi.adaguc.tools; + + +import java.io.BufferedInputStream; +import java.io.BufferedOutputStream; +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Comparator; +import java.util.zip.ZipEntry; +import java.util.zip.ZipOutputStream; + +import org.apache.commons.io.FileUtils; +import org.springframework.core.io.ClassPathResource; +public class Tools { + + /** + * + * @param file The filename to read + * @return Bytes of the read file + * @throws IOException + */ + static byte[] readBytes(String file) throws IOException{ + //DebugConsole.println("readBytes "+file); + File fileObject=new File(file); + byte[] data=new byte[(int) fileObject.length()]; + FileInputStream pemInputStream=new FileInputStream(fileObject); + pemInputStream.read(data); + pemInputStream.close(); + return data; + } + + public static String getExtension(String input){ + String output=input.trim(); + int dotPos = output.lastIndexOf("."); + if(dotPos == -1)return null; + String extension = output.substring(dotPos); + return extension; + } + + public static String makeCleanPath(String input){ + String output=input.trim(); + output=_removeDuplicateSlashes(output); + output=_fixDotDotDirs(output); + return output; + } + private static String _removeDuplicateSlashes(String input){ + String output=""; + String[] subPaths=input.split("/"); + for(int j=0;j0){ + if(subPaths[j].charAt(0)!='/'){ + if(output.length()>0){ + if(output.charAt(output.length()-1)!='/'){ + output+="/"; + } + }else if(input.charAt(0)=='/')output="/"; + //System.out.println(subPaths[j]); + if(!subPaths[j].equals(".")){ + output+=subPaths[j]; + } + } + } + + } + //System.out.println("--"+output); + return output; + } + private static String _fixDotDotDirs(String input){ + String output=""; + input+="/./"; + String[] subPaths=input.split("/"); + for(int j=0;j0){ + if(subPaths[j].charAt(0)!='/'){ + if(output.length()>0){ + if(output.charAt(output.length()-1)!='/'){ + output+="/"; + } + }else if(input.charAt(0)=='/')output="/"; + //System.out.println(subPaths[j]); + if(!subPaths[j].equals(".")){ + output+=subPaths[j]; + } + } + } + }else j++; + } + if(output.indexOf("..")>0){ + System.out.println("**"+output); + output=_fixDotDotDirs(output); + } + + //output+="/"; + return output; + } + + public static void cp(String source, String destination) throws IOException{ + File inputFile = new File(source); + + if(inputFile.isDirectory()==true){ + mkdir(destination); + File sourceDir = new File(source); + for(String file : sourceDir.list()){ + cp(source+"/"+file,destination+"/"+file); + } + return; + } + File sourceFile=new File(source); // source + BufferedInputStream bis = new BufferedInputStream(new FileInputStream(sourceFile), 4096); + File targetFile = new File(destination); // destination + BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(targetFile), 4096); + int theChar; + while ((theChar = bis.read()) != -1) { + bos.write(theChar); + } + bos.close(); + bis.close(); + } + public static void mv(String source, String destination) throws IOException{ + /*File inputFile = new File(source); + + if(inputFile.isDirectory()==true){ + mkdir(destination); + File sourceDir = new File(source); + for(String file : sourceDir.list()){ + cp(source+"/"+file,destination+"/"+file); + } + return; + }*/ + File sourceFile=new File(source); // source + File targetFile = new File(destination); // destination + boolean succes = sourceFile.renameTo(targetFile); + if(!succes){ + throw new IOException("Unable to rename '"+source+"' to '"+destination+"'"); + } + } + public static void mvcp(String source, String destination) throws IOException{ + cp(source,destination); + File d = new File(destination); + while(!d.exists()); + rmfile(source); + } + + public static void mkdir(String dir) throws IOException{ + if(dir==null)return; + if(dir.equals("null"))return; + File f = new File(dir);if(f.isDirectory()&&f.exists())return; + if(dir.length()==0){ + throw new IOException("Invalid directory name specified (0 chars)"); + } + File directory=new File(dir); + if(directory.exists()){ + //throw new IOException("Directory already exists: '"+dir+"'"); + return; + } + boolean success=directory.mkdir(); + if(!success){ + File test = new File(directory.getAbsolutePath()); + if(test.exists()==false){ + throw new IOException("mkdir: Directory could not be created and does not exist: "+directory.getAbsolutePath()); + }else{ + //throw new IOException("mkdir: Directory could not created, it exists already..."); + } + } + } + public static void mksubdirs(String dir) throws IOException{ + File f = new File(dir);if(f.isDirectory()&&f.exists())return; + String[] dirs = dir.split("/"); + String path=""; + for(int j=0;j 0) { + out.write(buf, 0, len); + } + + // Complete the entry + out.closeEntry(); + in.close(); + } + + // Complete the ZIP file + out.close(); + + return 0; + } + static class DirAlphaComparator implements Comparator { + + // Comparator interface requires defining compare method. + public int compare(File filea, File fileb) { + //... Sort directories before files, + // otherwise alphabetical ignoring case. + if (filea.isDirectory() && !fileb.isDirectory()) { + return -1; + + } else if (!filea.isDirectory() && fileb.isDirectory()) { + return 1; + + } else { + return filea.getName().compareToIgnoreCase(fileb.getName()); + } + } + } + + static public void writeFile(String fileName,String data) throws IOException{ + FileWriter fstream = new FileWriter(fileName); + BufferedWriter out = new BufferedWriter(fstream); + out.write(data); + out.close(); + fstream.close(); + } + static public void writeFile(String fileName,byte[] data) throws IOException{ + FileUtils.writeByteArrayToFile(new File(fileName), data); + } + static public String readFile(String fileName) throws IOException{ + StringBuffer fileData = new StringBuffer(1000); + BufferedReader reader = new BufferedReader( + new FileReader(fileName)); + char[] buf = new char[1024]; + int numRead=0; + while((numRead=reader.read(buf)) != -1){ + String readData = String.valueOf(buf, 0, numRead); + fileData.append(readData); + buf = new char[1024]; + } + reader.close(); + return fileData.toString(); + + } + + static public byte[] readFileRaw(String fileName) throws IOException{ + Path path = Paths.get(fileName); + byte[] data = Files.readAllBytes(path); + return data; + } + + + + public static String checkValidCharsForFile(String input) throws InvalidTokenException{ + if(input.indexOf("..")!=-1){ + throw new InvalidTokenException("Invalid sequence given: .."); + } + + byte[] validTokens = { + 'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z', + 'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z', + '0','1','2','3','4','5','6','7','8','9', + '+','-','|','&','.',',','~',' ','/','_' + }; + + byte[] str = input.getBytes(); + for(int c=0;c 0) { + result.append("\n"); + } + result.append(line); + } + inputStream.close(); + return result.toString(); + } +} diff --git a/src/main/java/nl/knmi/adaguc/tools/Watcher.java b/src/main/java/nl/knmi/adaguc/tools/Watcher.java new file mode 100644 index 0000000..1fc419f --- /dev/null +++ b/src/main/java/nl/knmi/adaguc/tools/Watcher.java @@ -0,0 +1,189 @@ +package nl.knmi.adaguc.tools; + +/** + * Copyright (c) 2010 Ng Pan Wei + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation files + * (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + + +import java.util.HashMap; + +/** +* For getting the signature of an executing line, the caller and so on. +* Supports logging and hyper-linking through Eclipse error parser. +* @author panwei +*/ +public class Watcher { + /** + * Get string signature of current executing line. + * @return + */ + public static String getSignature() { + StackTraceElement trace = getCaller(null) ; + String signature = getSignature(trace) ; + return signature; + } + /** + * Get the signature of the calling class. + * Count the number of classes == 3 in the normal case. + * Count the number of classes == 5 if it goes through a dyanmic proxy. + * This is highly dependent on invocation sequence. + * - This watcher class, the client class, and the calling class above the client. + * @return + */ + public static String getCallingClassSignature(int level) { + StackTraceElement callingTrace = getCaller(level) ; + if(callingTrace==null) + return "No Caller" ; + return getSignature(callingTrace) ; + } + /** + * Get the signature of stack trace conforming to eclipse error parser. + * @return + */ + protected static String getSignature(StackTraceElement trace) { + String classNameParts[] = trace.getClassName().split("\\."); + String className = classNameParts[classNameParts.length-1] ; + String signature = className+"."+trace.getMethodName(); + signature += "(" + trace.getFileName() + ":" + trace.getLineNumber() + ")" ; + return signature ; + } + /** + * Get the caller by scanning the stack trace. + * Ignores this class and classes provided by caller. + * @return + */ + protected static StackTraceElement getCaller(String pIgnoredClassNames[]) { + String thisClassName = Watcher.class.getSimpleName() ; + StackTraceElement[] traces = new Throwable().getStackTrace() ; + for(StackTraceElement trace : traces) { + String traceClassName = trace.getClassName() ; + boolean found = isTargetTrace(traceClassName, + thisClassName,pIgnoredClassNames) ; + if(found) return trace ; + } + return null ; + } + /** + * Get caller of the class above from the bottom of the call stack. + * Levels are computed by the different classes. + * @param pClassLevel + * @return + */ + protected static StackTraceElement getCaller(int pClassLevel) { + HashMap classCounter = new HashMap() ; + StackTraceElement[] traces = new Throwable().getStackTrace() ; + StackTraceElement callingTrace = null ; + for(StackTraceElement trace : traces) { + String traceClassName = trace.getClassName() ; + classCounter.put(traceClassName, ""); + if(classCounter.size()>pClassLevel) { + callingTrace = trace ; + break ; + } + } + return callingTrace ; + + } + /** + * Part of trace scanning to determine if the trace is to be ignored. + * @param traceClassName + * @param pWatcherName + * @param pIgnoredClassNames + * @return + */ + private static boolean isTargetTrace(String traceClassName, + String pWatcherName,String pIgnoredClassNames[]) { + if(traceClassName.endsWith(pWatcherName)==true) + return false ; + if(traceClassName.contains("$")==true) + return false ; + if(pIgnoredClassNames==null) + return true ; + for(String ignoredClassName : pIgnoredClassNames) { + if(traceClassName.endsWith(ignoredClassName)==true) + return false ; + } + return true ; + } + /** + * log executing class name, method name and line number. + */ + public static void log() { + log(null) ; System.err.println() ; + } + /** + * log a message with executing class name, method name and line number. + * @param pMessage + */ + public static void log(String pMessage) { + log(null,pMessage) ; + } + /** + * Log a message ignoring a number of classes in the stack. + * @param pIgnoredClassNames + * @param pMessage + */ + public static void log(String pIgnoredClassNames[],String pMessage) { + StackTraceElement trace = getCaller(pIgnoredClassNames) ; + String signature = getSignature(trace) ; + System.err.print(signature) ; + if(pMessage==null) + return ; + System.err.println(" [" + pMessage + "]"); + } + /** + * Begin a new watch session. + */ + public static void start() { + System.err.println("----------------------------------") ; + log(null) ; System.err.println() ; + } + protected static String getExternalSignature(String pPackageName,int count) { + StackTraceElement callingTrace = getTraceAbovePackage(pPackageName,count) ; + if(callingTrace==null) + return "No Caller" ; + String signature = getSignature(callingTrace) ; + return signature ; + } + + public static StackTraceElement getTraceAbovePackage(String pPackageName,int count) { + StackTraceElement[] traces = new Throwable().getStackTrace() ; + boolean currentMatch = false ; + boolean previousMatch = false ; + int matchCounter = 0 ; + for(StackTraceElement trace : traces) { + String traceClassName = trace.getClassName() ; + currentMatch = false ; + if(traceClassName.startsWith(pPackageName)) + currentMatch = true ; + if(currentMatch==false&&previousMatch==true) { + matchCounter++; + if(matchCounter>=count) + return trace ; + } + previousMatch = currentMatch ; + } + return null ; + } + +} diff --git a/src/main/java/nl/knmi/adaguc/tools/WebRequestBadStatusException.java b/src/main/java/nl/knmi/adaguc/tools/WebRequestBadStatusException.java new file mode 100644 index 0000000..dd306d3 --- /dev/null +++ b/src/main/java/nl/knmi/adaguc/tools/WebRequestBadStatusException.java @@ -0,0 +1,33 @@ +package nl.knmi.adaguc.tools; + +public class WebRequestBadStatusException extends Exception { + private static final long serialVersionUID = 1L; + int statusCode = 0; + String result = null; + + public WebRequestBadStatusException(int statusCode, String result) { + this.statusCode = statusCode; + this.result = result; + } + + public WebRequestBadStatusException(int statusCode) { + this.statusCode = statusCode; + this.result = ""; + } + + public int getStatusCode() { + return statusCode; + } + + public String getResult() { + return result; + } + + public String getMessage() { + + //if(statusCode == 401){ + return statusCode+": "+"EXCEPTION";// org.apache.commons.httpclient.HttpStatus.getStatusText(statusCode); + //} + //return ""+statusCode; + } + } diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 2642bcd..cb56c5c 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -23,4 +23,4 @@ tomcat.ajp.port=9090 tomcat.ajp.remoteauthentication=false -tomcat.ajp.enabled=true \ No newline at end of file +tomcat.ajp.enabled=true diff --git a/src/test/java/nl/knmi/adaguc/authentication/AuthenticatorImplTest.java b/src/test/java/nl/knmi/adaguc/authentication/AuthenticatorImplTest.java index e84b9f8..139d464 100644 --- a/src/test/java/nl/knmi/adaguc/authentication/AuthenticatorImplTest.java +++ b/src/test/java/nl/knmi/adaguc/authentication/AuthenticatorImplTest.java @@ -25,6 +25,7 @@ import nl.knmi.adaguc.security.PemX509Tools; import nl.knmi.adaguc.security.PemX509Tools.X509Info; +import nl.knmi.adaguc.security.token.TokenManager; import nl.knmi.adaguc.tools.Debug; @@ -52,6 +53,22 @@ public void setUp() { public final ExpectedException exception = ExpectedException.none(); + @Test + public void TestGetTokenFromPath() throws Exception{ + TokenManager tk = new TokenManager(); + String token = tk.getTokenFromPath("/test/bla/a02b717b-02d6-4db9-bddf-a1d3774fee87/bla/bla.nc"); + Debug.println(token); + assertThat(token,is("a02b717b-02d6-4db9-bddf-a1d3774fee87")); + String tokenNope = tk.getTokenFromPath("/test/bla/np-a02b717b-02d6-4db9-bddf-a1d3774fee87.test/bla/bla.nc"); + Debug.println(tokenNope); + assertThat(tokenNope,org.hamcrest.Matchers.isEmptyOrNullString()); + } + +// @Test +// public void TestDAPDDS() throws Exception{ +// +// TinyDapServer.handleOpenDapReqeuests("/home/c3smagic/Downloads/test-metric.nc","/","/",null,null); +// } @Test public void TestThis() throws Exception{