Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 70 additions & 0 deletions bolt/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright © 2021-present Arcade Data Ltd ([email protected])

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.

SPDX-FileCopyrightText: 2021-present Arcade Data Ltd ([email protected])
SPDX-License-Identifier: Apache-2.0
-->
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<parent>
<groupId>com.arcadedb</groupId>
<artifactId>arcadedb-parent</artifactId>
<version>26.2.1-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

<artifactId>arcadedb-bolt</artifactId>
<packaging>jar</packaging>
<name>ArcadeDB BOLT Protocol</name>
<description>Neo4j BOLT wire protocol implementation for ArcadeDB</description>

<properties>
<neo4j-driver.version>5.27.0</neo4j-driver.version>
</properties>

<dependencies>
<dependency>
<groupId>com.arcadedb</groupId>
<artifactId>arcadedb-server</artifactId>
<version>${project.parent.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.neo4j.driver</groupId>
<artifactId>neo4j-java-driver</artifactId>
<version>${neo4j-driver.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.arcadedb</groupId>
<artifactId>arcadedb-test-utils</artifactId>
<version>${project.parent.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
</plugin>
</plugins>
</build>

</project>
91 changes: 91 additions & 0 deletions bolt/src/main/java/com/arcadedb/bolt/BoltChunkedInput.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
/*
* Copyright © 2021-present Arcade Data Ltd ([email protected])
*
* 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.
*
* SPDX-FileCopyrightText: 2021-present Arcade Data Ltd ([email protected])
* SPDX-License-Identifier: Apache-2.0
*/
package com.arcadedb.bolt;

import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;

/**
* Handles chunked message framing for BOLT protocol input.
* Messages are received as: [chunk_size (2 bytes)][chunk_data]...[0x00 0x00]
*/
public class BoltChunkedInput {
private final DataInputStream in;

public BoltChunkedInput(final InputStream in) {
this.in = new DataInputStream(in);
}

/**
* Read a complete message by dechunking.
* Reads chunks until a zero-length chunk is encountered.
*/
public byte[] readMessage() throws IOException {
final ByteArrayOutputStream buffer = new ByteArrayOutputStream();

while (true) {
// Read chunk size (2 bytes, big-endian)
final int chunkSize = in.readUnsignedShort();

if (chunkSize == 0) {
// End of message
break;
}

// Read chunk data
final byte[] chunk = new byte[chunkSize];
in.readFully(chunk);
buffer.write(chunk);
}

return buffer.toByteArray();
}

/**
* Read raw bytes directly (for handshake).
*/
public byte[] readRaw(final int length) throws IOException {
final byte[] data = new byte[length];
in.readFully(data);
return data;
}

/**
* Read raw int (for handshake).
*/
public int readRawInt() throws IOException {
return in.readInt();
}

/**
* Read raw unsigned short (for chunk sizes).
*/
public int readRawShort() throws IOException {
return in.readUnsignedShort();
}

/**
* Check if data is available.
*/
public int available() throws IOException {
return in.available();
}
}
82 changes: 82 additions & 0 deletions bolt/src/main/java/com/arcadedb/bolt/BoltChunkedOutput.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
/*
* Copyright © 2021-present Arcade Data Ltd ([email protected])
*
* 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.
*
* SPDX-FileCopyrightText: 2021-present Arcade Data Ltd ([email protected])
* SPDX-License-Identifier: Apache-2.0
*/
package com.arcadedb.bolt;

import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.OutputStream;

/**
* Handles chunked message framing for BOLT protocol.
* Messages are sent as: [chunk_size (2 bytes)][chunk_data]...[0x00 0x00]
*/
public class BoltChunkedOutput {
private static final int MAX_CHUNK_SIZE = 65535;

private final DataOutputStream out;

public BoltChunkedOutput(final OutputStream out) {
this.out = new DataOutputStream(out);
}

/**
* Write a complete message with chunked framing.
*/
public void writeMessage(final byte[] messageData) throws IOException {
int offset = 0;
final int length = messageData.length;

while (offset < length) {
final int chunkSize = Math.min(length - offset, MAX_CHUNK_SIZE);

// Write chunk header (2-byte size, big-endian)
out.writeShort(chunkSize);

// Write chunk data
out.write(messageData, offset, chunkSize);

offset += chunkSize;
}

// Write end marker (two zero bytes)
out.writeShort(0);
out.flush();
}

/**
* Write raw bytes directly (for handshake).
*/
public void writeRaw(final byte[] data) throws IOException {
out.write(data);
out.flush();
}

/**
* Write raw int (for handshake version response).
*/
public void writeRawInt(final int value) throws IOException {
out.writeInt(value);
out.flush();
}

public void flush() throws IOException {
out.flush();
}
}
46 changes: 46 additions & 0 deletions bolt/src/main/java/com/arcadedb/bolt/BoltErrorCodes.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/*
* Copyright © 2021-present Arcade Data Ltd ([email protected])
*
* 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.
*
* SPDX-FileCopyrightText: 2021-present Arcade Data Ltd ([email protected])
* SPDX-License-Identifier: Apache-2.0
*/
package com.arcadedb.bolt;

/**
* Centralized constants for Neo4j-compatible BOLT error codes.
* These error codes are used across BOLT protocol messages and exceptions.
*/
public final class BoltErrorCodes {
private BoltErrorCodes() {
// Utility class - prevent instantiation
}

// Security errors
public static final String AUTHENTICATION_ERROR = "Neo.ClientError.Security.Unauthorized";

Check notice on line 31 in bolt/src/main/java/com/arcadedb/bolt/BoltErrorCodes.java

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

bolt/src/main/java/com/arcadedb/bolt/BoltErrorCodes.java#L31

Fields should be declared at the top of the class, before any method declarations, constructors, initializers or inner classes.
public static final String FORBIDDEN_ERROR = "Neo.ClientError.Security.Forbidden";

Check notice on line 32 in bolt/src/main/java/com/arcadedb/bolt/BoltErrorCodes.java

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

bolt/src/main/java/com/arcadedb/bolt/BoltErrorCodes.java#L32

Fields should be declared at the top of the class, before any method declarations, constructors, initializers or inner classes.

// Statement errors
public static final String SYNTAX_ERROR = "Neo.ClientError.Statement.SyntaxError";

Check notice on line 35 in bolt/src/main/java/com/arcadedb/bolt/BoltErrorCodes.java

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

bolt/src/main/java/com/arcadedb/bolt/BoltErrorCodes.java#L35

Fields should be declared at the top of the class, before any method declarations, constructors, initializers or inner classes.
public static final String SEMANTIC_ERROR = "Neo.ClientError.Statement.SemanticError";

Check notice on line 36 in bolt/src/main/java/com/arcadedb/bolt/BoltErrorCodes.java

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

bolt/src/main/java/com/arcadedb/bolt/BoltErrorCodes.java#L36

Fields should be declared at the top of the class, before any method declarations, constructors, initializers or inner classes.

// Transaction errors
public static final String TRANSACTION_ERROR = "Neo.ClientError.Transaction.TransactionNotFound";

Check notice on line 39 in bolt/src/main/java/com/arcadedb/bolt/BoltErrorCodes.java

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

bolt/src/main/java/com/arcadedb/bolt/BoltErrorCodes.java#L39

Fields should be declared at the top of the class, before any method declarations, constructors, initializers or inner classes.

// Request errors
public static final String PROTOCOL_ERROR = "Neo.ClientError.Request.Invalid";

Check notice on line 42 in bolt/src/main/java/com/arcadedb/bolt/BoltErrorCodes.java

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

bolt/src/main/java/com/arcadedb/bolt/BoltErrorCodes.java#L42

Fields should be declared at the top of the class, before any method declarations, constructors, initializers or inner classes.

// Database errors
public static final String DATABASE_ERROR = "Neo.DatabaseError.General.UnknownError";

Check notice on line 45 in bolt/src/main/java/com/arcadedb/bolt/BoltErrorCodes.java

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

bolt/src/main/java/com/arcadedb/bolt/BoltErrorCodes.java#L45

Fields should be declared at the top of the class, before any method declarations, constructors, initializers or inner classes.
}
76 changes: 76 additions & 0 deletions bolt/src/main/java/com/arcadedb/bolt/BoltException.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
/*
* Copyright © 2021-present Arcade Data Ltd ([email protected])
*
* 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.
*
* SPDX-FileCopyrightText: 2021-present Arcade Data Ltd ([email protected])
* SPDX-License-Identifier: Apache-2.0
*/
package com.arcadedb.bolt;

import com.arcadedb.exception.ArcadeDBException;

/**
* Exception for BOLT protocol errors.
* Error codes are defined in {@link BoltErrorCodes}.
*/
public class BoltException extends ArcadeDBException {
private final String errorCode;

public BoltException(final String message) {
super(message);
this.errorCode = BoltErrorCodes.DATABASE_ERROR;
}

public BoltException(final String errorCode, final String message) {
super(message);
this.errorCode = errorCode;
}

public BoltException(final String message, final Throwable cause) {
super(message, cause);
this.errorCode = BoltErrorCodes.DATABASE_ERROR;
}

public BoltException(final String errorCode, final String message, final Throwable cause) {
super(message, cause);
this.errorCode = errorCode;
}

public String getErrorCode() {
return errorCode;
}

// Deprecated: Use BoltErrorCodes constants instead
/** @deprecated Use {@link BoltErrorCodes#AUTHENTICATION_ERROR} */
@Deprecated
public static final String AUTHENTICATION_ERROR = BoltErrorCodes.AUTHENTICATION_ERROR;

Check notice on line 57 in bolt/src/main/java/com/arcadedb/bolt/BoltException.java

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

bolt/src/main/java/com/arcadedb/bolt/BoltException.java#L57

Fields should be declared at the top of the class, before any method declarations, constructors, initializers or inner classes.
/** @deprecated Use {@link BoltErrorCodes#SYNTAX_ERROR} */
@Deprecated
public static final String SYNTAX_ERROR = BoltErrorCodes.SYNTAX_ERROR;

Check notice on line 60 in bolt/src/main/java/com/arcadedb/bolt/BoltException.java

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

bolt/src/main/java/com/arcadedb/bolt/BoltException.java#L60

Fields should be declared at the top of the class, before any method declarations, constructors, initializers or inner classes.
/** @deprecated Use {@link BoltErrorCodes#SEMANTIC_ERROR} */
@Deprecated
public static final String SEMANTIC_ERROR = BoltErrorCodes.SEMANTIC_ERROR;

Check notice on line 63 in bolt/src/main/java/com/arcadedb/bolt/BoltException.java

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

bolt/src/main/java/com/arcadedb/bolt/BoltException.java#L63

Fields should be declared at the top of the class, before any method declarations, constructors, initializers or inner classes.
/** @deprecated Use {@link BoltErrorCodes#DATABASE_ERROR} */
@Deprecated
public static final String DATABASE_ERROR = BoltErrorCodes.DATABASE_ERROR;

Check notice on line 66 in bolt/src/main/java/com/arcadedb/bolt/BoltException.java

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

bolt/src/main/java/com/arcadedb/bolt/BoltException.java#L66

Fields should be declared at the top of the class, before any method declarations, constructors, initializers or inner classes.
/** @deprecated Use {@link BoltErrorCodes#TRANSACTION_ERROR} */
@Deprecated
public static final String TRANSACTION_ERROR = BoltErrorCodes.TRANSACTION_ERROR;

Check notice on line 69 in bolt/src/main/java/com/arcadedb/bolt/BoltException.java

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

bolt/src/main/java/com/arcadedb/bolt/BoltException.java#L69

Fields should be declared at the top of the class, before any method declarations, constructors, initializers or inner classes.
/** @deprecated Use {@link BoltErrorCodes#FORBIDDEN_ERROR} */
@Deprecated
public static final String FORBIDDEN_ERROR = BoltErrorCodes.FORBIDDEN_ERROR;

Check notice on line 72 in bolt/src/main/java/com/arcadedb/bolt/BoltException.java

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

bolt/src/main/java/com/arcadedb/bolt/BoltException.java#L72

Fields should be declared at the top of the class, before any method declarations, constructors, initializers or inner classes.
/** @deprecated Use {@link BoltErrorCodes#PROTOCOL_ERROR} */
@Deprecated
public static final String PROTOCOL_ERROR = BoltErrorCodes.PROTOCOL_ERROR;

Check notice on line 75 in bolt/src/main/java/com/arcadedb/bolt/BoltException.java

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

bolt/src/main/java/com/arcadedb/bolt/BoltException.java#L75

Fields should be declared at the top of the class, before any method declarations, constructors, initializers or inner classes.
}
Loading
Loading