forked from olap4j/olap4j
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Adds a proof-of-concept recording/playback cache for the XMLA driver.…
… To use, uncomment the right lines in test.properties and unzip the xmla/cache/mondrian-xmla-[VERSION].zip file you want to test against. Make sure that the test.properties entry points to the proper file. Known issues: The requests are loaded into memory in a simple hashmap. This is slow. There is also an issue with TestStatementTimeout. Will try to resolve that later. git-svn-id: https://olap4j.svn.sourceforge.net/svnroot/olap4j/trunk@421 c6a108a4-781c-0410-a6c6-c2d559e19af0
- Loading branch information
1 parent
aa89f47
commit 7915295
Showing
3 changed files
with
173 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
156 changes: 156 additions & 0 deletions
156
testsrc/org/olap4j/driver/xmla/cache/XmlaTextFileCache.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,156 @@ | ||
package org.olap4j.driver.xmla.cache; | ||
|
||
import java.io.BufferedReader; | ||
import java.io.DataInputStream; | ||
import java.io.File; | ||
import java.io.FileInputStream; | ||
import java.io.FileWriter; | ||
import java.io.IOException; | ||
import java.io.InputStreamReader; | ||
import java.net.URL; | ||
import java.util.Map; | ||
import java.util.StringTokenizer; | ||
import java.util.concurrent.ConcurrentHashMap; | ||
|
||
import org.olap4j.impl.Base64; | ||
|
||
/** | ||
* This mock server cache is only used to save and load | ||
* runs of the XMLA driver as an external file. | ||
* @author LBoudreau | ||
*/ | ||
public class XmlaTextFileCache implements XmlaOlap4jCache { | ||
|
||
private static boolean initDone = false; | ||
private final static String CACHE_IDENT= "Chunky Bacon!"; | ||
private final static ConcurrentHashMap<String, byte[]> cache = | ||
new ConcurrentHashMap<String, byte[]>(); | ||
|
||
public static enum Properties { | ||
/** | ||
* File to save the requests to, if RECORD is true. | ||
* java.util.File(path) will be used. | ||
*/ | ||
OUTPUT, | ||
/** | ||
* File to read the requests from, if PLAY is true. | ||
* java.util.File(path) will be used. | ||
*/ | ||
INPUT, | ||
/** | ||
* Whether to record the requests/responses to a file. | ||
*/ | ||
RECORD, | ||
/** | ||
* Whether to playback responses from a file. | ||
*/ | ||
PLAY, | ||
} | ||
|
||
private static File output = null; | ||
private static File input = null; | ||
private static boolean record = false; | ||
private static boolean play = false;; | ||
|
||
public void flushCache() { | ||
// no op | ||
} | ||
|
||
public byte[] get(String id, URL url, byte[] request) | ||
throws XmlaOlap4jInvalidStateException | ||
{ | ||
synchronized (cache) { | ||
if (play && input != null) { | ||
return cache.get(new String(request)); | ||
} else { | ||
return null; | ||
} | ||
} | ||
} | ||
|
||
public void put(String id, URL url, byte[] request, byte[] response) | ||
throws XmlaOlap4jInvalidStateException | ||
{ | ||
synchronized (cache) { | ||
if (record && output != null) { | ||
String base64Request = Base64.encodeBytes(request); | ||
String base64Response = Base64.encodeBytes(response); | ||
try { | ||
FileWriter writer = new FileWriter(output, true); | ||
try | ||
{ | ||
writer.write(base64Request); | ||
writer.write("\r\n||\r\n"); | ||
writer.write(base64Response); | ||
writer.write("\r\n||\r\n"); | ||
writer.flush(); | ||
} finally { | ||
writer.close(); | ||
} | ||
} catch (IOException e) { | ||
throw new RuntimeException(e); | ||
} | ||
} | ||
} | ||
} | ||
|
||
public String setParameters(Map<String, String> config, | ||
Map<String, String> props) | ||
{ | ||
if (!initDone) { | ||
synchronized (cache) { | ||
cache.clear(); | ||
try { | ||
if (props.containsKey(Properties.RECORD.name()) | ||
&& props.containsKey(Properties.OUTPUT.name())) | ||
{ | ||
record = true; | ||
output = new File(props.get(Properties.OUTPUT.name())); | ||
if (!output.exists() | ||
&& !output.createNewFile()) { | ||
throw new RuntimeException( | ||
"Failed to create output file."); | ||
} | ||
} | ||
if (props.containsKey(Properties.PLAY.name()) | ||
&& props.containsKey(Properties.INPUT.name())) | ||
{ | ||
play = true; | ||
input = new File(props.get(Properties.INPUT.name())); | ||
if (input.exists()) { | ||
FileInputStream fstream = | ||
new FileInputStream(input); | ||
DataInputStream in = | ||
new DataInputStream(fstream); | ||
BufferedReader br = | ||
new BufferedReader(new InputStreamReader(in)); | ||
String strLine; | ||
StringBuilder sb = new StringBuilder(); | ||
while ((strLine = br.readLine()) != null) { | ||
sb.append(strLine); | ||
} | ||
StringTokenizer st = | ||
new StringTokenizer( | ||
sb.toString(), | ||
"\r\n|||\r\n"); | ||
while (st.hasMoreTokens()) { | ||
byte[] request = | ||
Base64.decode(st.nextToken()); | ||
byte[] response = | ||
Base64.decode(st.nextToken()); | ||
cache.put(new String(request), response); | ||
} | ||
in.close(); | ||
} | ||
} | ||
} catch (Exception e) { | ||
throw new RuntimeException( | ||
"Failed to configure the mock server cache.", | ||
e); | ||
} | ||
} | ||
} | ||
return CACHE_IDENT; | ||
} | ||
|
||
} |
Binary file not shown.