Browse Source

Adding admin.html and updating all Admin API endpoints to return valid JSON responses. Updated cache-dump handler to download cache in JSON format.

Matt Clark 3 months ago
parent
commit
ac936d92f9

+ 59 - 0
resources/admin.html

@@ -0,0 +1,59 @@
+<html>
+<head>
+<title>BarcodeAPI.org</title>
+
+<meta name="viewport" content="width=device-width, initial-scale=1.0">
+
+<meta name="keywords"
+	content="barcode, barcode app, barcode generator, barcode api, qr code, qr code generator, code 128, code128, ean8, eac-8, ean13, ean-13, codabar, download barcode, barcodes, pdf, pdf 417">
+<meta name="description"
+	content="Generate barcodes of nearly any type, scan it in the web browser, or download the generated images for free.">
+
+<link rel="icon" type="image/png" href="/static/favicon.png" />
+<script src="/static/index.js"></script>
+<link rel="stylesheet" type="text/css"
+	href="/static/flexboxgrid.min.css" />
+<link rel="stylesheet" type="text/css" href="/static/index.css" />
+</head>
+
+<body onload="loadHash(); init();">
+	<div class="wrap container-fluid">
+
+		<div class="header row middle-xs between-xs">
+			<div class="col-xs-12 col-sm-3">
+				<div class="logo">
+					<img src="/img/barcodeapi-logo.svg" alt="BarcodeAPI Logo"
+						aria-label="Logo">
+				</div>
+			</div>
+		</div>
+
+		<b>Server</b>
+		<br />
+		<a href="/server/about">Server Information</a>
+		<br />
+		<a href="/server/stats">Server Statistics</a>
+		<br />
+		<a href="/admin/server/reload">Reload Config</a>
+		<br />
+		<br />
+		<b>Cache</b>
+		<br />
+		<a href="/admin/cache/dump">Download Cache</a>
+		<br />
+		<a href="/admin/cache/flush">Flush Barcode Caches</a>
+		<br />
+		<br />
+		<b>Session</b>
+		<br />
+		<a href="/session">Current Session</a>
+		<br />
+		<a href="/admin/session/list">Session List</a>
+		<br />
+		<a href="/admin/session/flush">Flush Sessions</a>
+		<br />
+	</div>
+
+</body>
+</html>
+

+ 1 - 1
src/main/java/org/barcodeapi/core/ServerRuntime.java

@@ -28,7 +28,7 @@ public class ServerRuntime {
 		StatsCollector.getInstance()//
 				.setValue(_RUNTIME_TIMESTART, "system", "time", "start");
 
-		_RUNTIME_VERSION = "";
+		_RUNTIME_VERSION = "2";
 		StatsCollector.getInstance()//
 				.setValue(_RUNTIME_VERSION, "system", "version");
 

+ 23 - 5
src/main/java/org/barcodeapi/server/admin/CacheDumpHandler.java

@@ -1,14 +1,18 @@
 package org.barcodeapi.server.admin;
 
 import java.io.IOException;
+import java.util.Map;
 
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 
 import org.barcodeapi.server.cache.BarcodeCache;
+import org.barcodeapi.server.core.CachedObject;
 import org.barcodeapi.server.core.RestHandler;
 import org.barcodeapi.server.gen.CodeType;
+import org.json.JSONArray;
 import org.json.JSONException;
+import org.json.JSONObject;
 
 public class CacheDumpHandler extends RestHandler {
 
@@ -21,14 +25,28 @@ public class CacheDumpHandler extends RestHandler {
 			throws JSONException, IOException {
 
 		// loop all caches
-		String output = "";
+		JSONObject types = new JSONObject();
 		for (CodeType type : CodeType.values()) {
-			for (String key : BarcodeCache.getCache(type).getKeys()) {
-				output += type.toString() + ":" + key + "\n";
+
+			JSONArray entries = new JSONArray();
+			types.put(type.toString(), entries);
+
+			// loop all cached objects
+			for (Map.Entry<String, CachedObject> entry : BarcodeCache.getCache(type).getRawCache().entrySet()) {
+
+				entries.put(new JSONObject()//
+						.put("text", entry.getKey())//
+						.put("hits", entry.getValue().getAccessCount()));
 			}
 		}
 
-		// write to client
-		response.getOutputStream().println(output);
+		// download the results
+		response.setHeader("Content-Type", "application/json");
+		response.setHeader("Content-Disposition", "attachment, filename=cache.json");
+
+		// print response to client
+		JSONObject output = new JSONObject()//
+				.put("cache", types);
+		response.getOutputStream().println(output.toString(4));
 	}
 }

+ 11 - 1
src/main/java/org/barcodeapi/server/admin/CacheFlushHandler.java

@@ -9,6 +9,7 @@ import org.barcodeapi.server.cache.BarcodeCache;
 import org.barcodeapi.server.core.RestHandler;
 import org.barcodeapi.server.gen.CodeType;
 import org.json.JSONException;
+import org.json.JSONObject;
 
 public class CacheFlushHandler extends RestHandler {
 
@@ -20,8 +21,17 @@ public class CacheFlushHandler extends RestHandler {
 	protected void onRequest(HttpServletRequest request, HttpServletResponse response)
 			throws JSONException, IOException {
 
+		JSONObject counts = new JSONObject();
 		for (CodeType type : CodeType.values()) {
-			BarcodeCache.getCache(type).clearCache();
+
+			double count = BarcodeCache.getCache(type).clearCache();
+			counts.put(type.toString(), count);
 		}
+
+		// print response to client
+		JSONObject output = new JSONObject()//
+				.put("message", "caches flushed")//
+				.put("counts", counts);
+		response.getOutputStream().println(output.toString(4));
 	}
 }

+ 6 - 0
src/main/java/org/barcodeapi/server/admin/ConfigReloadHandler.java

@@ -9,6 +9,7 @@ import org.barcodeapi.server.core.Authlist;
 import org.barcodeapi.server.core.Blacklist;
 import org.barcodeapi.server.core.RestHandler;
 import org.json.JSONException;
+import org.json.JSONObject;
 
 public class ConfigReloadHandler extends RestHandler {
 
@@ -22,5 +23,10 @@ public class ConfigReloadHandler extends RestHandler {
 
 		Authlist.reload();
 		Blacklist.reload();
+
+		// print response to client
+		JSONObject output = new JSONObject()//
+				.put("message", "config reloaded");
+		response.getOutputStream().println(output.toString(4));
 	}
 }

+ 8 - 1
src/main/java/org/barcodeapi/server/admin/SessionFlushHandler.java

@@ -8,6 +8,7 @@ import javax.servlet.http.HttpServletResponse;
 import org.barcodeapi.server.core.RestHandler;
 import org.barcodeapi.server.session.SessionCache;
 import org.json.JSONException;
+import org.json.JSONObject;
 
 public class SessionFlushHandler extends RestHandler {
 
@@ -19,6 +20,12 @@ public class SessionFlushHandler extends RestHandler {
 	protected void onRequest(HttpServletRequest request, HttpServletResponse response)
 			throws JSONException, IOException {
 
-		SessionCache.getCache().clearCache();
+		double count = SessionCache.getCache().clearCache();
+
+		// print response to client
+		JSONObject output = new JSONObject()//
+				.put("message", "sessions flushed")//
+				.put("count", count);
+		response.getOutputStream().println(output.toString(4));
 	}
 }

+ 10 - 5
src/main/java/org/barcodeapi/server/admin/SessionListHandler.java

@@ -7,7 +7,9 @@ import javax.servlet.http.HttpServletResponse;
 
 import org.barcodeapi.server.core.RestHandler;
 import org.barcodeapi.server.session.SessionCache;
+import org.json.JSONArray;
 import org.json.JSONException;
+import org.json.JSONObject;
 
 public class SessionListHandler extends RestHandler {
 
@@ -19,12 +21,15 @@ public class SessionListHandler extends RestHandler {
 	protected void onRequest(HttpServletRequest request, HttpServletResponse response)
 			throws JSONException, IOException {
 
-		String output = "";
-		for (String key : SessionCache.getCache().getKeys()) {
-			output += key + "\n";
+		JSONArray sessions = new JSONArray();
+		for (String key : SessionCache.getCache().getRawCache().keySet()) {
+			sessions.put(key);
 		}
 
-		// write to client
-		response.getOutputStream().println(output);
+		// print response to client
+		JSONObject output = new JSONObject()//
+				.put("sessions", sessions)//
+				.put("count", sessions.length());
+		response.getOutputStream().println(output.toString(4));
 	}
 }

+ 4 - 3
src/main/java/org/barcodeapi/server/api/AboutHandler.java

@@ -20,12 +20,13 @@ public class AboutHandler extends RestHandler {
 	protected void onRequest(HttpServletRequest request, HttpServletResponse response)
 			throws JSONException, IOException {
 
-		response.getOutputStream().println((new JSONObject()//
+		// print response to client
+		JSONObject output = new JSONObject()//
 				.put("runtimeId", ServerRuntime.getRuntimeID())//
 				.put("uptime", ServerRuntime.getTimeRunning())//
 				.put("admin", "---")//
 				.put("hostname", ServerRuntime.getHostname())//
-				.put("version", ServerRuntime.getVersion())//
-		).toString(4));
+				.put("version", ServerRuntime.getVersion());
+		response.getOutputStream().println(output.toString(4));
 	}
 }

+ 2 - 3
src/main/java/org/barcodeapi/server/api/SessionDetailsHandler.java

@@ -18,8 +18,7 @@ public class SessionDetailsHandler extends RestHandler {
 	protected void onRequest(HttpServletRequest request, HttpServletResponse response)
 			throws JSONException, IOException {
 
-		// print user session details
-		response.getOutputStream()//
-				.println(getSession(request).getDetails());
+		// print response to client
+		response.getOutputStream().println(getSession(request).getDetails().toString(4));
 	}
 }

+ 2 - 1
src/main/java/org/barcodeapi/server/api/StatsHandler.java

@@ -18,6 +18,7 @@ public class StatsHandler extends RestHandler {
 	protected void onRequest(HttpServletRequest request, HttpServletResponse response)
 			throws JSONException, IOException {
 
-		response.getOutputStream().println(getStats().getDetails().toString(2));
+		// print response to client
+		response.getOutputStream().println(getStats().getDetails().toString(4));
 	}
 }

+ 3 - 1
src/main/java/org/barcodeapi/server/api/TypesHandler.java

@@ -21,6 +21,7 @@ public class TypesHandler extends RestHandler {
 	protected void onRequest(HttpServletRequest request, HttpServletResponse response)
 			throws JSONException, IOException {
 
+		// loop all supported types
 		JSONArray output = new JSONArray();
 		for (CodeType type : CodeType.values()) {
 			output.put(new JSONObject()//
@@ -30,6 +31,7 @@ public class TypesHandler extends RestHandler {
 					.put("description", type.getDescription()));
 		}
 
-		response.getOutputStream().println(output.toString());
+		// print response to client
+		response.getOutputStream().println(output.toString(4));
 	}
 }

+ 7 - 0
src/main/java/org/barcodeapi/server/core/CachedObject.java

@@ -7,9 +7,11 @@ public abstract class CachedObject {
 	private final long timeCreated;
 	private long timeTimeout;
 	private long timeTouched;
+	private long accessCount;
 
 	public CachedObject() {
 
+		this.accessCount = 0;
 		this.timeCreated = System.currentTimeMillis();
 
 		this.touch();
@@ -36,7 +38,12 @@ public abstract class CachedObject {
 		this.timeTimeout = TimeUnit.MILLISECONDS.convert(timeoutTime, timeoutUnit);
 	}
 
+	public long getAccessCount() {
+		return accessCount;
+	}
+
 	protected void touch() {
+		accessCount += 1;
 		timeTouched = System.currentTimeMillis();
 	}
 

+ 7 - 6
src/main/java/org/barcodeapi/server/core/ObjectCache.java

@@ -2,7 +2,6 @@ package org.barcodeapi.server.core;
 
 import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentHashMap.KeySetView;
 
 import org.barcodeapi.server.core.Log.LOG;
 import org.barcodeapi.server.statistics.StatsCollector;
@@ -70,8 +69,8 @@ public class ObjectCache {
 		return cache.get(key);
 	}
 
-	public KeySetView<String, CachedObject> getKeys() {
-		return cache.keySet();
+	public ConcurrentHashMap<String, CachedObject> getRawCache() {
+		return cache;
 	}
 
 	public CachedObject remove(String key) {
@@ -80,14 +79,16 @@ public class ObjectCache {
 		return cache.remove(key);
 	}
 
-	public void clearCache() {
+	public double clearCache() {
 
+		double cleared = 0;
 		synchronized (cache) {
 
-			double num = cache.size();
-			stats.hitCounter(num, "cache", name, "clear");
+			cleared = cache.size();
+			stats.hitCounter(cleared, "cache", name, "clear");
 			cache.clear();
 		}
+		return cleared;
 	}
 
 	public static synchronized ObjectCache getCache(String name) {

+ 3 - 2
src/main/java/org/barcodeapi/server/core/RestHandler.java

@@ -100,7 +100,7 @@ public abstract class RestHandler extends AbstractHandler {
 		response.setStatus(HttpServletResponse.SC_OK);
 
 		// log the request
-		Log.out(LOG.REQUEST, _NAME + " : " + target + " : " + source + " : " + from);
+		Log.out(LOG.REQUEST, String.format("%s : %s : %s : %s", _NAME, target, source, from));
 
 		// server details
 		addCORSHeaders(baseRequest, response);
@@ -117,7 +117,8 @@ public abstract class RestHandler extends AbstractHandler {
 		// authenticate the user if required
 		if (authRequired() && !validateAdmin(request)) {
 
-			getStats().hitCounter("request", "authfail", request.getMethod());
+			getStats().hitCounter("request", "authfail");
+			getStats().hitCounter("request", "target", _NAME, "authfail");
 			response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
 			response.setHeader("WWW-Authenticate", "Basic realm=BarcodeAPI.org Admin API");
 			return;

+ 17 - 14
src/main/java/org/barcodeapi/server/session/CachedSession.java

@@ -1,5 +1,6 @@
 package org.barcodeapi.server.session;
 
+import java.util.Map;
 import java.util.UUID;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.TimeUnit;
@@ -7,6 +8,8 @@ import java.util.concurrent.TimeUnit;
 import javax.servlet.http.Cookie;
 
 import org.barcodeapi.server.core.CachedObject;
+import org.json.JSONArray;
+import org.json.JSONObject;
 
 public class CachedSession extends CachedObject {
 
@@ -37,25 +40,25 @@ public class CachedSession extends CachedObject {
 		sessionRequests.put(data, sessionRequests.get(data) + 1);
 	}
 
-	public String getDetails() {
+	public JSONObject getDetails() {
 
-		String requests = "";
 		int requestCount = 0;
-		for (String key : sessionRequests.keySet()) {
+		JSONArray requests = new JSONArray();
+		for (Map.Entry<String, Integer> entry : sessionRequests.entrySet()) {
 
-			int count = sessionRequests.get(key);
-			requestCount += count;
-
-			requests += String.format("%4d :: %s\n", count, key);
+			requestCount += entry.getValue();
+			requests.put(new JSONObject()//
+					.put("text", entry.getKey())//
+					.put("hits", entry.getValue()));
 		}
 
-		return "\n" + //
-				" Key: " + getKey() + "\n" + //
-				" Created: " + getTimeCreated() + "\n" + //
-				" Last Seen: " + getTimeLastSeen() + "\n" + //
-				" Expiration: " + getTimeExpires() + "\n" + //
-				" Request Count: " + requestCount + "\n" + //
-				"\n  --\n\n" + requests;
+		return new JSONObject()//
+				.put("sessionKey", getKey())//
+				.put("timeCreated", getTimeCreated())//
+				.put("timeLastSeen", getTimeLastSeen())//
+				.put("timeExpires", getTimeExpires())//
+				.put("requestCount", requestCount)//
+				.put("requestList", requests);
 	}
 
 	public Cookie getCookie() {