From 52e6709168c5205a8b65abe0b66d866bd43bb710 Mon Sep 17 00:00:00 2001 From: Jeremy Faden Date: Tue, 8 Nov 2022 08:30:31 -0600 Subject: [PATCH 001/680] Update README.md --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 792379b..9b42929 100644 --- a/README.md +++ b/README.md @@ -52,6 +52,9 @@ When changes are pushed to the github server, the war file is rebuilt and will b within a minute or two at https://cottagesystems.com/autoplot/git/server-java/HapiServer/dist/HapiServer.war +# Manual +For installation instuctions, see the wiki: https://github.com/hapi-server/server-java/wiki. + --- last_modified_at: 2022-07-26T16:26:24 --- From 8b606464d98c1b4859e4962e6587a18d9610e1f7 Mon Sep 17 00:00:00 2001 From: Jeremy Faden Date: Wed, 15 Mar 2023 08:54:57 -0500 Subject: [PATCH 002/680] move configuration to context.xml so that multiple servers can be run in the same web container. --- HapiServer/web/META-INF/context.xml | 4 +++- HapiServer/web/WEB-INF/web.xml | 4 ---- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/HapiServer/web/META-INF/context.xml b/HapiServer/web/META-INF/context.xml index 987d6dd..7624739 100644 --- a/HapiServer/web/META-INF/context.xml +++ b/HapiServer/web/META-INF/context.xml @@ -1,2 +1,4 @@ - + + + diff --git a/HapiServer/web/WEB-INF/web.xml b/HapiServer/web/WEB-INF/web.xml index 2607c2c..2f21c14 100644 --- a/HapiServer/web/WEB-INF/web.xml +++ b/HapiServer/web/WEB-INF/web.xml @@ -85,8 +85,4 @@ experimental and proposed for 3.2 java.lang.RuntimeException /hapi/error.jsp - - hapi_home - /tmp/hapi-server/ - From 2d5a7b141c4bab9763d845f9d01c12301c7ce9b3 Mon Sep 17 00:00:00 2001 From: Jeremy Faden Date: Wed, 15 Mar 2023 08:56:29 -0500 Subject: [PATCH 003/680] add note that the buildTime has not been set properly by the git pull --- HapiServer/src/java/org/hapiserver/Util.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/HapiServer/src/java/org/hapiserver/Util.java b/HapiServer/src/java/org/hapiserver/Util.java index 578b7a1..7909f7a 100644 --- a/HapiServer/src/java/org/hapiserver/Util.java +++ b/HapiServer/src/java/org/hapiserver/Util.java @@ -435,10 +435,11 @@ public static JSONObject newJSONObject( String s ) { /** * return a unique string for the build to aid in debugging. This is the last commit * of this file, only this file. This should be updated by the revision control system. + * Note this has not been working. * @return the time this file was last modified. */ public static String buildTime() { - String time= "last_modified_at: 2023-03-06T07:37:00"; + String time= "last_modified_at: 2023-03-15T08:55:00"; return time.substring(18); } } From 09c0d9b19afc5d7e344cd6d6805acde10ac258f7 Mon Sep 17 00:00:00 2001 From: Jeremy Faden Date: Wed, 15 Mar 2023 09:19:01 -0500 Subject: [PATCH 004/680] only create HAPI_HOME if it is /tmp/hapi-server/ (DEFAULT_HAPI_HOME) --- HapiServer/src/java/org/hapiserver/Initialize.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/HapiServer/src/java/org/hapiserver/Initialize.java b/HapiServer/src/java/org/hapiserver/Initialize.java index 0e8ef8e..bbbd19a 100644 --- a/HapiServer/src/java/org/hapiserver/Initialize.java +++ b/HapiServer/src/java/org/hapiserver/Initialize.java @@ -35,7 +35,8 @@ public class Initialize { public static final String DEFAULT_HAPI_HOME = "/tmp/hapi-server/"; /** - * initialize the HAPI_HOME if does not exist or the config directory does not exist. + * initialize the HAPI_HOME if does not exist or the config directory does not exist. Note + * if the HAPI_HOME is not DEFAULT_HAPI_HOME, the HAPI_HOME directory must exist already and be writable by the web server. * @param hapiHome */ public static void maybeInitialize( String hapiHome ) { @@ -43,7 +44,7 @@ public static void maybeInitialize( String hapiHome ) { throw new IllegalArgumentException("hapiHome is not set, set in web.xml or with environment variable HAPI_HOME."); } else { File f= new File( hapiHome ); - if ( !f.exists() ) { + if ( !f.exists() && f.toString().equals(DEFAULT_HAPI_HOME)) { Initialize.initialize(f); } else { File configFile= new File( f, "config" ); From 1cb0c346e2f2bd2bdb27f2b403b3f70b35b29b57 Mon Sep 17 00:00:00 2001 From: Jeremy Faden Date: Wed, 15 Mar 2023 10:47:40 -0500 Subject: [PATCH 005/680] support high-rank datasets, where only the times are read. --- .../src/org/hapiserver/source/CefFileIterator.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/HapiServerBase/src/org/hapiserver/source/CefFileIterator.java b/HapiServerBase/src/org/hapiserver/source/CefFileIterator.java index 599c0d1..771ea0e 100644 --- a/HapiServerBase/src/org/hapiserver/source/CefFileIterator.java +++ b/HapiServerBase/src/org/hapiserver/source/CefFileIterator.java @@ -504,10 +504,12 @@ private HapiRecord parseRecord(ByteBuffer record) { ffields.addAll( Arrays.asList(nonRecordVaryingValues) ); continue; } - if (p.sizes.length != 1) { - throw new IllegalArgumentException("Multi-dimensional data types not supported yet"); + int vectorLength; + vectorLength = p.sizes[0]; + for ( int j=1; j componentIndices = new ArrayList<>(); for (int iComponent = 0; iComponent < vectorLength; iComponent++) { componentIndices.add(index+iComponent); From 91548f970a44c9e387ddfabbaca273494c899037 Mon Sep 17 00:00:00 2001 From: Jeremy Faden Date: Wed, 15 Mar 2023 11:10:11 -0500 Subject: [PATCH 006/680] bugfix, CAA C4_CP_WHI_SOUNDING_TIMES had stop and start times at different resolutions. --- HapiServer/src/java/org/hapiserver/DataServlet.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/HapiServer/src/java/org/hapiserver/DataServlet.java b/HapiServer/src/java/org/hapiserver/DataServlet.java index 3d81d4c..7651dbc 100644 --- a/HapiServer/src/java/org/hapiserver/DataServlet.java +++ b/HapiServer/src/java/org/hapiserver/DataServlet.java @@ -82,19 +82,19 @@ private boolean check1405TimeRange( JSONObject info, String start, String stop ) String stopTime= info.optString("stopDate",""); if ( startTime.length()==0 ) throw new IllegalArgumentException("info must contain startDate"); if ( stopTime.length()==0 ) throw new IllegalArgumentException("info must contain stopDate"); + if ( stop.compareTo(start)<=0 ) { + throw new HapiException( 1404, "start time equal to or after stop time" ); + } try { start= TimeUtil.reformatIsoTime( startTime, start ); } catch ( IllegalArgumentException ex ) { throw new HapiException( 1402, "Bad request - error in start time" ); } try { - stop= TimeUtil.reformatIsoTime( startTime, stop ); + stop= TimeUtil.reformatIsoTime( stopTime, stop ); } catch ( IllegalArgumentException ex ) { throw new HapiException( 1403, "Bad request - error in stop time" ); } - if ( stop.compareTo(start)<=0 ) { - throw new HapiException( 1404, "start time equal to or after stop time" ); - } if ( start.compareTo(startTime)<0 ) { throw new HapiException( 1405, "time outside valid range", "start time must be no earlier than "+startTime ); } @@ -111,7 +111,7 @@ private boolean check1405TimeRange( JSONObject info, String start, String stop ) int[] istart= TimeUtil.parseISO8601Time(start); int[] stopLimit= TimeUtil.add( istart, iduration ); String fstopLimit= TimeUtil.formatIso8601Time(stopLimit); - fstopLimit= TimeUtil.reformatIsoTime( startTime, fstopLimit ); + fstopLimit= TimeUtil.reformatIsoTime( stop, fstopLimit ); if ( stop.compareTo(fstopLimit)>0 ) { throw new HapiException( 1408, "Bad request - too much time or data requested", "limit is "+duration ); } From 25630fd71c117305984223dad955241697580e34 Mon Sep 17 00:00:00 2001 From: Jeremy Faden Date: Thu, 16 Mar 2023 08:10:54 -0500 Subject: [PATCH 007/680] correction to landing page, which was at hapi/, not hapi. --- HapiServer/web/WEB-INF/web.xml | 13 +++++++++---- HapiServer/web/hapi/index.jsp | 16 ++++++++-------- 2 files changed, 17 insertions(+), 12 deletions(-) diff --git a/HapiServer/web/WEB-INF/web.xml b/HapiServer/web/WEB-INF/web.xml index 2f21c14..13b8ceb 100644 --- a/HapiServer/web/WEB-INF/web.xml +++ b/HapiServer/web/WEB-INF/web.xml @@ -41,6 +41,11 @@ experimental and proposed for 3.2 SemanticsServlet org.hapiserver.SemanticsServlet + + provides human-readable introduction and example queries + LandingServlet + /hapi/index.jsp + AboutServlet /hapi/about @@ -61,10 +66,6 @@ experimental and proposed for 3.2 DataServlet /hapi/data - - LandingServlet - /hapi/ - RelationsServlet /hapi/relations @@ -73,6 +74,10 @@ experimental and proposed for 3.2 SemanticsServlet /hapi/semantics + + LandingServlet + /hapi + 30 diff --git a/HapiServer/web/hapi/index.jsp b/HapiServer/web/hapi/index.jsp index 0574180..1df1f8a 100644 --- a/HapiServer/web/hapi/index.jsp +++ b/HapiServer/web/hapi/index.jsp @@ -44,9 +44,9 @@

Some example requests:

- About More about this server, like contact info.
- Capabilities Capabilities of the server.
- Catalog Show the catalog of available data sets.
+ About More about this server, like contact info.
+ Capabilities Capabilities of the server.
+ Catalog Show the catalog of available data sets.
<% boolean hasSemantics= false; try { @@ -56,7 +56,7 @@ } if ( hasSemantics ) { %> - Semantics Show declared relationships of data sets.
+ Semantics Show declared relationships of data sets.
<% } %> @@ -116,10 +116,10 @@ TimeUtil.formatIso8601TimeBrief(exampleRange,TimeUtil.TIME_DIGITS) ); out.println( String.format( "

%s

", title ) ); if ( exampleRange!=null ) { - out.println( String.format("[Info] [Data]", + out.println( String.format("[Info] [Data]", ds.getString("id"), ds.getString("id"), exampleTimeRange ) ); } else { - out.println( String.format("[Info] [Data]", + out.println( String.format("[Info] [Data]", ds.getString("id"), ds.getString("id") ) ); } @@ -140,7 +140,7 @@ if ( j>0 ) out.print(" "); try { String pname= parameters.getJSONObject(j).getString("name"); - out.print( String.format( "%s", ds.getString("id"), pname, exampleTimeRange, labels[j] ) ); + out.print( String.format( "%s", ds.getString("id"), pname, exampleTimeRange, labels[j] ) ); if ( j>0 && sparklines ) { //sparklines // vap +hapi :https ://jfaden.net /HapiServerDemo /hapi ?id=?parameters=Temperature //?url=vap%2Bhapi%3Ahttps%3A%2F%2Fjfaden.net%2FHapiServerDemo%2Fhapi%3Fid%3DpoolTemperature%26timerange%3D2020-08-06&format=image%2Fpng&width=70&height=20&column=0%2C100%25&row=0%2C100%25&timeRange=2003-mar&renderType=&color=%23000000&symbolSize=&fillColor=%23aaaaff&foregroundColor=%23000000&backgroundColor=none @@ -174,7 +174,7 @@ } } catch ( JSONException | IOException | RuntimeException ex ) { out.println( String.format( "

%s

", title ) ); - out.println( "

Unable to load info for dataset: "+id+", log files should notify the server host.

" ) ; + out.println( "

Unable to load info for dataset: "+id+", log files should notify the server host.

" ) ; Util.logError(ex); //out.println( "ex: " + ex ); //TODO: security!!! } From 535e38a37b4e0287df68adc50af05b18939681e5 Mon Sep 17 00:00:00 2001 From: Jeremy Faden Date: Thu, 16 Mar 2023 08:19:40 -0500 Subject: [PATCH 008/680] US-ASCII is the presumed encoding, but this needs review. --- HapiServer/web/hapi/index.jsp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/HapiServer/web/hapi/index.jsp b/HapiServer/web/hapi/index.jsp index 1df1f8a..bf25fad 100644 --- a/HapiServer/web/hapi/index.jsp +++ b/HapiServer/web/hapi/index.jsp @@ -70,8 +70,9 @@ JSONArray dss= catalog.getJSONArray("catalog"); - String pps= dss.length()>1 ? "s" : ""; - out.println("This server provides "+dss.length()+" dataset" + pps + ", examples follow."); + if ( dss.length()>1 ) { + out.println("This server provides "+dss.length()+" datasets, examples follow."); + } String autoplotServer= "https://jfaden.net/AutoplotServlet"; //String autoplotServer= "http://localhost:8084/AutoplotServlet"; @@ -152,13 +153,13 @@ ub.append("id="+id); ub.append("¶meters="+pname); ub.append("&timerange="+exampleRange.toString().replaceAll(" ","+") ); - sb.append( URLEncoder.encode(ub.toString()) ); + sb.append( URLEncoder.encode(ub.toString(),"US-ASCII") ); sb.append("&format=image%2Fpng"); sb.append("&width=70"); sb.append("&height=16"); sb.append("&row=0%25-1px%2C100%25"); sb.append("&column=0%25-1px%2C100%25"); - sb.append("&timerange="+URLEncoder.encode(exampleRange.toString()) ); + sb.append("&timerange="+URLEncoder.encode(exampleRange.toString(),"US-ASCII") ); out.print( ""); out.print( "" ); out.print( ""); @@ -180,7 +181,7 @@ } } if ( numDataSets1 ? "s" : ""; + String pps= (dss.length()-numDataSets)>1 ? "s" : ""; out.println("

("+(dss.length()-numDataSets)+" additional dataset" + pps +" can be accessed using a HAPI client.)

" ); } From 03dd702216c6965ebd06cd54eb337194386c97a5 Mon Sep 17 00:00:00 2001 From: Jeremy Faden Date: Thu, 16 Mar 2023 08:24:27 -0500 Subject: [PATCH 009/680] put in comment about the sparklines --- HapiServer/web/hapi/index.jsp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/HapiServer/web/hapi/index.jsp b/HapiServer/web/hapi/index.jsp index bf25fad..2dfcb74 100644 --- a/HapiServer/web/hapi/index.jsp +++ b/HapiServer/web/hapi/index.jsp @@ -74,7 +74,10 @@ out.println("This server provides "+dss.length()+" datasets, examples follow."); } - String autoplotServer= "https://jfaden.net/AutoplotServlet"; + // There is a method for including sparklines on the landing page, where an "AutoplotServer" is called + // to generate graphics for each dataset. Please ignore this if sparklines=false. + + String autoplotServer= "https://cottagesystems.com/AutoplotServlet"; //String autoplotServer= "http://localhost:8084/AutoplotServlet"; String me= "http://spot9/hapi"; // TODO: address this, what is the public name for the server From d1e7bb16ec5a79b563ba6a4638dc47ee46839664 Mon Sep 17 00:00:00 2001 From: Jeremy Faden Date: Thu, 16 Mar 2023 08:27:32 -0500 Subject: [PATCH 010/680] make it more obvious what the artifact is --- .github/workflows/first_workflow.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/first_workflow.yml b/.github/workflows/first_workflow.yml index c9d9f61..315426e 100644 --- a/.github/workflows/first_workflow.yml +++ b/.github/workflows/first_workflow.yml @@ -24,11 +24,11 @@ jobs: cd /var/www/cottagesystems.com/autoplot/git/server-java/HapiServerBase ant clean jar echo "see https://cottagesystems.com/autoplot/git/server-java/HapiServerBase/dist/HapiServerBase.jar" - echo "===" + echo "================" cd /var/www/cottagesystems.com/autoplot/git/server-java/HapiServer ant -Dj2ee.server.home=/usr/local/apache-tomcat-8/ clean dist echo "see https://cottagesystems.com/autoplot/git/server-java/HapiServer/dist/HapiServer.war" - echo "===" + echo "================" cd /var/www/cottagesystems.com/autoplot/git/server-java/SimpleClasspathExtension ant clean jar echo "see https://cottagesystems.com/autoplot/git/server-java/SimpleClasspathExtension/dist/SimpleClasspathExtension.jar" From 550c122a6257df847d4c667b139d7e347ec7721a Mon Sep 17 00:00:00 2001 From: Jeremy Faden Date: Thu, 16 Mar 2023 10:46:46 -0500 Subject: [PATCH 011/680] remove extraneous verify flag, leftover from an earlier implementation. --- HapiServer/src/java/org/hapiserver/DataServlet.java | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/HapiServer/src/java/org/hapiserver/DataServlet.java b/HapiServer/src/java/org/hapiserver/DataServlet.java index 7651dbc..9f919b0 100644 --- a/HapiServer/src/java/org/hapiserver/DataServlet.java +++ b/HapiServer/src/java/org/hapiserver/DataServlet.java @@ -320,7 +320,6 @@ protected void processRequest(HttpServletRequest request, HttpServletResponse re Logger.getLogger(DataServlet.class.getName()).log(Level.SEVERE, null, ex); } - boolean verify= true; boolean sendHeader= include.equals("header"); try { @@ -334,10 +333,7 @@ protected void processRequest(HttpServletRequest request, HttpServletResponse re dataFormatter.initialize( jo, out, first ); - if ( verify ) { - doVerify(dataFormatter, first, jo); - verify= false; - } + doVerify(dataFormatter, first, jo); // format time boundaries so they are in the same format as the data, and simple string comparisons can be made. String startTime= TimeUtil.reformatIsoTime( first.getIsoTime(0), timeMin ); From 87c87b88e0b718c8b0f5edd03f4a30f6996de34f Mon Sep 17 00:00:00 2001 From: Jeremy Faden Date: Thu, 16 Mar 2023 10:48:11 -0500 Subject: [PATCH 012/680] correction to getInfo when bad ID is used. Assumption that cc was non-null lead to null pointer exception. --- HapiServer/src/java/org/hapiserver/HapiServerSupport.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/HapiServer/src/java/org/hapiserver/HapiServerSupport.java b/HapiServer/src/java/org/hapiserver/HapiServerSupport.java index bb68079..63d8775 100644 --- a/HapiServer/src/java/org/hapiserver/HapiServerSupport.java +++ b/HapiServer/src/java/org/hapiserver/HapiServerSupport.java @@ -937,7 +937,8 @@ public static boolean validInfoObject( JSONObject jo ) throws IllegalArgumentExc * @throws java.io.IOException * @throws org.codehaus.jettison.json.JSONException * @throws org.hapiserver.exceptions.HapiException - * @throws IllegalArgumentException for bad id. + * @throws IllegalArgumentException for a bad id. + * @throws BadRequestIdException for a bad id. */ public static JSONObject getInfo( String HAPI_HOME, String id ) throws IOException, JSONException, HapiException { @@ -956,6 +957,7 @@ public static JSONObject getInfo( String HAPI_HOME, String id ) throws IOExcepti JSONObject config=null; if ( !infoConfigFile.exists() ) { + if ( cc==null ) throw new BadRequestIdException("",id); JSONArray arr= cc.catalog.getJSONArray("catalog"); JSONObject thisId=null; for ( int i=0; i Date: Thu, 16 Mar 2023 10:53:56 -0500 Subject: [PATCH 013/680] attempt to clean up error response, where we should be able to return content but tomcat won't let me. --- HapiServer/src/java/org/hapiserver/Util.java | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/HapiServer/src/java/org/hapiserver/Util.java b/HapiServer/src/java/org/hapiserver/Util.java index 7909f7a..b34d9a9 100644 --- a/HapiServer/src/java/org/hapiserver/Util.java +++ b/HapiServer/src/java/org/hapiserver/Util.java @@ -315,17 +315,20 @@ public static void raiseError( int statusCode, String statusMessage, HttpServlet JSONObject jo= createHapiResponse(statusCode,statusMessage); String s= jo.toString(4); int httpStatus= httpForHapiStatusCode(statusCode); + response.setContentType("application/json;charset=UTF-8"); if ( statusCode==1201 ) { - response.sendError( httpStatus, statusMessage ); + response.setStatus( httpStatus, statusMessage ); + //response.sendError( httpStatus, statusMessage ); // no data means empty response } else { if ( statusCode==1406 && statusMessage.equals("HAPI error 1406: unknown dataset id") ) { - response.sendError( httpStatus, "Not Found; HAPI error 1406: unknown dataset id" ); + //response.sendError( httpStatus, "Not Found; HAPI error 1406: unknown dataset id" ); + //response.setStatus( httpStatus, "Not Found; HAPI error 1406: unknown dataset id" ); } else { - response.sendError( httpStatus, statusMessage ); + response.setStatus( httpStatus, statusMessage ); } - response.setContentType("application/json;charset=UTF-8"); out.write(s.getBytes(CHARSET)); + out.close(); } } catch (JSONException ex) { From 814397a9fe715754b6c969338c8a76962825ec32 Mon Sep 17 00:00:00 2001 From: Jeremy Faden Date: Thu, 16 Mar 2023 10:58:16 -0500 Subject: [PATCH 014/680] /hapi is landing page --- HapiServer/web/WEB-INF/web.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/HapiServer/web/WEB-INF/web.xml b/HapiServer/web/WEB-INF/web.xml index 13b8ceb..224664e 100644 --- a/HapiServer/web/WEB-INF/web.xml +++ b/HapiServer/web/WEB-INF/web.xml @@ -84,7 +84,7 @@ experimental and proposed for 3.2
- /hapi/index.jsp + /hapi java.lang.RuntimeException From 11bb0057d31724e9bb303b0681936fe963543a4f Mon Sep 17 00:00:00 2001 From: Jeremy Faden Date: Thu, 16 Mar 2023 12:58:01 -0500 Subject: [PATCH 015/680] set the status properly for 1406 errors, I was experimenting. --- HapiServer/src/java/org/hapiserver/Util.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/HapiServer/src/java/org/hapiserver/Util.java b/HapiServer/src/java/org/hapiserver/Util.java index b34d9a9..95acce1 100644 --- a/HapiServer/src/java/org/hapiserver/Util.java +++ b/HapiServer/src/java/org/hapiserver/Util.java @@ -322,7 +322,7 @@ public static void raiseError( int statusCode, String statusMessage, HttpServlet // no data means empty response } else { if ( statusCode==1406 && statusMessage.equals("HAPI error 1406: unknown dataset id") ) { - //response.sendError( httpStatus, "Not Found; HAPI error 1406: unknown dataset id" ); + response.setStatus( httpStatus, "Not Found; HAPI error 1406: unknown dataset id" ); //response.setStatus( httpStatus, "Not Found; HAPI error 1406: unknown dataset id" ); } else { response.setStatus( httpStatus, statusMessage ); From 9cbe1e45d999121a91be91ab5e9f37a44f7f7e90 Mon Sep 17 00:00:00 2001 From: Jeremy Faden Date: Thu, 16 Mar 2023 13:13:45 -0500 Subject: [PATCH 016/680] trivial fix imports --- HapiServer/src/java/org/hapiserver/Util.java | 1 - 1 file changed, 1 deletion(-) diff --git a/HapiServer/src/java/org/hapiserver/Util.java b/HapiServer/src/java/org/hapiserver/Util.java index 95acce1..e272d99 100644 --- a/HapiServer/src/java/org/hapiserver/Util.java +++ b/HapiServer/src/java/org/hapiserver/Util.java @@ -6,7 +6,6 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; -import java.io.PrintWriter; import java.nio.charset.Charset; import java.nio.file.Files; import java.nio.file.Paths; From 902d650cad8517a1d0ca7d8a2d956aeb4dbd6338 Mon Sep 17 00:00:00 2001 From: Jeremy Faden Date: Thu, 16 Mar 2023 13:21:56 -0500 Subject: [PATCH 017/680] redirect to hapi page --- HapiServer/web/WEB-INF/web.xml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/HapiServer/web/WEB-INF/web.xml b/HapiServer/web/WEB-INF/web.xml index 224664e..ca8b339 100644 --- a/HapiServer/web/WEB-INF/web.xml +++ b/HapiServer/web/WEB-INF/web.xml @@ -46,6 +46,11 @@ experimental and proposed for 3.2 LandingServlet /hapi/index.jsp + + Redirect to landing servlet + EmptyServlet + org.hapiserver.LandingServlet + AboutServlet /hapi/about @@ -78,6 +83,10 @@ experimental and proposed for 3.2 LandingServlet /hapi + + EmptyServlet + / + 30 From 87aed27afcad212e7ff5db475e837aedb497d809 Mon Sep 17 00:00:00 2001 From: Jeremy Faden Date: Thu, 16 Mar 2023 13:22:29 -0500 Subject: [PATCH 018/680] redirect to hapi page --- HapiServer/src/java/org/hapiserver/LandingServlet.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/HapiServer/src/java/org/hapiserver/LandingServlet.java b/HapiServer/src/java/org/hapiserver/LandingServlet.java index 5231329..e8a78ae 100644 --- a/HapiServer/src/java/org/hapiserver/LandingServlet.java +++ b/HapiServer/src/java/org/hapiserver/LandingServlet.java @@ -14,10 +14,10 @@ import javax.servlet.http.HttpServletResponse; /** - * + * redirect the browser to the hapi landing page. * @author jbf */ -@WebServlet(name = "LandingServlet", urlPatterns = {"/hapi"}) +@WebServlet(name = "LandingServlet", urlPatterns = {"/"}) public class LandingServlet extends HttpServlet { /** @@ -31,7 +31,7 @@ public class LandingServlet extends HttpServlet { protected void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { - response.sendRedirect( "index.jsp"); + response.sendRedirect( "/hapi"); } From 595f01af89f669dd58e3373ffcb524edecbbeb65 Mon Sep 17 00:00:00 2001 From: Jeremy Faden Date: Thu, 16 Mar 2023 14:22:32 -0500 Subject: [PATCH 019/680] rename LandingServlet EmptyServlet --- .../{LandingServlet.java => EmptyServlet.java} | 11 +++-------- HapiServer/web/WEB-INF/web.xml | 9 ++------- 2 files changed, 5 insertions(+), 15 deletions(-) rename HapiServer/src/java/org/hapiserver/{LandingServlet.java => EmptyServlet.java} (86%) diff --git a/HapiServer/src/java/org/hapiserver/LandingServlet.java b/HapiServer/src/java/org/hapiserver/EmptyServlet.java similarity index 86% rename from HapiServer/src/java/org/hapiserver/LandingServlet.java rename to HapiServer/src/java/org/hapiserver/EmptyServlet.java index e8a78ae..50b8850 100644 --- a/HapiServer/src/java/org/hapiserver/LandingServlet.java +++ b/HapiServer/src/java/org/hapiserver/EmptyServlet.java @@ -1,12 +1,7 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ + package org.hapiserver; import java.io.IOException; -import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; @@ -17,8 +12,8 @@ * redirect the browser to the hapi landing page. * @author jbf */ -@WebServlet(name = "LandingServlet", urlPatterns = {"/"}) -public class LandingServlet extends HttpServlet { +@WebServlet(name = "EmptyServlet", urlPatterns = {"/"}) +public class EmptyServlet extends HttpServlet { /** * Processes requests for both HTTP GET and POST methods. diff --git a/HapiServer/web/WEB-INF/web.xml b/HapiServer/web/WEB-INF/web.xml index ca8b339..2b85d7d 100644 --- a/HapiServer/web/WEB-INF/web.xml +++ b/HapiServer/web/WEB-INF/web.xml @@ -6,7 +6,7 @@ GZIPFilter - /data + /hapi/.* Provides the server about response. @@ -41,15 +41,10 @@ experimental and proposed for 3.2 SemanticsServlet org.hapiserver.SemanticsServlet - - provides human-readable introduction and example queries - LandingServlet - /hapi/index.jsp - Redirect to landing servlet EmptyServlet - org.hapiserver.LandingServlet + org.hapiserver.EmptyServlet AboutServlet From a8a1430470a1830bf9b99c916e0301794a5865f9 Mon Sep 17 00:00:00 2001 From: Jeremy Faden Date: Fri, 17 Mar 2023 07:45:53 -0500 Subject: [PATCH 020/680] fix LandingServlet --- HapiServer/web/WEB-INF/web.xml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/HapiServer/web/WEB-INF/web.xml b/HapiServer/web/WEB-INF/web.xml index 2b85d7d..b30b31c 100644 --- a/HapiServer/web/WEB-INF/web.xml +++ b/HapiServer/web/WEB-INF/web.xml @@ -46,6 +46,10 @@ experimental and proposed for 3.2 EmptyServlet org.hapiserver.EmptyServlet + + LandingServlet + /hapi/index.jsp + AboutServlet /hapi/about @@ -77,7 +81,7 @@ experimental and proposed for 3.2 LandingServlet /hapi - + EmptyServlet / From c0e8a2276d71b0f6cc72bc6d2a21a4889304e84c Mon Sep 17 00:00:00 2001 From: Jeremy Faden Date: Fri, 17 Mar 2023 11:37:34 -0500 Subject: [PATCH 021/680] fix EmptyServlet --- HapiServer/src/java/org/hapiserver/EmptyServlet.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/HapiServer/src/java/org/hapiserver/EmptyServlet.java b/HapiServer/src/java/org/hapiserver/EmptyServlet.java index 50b8850..06fc7d7 100644 --- a/HapiServer/src/java/org/hapiserver/EmptyServlet.java +++ b/HapiServer/src/java/org/hapiserver/EmptyServlet.java @@ -26,7 +26,7 @@ public class EmptyServlet extends HttpServlet { protected void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { - response.sendRedirect( "/hapi"); + response.sendRedirect( "hapi"); } From 80d0d9168cc90e62afb88148404a0fd572a3c013 Mon Sep 17 00:00:00 2001 From: Jeremy Faden Date: Sun, 19 Mar 2023 09:34:48 -0500 Subject: [PATCH 022/680] update to support 2023-01-18T17:00/18:00 --- HapiServerBase/lib/UriTemplatesJava.jar | Bin 81255 -> 83224 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/HapiServerBase/lib/UriTemplatesJava.jar b/HapiServerBase/lib/UriTemplatesJava.jar index 93bb9af4ef7a65fafce28b116b7b00528f8b674b..545eca53922409d3bff4d2939bd68361e1dbdf3f 100644 GIT binary patch literal 83224 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 literal 81255 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 From c808a9af0ca30caf343459a6841a721479bf0ed7 Mon Sep 17 00:00:00 2001 From: Jeremy Faden Date: Mon, 20 Mar 2023 06:40:02 -0500 Subject: [PATCH 023/680] correct where GZIPFilter wasn't used, because pattern was used instead of glob (.* instead of *) --- .../src/java/com/jspbook/GZIPFilter.java | 51 ++++++++++--------- HapiServer/web/WEB-INF/web.xml | 2 +- 2 files changed, 27 insertions(+), 26 deletions(-) diff --git a/HapiServer/src/java/com/jspbook/GZIPFilter.java b/HapiServer/src/java/com/jspbook/GZIPFilter.java index 0a75265..8bd911b 100644 --- a/HapiServer/src/java/com/jspbook/GZIPFilter.java +++ b/HapiServer/src/java/com/jspbook/GZIPFilter.java @@ -15,32 +15,33 @@ import javax.servlet.http.*; public class GZIPFilter implements Filter { - private static final Logger logger= Logger.getLogger("hapi.gzip"); - - public void doFilter(ServletRequest req, ServletResponse res, - FilterChain chain) throws IOException, ServletException { - if (req instanceof HttpServletRequest) { - HttpServletRequest request = (HttpServletRequest) req; - HttpServletResponse response = (HttpServletResponse) res; - String ae = request.getHeader("accept-encoding"); - if (ae != null && ae.contains("gzip") ) { - logger.log(Level.FINER,"GZIP supported, compressing."); - GZIPResponseWrapper wrappedResponse = - new GZIPResponseWrapper(response); - chain.doFilter(req, wrappedResponse); - wrappedResponse.finishResponse(); - return; - } - chain.doFilter(req, res); + + private static final Logger logger = Logger.getLogger("hapi.gzip"); + + public void doFilter(ServletRequest req, ServletResponse res, + FilterChain chain) throws IOException, ServletException { + if (req instanceof HttpServletRequest) { + HttpServletRequest request = (HttpServletRequest) req; + HttpServletResponse response = (HttpServletResponse) res; + String ae = request.getHeader("accept-encoding"); + if (ae != null && ae.contains("gzip")) { + logger.log(Level.FINER, "GZIP supported, compressing."); + GZIPResponseWrapper wrappedResponse + = new GZIPResponseWrapper(response); + chain.doFilter(req, wrappedResponse); + wrappedResponse.finishResponse(); + return; + } + chain.doFilter(req, res); + } } - } - public void init(FilterConfig filterConfig) { - System.err.println("here"); - // noop - } + public void init(FilterConfig filterConfig) { + System.err.println("here in GZipFilter"); + // noop + } - public void destroy() { - // noop - } + public void destroy() { + // noop + } } diff --git a/HapiServer/web/WEB-INF/web.xml b/HapiServer/web/WEB-INF/web.xml index b30b31c..5ca1552 100644 --- a/HapiServer/web/WEB-INF/web.xml +++ b/HapiServer/web/WEB-INF/web.xml @@ -6,7 +6,7 @@ GZIPFilter - /hapi/.* + /hapi/* Provides the server about response. From a108a792f099912c564a6160837d70218a991b4f Mon Sep 17 00:00:00 2001 From: Jeremy Faden Date: Mon, 20 Mar 2023 07:09:40 -0500 Subject: [PATCH 024/680] close the inputStream --- HapiServerBase/src/org/hapiserver/source/CefFileIterator.java | 1 + 1 file changed, 1 insertion(+) diff --git a/HapiServerBase/src/org/hapiserver/source/CefFileIterator.java b/HapiServerBase/src/org/hapiserver/source/CefFileIterator.java index 771ea0e..6cdf5e6 100644 --- a/HapiServerBase/src/org/hapiserver/source/CefFileIterator.java +++ b/HapiServerBase/src/org/hapiserver/source/CefFileIterator.java @@ -673,6 +673,7 @@ private void readNextRecord() throws IOException { // *** Keep reading until we reach the end of the file. if (eof) { this.nextRecord = null; + this.lun.close(); } else { From c454ebfcabf58a30ab240d8aa1d3a979bb84948c Mon Sep 17 00:00:00 2001 From: Jeremy Faden Date: Mon, 20 Mar 2023 07:20:43 -0500 Subject: [PATCH 025/680] add exclude list of datasets which are presented by the server but do not work. --- .../source/CsaInfoCatalogSource.java | 55 ++++++++++++++++++- 1 file changed, 53 insertions(+), 2 deletions(-) diff --git a/HapiServerBase/src/org/hapiserver/source/CsaInfoCatalogSource.java b/HapiServerBase/src/org/hapiserver/source/CsaInfoCatalogSource.java index 06e9c84..5cb828d 100644 --- a/HapiServerBase/src/org/hapiserver/source/CsaInfoCatalogSource.java +++ b/HapiServerBase/src/org/hapiserver/source/CsaInfoCatalogSource.java @@ -1,10 +1,16 @@ package org.hapiserver.source; import java.io.BufferedReader; +import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.net.URL; +import java.nio.charset.Charset; +import java.nio.file.Files; +import java.util.HashSet; +import java.util.List; +import java.util.Set; import java.util.logging.Level; import java.util.logging.Logger; import javax.xml.parsers.DocumentBuilder; @@ -236,11 +242,12 @@ public static String getInfo(String id) throws IOException { } /** - * return the catalog + * return the catalog as a HAPI catalog response * @return @throws IOException */ public static String getCatalog() throws IOException { try { + loadExcludeList(); JSONArray catalog = new JSONArray(); String url = "https://csa.esac.esa.int/csa-sl-tap/tap/sync?REQUEST=doQuery&LANG=ADQL&FORMAT=CSV&QUERY=SELECT+dataset_id,title+FROM+csa.v_dataset"; try (InputStream in = new URL(url).openStream()) { @@ -252,7 +259,12 @@ public static String getCatalog() throws IOException { while (s != null) { int i = s.indexOf(","); JSONObject jo = new JSONObject(); - jo.put("id", s.substring(0, i).trim()); + String id= s.substring(0, i).trim(); + if ( exclude.contains(id) ) { + logger.log(Level.FINE, "excluding dataset id {0}", id); + continue; + } + jo.put("id", id); String t = s.substring(i + 1).trim(); if (t.startsWith("\"") && t.endsWith("\"")) { t = t.substring(1, t.length() - 1); @@ -293,6 +305,19 @@ private static void printHelp() { System.err.println(" [id] if missing, then return the catalog response"); } + private static Set exclude; + + private static void loadExcludeList() throws IOException { + exclude= new HashSet<>(); + try (InputStream ins = CsaInfoCatalogSource.class.getResourceAsStream("/org/hapiserver/source/CsaCatalogExclude.txt") ) { + BufferedReader read= new BufferedReader( new InputStreamReader( ins ) ); + String line= read.readLine(); + while ( line!=null ) { + exclude.add(line); + line= read.readLine(); + } + } + } /** * * @param args @@ -302,6 +327,32 @@ public static void main(String[] args) { if (args[0].equals("--help")) { printHelp(); System.exit(1); + } else if ( args[0].equals("--depth=all")) { + // this was to entertain the idea of doing a full catalog with every response info generated. + // I realized I could generate this just as easily by running the "makeGiantCatalog.jy" script + // on my instance of this, which has the side-effect of generating all the info responses. + try { + String s = getCatalog(); + JSONObject jo= new JSONObject(s); + JSONArray ja= jo.getJSONArray("catalog"); + JSONArray ja1= new JSONArray(); + int n= ja.length(); + for ( int i=0; i Date: Mon, 20 Mar 2023 07:21:33 -0500 Subject: [PATCH 026/680] correct bug where very short requests would result in identical start and stop times being sent to tapServerURL. --- .../org/hapiserver/source/TAPDataSource.java | 56 +++++++++++++++++-- 1 file changed, 51 insertions(+), 5 deletions(-) diff --git a/HapiServerBase/src/org/hapiserver/source/TAPDataSource.java b/HapiServerBase/src/org/hapiserver/source/TAPDataSource.java index 192ad41..98ca570 100644 --- a/HapiServerBase/src/org/hapiserver/source/TAPDataSource.java +++ b/HapiServerBase/src/org/hapiserver/source/TAPDataSource.java @@ -5,12 +5,15 @@ import java.net.URL; import java.nio.channels.Channels; import java.nio.channels.ReadableByteChannel; +import java.text.ParseException; +import java.util.Arrays; import java.util.Iterator; import java.util.logging.Level; import java.util.logging.Logger; import org.hapiserver.AbstractHapiRecordSource; import org.hapiserver.HapiRecord; +import org.hapiserver.TimeUtil; public class TAPDataSource extends AbstractHapiRecordSource { @@ -37,11 +40,22 @@ public boolean hasParamSubsetIterator() { @Override public Iterator getIterator(int[] start, int[] stop) { - String startTimeString = formatTime(start); - String endTimeString = formatTime(stop); - + String startTimeString; + String stopTimeString; + int minimumDurationNs=200000000; + int[] duration = TimeUtil.subtract(stop, start); + if ( duration[0]==0 && duration[1]==0 && duration[2]==0 + && duration[3]==0 && duration[4]==0 && duration[5]==0 + && duration[6] iter= new TAPDataSource(tapServerURL, id).getIterator(start, stop); + while ( iter.hasNext() ) { + HapiRecord r= iter.next(); + System.err.println( String.format( "%s %d fields", r.getIsoTime(0), r.length() ) ); + } + } + + public static void mainCase3( String[] args ) throws ParseException { + String tapServerURL="https://csa.esac.esa.int/csa-sl-tap/"; + String id="CM_CG_WBD_OVERVIEW_500_19_PNG"; + String tr= "2023-01-18T17:00/18:00"; + int[] timerange = TimeUtil.parseISO8601TimeRange(tr); + int[] start= Arrays.copyOfRange( timerange, 0, 7 ); + int[] stop= Arrays.copyOfRange( timerange, 7, 14 ); + Iterator iter= new TAPDataSource(tapServerURL, id).getIterator(start, stop); + while ( iter.hasNext() ) { + HapiRecord r= iter.next(); + System.err.println( String.format( "%s %d fields", r.getIsoTime(0), r.length() ) ); + } + } + + public static void main(String[] args ) throws Exception { + //mainCase1(args); + //mainCase2(args); + mainCase3(args); + } } From 3682dd9daa6da7b752dee2b067825c284261e18f Mon Sep 17 00:00:00 2001 From: Jeremy Faden Date: Mon, 20 Mar 2023 07:23:30 -0500 Subject: [PATCH 027/680] add exclude list of datasets which are presented by the server but do not work. (whoops!) --- .../src/org/hapiserver/source/CsaInfoCatalogSource.java | 1 + 1 file changed, 1 insertion(+) diff --git a/HapiServerBase/src/org/hapiserver/source/CsaInfoCatalogSource.java b/HapiServerBase/src/org/hapiserver/source/CsaInfoCatalogSource.java index 5cb828d..dfbd71b 100644 --- a/HapiServerBase/src/org/hapiserver/source/CsaInfoCatalogSource.java +++ b/HapiServerBase/src/org/hapiserver/source/CsaInfoCatalogSource.java @@ -262,6 +262,7 @@ public static String getCatalog() throws IOException { String id= s.substring(0, i).trim(); if ( exclude.contains(id) ) { logger.log(Level.FINE, "excluding dataset id {0}", id); + s = ins.readLine(); continue; } jo.put("id", id); From 44f26bba24915b1d132e59b41a8b90604a6bdb6e Mon Sep 17 00:00:00 2001 From: Jeremy Faden Date: Mon, 20 Mar 2023 08:41:28 -0500 Subject: [PATCH 028/680] update UriTemplatesJava --- HapiServer/lib/UriTemplatesJava.jar | Bin 81255 -> 83224 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/HapiServer/lib/UriTemplatesJava.jar b/HapiServer/lib/UriTemplatesJava.jar index 93bb9af4ef7a65fafce28b116b7b00528f8b674b..970d13e35ab75989f5ac9506b4a5fb6b107047cf 100644 GIT binary patch literal 83224 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