Skip to content

Commit 2bb87dc

Browse files
committed
Added async API examples
These will be included in the Neo4j developer manual.
1 parent ac7062a commit 2bb87dc

File tree

5 files changed

+262
-12
lines changed

5 files changed

+262
-12
lines changed

driver/src/test/java/org/neo4j/driver/v1/util/StdIOCapture.java

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@
2020

2121
import java.io.ByteArrayOutputStream;
2222
import java.io.PrintStream;
23-
import java.util.LinkedList;
2423
import java.util.List;
24+
import java.util.concurrent.CopyOnWriteArrayList;
2525

2626
import static java.util.Arrays.asList;
2727

@@ -30,8 +30,8 @@
3030
*/
3131
public class StdIOCapture
3232
{
33-
private final List<String> stdout = new LinkedList<>();
34-
private final List<String> stderr = new LinkedList<>();
33+
private final List<String> stdout = new CopyOnWriteArrayList<>();
34+
private final List<String> stderr = new CopyOnWriteArrayList<>();
3535

3636
/** Put this in a try-with-resources block to capture all standard io that happens within the try block */
3737
public AutoCloseable capture()
@@ -44,16 +44,12 @@ public AutoCloseable capture()
4444
System.setOut( new PrintStream( capturedStdOut ) );
4545
System.setErr( new PrintStream( capturedStdErr ) );
4646

47-
return new AutoCloseable()
47+
return () ->
4848
{
49-
@Override
50-
public void close() throws Exception
51-
{
52-
System.setOut( originalStdOut );
53-
System.setErr( originalStdErr );
54-
stdout.addAll( asList( capturedStdOut.toString( "UTF-8" ).split( System.lineSeparator() ) ) );
55-
stderr.addAll( asList( capturedStdErr.toString( "UTF-8" ).split( System.lineSeparator() ) ) );
56-
}
49+
System.setOut( originalStdOut );
50+
System.setErr( originalStdErr );
51+
stdout.addAll( asList( capturedStdOut.toString( "UTF-8" ).split( System.lineSeparator() ) ) );
52+
stderr.addAll( asList( capturedStdErr.toString( "UTF-8" ).split( System.lineSeparator() ) ) );
5753
};
5854
}
5955

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/*
2+
* Copyright (c) 2002-2017 "Neo Technology,"
3+
* Network Engine for Objects in Lund AB [http://neotechnology.com]
4+
*
5+
* This file is part of Neo4j.
6+
*
7+
* Licensed under the Apache License, Version 2.0 (the "License");
8+
* you may not use this file except in compliance with the License.
9+
* You may obtain a copy of the License at
10+
*
11+
* http://www.apache.org/licenses/LICENSE-2.0
12+
*
13+
* Unless required by applicable law or agreed to in writing, software
14+
* distributed under the License is distributed on an "AS IS" BASIS,
15+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16+
* See the License for the specific language governing permissions and
17+
* limitations under the License.
18+
*/
19+
package org.neo4j.docs.driver;
20+
21+
import java.util.Collections;
22+
import java.util.List;
23+
import java.util.Map;
24+
import java.util.concurrent.CompletionStage;
25+
26+
import org.neo4j.driver.v1.Session;
27+
28+
public class AsyncAutocommitTransactionExample extends BaseApplication
29+
{
30+
public AsyncAutocommitTransactionExample( String uri, String user, String password )
31+
{
32+
super( uri, user, password );
33+
}
34+
35+
public CompletionStage<List<String>> readProductTitles()
36+
{
37+
// tag::async-autocommit-transaction[]
38+
String query = "MATCH (p:Product) WHERE p.id = $id RETURN p.title";
39+
Map<String,Object> parameters = Collections.singletonMap( "id", 0 );
40+
41+
Session session = driver.session();
42+
43+
return session.runAsync( query, parameters )
44+
.thenCompose( cursor -> cursor.listAsync( record -> record.get( 0 ).asString() ) )
45+
.exceptionally( error ->
46+
{
47+
// query execution failed, print error and fallback to empty list of titles
48+
error.printStackTrace();
49+
return Collections.emptyList();
50+
} )
51+
.thenCompose( titles -> session.closeAsync().thenApply( ignore -> titles ) );
52+
// end::async-autocommit-transaction[]
53+
}
54+
}
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
/*
2+
* Copyright (c) 2002-2017 "Neo Technology,"
3+
* Network Engine for Objects in Lund AB [http://neotechnology.com]
4+
*
5+
* This file is part of Neo4j.
6+
*
7+
* Licensed under the Apache License, Version 2.0 (the "License");
8+
* you may not use this file except in compliance with the License.
9+
* You may obtain a copy of the License at
10+
*
11+
* http://www.apache.org/licenses/LICENSE-2.0
12+
*
13+
* Unless required by applicable law or agreed to in writing, software
14+
* distributed under the License is distributed on an "AS IS" BASIS,
15+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16+
* See the License for the specific language governing permissions and
17+
* limitations under the License.
18+
*/
19+
package org.neo4j.docs.driver;
20+
21+
import java.util.Collections;
22+
import java.util.Map;
23+
import java.util.concurrent.CompletionStage;
24+
import java.util.function.Function;
25+
26+
import org.neo4j.driver.v1.Session;
27+
import org.neo4j.driver.v1.StatementResultCursor;
28+
import org.neo4j.driver.v1.Transaction;
29+
30+
public class AsyncExplicitTransactionExample extends BaseApplication
31+
{
32+
public AsyncExplicitTransactionExample( String uri, String user, String password )
33+
{
34+
super( uri, user, password );
35+
}
36+
37+
public CompletionStage<Void> printSingleProduct()
38+
{
39+
// tag::async-explicit-transaction[]
40+
String query = "MATCH (p:Product) WHERE p.id = $id RETURN p.title";
41+
Map<String,Object> parameters = Collections.singletonMap( "id", 0 );
42+
43+
Session session = driver.session();
44+
45+
Function<Transaction,CompletionStage<Void>> printSingleTitle = tx ->
46+
tx.runAsync( query, parameters )
47+
.thenCompose( StatementResultCursor::singleAsync )
48+
.thenApply( record -> record.get( 0 ).asString() )
49+
.thenApply( title ->
50+
{
51+
// single title fetched successfully
52+
System.out.println( title );
53+
return true; // signal to commit the transaction
54+
} )
55+
.exceptionally( error ->
56+
{
57+
// query execution failed
58+
error.printStackTrace();
59+
return false; // signal to rollback the transaction
60+
} )
61+
.thenCompose( commit -> commit ? tx.commitAsync() : tx.rollbackAsync() );
62+
63+
return session.beginTransactionAsync()
64+
.thenCompose( printSingleTitle )
65+
.exceptionally( error ->
66+
{
67+
// either commit or rollback failed
68+
error.printStackTrace();
69+
return null;
70+
} )
71+
.thenCompose( ignore -> session.closeAsync() );
72+
// end::async-explicit-transaction[]
73+
}
74+
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
/*
2+
* Copyright (c) 2002-2017 "Neo Technology,"
3+
* Network Engine for Objects in Lund AB [http://neotechnology.com]
4+
*
5+
* This file is part of Neo4j.
6+
*
7+
* Licensed under the Apache License, Version 2.0 (the "License");
8+
* you may not use this file except in compliance with the License.
9+
* You may obtain a copy of the License at
10+
*
11+
* http://www.apache.org/licenses/LICENSE-2.0
12+
*
13+
* Unless required by applicable law or agreed to in writing, software
14+
* distributed under the License is distributed on an "AS IS" BASIS,
15+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16+
* See the License for the specific language governing permissions and
17+
* limitations under the License.
18+
*/
19+
package org.neo4j.docs.driver;
20+
21+
import java.util.Collections;
22+
import java.util.Map;
23+
import java.util.concurrent.CompletionStage;
24+
25+
import org.neo4j.driver.v1.Session;
26+
import org.neo4j.driver.v1.summary.ResultSummary;
27+
28+
public class AsyncTransactionFunctionExample extends BaseApplication
29+
{
30+
public AsyncTransactionFunctionExample( String uri, String user, String password )
31+
{
32+
super( uri, user, password );
33+
}
34+
35+
public CompletionStage<ResultSummary> printAllProducts()
36+
{
37+
// tag::async-transaction-function[]
38+
String query = "MATCH (p:Product) WHERE p.id = $id RETURN p.title";
39+
Map<String,Object> parameters = Collections.singletonMap( "id", 0 );
40+
41+
Session session = driver.session();
42+
43+
return session.readTransactionAsync( tx ->
44+
tx.runAsync( query, parameters )
45+
.thenCompose( cursor -> cursor.forEachAsync( record ->
46+
// asynchronously print every record
47+
System.out.println( record.get( 0 ).asString() ) ) )
48+
);
49+
// end::async-transaction-function[]
50+
}
51+
}

examples/src/test/java/org/neo4j/docs/driver/ExamplesIT.java

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,16 @@
2222
import org.junit.ClassRule;
2323
import org.junit.Test;
2424

25+
import java.util.HashSet;
2526
import java.util.List;
27+
import java.util.Set;
2628

2729
import org.neo4j.driver.v1.Session;
2830
import org.neo4j.driver.v1.Transaction;
2931
import org.neo4j.driver.v1.TransactionWork;
3032
import org.neo4j.driver.v1.Value;
33+
import org.neo4j.driver.v1.summary.ResultSummary;
34+
import org.neo4j.driver.v1.summary.StatementType;
3135
import org.neo4j.driver.v1.util.StdIOCapture;
3236
import org.neo4j.driver.v1.util.TestNeo4j;
3337
import org.neo4j.driver.v1.util.TestUtil;
@@ -39,11 +43,13 @@
3943
import static org.hamcrest.Matchers.greaterThanOrEqualTo;
4044
import static org.hamcrest.Matchers.instanceOf;
4145
import static org.hamcrest.Matchers.is;
46+
import static org.junit.Assert.assertEquals;
4247
import static org.junit.Assert.assertThat;
4348
import static org.junit.Assert.assertTrue;
4449
import static org.neo4j.driver.v1.Values.parameters;
4550
import static org.neo4j.driver.v1.util.Neo4jRunner.PASSWORD;
4651
import static org.neo4j.driver.v1.util.Neo4jRunner.USER;
52+
import static org.neo4j.driver.v1.util.TestUtil.await;
4753

4854
public class ExamplesIT
4955
{
@@ -124,6 +130,25 @@ public void testShouldRunAutocommitTransactionExample() throws Exception
124130
}
125131
}
126132

133+
@Test
134+
public void testShouldRunAsyncAutocommitTransactionExample() throws Exception
135+
{
136+
try ( AsyncAutocommitTransactionExample example = new AsyncAutocommitTransactionExample( uri, USER, PASSWORD ) )
137+
{
138+
// create some 'Product' nodes
139+
try ( Session session = neo4j.driver().session() )
140+
{
141+
session.run(
142+
"UNWIND ['Tesseract', 'Orb', 'Eye of Agamotto'] AS item " +
143+
"CREATE (:Product {id: 0, title: item})" );
144+
}
145+
146+
// read all 'Product' nodes
147+
List<String> titles = await( example.readProductTitles() );
148+
assertEquals( new HashSet<>( asList( "Tesseract", "Orb", "Eye of Agamotto" ) ), new HashSet<>( titles ) );
149+
}
150+
}
151+
127152
@Test
128153
public void testShouldRunConfigConnectionPoolExample() throws Exception
129154
{
@@ -352,6 +377,33 @@ public void testShouldRunTransactionFunctionExample() throws Exception
352377
}
353378
}
354379

380+
@Test
381+
public void testShouldRunAsyncTransactionFunctionExample() throws Exception
382+
{
383+
try ( AsyncTransactionFunctionExample example = new AsyncTransactionFunctionExample( uri, USER, PASSWORD ) )
384+
{
385+
// create some 'Product' nodes
386+
try ( Session session = neo4j.driver().session() )
387+
{
388+
session.run(
389+
"UNWIND ['Infinity Gauntlet', 'Mjölnir'] AS item " +
390+
"CREATE (:Product {id: 0, title: item})" );
391+
}
392+
393+
StdIOCapture stdIOCapture = new StdIOCapture();
394+
395+
// print all 'Product' nodes to fake stdout
396+
try ( AutoCloseable ignore = stdIOCapture.capture() )
397+
{
398+
ResultSummary summary = await( example.printAllProducts() );
399+
assertEquals( StatementType.READ_ONLY, summary.statementType() );
400+
}
401+
402+
Set<String> capturedOutput = new HashSet<>( stdIOCapture.stdout() );
403+
assertEquals( new HashSet<>( asList( "Infinity Gauntlet", "Mjölnir" ) ), capturedOutput );
404+
}
405+
}
406+
355407
@Test
356408
public void testPassBookmarksExample() throws Exception
357409
{
@@ -380,4 +432,27 @@ public void testPassBookmarksExample() throws Exception
380432
}
381433
}
382434

435+
@Test
436+
public void testAsyncExplicitTransactionExample() throws Exception
437+
{
438+
try ( AsyncExplicitTransactionExample example = new AsyncExplicitTransactionExample( uri, USER, PASSWORD ) )
439+
{
440+
// create a 'Product' node
441+
try ( Session session = neo4j.driver().session() )
442+
{
443+
session.run( "CREATE (:Product {id: 0, title: 'Mind Gem'})" );
444+
}
445+
446+
StdIOCapture stdIOCapture = new StdIOCapture();
447+
448+
// print the single 'Product' node
449+
try ( AutoCloseable ignore = stdIOCapture.capture() )
450+
{
451+
await( example.printSingleProduct() );
452+
}
453+
454+
assertEquals( 1, stdIOCapture.stdout().size() );
455+
assertEquals( "Mind Gem", stdIOCapture.stdout().get( 0 ) );
456+
}
457+
}
383458
}

0 commit comments

Comments
 (0)