Added a file store and added support for lists in the JSONObjectInputStream
This commit is contained in:
parent
6d3b27ed2b
commit
7206636502
5 changed files with 147 additions and 10 deletions
|
|
@ -24,25 +24,30 @@
|
||||||
|
|
||||||
package zutil;
|
package zutil;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class is a timer, it will track time and
|
* This class is a timer, it will track time and
|
||||||
* timeout after a specific amount of time.
|
* timeout after a specific amount of time.
|
||||||
* <br>
|
* <br>
|
||||||
* Note that the {@link #start()} method needs to be called for the timer to start.
|
* Note that the {@link #start()} method needs to be called for the timer to start.
|
||||||
*
|
|
||||||
* Created by Ziver on 2015-07-15.
|
|
||||||
*/
|
*/
|
||||||
public class Timer {
|
public class Timer implements Serializable {
|
||||||
/** The timeout period **/
|
/** The timeout period **/
|
||||||
private long period;
|
private long period;
|
||||||
/** The timestamp when the timer was started, -1 if timer has not been started or has been reset **/
|
/** The timestamp when the timer was started, -1 if timer has not been started or has been reset **/
|
||||||
private long timestamp;
|
private long timestamp;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new timer with no timeout period configured.
|
||||||
|
*/
|
||||||
|
public Timer() {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new timer that will timeout in a specified amount of time from now.
|
* Create a new timer that will timeout in a specified amount of time from now.
|
||||||
*
|
*
|
||||||
* @param millisecond the time in milliseconds that the timeout should happen.
|
* @param millisecond is the period in milliseconds that the timeout should happen in.
|
||||||
*/
|
*/
|
||||||
public Timer(long millisecond) {
|
public Timer(long millisecond) {
|
||||||
this.period = millisecond;
|
this.period = millisecond;
|
||||||
|
|
@ -50,6 +55,17 @@ public class Timer {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets a new timeout period. Note that this will modify the timeout of a already started timer.
|
||||||
|
*
|
||||||
|
* @param millisecond is the new period of timeout in milliseconds.
|
||||||
|
* @return a reference of itself
|
||||||
|
*/
|
||||||
|
public Timer setPeriod(long millisecond) {
|
||||||
|
this.period = millisecond;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Will start or restart the timer if it is already running
|
* Will start or restart the timer if it is already running
|
||||||
*
|
*
|
||||||
|
|
@ -62,9 +78,12 @@ public class Timer {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Will reset the timer so that {@link #hasTimedOut()} returns true
|
* Will reset the timer so that {@link #hasTimedOut()} returns true
|
||||||
|
*
|
||||||
|
* @return a reference of itself
|
||||||
*/
|
*/
|
||||||
public void reset() {
|
public Timer reset() {
|
||||||
timestamp = -1;
|
timestamp = -1;
|
||||||
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
57
src/zutil/net/http/page/oauth/OAuth2RegistryFileStore.java
Normal file
57
src/zutil/net/http/page/oauth/OAuth2RegistryFileStore.java
Normal file
|
|
@ -0,0 +1,57 @@
|
||||||
|
package zutil.net.http.page.oauth;
|
||||||
|
|
||||||
|
import zutil.ObjectUtil;
|
||||||
|
import zutil.io.file.FileUtil;
|
||||||
|
import zutil.log.LogUtil;
|
||||||
|
import zutil.parser.json.JSONObjectInputStream;
|
||||||
|
import zutil.parser.json.JSONObjectOutputStream;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
|
||||||
|
public class OAuth2RegistryFileStore implements OAuth2RegistryStore {
|
||||||
|
private static final Logger logger = LogUtil.getLogger();
|
||||||
|
|
||||||
|
private final File file;
|
||||||
|
private List<OAuth2ClientRegister> registerList = new ArrayList<>();
|
||||||
|
|
||||||
|
|
||||||
|
public OAuth2RegistryFileStore(File file) {
|
||||||
|
this.file = file;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public synchronized List<OAuth2ClientRegister> getClientRegistries() {
|
||||||
|
if (file.exists()) {
|
||||||
|
try {
|
||||||
|
String json = FileUtil.getContent(file);
|
||||||
|
|
||||||
|
if (!ObjectUtil.isEmpty(json)) {
|
||||||
|
registerList = JSONObjectInputStream.parse(json);
|
||||||
|
return registerList;
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.log(Level.SEVERE, "Was unable to read in OAuth2 registry from file: " + file, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public synchronized void storeClientRegister(OAuth2ClientRegister register) {
|
||||||
|
registerList.remove(register);
|
||||||
|
registerList.add(register);
|
||||||
|
|
||||||
|
try {
|
||||||
|
FileUtil.setContent(file, JSONObjectOutputStream.toString(registerList));
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.log(Level.SEVERE, "Was unable to write the OAuth2 registry into file: " + file, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -36,6 +36,7 @@ public interface OAuth2RegistryStore {
|
||||||
public HashMap<String, Timer> accessTokens = new HashMap<>();
|
public HashMap<String, Timer> accessTokens = new HashMap<>();
|
||||||
|
|
||||||
|
|
||||||
|
public OAuth2ClientRegister() {}
|
||||||
public OAuth2ClientRegister(String clientId) {
|
public OAuth2ClientRegister(String clientId) {
|
||||||
this.clientId = clientId;
|
this.clientId = clientId;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -62,7 +62,7 @@ public class JSONObjectInputStream extends InputStream implements ObjectInput, C
|
||||||
*/
|
*/
|
||||||
public static <T> T parse(String json) {
|
public static <T> T parse(String json) {
|
||||||
try {
|
try {
|
||||||
StringInputStream in = new StringInputStream();
|
StringInputStream in = new StringInputStream(json);
|
||||||
JSONObjectInputStream reader = new JSONObjectInputStream(in);
|
JSONObjectInputStream reader = new JSONObjectInputStream(in);
|
||||||
T object = reader.readGenericObject();
|
T object = reader.readGenericObject();
|
||||||
reader.close();
|
reader.close();
|
||||||
|
|
@ -119,7 +119,15 @@ public class JSONObjectInputStream extends InputStream implements ObjectInput, C
|
||||||
try {
|
try {
|
||||||
DataNode root = parser.read();
|
DataNode root = parser.read();
|
||||||
if (root != null) {
|
if (root != null) {
|
||||||
return (T) readObject(c, null, root);
|
if (root.isList()) { // Handle json that starts as an array
|
||||||
|
ArrayList list = new ArrayList();
|
||||||
|
for (DataNode node : root) {
|
||||||
|
list.add((T) readObject(c, null, node));
|
||||||
|
}
|
||||||
|
return (T) list;
|
||||||
|
} else { // Handle json that starts as an object
|
||||||
|
return (T) readObject(c, null, root);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
logger.log(Level.SEVERE, null, e);
|
logger.log(Level.SEVERE, null, e);
|
||||||
|
|
@ -132,7 +140,7 @@ public class JSONObjectInputStream extends InputStream implements ObjectInput, C
|
||||||
|
|
||||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||||
protected Object readType(Class<?> type, Class<?>[] genericType, Object currentValue, String key, DataNode json)
|
protected Object readType(Class<?> type, Class<?>[] genericType, Object currentValue, String key, DataNode json)
|
||||||
throws IllegalAccessException, ClassNotFoundException, InstantiationException, NoSuchFieldException, NoSuchMethodException, InvocationTargetException {
|
throws IllegalAccessException, ClassNotFoundException, InstantiationException, NoSuchMethodException, InvocationTargetException {
|
||||||
|
|
||||||
if (json == null || type == null)
|
if (json == null || type == null)
|
||||||
return null;
|
return null;
|
||||||
|
|
@ -217,12 +225,12 @@ public class JSONObjectInputStream extends InputStream implements ObjectInput, C
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
protected Object readObject(Class<?> type, String key, DataNode json) throws IllegalAccessException, InstantiationException, ClassNotFoundException, IllegalArgumentException, NoSuchFieldException, NoSuchMethodException, InvocationTargetException {
|
protected Object readObject(Class<?> type, String key, DataNode json) throws ClassNotFoundException, IllegalArgumentException {
|
||||||
// Only parse if json is a map
|
// Only parse if json is a map
|
||||||
if (json == null || !json.isMap())
|
if (json == null || !json.isMap())
|
||||||
return null;
|
return null;
|
||||||
// See if the Object id is in the cache before continuing
|
// See if the Object id is in the cache before continuing
|
||||||
if (json.getString("@object_id") != null && objectCache.containsKey(json.getInt(MD_OBJECT_ID)))
|
if (json.getString(MD_OBJECT_ID) != null && objectCache.containsKey(json.getInt(MD_OBJECT_ID)))
|
||||||
return objectCache.get(json.getInt(MD_OBJECT_ID));
|
return objectCache.get(json.getInt(MD_OBJECT_ID));
|
||||||
|
|
||||||
// ------------------------------------------------
|
// ------------------------------------------------
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,52 @@
|
||||||
|
package zutil.net.http.page.oauth;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
import zutil.Timer;
|
||||||
|
import zutil.io.file.FileUtil;
|
||||||
|
import zutil.net.http.page.oauth.OAuth2RegistryStore.OAuth2ClientRegister;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
public class OAuth2RegistryFileStoreTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getClientRegistries() throws IOException {
|
||||||
|
File file = File.createTempFile("oauth2_test", ".json");
|
||||||
|
file.deleteOnExit();
|
||||||
|
FileUtil.setContent(file, "[{\"@class\": \"zutil.net.http.page.oauth.OAuth2RegistryStore$OAuth2ClientRegister\", \"clientId\": \"test-client-id\", \"authCodes\": {\"code-abc\": {\"period\": 100, \"@class\": \"zutil.Timer\", \"@object_id\": 2, \"timestamp\": 2000000000000}}, \"@object_id\": 1, \"accessTokens\": {\"token-abc\": {\"period\": 500, \"@class\": \"zutil.Timer\", \"@object_id\": 3, \"timestamp\": 2000000000000}}}]");
|
||||||
|
|
||||||
|
OAuth2RegistryFileStore store = new OAuth2RegistryFileStore(file);
|
||||||
|
List<OAuth2ClientRegister> list = store.getClientRegistries();
|
||||||
|
|
||||||
|
assertNotNull(list);
|
||||||
|
assertEquals(1, list.size());
|
||||||
|
assertEquals("test-client-id", list.get(0).clientId);
|
||||||
|
assertEquals(2000000000100l, list.get(0).authCodes.get("code-abc").getTimeoutTimeMillis());
|
||||||
|
assertEquals(2000000000500l, list.get(0).accessTokens.get("token-abc").getTimeoutTimeMillis());
|
||||||
|
|
||||||
|
file.delete();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void storeClientRegister() throws IOException {
|
||||||
|
File file = File.createTempFile("oauth2_test", ".json");
|
||||||
|
file.deleteOnExit();
|
||||||
|
|
||||||
|
OAuth2ClientRegister obj = new OAuth2ClientRegister("test-client-id");
|
||||||
|
obj.authCodes.put("code-abc", new Timer(100));
|
||||||
|
obj.accessTokens.put("token-abc", new Timer(500));
|
||||||
|
|
||||||
|
OAuth2RegistryFileStore store = new OAuth2RegistryFileStore(file);
|
||||||
|
store.storeClientRegister(obj);
|
||||||
|
|
||||||
|
assertEquals("[{\"@class\": \"zutil.net.http.page.oauth.OAuth2RegistryStore$OAuth2ClientRegister\", \"clientId\": \"test-client-id\", \"authCodes\": {\"code-abc\": {\"period\": 100, \"@class\": \"zutil.Timer\", \"@object_id\": 2, \"timestamp\": -1}}, \"@object_id\": 1, \"accessTokens\": {\"token-abc\": {\"period\": 500, \"@class\": \"zutil.Timer\", \"@object_id\": 3, \"timestamp\": -1}}}]",
|
||||||
|
FileUtil.getContent(file));
|
||||||
|
|
||||||
|
file.delete();
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue