/*
* Copyright (C) 2010 eXo Platform SAS.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.exoplatform.services.jcr.cluster.load.query;
import org.exoplatform.services.jcr.JcrImplBaseTest;
import org.exoplatform.services.jcr.cluster.load.AbstractAvgResponseTimeTest;
import org.exoplatform.services.jcr.cluster.load.AbstractTestAgent;
import org.exoplatform.services.jcr.cluster.load.NodeInfo;
import org.exoplatform.services.jcr.cluster.load.ResultCollector;
import org.exoplatform.services.jcr.core.CredentialsImpl;
import org.exoplatform.services.jcr.impl.core.RepositoryImpl;
import java.util.List;
import java.util.Random;
import java.util.UUID;
import java.util.concurrent.CountDownLatch;
import javax.jcr.AccessDeniedException;
import javax.jcr.InvalidItemStateException;
import javax.jcr.ItemExistsException;
import javax.jcr.LoginException;
import javax.jcr.NoSuchWorkspaceException;
import javax.jcr.Node;
import javax.jcr.PathNotFoundException;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.jcr.lock.LockException;
import javax.jcr.nodetype.ConstraintViolationException;
import javax.jcr.nodetype.NoSuchNodeTypeException;
import javax.jcr.query.Query;
import javax.jcr.query.QueryResult;
import javax.jcr.version.VersionException;
/**
* @author <a href="mailto:Sergey.Kabashnyuk@exoplatform.org">Sergey Kabashnyuk</a>
* @version $Id: exo-jboss-codetemplates.xml 34360 2009-07-22 23:58:59Z ksm $
*
*/
public class JcrQueryAvgResponseTimeTest extends JcrImplBaseTest
{
/**
* 2min default time of work of one iteration.
*/
private static final int ITERATION_TIME = 60 * 1000;
/**
* How much thread will be added on the next iteration.
*/
private static final int ITERATION_GROWING_POLL = 15;
/**
* Number between 0 and 100 show % how many read operations.
*/
private static final int READ_VALUE = 90;
private static final String[] words =
new String[]{"private", "branch", "final", "string", "logging", "bottle", "property", "node", "repository",
"exception", "cycle", "value", "index", "meaning", "strange", "words", "hello", "outline", "finest",
"basetest", "writer"};
public static final String FIELDNAME_COUNT = "count";
public static final String FIELDNAME_CONTENT = "Content";
public static final String FIELDNAME_STATISTIC = "Statistic";
private static final String TEST_ROOT = "JcrQueryAvgResponceTimeTest";
public void testname() throws Exception
{
QueryAvgResponceTimeTest test =
new QueryAvgResponceTimeTest(repository, ITERATION_GROWING_POLL, ITERATION_TIME, 5, READ_VALUE);
test.testResponce();
}
private class QueryAvgResponceTimeTest extends AbstractAvgResponseTimeTest
{
private final RepositoryImpl repository;
/**
* @param iterationGrowingPoll
* @param iterationTime
* @param initialSize
* @param readValue
*/
public QueryAvgResponceTimeTest(RepositoryImpl repository, int iterationGrowingPoll, int iterationTime,
int initialSize, int readValue)
{
super(iterationGrowingPoll, iterationTime, initialSize, readValue);
this.repository = repository;
}
/**
* @see org.exoplatform.services.jcr.cluster.load.AbstractAvgResponseTimeTest#getAgent(java.util.List, java.util.List, java.util.concurrent.CountDownLatch, int, java.util.Random)
*/
@Override
protected AbstractTestAgent getAgent(List<NodeInfo> nodesPath, ResultCollector resultCollector,
CountDownLatch startSignal, int readValue, Random random, boolean isReadThread)
{
return new QueryTestAgent(repository, nodesPath, resultCollector, startSignal, readValue, random, isReadThread);
}
}
private class QueryTestAgent extends AbstractTestAgent
{
private final RepositoryImpl repository;
private UUID threadUUID;
/**
* @param repository
* @param nodesPath
* @param responceResults
* @param startSignal
* @param READ_VALUE
* @param random
*/
public QueryTestAgent(RepositoryImpl repository, List<NodeInfo> nodesPath, ResultCollector resultCollector,
CountDownLatch startSignal, int readValue, Random random, boolean isReadThread)
{
super(nodesPath, resultCollector, startSignal, readValue, random, true);
this.threadUUID = UUID.randomUUID();
this.repository = repository;
initRoot();
}
/**
* @param repository
* @throws LoginException
* @throws NoSuchWorkspaceException
* @throws RepositoryException
* @throws ItemExistsException
* @throws PathNotFoundException
* @throws VersionException
* @throws ConstraintViolationException
* @throws LockException
* @throws AccessDeniedException
* @throws InvalidItemStateException
* @throws NoSuchNodeTypeException
*/
private void initRoot()
{
int maxAttempts = 10;
CredentialsImpl credentials = new CredentialsImpl("admin", "admin".toCharArray());
for (int i = 0; i < maxAttempts; i++)
{
boolean isSuccessful = false;
Session sessionLocal = null;
try
{
sessionLocal = repository.login(credentials, "ws");
// prepare nodes
Node wsRoot = sessionLocal.getRootNode();
Node threadNode = getOrCreateNode(getOrCreateNode(TEST_ROOT, wsRoot), threadUUID);
sessionLocal.save();
sessionLocal.logout();
sessionLocal = null;
isSuccessful = true;
}
catch (RepositoryException e)
{
log.error("error on creating root attempt " + i + " from " + maxAttempts);
}
finally
{
if (sessionLocal != null)
{
try
{
sessionLocal.refresh(false);
sessionLocal.logout();
}
catch (RepositoryException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
if (isSuccessful)
{
break;
}
}
}
/**
* @see org.exoplatform.services.jcr.cluster.load.AbstractTestAgent#doRead(java.util.List)
*/
@Override
public void doRead(List<NodeInfo> nodesPath, ResultCollector resultCollector)
{
Session sessionLocal = null;
try
{
// login
CredentialsImpl credentials = new CredentialsImpl("admin", "admin".toCharArray());
sessionLocal = repository.login(credentials, "ws");
Node testRoot = sessionLocal.getRootNode().getNode(TEST_ROOT);
// prepare nodes
int i = random.nextInt(words.length);
String word = words[i];
Query q =
sessionLocal.getWorkspace().getQueryManager().createQuery(
"SELECT * FROM nt:base WHERE " + FIELDNAME_CONTENT + "='" + word + "' AND jcr:path LIKE '"
+ testRoot.getPath() + "/%'", Query.SQL);
long start = System.currentTimeMillis();
QueryResult res = q.execute();
long sqlsize = res.getNodes().getSize();
resultCollector.addResult(true, System.currentTimeMillis() - start);
//log.info(word + " found:" + sqlsize + " time=" + (System.currentTimeMillis() - start));
}
catch (Exception e)
{
log.error(e);
}
finally
{
if (sessionLocal != null)
{
sessionLocal.logout();
sessionLocal = null;
}
}
}
/**
* @see org.exoplatform.services.jcr.cluster.load.AbstractTestAgent#doWrite(java.util.List)
*/
@Override
public void doWrite(List<NodeInfo> nodesPath, ResultCollector resultCollector)
{
// get any word
int i = random.nextInt(words.length);
String word = words[i];
Session sessionLocal = null;
try
{
CredentialsImpl credentials = new CredentialsImpl("admin", "admin".toCharArray());
sessionLocal = repository.login(credentials, "ws");
long start = System.currentTimeMillis();
Node threadNode = getOrCreateNode(getOrCreateNode(TEST_ROOT, sessionLocal.getRootNode()), threadUUID);
addCountent(threadNode, UUID.randomUUID(), word);
sessionLocal.save();
resultCollector.addResult(false, System.currentTimeMillis() - start);
//log.info(word + " time : " + (System.currentTimeMillis() - start));
}
catch (Exception e1)
{
if (sessionLocal != null)
{
// discard session changes
try
{
sessionLocal.refresh(false);
}
catch (RepositoryException e)
{
log.error("An error occurs", e);
}
}
log.error("An error occurs", e1);
}
finally
{
if (sessionLocal != null)
{
sessionLocal.logout();
sessionLocal = null;
}
}
}
private void addCountent(Node testRoot, UUID nodePath, String content) throws RepositoryException
{
Node l5 = getOrCreateNode(testRoot, nodePath);
l5.setProperty(FIELDNAME_CONTENT, content);
}
private Node getOrCreateNode(Node testRoot, UUID nodePath) throws RepositoryException
{
String uuidPath = nodePath.toString();
Node l1 = getOrCreateNode(uuidPath.substring(0, 8), testRoot);
Node l2 = getOrCreateNode(uuidPath.substring(9, 13), l1);
Node l3 = getOrCreateNode(uuidPath.substring(14, 18), l2);
Node l4 = getOrCreateNode(uuidPath.substring(19, 23), l3);
return getOrCreateNode(uuidPath.substring(24), l4);
}
/**
* Gets or creates node
*
* @param name
* @param parent
* @return
* @throws RepositoryException
*/
private Node getOrCreateNode(String name, Node parent) throws RepositoryException
{
if (parent.hasNode(name))
{
return parent.getNode(name);
}
return parent.addNode(name);
}
}
}