package org.fcrepo.test.fesl.policyindex; import java.io.IOException; import org.apache.http.client.ClientProtocolException; import org.fcrepo.test.fesl.util.AuthorizationDeniedException; import org.fcrepo.test.fesl.util.HttpUtils; // FIXME: should spin off readers and updaters into separate classes with the same interface/abstract base class public class PolicyIndexExerciser extends Thread { // counts how many exercisers are currently running private static int updaterRunningCount = 0; private static int readerRunningCount = 0; // record if failed, and reason private Throwable failure; private boolean failed = false; private static int updaterPassedCount = 0; private static int readerPassedCount = 0; private HttpUtils utils = null; private HttpUtils adminUtils = null; private byte[][] objects = null; private String[] pids = null; private static String urlA = "/fedora/objects/test:1000002?format=xml"; private static String urlB = "/fedora/objects/test:1000007?format=xml"; private String url = ""; private boolean isReader = false; private boolean stopped = false; // constructor for an updater public PolicyIndexExerciser(String testurl, String testuser, String testpassword, String adminUrl, String adminUser, String adminPassword, String[] testPids) throws Exception { utils = new HttpUtils(testurl, testuser, testpassword); adminUtils = new HttpUtils(adminUrl, adminUser, adminPassword); pids =testPids; // construct array of foxml policy objects to test on objects = new byte[pids.length][]; for (int i = 0; i < pids.length; i++) { // alternate policy A and policy B String policy = (i % 2) == 0 ? "A" : "B"; objects[i] = PolicyIndexUtils.getPolicyObject(policy, "A", "A", pids[i]); } } // constructor for a reader public PolicyIndexExerciser(String testurl, String testuser, String testpassword) throws Exception { utils = new HttpUtils(testurl, testuser, testpassword); isReader = true; } public void shutdown() { utils.shutdown(); if (adminUtils != null) { adminUtils.shutdown(); } } @Override public void run() { if (isReader) { runReader(); } else { runUpdater(); } } private void runReader() { readerStarted(); try { while (!stopped()) { // read read("A"); read("B"); } readerPass(); } catch (Throwable th) { failed = true; failure = th; } finally { readerFinished(); } } private boolean stopped() { synchronized(this) { return stopped; } } public void stopit() { synchronized(this) { stopped = true; } } private void runUpdater() { updaterStarted(); try { for (int i = 0; i < pids.length; i++) { // read read("A"); read("B"); // add policy add(objects[i]); // read read("A"); read("B"); // delete policy delete(pids[i]); // read read("A"); read("B"); } updaterPass(); } catch (Throwable th) { failed = true; failure = th; } finally { updaterFinished(); } } // access object covered by policy // may succeed or fail depending what policies are actually in force, ignore authz failure private void read(String policy) throws ClientProtocolException, IOException { long startTime = System.nanoTime(); if (policy.equals("A")) { url = urlA; } else if (policy.equals("B")) { url = urlB; } try { utils.get(url); doSleep(startTime, System.nanoTime()); } catch (AuthorizationDeniedException e) { // don't care if access was allowed } } private void add(byte[] object) throws ClientProtocolException, IOException, AuthorizationDeniedException { long startTime = System.nanoTime(); url = "/fedora/objects/new"; adminUtils.post(url, null, object); doSleep(startTime, System.nanoTime()); } private void delete(String pid) throws ClientProtocolException, IOException, AuthorizationDeniedException { long startTime = System.nanoTime(); url = "/fedora/objects/" + pid; adminUtils.delete(url, null); doSleep(startTime, System.nanoTime()); } private static void doSleep(long startTime, long endTime) { try { sleep((endTime - startTime)/2000000); // wait for half the operation's execution time } catch (InterruptedException e) { // should not happen throw new RuntimeException("Sleep failed - " + e.getMessage(), e); } } public static synchronized int updaterRunningCount() { return updaterRunningCount; } private static synchronized void updaterFinished() { updaterRunningCount--; } private static synchronized void updaterStarted() { updaterRunningCount++; } private static synchronized void updaterPass() { updaterPassedCount++; } public static synchronized int updaterPassedCount() { return updaterPassedCount; } public static synchronized int readerRunningCount() { return readerRunningCount; } private static synchronized void readerFinished() { readerRunningCount--; } private static synchronized void readerStarted() { readerRunningCount++; } private static synchronized void readerPass() { readerPassedCount++; } public static synchronized int readerPassedCount() { return readerPassedCount; } public Throwable failure() { return failure; } public boolean failed() { return failed; } public String lastUrl() { return url; } }