-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
37 changed files
with
1,888 additions
and
48 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,3 @@ | ||
# AspikeServerUmbrella | ||
|
||
**TODO: Add description** | ||
# Aerospike Server Emulator | ||
|
||
*Uses Aerospike Binary Protocol* - https://github.com/vsavkov/aspike-protocol |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
-define(TEST_NODE_NAME_0, "A0"). | ||
-define(TEST_ADDRESS, "127.0.0.1"). | ||
-define(TEST_PORT, 62169). | ||
|
||
-define(TEST_USER1, <<"User1">>). | ||
-define(TEST_PASSWORD1, "pass1"). | ||
-define(TEST_PASSWORD1_CRYPT, <<"$2a$10$7EqJtq98hPqEX7fNZaFWoOOY1Ba9.gZNwHJkrSKJl7mXQyPCsCrQa">>). | ||
-define(TEST_SESSION_TTL, 12345). | ||
-define(TEST_SESSION_TOKEN1, <<"test_session_token1">>). | ||
|
||
-define(TEST_NAMESPACE, "Test-Namespace"). |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,154 @@ | ||
%% Proto header version | ||
-define(AS_PROTO_VERSION, 2). | ||
|
||
%% Proto message types | ||
-define(AS_INFO_MESSAGE_TYPE, 1). | ||
-define(AS_ADMIN_MESSAGE_TYPE, 2). | ||
-define(AS_MESSAGE_TYPE, 3). | ||
-define(AS_COMPRESSED_MESSAGE_TYPE, 4). | ||
-define(PROTO_SIZE_MAX, (128 * 1024 * 1024)). % 2^27 = 128 MB | ||
|
||
%% admin Commands | ||
-define(LOGIN, 20). % 0x14 = 16#14. | ||
|
||
%% Field IDs in admin Commands | ||
-define(USER, 0). | ||
-define(CREDENTIAL, 3). | ||
-define(SESSION_TOKEN, 5). | ||
-define(SESSION_TTL, 6). | ||
|
||
-define(AS_PROTO_DISTANCE_BTW_SIZE_AND_FIELDS, 16). | ||
|
||
%% Field IDs | ||
-define(AS_FIELD_NAMESPACE, 0). | ||
-define(AS_FIELD_SETNAME, 1). | ||
-define(AS_FIELD_KEY, 2). | ||
-define(AS_FIELD_DIGEST, 4). | ||
-define(AS_FIELD_TASK_ID, 7). | ||
-define(AS_FIELD_SOCKET_TIMEOUT, 9). | ||
-define(AS_FIELD_RPS, 10). | ||
-define(AS_FIELD_PID_ARRAY, 11). | ||
-define(AS_FIELD_DIGEST_ARRAY, 12). | ||
-define(AS_FIELD_MAX_RECORDS, 13). | ||
-define(AS_FIELD_BVAL_ARRAY, 15). | ||
-define(AS_FIELD_INDEX_RANGE, 22). | ||
-define(AS_FIELD_INDEX_CONTEXT, 23). | ||
-define(AS_FIELD_INDEX_TYPE, 26). | ||
-define(AS_FIELD_UDF_PACKAGE_NAME, 30). | ||
-define(AS_FIELD_UDF_FUNCTION, 31). | ||
-define(AS_FIELD_UDF_ARGLIST, 32). | ||
-define(AS_FIELD_UDF_OP, 33). | ||
-define(AS_FIELD_QUERY_BINS, 40). | ||
-define(AS_FIELD_BATCH_INDEX, 41). | ||
-define(AS_FIELD_FILTER, 43). | ||
|
||
%% Message info1 bits | ||
-define(AS_MSG_INFO1_READ, (1 bsl 0)). % contains a read operation | ||
-define(AS_MSG_INFO1_GET_ALL, (1 bsl 1)). % get all bins, period | ||
-define(AS_MSG_INFO1_SHORT_QUERY, (1 bsl 2)). % short query | ||
-define(AS_MSG_INFO1_BATCH_INDEX, (1 bsl 3)). % batch | ||
-define(AS_MSG_INFO1_XDR, (1 bsl 4)). % operation is being performed by XDR | ||
-define(AS_MSG_INFO1_GET_NOBINDATA, (1 bsl 5)). % do not get information about bins and its data | ||
-define(AS_MSG_INFO1_READ_MODE_AP_ALL, (1 bsl 6)). % read mode all for AP namespaces. | ||
-define(AS_MSG_INFO1_COMPRESS_RESPONSE, (1 bsl 7)). % tell server to compress it's response. | ||
|
||
%% Message info2 bits | ||
-define(AS_MSG_INFO2_WRITE, (1 bsl 0)). % contains a write semantic | ||
-define(AS_MSG_INFO2_DELETE, (1 bsl 1)). % delete record | ||
-define(AS_MSG_INFO2_GENERATION, (1 bsl 2)). % pay attention to the generation | ||
-define(AS_MSG_INFO2_GENERATION_GT, (1 bsl 3)). % apply write if new generation >= old, good for restore | ||
-define(AS_MSG_INFO2_DURABLE_DELETE, (1 bsl 4)). % transaction resulting in record deletion leaves tombstone (Enterprise only). | ||
-define(AS_MSG_INFO2_CREATE_ONLY, (1 bsl 5)). % write record only if it doesn't exist | ||
%% (Note: Bit 6 is unused.) | ||
-define(AS_MSG_INFO2_RESPOND_ALL_OPS, (1 bsl 7)). % return a result for every operation. | ||
|
||
%% Message info3 bits | ||
-define(AS_MSG_INFO3_LAST, (1 bsl 0)). % this is the last of a multi-part message | ||
-define(AS_MSG_INFO3_COMMIT_MASTER, (1 bsl 1)). % write commit level - bit 0 | ||
%% On send: Do not return partition done in scan/query. | ||
%% On receive: Specified partition is done in scan/query. | ||
-define(AS_MSG_INFO3_PARTITION_DONE, (1 bsl 2)). | ||
-define(AS_MSG_INFO3_UPDATE_ONLY, (1 bsl 3)). % update existing record only, do not create new record | ||
-define(AS_MSG_INFO3_CREATE_OR_REPLACE, (1 bsl 4)). % completely replace existing record, or create new record | ||
-define(AS_MSG_INFO3_REPLACE_ONLY, (1 bsl 5)). % completely replace existing record, do not create new record | ||
-define(AS_MSG_INFO3_SC_READ_TYPE, (1 bsl 6)). % see aerospike-client-c for details | ||
-define(AS_MSG_INFO3_SC_READ_RELAX, (1 bsl 7)). % see aerospike-client-c for details | ||
|
||
|
||
-define(AS_OPERATOR_READ, 1). | ||
-define(AS_OPERATOR_WRITE, 2). | ||
-define(AS_OPERATOR_CDT_READ, 3). | ||
-define(AS_OPERATOR_CDT_MODIFY, 4). | ||
-define(AS_OPERATOR_MAP_READ, 5). | ||
-define(AS_OPERATOR_MAP_MODIFY, 6). | ||
-define(AS_OPERATOR_INCR, 7). | ||
-define(AS_OPERATOR_EXP_READ, 8). | ||
-define(AS_OPERATOR_EXP_MODIFY, 9). | ||
-define(AS_OPERATOR_APPEND, 10). | ||
-define(AS_OPERATOR_PREPEND, 11). | ||
-define(AS_OPERATOR_TOUCH, 12). | ||
-define(AS_OPERATOR_BIT_READ, 13). | ||
-define(AS_OPERATOR_BIT_MODIFY, 14). | ||
-define(AS_OPERATOR_DELETE, 15). | ||
-define(AS_OPERATOR_HLL_READ, 16). | ||
-define(AS_OPERATOR_HLL_MODIFY, 17). | ||
|
||
-define(KEY_DIGEST_SIZE, 160). % RIPEMD160 crypto:hash(ripemd160, ...) | ||
|
||
|
||
-define(AS_BYTES_UNDEF, 0). | ||
-define(AS_BYTES_INTEGER, 1). | ||
-define(AS_BYTES_DOUBLE, 2). | ||
-define(AS_BYTES_STRING, 3). | ||
-define(AS_BYTES_BLOB, 4). | ||
-define(AS_BYTES_JAVA, 7). | ||
-define(AS_BYTES_CSHARP, 8). | ||
-define(AS_BYTES_PYTHON, 9). | ||
-define(AS_BYTES_RUBY, 10). | ||
-define(AS_BYTES_PHP, 11). | ||
-define(AS_BYTES_ERLANG, 12). | ||
-define(AS_BYTES_BOOL, 17). | ||
-define(AS_BYTES_HLL, 18). | ||
-define(AS_BYTES_MAP, 19). | ||
-define(AS_BYTES_LIST, 20). | ||
-define(AS_BYTES_GEOJSON, 23). | ||
-define(AS_BYTES_TYPE_MAX, 24). | ||
|
||
%% as_proto reflects binary (physical) layout | ||
-record(as_proto, { | ||
version :: aspike:uint8_t(), | ||
type :: aspike:uint8_t(), | ||
sz :: aspike:uint48_t() | ||
}). | ||
|
||
%% as_msg reflects binary (physical) layout | ||
-record(as_msg, { | ||
header_sz :: aspike:uint8_t(), % number of uint8_ts in this header | ||
info1 :: aspike:uint8_t(), % bitfield about this request | ||
info2 :: aspike:uint8_t(), | ||
info3 :: aspike:uint8_t(), | ||
unused :: aspike:uint8_t(), | ||
result_code :: aspike:uint8_t(), | ||
generation :: aspike:uint32_t(), | ||
record_ttl :: aspike:uint32_t(), | ||
transaction_ttl :: aspike:uint32_t(), | ||
n_fields :: aspike:uint16_t(), % size in uint8_ts | ||
n_ops :: aspike:uint16_t() % number of operations | ||
% followed by data that contain | ||
% the fields, occupying n_fields bytes | ||
% then the n_ops number of ops. | ||
}). | ||
|
||
%% aspike_message_type_header is a logical representation of as_msg | ||
-record(aspike_message_type_header, { | ||
result_code :: aspike:uint8_t(), | ||
n_fields :: aspike:uint16_t(), | ||
n_bins :: aspike:uint16_t(), | ||
ttl :: aspike:uint32_t(), | ||
timeout :: aspike:uint32_t(), | ||
read_attr :: aspike:uint8_t(), | ||
write_attr :: aspike:uint8_t(), | ||
info_attr :: aspike:uint8_t(), | ||
generation :: aspike:uint32_t(), | ||
unused :: aspike:uint8_t() | ||
}). |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
%% Corresponds to as_status.h | ||
|
||
%% Success | ||
-define(AEROSPIKE_OK, 0). | ||
|
||
%% Server Errors | ||
-define(AEROSPIKE_ERR_SERVER, 1). | ||
-define(AEROSPIKE_ERR_RECORD_NOT_FOUND, 2). | ||
-define(AEROSPIKE_ERR_RECORD_GENERATION, 3). | ||
-define(AEROSPIKE_ERR_REQUEST_INVALID, 4). | ||
-define(AEROSPIKE_ERR_RECORD_EXISTS, 5). | ||
-define(AEROSPIKE_ERR_BIN_EXISTS, 6). | ||
-define(AEROSPIKE_ERR_CLUSTER_CHANGE, 7). | ||
-define(AEROSPIKE_ERR_SERVER_FULL, 8). | ||
-define(AEROSPIKE_ERR_TIMEOUT, 9). | ||
-define(AEROSPIKE_ERR_ALWAYS_FORBIDDEN, 10). | ||
-define(AEROSPIKE_ERR_CLUSTER, 11). | ||
-define(AEROSPIKE_ERR_BIN_INCOMPATIBLE_TYPE, 12). | ||
-define(AEROSPIKE_ERR_RECORD_TOO_BIG, 13). | ||
-define(AEROSPIKE_ERR_RECORD_BUSY, 14). | ||
-define(AEROSPIKE_ERR_SCAN_ABORTED, 15). | ||
-define(AEROSPIKE_ERR_UNSUPPORTED_FEATURE, 16). | ||
-define(AEROSPIKE_ERR_BIN_NOT_FOUND, 17). | ||
-define(AEROSPIKE_ERR_DEVICE_OVERLOAD, 18). | ||
-define(AEROSPIKE_ERR_RECORD_KEY_MISMATCH, 19). | ||
-define(AEROSPIKE_ERR_NAMESPACE_NOT_FOUND, 20). | ||
-define(AEROSPIKE_ERR_BIN_NAME, 21). | ||
-define(AEROSPIKE_ERR_FAIL_FORBIDDEN, 22). | ||
-define(AEROSPIKE_ERR_FAIL_ELEMENT_NOT_FOUND, 23). | ||
-define(AEROSPIKE_ERR_FAIL_ELEMENT_EXISTS, 24). | ||
-define(AEROSPIKE_ERR_ENTERPRISE_ONLY, 25). | ||
-define(AEROSPIKE_ERR_OP_NOT_APPLICABLE, 26). | ||
-define(AEROSPIKE_FILTERED_OUT, 27). | ||
-define(AEROSPIKE_LOST_CONFLICT, 28). | ||
-define(AEROSPIKE_QUERY_END, 50). | ||
-define(AEROSPIKE_SECURITY_NOT_SUPPORTED, 51). | ||
-define(AEROSPIKE_SECURITY_NOT_ENABLED, 52). | ||
-define(AEROSPIKE_SECURITY_SCHEME_NOT_SUPPORTED, 53). | ||
-define(AEROSPIKE_INVALID_COMMAND, 54). | ||
-define(AEROSPIKE_INVALID_FIELD, 55). | ||
-define(AEROSPIKE_ILLEGAL_STATE, 56). | ||
-define(AEROSPIKE_INVALID_USER, 60). | ||
-define(AEROSPIKE_USER_ALREADY_EXISTS, 61). | ||
-define(AEROSPIKE_INVALID_PASSWORD, 62). | ||
-define(AEROSPIKE_EXPIRED_PASSWORD, 63). | ||
-define(AEROSPIKE_FORBIDDEN_PASSWORD, 64). | ||
-define(AEROSPIKE_INVALID_CREDENTIAL, 65). | ||
-define(AEROSPIKE_EXPIRED_SESSION, 66). | ||
-define(AEROSPIKE_INVALID_ROLE, 70). | ||
-define(AEROSPIKE_ROLE_ALREADY_EXISTS, 71). | ||
-define(AEROSPIKE_INVALID_PRIVILEGE, 72). | ||
-define(AEROSPIKE_INVALID_WHITELIST, 73). | ||
-define(AEROSPIKE_QUOTAS_NOT_ENABLED, 74). | ||
-define(AEROSPIKE_INVALID_QUOTA, 75). | ||
-define(AEROSPIKE_NOT_AUTHENTICATED, 80). | ||
-define(AEROSPIKE_ROLE_VIOLATION, 81). | ||
-define(AEROSPIKE_NOT_WHITELISTED, 82). | ||
-define(AEROSPIKE_QUOTA_EXCEEDED, 83). | ||
-define(AEROSPIKE_ERR_UDF, 100). | ||
-define(AEROSPIKE_ERR_BATCH_DISABLED, 150). | ||
-define(AEROSPIKE_ERR_BATCH_MAX_REQUESTS_EXCEEDED, 151). | ||
-define(AEROSPIKE_ERR_BATCH_QUEUES_FULL, 152). | ||
-define(AEROSPIKE_ERR_GEO_INVALID_GEOJSON, 160). | ||
-define(AEROSPIKE_ERR_INDEX_FOUND, 200). | ||
-define(AEROSPIKE_ERR_INDEX_NOT_FOUND, 201). | ||
-define(AEROSPIKE_ERR_INDEX_OOM, 202). | ||
-define(AEROSPIKE_ERR_INDEX_NOT_READABLE, 203). | ||
-define(AEROSPIKE_ERR_INDEX, 204). | ||
-define(AEROSPIKE_ERR_INDEX_NAME_MAXLEN, 205). | ||
-define(AEROSPIKE_ERR_INDEX_MAXCOUNT, 206). | ||
-define(AEROSPIKE_ERR_QUERY_ABORTED, 210). | ||
-define(AEROSPIKE_ERR_QUERY_QUEUE_FULL, 211). | ||
-define(AEROSPIKE_ERR_QUERY_TIMEOUT, 212). | ||
-define(AEROSPIKE_ERR_QUERY, 213). | ||
-define(AEROSPIKE_ERR_UDF_NOT_FOUND, 1301). % likely internal Aerospike server error? | ||
-define(AEROSPIKE_ERR_LUA_FILE_NOT_FOUND, 1302). % likely internal Aerospike server error? | ||
|
||
%% Client Errors. | ||
%% These are C-client errors, irrelevant for Erlang client. | ||
-define(AEROSPIKE_BATCH_FAILED, -16). | ||
-define(AEROSPIKE_NO_RESPONSE, -15). | ||
-define(AEROSPIKE_MAX_ERROR_RATE, -14). | ||
-define(AEROSPIKE_USE_NORMAL_RETRY, -13). | ||
-define(AEROSPIKE_ERR_MAX_RETRIES_EXCEEDED, -12). | ||
-define(AEROSPIKE_ERR_ASYNC_QUEUE_FULL, -11). | ||
-define(AEROSPIKE_ERR_CONNECTION, -10). | ||
-define(AEROSPIKE_ERR_TLS_ERROR, -9). | ||
-define(AEROSPIKE_ERR_INVALID_NODE, -8). | ||
-define(AEROSPIKE_ERR_NO_MORE_CONNECTIONS, -7). | ||
-define(AEROSPIKE_ERR_ASYNC_CONNECTION, -6). | ||
-define(AEROSPIKE_ERR_CLIENT_ABORT, -5). | ||
-define(AEROSPIKE_ERR_INVALID_HOST, -4). | ||
-define(AEROSPIKE_NO_MORE_RECORDS, -3). | ||
-define(AEROSPIKE_ERR_PARAM, -2). | ||
-define(AEROSPIKE_ERR_CLIENT, -1). | ||
-define(AEROSPIKE_ERR, -1). |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
defmodule Aspike.Server.Application do | ||
# See https://hexdocs.pm/elixir/Application.html | ||
# for more information on OTP Applications | ||
@moduledoc false | ||
|
||
use Application | ||
|
||
@impl true | ||
def start(_type, _args) do | ||
children = [ | ||
{Task.Supervisor, name: Aspike.Server.ProcessorSupervisor}, | ||
{Aspike.Server, 4041} | ||
] | ||
|
||
# See https://hexdocs.pm/elixir/Supervisor.html | ||
# for other strategies and supported options | ||
opts = [strategy: :one_for_one, name: Aspike.Server.Supervisor] | ||
Supervisor.start_link(children, opts) | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,18 +1,29 @@ | ||
defmodule AspikeServer do | ||
@moduledoc """ | ||
Documentation for `AspikeServer`. | ||
""" | ||
defmodule Aspike.Server do | ||
@moduledoc false | ||
use Task, restart: :transient | ||
require Logger | ||
|
||
@doc """ | ||
Hello world. | ||
## Examples | ||
def start_link(arg) do | ||
Task.start_link(__MODULE__, :accept, [arg]) | ||
end | ||
|
||
iex> AspikeServer.hello() | ||
:world | ||
def accept(port) do | ||
{:ok, socket} = :gen_tcp.listen(port, | ||
[:binary, | ||
packet: :raw, | ||
active: false, | ||
reuseaddr: true, | ||
backlog: 4096]) | ||
Logger.info "Accepting connections on port #{port}" | ||
loop_acceptor(socket) | ||
end | ||
|
||
""" | ||
def hello do | ||
:world | ||
defp loop_acceptor(socket) do | ||
{:ok, client} = :gen_tcp.accept(socket) | ||
{:ok, pid} = Task.Supervisor.start_child( | ||
Aspike.Server.ProcessorSupervisor, | ||
Aspike.Server.Processor, :run, [client, <<>>]) | ||
:ok = :gen_tcp.controlling_process(client, pid) | ||
loop_acceptor(socket) | ||
end | ||
end |
Oops, something went wrong.