diff --git a/testkit-backend/src/main/java/neo4j/org/testkit/backend/channel/handler/TestkitRequestProcessorHandler.java b/testkit-backend/src/main/java/neo4j/org/testkit/backend/channel/handler/TestkitRequestProcessorHandler.java index 03ebf2ca25..80c64cd266 100644 --- a/testkit-backend/src/main/java/neo4j/org/testkit/backend/channel/handler/TestkitRequestProcessorHandler.java +++ b/testkit-backend/src/main/java/neo4j/org/testkit/backend/channel/handler/TestkitRequestProcessorHandler.java @@ -37,6 +37,7 @@ import java.util.function.BiFunction; import org.neo4j.driver.exceptions.Neo4jException; +import org.neo4j.driver.exceptions.NoSuchRecordException; import org.neo4j.driver.exceptions.UntrustedServerException; import org.neo4j.driver.internal.spi.ConnectionPool; @@ -138,7 +139,7 @@ private TestkitResponse createErrorResponse( Throwable throwable ) .build() ) .build(); } - else if ( isConnectionPoolClosedException( throwable ) || throwable instanceof UntrustedServerException ) + else if ( isConnectionPoolClosedException( throwable ) || throwable instanceof UntrustedServerException || throwable instanceof NoSuchRecordException ) { String id = testkitState.newId(); return DriverError.builder() diff --git a/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/requests/GetFeatures.java b/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/requests/GetFeatures.java index 309880a2d6..ecf4beeb12 100644 --- a/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/requests/GetFeatures.java +++ b/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/requests/GetFeatures.java @@ -66,7 +66,8 @@ public class GetFeatures implements TestkitRequest "Optimization:PullPipelining", "Feature:API:Result.List", "Feature:API:Result.Peek", - "Optimization:ResultListFetchAll" + "Optimization:ResultListFetchAll", + "Feature:API:Result.Single" ) ); private static final Set ASYNC_FEATURES = new HashSet<>( Arrays.asList( @@ -74,7 +75,8 @@ public class GetFeatures implements TestkitRequest "Optimization:PullPipelining", "Feature:API:Result.List", "Feature:API:Result.Peek", - "Optimization:ResultListFetchAll" + "Optimization:ResultListFetchAll", + "Feature:API:Result.Single" ) ); @Override diff --git a/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/requests/ResultSingle.java b/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/requests/ResultSingle.java new file mode 100644 index 0000000000..104d23f535 --- /dev/null +++ b/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/requests/ResultSingle.java @@ -0,0 +1,81 @@ +/* + * Copyright (c) "Neo4j" + * Neo4j Sweden AB [http://neo4j.com] + * + * This file is part of Neo4j. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package neo4j.org.testkit.backend.messages.requests; + +import lombok.Getter; +import lombok.Setter; +import neo4j.org.testkit.backend.TestkitState; +import neo4j.org.testkit.backend.holder.ResultCursorHolder; +import neo4j.org.testkit.backend.messages.responses.TestkitResponse; +import reactor.core.publisher.Mono; + +import java.util.concurrent.CompletionStage; + +import org.neo4j.driver.Record; +import org.neo4j.driver.async.ResultCursor; + +@Setter +@Getter +public class ResultSingle implements TestkitRequest +{ + private ResultSingleBody data; + + @Override + public TestkitResponse process( TestkitState testkitState ) + { + return createResponse( testkitState.getResultHolder( data.getResultId() ).getResult().single() ); + } + + @Override + public CompletionStage processAsync( TestkitState testkitState ) + { + return testkitState.getAsyncResultHolder( data.getResultId() ) + .thenApply( ResultCursorHolder::getResult ) + .thenCompose( ResultCursor::singleAsync ) + .thenApply( this::createResponse ); + } + + @Override + public Mono processRx( TestkitState testkitState ) + { + throw new UnsupportedOperationException( "Single method is not supported by reactive API" ); + } + + @Override + public Mono processReactive( TestkitState testkitState ) + { + throw new UnsupportedOperationException( "Single method is not supported by reactive API" ); + } + + private neo4j.org.testkit.backend.messages.responses.TestkitResponse createResponse( Record record ) + { + return neo4j.org.testkit.backend.messages.responses.Record.builder() + .data( neo4j.org.testkit.backend.messages.responses.Record.RecordBody.builder() + .values( record ) + .build() ) + .build(); + } + + @Setter + @Getter + public static class ResultSingleBody + { + private String resultId; + } +} diff --git a/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/requests/TestkitRequest.java b/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/requests/TestkitRequest.java index f363e915ab..ffc4438f5e 100644 --- a/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/requests/TestkitRequest.java +++ b/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/requests/TestkitRequest.java @@ -42,7 +42,7 @@ @JsonSubTypes.Type( GetRoutingTable.class ), @JsonSubTypes.Type( TransactionClose.class ), @JsonSubTypes.Type( ResultList.class ), @JsonSubTypes.Type( GetConnectionPoolMetrics.class ), @JsonSubTypes.Type( ResultPeek.class ), @JsonSubTypes.Type( CheckDriverIsEncrypted.class ), - @JsonSubTypes.Type( CypherTypeField.class ) + @JsonSubTypes.Type( CypherTypeField.class ), @JsonSubTypes.Type( ResultSingle.class ) } ) public interface TestkitRequest {