From 3456532b94a975ee02c3f1bac2d4983249432f99 Mon Sep 17 00:00:00 2001 From: Paul Millar Date: Thu, 11 Feb 2016 09:57:45 +0100 Subject: [PATCH] statistics: encode '/' in filenames The statistics service creates static HTML pages that describe dCache usage over time as simple files that the webadmin service can serve. Currently the files used to store summary information about pools and store-units derive their filename directly from the pool or store-unit names. Unfortunately pools and store-units may have characters that cannot be represented as filenames in the underlying storage system. With POSIX-like filesystems, the '/' character is not allowed. This patch adds a simple encoding: any '/' character is mapped to the "^s^" sequence and any '^' is mapped to a "^o^" sequence. NB: this patch results in the statistics module loosing track of pools or store-units that have a '^' in the name. Target: master Require-notes: yes Require-book: no Request: 2.14 Request: 2.13 Request: 2.12 Request: 2.11 Request: 2.10 Bug: https://github.com/dCache/dcache/issues/1635 Patch: https://rb.dcache.org/r/8315/ Acked-by: Gerd Behrmann --- .../services/PoolStatisticsV0.java | 43 +++++++++---------- 1 file changed, 20 insertions(+), 23 deletions(-) diff --git a/modules/dcache/src/main/java/diskCacheV111/services/PoolStatisticsV0.java b/modules/dcache/src/main/java/diskCacheV111/services/PoolStatisticsV0.java index c5fc6b2ab26..4eba274c3fd 100644 --- a/modules/dcache/src/main/java/diskCacheV111/services/PoolStatisticsV0.java +++ b/modules/dcache/src/main/java/diskCacheV111/services/PoolStatisticsV0.java @@ -2,6 +2,9 @@ package diskCacheV111.services ; +import com.google.common.escape.Escaper; +import com.google.common.escape.Escapers; +import com.google.common.net.UrlEscapers; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -146,6 +149,12 @@ public class PoolStatisticsV0 extends CellAdapter implements CellCron.TaskRunnab private static final int RESTORE = 10 ; private static final int STORE = 11 ; + private static final Escaper AS_FILENAME = Escapers.builder(). + addEscape('^', "^o^"). + addEscape('/', "^s^"). + build(); + private static final Escaper AS_PATH_ELEMENT = UrlEscapers.urlPathSegmentEscaper(); + private static final String defaultAuthor = "© dCache.org " ; private static final ThreadLocal _pathFromDate = @@ -583,7 +592,7 @@ private void updateHtmlMonth( Calendar calendar ) throws IOException { System.arraycopy(counter, 0, lastInMonth, 0, counter.length); } add( total , counter ) ; - html.add( key , list[i].getName()+File.separator+"index.html" , counter ) ; + html.add(key, AS_PATH_ELEMENT.escape(list[i].getName())+"/index.html", counter); }finally{ try{ br.close() ; }catch(IOException eee ){} @@ -649,7 +658,7 @@ private void updateHtmlYear( Calendar calendar ) throws IOException { System.arraycopy(counter, 0, lastInMonth, 0, counter.length); } add( total , counter ) ; - html.add( key , list[i].getName()+File.separator+"index.html" , counter ) ; + html.add(key, AS_PATH_ELEMENT.escape(list[i].getName())+"/index.html", counter); }finally{ try{ br.close() ; }catch(IOException eee ){} @@ -1194,13 +1203,14 @@ private void prepareDailyHtmlFiles( Calendar calendar ){ // // statistics ... // - html.add( className , "class-"+className+".html" , values ) ; + html.add(className, AS_PATH_ELEMENT.escape(AS_FILENAME.escape("class-"+className+".html")), values); } + String filename = AS_FILENAME.escape("pool-" + poolName + ".html"); if( sum != null ) { - allPoolsHtml.add(poolName, "pool-" + poolName + ".html", sum); + allPoolsHtml.add(poolName, AS_PATH_ELEMENT.escape(filename), sum); } - try (PrintWriter pw = new PrintWriter(new FileWriter(new File(pathBase, "pool-" + poolName + ".html")))) { + try (PrintWriter pw = new PrintWriter(new FileWriter(new File(pathBase, filename)))) { html.setPrintWriter(pw); html.dump(); } @@ -1252,14 +1262,15 @@ private void prepareDailyHtmlFiles( Calendar calendar ){ } add(sum, values); - html.add(poolName, "pool-" + poolName + ".html", values); + html.add(poolName, AS_PATH_ELEMENT.escape("pool-" + poolName + ".html"), values); } + String filename = AS_FILENAME.escape("class-" + className + ".html"); if( sum != null ) { - allClassesHtml.add(className, "class-" + className + ".html", sum); + allClassesHtml.add(className, AS_PATH_ELEMENT.escape(filename), sum); } - try (PrintWriter pw = new PrintWriter(new FileWriter(new File(pathBase, "class-" + className + ".html")))) { + try (PrintWriter pw = new PrintWriter(new FileWriter(new File(pathBase, filename)))) { html.setPrintWriter(pw); html.dump(); } @@ -1732,7 +1743,7 @@ public void reset(){ public void add( String title , String link , long [] counter ){ Object [] o = new Object[3] ; o[0] = title ; - o[1] = makeLink( link ) ; + o[1] = link; o[2] = counter ; _maxCounterValue = Math.max( _maxCounterValue , getNorm(counter) ); _map.put( title , o ) ; @@ -1765,20 +1776,6 @@ public void dump(){ printTrailer(_author+" ; Created : "+new Date().toString()) ; } - private String makeLink( String link ){ - StringBuilder sb = new StringBuilder() ; - for( int i= 0 , n = link.length() ; i < n ; i ++ ){ - char c = link.charAt(i) ; - switch(c){ - case ':' : - sb.append("%3A"); - break ; - default : - sb.append(c); - } - } - return sb.toString() ; - } private void printTableHeader(){ _pw.println("
");