I have created folder using superuser and provided read-only access to folder for application user.
When trying to query all accessible folders(nt:folder), getting properties list as empty.
Partial code to reproduce:
Created folder:
public Node createFolder(Session adminSession) {
try {
Node parentNode = adminSession.getNode("/MyCompany/CommonFolder”);
if(!parentNode.hasNode("T1")){
Node node = parentNode.addNode("T1", "nt:folder");
node.addMixin("et:folderProperties");
node.setProperty("et:folderName", "T1");
node.addMixin("rep:AccessControllable");
session.save(); return node;
}else {
System.out.println("Node already exists");
}
} catch (RepositoryException e) {
e.printStackTrace();
}
return null;
}
Sharing to user(Principal based)
accessControlManager = (JackrabbitAccessControlManager)
adminSession.getAccessControlManager();
accessControlPolicy = accessControlManager.getApplicablePolicies(userPrincipal);
// for ex., principal is appuser1
if(accessControlPolicy != null && accessControlPolicy.length > 0) {
accessControlList = (JackrabbitAccessControlList) accessControlPolicy[0];
}else {
accessControlPolicy = accessControlManager.getPolicies(userPrincipal);
accessControlList = (JackrabbitAccessControlList) accessControlPolicy[0];
}
ValueFactory valueFactory = adminSession.getValueFactory();
//Tried all combinations, even providing with "JCR:ALL";
Privilege[] readPrivilege = new javax.jcr.security.Privilege[] {
accessControlManager.privilegeFromName(
javax.jcr.security.Privilege.JCR_READ),
accessControlManager.privilegeFromName(
javax.jcr.security.Privilege.JCR_NODE_TYPE_MANAGEMENT),
accessControlManager.privilegeFromName(
javax.jcr.security.Privilege.JCR_READ_ACCESS_CONTROL)};
Map<String, Value> restrictions = new HashMap<String, Value>();
restrictions.put("rep:nodePath", valueFactory.createValue("/MyCompany/CommonFolder/T1",
PropertyType.PATH));
restrictions.put("rep:glob", valueFactory.createValue(""));
accessControlList.addEntry(userPrincipal, privileges, true , restrictions);
accessControlManager.setPolicy(accessControlList.getPath(), accessControlList);
adminSession.save();
Printing all applicable folders for user
public void printAllFolders(Session userSession) {
QueryManager queryManager;
try {
queryManager = userSession.getWorkspace().getQueryManager();
String sql = "SELECT * FROM [nt:folder]";
Query query= queryManager.createQuery(sql, Query.JCR_SQL2);
QueryResult result = query.execute();
NodeIterator nodeIterator = result.getNodes();
System.out.println("Printing all applicable folders");
while(nodeIterator.hasNext()) {
Node node = nodeIterator.nextNode();
System.out.println("Folder Name:" + node.getName() + "; path: " + node.getPath());
PropertyIterator pIterator = node.getProperties();
while (pIterator.hasNext()){ //Returning empty for path "/MyCompany/CommonFolder/T1"
Property property = pIterator.nextProperty();
if (property.getDefinition().isMultiple()) {
Value[] values = property.getValues();
for(Value v11: values) {
QValueValue value = (QValueValue)v11;
System.out.println(String.format("Multi-valued property for node:
'%s' - %s has values",node.getName(),
property.getName() ,value.getString()));
}
} else {
QValueValue value = (QValueValue) property.getValue();
String strValue = value.getString();
System.out.println(String.format("property for node: '%s' - %s has value
%s",node.getName(),property.getName(),strValue));
}
}
}
} catch (RepositoryException e) {
e.printStackTrace();
}
}
using Jackrabbit(2.6.0 version) and JCR( 2.0 version).
Node child = cl.addNode("ONE");
child.setProperty("message", ("CL Child" + i));
session.save();
PropertyIterator iter = child.getProperties();
System.out.println("Size" + iter.getSize());
while (iter.hasNext()) {
PropertyImpl key = (PropertyImpl) iter.next();
String value = key.getString();
System.out.println("------------->" + key);
System.out.println("------------->" + value);
}
Related
I'm using an embedded Neo4j instance in my Spring Boot project (I'm using Spring JPA and Neo4j separately and I'm not using Spring-Boot-Neo4j stuff) and I want to visualise the graph I build using the Neo4j browser that I downloaded from here with the addition of a custom init.coffee that allows it to display images inside the nodes
This is the code I use in order to build my graph. The "buildGraph" function is executed when a request is being received by one of my RestControllers
(the reason I include all of my business logic implementation is because it may help detecting relationships/nodes etc being created/handled in a wrong way)
#Component
public class GraphBuilder
{
private String dbPath;
private int numberOFConnectionsForKeyIndividuals;
private String neo4jBoltAddress;
#Autowired
PersonService personService;
private final GraphDatabaseService graphDb;
public GraphBuilder(#Value("${dbPath}") String dbPath,
#Value("${neo4jBoltAddress}") String neo4jBoltAddress,
#Value("${numberOFConnectionsForKeyIndividuals}") int numberOFConnectionsForKeyIndividuals)
{
GraphDatabaseSettings.BoltConnector bolt = GraphDatabaseSettings.boltConnector( "0" );
this.dbPath = dbPath;
this.neo4jBoltAddress = neo4jBoltAddress;
this.numberOFConnectionsForKeyIndividuals = numberOFConnectionsForKeyIndividuals;
graphDb = new GraphDatabaseFactory()
.newEmbeddedDatabaseBuilder( new File(dbPath) )
.setConfig( bolt.type, "BOLT" )
.setConfig( bolt.enabled, "true" )
.setConfig( bolt.address, neo4jBoltAddress )
.newGraphDatabase();
registerShutdownHook( graphDb );
}
public void buildGraph()
{
List<Long> AsIDs = new ArrayList<>();
Map<Long,Long> personIdToNodeMap = new HashMap<>();
Map<String,List<Long>> nameToId = new HashMap<>();
Map<Long,List<Association>> associationsMap = new HashMap<>();
try ( Transaction tx = graphDb.beginTx() )
{
Schema schema = graphDb.schema();
for(Person person : personService.findAllPersons())
{
Node personNode = graphDb.createNode(new Label() {
#Override
public String name() {
return "Person";
}
});
//mapping persons to their respective nodes
personIdToNodeMap.put(person.getPersonId(),personNode.getId());
//mapping names to the ids of the persons
if(nameToId.get(person.getName()) == null)
{
nameToId.put(person.getName(), new ArrayList<>());
}
nameToId.get(person.getName()).add(person.getPersonId());
personNode.setProperty("Name", person.getName());
for(int a = 0 ; a < person.getAliases().size() ; a++)
{
personNode.setProperty("Alias " + a+1, person.getAliases().get(a).getAlias());
}
personNode.setProperty("Additional Name Information", person.getAdditionalNameInformation() != null ? person.getAdditionalNameInformation() : "");
personNode.setProperty("Id", person.getPersonId());
personNode.setProperty("Date of Birth", person.getDob() != null ? person.getDob() : "");
for(int f = 0 ; f < person.getFacebook().size() ; f++)
{
personNode.setProperty("Facebook " + f+1, person.getFacebook().get(f).getFacebookPage() + " (" + person.getFacebook().get(f).getAdditionalFacebookPageInformation() + ")");
}
personNode.setProperty("Additional Information", person.getInfo() != null ? person.getInfo() : "");
personNode.setProperty("image_url","http://localhost:8888/files/"+person.getPictureFilePath());
personNode.setProperty("Node Type", "Person");
if(person.getAssociations().size() > numberOFConnectionsForKeyIndividuals)
{
personNode.setProperty("Key_Individual","Yes");
}
for(A A : person.getAs())
{
Node ANode = graphDb.createNode(new Label() {
#Override
public String name() {
return "A";
}
});
ANode.setProperty("A", A.getA());
//TODO elaborate more on the A with additional properties
ANode.setProperty("Node Type", "A");
personNode.createRelationshipTo( ANode, EdgeTypes.HAS_DONE );
ANode.setProperty("image_url","http://localhost:8888/images/A.png");
AsIDs.add(ANode.getId());
}
for(Association association : person.getAssociations())
{
if(associationsMap.get(person.getPersonId()) == null)
{
associationsMap.put(person.getPersonId(), new ArrayList<>());
}
associationsMap.get(person.getPersonId()).add(association);
}
}
//Validating and building the association edges
//iterating through the nodes
for(Long personFromId : associationsMap.keySet())
{
//iterating through the associations registered for the node
for(Association associationFrom : associationsMap.get(personFromId))
{
String personNameFrom = associationFrom.getPersonNameFrom();
String personNameTo = associationFrom.getPersonNameTo();
//iterating through the persons whose name matches the other end of the association
if(nameToId.get(personNameTo) != null)
{
for(Long personToId : nameToId.get(personNameTo))
{
//iterating through the associations of the person at the other end of the association
if(associationsMap.get(personToId) != null)
{
List<Association> associationsToRemove = new ArrayList<>();
for(Association associationTo : associationsMap.get(personToId))
{
if(associationTo.getPersonNameTo().equals(personNameFrom) && nameToId.get(personNameFrom).contains(personFromId))
{
if(nameToId.get(personNameFrom).size() == 1)
{
Relationship relationship = graphDb.getNodeById(personIdToNodeMap.get(personFromId))
.createRelationshipTo( graphDb.getNodeById(personIdToNodeMap.get(personToId)), EdgeTypes.ASSOCIATES_WITH );
if(associationFrom.getType() != null)
{
relationship.setProperty("Association Type",associationFrom.getType());
}
associationsToRemove.add(associationTo);
}
else
{
boolean alreadyConnected = false;
for(Relationship rel : graphDb.getNodeById(personIdToNodeMap.get(personFromId)).getRelationships())
{
if( ( rel.getOtherNode(graphDb.getNodeById(personIdToNodeMap.get(personFromId))).
equals(graphDb.getNodeById(personIdToNodeMap.get(personToId))) ) )
{
alreadyConnected = true;
break;
}
}
if(!alreadyConnected)
{
Relationship relationship = graphDb.getNodeById(personIdToNodeMap.get(personFromId))
.createRelationshipTo( graphDb.getNodeById(personIdToNodeMap.get(personToId)), EdgeTypes.PROBABLY_ASSOCIATES_WITH );
if(associationFrom.getType() != null)
{
relationship.setProperty("Association Type",associationFrom.getType());
}
}
// associationsToRemove.add(associationTo);
}
}
}
associationsMap.get(personToId).removeAll(associationsToRemove);
}
}
}
}
}
tx.success();
}
Map<Long,List<String>> AToNamesMap = new HashMap<>();
//detecting names referred in the A's description
try(Transaction txAs = graphDb.beginTx() )
{
for(Long id : AsIDs)
{
Node ANode = graphDb.getNodeById(id);
String A = (String) ANode.getProperty("A");
for(String name : nameToId.keySet())
{
if(A.contains(name)) {
if(AToNamesMap.get(id) == null)
{
AToNamesMap.put(id,new ArrayList<>());
}
AToNamesMap.get(id).add(name);
}
}
}
List<Long> groupedAs = new ArrayList<>();
for(Long id : AsIDs)
{
if(AToNamesMap.get(id)!= null && AToNamesMap.get(id).size() > 1)
{
for(Long otherAID : AToNamesMap.keySet())
{
if(id != otherAID && !groupedAs.contains(otherAID) && !groupedAs.contains(id))
{
if(compareNamesLists(AToNamesMap.get(id), AToNamesMap.get(otherAID)))
{
Relationship rel = graphDb.getNodeById(otherAID).getSingleRelationship(EdgeTypes.HAS_DONE,Direction.INCOMING);
Node otherPersonNode = rel.getStartNode();
if(nameToId.get(otherPersonNode.getProperty("Name")) != null && nameToId.get(otherPersonNode.getProperty("Name")).size() > 1)
{
otherPersonNode.createRelationshipTo(graphDb.getNodeById(id), EdgeTypes.HAS_PROBABLY_DONE);
}
else
{
otherPersonNode.createRelationshipTo(graphDb.getNodeById(id), EdgeTypes.HAD_DONE);
}
rel.delete();
graphDb.getNodeById(otherAID).delete();
groupedAs.add(otherAID);
}
}
}
}
groupedAs.add(id);
}
txAs.success();
}
}
private static void registerShutdownHook( final GraphDatabaseService graphDb )
{
// Registers a shutdown hook for the Neo4j instance so that it
// shuts down nicely when the VM exits (even if you "Ctrl-C" the
// running application).
Runtime.getRuntime().addShutdownHook( new Thread()
{
#Override
public void run()
{
graphDb.shutdown();
}
} );
}
}
When I open the browser and connect it to the bolt that I expose for my embedded neo4j, the browser is able to show all the nodes in my graph database (at the moment less than 100) and it then freezes, causing the entire system to freeze (MacBook Pro 2016, 16GB). This happens around 3/5 times.
I know that the way I make my transactions is not ideal, but as I said all this processing happens before the neo4j browser starts.
Can you advise me on how to solve this issue?
Can you see anything in my code (connection left open etc) Is this a known issue for the neo4j browser?
When I execute the creation of relationships it crashes on session close.
The code:
#Override
public boolean applyCreate(final RelationshipStorage storage, final long snapshotId)
{
final Session sess = db.newSession();
final Graph graph = sess.getGraph();
final Objects startObjs = findNode(graph, storage.getStartNode());
final Objects endObjs = findNode(graph, storage.getEndNode());
if(startObjs == null || endObjs == null)
{
if(startObjs != null)
{
startObjs.close();
}
if(endObjs != null)
{
endObjs.close();
}
sess.close();
return false;
}
final ObjectsIterator startIt = startObjs.iterator();
final ObjectsIterator endIt = endObjs.iterator();
while(startIt.hasNext())
{
long startNode = startIt.next();
while (endIt.hasNext())
{
final long endNode = endIt.next();
int edgeType = graph.findType(storage.getId());
if (Type.InvalidType == edgeType)
{
edgeType = graph.newEdgeType(storage.getId(), true, false);
}
final long relationship = graph.findOrCreateEdge(edgeType, startNode, endNode);
for (final Map.Entry<String, Object> entry : storage.getProperties().entrySet())
{
graph.setAttribute(relationship,
SparkseeUtils.createOrFindAttributeType(entry.getKey(), entry.getValue(), Type.GlobalType, graph),
SparkseeUtils.getValue(entry.getValue()));
}
int snapshotAttributeId = SparkseeUtils.createOrFindAttributeType(Constants.TAG_SNAPSHOT_ID, snapshotId, Type.GlobalType, graph);
graph.setAttribute(relationship, snapshotAttributeId, SparkseeUtils.getValue(snapshotId));
try
{
int hashAttributeId = SparkseeUtils.createOrFindAttributeType(Constants.TAG_HASH, " ", Type.GlobalType, graph);
graph.setAttribute(relationship, hashAttributeId, SparkseeUtils.getValue(HashCreator.sha1FromRelationship(storage)));
}
catch (NoSuchAlgorithmException e)
{
Log.getLogger().warn("Couldn't execute create node transaction in server: " + id, e);
endObjs.close();
startObjs.close();
startIt.close();
endIt.close();
sess.close();
return false;
}
Log.getLogger().warn("Successfully executed create relationship transaction in server: " + id);
}
}
startObjs.close();
endObjs.close();
startIt.close();
endIt.close();
sess.close();
return true;
}
/**
* Return a Objects array matching the nodeType and properties.
* #param graph the graph.
* #param storage the storage of the node.
* #return Objects which match the attributes.
*/
private Objects findNode(final Graph graph, final NodeStorage storage)
{
Objects objects = null;
if(!storage.getId().isEmpty())
{
int nodeTypeId = SparkseeUtils.createOrFindNodeType(storage, graph);
objects = graph.select(nodeTypeId);
}
for (final Map.Entry<String, Object> entry : storage.getProperties().entrySet())
{
final int attributeId = graph.findAttribute(Type.GlobalType, entry.getKey());
if (objects == null || objects.isEmpty())
{
if(objects != null)
{
objects.close();
}
objects = graph.select(attributeId, Condition.Equal, SparkseeUtils.getValue(entry.getValue()));
}
else
{
objects = graph.select(attributeId, Condition.Equal, SparkseeUtils.getValue(entry.getValue()), objects);
}
}
return objects;
}
The crashlog:
Closing sparkseejava.lang.RuntimeException: Session data still active when closing at
com.sparsity.sparkseejavawrapJNI.delete_sparksee_gdb_Session(Native
Method) at com.sparsity.sparksee.gdb.Session.delete(Session.java:32)
at com.sparsity.sparksee.gdb.Session.close(Session.java:40) at
main.java.com.bag.server.database.SparkseeDatabaseAccess.applyCreate(SparkseeDatabaseAccess.java:595)
at
main.java.com.bag.main.DatabaseLoader.loadGraph(DatabaseLoader.java:97)
at
main.java.com.bag.main.DatabaseLoader.main(DatabaseLoader.java:191)
I can't see what I have to close still.
I closed all iterators and objects.
Original answer on google groups:
https://groups.google.com/forum/#!topic/sparksee/brcfhvFzdjg
I have to close the temporary objects "objects" before I assign a new one to it.
Objects tempObj = graph.select(attributeId, Condition.Equal, SparkseeUtils.getValue(entry.getValue()), objects);
objects.close();
objects = tempObj;
I am trying to update multi records with Transaction ebean, however when I am trying more than one record, there is an error on the screen :
[IllegalStateException: Transaction is Inactive]
any idea please ?
public Result savemulti(String selected) throws PersistenceException {
Form<Computer> computerForm = formFactory.form(Computer.class).bindFromRequest();
if(computerForm.hasErrors()) {return badRequest(views.html.computers.editMulti.render(AuthorisedUser.findByEmail(request().username()), computerForm, selected));}
java.util.Date dtcreate = new java.util.Date();
String connectedEmail = ctx().session().get("email");
AuthorisedUser singleUser = AuthorisedUser.findByEmail(connectedEmail);
String[] ids = selected.split(";");
Transaction txn = Ebean.beginTransaction();
try{
for (String temp : ids){
Computer savedComputer = Computer.find.byId(Long.parseLong(temp));
if (savedComputer != null){
Computer newComputerData = computerForm.get();
savedComputer.company = newComputerData.company;
savedComputer.discontinued = newComputerData.discontinued;
savedComputer.introduced = newComputerData.introduced;
savedComputer.name = newComputerData.name;
savedComputer.status = newComputerData.status;
savedComputer.moddt = new java.sql.Timestamp(dtcreate.getTime());
savedComputer.modby = singleUser.userName;
savedComputer.site = singleUser.site;
savedComputer.update();
flash("success", "Computer [ " + computerForm.get().name + " ] has been updated");
txn.commit();
}
}
} finally {
txn.end();
}
return GO_HOME;
}
I just put for before transaction and it works perfectly, thank you.
public Result savemulti(String selected) throws PersistenceException {
Form<Computer> computerForm = formFactory.form(Computer.class).bindFromRequest();
if(computerForm.hasErrors()) {return badRequest(views.html.computers.editMulti.render(AuthorisedUser.findByEmail(request().username()), computerForm, selected));}
java.util.Date dtcreate = new java.util.Date();
String connectedEmail = ctx().session().get("email");
AuthorisedUser singleUser = AuthorisedUser.findByEmail(connectedEmail);
String[] ids = selected.split(";");
for (String temp : ids)
{
Transaction txn = Ebean.beginTransaction();
try
{
Computer savedComputer = Computer.find.byId(Long.parseLong(temp));
if (savedComputer != null)
{
Computer newComputerData = computerForm.get();
savedComputer.company = newComputerData.company;
savedComputer.active = newComputerData.active;
savedComputer.discontinued = newComputerData.discontinued;
savedComputer.introduced = newComputerData.introduced;
savedComputer.name = newComputerData.name;
savedComputer.status = newComputerData.status;
savedComputer.moddt = new java.sql.Timestamp(dtcreate.getTime());
savedComputer.modby = singleUser.userName;
savedComputer.site = singleUser.site;
savedComputer.update();
txn.commit();
}
}
finally { txn.end(); }
}
flash("success", "Computers [ " + selected + " ] has been updated");
return GO_HOME;
}
I am trying to retrieve the PwdLastSet attribute from LDAP using java. It fails and doesn't throw an error. Here's the code:
private String getPasswordLastSet() {
int searchScope = LDAPConnection.SCOPE_BASE;
int ldapVersion = LDAPConnection.LDAP_V3;
int ldapPort = 389;
String ldapHost = "Adapps.domain.mycompany.com";
String loginDN = "cn=myNTusername,OU=users,OU=colorado,OU=corporate,dc=domain,dc=mycompany,dc=com";
String password = "myNTpassword";
String baseDn = "dc=mycompany,dc=com";
LDAPConnection lc = new LDAPConnection();
String attributes[] = {"PwdLastSet"};
String pwdLastSet = null;
try {
lc.connect( ldapHost, ldapPort );
lc.bind( ldapVersion, loginDN, password.getBytes("UTF8") );
String filter = "(sAMAccountName=myNtusername)";
LDAPSearchResults searchResults =
lc.search( baseDn,
searchScope,
filter,
attributes,
true); // return attributes and values
while ( searchResults.hasMore()) {
LDAPEntry nextEntry = null;
try {
actionlogger.debug("about to searchResults.next...");
nextEntry = searchResults.next();
actionlogger.debug("about to nextEntry.getAttribute...");
LDAPAttribute pwdLastSetAttribute = nextEntry.getAttribute("PwdLastSet");
pwdLastSet = pwdLastSetAttribute.getStringValue();
} catch(LDAPException e) {
e.printStackTrace();
} catch(Exception e){
e.printStackTrace();
}
}
} catch( LDAPException e ) {
actionlogger.error( "Error occured while LDAP Search : " + e.getMessage(),e );
} catch (Exception e) {
e.printStackTrace();
}
return pwdLastSet;
}
The output is
about to searchResults.next...
But
about to nextEntry.getAttribute...
is never hit. Any ideas?
It was nearly correct. I just
Changed searchScope to LDAPConnection.SCOPE_SUB;
Changed loginDN = DOMAIN\MyNTusername;
Changed baseDN = "dc=mydomain,dc=mycompany,dc=com";
Changed true to false in lc.search.
Not sure which of those changes caused it to start working.
I am trying to implement paging in an already running application, it works like mongodb where you get a query with bunch of parameters like
searchConditions ,limit( how many docs you want), skip ( skip these many docs)
and so on
and the response is back in json my task is to generate the previous and next link to the query that means previous page and the next page as per query
I came up with a method below
public Paging generateLink(RequestFilter filter) {
int prev_skip;
int prev_limit;
String pagePrev = "";
String pageNext = "";
int next_skip;
int next_limit;
String searchCondition = JsonUtils.toSimpleJsonString(filter.getSearch());
String url = "http://isgswmdi1n1.nam.nsroot.net:7014/account-search/rest/api/v1/pmm";
//properties.getProperty("paging.link");
System.out.println(url);
Paging pagingOption = new Paging();
Result result = new Result();
int count = luceneSearchService.searchCount(filter);
try {
if (count > 1) {
if (filter.getSkip() > 0) {
prev_skip = Math.max((filter.getSkip() - 1), 0);
prev_limit = filter.getLimit();
pagePrev = url + "?search=" + searchCondition + "&skip=" + prev_skip + "$limit=" + prev_limit;
} else{
result.setPaging(null);
return null;
}
if (count > (filter.getLimit() + filter.getSkip())) {
next_skip = (filter.getSkip() + filter.getLimit());
next_limit = filter.getLimit();
pageNext = url + "?search=" + searchCondition + "&skip=" + next_skip + "$limit=" + next_limit;
} else{
result.setPaging(null);
return null;
}
pagingOption.setPagePrev(pagePrev);
pagingOption.setPageNext(pageNext);
result.setPaging(pagingOption);
}
return pagingOption;
} catch (NullPointerException n)
{
n.printStackTrace();
return pagingOption;
}
}
call to generateLink method
return Result.ok(resultRow, generateLink(filter));
the ok response method in the Result class
public static Result ok(List<ResultRow> resultRows, Paging paging) {
if (paging != null) {
return new Result(resultRows, 200, "Completed", paging);
} else
return new Result(resultRows, 200, "Completed");
}
Underlying paging class
public class Paging implements Serializable {
public String getPagePrev() {
return pagePrev;
}
public void setPagePrev(String pagePrev) {
this.pagePrev = pagePrev;
}
#JsonProperty("pagePrev")
private String pagePrev;
public String getPageNext() {
return pageNext;
}
public void setPageNext(String pageNext) {
this.pageNext = pageNext;
}
#JsonProperty("pageNext")
private String pageNext;
}
but my test method is failing
#Test
public void search_allFilterParamsAreDefined_hp() throws Exception {
// given
Map<String, Serializable> searchConditions = singletonMap("shortName", "GO");
List<String> returnFields = asList("shortname", "gfcid");
String returnFieldsStr = returnFields.stream().collect(joining(","));
RequestFilter filter = RequestFilter.create(searchConditions, returnFieldsStr, 5, 10, true);
int resultSize = 20;
List<ResultRow> searchResult = getSearchResult(resultSize);
when(luceneSearchService.search(filter)).thenReturn(searchResult);
when(luceneSearchService.searchCount(filter)).thenReturn(resultSize);
// do
Result result = searchCoordinator.search(filter);
// verify
assertEquals(searchResult, result.getRows());
assertReturnFields(returnFields, result.getRows());
assertNotNull(result.getPaging());
Map<String, String> nextParams = getQueryParams(result.getPaging().getPageNext());
assertParam(nextParams, "search", toSimpleJsonString(searchConditions));
assertParam(nextParams, "skip", "15");
assertParam(nextParams, "limit", "10");
}