Merge branch 'master' into feature-remote-logs
# Conflicts: # fdbserver/DataDistribution.actor.cpp
This commit is contained in:
commit
10d25927cd
|
@ -0,0 +1,66 @@
|
|||
Language: Cpp
|
||||
# BasedOnStyle: Mozilla
|
||||
AccessModifierOffset: -4
|
||||
AlignAfterOpenBracket: Align
|
||||
AlignConsecutiveAssignments: false
|
||||
AlignConsecutiveDeclarations: false
|
||||
AlignEscapedNewlinesLeft: false
|
||||
AlignOperands: true
|
||||
AlignTrailingComments: false
|
||||
AllowAllParametersOfDeclarationOnNextLine: false
|
||||
AllowShortBlocksOnASingleLine: false
|
||||
AllowShortCaseLabelsOnASingleLine: false
|
||||
AllowShortFunctionsOnASingleLine: Inline
|
||||
AllowShortIfStatementsOnASingleLine: true
|
||||
AllowShortLoopsOnASingleLine: true
|
||||
AlwaysBreakAfterDefinitionReturnType: None
|
||||
AlwaysBreakAfterReturnType: None
|
||||
AlwaysBreakBeforeMultilineStrings: false
|
||||
AlwaysBreakTemplateDeclarations: true
|
||||
BinPackArguments: true
|
||||
BinPackParameters: true
|
||||
BreakBeforeBinaryOperators: None
|
||||
BreakBeforeBraces: Attach
|
||||
ColumnLimit: 120
|
||||
CommentPragmas: '^ IWYU pragma:|^ clang-format: ignore$|^TraceEvent'
|
||||
ConstructorInitializerAllOnOneLineOrOnePerLine: false
|
||||
ConstructorInitializerIndentWidth: 2
|
||||
ContinuationIndentWidth: 4
|
||||
Cpp11BracedListStyle: false
|
||||
DerivePointerAlignment: false
|
||||
DisableFormat: false
|
||||
ExperimentalAutoDetectBinPacking: false
|
||||
ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ]
|
||||
IndentCaseLabels: false
|
||||
IndentWidth: 4
|
||||
IndentWrappedFunctionNames: false
|
||||
KeepEmptyLinesAtTheStartOfBlocks: true
|
||||
MacroBlockBegin: ''
|
||||
MacroBlockEnd: ''
|
||||
MaxEmptyLinesToKeep: 1
|
||||
NamespaceIndentation: None
|
||||
ObjCBlockIndentWidth: 2
|
||||
ObjCSpaceAfterProperty: true
|
||||
ObjCSpaceBeforeProtocolList: false
|
||||
PenaltyBreakBeforeFirstCallParameter: 19
|
||||
PenaltyBreakComment: 300
|
||||
PenaltyBreakFirstLessLess: 120
|
||||
PenaltyBreakString: 1000
|
||||
PenaltyExcessCharacter: 1000000
|
||||
PenaltyReturnTypeOnItsOwnLine: 200
|
||||
PointerAlignment: Left
|
||||
ReflowComments: true
|
||||
SortIncludes: false
|
||||
SpaceAfterCStyleCast: false
|
||||
SpaceBeforeAssignmentOperators: true
|
||||
SpaceBeforeParens: ControlStatements
|
||||
SpaceInEmptyParentheses: false
|
||||
SpacesBeforeTrailingComments: 1
|
||||
SpacesInAngles: false
|
||||
SpacesInContainerLiterals: true
|
||||
SpacesInCStyleCastParentheses: false
|
||||
SpacesInParentheses: false
|
||||
SpacesInSquareBrackets: false
|
||||
Standard: Cpp11
|
||||
TabWidth: 4
|
||||
UseTab: ForIndentation
|
|
@ -6,8 +6,6 @@ bindings/flow/bin/
|
|||
bindings/java/foundationdb-client*.jar
|
||||
bindings/java/foundationdb-tests*.jar
|
||||
bindings/java/fdb-java-*-sources.jar
|
||||
bindings/nodejs/build/
|
||||
bindings/nodejs/modules/
|
||||
packaging/msi/FDBInstaller.msi
|
||||
|
||||
# Generated source, build, and packaging files
|
||||
|
@ -16,7 +14,6 @@ packaging/msi/FDBInstaller.msi
|
|||
*.g.S
|
||||
*.g.asm
|
||||
*.pom
|
||||
bindings/go/src/fdb/generated.go
|
||||
bindings/java/pom*.xml
|
||||
bindings/java/src*/main/overview.html
|
||||
bindings/java/src*/main/com/apple/foundationdb/*Options.java
|
||||
|
@ -24,7 +21,6 @@ bindings/java/src*/main/com/apple/foundationdb/StreamingMode.java
|
|||
bindings/java/src*/main/com/apple/foundationdb/MutationType.java
|
||||
bindings/java/src*/main/com/apple/foundationdb/ConflictRangeType.java
|
||||
bindings/java/src*/main/com/apple/foundationdb/FDBException.java
|
||||
bindings/nodejs/package.json
|
||||
bindings/python/fdb/fdb*options.py
|
||||
bindings/python/dist/
|
||||
bindings/python/setup.py
|
||||
|
@ -52,12 +48,8 @@ bindings/go/godoc
|
|||
bindings/java/.classstamp*
|
||||
bindings/java/classes*/
|
||||
bindings/java/javadoc*/
|
||||
bindings/nodejs/fdb_node.stamp
|
||||
bindings/nodejs/node_modules/
|
||||
|
||||
# Testing and logging
|
||||
bindings/nodejs/fdb_node*.log
|
||||
bindings/nodejs/npm-debug.log
|
||||
packaging/msi/*.log
|
||||
packaging/msi/obj
|
||||
simfdb
|
||||
|
|
|
@ -0,0 +1,71 @@
|
|||
# Contributor Covenant Code of Conduct
|
||||
|
||||
## Our Pledge
|
||||
|
||||
In the interest of fostering an open and welcoming environment, we as
|
||||
contributors and maintainers pledge to making participation in our project and
|
||||
our community a harassment-free experience for everyone, regardless of age, body
|
||||
size, disability, ethnicity, gender identity and expression, level of experience,
|
||||
education, socio-economic status, nationality, personal appearance, race,
|
||||
religion, or sexual identity and orientation.
|
||||
|
||||
## Our Standards
|
||||
|
||||
Examples of behavior that contributes to creating a positive environment
|
||||
include:
|
||||
|
||||
* Using welcoming and inclusive language
|
||||
* Being respectful of differing viewpoints and experiences
|
||||
* Gracefully accepting constructive criticism
|
||||
* Focusing on what is best for the community
|
||||
* Showing empathy towards other community members
|
||||
|
||||
Examples of unacceptable behavior by participants include:
|
||||
|
||||
* The use of sexualized language or imagery and unwelcome sexual attention or
|
||||
advances
|
||||
* Trolling, insulting/derogatory comments, and personal or political attacks
|
||||
* Public or private harassment
|
||||
* Publishing others' private information, such as a physical or electronic
|
||||
address, without explicit permission
|
||||
* Other conduct which could reasonably be considered inappropriate in a
|
||||
professional setting
|
||||
|
||||
## Our Responsibilities
|
||||
|
||||
Project maintainers are responsible for clarifying the standards of acceptable
|
||||
behavior and are expected to take appropriate and fair corrective action in
|
||||
response to any instances of unacceptable behavior.
|
||||
|
||||
Project maintainers have the right and responsibility to remove, edit, or
|
||||
reject comments, commits, code, wiki edits, issues, and other contributions
|
||||
that are not aligned to this Code of Conduct, or to ban temporarily or
|
||||
permanently any contributor for other behaviors that they deem inappropriate,
|
||||
threatening, offensive, or harmful.
|
||||
|
||||
## Scope
|
||||
|
||||
This Code of Conduct applies both within project spaces and in public spaces
|
||||
when an individual is representing the project or its community. Examples of
|
||||
representing a project or community include using an official project e-mail
|
||||
address, posting via an official social media account, or acting as an appointed
|
||||
representative at an online or offline event. Representation of a project may be
|
||||
further defined and clarified by project maintainers.
|
||||
|
||||
## Enforcement
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
||||
reported by contacting the project team at fdb-conduct@group.apple.com. All
|
||||
complaints will be reviewed and investigated and will result in a response that
|
||||
is deemed necessary and appropriate to the circumstances. The project team is
|
||||
obligated to maintain confidentiality with regard to the reporter of an incident.
|
||||
Further details of specific enforcement policies may be posted separately.
|
||||
|
||||
Project maintainers who do not follow or enforce the Code of Conduct in good
|
||||
faith may face temporary or permanent repercussions as determined by other
|
||||
members of the project's leadership.
|
||||
|
||||
## Attribution
|
||||
|
||||
This Code of Conduct is adapted from the [Contributor Covenant](https://www.contributor-covenant.org/), version 1.4,
|
||||
available at [https://www.contributor-covenant.org/version/1/4/code-of-conduct.html](https://www.contributor-covenant.org/version/1/4/code-of-conduct.html)
|
|
@ -0,0 +1,68 @@
|
|||
# Contributing to FoundationDB
|
||||
|
||||
Welcome to the FoundationDB community, and thank you for contributing! The following guide outlines the basics of how to get involved.
|
||||
|
||||
If you have questions, we encourage you to engage in discussion on the [community forums](https://forums.foundationdb.org). Pull requests to update and expand this guide are also welcome.
|
||||
|
||||
#### Table of Contents
|
||||
|
||||
* [Before you get started](#before-you-get-started)
|
||||
* [Community Guidelines](#community-guidelines)
|
||||
* [Project Licensing](#project-licensing)
|
||||
* [Governance and Decision Making](#governance-and-decision-making)
|
||||
* [Contributing](#contributing)
|
||||
* [Opening a Pull Request](#opening-a-pull-request)
|
||||
* [Reporting Issues](#reporting-issues)
|
||||
* [Project Communication](#project-communication)
|
||||
* [Community Forums](#community-forums)
|
||||
* [Using GitHub Issues and Community Forums](#using-github-issues-and-community-forums)
|
||||
* [Project and Development Updates](#project-and-development-updates)
|
||||
|
||||
## Before you get started
|
||||
### Community Guidelines
|
||||
We want the FoundationDB community to be as welcoming and inclusive as possible, and have adopted a [Code of Conduct](CODE_OF_CONDUCT.md) that we ask all community members to read and observe.
|
||||
|
||||
### Project Licensing
|
||||
By submitting a pull request, you represent that you have the right to license your contribution to Apple and the community, and agree by submitting the patch that your contributions are licensed under the Apache 2.0 license.
|
||||
|
||||
### Governance and Decision Making
|
||||
At project launch, FoundationDB has a light governance structure. The intention is for the community to evolve quickly and adopt additional processes as participation grows. Stay tuned, and stay engaged! Your feedback is welcome.
|
||||
|
||||
We draw inspiration from the Apache Software Foundation's informal motto: ["community over code"](https://blogs.apache.org/foundation/entry/asf_15_community_over_code), and their emphasis on meritocratic rules. You'll also observe that some initial community structure is [inspired by the Swift community](https://swift.org/community/#community-structure).
|
||||
|
||||
The project technical lead is Ben Collins (bbc@apple.com).
|
||||
|
||||
Members of the Apple FoundationDB team are part of the initial core committers helping review individual contributions; you'll see them commenting on your pull requests. Future committers to the open source project, and the process for adding individuals in this role will be formalized in the future.
|
||||
|
||||
## Contributing
|
||||
### Opening a Pull Request
|
||||
We love pull requests! For minor changes, feel free to open up a PR directly. For larger feature development and any changes that may require community discussion, we ask that you discuss your ideas on the [community forums](https://forums.foundationdb.org) prior to opening a PR, and then reference that thread within your PR comment.
|
||||
|
||||
Upon release, no community CI is available. Tests can be run locally, and core committers will validate pull requests prior to merging them.
|
||||
|
||||
### Reporting issues
|
||||
Please refer to the section below on [using GitHub issues and the community forums](#using-github-issues-and-community-forums) for more info.
|
||||
|
||||
#### Security issues
|
||||
To report a security issue, please **DO NOT** start by filing a public issue or posting to the forums; instead send a private email to [fdb-oss-security@group.apple.com](mailto:fdb-oss-security@group.apple.com).
|
||||
|
||||
## Project Communication
|
||||
### Community Forums
|
||||
We encourage your participation asking questions and helping improve the FoundationDB project. Check out the [FoundationDB community forums](https://forums.foundationdb.org), which serve a similar function as mailing lists in many open source projects. The forums are organized into three sections:
|
||||
|
||||
* [Development](https://forums.foundationdb.org/c/development): For discussing the internals and development of the FoundationDB core, as well as layers.
|
||||
* [Using FoundationDB](https://forums.foundationdb.org/c/using-foundationdb): For discussing user-facing topics. Getting started and have a question? This is the place for you.
|
||||
* [Site Feedback](https://forums.foundationdb.org/c/site-feedback): A category for discussing the forums and the OSS project, its organization, how it works, and how we can improve it.
|
||||
|
||||
### Using GitHub Issues and Community Forums
|
||||
GitHub issues and the community forums both offer features to facilitate discussion. To clarify how and when to use each tool, here's a quick summary of how we think about them:
|
||||
|
||||
GitHub Issues should be used for tracking tasks. If you know the specific code that needs to be changed, then it should go to GitHub Issues. Everything else should go to the Forums. For example:
|
||||
|
||||
* I am experiencing some weird behavior, which I think is a bug, but I don't know where exactly (mysteries and unexpected behaviors): *Forums*
|
||||
* I see a bug in this piece of code: *GitHub Issues*
|
||||
* Feature requests and design documents: *Forums*
|
||||
* Implementing an agreed upon feature: *GitHub Issues*
|
||||
|
||||
### Project and Development Updates
|
||||
Stay connected to the project and the community! For project and community updates, follow the [FoundationDB project blog](https://www.foundationdb.org/blog/). Development announcements will be made via the community forums' [dev-announce](https://forums.foundationdb.org/c/development/dev-announce) section.
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
global:
|
||||
get_plugin;
|
||||
local:
|
||||
*;
|
||||
};
|
|
@ -0,0 +1 @@
|
|||
_get_plugin
|
|
@ -0,0 +1,31 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|X64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>X64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|X64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>X64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="FDBLibTLSPlugin.h" />
|
||||
<ClCompile Include="FDBLibTLSPlugin.cpp" />
|
||||
<ClInclude Include="FDBLibTLSPolicy.h" />
|
||||
<ClCompile Include="FDBLibTLSPolicy.cpp" />
|
||||
<ClInclude Include="FDBLibTLSSession.h" />
|
||||
<ClCompile Include="FDBLibTLSSession.cpp" />
|
||||
</ItemGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|X64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
<PlatformToolset>v140_xp</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|X64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
<PlatformToolset>v140_xp</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
</Project>
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* FDBLibTLSPlugin.cpp
|
||||
*
|
||||
* This source file is part of the FoundationDB open source project
|
||||
*
|
||||
* Copyright 2013-2018 Apple Inc. and the FoundationDB project authors
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "boost/config.hpp"
|
||||
|
||||
#include "FDBLibTLSPlugin.h"
|
||||
#include "FDBLibTLSPolicy.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
FDBLibTLSPlugin::FDBLibTLSPlugin() {
|
||||
// tls_init is not currently thread safe - caller's responsibility.
|
||||
rc = tls_init();
|
||||
}
|
||||
|
||||
FDBLibTLSPlugin::~FDBLibTLSPlugin() {
|
||||
}
|
||||
|
||||
ITLSPolicy *FDBLibTLSPlugin::create_policy(ITLSLogFunc logf) {
|
||||
if (rc < 0) {
|
||||
// Log the failure from tls_init during our constructor.
|
||||
logf("FDBLibTLSInitError", NULL, true, "LibTLSErrorMessage", "failed to initialize libtls", NULL);
|
||||
return NULL;
|
||||
}
|
||||
return new FDBLibTLSPolicy(Reference<FDBLibTLSPlugin>::addRef(this), logf);
|
||||
}
|
||||
|
||||
extern "C" BOOST_SYMBOL_EXPORT void *get_plugin(const char *plugin_type_name_and_version) {
|
||||
if (strcmp(plugin_type_name_and_version, FDBLibTLSPlugin::get_plugin_type_name_and_version()) == 0) {
|
||||
return new FDBLibTLSPlugin;
|
||||
}
|
||||
return NULL;
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* FdbError.h
|
||||
* FDBLibTLSPlugin.h
|
||||
*
|
||||
* This source file is part of the FoundationDB open source project
|
||||
*
|
||||
|
@ -18,23 +18,26 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef FDB_LIBTLS_PLUGIN_H
|
||||
#define FDB_LIBTLS_PLUGIN_H
|
||||
|
||||
#ifndef FDB_NODE_FDB_ERROR_H
|
||||
#define FDB_NODE_FDB_ERROR_H
|
||||
#pragma once
|
||||
|
||||
#include "Version.h"
|
||||
#include "ITLSPlugin.h"
|
||||
#include "ReferenceCounted.h"
|
||||
|
||||
#include <foundationdb/fdb_c.h>
|
||||
#include <node.h>
|
||||
#include <tls.h>
|
||||
|
||||
class FdbError {
|
||||
public:
|
||||
static v8::Handle<v8::Value> NewInstance(fdb_error_t code, const char *description);
|
||||
struct FDBLibTLSPlugin : ITLSPlugin, ReferenceCounted<FDBLibTLSPlugin> {
|
||||
FDBLibTLSPlugin();
|
||||
virtual ~FDBLibTLSPlugin();
|
||||
|
||||
static void Init( v8::Handle<v8::Object> module );
|
||||
virtual void addref() { ReferenceCounted<FDBLibTLSPlugin>::addref(); }
|
||||
virtual void delref() { ReferenceCounted<FDBLibTLSPlugin>::delref(); }
|
||||
|
||||
private:
|
||||
FdbError(); // not implemented by design
|
||||
virtual ITLSPolicy *create_policy(ITLSLogFunc logf);
|
||||
|
||||
int rc;
|
||||
};
|
||||
|
||||
#endif
|
||||
#endif /* FDB_LIBTLS_PLUGIN_H */
|
|
@ -0,0 +1,420 @@
|
|||
/*
|
||||
* FDBLibTLSPolicy.cpp
|
||||
*
|
||||
* This source file is part of the FoundationDB open source project
|
||||
*
|
||||
* Copyright 2013-2018 Apple Inc. and the FoundationDB project authors
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "FDBLibTLSPolicy.h"
|
||||
#include "FDBLibTLSSession.h"
|
||||
|
||||
#include <openssl/bio.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/objects.h>
|
||||
#include <openssl/obj_mac.h>
|
||||
#include <openssl/pem.h>
|
||||
#include <openssl/x509.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <exception>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
|
||||
FDBLibTLSPolicy::FDBLibTLSPolicy(Reference<FDBLibTLSPlugin> plugin, ITLSLogFunc logf):
|
||||
plugin(plugin), logf(logf), tls_cfg(NULL), session_created(false), cert_data_set(false),
|
||||
key_data_set(false), verify_peers_set(false), verify_cert(true), verify_time(true) {
|
||||
|
||||
if ((tls_cfg = tls_config_new()) == NULL) {
|
||||
logf("FDBLibTLSConfigError", NULL, true, NULL);
|
||||
throw std::runtime_error("FDBLibTLSConfigError");
|
||||
}
|
||||
|
||||
// Require client certificates for authentication.
|
||||
tls_config_verify_client(tls_cfg);
|
||||
|
||||
// Name verification is always manually handled (if requested via configuration).
|
||||
tls_config_insecure_noverifyname(tls_cfg);
|
||||
}
|
||||
|
||||
FDBLibTLSPolicy::~FDBLibTLSPolicy() {
|
||||
tls_config_free(tls_cfg);
|
||||
}
|
||||
|
||||
ITLSSession* FDBLibTLSPolicy::create_session(bool is_client, TLSSendCallbackFunc send_func, void* send_ctx, TLSRecvCallbackFunc recv_func, void* recv_ctx, void* uid) {
|
||||
session_created = true;
|
||||
try {
|
||||
return new FDBLibTLSSession(Reference<FDBLibTLSPolicy>::addRef(this), is_client, send_func, send_ctx, recv_func, recv_ctx, uid);
|
||||
} catch ( ... ) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static int hexValue(char c) {
|
||||
static char const digits[] = "0123456789ABCDEF";
|
||||
|
||||
if (c >= 'a' && c <= 'f')
|
||||
c -= ('a' - 'A');
|
||||
|
||||
int value = std::find(digits, digits + 16, c) - digits;
|
||||
if (value >= 16) {
|
||||
throw std::runtime_error("hexValue");
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
// Does not handle "raw" form (e.g. #28C4D1), only escaped text
|
||||
static std::string de4514(std::string const& input, int start, int& out_end) {
|
||||
std::string output;
|
||||
|
||||
if(input[start] == '#' || input[start] == ' ') {
|
||||
out_end = start;
|
||||
return output;
|
||||
}
|
||||
|
||||
int space_count = 0;
|
||||
|
||||
for(int p = start; p < input.size();) {
|
||||
switch(input[p]) {
|
||||
case '\\': // Handle escaped sequence
|
||||
|
||||
// Backslash escaping nothing!
|
||||
if(p == input.size() - 1) {
|
||||
out_end = p;
|
||||
goto FIN;
|
||||
}
|
||||
|
||||
switch(input[p+1]) {
|
||||
case ' ':
|
||||
case '"':
|
||||
case '#':
|
||||
case '+':
|
||||
case ',':
|
||||
case ';':
|
||||
case '<':
|
||||
case '=':
|
||||
case '>':
|
||||
case '\\':
|
||||
output += input[p+1];
|
||||
p += 2;
|
||||
space_count = 0;
|
||||
continue;
|
||||
|
||||
default:
|
||||
// Backslash escaping pair of hex digits requires two characters
|
||||
if(p == input.size() - 2) {
|
||||
out_end = p;
|
||||
goto FIN;
|
||||
}
|
||||
|
||||
try {
|
||||
output += hexValue(input[p+1]) * 16 + hexValue(input[p+2]);
|
||||
p += 3;
|
||||
space_count = 0;
|
||||
continue;
|
||||
} catch( ... ) {
|
||||
out_end = p;
|
||||
goto FIN;
|
||||
}
|
||||
}
|
||||
|
||||
case '"':
|
||||
case '+':
|
||||
case ',':
|
||||
case ';':
|
||||
case '<':
|
||||
case '>':
|
||||
case 0:
|
||||
// All of these must have been escaped
|
||||
out_end = p;
|
||||
goto FIN;
|
||||
|
||||
default:
|
||||
// Character is what it is
|
||||
output += input[p];
|
||||
if(input[p] == ' ')
|
||||
space_count++;
|
||||
else
|
||||
space_count = 0;
|
||||
p++;
|
||||
}
|
||||
}
|
||||
|
||||
out_end = input.size();
|
||||
|
||||
FIN:
|
||||
out_end -= space_count;
|
||||
output.resize(output.size() - space_count);
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
static std::pair<std::string, std::string> splitPair(std::string const& input, char c) {
|
||||
int p = input.find_first_of(c);
|
||||
if(p == input.npos) {
|
||||
throw std::runtime_error("splitPair");
|
||||
}
|
||||
return std::make_pair(input.substr(0, p), input.substr(p+1, input.size()));
|
||||
}
|
||||
|
||||
static int abbrevToNID(std::string const& sn) {
|
||||
int nid = NID_undef;
|
||||
|
||||
if (sn == "C" || sn == "CN" || sn == "L" || sn == "ST" || sn == "O" || sn == "OU")
|
||||
nid = OBJ_sn2nid(sn.c_str());
|
||||
if (nid == NID_undef)
|
||||
throw std::runtime_error("abbrevToNID");
|
||||
|
||||
return nid;
|
||||
}
|
||||
|
||||
void FDBLibTLSPolicy::parse_verify(std::string input) {
|
||||
int s = 0;
|
||||
|
||||
while (s < input.size()) {
|
||||
int eq = input.find('=', s);
|
||||
|
||||
if (eq == input.npos)
|
||||
throw std::runtime_error("parse_verify");
|
||||
|
||||
std::string term = input.substr(s, eq - s);
|
||||
|
||||
if (term.find("Check.") == 0) {
|
||||
if (eq + 2 > input.size())
|
||||
throw std::runtime_error("parse_verify");
|
||||
if (eq + 2 != input.size() && input[eq + 2] != ',')
|
||||
throw std::runtime_error("parse_verify");
|
||||
|
||||
bool* flag;
|
||||
|
||||
if (term == "Check.Valid")
|
||||
flag = &verify_cert;
|
||||
else if (term == "Check.Unexpired")
|
||||
flag = &verify_time;
|
||||
else
|
||||
throw std::runtime_error("parse_verify");
|
||||
|
||||
if (input[eq + 1] == '0')
|
||||
*flag = false;
|
||||
else if (input[eq + 1] == '1')
|
||||
*flag = true;
|
||||
else
|
||||
throw std::runtime_error("parse_verify");
|
||||
|
||||
s = eq + 3;
|
||||
} else {
|
||||
std::map<int, std::string>* criteria = &subject_criteria;
|
||||
|
||||
if (term.find('.') != term.npos) {
|
||||
auto scoped = splitPair(term, '.');
|
||||
|
||||
if (scoped.first == "S" || scoped.first == "Subject")
|
||||
criteria = &subject_criteria;
|
||||
else if (scoped.first == "I" || scoped.first == "Issuer")
|
||||
criteria = &issuer_criteria;
|
||||
else
|
||||
throw std::runtime_error("parse_verify");
|
||||
|
||||
term = scoped.second;
|
||||
}
|
||||
|
||||
int remain;
|
||||
auto unesc = de4514(input, eq + 1, remain);
|
||||
|
||||
if (remain == eq + 1)
|
||||
throw std::runtime_error("parse_verify");
|
||||
|
||||
criteria->insert(std::make_pair(abbrevToNID(term), unesc));
|
||||
|
||||
if (remain != input.size() && input[remain] != ',')
|
||||
throw std::runtime_error("parse_verify");
|
||||
|
||||
s = remain + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FDBLibTLSPolicy::reset_verify() {
|
||||
verify_cert = true;
|
||||
verify_time = true;
|
||||
subject_criteria = {};
|
||||
issuer_criteria = {};
|
||||
}
|
||||
|
||||
int password_cb(char *buf, int size, int rwflag, void *u) {
|
||||
// A no-op password callback is provided simply to stop libcrypto
|
||||
// from trying to use its own password reading functionality.
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool FDBLibTLSPolicy::set_cert_data(const uint8_t* cert_data, int cert_len) {
|
||||
struct stack_st_X509 *certs = NULL;
|
||||
unsigned long errnum;
|
||||
X509 *cert = NULL;
|
||||
BIO *bio = NULL;
|
||||
long data_len;
|
||||
char *data;
|
||||
bool rc = false;
|
||||
|
||||
// The cert data contains one or more PEM encoded certificates - the
|
||||
// first certificate is for this host, with any additional certificates
|
||||
// being the full certificate chain. As such, the last certificate
|
||||
// is the trusted root certificate. If only one certificate is provided
|
||||
// then it is required to be a self-signed certificate, which is also
|
||||
// treated as the trusted root.
|
||||
|
||||
if (cert_data_set) {
|
||||
logf("FDBLibTLSCertAlreadySet", NULL, true, NULL);
|
||||
goto err;
|
||||
}
|
||||
if (session_created) {
|
||||
logf("FDBLibTLSPolicyAlreadyActive", NULL, true, NULL);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if ((certs = sk_X509_new_null()) == NULL) {
|
||||
logf("FDBLibTLSOutOfMemory", NULL, true, NULL);
|
||||
goto err;
|
||||
}
|
||||
if ((bio = BIO_new_mem_buf((void *)cert_data, cert_len)) == NULL) {
|
||||
logf("FDBLibTLSOutOfMemory", NULL, true, NULL);
|
||||
goto err;
|
||||
}
|
||||
|
||||
ERR_clear_error();
|
||||
while ((cert = PEM_read_bio_X509(bio, NULL, password_cb, NULL)) != NULL) {
|
||||
if (!sk_X509_push(certs, cert)) {
|
||||
logf("FDBLibTLSOutOfMemory", NULL, true, NULL);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure that the NULL cert was caused by EOF and not some other failure.
|
||||
errnum = ERR_peek_last_error();
|
||||
if (ERR_GET_LIB(errnum) != ERR_LIB_PEM || ERR_GET_REASON(errnum) != PEM_R_NO_START_LINE) {
|
||||
char errbuf[256];
|
||||
|
||||
ERR_error_string_n(errnum, errbuf, sizeof(errbuf));
|
||||
logf("FDBLibTLSCertDataError", NULL, true, "LibcryptoErrorMessage", errbuf, NULL);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (sk_X509_num(certs) < 1) {
|
||||
logf("FDBLibTLSNoCerts", NULL, true, NULL);
|
||||
goto err;
|
||||
}
|
||||
|
||||
BIO_free_all(bio);
|
||||
if ((bio = BIO_new(BIO_s_mem())) == NULL) {
|
||||
logf("FDBLibTLSOutOfMemory", NULL, true, NULL);
|
||||
goto err;
|
||||
}
|
||||
if (!PEM_write_bio_X509(bio, sk_X509_value(certs, sk_X509_num(certs) - 1))) {
|
||||
logf("FDBLibTLSCertWriteError", NULL, true, NULL);
|
||||
goto err;
|
||||
}
|
||||
if ((data_len = BIO_get_mem_data(bio, &data)) <= 0) {
|
||||
logf("FDBLibTLSCertError", NULL, true, NULL);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (tls_config_set_ca_mem(tls_cfg, (const uint8_t *)data, data_len) == -1) {
|
||||
logf("FDBLibTLSSetCAError", NULL, true, "LibTLSErrorMessage", tls_config_error(tls_cfg), NULL);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (sk_X509_num(certs) > 1) {
|
||||
BIO_free_all(bio);
|
||||
if ((bio = BIO_new(BIO_s_mem())) == NULL) {
|
||||
logf("FDBLibTLSOutOfMemory", NULL, true, NULL);
|
||||
goto err;
|
||||
}
|
||||
for (int i = 0; i < sk_X509_num(certs) - 1; i++) {
|
||||
if (!PEM_write_bio_X509(bio, sk_X509_value(certs, i))) {
|
||||
logf("FDBLibTLSCertWriteError", NULL, true, NULL);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
if ((data_len = BIO_get_mem_data(bio, &data)) <= 0) {
|
||||
logf("FDBLibTLSCertError", NULL, true, NULL);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
if (tls_config_set_cert_mem(tls_cfg, (const uint8_t *)data, data_len) == -1) {
|
||||
logf("FDBLibTLSSetCertError", NULL, true, "LibTLSErrorMessage", tls_config_error(tls_cfg), NULL);
|
||||
goto err;
|
||||
}
|
||||
|
||||
rc = true;
|
||||
|
||||
err:
|
||||
sk_X509_pop_free(certs, X509_free);
|
||||
X509_free(cert);
|
||||
BIO_free_all(bio);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
bool FDBLibTLSPolicy::set_key_data(const uint8_t* key_data, int key_len) {
|
||||
if (key_data_set) {
|
||||
logf("FDBLibTLSKeyAlreadySet", NULL, true, NULL);
|
||||
return false;
|
||||
}
|
||||
if (session_created) {
|
||||
logf("FDBLibTLSPolicyAlreadyActive", NULL, true, NULL);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (tls_config_set_key_mem(tls_cfg, key_data, key_len) == -1) {
|
||||
logf("FDBLibTLSKeyError", NULL, true, "LibTLSErrorMessage", tls_config_error(tls_cfg), NULL);
|
||||
return false;
|
||||
}
|
||||
|
||||
key_data_set = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool FDBLibTLSPolicy::set_verify_peers(const uint8_t* verify_peers, int verify_peers_len) {
|
||||
if (verify_peers_set) {
|
||||
logf("FDBLibTLSVerifyPeersAlreadySet", NULL, true, NULL);
|
||||
return false;
|
||||
}
|
||||
if (session_created) {
|
||||
logf("FDBLibTLSPolicyAlreadyActive", NULL, true, NULL);
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
parse_verify(std::string((const char*)verify_peers, verify_peers_len));
|
||||
} catch ( const std::runtime_error& e ) {
|
||||
reset_verify();
|
||||
logf("FDBLibTLSVerifyPeersParseError", NULL, true, "Config", verify_peers, NULL);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!verify_cert)
|
||||
tls_config_insecure_noverifycert(tls_cfg);
|
||||
|
||||
if (!verify_time)
|
||||
tls_config_insecure_noverifytime(tls_cfg);
|
||||
|
||||
verify_peers_set = true;
|
||||
|
||||
return true;
|
||||
}
|
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
* FDBLibTLSPolicy.h
|
||||
*
|
||||
* This source file is part of the FoundationDB open source project
|
||||
*
|
||||
* Copyright 2013-2018 Apple Inc. and the FoundationDB project authors
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef FDB_LIBTLS_POLICY_H
|
||||
#define FDB_LIBTLS_POLICY_H
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "FDBLibTLSPlugin.h"
|
||||
#include "ITLSPlugin.h"
|
||||
#include "ReferenceCounted.h"
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
struct FDBLibTLSPolicy: ITLSPolicy, ReferenceCounted<FDBLibTLSPolicy> {
|
||||
FDBLibTLSPolicy(Reference<FDBLibTLSPlugin> plugin, ITLSLogFunc logf);
|
||||
virtual ~FDBLibTLSPolicy();
|
||||
|
||||
virtual void addref() { ReferenceCounted<FDBLibTLSPolicy>::addref(); }
|
||||
virtual void delref() { ReferenceCounted<FDBLibTLSPolicy>::delref(); }
|
||||
|
||||
Reference<FDBLibTLSPlugin> plugin;
|
||||
ITLSLogFunc logf;
|
||||
|
||||
virtual ITLSSession* create_session(bool is_client, TLSSendCallbackFunc send_func, void* send_ctx, TLSRecvCallbackFunc recv_func, void* recv_ctx, void* uid);
|
||||
|
||||
void parse_verify(std::string input);
|
||||
void reset_verify(void);
|
||||
|
||||
virtual bool set_cert_data(const uint8_t* cert_data, int cert_len);
|
||||
virtual bool set_key_data(const uint8_t* key_data, int key_len);
|
||||
virtual bool set_verify_peers(const uint8_t* verify_peers, int verify_peers_len);
|
||||
|
||||
struct tls_config *tls_cfg;
|
||||
|
||||
bool session_created;
|
||||
|
||||
bool cert_data_set;
|
||||
bool key_data_set;
|
||||
bool verify_peers_set;
|
||||
|
||||
bool verify_cert;
|
||||
bool verify_time;
|
||||
|
||||
std::map<int, std::string> subject_criteria;
|
||||
std::map<int, std::string> issuer_criteria;
|
||||
};
|
||||
|
||||
#endif /* FDB_LIBTLS_POLICY_H */
|
|
@ -0,0 +1,275 @@
|
|||
/*
|
||||
* FDBLibTLSSession.cpp
|
||||
*
|
||||
* This source file is part of the FoundationDB open source project
|
||||
*
|
||||
* Copyright 2013-2018 Apple Inc. and the FoundationDB project authors
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "FDBLibTLSSession.h"
|
||||
|
||||
#include <openssl/bio.h>
|
||||
#include <openssl/pem.h>
|
||||
#include <openssl/x509.h>
|
||||
|
||||
#include <exception>
|
||||
#include <iostream>
|
||||
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
|
||||
static ssize_t tls_read_func(struct tls *ctx, void *buf, size_t buflen, void *cb_arg)
|
||||
{
|
||||
FDBLibTLSSession *session = (FDBLibTLSSession *)cb_arg;
|
||||
|
||||
int rv = session->recv_func(session->recv_ctx, (uint8_t *)buf, buflen);
|
||||
if (rv < 0)
|
||||
return 0;
|
||||
if (rv == 0)
|
||||
return TLS_WANT_POLLIN;
|
||||
return (ssize_t)rv;
|
||||
}
|
||||
|
||||
static ssize_t tls_write_func(struct tls *ctx, const void *buf, size_t buflen, void *cb_arg)
|
||||
{
|
||||
FDBLibTLSSession *session = (FDBLibTLSSession *)cb_arg;
|
||||
|
||||
int rv = session->send_func(session->send_ctx, (const uint8_t *)buf, buflen);
|
||||
if (rv < 0)
|
||||
return 0;
|
||||
if (rv == 0)
|
||||
return TLS_WANT_POLLOUT;
|
||||
return (ssize_t)rv;
|
||||
}
|
||||
|
||||
FDBLibTLSSession::FDBLibTLSSession(Reference<FDBLibTLSPolicy> policy, bool is_client, TLSSendCallbackFunc send_func, void* send_ctx, TLSRecvCallbackFunc recv_func, void* recv_ctx, void* uid) :
|
||||
tls_ctx(NULL), tls_sctx(NULL), policy(policy), send_func(send_func), send_ctx(send_ctx), recv_func(recv_func), recv_ctx(recv_ctx), handshake_completed(false), uid(uid) {
|
||||
|
||||
if (is_client) {
|
||||
if ((tls_ctx = tls_client()) == NULL) {
|
||||
policy->logf("FDBLibTLSClientError", uid, true, NULL);
|
||||
throw std::runtime_error("FDBLibTLSClientError");
|
||||
}
|
||||
if (tls_configure(tls_ctx, policy->tls_cfg) == -1) {
|
||||
policy->logf("FDBLibTLSConfigureError", uid, true, "LibTLSErrorMessage", tls_error(tls_ctx), NULL);
|
||||
tls_free(tls_ctx);
|
||||
throw std::runtime_error("FDBLibTLSConfigureError");
|
||||
}
|
||||
if (tls_connect_cbs(tls_ctx, tls_read_func, tls_write_func, this, NULL) == -1) {
|
||||
policy->logf("FDBLibTLSConnectError", uid, true, "LibTLSErrorMessage", tls_error(tls_ctx), NULL);
|
||||
tls_free(tls_ctx);
|
||||
throw std::runtime_error("FDBLibTLSConnectError");
|
||||
}
|
||||
} else {
|
||||
if ((tls_sctx = tls_server()) == NULL) {
|
||||
policy->logf("FDBLibTLSServerError", uid, true, NULL);
|
||||
throw std::runtime_error("FDBLibTLSServerError");
|
||||
}
|
||||
if (tls_configure(tls_sctx, policy->tls_cfg) == -1) {
|
||||
policy->logf("FDBLibTLSConfigureError", uid, true, "LibTLSErrorMessage", tls_error(tls_sctx), NULL);
|
||||
tls_free(tls_sctx);
|
||||
throw std::runtime_error("FDBLibTLSConfigureError");
|
||||
}
|
||||
if (tls_accept_cbs(tls_sctx, &tls_ctx, tls_read_func, tls_write_func, this) == -1) {
|
||||
policy->logf("FDBLibTLSAcceptError", uid, true, "LibTLSErrorMessage", tls_error(tls_sctx), NULL);
|
||||
tls_free(tls_sctx);
|
||||
throw std::runtime_error("FDBLibTLSAcceptError");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FDBLibTLSSession::~FDBLibTLSSession() {
|
||||
// This would ideally call tls_close(), however that means either looping
|
||||
// in a destructor or doing it opportunistically...
|
||||
tls_free(tls_ctx);
|
||||
tls_free(tls_sctx);
|
||||
}
|
||||
|
||||
int password_cb(char *buf, int size, int rwflag, void *u);
|
||||
|
||||
bool match_criteria(X509_NAME *name, int nid, const char *value, size_t len) {
|
||||
unsigned char *name_entry_utf8 = NULL, *criteria_utf8 = NULL;
|
||||
int name_entry_utf8_len, criteria_utf8_len;
|
||||
ASN1_STRING *criteria = NULL;
|
||||
X509_NAME_ENTRY *name_entry;
|
||||
BIO *bio;
|
||||
bool rc = false;
|
||||
int idx;
|
||||
|
||||
if ((criteria = ASN1_IA5STRING_new()) == NULL)
|
||||
goto err;
|
||||
if (ASN1_STRING_set(criteria, value, len) != 1)
|
||||
goto err;
|
||||
|
||||
// If name does not exist, or has multiple of this RDN, refuse to proceed.
|
||||
if ((idx = X509_NAME_get_index_by_NID(name, nid, -1)) < 0)
|
||||
goto err;
|
||||
if (X509_NAME_get_index_by_NID(name, nid, idx) != -1)
|
||||
goto err;
|
||||
if ((name_entry = X509_NAME_get_entry(name, idx)) == NULL)
|
||||
goto err;
|
||||
|
||||
// Convert both to UTF8 and compare.
|
||||
if ((criteria_utf8_len = ASN1_STRING_to_UTF8(&criteria_utf8, criteria)) < 1)
|
||||
goto err;
|
||||
if ((name_entry_utf8_len = ASN1_STRING_to_UTF8(&name_entry_utf8, name_entry->value)) < 1)
|
||||
goto err;
|
||||
if (criteria_utf8_len == name_entry_utf8_len &&
|
||||
memcmp(criteria_utf8, name_entry_utf8, criteria_utf8_len) == 0)
|
||||
rc = true;
|
||||
|
||||
err:
|
||||
ASN1_STRING_free(criteria);
|
||||
free(criteria_utf8);
|
||||
free(name_entry_utf8);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
bool FDBLibTLSSession::check_criteria() {
|
||||
X509_NAME *subject, *issuer;
|
||||
const uint8_t *cert_pem;
|
||||
size_t cert_pem_len;
|
||||
X509 *cert = NULL;
|
||||
BIO *bio = NULL;
|
||||
bool rc = false;
|
||||
|
||||
// If certificate verification is disabled, there's nothing more to do.
|
||||
if (!policy->verify_cert)
|
||||
return true;
|
||||
|
||||
// If no criteria have been specified, then we're done.
|
||||
if (policy->subject_criteria.size() == 0 && policy->issuer_criteria.size() == 0)
|
||||
return true;
|
||||
|
||||
if ((cert_pem = tls_peer_cert_chain_pem(tls_ctx, &cert_pem_len)) == NULL) {
|
||||
policy->logf("FDBLibTLSNoCertError", uid, true, NULL);
|
||||
goto err;
|
||||
}
|
||||
if ((bio = BIO_new_mem_buf((void *)cert_pem, cert_pem_len)) == NULL) {
|
||||
policy->logf("FDBLibTLSOutOfMemory", NULL, true, NULL);
|
||||
goto err;
|
||||
}
|
||||
if ((cert = PEM_read_bio_X509(bio, NULL, password_cb, NULL)) == NULL) {
|
||||
policy->logf("FDBLibTLSCertPEMError", uid, true, NULL);
|
||||
goto err;
|
||||
}
|
||||
|
||||
// Check subject criteria.
|
||||
if ((subject = X509_get_subject_name(cert)) == NULL) {
|
||||
policy->logf("FDBLibTLSCertSubjectError", uid, true, NULL);
|
||||
goto err;
|
||||
}
|
||||
for (auto &pair: policy->subject_criteria) {
|
||||
if (!match_criteria(subject, pair.first, pair.second.c_str(), pair.second.size())) {
|
||||
policy->logf("FDBLibTLSCertSubjectMatchFailure", uid, true, NULL);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
// Check issuer criteria.
|
||||
if ((issuer = X509_get_issuer_name(cert)) == NULL) {
|
||||
policy->logf("FDBLibTLSCertIssuerError", uid, true, NULL);
|
||||
goto err;
|
||||
}
|
||||
for (auto &pair: policy->issuer_criteria) {
|
||||
if (!match_criteria(issuer, pair.first, pair.second.c_str(), pair.second.size())) {
|
||||
policy->logf("FDBLibTLSCertIssuerMatchFailure", uid, true, NULL);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
// If we got this far, everything checked out...
|
||||
rc = true;
|
||||
|
||||
err:
|
||||
BIO_free_all(bio);
|
||||
X509_free(cert);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int FDBLibTLSSession::handshake() {
|
||||
int rv = tls_handshake(tls_ctx);
|
||||
|
||||
switch (rv) {
|
||||
case 0:
|
||||
if (!check_criteria())
|
||||
return FAILED;
|
||||
handshake_completed = true;
|
||||
return SUCCESS;
|
||||
case TLS_WANT_POLLIN:
|
||||
return WANT_READ;
|
||||
case TLS_WANT_POLLOUT:
|
||||
return WANT_WRITE;
|
||||
default:
|
||||
policy->logf("FDBLibTLSHandshakeError", uid, false, "LibTLSErrorMessage", tls_error(tls_ctx), NULL);
|
||||
return FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
int FDBLibTLSSession::read(uint8_t* data, int length) {
|
||||
if (!handshake_completed) {
|
||||
policy->logf("FDBLibTLSReadHandshakeError", uid, true, NULL);
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
ssize_t n = tls_read(tls_ctx, data, length);
|
||||
if (n > 0) {
|
||||
if (n > INT_MAX) {
|
||||
policy->logf("FDBLibTLSReadOverflow", uid, true, NULL);
|
||||
return FAILED;
|
||||
}
|
||||
return (int)n;
|
||||
}
|
||||
if (n == 0) {
|
||||
policy->logf("FDBLibTLSReadEOF", uid, false, NULL);
|
||||
return FAILED;
|
||||
}
|
||||
if (n == TLS_WANT_POLLIN)
|
||||
return WANT_READ;
|
||||
if (n == TLS_WANT_POLLOUT)
|
||||
return WANT_WRITE;
|
||||
|
||||
policy->logf("FDBLibTLSReadError", uid, false, "LibTLSErrorMessage", tls_error(tls_ctx), NULL);
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
int FDBLibTLSSession::write(const uint8_t* data, int length) {
|
||||
if (!handshake_completed) {
|
||||
policy->logf("FDBLibTLSWriteHandshakeError", uid, true, NULL);
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
ssize_t n = tls_write(tls_ctx, data, length);
|
||||
if (n > 0) {
|
||||
if (n > INT_MAX) {
|
||||
policy->logf("FDBLibTLSWriteOverflow", uid, true, NULL);
|
||||
return FAILED;
|
||||
}
|
||||
return (int)n;
|
||||
}
|
||||
if (n == 0) {
|
||||
policy->logf("FDBLibTLSWriteEOF", uid, false, NULL);
|
||||
return FAILED;
|
||||
}
|
||||
if (n == TLS_WANT_POLLIN)
|
||||
return WANT_READ;
|
||||
if (n == TLS_WANT_POLLOUT)
|
||||
return WANT_WRITE;
|
||||
|
||||
policy->logf("FDBLibTLSWriteError", uid, false, "LibTLSErrorMessage", tls_error(tls_ctx), NULL);
|
||||
return FAILED;
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
* FDBLibTLSSession.h
|
||||
*
|
||||
* This source file is part of the FoundationDB open source project
|
||||
*
|
||||
* Copyright 2013-2018 Apple Inc. and the FoundationDB project authors
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef FDB_LIBTLS_SESSION_H
|
||||
#define FDB_LIBTLS_SESSION_H
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "ITLSPlugin.h"
|
||||
#include "ReferenceCounted.h"
|
||||
|
||||
#include "FDBLibTLSPolicy.h"
|
||||
|
||||
#include <tls.h>
|
||||
|
||||
struct FDBLibTLSSession : ITLSSession, ReferenceCounted<FDBLibTLSSession> {
|
||||
FDBLibTLSSession(Reference<FDBLibTLSPolicy> policy, bool is_client, TLSSendCallbackFunc send_func, void* send_ctx, TLSRecvCallbackFunc recv_func, void* recv_ctx, void* uid);
|
||||
virtual ~FDBLibTLSSession();
|
||||
|
||||
virtual void addref() { ReferenceCounted<FDBLibTLSSession>::addref(); }
|
||||
virtual void delref() { ReferenceCounted<FDBLibTLSSession>::delref(); }
|
||||
|
||||
bool check_criteria();
|
||||
|
||||
virtual int handshake();
|
||||
virtual int read(uint8_t* data, int length);
|
||||
virtual int write(const uint8_t* data, int length);
|
||||
|
||||
Reference<FDBLibTLSPolicy> policy;
|
||||
|
||||
struct tls *tls_ctx;
|
||||
struct tls *tls_sctx;
|
||||
|
||||
TLSSendCallbackFunc send_func;
|
||||
void* send_ctx;
|
||||
TLSRecvCallbackFunc recv_func;
|
||||
void* recv_ctx;
|
||||
|
||||
bool handshake_completed;
|
||||
|
||||
void* uid;
|
||||
};
|
||||
|
||||
#endif /* FDB_LIBTLS_SESSION_H */
|
|
@ -0,0 +1,140 @@
|
|||
/*
|
||||
* ITLSPlugin.h
|
||||
*
|
||||
* This source file is part of the FoundationDB open source project
|
||||
*
|
||||
* Copyright 2013-2018 Apple Inc. and the FoundationDB project authors
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef FDB_ITLSPLUGIN_H
|
||||
#define FDB_ITLSPLUGIN_H
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
struct ITLSSession {
|
||||
enum { SUCCESS = 0, WANT_READ = -1, WANT_WRITE = -2, FAILED = -3 };
|
||||
|
||||
virtual void addref() = 0;
|
||||
virtual void delref() = 0;
|
||||
|
||||
// handshake should return SUCCESS if the handshake is complete,
|
||||
// FAILED on fatal error, or one of WANT_READ or WANT_WRITE if the
|
||||
// handshake should be reattempted after more data can be
|
||||
// read/written on the underlying connection.
|
||||
virtual int handshake() = 0;
|
||||
|
||||
// read should return the (non-zero) number of bytes read,
|
||||
// WANT_READ or WANT_WRITE if the operation is blocked by the
|
||||
// underlying stream, or FAILED if there is an error (including a
|
||||
// closed connection).
|
||||
virtual int read(uint8_t* data, int length) = 0;
|
||||
|
||||
// write should return the (non-zero) number of bytes written, or
|
||||
// WANT_READ or WANT_WRITE if the operation is blocked by the
|
||||
// underlying stream, or FAILED if there is an error.
|
||||
virtual int write(const uint8_t* data, int length) = 0;
|
||||
};
|
||||
|
||||
// Returns the number of bytes sent (possibly 0), or -1 on error
|
||||
// (including connection close)
|
||||
typedef int (*TLSSendCallbackFunc)(void* ctx, const uint8_t* buf, int len);
|
||||
|
||||
// Returns the number of bytes read (possibly 0), or -1 on error
|
||||
// (including connection close)
|
||||
typedef int (*TLSRecvCallbackFunc)(void* ctx, uint8_t* buf, int len);
|
||||
|
||||
struct ITLSPolicy {
|
||||
virtual void addref() = 0;
|
||||
virtual void delref() = 0;
|
||||
|
||||
// set_cert_data should import the provided certificate list and
|
||||
// associate it with this policy. cert_data will point to a PEM
|
||||
// encoded certificate list, ordered such that each certificate
|
||||
// certifies the one before it.
|
||||
//
|
||||
// cert_data may additionally contain key information, which must
|
||||
// be ignored.
|
||||
//
|
||||
// set_cert_data should return true if the operation succeeded,
|
||||
// and false otherwise. After the first call to create_session for
|
||||
// a given policy, set_cert_data should immediately return false
|
||||
// if called.
|
||||
virtual bool set_cert_data(const uint8_t* cert_data, int cert_len) = 0;
|
||||
|
||||
// set_key_data should import the provided private key and
|
||||
// associate it with this policy. key_data will point to a PEM
|
||||
// encoded key.
|
||||
//
|
||||
// key_data may additionally contain certificate information,
|
||||
// which must be ignored.
|
||||
//
|
||||
// set_key_data should return true if the operation succeeded, and
|
||||
// false otherwise. After the first call to create_session for a
|
||||
// given policy, set_key_data should immediately return false if
|
||||
// called.
|
||||
virtual bool set_key_data(const uint8_t* key_data, int key_len) = 0;
|
||||
|
||||
// set_verify_peers should modify the validation rules for
|
||||
// verifying a peer during connection handshake. The format of
|
||||
// verify_peers is implementation specific.
|
||||
//
|
||||
// set_verify_peers should return true if the operation succeed,
|
||||
// and false otherwise. After the first call to create_session for
|
||||
// a given policy, set_verify_peers should immediately return
|
||||
// false if called.
|
||||
virtual bool set_verify_peers(const uint8_t* verify_peers, int verify_peers_len) = 0;
|
||||
|
||||
// create_session should return a new object that implements
|
||||
// ITLSSession, associated with this policy. After the first call
|
||||
// to create_session for a given policy, further calls to
|
||||
// ITLSPolicy::set_* will fail and return false.
|
||||
//
|
||||
// The newly created session should use send_func and recv_func to
|
||||
// send and receive data on the underlying transport, and must
|
||||
// provide send_ctx/recv_ctx to the callbacks.
|
||||
//
|
||||
// uid should only be provided when invoking an ITLSLogFunc, which
|
||||
// will use it to identify this session.
|
||||
virtual ITLSSession* create_session(bool is_client, TLSSendCallbackFunc send_func, void* send_ctx, TLSRecvCallbackFunc recv_func, void* recv_ctx, void* uid ) = 0;
|
||||
};
|
||||
|
||||
// Logs a message/error to the appropriate trace log.
|
||||
//
|
||||
// event must be a valid XML attribute value. uid may be NULL or the
|
||||
// uid provided to ITLSPolicy::create_session by the caller. is_error
|
||||
// should be true for errors and false for informational messages. The
|
||||
// remaining arguments must be pairs of (const char*); the first of
|
||||
// each pair must be a valid XML attribute name, and the second a
|
||||
// valid XML attribute value. The final parameter must be NULL.
|
||||
typedef void (*ITLSLogFunc)(const char* event, void* uid, bool is_error, ...);
|
||||
|
||||
struct ITLSPlugin {
|
||||
virtual void addref() = 0;
|
||||
virtual void delref() = 0;
|
||||
|
||||
// create_policy should return a new object that implements
|
||||
// ITLSPolicy.
|
||||
//
|
||||
// The newly created policy, and any session further created from
|
||||
// the policy, should use logf to log any messages or errors that
|
||||
// occur.
|
||||
virtual ITLSPolicy* create_policy( ITLSLogFunc logf ) = 0;
|
||||
|
||||
static inline const char* get_plugin_type_name_and_version() { return "ITLSPlugin"; }
|
||||
};
|
||||
|
||||
#endif /* FDB_ITLSPLUGIN_H */
|
|
@ -0,0 +1,109 @@
|
|||
PROJECTPATH = $(dir $(realpath $(firstword $(MAKEFILE_LIST))))
|
||||
PLUGINPATH = $(PROJECTPATH)/$(PLUGIN)
|
||||
|
||||
CFLAGS ?= -O2 -g
|
||||
|
||||
CXXFLAGS ?= -std=c++0x
|
||||
|
||||
CFLAGS += -I/usr/local/include
|
||||
LDFLAGS += -L/usr/local/lib
|
||||
|
||||
LIBS += -ltls -lssl -lcrypto
|
||||
|
||||
PLATFORM := $(shell uname)
|
||||
ifneq ($(PLATFORM),Darwin)
|
||||
PLATFORM := $(shell uname -o)
|
||||
endif
|
||||
|
||||
ifeq ($(PLATFORM),Cygwin)
|
||||
HOST := x86_64-w64-mingw32
|
||||
CC := $(HOST)-gcc
|
||||
CXX := $(HOST)-g++
|
||||
STRIP := $(HOST)-strip --strip-all
|
||||
|
||||
DYEXT = dll
|
||||
PLUGINPATH = $(PLUGIN)
|
||||
|
||||
LIBS += -static-libstdc++ -static-libgcc
|
||||
LIBS += -lws2_32
|
||||
|
||||
LINK_LDFLAGS = -shared
|
||||
LINK_LDFLAGS += -Wl,-soname,$(PLUGIN)
|
||||
LINK_LDFLAGS += -Wl,--version-script=FDBLibTLS.map
|
||||
LINK_LDFLAGS += -Wl,-Bstatic $(LIBS) -Wl,-Bdynamic
|
||||
|
||||
else ifeq ($(PLATFORM),Darwin)
|
||||
CC := clang
|
||||
CXX := clang++
|
||||
STRIP := strip -S -x
|
||||
|
||||
CFLAGS += -fPIC
|
||||
|
||||
DYEXT = dylib
|
||||
|
||||
vpath %.a /usr/local/lib
|
||||
.LIBPATTERNS = lib%.a lib%.dylib lib%.so
|
||||
|
||||
LINK_LDFLAGS = -shared
|
||||
LINK_LDFLAGS += -Wl,-exported_symbols_list,FDBLibTLS.symbols
|
||||
LINK_LDFLAGS += -Wl,-dylib_install_name,$(PLUGIN)
|
||||
LINK_LDFLAGS += $(LIBS)
|
||||
|
||||
else ifeq ($(PLATFORM),GNU/Linux)
|
||||
CC := clang
|
||||
CXX := clang++
|
||||
STRIP := strip --strip-all
|
||||
|
||||
CFLAGS += -fPIC
|
||||
DYEXT = so
|
||||
|
||||
LIBS += -static-libstdc++ -static-libgcc -lrt
|
||||
|
||||
LINK_LDFLAGS = -shared
|
||||
LINK_LDFLAGS += -Wl,-soname,$(PLUGIN)
|
||||
LINK_LDFLAGS += -Wl,--version-script=FDBLibTLS.map
|
||||
LINK_LDFLAGS += -Wl,-Bstatic $(LIBS) -Wl,-Bdynamic
|
||||
|
||||
else
|
||||
$(error Unknown platform $(PLATFORM))
|
||||
endif
|
||||
|
||||
PLUGIN := FDBLibTLS.$(DYEXT)
|
||||
OBJECTS := FDBLibTLSPlugin.o FDBLibTLSPolicy.o FDBLibTLSSession.o
|
||||
LINKLINE := $(CXXFLAGS) $(CFLAGS) $(LDFLAGS) $(OBJECTS) $(LINK_LDFLAGS) -o $(PLUGIN)
|
||||
|
||||
all: $(PLUGIN)
|
||||
|
||||
build-depends-linux:
|
||||
apt install clang make libboost-dev
|
||||
|
||||
clean:
|
||||
@rm -f *.o *.d $(PLUGIN) plugin-test verify-test
|
||||
@rm -rf *.dSYM
|
||||
|
||||
DEPS := $(patsubst %.o,%.d,$(OBJECTS))
|
||||
-include $(DEPS)
|
||||
|
||||
$(OBJECTS): %.o: %.cpp Makefile
|
||||
@echo "Compiling $<"
|
||||
@$(CXX) $(CXXFLAGS) $(CFLAGS) $(INCLUDES) -c $< -o $@ -MD -MP
|
||||
|
||||
$(PLUGIN): $(OBJECTS) Makefile
|
||||
@echo "Linking $@"
|
||||
@$(CXX) $(LINKLINE)
|
||||
@echo "Stripping $@"
|
||||
@$(STRIP) $@
|
||||
|
||||
test: test-plugin test-verify
|
||||
|
||||
test-plugin: plugin-test.cpp $(PLUGIN) Makefile
|
||||
@echo "Compiling plugin-test"
|
||||
@$(CXX) $(CXXFLAGS) $(CFLAGS) plugin-test.cpp -ldl -o plugin-test
|
||||
@echo "Running plugin-test..."
|
||||
@$(PROJECTPATH)/plugin-test $(PLUGINPATH)
|
||||
|
||||
test-verify: verify-test.cpp $(OBJECTS) Makefile
|
||||
@echo "Compiling verify-test"
|
||||
@$(CXX) $(CXXFLAGS) $(CFLAGS) $(LDFLAGS) $(OBJECTS) verify-test.cpp $(LIBS) -o verify-test
|
||||
@echo "Running verify-test..."
|
||||
@$(PROJECTPATH)/verify-test
|
|
@ -0,0 +1,108 @@
|
|||
/*
|
||||
* ReferenceCounted.h
|
||||
*
|
||||
* This source file is part of the FoundationDB open source project
|
||||
*
|
||||
* Copyright 2013-2018 Apple Inc. and the FoundationDB project authors
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef FDB_REFERENCE_COUNTED_H
|
||||
#define FDB_REFERENCE_COUNTED_H
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
template <class T>
|
||||
struct ReferenceCounted {
|
||||
void addref() { ++referenceCount; }
|
||||
void delref() { if (--referenceCount == 0) { delete (T*)this; } }
|
||||
|
||||
ReferenceCounted() : referenceCount(1) {}
|
||||
|
||||
private:
|
||||
ReferenceCounted(const ReferenceCounted&) = delete;
|
||||
void operator=(const ReferenceCounted&) = delete;
|
||||
int32_t referenceCount;
|
||||
};
|
||||
|
||||
template <class P>
|
||||
void addref(P* ptr) { ptr->addref(); }
|
||||
template <class P>
|
||||
void delref(P* ptr) { ptr->delref(); }
|
||||
|
||||
template <class P>
|
||||
struct Reference {
|
||||
Reference() : ptr(NULL) {}
|
||||
explicit Reference( P* ptr ) : ptr(ptr) {}
|
||||
static Reference<P> addRef( P* ptr ) { ptr->addref(); return Reference(ptr); }
|
||||
|
||||
Reference(const Reference& r) : ptr(r.getPtr()) { if (ptr) addref(ptr); }
|
||||
Reference(Reference && r) : ptr(r.getPtr()) { r.ptr = NULL; }
|
||||
|
||||
template <class Q>
|
||||
Reference(const Reference<Q>& r) : ptr(r.getPtr()) { if (ptr) addref(ptr); }
|
||||
template <class Q>
|
||||
Reference(Reference<Q> && r) : ptr(r.getPtr()) { r.setPtrUnsafe(NULL); }
|
||||
|
||||
~Reference() { if (ptr) delref(ptr); }
|
||||
Reference& operator=(const Reference& r) {
|
||||
P* oldPtr = ptr;
|
||||
P* newPtr = r.ptr;
|
||||
if (oldPtr != newPtr) {
|
||||
if (newPtr) addref(newPtr);
|
||||
ptr = newPtr;
|
||||
if (oldPtr) delref(oldPtr);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
Reference& operator=(Reference&& r) {
|
||||
P* oldPtr = ptr;
|
||||
P* newPtr = r.ptr;
|
||||
if (oldPtr != newPtr) {
|
||||
r.ptr = NULL;
|
||||
ptr = newPtr;
|
||||
if (oldPtr) delref(oldPtr);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
void clear() {
|
||||
P* oldPtr = ptr;
|
||||
if (oldPtr) {
|
||||
ptr = NULL;
|
||||
delref(oldPtr);
|
||||
}
|
||||
}
|
||||
|
||||
P* operator->() const { return ptr; }
|
||||
P& operator*() const { return *ptr; }
|
||||
P* getPtr() const { return ptr; }
|
||||
|
||||
void setPtrUnsafe( P* p ) { ptr = p; }
|
||||
|
||||
P* extractPtr() { auto *p = ptr; ptr = NULL; return p; }
|
||||
|
||||
bool boolean_test() const { return ptr != 0; }
|
||||
private:
|
||||
P *ptr;
|
||||
};
|
||||
|
||||
template <class P>
|
||||
bool operator==( const Reference<P>& lhs, const Reference<P>& rhs ) {
|
||||
return lhs.getPtr() == rhs.getPtr();
|
||||
}
|
||||
|
||||
#endif /* FDB_REFERENCE_COUNTED_H */
|
|
@ -0,0 +1,11 @@
|
|||
FDBLibTLS_CFLAGS := -fPIC -I/usr/local/include -I$(BOOSTDIR)
|
||||
FDBLibTLS_STATIC_LIBS := -ltls -lssl -lcrypto
|
||||
FDBLibTLS_LDFLAGS := -L/usr/local/lib -static-libstdc++ -static-libgcc -lrt
|
||||
FDBLibTLS_LDFLAGS += -Wl,-soname,FDBLibTLS.so -Wl,--version-script=FDBLibTLS/FDBLibTLS.map
|
||||
|
||||
# The plugin isn't a typical library, so it feels more sensible to have a copy
|
||||
# of it in bin/.
|
||||
bin/FDBLibTLS.$(DLEXT): lib/libFDBLibTLS.$(DLEXT)
|
||||
@cp $< $@
|
||||
|
||||
TARGETS += bin/FDBLibTLS.$(DLEXT)
|
|
@ -0,0 +1,585 @@
|
|||
/*
|
||||
* plugin-test.cpp
|
||||
*
|
||||
* This source file is part of the FoundationDB open source project
|
||||
*
|
||||
* Copyright 2013-2018 Apple Inc. and the FoundationDB project authors
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <exception>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <dlfcn.h>
|
||||
|
||||
#include <boost/circular_buffer.hpp>
|
||||
|
||||
#include "ITLSPlugin.h"
|
||||
#include "ReferenceCounted.h"
|
||||
|
||||
#include "FDBLibTLSPlugin.h"
|
||||
|
||||
#define TESTDATA "./testdata/"
|
||||
|
||||
static std::string load_file(std::string path)
|
||||
{
|
||||
std::ifstream fs(path);
|
||||
std::stringstream ss;
|
||||
|
||||
ss << fs.rdbuf();
|
||||
fs.close();
|
||||
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
struct FDBLibTLSClientServerTest {
|
||||
FDBLibTLSClientServerTest(bool client_success, bool server_success, std::string client_path, std::string server_path, std::string client_verify, std::string server_verify):
|
||||
client_success(client_success), server_success(server_success), client_verify(client_verify), server_verify(server_verify) {
|
||||
client_data = load_file(TESTDATA + client_path);
|
||||
server_data = load_file(TESTDATA + server_path);
|
||||
}
|
||||
~FDBLibTLSClientServerTest() {}
|
||||
|
||||
bool client_success;
|
||||
bool server_success;
|
||||
|
||||
std::string client_data;
|
||||
std::string client_verify;
|
||||
std::string server_data;
|
||||
std::string server_verify;
|
||||
};
|
||||
|
||||
struct FDBLibTLSPluginTest {
|
||||
FDBLibTLSPluginTest(Reference<ITLSPlugin> plugin, ITLSLogFunc logf);
|
||||
~FDBLibTLSPluginTest();
|
||||
|
||||
Reference<ITLSPlugin> plugin;
|
||||
ITLSLogFunc logf;
|
||||
|
||||
boost::circular_buffer<uint8_t> client_buffer;
|
||||
boost::circular_buffer<uint8_t> server_buffer;
|
||||
|
||||
int circular_read(boost::circular_buffer<uint8_t> *cb, uint8_t* buf, int len);
|
||||
int circular_write(boost::circular_buffer<uint8_t> *cb, const uint8_t* buf, int len);
|
||||
int client_read(uint8_t* buf, int len);
|
||||
int client_write(const uint8_t* buf, int len);
|
||||
int server_read(uint8_t* buf, int len);
|
||||
int server_write(const uint8_t* buf, int len);
|
||||
|
||||
Reference<ITLSPolicy> create_policy(void);
|
||||
Reference<ITLSSession> create_client_session(Reference<ITLSPolicy> policy);
|
||||
Reference<ITLSSession> create_server_session(Reference<ITLSPolicy> policy);
|
||||
|
||||
void circular_reset(void);
|
||||
void circular_self_test(void);
|
||||
|
||||
int client_server_test(FDBLibTLSClientServerTest const& cst);
|
||||
int set_cert_data_test(void);
|
||||
};
|
||||
|
||||
FDBLibTLSPluginTest::FDBLibTLSPluginTest(Reference<ITLSPlugin> plugin, ITLSLogFunc logf) :
|
||||
plugin(plugin), logf(logf)
|
||||
{
|
||||
circular_reset();
|
||||
circular_self_test();
|
||||
}
|
||||
|
||||
FDBLibTLSPluginTest::~FDBLibTLSPluginTest()
|
||||
{
|
||||
}
|
||||
|
||||
int FDBLibTLSPluginTest::circular_read(boost::circular_buffer<uint8_t> *cb, uint8_t* buf, int len)
|
||||
{
|
||||
int n = 0;
|
||||
|
||||
for (n = 0; n < len; n++) {
|
||||
if (cb->empty())
|
||||
break;
|
||||
buf[n] = (*cb)[0];
|
||||
cb->pop_front();
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
int FDBLibTLSPluginTest::circular_write(boost::circular_buffer<uint8_t> *cb, const uint8_t* buf, int len)
|
||||
{
|
||||
int n = 0;
|
||||
|
||||
for (n = 0; n < len; n++) {
|
||||
if (cb->full())
|
||||
break;
|
||||
cb->push_back(buf[n]);
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
int FDBLibTLSPluginTest::client_read(uint8_t* buf, int len)
|
||||
{
|
||||
// Read bytes from the server from the client's buffer.
|
||||
return circular_read(&client_buffer, buf, len);
|
||||
}
|
||||
|
||||
int FDBLibTLSPluginTest::client_write(const uint8_t* buf, int len)
|
||||
{
|
||||
// Write bytes from the client into the server's buffer.
|
||||
return circular_write(&server_buffer, buf, len);
|
||||
}
|
||||
|
||||
int FDBLibTLSPluginTest::server_read(uint8_t* buf, int len)
|
||||
{
|
||||
// Read bytes from the client from the server's buffer.
|
||||
return circular_read(&server_buffer, buf, len);
|
||||
}
|
||||
|
||||
int FDBLibTLSPluginTest::server_write(const uint8_t* buf, int len)
|
||||
{
|
||||
// Write bytes from the server into the client's buffer.
|
||||
return circular_write(&client_buffer, buf, len);
|
||||
}
|
||||
|
||||
void FDBLibTLSPluginTest::circular_reset()
|
||||
{
|
||||
client_buffer = boost::circular_buffer<uint8_t>(1024);
|
||||
server_buffer = boost::circular_buffer<uint8_t>(1024);
|
||||
}
|
||||
|
||||
void FDBLibTLSPluginTest::circular_self_test()
|
||||
{
|
||||
uint8_t buf[1024] = {1, 2, 3};
|
||||
|
||||
std::cerr << "INFO: running circular buffer self tests...\n";
|
||||
|
||||
assert(server_read(buf, 3) == 0);
|
||||
|
||||
buf[0] = 1, buf[1] = 2, buf[2] = 3;
|
||||
assert(client_write(buf, 2) == 2);
|
||||
|
||||
buf[0] = buf[1] = buf[2] = 255;
|
||||
assert(server_read(buf, 3) == 2);
|
||||
assert(buf[0] == 1 && buf[1] == 2 && buf[2] == 255);
|
||||
|
||||
assert(client_write(buf, 1024) == 1024);
|
||||
assert(client_write(buf, 1) == 0);
|
||||
assert(server_read(buf, 1) == 1);
|
||||
assert(client_write(buf, 1) == 1);
|
||||
assert(client_write(buf, 1) == 0);
|
||||
assert(server_read(buf, 1024) == 1024);
|
||||
assert(server_read(buf, 1024) == 0);
|
||||
|
||||
assert(client_read(buf, 3) == 0);
|
||||
|
||||
buf[0] = 1, buf[1] = 2, buf[2] = 3;
|
||||
assert(server_write(buf, 2) == 2);
|
||||
|
||||
buf[0] = buf[1] = buf[2] = 255;
|
||||
assert(client_read(buf, 3) == 2);
|
||||
assert(buf[0] == 1 && buf[1] == 2 && buf[2] == 255);
|
||||
|
||||
assert(server_write(buf, 1024) == 1024);
|
||||
assert(server_write(buf, 1) == 0);
|
||||
assert(client_read(buf, 1) == 1);
|
||||
assert(server_write(buf, 1) == 1);
|
||||
assert(server_write(buf, 1) == 0);
|
||||
assert(client_read(buf, 1024) == 1024);
|
||||
assert(client_read(buf, 1024) == 0);
|
||||
}
|
||||
|
||||
Reference<ITLSPolicy> FDBLibTLSPluginTest::create_policy(void)
|
||||
{
|
||||
return Reference<ITLSPolicy>(plugin->create_policy((ITLSLogFunc)logf));
|
||||
}
|
||||
|
||||
static int client_send_func(void* ctx, const uint8_t* buf, int len) {
|
||||
FDBLibTLSPluginTest *pt = (FDBLibTLSPluginTest *)ctx;
|
||||
try {
|
||||
return pt->client_write(buf, len);
|
||||
} catch ( const std::runtime_error& e ) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
static int client_recv_func(void* ctx, uint8_t* buf, int len) {
|
||||
FDBLibTLSPluginTest *pt = (FDBLibTLSPluginTest *)ctx;
|
||||
try {
|
||||
return pt->client_read(buf, len);
|
||||
} catch ( const std::runtime_error& e ) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
Reference<ITLSSession> FDBLibTLSPluginTest::create_client_session(Reference<ITLSPolicy> policy)
|
||||
{
|
||||
return Reference<ITLSSession>(policy->create_session(true, client_send_func, this, client_recv_func, this, NULL));
|
||||
}
|
||||
|
||||
static int server_send_func(void* ctx, const uint8_t* buf, int len) {
|
||||
FDBLibTLSPluginTest *pt = (FDBLibTLSPluginTest *)ctx;
|
||||
try {
|
||||
return pt->server_write(buf, len);
|
||||
} catch ( const std::runtime_error& e ) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
static int server_recv_func(void* ctx, uint8_t* buf, int len) {
|
||||
FDBLibTLSPluginTest *pt = (FDBLibTLSPluginTest *)ctx;
|
||||
try {
|
||||
return pt->server_read(buf, len);
|
||||
} catch ( const std::runtime_error& e ) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
Reference<ITLSSession> FDBLibTLSPluginTest::create_server_session(Reference<ITLSPolicy> policy)
|
||||
{
|
||||
return Reference<ITLSSession>(policy->create_session(false, server_send_func, this, server_recv_func, this, NULL));
|
||||
}
|
||||
|
||||
int FDBLibTLSPluginTest::client_server_test(FDBLibTLSClientServerTest const& cst)
|
||||
{
|
||||
circular_reset();
|
||||
|
||||
Reference<ITLSPolicy> client_policy = create_policy();
|
||||
if (!client_policy->set_cert_data((const uint8_t*)&cst.client_data[0], cst.client_data.size())) {
|
||||
std::cerr << "FAIL: failed to set client cert data\n";
|
||||
return 1;
|
||||
}
|
||||
if (!client_policy->set_key_data((const uint8_t*)&cst.client_data[0], cst.client_data.size())) {
|
||||
std::cerr << "FAIL: failed to set client key data\n";
|
||||
return 1;
|
||||
}
|
||||
if (!client_policy->set_verify_peers((const uint8_t*)&cst.client_verify[0], cst.client_verify.size())) {
|
||||
std::cerr << "FAIL: failed to set client key data\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
Reference<ITLSPolicy> server_policy = create_policy();
|
||||
if (!server_policy->set_cert_data((const uint8_t*)&cst.server_data[0], cst.server_data.size())) {
|
||||
std::cerr << "FAIL: failed to set server cert data\n";
|
||||
return 1;
|
||||
}
|
||||
if (!server_policy->set_key_data((const uint8_t*)&cst.server_data[0], cst.server_data.size())) {
|
||||
std::cerr << "FAIL: failed to set server key data\n";
|
||||
return 1;
|
||||
}
|
||||
if (!server_policy->set_verify_peers((const uint8_t*)&cst.server_verify[0], cst.server_verify.size())) {
|
||||
std::cerr << "FAIL: failed to set client key data\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
Reference<ITLSSession> client_session = create_client_session(client_policy);
|
||||
Reference<ITLSSession> server_session = create_server_session(server_policy);
|
||||
|
||||
if (client_session.getPtr() == NULL || server_session.getPtr() == NULL)
|
||||
return 1;
|
||||
|
||||
std::cerr << "INFO: starting TLS handshake...\n";
|
||||
|
||||
bool client_done = false, server_done = false;
|
||||
bool client_failed = false, server_failed = false;
|
||||
int rc, i = 0;
|
||||
do {
|
||||
if (!client_done) {
|
||||
rc = client_session->handshake();
|
||||
if (rc == ITLSSession::SUCCESS) {
|
||||
client_done = true;
|
||||
} else if (rc == ITLSSession::FAILED) {
|
||||
if (cst.client_success) {
|
||||
std::cerr << "FAIL: failed to complete client handshake\n";
|
||||
return 1;
|
||||
} else {
|
||||
std::cerr << "INFO: failed to complete client handshake (as expected)\n";
|
||||
client_failed = true;
|
||||
client_done = true;
|
||||
}
|
||||
} else if (rc != ITLSSession::WANT_READ && rc != ITLSSession::WANT_WRITE) {
|
||||
std::cerr << "FAIL: client handshake returned unknown value: " << rc << "\n";
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
if (!server_done) {
|
||||
rc = server_session->handshake();
|
||||
if (rc == ITLSSession::SUCCESS) {
|
||||
server_done = true;
|
||||
} else if (rc == ITLSSession::FAILED) {
|
||||
if (cst.server_success) {
|
||||
std::cerr << "FAIL: failed to complete server handshake\n";
|
||||
return 1;
|
||||
} else {
|
||||
std::cerr << "INFO: failed to complete server handshake (as expected)\n";
|
||||
server_failed = true;
|
||||
server_done = true;
|
||||
}
|
||||
} else if (rc != ITLSSession::WANT_READ && rc != ITLSSession::WANT_WRITE) {
|
||||
std::cerr << "FAIL: server handshake returned unknown value: " << rc << "\n";
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
} while (i++ < 100 && (!client_done || !server_done));
|
||||
|
||||
if (!client_done || !server_done) {
|
||||
std::cerr << "FAIL: failed to complete handshake\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!cst.client_success && !client_failed)
|
||||
std::cerr << "FAIL: client handshake succeeded when it should have failed\n";
|
||||
if (!cst.server_success && !server_failed)
|
||||
std::cerr << "FAIL: server handshake succeeded when it should have failed\n";
|
||||
if (!cst.client_success || !cst.server_success)
|
||||
return 0;
|
||||
|
||||
std::cerr << "INFO: handshake completed successfully\n";
|
||||
|
||||
//
|
||||
// Write on client and read on server.
|
||||
//
|
||||
std::cerr << "INFO: starting client write test...\n";
|
||||
|
||||
std::string client_msg("FDBLibTLSPlugin Client Write Test");
|
||||
std::string server_msg;
|
||||
size_t cn = 0, sn = 0;
|
||||
uint8_t buf[16];
|
||||
|
||||
client_done = false, server_done = false;
|
||||
i = 0;
|
||||
do {
|
||||
if (!client_done) {
|
||||
rc = client_session->write((const uint8_t*)&client_msg[cn], client_msg.size()-cn);
|
||||
if (rc > 0) {
|
||||
cn += rc;
|
||||
if (cn >= client_msg.size())
|
||||
client_done = true;
|
||||
} else if (rc == ITLSSession::FAILED) {
|
||||
std::cerr << "FAIL: failed to complete client write\n";
|
||||
return 1;
|
||||
} else if (rc != ITLSSession::WANT_READ && rc != ITLSSession::WANT_WRITE) {
|
||||
std::cerr << "FAIL: client write returned unknown value: " << rc << "\n";
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
if (!server_done) {
|
||||
rc = server_session->read(buf, sizeof(buf));
|
||||
if (rc > 0) {
|
||||
sn += rc;
|
||||
for (int j = 0; j < rc; j++)
|
||||
server_msg += buf[j];
|
||||
if (sn >= client_msg.size())
|
||||
server_done = true;
|
||||
} else if (rc == ITLSSession::FAILED) {
|
||||
std::cerr << "FAIL: failed to complete server read\n";
|
||||
return 1;
|
||||
} else if (rc != ITLSSession::WANT_READ && rc != ITLSSession::WANT_WRITE) {
|
||||
std::cerr << "FAIL: server read returned unknown value: " << rc << "\n";
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
} while (i++ < 100 && (!client_done || !server_done));
|
||||
|
||||
if (client_msg != server_msg) {
|
||||
std::cerr << "FAIL: got client msg '" << server_msg << "' want '" << client_msg << "'\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
std::cerr << "INFO: client write test completed successfully\n";
|
||||
|
||||
//
|
||||
// Write on server and read on client.
|
||||
//
|
||||
std::cerr << "INFO: starting server write test...\n";
|
||||
|
||||
server_msg = "FDBLibTLSPlugin Server Write Test";
|
||||
client_msg.clear();
|
||||
cn = 0, sn = 0;
|
||||
|
||||
client_done = false, server_done = false;
|
||||
i = 0;
|
||||
do {
|
||||
if (!server_done) {
|
||||
rc = server_session->write((const uint8_t*)&server_msg[cn], server_msg.size()-cn);
|
||||
if (rc > 0) {
|
||||
cn += rc;
|
||||
if (cn >= server_msg.size())
|
||||
server_done = true;
|
||||
} else if (rc == ITLSSession::FAILED) {
|
||||
std::cerr << "FAIL: failed to complete server write\n";
|
||||
return 1;
|
||||
} else if (rc != ITLSSession::WANT_READ && rc != ITLSSession::WANT_WRITE) {
|
||||
std::cerr << "FAIL: server write returned unknown value: " << rc << "\n";
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
if (!client_done) {
|
||||
rc = client_session->read(buf, sizeof(buf));
|
||||
if (rc > 0) {
|
||||
sn += rc;
|
||||
for (int j = 0; j < rc; j++)
|
||||
client_msg += buf[j];
|
||||
if (sn >= server_msg.size())
|
||||
client_done = true;
|
||||
} else if (rc == ITLSSession::FAILED) {
|
||||
std::cerr << "FAIL: failed to complete client read\n";
|
||||
return 1;
|
||||
} else if (rc != ITLSSession::WANT_READ && rc != ITLSSession::WANT_WRITE) {
|
||||
std::cerr << "FAIL: client read returned unknown value: " << rc << "\n";
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
} while (i++ < 100 && (!client_done || !server_done));
|
||||
|
||||
if (server_msg != client_msg) {
|
||||
std::cerr << "FAIL: got server msg '" << client_msg << "' want '" << server_msg << "'\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
std::cerr << "INFO: server write test completed successfully\n";
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void logf(const char* event, void* uid, int is_error, ...) {
|
||||
va_list args;
|
||||
|
||||
std::string log_type ("INFO");
|
||||
if (is_error)
|
||||
log_type = "ERROR";
|
||||
|
||||
std::cerr << log_type << ": " << event;
|
||||
|
||||
va_start(args, is_error);
|
||||
|
||||
const char *s = va_arg(args, const char *);
|
||||
while (s != NULL) {
|
||||
std::cerr << " " << s;
|
||||
s = va_arg(args, const char *);
|
||||
}
|
||||
|
||||
std::cerr << "\n";
|
||||
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
void *pluginSO = NULL;
|
||||
void *(*getPlugin)(const char*);
|
||||
int failed = 0;
|
||||
|
||||
if (argc != 2) {
|
||||
std::cerr << "usage: " << argv[0] << " <plugin_path>\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
pluginSO = dlopen(argv[1], RTLD_LAZY | RTLD_LOCAL);
|
||||
if (pluginSO == NULL) {
|
||||
std::cerr << "failed to load plugin '" << argv[1] << "': " << dlerror() << "\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
getPlugin = (void*(*)(const char*))dlsym( pluginSO, "get_plugin" );
|
||||
if (getPlugin == NULL) {
|
||||
std::cerr << "plugin '" << argv[1] << "' does not provide get_plugin()\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
Reference<ITLSPlugin> plugin = Reference<ITLSPlugin>((ITLSPlugin *)getPlugin(ITLSPlugin::get_plugin_type_name_and_version()));
|
||||
|
||||
std::vector<FDBLibTLSClientServerTest> tests = {
|
||||
// Valid - all use single root CA.
|
||||
FDBLibTLSClientServerTest(true, true, "test-1-client.pem", "test-1-server.pem", "", ""),
|
||||
FDBLibTLSClientServerTest(true, true, "test-1-client.pem", "test-2-server.pem", "", ""),
|
||||
FDBLibTLSClientServerTest(true, true, "test-2-client.pem", "test-2-server.pem", "", ""),
|
||||
FDBLibTLSClientServerTest(true, true, "test-2-client.pem", "test-1-server.pem", "", ""),
|
||||
|
||||
// Certificates terminate at different intermediate CAs.
|
||||
FDBLibTLSClientServerTest(false, false, "test-4-client.pem", "test-5-server.pem", "", ""),
|
||||
FDBLibTLSClientServerTest(false, false, "test-5-client.pem", "test-4-server.pem", "", ""),
|
||||
FDBLibTLSClientServerTest(true, true, "test-4-client.pem", "test-5-server.pem",
|
||||
"Check.Valid=0", "Check.Valid=0"),
|
||||
FDBLibTLSClientServerTest(true, true, "test-5-client.pem", "test-4-server.pem",
|
||||
"Check.Valid=0", "Check.Valid=0"),
|
||||
|
||||
// Expired certificates.
|
||||
FDBLibTLSClientServerTest(false, false, "test-1-client.pem", "test-3-server.pem", "", ""),
|
||||
FDBLibTLSClientServerTest(false, false, "test-3-client.pem", "test-1-server.pem", "", ""),
|
||||
FDBLibTLSClientServerTest(true, true, "test-1-client.pem", "test-3-server.pem", "Check.Unexpired=0", ""),
|
||||
FDBLibTLSClientServerTest(true, true, "test-3-client.pem", "test-1-server.pem", "", "Check.Unexpired=0"),
|
||||
FDBLibTLSClientServerTest(true, true, "test-1-client.pem", "test-3-server.pem", "Check.Valid=0", ""),
|
||||
FDBLibTLSClientServerTest(true, true, "test-3-client.pem", "test-1-server.pem", "", "Check.Valid=0"),
|
||||
|
||||
// Match on specific subject and/or issuer.
|
||||
FDBLibTLSClientServerTest(true, true, "test-1-client.pem", "test-1-server.pem", "C=US", ""),
|
||||
FDBLibTLSClientServerTest(false, true, "test-1-client.pem", "test-2-server.pem", "C=US", ""),
|
||||
FDBLibTLSClientServerTest(true, true, "test-1-client.pem", "test-2-server.pem", "C=AU", ""),
|
||||
FDBLibTLSClientServerTest(true, true, "test-1-client.pem", "test-2-server.pem",
|
||||
"CN=FDB LibTLS Plugin Test Server 2\\, \\80 \\<\\01\\+\\02=\\03\\>", ""),
|
||||
FDBLibTLSClientServerTest(false, true, "test-1-client.pem", "test-2-server.pem",
|
||||
"CN=FDB LibTLS Plugin Test Server 2\\, \\80 \\<\\01\\+\\02=\\04\\>", ""),
|
||||
FDBLibTLSClientServerTest(false, true, "test-1-client.pem", "test-2-server.pem",
|
||||
"CN=FDB LibTLS Plugin Test Server 2\\, \\81 \\<\\01\\+\\02=\\04\\>", ""),
|
||||
FDBLibTLSClientServerTest(false, true, "test-1-client.pem", "test-2-server.pem",
|
||||
"CN=FDB LibTLS Plugin Test Server 2\\, \\80 \\<\\01\\+\\02=\\04", ""),
|
||||
FDBLibTLSClientServerTest(true, true, "test-1-client.pem", "test-2-server.pem",
|
||||
"CN=FDB LibTLS Plugin Test Server 2\\, \\80 \\<\\01\\+\\02=\\03\\>",
|
||||
"CN=FDB LibTLS Plugin Test Client 1"),
|
||||
FDBLibTLSClientServerTest(true, true, "test-1-client.pem", "test-1-server.pem",
|
||||
"", "CN=FDB LibTLS Plugin Test Client 1"),
|
||||
FDBLibTLSClientServerTest(true, false, "test-2-client.pem", "test-1-server.pem",
|
||||
"", "O=Apple Pty Limited,OU=FDC Team"),
|
||||
FDBLibTLSClientServerTest(true, true, "test-2-client.pem", "test-1-server.pem",
|
||||
"O=Apple Inc.,OU=FDB Team", "O=Apple Pty Limited,OU=FDB Team"),
|
||||
FDBLibTLSClientServerTest(false, false, "test-2-client.pem", "test-1-server.pem",
|
||||
"O=Apple Inc.,OU=FDC Team", "O=Apple Pty Limited,OU=FDC Team"),
|
||||
FDBLibTLSClientServerTest(true, true, "test-1-client.pem", "test-1-server.pem",
|
||||
"I.C=US,I.ST=California,I.L=Cupertino,I.O=Apple Inc.,I.OU=FDB Team",
|
||||
"I.C=US,I.ST=California,I.L=Cupertino,I.O=Apple Inc.,I.OU=FDB Team"),
|
||||
FDBLibTLSClientServerTest(false, false, "test-1-client.pem", "test-1-server.pem",
|
||||
"I.C=US,I.ST=California,I.L=Cupertino,I.O=Apple Inc.,I.OU=FDC Team",
|
||||
"I.C=US,I.ST=California,I.L=Cupertino,I.O=Apple Inc.,I.OU=FDC Team"),
|
||||
FDBLibTLSClientServerTest(true, true, "test-1-client.pem", "test-1-server.pem",
|
||||
"I.CN=FDB LibTLS Plugin Test Intermediate CA 1",
|
||||
"I.CN=FDB LibTLS Plugin Test Intermediate CA 1"),
|
||||
FDBLibTLSClientServerTest(false, true, "test-1-client.pem", "test-1-server.pem",
|
||||
"I.CN=FDB LibTLS Plugin Test Intermediate CA 2",
|
||||
"I.CN=FDB LibTLS Plugin Test Intermediate CA 1"),
|
||||
FDBLibTLSClientServerTest(true, true, "test-1-client.pem", "test-2-server.pem",
|
||||
"I.CN=FDB LibTLS Plugin Test Intermediate CA 2",
|
||||
"I.CN=FDB LibTLS Plugin Test Intermediate CA 1"),
|
||||
FDBLibTLSClientServerTest(true, true, "test-1-client.pem", "test-2-server.pem",
|
||||
"CN=FDB LibTLS Plugin Test Server 2\\, \\80 \\<\\01\\+\\02=\\03\\>,I.CN=FDB LibTLS Plugin Test Intermediate CA 2",
|
||||
"I.CN=FDB LibTLS Plugin Test Intermediate CA 1,O=Apple Inc.,I.C=US,S.C=US"),
|
||||
FDBLibTLSClientServerTest(false, true, "test-1-client.pem", "test-2-server.pem",
|
||||
"CN=FDB LibTLS Plugin Test Server 2\\, \\80 \\<\\01\\+\\02=\\03\\>,I.CN=FDB LibTLS Plugin Test Intermediate CA 1",
|
||||
"I.CN=FDB LibTLS Plugin Test Intermediate CA 1,O=Apple Inc.,I.C=US,S.C=US"),
|
||||
};
|
||||
|
||||
FDBLibTLSPluginTest *pt = new FDBLibTLSPluginTest(plugin, (ITLSLogFunc)logf);
|
||||
|
||||
int test_num = 1;
|
||||
for (auto &test: tests) {
|
||||
std::cerr << "== Test " << test_num++ << " ==\n";
|
||||
failed |= pt->client_server_test(test);
|
||||
}
|
||||
|
||||
delete pt;
|
||||
|
||||
return (failed);
|
||||
}
|
|
@ -0,0 +1,178 @@
|
|||
#!/bin/sh
|
||||
#
|
||||
# make-tests-certs.sh
|
||||
#
|
||||
# This source file is part of the FoundationDB open source project
|
||||
#
|
||||
# Copyright 2013-2018 Apple Inc. and the FoundationDB project authors
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
set -e
|
||||
set -u
|
||||
|
||||
readonly SUBJECT="/C=US/ST=California/L=Cupertino/O=Apple Inc./OU=FDB Team/CN=FDB LibTLS Plugin Test"
|
||||
readonly SUBJECT_ALT="/C=AU/ST=New South Wales/L=Sydney/O=Apple Pty Limited/OU=FDB Team/CN=FDB LibTLS Plugin Test"
|
||||
|
||||
readonly TMPDIR=$(mktemp -d)
|
||||
|
||||
cleanup() {
|
||||
rm -rf "${TMPDIR}"
|
||||
}
|
||||
|
||||
trap cleanup EXIT INT
|
||||
|
||||
make_bundle() {
|
||||
local bundle_file=$1;
|
||||
local key_file=$2;
|
||||
shift 2;
|
||||
|
||||
printf '' > "${bundle_file}"
|
||||
for f in $@; do
|
||||
openssl x509 -nameopt oneline -subject -issuer -noout -in "${TMPDIR}/${f}" >> "${bundle_file}"
|
||||
done
|
||||
for f in $@; do
|
||||
cat "${TMPDIR}/${f}" >> "${bundle_file}"
|
||||
done
|
||||
cat "${TMPDIR}/${key_file}" >> "${bundle_file}"
|
||||
}
|
||||
|
||||
echo '100001' > "${TMPDIR}/certserial"
|
||||
|
||||
cat > "${TMPDIR}/openssl.cnf" <<EOF
|
||||
[ca]
|
||||
default_ca = fdb_test_ca
|
||||
|
||||
[req]
|
||||
distinguished_name = req_distinguished_name
|
||||
|
||||
[req_distinguished_name]
|
||||
|
||||
[fdb_test_ca]
|
||||
unique_subject = no
|
||||
database = ${TMPDIR}/certindex
|
||||
default_md = sha256
|
||||
new_certs_dir = ${TMPDIR}/
|
||||
policy = fdb_test_ca_policy
|
||||
serial = ${TMPDIR}/certserial
|
||||
|
||||
[fdb_test_ca_policy]
|
||||
|
||||
[fdb_v3_ca]
|
||||
subjectKeyIdentifier = hash
|
||||
authorityKeyIdentifier = keyid:always,issuer
|
||||
basicConstraints = critical, CA:true
|
||||
keyUsage = critical, cRLSign, keyCertSign
|
||||
|
||||
[fdb_v3_other]
|
||||
subjectKeyIdentifier = hash
|
||||
authorityKeyIdentifier = keyid:always,issuer
|
||||
basicConstraints = critical, CA:false
|
||||
keyUsage = critical, digitalSignature
|
||||
EOF
|
||||
|
||||
# Root CA.
|
||||
openssl req -new -days 3650 -nodes -newkey rsa:2048 -sha256 -x509 \
|
||||
-subj "${SUBJECT} Root CA" -keyout "${TMPDIR}/ca-root.key" \
|
||||
-config "${TMPDIR}/openssl.cnf" -extensions fdb_v3_ca \
|
||||
-out "${TMPDIR}/ca-root.crt"
|
||||
|
||||
# Intermediate CA 1.
|
||||
openssl req -new -days 3650 -nodes -newkey rsa:2048 -sha256 \
|
||||
-subj "${SUBJECT} Intermediate CA 1" -keyout "${TMPDIR}/ca-int-1.key" \
|
||||
-out "${TMPDIR}/ca-int-1.csr"
|
||||
openssl x509 -req -days 3650 -CA "${TMPDIR}/ca-root.crt" -CAkey "${TMPDIR}/ca-root.key" \
|
||||
-extfile "${TMPDIR}/openssl.cnf" -extensions fdb_v3_ca -days 3650 \
|
||||
-CAcreateserial -in "${TMPDIR}/ca-int-1.csr" -out "${TMPDIR}/ca-int-1.crt"
|
||||
|
||||
# Intermediate CA 2.
|
||||
openssl req -new -days 3650 -nodes -newkey rsa:2048 -sha256 \
|
||||
-subj "${SUBJECT} Intermediate CA 2" -keyout "${TMPDIR}/ca-int-2.key" \
|
||||
-out "${TMPDIR}/ca-int-2.csr"
|
||||
openssl x509 -req -days 3650 -CA "${TMPDIR}/ca-root.crt" -CAkey "${TMPDIR}/ca-root.key" \
|
||||
-extfile "${TMPDIR}/openssl.cnf" -extensions fdb_v3_ca -days 3650 \
|
||||
-CAcreateserial -in "${TMPDIR}/ca-int-2.csr" -out "${TMPDIR}/ca-int-2.crt"
|
||||
|
||||
# Server 1.
|
||||
openssl req -new -days 3650 -nodes -newkey rsa:2048 -sha256 \
|
||||
-subj "${SUBJECT} Server 1" -keyout "${TMPDIR}/server-1.key" \
|
||||
-out "${TMPDIR}/server-1.csr"
|
||||
openssl x509 -req -days 3650 -CA "${TMPDIR}/ca-int-1.crt" -CAkey "${TMPDIR}/ca-int-1.key" \
|
||||
-extfile "${TMPDIR}/openssl.cnf" -extensions fdb_v3_other -days 3650 \
|
||||
-CAcreateserial -in "${TMPDIR}/server-1.csr" -out "${TMPDIR}/server-1.crt"
|
||||
|
||||
# Server 2.
|
||||
openssl req -new -days 3650 -nodes -newkey rsa:2048 -sha256 \
|
||||
-subj "$(printf "${SUBJECT_ALT} Server 2, \200 <\001+\002=\003>")" -keyout "${TMPDIR}/server-2.key" \
|
||||
-out "${TMPDIR}/server-2.csr"
|
||||
openssl x509 -req -days 3650 -CA "${TMPDIR}/ca-int-2.crt" -CAkey "${TMPDIR}/ca-int-2.key" \
|
||||
-extfile "${TMPDIR}/openssl.cnf" -extensions fdb_v3_other \
|
||||
-CAcreateserial -in "${TMPDIR}/server-2.csr" -out "${TMPDIR}/server-2.crt"
|
||||
|
||||
# Server 3 (expired).
|
||||
openssl req -new -days 1 -nodes -newkey rsa:2048 -sha256 \
|
||||
-subj "${SUBJECT} Server 3" -keyout "${TMPDIR}/server-3.key" \
|
||||
-out "${TMPDIR}/server-3.csr"
|
||||
cp /dev/null "${TMPDIR}/certindex"
|
||||
printf "y\ny\n" | openssl ca -cert "${TMPDIR}/ca-int-1.crt" -keyfile "${TMPDIR}/ca-int-1.key" \
|
||||
-startdate 20170101000000Z -enddate 20171231000000Z \
|
||||
-config "${TMPDIR}/openssl.cnf" -notext \
|
||||
-in "${TMPDIR}/server-3.csr" -out "${TMPDIR}/server-3.crt"
|
||||
|
||||
# Client 1.
|
||||
openssl req -new -days 3650 -nodes -newkey rsa:2048 -sha256 \
|
||||
-subj "${SUBJECT} Client 1" -keyout "${TMPDIR}/client-1.key" \
|
||||
-out "${TMPDIR}/client-1.csr"
|
||||
openssl x509 -req -days 3650 -CA "${TMPDIR}/ca-int-1.crt" -CAkey "${TMPDIR}/ca-int-1.key" \
|
||||
-extfile "${TMPDIR}/openssl.cnf" -extensions fdb_v3_other \
|
||||
-CAcreateserial -in "${TMPDIR}/client-1.csr" -out "${TMPDIR}/client-1.crt"
|
||||
|
||||
# Client 2.
|
||||
openssl req -new -days 3650 -nodes -newkey rsa:2048 -sha256 \
|
||||
-subj "$(printf "${SUBJECT_ALT} Client 2, \200 <\001+\002=\003>")" -keyout "${TMPDIR}/client-2.key" \
|
||||
-out "${TMPDIR}/client-2.csr"
|
||||
openssl x509 -req -days 3650 -CA "${TMPDIR}/ca-int-2.crt" -CAkey "${TMPDIR}/ca-int-2.key" \
|
||||
-extfile "${TMPDIR}/openssl.cnf" -extensions fdb_v3_other \
|
||||
-CAcreateserial -in "${TMPDIR}/client-2.csr" -out "${TMPDIR}/client-2.crt"
|
||||
|
||||
# Client 3 (expired).
|
||||
openssl req -new -days 1 -nodes -newkey rsa:2048 -sha256 \
|
||||
-subj "${SUBJECT} Client 3" -keyout "${TMPDIR}/client-3.key" \
|
||||
-out "${TMPDIR}/client-3.csr"
|
||||
cp /dev/null "${TMPDIR}/certindex"
|
||||
printf "y\ny\n" | openssl ca -cert "${TMPDIR}/ca-int-1.crt" -keyfile "${TMPDIR}/ca-int-1.key" \
|
||||
-startdate 20170101000000Z -enddate 20171231000000Z \
|
||||
-config "${TMPDIR}/openssl.cnf" \
|
||||
-in "${TMPDIR}/client-3.csr" -out "${TMPDIR}/client-3.crt"
|
||||
|
||||
#
|
||||
# Test Bundles
|
||||
#
|
||||
|
||||
make_bundle 'test-1-server.pem' 'server-1.key' 'server-1.crt' 'ca-int-1.crt' 'ca-root.crt'
|
||||
make_bundle 'test-1-client.pem' 'client-1.key' 'client-1.crt' 'ca-int-1.crt' 'ca-root.crt'
|
||||
make_bundle 'test-2-server.pem' 'server-2.key' 'server-2.crt' 'ca-int-2.crt' 'ca-root.crt'
|
||||
make_bundle 'test-2-client.pem' 'client-2.key' 'client-2.crt' 'ca-int-2.crt' 'ca-root.crt'
|
||||
|
||||
# Expired client/server.
|
||||
make_bundle 'test-3-client.pem' 'client-3.key' 'client-3.crt' 'ca-int-1.crt' 'ca-root.crt'
|
||||
make_bundle 'test-3-server.pem' 'server-3.key' 'server-3.crt' 'ca-int-1.crt' 'ca-root.crt'
|
||||
|
||||
# Bundles that terminate at intermediate 1.
|
||||
make_bundle 'test-4-server.pem' 'server-1.key' 'server-1.crt' 'ca-int-1.crt'
|
||||
make_bundle 'test-4-client.pem' 'client-1.key' 'client-1.crt' 'ca-int-1.crt'
|
||||
|
||||
# Bundles that terminate at intermediate 2.
|
||||
make_bundle 'test-5-server.pem' 'server-2.key' 'server-2.crt' 'ca-int-2.crt'
|
||||
make_bundle 'test-5-client.pem' 'client-2.key' 'client-2.crt' 'ca-int-2.crt'
|
|
@ -0,0 +1,106 @@
|
|||
subject= C = US, ST = California, L = Cupertino, O = Apple Inc., OU = FDB Team, CN = FDB LibTLS Plugin Test Client 1
|
||||
issuer= C = US, ST = California, L = Cupertino, O = Apple Inc., OU = FDB Team, CN = FDB LibTLS Plugin Test Intermediate CA 1
|
||||
subject= C = US, ST = California, L = Cupertino, O = Apple Inc., OU = FDB Team, CN = FDB LibTLS Plugin Test Intermediate CA 1
|
||||
issuer= C = US, ST = California, L = Cupertino, O = Apple Inc., OU = FDB Team, CN = FDB LibTLS Plugin Test Root CA
|
||||
subject= C = US, ST = California, L = Cupertino, O = Apple Inc., OU = FDB Team, CN = FDB LibTLS Plugin Test Root CA
|
||||
issuer= C = US, ST = California, L = Cupertino, O = Apple Inc., OU = FDB Team, CN = FDB LibTLS Plugin Test Root CA
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIID/jCCAuagAwIBAgIJALOPTrQGpeslMA0GCSqGSIb3DQEBBQUAMIGRMQswCQYD
|
||||
VQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTESMBAGA1UEBwwJQ3VwZXJ0aW5v
|
||||
MRMwEQYDVQQKDApBcHBsZSBJbmMuMREwDwYDVQQLDAhGREIgVGVhbTExMC8GA1UE
|
||||
AwwoRkRCIExpYlRMUyBQbHVnaW4gVGVzdCBJbnRlcm1lZGlhdGUgQ0EgMTAeFw0x
|
||||
ODA0MDcxNDE2MDJaFw0yODA0MDQxNDE2MDJaMIGIMQswCQYDVQQGEwJVUzETMBEG
|
||||
A1UECAwKQ2FsaWZvcm5pYTESMBAGA1UEBwwJQ3VwZXJ0aW5vMRMwEQYDVQQKDApB
|
||||
cHBsZSBJbmMuMREwDwYDVQQLDAhGREIgVGVhbTEoMCYGA1UEAwwfRkRCIExpYlRM
|
||||
UyBQbHVnaW4gVGVzdCBDbGllbnQgMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC
|
||||
AQoCggEBALVkdxOmWcd959NyirJ1iz7q5fkjdRUV+88KMMehQWc3f50GJIQ+eZo+
|
||||
7RhwVE+n8nd0i5iGfyY6LRuupdwoQUxoZ/5rUIDGKspNO62DVRW+tZqzpEa1+ub5
|
||||
75BMoc7I7l9sXDkuiMu1OYcPNKMv4F3mf+B3ourLqjUekKlUv8XIZXAvN+R19HlR
|
||||
FM8vs8rnhQXx7iWVP91frDvyD8G7lOf6R7R4homnB37kLom8WU+fCmcyA6em0qX0
|
||||
JeVP6xk2qXU1cMs7DL8WftdrWHv+a73/l4hytQHo5OvtGaLZhpPYpC/FMSaFHVSM
|
||||
irWSFK+ZtvaLi3LXc2HGANMokjPoRf8CAwEAAaNgMF4wHQYDVR0OBBYEFPtTL9KZ
|
||||
jn49cLediy1ixz7AXOI3MB8GA1UdIwQYMBaAFCXTF7f83Hd7xm9gR+O4QrvjNo8Q
|
||||
MAwGA1UdEwEB/wQCMAAwDgYDVR0PAQH/BAQDAgeAMA0GCSqGSIb3DQEBBQUAA4IB
|
||||
AQA17a4d/tSWIlTkIfkrXziD21+1OsN6/dUrWQK7kxtEe21QXIutccW4bwpM0JDB
|
||||
M+bZiWkdgQ15+ZotX5UXlBcx9WWDU5RqSO06hhXu5b8gZwfVF4Od6tBdVxkn4KbU
|
||||
0YujOZrL8fDOrQHqCO7nhNlYgcEn7bKF5wjtOoiKhtA9sLSIZQR5g32kkJXXGvcY
|
||||
lLWMXygEg9FMQoldW9RHq4GbUiYEeqEq6k4S7cE03R1lvmQEOOAJ2S7LnaS4UHQT
|
||||
GmW6uvLnJJrG4HB9JGE+y1e9M+C7Enzhi39RGd8ylignGimkdw/1UEWnvKGCqoU7
|
||||
ufWGF7eUV8dCqO+jYghIY8rA
|
||||
-----END CERTIFICATE-----
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIEADCCAuigAwIBAgIJALOPTrQGpeshMA0GCSqGSIb3DQEBBQUAMIGHMQswCQYD
|
||||
VQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTESMBAGA1UEBwwJQ3VwZXJ0aW5v
|
||||
MRMwEQYDVQQKDApBcHBsZSBJbmMuMREwDwYDVQQLDAhGREIgVGVhbTEnMCUGA1UE
|
||||
AwweRkRCIExpYlRMUyBQbHVnaW4gVGVzdCBSb290IENBMB4XDTE4MDQwNzE0MTYw
|
||||
MVoXDTI4MDQwNDE0MTYwMVowgZExCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxp
|
||||
Zm9ybmlhMRIwEAYDVQQHDAlDdXBlcnRpbm8xEzARBgNVBAoMCkFwcGxlIEluYy4x
|
||||
ETAPBgNVBAsMCEZEQiBUZWFtMTEwLwYDVQQDDChGREIgTGliVExTIFBsdWdpbiBU
|
||||
ZXN0IEludGVybWVkaWF0ZSBDQSAxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
|
||||
CgKCAQEAyOwdOcYcH3wYou13CchsXh3lLWA85E550tT6/WwDnslQjiMZHFrKvUT2
|
||||
B8CUOR3Fr+4RG+cdw80rgojYEUuHKwmIGyjo5IotdaYbWzf6mvYThlIPPudCCkSU
|
||||
CTtqPv8Oq4QdIpCxHdix0MINKu7c+qt1rUwnDFQSv/gHhVnNxT4r8pwVp6T4hwka
|
||||
2YQaRNjzUuuFinMub0UtxnUX0rH8X5STlOSVn4Ksjo0OhQzsGEYDx86jVAXjgGcb
|
||||
2CgGGctgq04hVrngP5ahT1Xeh9YycMlQJXsckJJBxfUJebIjANSRyzxI5fYt+ZkY
|
||||
qoG5VLPREUQknxcpbT7Rsj0n+k0RhwIDAQABo2MwYTAdBgNVHQ4EFgQUJdMXt/zc
|
||||
d3vGb2BH47hCu+M2jxAwHwYDVR0jBBgwFoAUnqtGja3O5jGlh5vHgp3Tf8NCPKkw
|
||||
DwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQEFBQAD
|
||||
ggEBAGwW7bRqB7aYUGsD1MOE9d5slp6Iw6wKyNLdg+mzoV+iCV2ZM7ejNRButiAy
|
||||
vPOxSQwXcibLm/g599e+LY1TiI1XXPbL2bFnTcnThqpHHFe+eRrDgqxO8qJyrcBp
|
||||
EfyMCJWq7jFg4bWoYTpLeC/RAKyi9fxlqY1NzQCp1bG3LiaDJ5VJd4uwkgX2a0yN
|
||||
3e0XEFNi7r4u4IHejwFjKWrDg8sstjbY+XOYC4EVQyUsbzeKZKSqnOdR2Jv1QZHH
|
||||
5O24G/efIFpsA6MVUOfRk0eq0RfKX7CdHn2a5p8aC6E6YMDhXL6xo146n49t9sYD
|
||||
HMUnfG6AEboTBa/l+zwCG/u4f/Y=
|
||||
-----END CERTIFICATE-----
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIID9jCCAt6gAwIBAgIJALfRa36cuemYMA0GCSqGSIb3DQEBCwUAMIGHMQswCQYD
|
||||
VQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTESMBAGA1UEBwwJQ3VwZXJ0aW5v
|
||||
MRMwEQYDVQQKDApBcHBsZSBJbmMuMREwDwYDVQQLDAhGREIgVGVhbTEnMCUGA1UE
|
||||
AwweRkRCIExpYlRMUyBQbHVnaW4gVGVzdCBSb290IENBMB4XDTE4MDQwNzE0MTYw
|
||||
MVoXDTI4MDQwNDE0MTYwMVowgYcxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxp
|
||||
Zm9ybmlhMRIwEAYDVQQHDAlDdXBlcnRpbm8xEzARBgNVBAoMCkFwcGxlIEluYy4x
|
||||
ETAPBgNVBAsMCEZEQiBUZWFtMScwJQYDVQQDDB5GREIgTGliVExTIFBsdWdpbiBU
|
||||
ZXN0IFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC/J+sL
|
||||
7POoXNdzYRsMZCI5juxMPOVue5vU2QPU9z/PHBsBICX6tVsCnkzk5CLdM6TxofgX
|
||||
F+MqRKxtcIqxBcKjjVecJlqHuNY+jS2r8UjcoQm+EQ5RsBWu8yaSnXIiZTccQNjB
|
||||
5T2awwt9Ptbn946MZfq6oEnn4ZPByu9/nCrlk7QXTkuGdpTnC6paQWt/lVxZfELM
|
||||
i0g76/K/f3e2Lv9UCvlxKOwFMye9XjwF3ekEmUuio5JZEdn+LIs9zB1zehFhGlYB
|
||||
TUXnkZ0LTOPbH9OxsOli04n31/n7UbYq1BSuoiXx5A2eHOunMppa0NDg7oXmDSKE
|
||||
A1zo+QtIu1YPXaLdAgMBAAGjYzBhMB0GA1UdDgQWBBSeq0aNrc7mMaWHm8eCndN/
|
||||
w0I8qTAfBgNVHSMEGDAWgBSeq0aNrc7mMaWHm8eCndN/w0I8qTAPBgNVHRMBAf8E
|
||||
BTADAQH/MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAQEAIOw1jC39
|
||||
VW+1fqGT+n44Y6Oh66lAowIvi/BEOW1I4iPAjkr0g6FbbdKeq0VLL7aMMu+q/AOv
|
||||
UETv7MdVh9xjTLqWZGN0R3Lr/n6ButI3E7MLKL5ByLNCoOhF42aBLINkpKSNFRrQ
|
||||
40iNoHm3BaNRLKS7poCk5HFkEMjvxdQ1AenNbUa21DTh7y9arHF4CPfi8Ity29jW
|
||||
ED8jYK/+bWIaO+YhGkRh8UuD3o5WnOti+9QK56qxkPtkqVTh9vMVHfD0DgVeLvMN
|
||||
nZpTplLTfhjzyFJELwE/U+HJ6KIslmqwarJ1Sla+1gHCmJEbzbsrnb6bLtrHtXCZ
|
||||
XvmR6B5iRkDVpw==
|
||||
-----END CERTIFICATE-----
|
||||
-----BEGIN PRIVATE KEY-----
|
||||
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC1ZHcTplnHfefT
|
||||
coqydYs+6uX5I3UVFfvPCjDHoUFnN3+dBiSEPnmaPu0YcFRPp/J3dIuYhn8mOi0b
|
||||
rqXcKEFMaGf+a1CAxirKTTutg1UVvrWas6RGtfrm+e+QTKHOyO5fbFw5LojLtTmH
|
||||
DzSjL+Bd5n/gd6Lqy6o1HpCpVL/FyGVwLzfkdfR5URTPL7PK54UF8e4llT/dX6w7
|
||||
8g/Bu5Tn+ke0eIaJpwd+5C6JvFlPnwpnMgOnptKl9CXlT+sZNql1NXDLOwy/Fn7X
|
||||
a1h7/mu9/5eIcrUB6OTr7Rmi2YaT2KQvxTEmhR1UjIq1khSvmbb2i4ty13NhxgDT
|
||||
KJIz6EX/AgMBAAECggEAEm2Mc2CZCl1OKfsfABZU+SVgC7mAcY30MQp1/jHxtQy8
|
||||
WDWBjDXUoMj3yV3QEu+bAGvEqtAvJrEOWBucGgu05pBM0FoSqaJ4QmkqQOxwvm7L
|
||||
gFXzwINIZCLMJbrDTYC4RtV5YQ3LM/bLS19OF64Lez6piyJcWMIsHo1mYO2NNgiD
|
||||
7f1x1uQw46Q0YHWeoHY58MPfmgfKsqnJDWc8cCuU9fJOWeU4dVrfW8dh9WVAoLZ7
|
||||
qAM5vvap11Qk8RXaRnmLjxN6H1M7iVNfcLVNKfG6XOBBepYjZr/qMkuN3ONuqBHl
|
||||
fC3Zia2zQZRfiuPspX0KhjCfYAKbIZC6oyrQM2uXgQKBgQDoD5voZiCOeGXJEMUk
|
||||
9JV4V8A96aE0xxy+OHMogVpysxBO4V0Nh0krSLTt9NXnpjawZQ+3pLQ4+2J2XM2e
|
||||
fJuJJ7Z+Mhjv6epnMM7FoxK1VF7oe+LE7Yk/kg/moCuVS/XhLdQrhZVBJhfEADS3
|
||||
oFybf7Q6rJYtN3OYsiFymyneHwKBgQDIGsY5kGdmx27LS5rPMwdw632TF8G5BGbu
|
||||
C3ty7LYkOWb/9/V4cuWjW4eLJQqCWbJQrzOvg0coxwXLUuEQik+IP2IkF0YlRS43
|
||||
VJuULwOxi3Cbj51RoapHhmYTO9fe2A1N9oJMAqEUHY1q/r9txPcguRWyuH2Yv9Ih
|
||||
OzHnc2DcIQKBgQCGW0MxMq/2zM5hs0vxMYq4ulWbgwDKxd1mZNiHwxzS+8mdYe22
|
||||
P3WlkdrvSqnuDNXtGxYWhU2zEBjZ3rFN6WdD6bJHLkox3YTRafjNhLT4N3kbsV6C
|
||||
FeU44SBDrsiNEAWz8gy9hgH8TknEOTpMdpQnk7CNqA7q7wgGiFvFNwDukQKBgG7i
|
||||
R03Gs0XE5aRJtPN0N39fPyqvU24O/mqSekno2dWg6W6WHLQuFwo6whVc5UHuKl2D
|
||||
eISdnmT+RDuzJXxg6El7tgqByyEEAOQwQjYPB2Du/+tz3Z1KlG0mEJI/6xNVbany
|
||||
G6m7Gz9mUOMlXzaYmsjLRzbN/OsUAIDhqHm0+cuBAoGAZCND80akS3xr3yC87GyX
|
||||
aA0RoHXbdB6dbP8Y6XYDXR4QFIA4kXwY5cCLaZA/0hP5FOzDhORmaoaPM8vUdNyb
|
||||
IYvbw2H6tODiU5oICWY6+HQQ2nXikucI4HDYDLbsiV2htZkEmBYWLilYq0Tb8jC5
|
||||
u+ehIIvZYLqKaY1GaKmF86A=
|
||||
-----END PRIVATE KEY-----
|
|
@ -0,0 +1,106 @@
|
|||
subject= C = US, ST = California, L = Cupertino, O = Apple Inc., OU = FDB Team, CN = FDB LibTLS Plugin Test Server 1
|
||||
issuer= C = US, ST = California, L = Cupertino, O = Apple Inc., OU = FDB Team, CN = FDB LibTLS Plugin Test Intermediate CA 1
|
||||
subject= C = US, ST = California, L = Cupertino, O = Apple Inc., OU = FDB Team, CN = FDB LibTLS Plugin Test Intermediate CA 1
|
||||
issuer= C = US, ST = California, L = Cupertino, O = Apple Inc., OU = FDB Team, CN = FDB LibTLS Plugin Test Root CA
|
||||
subject= C = US, ST = California, L = Cupertino, O = Apple Inc., OU = FDB Team, CN = FDB LibTLS Plugin Test Root CA
|
||||
issuer= C = US, ST = California, L = Cupertino, O = Apple Inc., OU = FDB Team, CN = FDB LibTLS Plugin Test Root CA
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIID/jCCAuagAwIBAgIJALOPTrQGpesjMA0GCSqGSIb3DQEBBQUAMIGRMQswCQYD
|
||||
VQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTESMBAGA1UEBwwJQ3VwZXJ0aW5v
|
||||
MRMwEQYDVQQKDApBcHBsZSBJbmMuMREwDwYDVQQLDAhGREIgVGVhbTExMC8GA1UE
|
||||
AwwoRkRCIExpYlRMUyBQbHVnaW4gVGVzdCBJbnRlcm1lZGlhdGUgQ0EgMTAeFw0x
|
||||
ODA0MDcxNDE2MDJaFw0yODA0MDQxNDE2MDJaMIGIMQswCQYDVQQGEwJVUzETMBEG
|
||||
A1UECAwKQ2FsaWZvcm5pYTESMBAGA1UEBwwJQ3VwZXJ0aW5vMRMwEQYDVQQKDApB
|
||||
cHBsZSBJbmMuMREwDwYDVQQLDAhGREIgVGVhbTEoMCYGA1UEAwwfRkRCIExpYlRM
|
||||
UyBQbHVnaW4gVGVzdCBTZXJ2ZXIgMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC
|
||||
AQoCggEBAJp26QAmlMusO7C8Py/I117r3kHvB+My5kIrj8g9sKpktwTzmsJGpvJU
|
||||
EaKISEdBsJHLGnZJhwIhr/+MG4WDEM4oFNCtBQZznV3wjIQWq1w4IO8/f3+nBPpW
|
||||
f14fjs1E911Uo/ZOL9bxvh1SIHkS6itgJi+tgVPx7C3s3W3mC5nU3omsE+Rx4DDm
|
||||
KUq1kyN1ELBIAceQ4wTmQ5B8dv6MSW7zt8Jdrhfhg2GJIPPB6XUZJ2yIOvgu55GW
|
||||
J5sMPa0uNDfCsWJ37fzFm+XJ/D96t7x8I49IyfzbIgcU9JYFlcqkryvKh5IpQGGm
|
||||
H/I6adIWa5xWpMhB2PA6kgtDD07Hu2sCAwEAAaNgMF4wHQYDVR0OBBYEFJ7S+FUz
|
||||
9ngzH/TNPVeM/cE7LeBGMB8GA1UdIwQYMBaAFCXTF7f83Hd7xm9gR+O4QrvjNo8Q
|
||||
MAwGA1UdEwEB/wQCMAAwDgYDVR0PAQH/BAQDAgeAMA0GCSqGSIb3DQEBBQUAA4IB
|
||||
AQAx6WHwikVFAH0TRYCznwO6He+0t2pnlyfrI+24N28tzupMSrRPs086UbLgHLz1
|
||||
lbkYdheeOkLPzjWi5vfymL1Oua3E2iAXWEpMb4Sg7E5SVHp9yt6gZ0DTVwR+Gcu7
|
||||
uooroidAG3OFeOXL5ivU5J5ipaoEAiLprpKxtPzo4z/TxIqw3kJISC56qw9VTJNQ
|
||||
TQZvneUecykdIZuH61ih0cJLe5WRkEs/63Dgl8TBYiVDbvBSGRbsXoAXcspVlc2x
|
||||
XOLey5IVJ4/TH5ZBobShC6J1KrjZTNYvUgc44CocOgrc0ePPiQzB7JXxR1H8ATGl
|
||||
yKjWqT2PkrfHmjdcmsi2GIVt
|
||||
-----END CERTIFICATE-----
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIEADCCAuigAwIBAgIJALOPTrQGpeshMA0GCSqGSIb3DQEBBQUAMIGHMQswCQYD
|
||||
VQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTESMBAGA1UEBwwJQ3VwZXJ0aW5v
|
||||
MRMwEQYDVQQKDApBcHBsZSBJbmMuMREwDwYDVQQLDAhGREIgVGVhbTEnMCUGA1UE
|
||||
AwweRkRCIExpYlRMUyBQbHVnaW4gVGVzdCBSb290IENBMB4XDTE4MDQwNzE0MTYw
|
||||
MVoXDTI4MDQwNDE0MTYwMVowgZExCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxp
|
||||
Zm9ybmlhMRIwEAYDVQQHDAlDdXBlcnRpbm8xEzARBgNVBAoMCkFwcGxlIEluYy4x
|
||||
ETAPBgNVBAsMCEZEQiBUZWFtMTEwLwYDVQQDDChGREIgTGliVExTIFBsdWdpbiBU
|
||||
ZXN0IEludGVybWVkaWF0ZSBDQSAxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
|
||||
CgKCAQEAyOwdOcYcH3wYou13CchsXh3lLWA85E550tT6/WwDnslQjiMZHFrKvUT2
|
||||
B8CUOR3Fr+4RG+cdw80rgojYEUuHKwmIGyjo5IotdaYbWzf6mvYThlIPPudCCkSU
|
||||
CTtqPv8Oq4QdIpCxHdix0MINKu7c+qt1rUwnDFQSv/gHhVnNxT4r8pwVp6T4hwka
|
||||
2YQaRNjzUuuFinMub0UtxnUX0rH8X5STlOSVn4Ksjo0OhQzsGEYDx86jVAXjgGcb
|
||||
2CgGGctgq04hVrngP5ahT1Xeh9YycMlQJXsckJJBxfUJebIjANSRyzxI5fYt+ZkY
|
||||
qoG5VLPREUQknxcpbT7Rsj0n+k0RhwIDAQABo2MwYTAdBgNVHQ4EFgQUJdMXt/zc
|
||||
d3vGb2BH47hCu+M2jxAwHwYDVR0jBBgwFoAUnqtGja3O5jGlh5vHgp3Tf8NCPKkw
|
||||
DwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQEFBQAD
|
||||
ggEBAGwW7bRqB7aYUGsD1MOE9d5slp6Iw6wKyNLdg+mzoV+iCV2ZM7ejNRButiAy
|
||||
vPOxSQwXcibLm/g599e+LY1TiI1XXPbL2bFnTcnThqpHHFe+eRrDgqxO8qJyrcBp
|
||||
EfyMCJWq7jFg4bWoYTpLeC/RAKyi9fxlqY1NzQCp1bG3LiaDJ5VJd4uwkgX2a0yN
|
||||
3e0XEFNi7r4u4IHejwFjKWrDg8sstjbY+XOYC4EVQyUsbzeKZKSqnOdR2Jv1QZHH
|
||||
5O24G/efIFpsA6MVUOfRk0eq0RfKX7CdHn2a5p8aC6E6YMDhXL6xo146n49t9sYD
|
||||
HMUnfG6AEboTBa/l+zwCG/u4f/Y=
|
||||
-----END CERTIFICATE-----
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIID9jCCAt6gAwIBAgIJALfRa36cuemYMA0GCSqGSIb3DQEBCwUAMIGHMQswCQYD
|
||||
VQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTESMBAGA1UEBwwJQ3VwZXJ0aW5v
|
||||
MRMwEQYDVQQKDApBcHBsZSBJbmMuMREwDwYDVQQLDAhGREIgVGVhbTEnMCUGA1UE
|
||||
AwweRkRCIExpYlRMUyBQbHVnaW4gVGVzdCBSb290IENBMB4XDTE4MDQwNzE0MTYw
|
||||
MVoXDTI4MDQwNDE0MTYwMVowgYcxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxp
|
||||
Zm9ybmlhMRIwEAYDVQQHDAlDdXBlcnRpbm8xEzARBgNVBAoMCkFwcGxlIEluYy4x
|
||||
ETAPBgNVBAsMCEZEQiBUZWFtMScwJQYDVQQDDB5GREIgTGliVExTIFBsdWdpbiBU
|
||||
ZXN0IFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC/J+sL
|
||||
7POoXNdzYRsMZCI5juxMPOVue5vU2QPU9z/PHBsBICX6tVsCnkzk5CLdM6TxofgX
|
||||
F+MqRKxtcIqxBcKjjVecJlqHuNY+jS2r8UjcoQm+EQ5RsBWu8yaSnXIiZTccQNjB
|
||||
5T2awwt9Ptbn946MZfq6oEnn4ZPByu9/nCrlk7QXTkuGdpTnC6paQWt/lVxZfELM
|
||||
i0g76/K/f3e2Lv9UCvlxKOwFMye9XjwF3ekEmUuio5JZEdn+LIs9zB1zehFhGlYB
|
||||
TUXnkZ0LTOPbH9OxsOli04n31/n7UbYq1BSuoiXx5A2eHOunMppa0NDg7oXmDSKE
|
||||
A1zo+QtIu1YPXaLdAgMBAAGjYzBhMB0GA1UdDgQWBBSeq0aNrc7mMaWHm8eCndN/
|
||||
w0I8qTAfBgNVHSMEGDAWgBSeq0aNrc7mMaWHm8eCndN/w0I8qTAPBgNVHRMBAf8E
|
||||
BTADAQH/MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAQEAIOw1jC39
|
||||
VW+1fqGT+n44Y6Oh66lAowIvi/BEOW1I4iPAjkr0g6FbbdKeq0VLL7aMMu+q/AOv
|
||||
UETv7MdVh9xjTLqWZGN0R3Lr/n6ButI3E7MLKL5ByLNCoOhF42aBLINkpKSNFRrQ
|
||||
40iNoHm3BaNRLKS7poCk5HFkEMjvxdQ1AenNbUa21DTh7y9arHF4CPfi8Ity29jW
|
||||
ED8jYK/+bWIaO+YhGkRh8UuD3o5WnOti+9QK56qxkPtkqVTh9vMVHfD0DgVeLvMN
|
||||
nZpTplLTfhjzyFJELwE/U+HJ6KIslmqwarJ1Sla+1gHCmJEbzbsrnb6bLtrHtXCZ
|
||||
XvmR6B5iRkDVpw==
|
||||
-----END CERTIFICATE-----
|
||||
-----BEGIN PRIVATE KEY-----
|
||||
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCadukAJpTLrDuw
|
||||
vD8vyNde695B7wfjMuZCK4/IPbCqZLcE85rCRqbyVBGiiEhHQbCRyxp2SYcCIa//
|
||||
jBuFgxDOKBTQrQUGc51d8IyEFqtcOCDvP39/pwT6Vn9eH47NRPddVKP2Ti/W8b4d
|
||||
UiB5EuorYCYvrYFT8ewt7N1t5guZ1N6JrBPkceAw5ilKtZMjdRCwSAHHkOME5kOQ
|
||||
fHb+jElu87fCXa4X4YNhiSDzwel1GSdsiDr4LueRliebDD2tLjQ3wrFid+38xZvl
|
||||
yfw/ere8fCOPSMn82yIHFPSWBZXKpK8ryoeSKUBhph/yOmnSFmucVqTIQdjwOpIL
|
||||
Qw9Ox7trAgMBAAECggEAOZAMvsCh/NDfobpVddJL6JTPzBRvBQ1H3+rp9z5+ItHL
|
||||
nq3Fw5aeynnn5IETJnLlgT+GSgSWqoWxV/N3oia40YsATs/bqo7VW1e0ldj43TIR
|
||||
m/c25XRxl3U6m/H4vqhv4rkTLUvv6hNGvRiI/3W8DJQVRvlK0+S5FlhKIJV1R0sH
|
||||
tp5vmaPp09Ln+NVno3u3iaYkVgVME4Ukul2i03sQ9OgvZSBCaVr//fMpiPdBeeN6
|
||||
QY6XHjeGQRnP/UdzMYJ4Qz1yovL1ntneaTMdz/GkKuAFoNNh8Vr2kiEskW17OWPB
|
||||
ZGcIT6YpBEPo34xXUhUQt7ylFPxGH+zZyHZ3vb8j6QKBgQDJPeu/iPg+M5nz5gO5
|
||||
ge9gzYrhxK/1mwbFlD7qt1NjOSm6xWxUcss3STjuG7jB0c+NopIUoq/egsUnxrRm
|
||||
4l17uOCYNLbhTJ2ynfv6QnUMxW5Xkve3DkLa2bze/fhMUywTy8N4A7z0+y35qzm3
|
||||
lY4rLmQOQKPkmqWRnxU1u8fjFQKBgQDEfpOZ0fp2D/1gTG+D+/zrMEbjnNn3ZO8I
|
||||
wrjoXwRxcRggt7lJhxgQpwtDr98IqYkDzX7bvyMFJuyTii3NM6NYycpA1pHX70B/
|
||||
xMvOcrgJnIUAoJ7nl43Or7s8bFTPDLaD9PNGHjrlkF3JOXqSKEbw367jHVOa4SYr
|
||||
OjrogjrEfwKBgQDHU2a7ax5+9btqggx0ZQfGOTBzmM60lZ3qe4CqGXUl1YvIrB01
|
||||
tBImq4cRCTJB/9/1qO3KNK2/1oUTddRgB5ySnDcRaz0tASc9sQ/Q/JxVTwSRB0gG
|
||||
78A2Zu6VbLbQWp1Q6kWtDP7PJC+QmRFtDlwn1yZRm6L6HlcaWpi2hU1iVQKBgCEu
|
||||
ashv8Aad3qCzZ6V3GReyOFZZd2lSjxcAou8ClKJ/gZ6Mx+pFuOee/cT5XwV8c5nD
|
||||
yuda2JQXJZ4omGFtlej5coEOeuRnD5JD7lK3hqKA3ujjNtJPAnBjto+Wj5/DOtL/
|
||||
u1Ec6782aNABN9SUnp4wd7z8h9DAsoxcMfRvgXMLAoGBAJ9gGttfqZbuPz9V0rAo
|
||||
p05SPPado1i5+2dUOScIbNB6+vQij9IlR2Tzu1T9DwzrBqTDPPmSggeA/JXeTvh6
|
||||
Skb9fDukizeDfwPYUN2gljhiJEqFdpRBr5vP0lFi291+a0jMW1zldrumxCcGKMyU
|
||||
D5ReKLp/zSQSQi/Wt4FF1II7
|
||||
-----END PRIVATE KEY-----
|
|
@ -0,0 +1,106 @@
|
|||
subject= C = AU, ST = New South Wales, L = Sydney, O = Apple Pty Limited, OU = FDB Team, CN = "FDB LibTLS Plugin Test Client 2, \C2\80 <\01+\02=\03>"
|
||||
issuer= C = US, ST = California, L = Cupertino, O = Apple Inc., OU = FDB Team, CN = FDB LibTLS Plugin Test Intermediate CA 2
|
||||
subject= C = US, ST = California, L = Cupertino, O = Apple Inc., OU = FDB Team, CN = FDB LibTLS Plugin Test Intermediate CA 2
|
||||
issuer= C = US, ST = California, L = Cupertino, O = Apple Inc., OU = FDB Team, CN = FDB LibTLS Plugin Test Root CA
|
||||
subject= C = US, ST = California, L = Cupertino, O = Apple Inc., OU = FDB Team, CN = FDB LibTLS Plugin Test Root CA
|
||||
issuer= C = US, ST = California, L = Cupertino, O = Apple Inc., OU = FDB Team, CN = FDB LibTLS Plugin Test Root CA
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIEEzCCAvugAwIBAgIJALOPTrQGpesmMA0GCSqGSIb3DQEBBQUAMIGRMQswCQYD
|
||||
VQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTESMBAGA1UEBwwJQ3VwZXJ0aW5v
|
||||
MRMwEQYDVQQKDApBcHBsZSBJbmMuMREwDwYDVQQLDAhGREIgVGVhbTExMC8GA1UE
|
||||
AwwoRkRCIExpYlRMUyBQbHVnaW4gVGVzdCBJbnRlcm1lZGlhdGUgQ0EgMjAeFw0x
|
||||
ODA0MDcxNDE2MDJaFw0yODA0MDQxNDE2MDJaMIGdMQswCQYDVQQGEwJBVTEYMBYG
|
||||
A1UECAwPTmV3IFNvdXRoIFdhbGVzMQ8wDQYDVQQHDAZTeWRuZXkxGjAYBgNVBAoM
|
||||
EUFwcGxlIFB0eSBMaW1pdGVkMREwDwYDVQQLDAhGREIgVGVhbTE0MDIGA1UEAwwr
|
||||
RkRCIExpYlRMUyBQbHVnaW4gVGVzdCBDbGllbnQgMiwgwoAgPAErAj0DPjCCASIw
|
||||
DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALanLExQi/yK2PRyu6Mvdw2MRxUs
|
||||
26kJftYuK7KtYyltTO3vtj4kNKg1vZI1eezhqr2Ta/1DzE76eLVs8EOW0LAb5oWM
|
||||
zXdYBXBX4vG+K7pYfjuvZUd6jfX2bHW10xC96HgDTfRn6dof8GR0fILJ6DoEcyI3
|
||||
82xnKKxTsgAuXU4uvcsl0g0F78nXuIbk8ZktTV3LIdbOCIcLQfG7DdDyAfEA0T7Q
|
||||
Vg6eeLknIUvPePxyWkUdYeSCDP2d+3NIlHMxNPmH1q3+fCsEsy/kqdVO9e6KrZla
|
||||
CKqnc6yYTXvTffpPepC3Igz678iGg3dv9rLj0i4fyTr4tEOTJebO9Ka3TbMCAwEA
|
||||
AaNgMF4wHQYDVR0OBBYEFKO2/D1IhG8KWFwR6OdyoFqEzIWAMB8GA1UdIwQYMBaA
|
||||
FJFP+HFpDrD0BRU0yE606s6xkqFBMAwGA1UdEwEB/wQCMAAwDgYDVR0PAQH/BAQD
|
||||
AgeAMA0GCSqGSIb3DQEBBQUAA4IBAQAQV3FjsvZvwi5Oi/oSc7Du/BQS9nQ/D4j6
|
||||
IeYpd3M0y50awZB83BReYrhdC907xKkLRD0R8oEPDEg5SaSj3vRML4kaUUqnEINW
|
||||
4JQtv4wNO9CagYriGg8ygQa0xd683svHeXDet3ov11XN/Ms8lfDiOUp2291HgeTW
|
||||
8hqn1DaNfZrCb3EkdoNThwVKIUzQtEPBuPkLE+XT8kZP5d8KHmv8/9L39NdZY32d
|
||||
fzKGBeCxZ34pQS0cTap3rZ02nDfV2vNevODRyuqdhs7EQps2Oe1IfPB9GSE0OFUQ
|
||||
tdphxSjsv1BcHpTwBDpIITKarnceMIKxQjcZU3yPv5ibIaGCgZOt
|
||||
-----END CERTIFICATE-----
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIEADCCAuigAwIBAgIJALOPTrQGpesiMA0GCSqGSIb3DQEBBQUAMIGHMQswCQYD
|
||||
VQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTESMBAGA1UEBwwJQ3VwZXJ0aW5v
|
||||
MRMwEQYDVQQKDApBcHBsZSBJbmMuMREwDwYDVQQLDAhGREIgVGVhbTEnMCUGA1UE
|
||||
AwweRkRCIExpYlRMUyBQbHVnaW4gVGVzdCBSb290IENBMB4XDTE4MDQwNzE0MTYw
|
||||
MVoXDTI4MDQwNDE0MTYwMVowgZExCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxp
|
||||
Zm9ybmlhMRIwEAYDVQQHDAlDdXBlcnRpbm8xEzARBgNVBAoMCkFwcGxlIEluYy4x
|
||||
ETAPBgNVBAsMCEZEQiBUZWFtMTEwLwYDVQQDDChGREIgTGliVExTIFBsdWdpbiBU
|
||||
ZXN0IEludGVybWVkaWF0ZSBDQSAyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
|
||||
CgKCAQEApTSBCiUb0amf+QRV2WY6b3bK93D/PSrm4KR/2m2V0lciU1DAk00/kZ52
|
||||
ZIZmq8g9EaE2+CaDtU0fMvDZpaZD+vTFRwsx4varehq0ZwX9Wt25i/3G/eGLNlD3
|
||||
9E4tDNruK5UQjum4nJ0SV+AdFEGkSfeU3ZJEHYH0NrcbyAUbh0KeWCSwHiYiFJJf
|
||||
gBYwRq/HdKNoS/4YvLXzTLR7BSm3YcqWlO5tdkJ2lcT/7Th/Hq1TCW/FKwdQJJBq
|
||||
JrbOYGlMrf1pLO7Drei/xhsYkwTQ899MhSjkBRhc+401p41Mky0n8wLkuPJGhoY3
|
||||
9QUOjT+Rmvq5yryg0eWGiFquk6Ru5QIDAQABo2MwYTAdBgNVHQ4EFgQUkU/4cWkO
|
||||
sPQFFTTITrTqzrGSoUEwHwYDVR0jBBgwFoAUnqtGja3O5jGlh5vHgp3Tf8NCPKkw
|
||||
DwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQEFBQAD
|
||||
ggEBAJfCHU7dm2/2ASyt3wyxivQLxlV6FsEZcF7HcpbbxuB73frGOL4kEoOxvr2X
|
||||
fBGyjlPMotbc1MeAalAv+hVHdcAcBFPF7lxtYiV6D7YI5T5yVbWSASG3+DMAiW6S
|
||||
GdQi2eyeh00nH7Y1IkW+yaky0enBtWLzrw+XzHl6xT6DIEJnir//PNxvgXTJ5sjk
|
||||
6eFAm8HJIqkNQmgfChMQfUH6nm66WwULW6I117RCSkXhIgxZ7wzDq8bXcEdXCrZk
|
||||
yy5ket9OiVpbd38JgdYirBLmCQVq0uDOOPLz4ZJmNCzQzEt+38AAK2azAk/eb8W9
|
||||
JaKWH+5V8lhlyGw1zQKdNEP/wg8=
|
||||
-----END CERTIFICATE-----
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIID9jCCAt6gAwIBAgIJALfRa36cuemYMA0GCSqGSIb3DQEBCwUAMIGHMQswCQYD
|
||||
VQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTESMBAGA1UEBwwJQ3VwZXJ0aW5v
|
||||
MRMwEQYDVQQKDApBcHBsZSBJbmMuMREwDwYDVQQLDAhGREIgVGVhbTEnMCUGA1UE
|
||||
AwweRkRCIExpYlRMUyBQbHVnaW4gVGVzdCBSb290IENBMB4XDTE4MDQwNzE0MTYw
|
||||
MVoXDTI4MDQwNDE0MTYwMVowgYcxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxp
|
||||
Zm9ybmlhMRIwEAYDVQQHDAlDdXBlcnRpbm8xEzARBgNVBAoMCkFwcGxlIEluYy4x
|
||||
ETAPBgNVBAsMCEZEQiBUZWFtMScwJQYDVQQDDB5GREIgTGliVExTIFBsdWdpbiBU
|
||||
ZXN0IFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC/J+sL
|
||||
7POoXNdzYRsMZCI5juxMPOVue5vU2QPU9z/PHBsBICX6tVsCnkzk5CLdM6TxofgX
|
||||
F+MqRKxtcIqxBcKjjVecJlqHuNY+jS2r8UjcoQm+EQ5RsBWu8yaSnXIiZTccQNjB
|
||||
5T2awwt9Ptbn946MZfq6oEnn4ZPByu9/nCrlk7QXTkuGdpTnC6paQWt/lVxZfELM
|
||||
i0g76/K/f3e2Lv9UCvlxKOwFMye9XjwF3ekEmUuio5JZEdn+LIs9zB1zehFhGlYB
|
||||
TUXnkZ0LTOPbH9OxsOli04n31/n7UbYq1BSuoiXx5A2eHOunMppa0NDg7oXmDSKE
|
||||
A1zo+QtIu1YPXaLdAgMBAAGjYzBhMB0GA1UdDgQWBBSeq0aNrc7mMaWHm8eCndN/
|
||||
w0I8qTAfBgNVHSMEGDAWgBSeq0aNrc7mMaWHm8eCndN/w0I8qTAPBgNVHRMBAf8E
|
||||
BTADAQH/MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAQEAIOw1jC39
|
||||
VW+1fqGT+n44Y6Oh66lAowIvi/BEOW1I4iPAjkr0g6FbbdKeq0VLL7aMMu+q/AOv
|
||||
UETv7MdVh9xjTLqWZGN0R3Lr/n6ButI3E7MLKL5ByLNCoOhF42aBLINkpKSNFRrQ
|
||||
40iNoHm3BaNRLKS7poCk5HFkEMjvxdQ1AenNbUa21DTh7y9arHF4CPfi8Ity29jW
|
||||
ED8jYK/+bWIaO+YhGkRh8UuD3o5WnOti+9QK56qxkPtkqVTh9vMVHfD0DgVeLvMN
|
||||
nZpTplLTfhjzyFJELwE/U+HJ6KIslmqwarJ1Sla+1gHCmJEbzbsrnb6bLtrHtXCZ
|
||||
XvmR6B5iRkDVpw==
|
||||
-----END CERTIFICATE-----
|
||||
-----BEGIN PRIVATE KEY-----
|
||||
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC2pyxMUIv8itj0
|
||||
crujL3cNjEcVLNupCX7WLiuyrWMpbUzt77Y+JDSoNb2SNXns4aq9k2v9Q8xO+ni1
|
||||
bPBDltCwG+aFjM13WAVwV+Lxviu6WH47r2VHeo319mx1tdMQveh4A030Z+naH/Bk
|
||||
dHyCyeg6BHMiN/NsZyisU7IALl1OLr3LJdINBe/J17iG5PGZLU1dyyHWzgiHC0Hx
|
||||
uw3Q8gHxANE+0FYOnni5JyFLz3j8clpFHWHkggz9nftzSJRzMTT5h9at/nwrBLMv
|
||||
5KnVTvXuiq2ZWgiqp3OsmE170336T3qQtyIM+u/IhoN3b/ay49IuH8k6+LRDkyXm
|
||||
zvSmt02zAgMBAAECggEAU2sYHSZwOH+FRGcd8RJdcg+N60rYa2QNzG27wVfUwPfN
|
||||
OaHP/qN0dRpOIPdRXvFVlE0+9aVAKxXTiTBers+zMascZgP/VrEZksxgtn1e5TVD
|
||||
OakKPVHogdvwfvXylmPVRvJjaOsIb3lExew5bVYfPFgJ6Sfagbi/Z6y1z8VdEbYb
|
||||
mI34KSZA4bBAMAHPZLa9TGEx/vbPsBlqpU6k8lcoy3cTkO5fCZW4ZZIpwBwef4uJ
|
||||
UozhRgtTtRBiUpk0F9IoOXonZY1Dtpg+HcDMti/FYgahBVe1hadJ+lbVTxH6GxyI
|
||||
NJYvptdq5S99UOoJDmCCih0v0ZCUNYWoO0I0vzNncQKBgQDemN7es2fIBstiPjOf
|
||||
p103DF5j9Uxq5YH9B3wli0CXf6Z2w5uosONoJWgJZKsHJ6f+YSuHsoE/eCrFF3U9
|
||||
lxT9Nie/wYYIGedly/VR143aCdiTXI44m5gxXgwaUcjvY1DpWyEAAmr5XNdoyZ5n
|
||||
LNTvOTb4vVo9SgDU7II7rdpRmwKBgQDSD9aBtIy/650suQK/9RiXRU0Kg7LXXVM5
|
||||
lavPgLvH55lufJeGSa8+ofCNeo31N4AaVuU4lkGeny9tLNBQbYAoyAz0lf51qK7B
|
||||
1u5JqBDyRrIpdkqwbT0FT1pu1LA3+Qg0KQBrTCnOx+YyyVSivR4YMZzJjmwZGKMg
|
||||
BWOi0PzhyQKBgGR44dfpaIWbs39zjf+ZHnTza0N4+/YgA60/DKUxloULRArFPeRF
|
||||
e0+N2siqnJvNJYGnQGuugbIxPjTZ4rxbDklAgW6HHkVX099Z0TAQuGFbIltZYoRg
|
||||
jrBxv8q9cZHD5Uh/LoT/kmNdqYkNwCbX0IDt9UcOyMVzOq7g1eO0FB/TAoGBAMaG
|
||||
tWIsMwGHOip0SAcHKtB8bI1NXo5v4yH/NDuOHOqXFcj383S02uzEu8XaV6Ozalx6
|
||||
V3SdfTLem0IBIneApajlOGlIAQ9N9qu358ixECMJcYQCCiCnfQ4xqvQoCss7judN
|
||||
ANpnRvPotMS2xkhvl6uh594NvlgRksnGjh3oibcRAoGBAJKiu5ajmIkelzAhFMEC
|
||||
Slxhg/E+djJ1/SG/FaF8zIyTOxre/QUvmTwFKtHe6A5EfKQo9GCTuHuAcJ1U7eQP
|
||||
l2BoY0POqJFpw3s/QOt4g/pOz0YjD9GD6awL5WDfO++s4mnI1Snc3wcu99N4Klax
|
||||
htsaEUECJBUF0ZpIFad73s2f
|
||||
-----END PRIVATE KEY-----
|
|
@ -0,0 +1,106 @@
|
|||
subject= C = AU, ST = New South Wales, L = Sydney, O = Apple Pty Limited, OU = FDB Team, CN = "FDB LibTLS Plugin Test Server 2, \C2\80 <\01+\02=\03>"
|
||||
issuer= C = US, ST = California, L = Cupertino, O = Apple Inc., OU = FDB Team, CN = FDB LibTLS Plugin Test Intermediate CA 2
|
||||
subject= C = US, ST = California, L = Cupertino, O = Apple Inc., OU = FDB Team, CN = FDB LibTLS Plugin Test Intermediate CA 2
|
||||
issuer= C = US, ST = California, L = Cupertino, O = Apple Inc., OU = FDB Team, CN = FDB LibTLS Plugin Test Root CA
|
||||
subject= C = US, ST = California, L = Cupertino, O = Apple Inc., OU = FDB Team, CN = FDB LibTLS Plugin Test Root CA
|
||||
issuer= C = US, ST = California, L = Cupertino, O = Apple Inc., OU = FDB Team, CN = FDB LibTLS Plugin Test Root CA
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIEEzCCAvugAwIBAgIJALOPTrQGpeskMA0GCSqGSIb3DQEBBQUAMIGRMQswCQYD
|
||||
VQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTESMBAGA1UEBwwJQ3VwZXJ0aW5v
|
||||
MRMwEQYDVQQKDApBcHBsZSBJbmMuMREwDwYDVQQLDAhGREIgVGVhbTExMC8GA1UE
|
||||
AwwoRkRCIExpYlRMUyBQbHVnaW4gVGVzdCBJbnRlcm1lZGlhdGUgQ0EgMjAeFw0x
|
||||
ODA0MDcxNDE2MDJaFw0yODA0MDQxNDE2MDJaMIGdMQswCQYDVQQGEwJBVTEYMBYG
|
||||
A1UECAwPTmV3IFNvdXRoIFdhbGVzMQ8wDQYDVQQHDAZTeWRuZXkxGjAYBgNVBAoM
|
||||
EUFwcGxlIFB0eSBMaW1pdGVkMREwDwYDVQQLDAhGREIgVGVhbTE0MDIGA1UEAwwr
|
||||
RkRCIExpYlRMUyBQbHVnaW4gVGVzdCBTZXJ2ZXIgMiwgwoAgPAErAj0DPjCCASIw
|
||||
DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALAolQZIGMeL5w/Bu2X6lHWjO58u
|
||||
+HUDtBmr37So4jazhZBSFDBg+QlRMiYGLev9EhvCrUsVcRwtvtcuMI3wfKl7qgbi
|
||||
ZX8zmrzZ3YJo9U47NzCa05faOl8uSBvuXuXUBLU342WFP8XDB1W8yOBQMK73xoFv
|
||||
DkcxURx9ZtOhdC3EgYKrFqOB1Azl1DB4gLV3h9rHW5QpQ8SqD9CyggcDBpDeZQIP
|
||||
+4l5YFE9Nb4kEUTscz2wGn4TdHMmcnVpfUxp1Y2o8Umvh4llXHIPhximGb3JJ4QQ
|
||||
Sir4ZXeeoooWoJG0sdlqVLroKav/VMGtEu9LyfbrNdKnTJq3ceVQ+HJ2hlMCAwEA
|
||||
AaNgMF4wHQYDVR0OBBYEFH61Z8O9vFsVdhM4MBU3poX2UMTEMB8GA1UdIwQYMBaA
|
||||
FJFP+HFpDrD0BRU0yE606s6xkqFBMAwGA1UdEwEB/wQCMAAwDgYDVR0PAQH/BAQD
|
||||
AgeAMA0GCSqGSIb3DQEBBQUAA4IBAQCVbxlLGIBCo6/XXjqoMyZc7uQZJj7pGnwh
|
||||
nIMs2izCLfax8j+QrThO2Qjn03zT/WF8eG6ibPbjgnw3VFwCkV6oQ+BXG6Yt0xqP
|
||||
4rz1LzxSio6HSm26gSk4SQUsVoAtz3OImoTCFVfz+Mixe87pyVXXEEtCYvfU74H9
|
||||
I1WGyNkWAxiJbqeIxF5PKoc3EdnT5mfdC6sdeGm7t2neeS8PDFQtJ4UfVIEK5z1C
|
||||
MOfQILNkLX2nBYxNqKpV66zf68VZNN9002ZH2FITGqImpj74BEws3sheiuZySdoI
|
||||
wnAwRnymIMfAmkf9C7Q2ugId0YMMyesaWrIwSlXlJOHGsA1VrBRD
|
||||
-----END CERTIFICATE-----
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIEADCCAuigAwIBAgIJALOPTrQGpesiMA0GCSqGSIb3DQEBBQUAMIGHMQswCQYD
|
||||
VQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTESMBAGA1UEBwwJQ3VwZXJ0aW5v
|
||||
MRMwEQYDVQQKDApBcHBsZSBJbmMuMREwDwYDVQQLDAhGREIgVGVhbTEnMCUGA1UE
|
||||
AwweRkRCIExpYlRMUyBQbHVnaW4gVGVzdCBSb290IENBMB4XDTE4MDQwNzE0MTYw
|
||||
MVoXDTI4MDQwNDE0MTYwMVowgZExCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxp
|
||||
Zm9ybmlhMRIwEAYDVQQHDAlDdXBlcnRpbm8xEzARBgNVBAoMCkFwcGxlIEluYy4x
|
||||
ETAPBgNVBAsMCEZEQiBUZWFtMTEwLwYDVQQDDChGREIgTGliVExTIFBsdWdpbiBU
|
||||
ZXN0IEludGVybWVkaWF0ZSBDQSAyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
|
||||
CgKCAQEApTSBCiUb0amf+QRV2WY6b3bK93D/PSrm4KR/2m2V0lciU1DAk00/kZ52
|
||||
ZIZmq8g9EaE2+CaDtU0fMvDZpaZD+vTFRwsx4varehq0ZwX9Wt25i/3G/eGLNlD3
|
||||
9E4tDNruK5UQjum4nJ0SV+AdFEGkSfeU3ZJEHYH0NrcbyAUbh0KeWCSwHiYiFJJf
|
||||
gBYwRq/HdKNoS/4YvLXzTLR7BSm3YcqWlO5tdkJ2lcT/7Th/Hq1TCW/FKwdQJJBq
|
||||
JrbOYGlMrf1pLO7Drei/xhsYkwTQ899MhSjkBRhc+401p41Mky0n8wLkuPJGhoY3
|
||||
9QUOjT+Rmvq5yryg0eWGiFquk6Ru5QIDAQABo2MwYTAdBgNVHQ4EFgQUkU/4cWkO
|
||||
sPQFFTTITrTqzrGSoUEwHwYDVR0jBBgwFoAUnqtGja3O5jGlh5vHgp3Tf8NCPKkw
|
||||
DwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQEFBQAD
|
||||
ggEBAJfCHU7dm2/2ASyt3wyxivQLxlV6FsEZcF7HcpbbxuB73frGOL4kEoOxvr2X
|
||||
fBGyjlPMotbc1MeAalAv+hVHdcAcBFPF7lxtYiV6D7YI5T5yVbWSASG3+DMAiW6S
|
||||
GdQi2eyeh00nH7Y1IkW+yaky0enBtWLzrw+XzHl6xT6DIEJnir//PNxvgXTJ5sjk
|
||||
6eFAm8HJIqkNQmgfChMQfUH6nm66WwULW6I117RCSkXhIgxZ7wzDq8bXcEdXCrZk
|
||||
yy5ket9OiVpbd38JgdYirBLmCQVq0uDOOPLz4ZJmNCzQzEt+38AAK2azAk/eb8W9
|
||||
JaKWH+5V8lhlyGw1zQKdNEP/wg8=
|
||||
-----END CERTIFICATE-----
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIID9jCCAt6gAwIBAgIJALfRa36cuemYMA0GCSqGSIb3DQEBCwUAMIGHMQswCQYD
|
||||
VQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTESMBAGA1UEBwwJQ3VwZXJ0aW5v
|
||||
MRMwEQYDVQQKDApBcHBsZSBJbmMuMREwDwYDVQQLDAhGREIgVGVhbTEnMCUGA1UE
|
||||
AwweRkRCIExpYlRMUyBQbHVnaW4gVGVzdCBSb290IENBMB4XDTE4MDQwNzE0MTYw
|
||||
MVoXDTI4MDQwNDE0MTYwMVowgYcxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxp
|
||||
Zm9ybmlhMRIwEAYDVQQHDAlDdXBlcnRpbm8xEzARBgNVBAoMCkFwcGxlIEluYy4x
|
||||
ETAPBgNVBAsMCEZEQiBUZWFtMScwJQYDVQQDDB5GREIgTGliVExTIFBsdWdpbiBU
|
||||
ZXN0IFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC/J+sL
|
||||
7POoXNdzYRsMZCI5juxMPOVue5vU2QPU9z/PHBsBICX6tVsCnkzk5CLdM6TxofgX
|
||||
F+MqRKxtcIqxBcKjjVecJlqHuNY+jS2r8UjcoQm+EQ5RsBWu8yaSnXIiZTccQNjB
|
||||
5T2awwt9Ptbn946MZfq6oEnn4ZPByu9/nCrlk7QXTkuGdpTnC6paQWt/lVxZfELM
|
||||
i0g76/K/f3e2Lv9UCvlxKOwFMye9XjwF3ekEmUuio5JZEdn+LIs9zB1zehFhGlYB
|
||||
TUXnkZ0LTOPbH9OxsOli04n31/n7UbYq1BSuoiXx5A2eHOunMppa0NDg7oXmDSKE
|
||||
A1zo+QtIu1YPXaLdAgMBAAGjYzBhMB0GA1UdDgQWBBSeq0aNrc7mMaWHm8eCndN/
|
||||
w0I8qTAfBgNVHSMEGDAWgBSeq0aNrc7mMaWHm8eCndN/w0I8qTAPBgNVHRMBAf8E
|
||||
BTADAQH/MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAQEAIOw1jC39
|
||||
VW+1fqGT+n44Y6Oh66lAowIvi/BEOW1I4iPAjkr0g6FbbdKeq0VLL7aMMu+q/AOv
|
||||
UETv7MdVh9xjTLqWZGN0R3Lr/n6ButI3E7MLKL5ByLNCoOhF42aBLINkpKSNFRrQ
|
||||
40iNoHm3BaNRLKS7poCk5HFkEMjvxdQ1AenNbUa21DTh7y9arHF4CPfi8Ity29jW
|
||||
ED8jYK/+bWIaO+YhGkRh8UuD3o5WnOti+9QK56qxkPtkqVTh9vMVHfD0DgVeLvMN
|
||||
nZpTplLTfhjzyFJELwE/U+HJ6KIslmqwarJ1Sla+1gHCmJEbzbsrnb6bLtrHtXCZ
|
||||
XvmR6B5iRkDVpw==
|
||||
-----END CERTIFICATE-----
|
||||
-----BEGIN PRIVATE KEY-----
|
||||
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCwKJUGSBjHi+cP
|
||||
wbtl+pR1ozufLvh1A7QZq9+0qOI2s4WQUhQwYPkJUTImBi3r/RIbwq1LFXEcLb7X
|
||||
LjCN8Hype6oG4mV/M5q82d2CaPVOOzcwmtOX2jpfLkgb7l7l1AS1N+NlhT/FwwdV
|
||||
vMjgUDCu98aBbw5HMVEcfWbToXQtxIGCqxajgdQM5dQweIC1d4fax1uUKUPEqg/Q
|
||||
soIHAwaQ3mUCD/uJeWBRPTW+JBFE7HM9sBp+E3RzJnJ1aX1MadWNqPFJr4eJZVxy
|
||||
D4cYphm9ySeEEEoq+GV3nqKKFqCRtLHZalS66Cmr/1TBrRLvS8n26zXSp0yat3Hl
|
||||
UPhydoZTAgMBAAECggEAVD60NlLYduXzVNfDtVuHEFNGOjSOYfepc/V8gLubo6lr
|
||||
IMAAI7rcnpYUM5cU8x0OQfRyR8wzUdSWxfWzBs6R78PSZoRzIcgeIl7Wzn0/g3BS
|
||||
To5czuxwqgBKQAFZpPQmZDwcJfr5qqxAn8IvFweCoMqiRlhELcvqDIP0XxWBqDjc
|
||||
TNJ988XzZXQmJbjjpWOkUBy2Uqz8lZt8MmxKFpW7SW4tBJwPphnorgjWfjCV/VEh
|
||||
ORio0rG74NHFo4f1TSrdU2BcB2cbVJ4B+bcUYRdvYmS5bmokhGF8vir0l43gUEdz
|
||||
Fyk6MaPrTI6cinqzenm3q/0eRvNhBE56U0tiGLn14QKBgQDkCkt1Y4LEboSwsVYl
|
||||
IXriStqj9p9MOizihh0enhzRXTTQuLX82fNi+bh1LAluwv290Q57pvKa+hB/YciB
|
||||
o4s7QfSojxQY9DxqvXN7CvxPWXHTyFY5sL4Rm807+C/a9rd39MxBynz9u/7YRvsA
|
||||
s8v8Y/01qIHnTo+mpDvu6HttWwKBgQDFwdRkgstuE+dXZZe8g1ivh3RNPa968TE3
|
||||
b8rzF9/nOJV7f6B/n6YEmHD/cHF5mm1bR+zt/jtf1NCRMpazchw3vT3JzQZYMDnM
|
||||
SD6vxTs5rG47QLiNyTIRmmD4gsEWBpyvoyP8E/9QdfDT1bWI5zZnky9CquRlN+cu
|
||||
J1bTsefEaQKBgGJsRxFNd91MThztDV9NSfptkFyAT1TZLxI+DEdwusNqVSdY8cNG
|
||||
VpP7cC+yaAfURSwuFPAtqDxXfdNc4uuBKNDUsMInrubuUz1Gs5cBsNCWrFhZ+U1B
|
||||
CWgUNMqTXiRFo/40PAyRVs003NOAH0m4UGyIw3rrVdX9xGaKMAv3b35NAoGATkkl
|
||||
I4UDs1f9xQNaxi3Y9ePRjqJUzX6d1SxUU1eoM4ia5IDpsJwqxLb0RKrmwRT5JaGb
|
||||
kbuLFazRxCkar38E3Kv1weWAFXlB6DTRXBPgFjzEhoBgjwCO6ZkLulVIysdjT8Rt
|
||||
gmUINXn7FGENtFyTlP0XQHUWZVt0ETlRjgxni8ECgYBYv6MoSr0iPjQpxeKvwFDz
|
||||
d9zE+ZXN+3GwtkI340lKRSc/f0Uq1TlC2w+DzjyyXcrBwubMQKTKcQQSH9f3YbMu
|
||||
DuxVE9AXdlQ1gSQHGjS0qUWwsS/8Xcjk8ZuduAXPGr/MsvsW+FbbZqG8qdZTeMHu
|
||||
MSTpOxu9HXC8SHML+y0cpw==
|
||||
-----END PRIVATE KEY-----
|
|
@ -0,0 +1,150 @@
|
|||
subject=
|
||||
issuer= C = US, ST = California, L = Cupertino, O = Apple Inc., OU = FDB Team, CN = FDB LibTLS Plugin Test Intermediate CA 1
|
||||
subject= C = US, ST = California, L = Cupertino, O = Apple Inc., OU = FDB Team, CN = FDB LibTLS Plugin Test Intermediate CA 1
|
||||
issuer= C = US, ST = California, L = Cupertino, O = Apple Inc., OU = FDB Team, CN = FDB LibTLS Plugin Test Root CA
|
||||
subject= C = US, ST = California, L = Cupertino, O = Apple Inc., OU = FDB Team, CN = FDB LibTLS Plugin Test Root CA
|
||||
issuer= C = US, ST = California, L = Cupertino, O = Apple Inc., OU = FDB Team, CN = FDB LibTLS Plugin Test Root CA
|
||||
Certificate:
|
||||
Data:
|
||||
Version: 1 (0x0)
|
||||
Serial Number: 1048578 (0x100002)
|
||||
Signature Algorithm: sha256WithRSAEncryption
|
||||
Issuer: C=US, ST=California, L=Cupertino, O=Apple Inc., OU=FDB Team, CN=FDB LibTLS Plugin Test Intermediate CA 1
|
||||
Validity
|
||||
Not Before: Jan 1 00:00:00 2017 GMT
|
||||
Not After : Dec 31 00:00:00 2017 GMT
|
||||
Subject:
|
||||
Subject Public Key Info:
|
||||
Public Key Algorithm: rsaEncryption
|
||||
Public-Key: (2048 bit)
|
||||
Modulus:
|
||||
00:e4:6f:67:4b:e7:d2:1b:0a:ec:f8:92:ae:1e:d4:
|
||||
e9:00:6b:47:83:ad:4e:9e:e2:cc:52:b0:8a:04:46:
|
||||
57:1f:f7:32:37:cc:f0:cd:ec:c0:b9:b9:27:b4:19:
|
||||
33:a1:21:a7:4c:a2:6c:c7:56:31:c4:6a:4f:5f:fb:
|
||||
92:6c:22:8f:c4:eb:3f:d1:2b:06:c7:7b:6b:90:83:
|
||||
37:d3:59:1c:c0:da:de:85:a1:dc:e6:9d:e1:d8:fc:
|
||||
6f:d4:c0:b4:6e:37:3d:d2:d7:4e:4e:04:09:6a:fb:
|
||||
9f:d3:cf:b1:80:db:7a:78:97:65:e1:bc:8d:5a:fa:
|
||||
ec:b1:b6:ee:3f:c9:03:83:ab:0a:9a:8e:03:29:88:
|
||||
42:14:50:80:11:a7:d5:2d:87:c8:bd:25:32:9e:55:
|
||||
fb:22:ef:9c:64:a8:a4:62:3b:d6:86:43:1a:22:a3:
|
||||
1c:4b:ee:af:30:70:d3:9c:aa:da:b6:87:61:78:87:
|
||||
32:0c:0b:b7:44:16:9b:44:1b:4e:6d:f3:98:99:f8:
|
||||
ed:ae:41:02:5d:52:9a:98:49:c3:24:24:0b:18:7b:
|
||||
bf:40:ce:37:65:0f:32:0c:1c:5a:47:4b:b0:3f:db:
|
||||
17:b6:89:68:99:3c:0e:70:84:92:5c:33:cb:6d:2e:
|
||||
67:c8:af:47:41:87:bd:37:87:88:00:65:1f:7e:7b:
|
||||
d9:09
|
||||
Exponent: 65537 (0x10001)
|
||||
Signature Algorithm: sha256WithRSAEncryption
|
||||
0b:5a:f7:7e:e5:93:4b:25:dc:01:eb:20:37:cb:bd:a9:71:3a:
|
||||
af:6d:73:d9:9e:3c:8b:5c:6d:74:45:76:72:02:64:7e:e6:41:
|
||||
bf:29:d7:cd:f8:a7:2d:87:32:6d:25:3f:14:11:2b:95:5a:2e:
|
||||
a8:8b:ba:b1:f9:52:79:b4:5b:ea:fe:b0:ee:b0:9c:14:53:ba:
|
||||
5d:64:aa:b9:d9:ca:17:b2:99:da:34:18:31:56:83:d9:21:8f:
|
||||
20:9e:6a:7f:09:41:2f:36:fa:ab:e7:d1:6c:76:50:d4:51:69:
|
||||
b9:93:ae:9a:eb:8a:6f:a9:91:21:58:a9:3d:53:e8:c1:2c:6f:
|
||||
88:25:65:03:8a:90:9c:8e:58:5d:9a:e2:67:8e:6a:f6:11:19:
|
||||
24:8d:89:b7:11:5e:a8:dc:21:35:7a:9a:78:8a:94:c2:29:84:
|
||||
bb:b7:a5:8e:04:79:dc:db:9d:d7:a7:a3:b7:39:e6:c3:a5:be:
|
||||
83:ad:59:3a:ee:ea:4a:8a:bd:6e:71:c9:e4:a7:46:d5:a3:fd:
|
||||
a0:b1:a3:54:8d:bc:01:fb:68:4c:5a:a2:f5:79:44:f7:b9:e9:
|
||||
7b:db:91:91:74:5b:68:f6:3a:b2:70:ee:e6:49:f4:f1:a6:53:
|
||||
66:13:ce:2f:9e:88:45:66:34:ae:fc:0d:14:02:6f:6a:c9:ac:
|
||||
b5:3f:89:bc
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIDCDCCAfACAxAAAjANBgkqhkiG9w0BAQsFADCBkTELMAkGA1UEBhMCVVMxEzAR
|
||||
BgNVBAgMCkNhbGlmb3JuaWExEjAQBgNVBAcMCUN1cGVydGlubzETMBEGA1UECgwK
|
||||
QXBwbGUgSW5jLjERMA8GA1UECwwIRkRCIFRlYW0xMTAvBgNVBAMMKEZEQiBMaWJU
|
||||
TFMgUGx1Z2luIFRlc3QgSW50ZXJtZWRpYXRlIENBIDEwHhcNMTcwMTAxMDAwMDAw
|
||||
WhcNMTcxMjMxMDAwMDAwWjAAMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC
|
||||
AQEA5G9nS+fSGwrs+JKuHtTpAGtHg61OnuLMUrCKBEZXH/cyN8zwzezAubkntBkz
|
||||
oSGnTKJsx1YxxGpPX/uSbCKPxOs/0SsGx3trkIM301kcwNrehaHc5p3h2Pxv1MC0
|
||||
bjc90tdOTgQJavuf08+xgNt6eJdl4byNWvrssbbuP8kDg6sKmo4DKYhCFFCAEafV
|
||||
LYfIvSUynlX7Iu+cZKikYjvWhkMaIqMcS+6vMHDTnKratodheIcyDAu3RBabRBtO
|
||||
bfOYmfjtrkECXVKamEnDJCQLGHu/QM43ZQ8yDBxaR0uwP9sXtolomTwOcISSXDPL
|
||||
bS5nyK9HQYe9N4eIAGUffnvZCQIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQALWvd+
|
||||
5ZNLJdwB6yA3y72pcTqvbXPZnjyLXG10RXZyAmR+5kG/KdfN+KcthzJtJT8UESuV
|
||||
Wi6oi7qx+VJ5tFvq/rDusJwUU7pdZKq52coXspnaNBgxVoPZIY8gnmp/CUEvNvqr
|
||||
59FsdlDUUWm5k66a64pvqZEhWKk9U+jBLG+IJWUDipCcjlhdmuJnjmr2ERkkjYm3
|
||||
EV6o3CE1epp4ipTCKYS7t6WOBHnc253Xp6O3OebDpb6DrVk67upKir1uccnkp0bV
|
||||
o/2gsaNUjbwB+2hMWqL1eUT3uel725GRdFto9jqycO7mSfTxplNmE84vnohFZjSu
|
||||
/A0UAm9qyay1P4m8
|
||||
-----END CERTIFICATE-----
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIEADCCAuigAwIBAgIJALOPTrQGpeshMA0GCSqGSIb3DQEBBQUAMIGHMQswCQYD
|
||||
VQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTESMBAGA1UEBwwJQ3VwZXJ0aW5v
|
||||
MRMwEQYDVQQKDApBcHBsZSBJbmMuMREwDwYDVQQLDAhGREIgVGVhbTEnMCUGA1UE
|
||||
AwweRkRCIExpYlRMUyBQbHVnaW4gVGVzdCBSb290IENBMB4XDTE4MDQwNzE0MTYw
|
||||
MVoXDTI4MDQwNDE0MTYwMVowgZExCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxp
|
||||
Zm9ybmlhMRIwEAYDVQQHDAlDdXBlcnRpbm8xEzARBgNVBAoMCkFwcGxlIEluYy4x
|
||||
ETAPBgNVBAsMCEZEQiBUZWFtMTEwLwYDVQQDDChGREIgTGliVExTIFBsdWdpbiBU
|
||||
ZXN0IEludGVybWVkaWF0ZSBDQSAxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
|
||||
CgKCAQEAyOwdOcYcH3wYou13CchsXh3lLWA85E550tT6/WwDnslQjiMZHFrKvUT2
|
||||
B8CUOR3Fr+4RG+cdw80rgojYEUuHKwmIGyjo5IotdaYbWzf6mvYThlIPPudCCkSU
|
||||
CTtqPv8Oq4QdIpCxHdix0MINKu7c+qt1rUwnDFQSv/gHhVnNxT4r8pwVp6T4hwka
|
||||
2YQaRNjzUuuFinMub0UtxnUX0rH8X5STlOSVn4Ksjo0OhQzsGEYDx86jVAXjgGcb
|
||||
2CgGGctgq04hVrngP5ahT1Xeh9YycMlQJXsckJJBxfUJebIjANSRyzxI5fYt+ZkY
|
||||
qoG5VLPREUQknxcpbT7Rsj0n+k0RhwIDAQABo2MwYTAdBgNVHQ4EFgQUJdMXt/zc
|
||||
d3vGb2BH47hCu+M2jxAwHwYDVR0jBBgwFoAUnqtGja3O5jGlh5vHgp3Tf8NCPKkw
|
||||
DwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQEFBQAD
|
||||
ggEBAGwW7bRqB7aYUGsD1MOE9d5slp6Iw6wKyNLdg+mzoV+iCV2ZM7ejNRButiAy
|
||||
vPOxSQwXcibLm/g599e+LY1TiI1XXPbL2bFnTcnThqpHHFe+eRrDgqxO8qJyrcBp
|
||||
EfyMCJWq7jFg4bWoYTpLeC/RAKyi9fxlqY1NzQCp1bG3LiaDJ5VJd4uwkgX2a0yN
|
||||
3e0XEFNi7r4u4IHejwFjKWrDg8sstjbY+XOYC4EVQyUsbzeKZKSqnOdR2Jv1QZHH
|
||||
5O24G/efIFpsA6MVUOfRk0eq0RfKX7CdHn2a5p8aC6E6YMDhXL6xo146n49t9sYD
|
||||
HMUnfG6AEboTBa/l+zwCG/u4f/Y=
|
||||
-----END CERTIFICATE-----
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIID9jCCAt6gAwIBAgIJALfRa36cuemYMA0GCSqGSIb3DQEBCwUAMIGHMQswCQYD
|
||||
VQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTESMBAGA1UEBwwJQ3VwZXJ0aW5v
|
||||
MRMwEQYDVQQKDApBcHBsZSBJbmMuMREwDwYDVQQLDAhGREIgVGVhbTEnMCUGA1UE
|
||||
AwweRkRCIExpYlRMUyBQbHVnaW4gVGVzdCBSb290IENBMB4XDTE4MDQwNzE0MTYw
|
||||
MVoXDTI4MDQwNDE0MTYwMVowgYcxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxp
|
||||
Zm9ybmlhMRIwEAYDVQQHDAlDdXBlcnRpbm8xEzARBgNVBAoMCkFwcGxlIEluYy4x
|
||||
ETAPBgNVBAsMCEZEQiBUZWFtMScwJQYDVQQDDB5GREIgTGliVExTIFBsdWdpbiBU
|
||||
ZXN0IFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC/J+sL
|
||||
7POoXNdzYRsMZCI5juxMPOVue5vU2QPU9z/PHBsBICX6tVsCnkzk5CLdM6TxofgX
|
||||
F+MqRKxtcIqxBcKjjVecJlqHuNY+jS2r8UjcoQm+EQ5RsBWu8yaSnXIiZTccQNjB
|
||||
5T2awwt9Ptbn946MZfq6oEnn4ZPByu9/nCrlk7QXTkuGdpTnC6paQWt/lVxZfELM
|
||||
i0g76/K/f3e2Lv9UCvlxKOwFMye9XjwF3ekEmUuio5JZEdn+LIs9zB1zehFhGlYB
|
||||
TUXnkZ0LTOPbH9OxsOli04n31/n7UbYq1BSuoiXx5A2eHOunMppa0NDg7oXmDSKE
|
||||
A1zo+QtIu1YPXaLdAgMBAAGjYzBhMB0GA1UdDgQWBBSeq0aNrc7mMaWHm8eCndN/
|
||||
w0I8qTAfBgNVHSMEGDAWgBSeq0aNrc7mMaWHm8eCndN/w0I8qTAPBgNVHRMBAf8E
|
||||
BTADAQH/MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAQEAIOw1jC39
|
||||
VW+1fqGT+n44Y6Oh66lAowIvi/BEOW1I4iPAjkr0g6FbbdKeq0VLL7aMMu+q/AOv
|
||||
UETv7MdVh9xjTLqWZGN0R3Lr/n6ButI3E7MLKL5ByLNCoOhF42aBLINkpKSNFRrQ
|
||||
40iNoHm3BaNRLKS7poCk5HFkEMjvxdQ1AenNbUa21DTh7y9arHF4CPfi8Ity29jW
|
||||
ED8jYK/+bWIaO+YhGkRh8UuD3o5WnOti+9QK56qxkPtkqVTh9vMVHfD0DgVeLvMN
|
||||
nZpTplLTfhjzyFJELwE/U+HJ6KIslmqwarJ1Sla+1gHCmJEbzbsrnb6bLtrHtXCZ
|
||||
XvmR6B5iRkDVpw==
|
||||
-----END CERTIFICATE-----
|
||||
-----BEGIN PRIVATE KEY-----
|
||||
MIIEwAIBADANBgkqhkiG9w0BAQEFAASCBKowggSmAgEAAoIBAQDkb2dL59IbCuz4
|
||||
kq4e1OkAa0eDrU6e4sxSsIoERlcf9zI3zPDN7MC5uSe0GTOhIadMomzHVjHEak9f
|
||||
+5JsIo/E6z/RKwbHe2uQgzfTWRzA2t6FodzmneHY/G/UwLRuNz3S105OBAlq+5/T
|
||||
z7GA23p4l2XhvI1a+uyxtu4/yQODqwqajgMpiEIUUIARp9Uth8i9JTKeVfsi75xk
|
||||
qKRiO9aGQxoioxxL7q8wcNOcqtq2h2F4hzIMC7dEFptEG05t85iZ+O2uQQJdUpqY
|
||||
ScMkJAsYe79AzjdlDzIMHFpHS7A/2xe2iWiZPA5whJJcM8ttLmfIr0dBh703h4gA
|
||||
ZR9+e9kJAgMBAAECggEBAKC87x+PQN18g6CpfdH+GPINiuXR9ieBCSsKRCOb50R7
|
||||
6Z8wGyWbeUV2TsTAkv7HsnQPOqHNOfmuoKm2WKK0cxuqOV6SexO0+cxXONoDs2LU
|
||||
342ChvDTmY7YmkxHSO7g+iS5EcV9u67G3gDp/Unhpjzis3Ly/ThOpmyqftztMgbb
|
||||
6KKfgGi3VL+fZ2x8gQt0II2QcO6GIzrPcn9ruEM6tXJhQ50YaSCeCmseKBvKuWPW
|
||||
b/Gj7wgYhsiMW+nt8QjVam99eCQ6Q94CsapWRdGpj1Nrd4ISREbqr8x4fmcbiSO6
|
||||
6HZyUidxZIxr2Y4/BTd/BiIqXXdKAMoCVElmyE09P4ECgYEA9IkOkHq1jDLAmppd
|
||||
fNSC/ndmITS0imvwzTTubXKOTn3yZHVxk2/ld83aauGA3UwAueW4Hh0hJdIWqC0d
|
||||
IyaNj3EhcVbidyYwvXdChlPuQ1uccu/earhzsbaFwqNoLVgMrPcB5QcMKUs2/s4Q
|
||||
tBXOqNlFjDZ+bkHQyGXtFYJzknECgYEA7yUcJqf2jB5e4LWG4Se4zD1E/ccZH3t8
|
||||
nhuXa6nDsx2trZBknHpQmc85WzbBITD+LRaamlYpnB1Ueiyr7/Efamtls7NvnoQN
|
||||
14cNFnnj5HooTHJHgNBuL/M3hr/q8uK4lR6bu/DOfzUfRGowX3pj+POB01ObPdm8
|
||||
BUTFwmfJTBkCgYEAkakqccmGZxK8Q9t7oKX9uZJp1ZHNkT6m27WR6MP6HKtNPaXv
|
||||
l4Fp0KlgV5Yn6qohLJq3x8hWPG8ea+MjnhKS9ETRRPAaShsHoXRuvhE0tg7V7GkR
|
||||
tcRVtiAhIUWxAoGWW1lvWXuPNPHGupUIwhzTUyTJFrJHMWom8Zg1V0CzkyECgYEA
|
||||
0JpPXwzejEUlv9+4owhyM34ygyg8KvEduBEbWWfBdKmryR2OFczAKBrRzlYJy3kg
|
||||
DpaMD5qfOzV+bgAvjuKG496A3WrlL6HDLUD50qRKfQ9tvZll8+BcbWk8A0e/m1TX
|
||||
bARCFoOsrNvaxWPXhEGPmSZYFc31OdOHJhViZ/z+Y2kCgYEAphx6cPXLMcgv0ivj
|
||||
SgIG09vo3hGA5r06FkLtGL677CTvYsk/Equ5TkG0AIJ0acY9wiabk6zyM/9XjRAp
|
||||
Nf8qYzhaMxJiyw+JEXmud4Dc41DqjGm9bLV4tKSR+7xzPBP9Q/QLxfRvArBOKhiX
|
||||
L5fWmM5SQAoHsf124DTKckNirLI=
|
||||
-----END PRIVATE KEY-----
|
|
@ -0,0 +1,101 @@
|
|||
subject=
|
||||
issuer= C = US, ST = California, L = Cupertino, O = Apple Inc., OU = FDB Team, CN = FDB LibTLS Plugin Test Intermediate CA 1
|
||||
subject= C = US, ST = California, L = Cupertino, O = Apple Inc., OU = FDB Team, CN = FDB LibTLS Plugin Test Intermediate CA 1
|
||||
issuer= C = US, ST = California, L = Cupertino, O = Apple Inc., OU = FDB Team, CN = FDB LibTLS Plugin Test Root CA
|
||||
subject= C = US, ST = California, L = Cupertino, O = Apple Inc., OU = FDB Team, CN = FDB LibTLS Plugin Test Root CA
|
||||
issuer= C = US, ST = California, L = Cupertino, O = Apple Inc., OU = FDB Team, CN = FDB LibTLS Plugin Test Root CA
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIDCDCCAfACAxAAATANBgkqhkiG9w0BAQsFADCBkTELMAkGA1UEBhMCVVMxEzAR
|
||||
BgNVBAgMCkNhbGlmb3JuaWExEjAQBgNVBAcMCUN1cGVydGlubzETMBEGA1UECgwK
|
||||
QXBwbGUgSW5jLjERMA8GA1UECwwIRkRCIFRlYW0xMTAvBgNVBAMMKEZEQiBMaWJU
|
||||
TFMgUGx1Z2luIFRlc3QgSW50ZXJtZWRpYXRlIENBIDEwHhcNMTcwMTAxMDAwMDAw
|
||||
WhcNMTcxMjMxMDAwMDAwWjAAMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC
|
||||
AQEA43+uFNDYKXQQ4fmSencxdm/mfM6FAlGwRBWotptutznfH0N+ulp5RhjRcbGb
|
||||
AHwPOBBNEBSIV3LhdPXep3NcmSkfaMdnPEgrurI0DLYbxZryEXdJZyoueT+w4TNx
|
||||
I5mNlZDKD5bH5rhV/dUAmK/+LpWuxWraWYaHBZBsuqpb0MF6IZJAN9Ve9JiKHeiY
|
||||
6ecz/o9XIrFFeWKMncHwBV1taPPoG2Ksjv8UlqqehrYXG+md958MXf69dkuQJLCS
|
||||
rojPOkhUroixvGiXJBRSFCyVhQxPCLyASsEv8qPEKMUiW4oY3w5R9RQmw97AHlA1
|
||||
7xB4mGZTZEjUIOYDdd8LyuRpawIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQAHMAsm
|
||||
zLtFnDaYaOgJdPpi9VAUkZpbSXcA3a02PzOvLN9VV1Fogf1+F0zYFlWbiYGIwcI4
|
||||
3YfuFr97/e0uEQd6pwGc8/a63q+CunGz+HPStWZm+2ZgmJhBH6i1RwmhA9rH6rGK
|
||||
j2UghYIYT83gn6S2XSfUwzV8gCw+JjJwczcjGpOf9dRCAEsRDcRwUX7rI16cE2tZ
|
||||
SLzYB/Kg3wSnUXTKXRJfg6VbVRPFXHQlRYpOxe2z5LWoTEo2uYuHgYO+DzSO9pEj
|
||||
WgyKBwcc+L3zIZFYCqc9EN//QrLlXsiwSDVMvtzVnzvIQKcGF7OE22NyojTaMzQL
|
||||
2h8UA9W0Mew5PTSl
|
||||
-----END CERTIFICATE-----
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIEADCCAuigAwIBAgIJALOPTrQGpeshMA0GCSqGSIb3DQEBBQUAMIGHMQswCQYD
|
||||
VQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTESMBAGA1UEBwwJQ3VwZXJ0aW5v
|
||||
MRMwEQYDVQQKDApBcHBsZSBJbmMuMREwDwYDVQQLDAhGREIgVGVhbTEnMCUGA1UE
|
||||
AwweRkRCIExpYlRMUyBQbHVnaW4gVGVzdCBSb290IENBMB4XDTE4MDQwNzE0MTYw
|
||||
MVoXDTI4MDQwNDE0MTYwMVowgZExCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxp
|
||||
Zm9ybmlhMRIwEAYDVQQHDAlDdXBlcnRpbm8xEzARBgNVBAoMCkFwcGxlIEluYy4x
|
||||
ETAPBgNVBAsMCEZEQiBUZWFtMTEwLwYDVQQDDChGREIgTGliVExTIFBsdWdpbiBU
|
||||
ZXN0IEludGVybWVkaWF0ZSBDQSAxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
|
||||
CgKCAQEAyOwdOcYcH3wYou13CchsXh3lLWA85E550tT6/WwDnslQjiMZHFrKvUT2
|
||||
B8CUOR3Fr+4RG+cdw80rgojYEUuHKwmIGyjo5IotdaYbWzf6mvYThlIPPudCCkSU
|
||||
CTtqPv8Oq4QdIpCxHdix0MINKu7c+qt1rUwnDFQSv/gHhVnNxT4r8pwVp6T4hwka
|
||||
2YQaRNjzUuuFinMub0UtxnUX0rH8X5STlOSVn4Ksjo0OhQzsGEYDx86jVAXjgGcb
|
||||
2CgGGctgq04hVrngP5ahT1Xeh9YycMlQJXsckJJBxfUJebIjANSRyzxI5fYt+ZkY
|
||||
qoG5VLPREUQknxcpbT7Rsj0n+k0RhwIDAQABo2MwYTAdBgNVHQ4EFgQUJdMXt/zc
|
||||
d3vGb2BH47hCu+M2jxAwHwYDVR0jBBgwFoAUnqtGja3O5jGlh5vHgp3Tf8NCPKkw
|
||||
DwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQEFBQAD
|
||||
ggEBAGwW7bRqB7aYUGsD1MOE9d5slp6Iw6wKyNLdg+mzoV+iCV2ZM7ejNRButiAy
|
||||
vPOxSQwXcibLm/g599e+LY1TiI1XXPbL2bFnTcnThqpHHFe+eRrDgqxO8qJyrcBp
|
||||
EfyMCJWq7jFg4bWoYTpLeC/RAKyi9fxlqY1NzQCp1bG3LiaDJ5VJd4uwkgX2a0yN
|
||||
3e0XEFNi7r4u4IHejwFjKWrDg8sstjbY+XOYC4EVQyUsbzeKZKSqnOdR2Jv1QZHH
|
||||
5O24G/efIFpsA6MVUOfRk0eq0RfKX7CdHn2a5p8aC6E6YMDhXL6xo146n49t9sYD
|
||||
HMUnfG6AEboTBa/l+zwCG/u4f/Y=
|
||||
-----END CERTIFICATE-----
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIID9jCCAt6gAwIBAgIJALfRa36cuemYMA0GCSqGSIb3DQEBCwUAMIGHMQswCQYD
|
||||
VQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTESMBAGA1UEBwwJQ3VwZXJ0aW5v
|
||||
MRMwEQYDVQQKDApBcHBsZSBJbmMuMREwDwYDVQQLDAhGREIgVGVhbTEnMCUGA1UE
|
||||
AwweRkRCIExpYlRMUyBQbHVnaW4gVGVzdCBSb290IENBMB4XDTE4MDQwNzE0MTYw
|
||||
MVoXDTI4MDQwNDE0MTYwMVowgYcxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxp
|
||||
Zm9ybmlhMRIwEAYDVQQHDAlDdXBlcnRpbm8xEzARBgNVBAoMCkFwcGxlIEluYy4x
|
||||
ETAPBgNVBAsMCEZEQiBUZWFtMScwJQYDVQQDDB5GREIgTGliVExTIFBsdWdpbiBU
|
||||
ZXN0IFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC/J+sL
|
||||
7POoXNdzYRsMZCI5juxMPOVue5vU2QPU9z/PHBsBICX6tVsCnkzk5CLdM6TxofgX
|
||||
F+MqRKxtcIqxBcKjjVecJlqHuNY+jS2r8UjcoQm+EQ5RsBWu8yaSnXIiZTccQNjB
|
||||
5T2awwt9Ptbn946MZfq6oEnn4ZPByu9/nCrlk7QXTkuGdpTnC6paQWt/lVxZfELM
|
||||
i0g76/K/f3e2Lv9UCvlxKOwFMye9XjwF3ekEmUuio5JZEdn+LIs9zB1zehFhGlYB
|
||||
TUXnkZ0LTOPbH9OxsOli04n31/n7UbYq1BSuoiXx5A2eHOunMppa0NDg7oXmDSKE
|
||||
A1zo+QtIu1YPXaLdAgMBAAGjYzBhMB0GA1UdDgQWBBSeq0aNrc7mMaWHm8eCndN/
|
||||
w0I8qTAfBgNVHSMEGDAWgBSeq0aNrc7mMaWHm8eCndN/w0I8qTAPBgNVHRMBAf8E
|
||||
BTADAQH/MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAQEAIOw1jC39
|
||||
VW+1fqGT+n44Y6Oh66lAowIvi/BEOW1I4iPAjkr0g6FbbdKeq0VLL7aMMu+q/AOv
|
||||
UETv7MdVh9xjTLqWZGN0R3Lr/n6ButI3E7MLKL5ByLNCoOhF42aBLINkpKSNFRrQ
|
||||
40iNoHm3BaNRLKS7poCk5HFkEMjvxdQ1AenNbUa21DTh7y9arHF4CPfi8Ity29jW
|
||||
ED8jYK/+bWIaO+YhGkRh8UuD3o5WnOti+9QK56qxkPtkqVTh9vMVHfD0DgVeLvMN
|
||||
nZpTplLTfhjzyFJELwE/U+HJ6KIslmqwarJ1Sla+1gHCmJEbzbsrnb6bLtrHtXCZ
|
||||
XvmR6B5iRkDVpw==
|
||||
-----END CERTIFICATE-----
|
||||
-----BEGIN PRIVATE KEY-----
|
||||
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDjf64U0NgpdBDh
|
||||
+ZJ6dzF2b+Z8zoUCUbBEFai2m263Od8fQ366WnlGGNFxsZsAfA84EE0QFIhXcuF0
|
||||
9d6nc1yZKR9ox2c8SCu6sjQMthvFmvIRd0lnKi55P7DhM3EjmY2VkMoPlsfmuFX9
|
||||
1QCYr/4ula7FatpZhocFkGy6qlvQwXohkkA31V70mIod6Jjp5zP+j1cisUV5Yoyd
|
||||
wfAFXW1o8+gbYqyO/xSWqp6Gthcb6Z33nwxd/r12S5AksJKuiM86SFSuiLG8aJck
|
||||
FFIULJWFDE8IvIBKwS/yo8QoxSJbihjfDlH1FCbD3sAeUDXvEHiYZlNkSNQg5gN1
|
||||
3wvK5GlrAgMBAAECggEAAVjMKwthfD1XrD7SAy+Zd14KO0rttqnNJVoLealJ6oPJ
|
||||
MmIv6eKHPUcAVm/6vvH9FRPjoOi+NeZUN2ENRGiGb9GygehMUCsNNzm+3SRm3bCh
|
||||
JkFSie3SAJ3D6lFnphJOqEgHKjh2ToNg3vPX4Q+JrbTtJ/YN/OGzAvFr81721DGO
|
||||
L7Hs6foBHKrLeibbguVRdc5zc/WtWjGPFhNAmR9qincM3Q9DrUUHjbJzTS1UXDVT
|
||||
zssTUTZe9TLd4buqHjLLfmiPoTV8qzv5l4RwkmuuLIT+5mO7X41glwdOkBfk+Cum
|
||||
BZjrjgTDXbqLNXjMsvXkG1hCZQ6qwdT4GINYlYSiQQKBgQD4pJf7xLaX53rj+LDc
|
||||
HY3TbWDdyS7h7cq4ZoKa1xPt4Va3xIAIst20edTr6tBYtNygjFZwIkPFYGwdGKVK
|
||||
CqbpzTxVl8p5I3uoUmIFDo8hX7ChLC928K9lfD62agU85ZfP9Vly4zvDG2sIvxpw
|
||||
HUY/96VhdSG3fssWYvg3dYUGCQKBgQDqOuyrcTHaZujFMN+MIuUExgYOMS0R0O4T
|
||||
zCMtWIEkjntSk4CBMsHSb/dZH3CbFB90GjS+WklfTBd6kZ8tBO35vtM6nz5NPCEr
|
||||
2umqJR5hijHV2tB98qV9qJttJrH/z0VKuuZBa14S1rJwGpX9ZoOULwcOGK3VC9pQ
|
||||
YnH7Wdjw0wKBgFtBZXqE7xL/ZS4IVzjiK+xeJ4Ae13MaKB3XmbWknG7hFkep+ee3
|
||||
ZgFX+ZqAeukjsBnIh+zt1nu5cNSY+Akdsbb7mVo8tJYTPM5BNjJu7n8sNJJiuiTo
|
||||
HyebGxUuAjAgf8BWZvbwiT2JcZYrNVPSmrbdeDg1miNTiMv1lO4d1q2pAoGBANq8
|
||||
oFwSX24IAIR1+a2SwLDOhMUoI2Cp7ktKrecg6alL7drVqIH+9oYgzarK84u/JQh1
|
||||
mJ/TDQYTtzFdYHrYSaybCgOKxtG1v3yG+QNNmquYNKXzrBSSTv2kQVGTe1LbK2h4
|
||||
VaLuM3IAUa7jBQMZgvMVX89IOL3mTcAXzz3dT/zFAoGBAI/pVbABfPihWZ1MrmTN
|
||||
pnRmQ0461J0WGT+fIgAPR+R+umckHaOVAGiSQomfNrUBbsydoZYu/by7GhIGsDeO
|
||||
8XKwEP/HLRrABvZu4KLTxa+qTnW/t6BSIfFwQmrNMofxcFRbdzNAODKjyaJG2dqT
|
||||
ksg9s2SxReRrGOeb43CAw5SC
|
||||
-----END PRIVATE KEY-----
|
|
@ -0,0 +1,80 @@
|
|||
subject= C = US, ST = California, L = Cupertino, O = Apple Inc., OU = FDB Team, CN = FDB LibTLS Plugin Test Client 1
|
||||
issuer= C = US, ST = California, L = Cupertino, O = Apple Inc., OU = FDB Team, CN = FDB LibTLS Plugin Test Intermediate CA 1
|
||||
subject= C = US, ST = California, L = Cupertino, O = Apple Inc., OU = FDB Team, CN = FDB LibTLS Plugin Test Intermediate CA 1
|
||||
issuer= C = US, ST = California, L = Cupertino, O = Apple Inc., OU = FDB Team, CN = FDB LibTLS Plugin Test Root CA
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIID/jCCAuagAwIBAgIJALOPTrQGpeslMA0GCSqGSIb3DQEBBQUAMIGRMQswCQYD
|
||||
VQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTESMBAGA1UEBwwJQ3VwZXJ0aW5v
|
||||
MRMwEQYDVQQKDApBcHBsZSBJbmMuMREwDwYDVQQLDAhGREIgVGVhbTExMC8GA1UE
|
||||
AwwoRkRCIExpYlRMUyBQbHVnaW4gVGVzdCBJbnRlcm1lZGlhdGUgQ0EgMTAeFw0x
|
||||
ODA0MDcxNDE2MDJaFw0yODA0MDQxNDE2MDJaMIGIMQswCQYDVQQGEwJVUzETMBEG
|
||||
A1UECAwKQ2FsaWZvcm5pYTESMBAGA1UEBwwJQ3VwZXJ0aW5vMRMwEQYDVQQKDApB
|
||||
cHBsZSBJbmMuMREwDwYDVQQLDAhGREIgVGVhbTEoMCYGA1UEAwwfRkRCIExpYlRM
|
||||
UyBQbHVnaW4gVGVzdCBDbGllbnQgMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC
|
||||
AQoCggEBALVkdxOmWcd959NyirJ1iz7q5fkjdRUV+88KMMehQWc3f50GJIQ+eZo+
|
||||
7RhwVE+n8nd0i5iGfyY6LRuupdwoQUxoZ/5rUIDGKspNO62DVRW+tZqzpEa1+ub5
|
||||
75BMoc7I7l9sXDkuiMu1OYcPNKMv4F3mf+B3ourLqjUekKlUv8XIZXAvN+R19HlR
|
||||
FM8vs8rnhQXx7iWVP91frDvyD8G7lOf6R7R4homnB37kLom8WU+fCmcyA6em0qX0
|
||||
JeVP6xk2qXU1cMs7DL8WftdrWHv+a73/l4hytQHo5OvtGaLZhpPYpC/FMSaFHVSM
|
||||
irWSFK+ZtvaLi3LXc2HGANMokjPoRf8CAwEAAaNgMF4wHQYDVR0OBBYEFPtTL9KZ
|
||||
jn49cLediy1ixz7AXOI3MB8GA1UdIwQYMBaAFCXTF7f83Hd7xm9gR+O4QrvjNo8Q
|
||||
MAwGA1UdEwEB/wQCMAAwDgYDVR0PAQH/BAQDAgeAMA0GCSqGSIb3DQEBBQUAA4IB
|
||||
AQA17a4d/tSWIlTkIfkrXziD21+1OsN6/dUrWQK7kxtEe21QXIutccW4bwpM0JDB
|
||||
M+bZiWkdgQ15+ZotX5UXlBcx9WWDU5RqSO06hhXu5b8gZwfVF4Od6tBdVxkn4KbU
|
||||
0YujOZrL8fDOrQHqCO7nhNlYgcEn7bKF5wjtOoiKhtA9sLSIZQR5g32kkJXXGvcY
|
||||
lLWMXygEg9FMQoldW9RHq4GbUiYEeqEq6k4S7cE03R1lvmQEOOAJ2S7LnaS4UHQT
|
||||
GmW6uvLnJJrG4HB9JGE+y1e9M+C7Enzhi39RGd8ylignGimkdw/1UEWnvKGCqoU7
|
||||
ufWGF7eUV8dCqO+jYghIY8rA
|
||||
-----END CERTIFICATE-----
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIEADCCAuigAwIBAgIJALOPTrQGpeshMA0GCSqGSIb3DQEBBQUAMIGHMQswCQYD
|
||||
VQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTESMBAGA1UEBwwJQ3VwZXJ0aW5v
|
||||
MRMwEQYDVQQKDApBcHBsZSBJbmMuMREwDwYDVQQLDAhGREIgVGVhbTEnMCUGA1UE
|
||||
AwweRkRCIExpYlRMUyBQbHVnaW4gVGVzdCBSb290IENBMB4XDTE4MDQwNzE0MTYw
|
||||
MVoXDTI4MDQwNDE0MTYwMVowgZExCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxp
|
||||
Zm9ybmlhMRIwEAYDVQQHDAlDdXBlcnRpbm8xEzARBgNVBAoMCkFwcGxlIEluYy4x
|
||||
ETAPBgNVBAsMCEZEQiBUZWFtMTEwLwYDVQQDDChGREIgTGliVExTIFBsdWdpbiBU
|
||||
ZXN0IEludGVybWVkaWF0ZSBDQSAxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
|
||||
CgKCAQEAyOwdOcYcH3wYou13CchsXh3lLWA85E550tT6/WwDnslQjiMZHFrKvUT2
|
||||
B8CUOR3Fr+4RG+cdw80rgojYEUuHKwmIGyjo5IotdaYbWzf6mvYThlIPPudCCkSU
|
||||
CTtqPv8Oq4QdIpCxHdix0MINKu7c+qt1rUwnDFQSv/gHhVnNxT4r8pwVp6T4hwka
|
||||
2YQaRNjzUuuFinMub0UtxnUX0rH8X5STlOSVn4Ksjo0OhQzsGEYDx86jVAXjgGcb
|
||||
2CgGGctgq04hVrngP5ahT1Xeh9YycMlQJXsckJJBxfUJebIjANSRyzxI5fYt+ZkY
|
||||
qoG5VLPREUQknxcpbT7Rsj0n+k0RhwIDAQABo2MwYTAdBgNVHQ4EFgQUJdMXt/zc
|
||||
d3vGb2BH47hCu+M2jxAwHwYDVR0jBBgwFoAUnqtGja3O5jGlh5vHgp3Tf8NCPKkw
|
||||
DwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQEFBQAD
|
||||
ggEBAGwW7bRqB7aYUGsD1MOE9d5slp6Iw6wKyNLdg+mzoV+iCV2ZM7ejNRButiAy
|
||||
vPOxSQwXcibLm/g599e+LY1TiI1XXPbL2bFnTcnThqpHHFe+eRrDgqxO8qJyrcBp
|
||||
EfyMCJWq7jFg4bWoYTpLeC/RAKyi9fxlqY1NzQCp1bG3LiaDJ5VJd4uwkgX2a0yN
|
||||
3e0XEFNi7r4u4IHejwFjKWrDg8sstjbY+XOYC4EVQyUsbzeKZKSqnOdR2Jv1QZHH
|
||||
5O24G/efIFpsA6MVUOfRk0eq0RfKX7CdHn2a5p8aC6E6YMDhXL6xo146n49t9sYD
|
||||
HMUnfG6AEboTBa/l+zwCG/u4f/Y=
|
||||
-----END CERTIFICATE-----
|
||||
-----BEGIN PRIVATE KEY-----
|
||||
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC1ZHcTplnHfefT
|
||||
coqydYs+6uX5I3UVFfvPCjDHoUFnN3+dBiSEPnmaPu0YcFRPp/J3dIuYhn8mOi0b
|
||||
rqXcKEFMaGf+a1CAxirKTTutg1UVvrWas6RGtfrm+e+QTKHOyO5fbFw5LojLtTmH
|
||||
DzSjL+Bd5n/gd6Lqy6o1HpCpVL/FyGVwLzfkdfR5URTPL7PK54UF8e4llT/dX6w7
|
||||
8g/Bu5Tn+ke0eIaJpwd+5C6JvFlPnwpnMgOnptKl9CXlT+sZNql1NXDLOwy/Fn7X
|
||||
a1h7/mu9/5eIcrUB6OTr7Rmi2YaT2KQvxTEmhR1UjIq1khSvmbb2i4ty13NhxgDT
|
||||
KJIz6EX/AgMBAAECggEAEm2Mc2CZCl1OKfsfABZU+SVgC7mAcY30MQp1/jHxtQy8
|
||||
WDWBjDXUoMj3yV3QEu+bAGvEqtAvJrEOWBucGgu05pBM0FoSqaJ4QmkqQOxwvm7L
|
||||
gFXzwINIZCLMJbrDTYC4RtV5YQ3LM/bLS19OF64Lez6piyJcWMIsHo1mYO2NNgiD
|
||||
7f1x1uQw46Q0YHWeoHY58MPfmgfKsqnJDWc8cCuU9fJOWeU4dVrfW8dh9WVAoLZ7
|
||||
qAM5vvap11Qk8RXaRnmLjxN6H1M7iVNfcLVNKfG6XOBBepYjZr/qMkuN3ONuqBHl
|
||||
fC3Zia2zQZRfiuPspX0KhjCfYAKbIZC6oyrQM2uXgQKBgQDoD5voZiCOeGXJEMUk
|
||||
9JV4V8A96aE0xxy+OHMogVpysxBO4V0Nh0krSLTt9NXnpjawZQ+3pLQ4+2J2XM2e
|
||||
fJuJJ7Z+Mhjv6epnMM7FoxK1VF7oe+LE7Yk/kg/moCuVS/XhLdQrhZVBJhfEADS3
|
||||
oFybf7Q6rJYtN3OYsiFymyneHwKBgQDIGsY5kGdmx27LS5rPMwdw632TF8G5BGbu
|
||||
C3ty7LYkOWb/9/V4cuWjW4eLJQqCWbJQrzOvg0coxwXLUuEQik+IP2IkF0YlRS43
|
||||
VJuULwOxi3Cbj51RoapHhmYTO9fe2A1N9oJMAqEUHY1q/r9txPcguRWyuH2Yv9Ih
|
||||
OzHnc2DcIQKBgQCGW0MxMq/2zM5hs0vxMYq4ulWbgwDKxd1mZNiHwxzS+8mdYe22
|
||||
P3WlkdrvSqnuDNXtGxYWhU2zEBjZ3rFN6WdD6bJHLkox3YTRafjNhLT4N3kbsV6C
|
||||
FeU44SBDrsiNEAWz8gy9hgH8TknEOTpMdpQnk7CNqA7q7wgGiFvFNwDukQKBgG7i
|
||||
R03Gs0XE5aRJtPN0N39fPyqvU24O/mqSekno2dWg6W6WHLQuFwo6whVc5UHuKl2D
|
||||
eISdnmT+RDuzJXxg6El7tgqByyEEAOQwQjYPB2Du/+tz3Z1KlG0mEJI/6xNVbany
|
||||
G6m7Gz9mUOMlXzaYmsjLRzbN/OsUAIDhqHm0+cuBAoGAZCND80akS3xr3yC87GyX
|
||||
aA0RoHXbdB6dbP8Y6XYDXR4QFIA4kXwY5cCLaZA/0hP5FOzDhORmaoaPM8vUdNyb
|
||||
IYvbw2H6tODiU5oICWY6+HQQ2nXikucI4HDYDLbsiV2htZkEmBYWLilYq0Tb8jC5
|
||||
u+ehIIvZYLqKaY1GaKmF86A=
|
||||
-----END PRIVATE KEY-----
|
|
@ -0,0 +1,80 @@
|
|||
subject= C = US, ST = California, L = Cupertino, O = Apple Inc., OU = FDB Team, CN = FDB LibTLS Plugin Test Server 1
|
||||
issuer= C = US, ST = California, L = Cupertino, O = Apple Inc., OU = FDB Team, CN = FDB LibTLS Plugin Test Intermediate CA 1
|
||||
subject= C = US, ST = California, L = Cupertino, O = Apple Inc., OU = FDB Team, CN = FDB LibTLS Plugin Test Intermediate CA 1
|
||||
issuer= C = US, ST = California, L = Cupertino, O = Apple Inc., OU = FDB Team, CN = FDB LibTLS Plugin Test Root CA
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIID/jCCAuagAwIBAgIJALOPTrQGpesjMA0GCSqGSIb3DQEBBQUAMIGRMQswCQYD
|
||||
VQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTESMBAGA1UEBwwJQ3VwZXJ0aW5v
|
||||
MRMwEQYDVQQKDApBcHBsZSBJbmMuMREwDwYDVQQLDAhGREIgVGVhbTExMC8GA1UE
|
||||
AwwoRkRCIExpYlRMUyBQbHVnaW4gVGVzdCBJbnRlcm1lZGlhdGUgQ0EgMTAeFw0x
|
||||
ODA0MDcxNDE2MDJaFw0yODA0MDQxNDE2MDJaMIGIMQswCQYDVQQGEwJVUzETMBEG
|
||||
A1UECAwKQ2FsaWZvcm5pYTESMBAGA1UEBwwJQ3VwZXJ0aW5vMRMwEQYDVQQKDApB
|
||||
cHBsZSBJbmMuMREwDwYDVQQLDAhGREIgVGVhbTEoMCYGA1UEAwwfRkRCIExpYlRM
|
||||
UyBQbHVnaW4gVGVzdCBTZXJ2ZXIgMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC
|
||||
AQoCggEBAJp26QAmlMusO7C8Py/I117r3kHvB+My5kIrj8g9sKpktwTzmsJGpvJU
|
||||
EaKISEdBsJHLGnZJhwIhr/+MG4WDEM4oFNCtBQZznV3wjIQWq1w4IO8/f3+nBPpW
|
||||
f14fjs1E911Uo/ZOL9bxvh1SIHkS6itgJi+tgVPx7C3s3W3mC5nU3omsE+Rx4DDm
|
||||
KUq1kyN1ELBIAceQ4wTmQ5B8dv6MSW7zt8Jdrhfhg2GJIPPB6XUZJ2yIOvgu55GW
|
||||
J5sMPa0uNDfCsWJ37fzFm+XJ/D96t7x8I49IyfzbIgcU9JYFlcqkryvKh5IpQGGm
|
||||
H/I6adIWa5xWpMhB2PA6kgtDD07Hu2sCAwEAAaNgMF4wHQYDVR0OBBYEFJ7S+FUz
|
||||
9ngzH/TNPVeM/cE7LeBGMB8GA1UdIwQYMBaAFCXTF7f83Hd7xm9gR+O4QrvjNo8Q
|
||||
MAwGA1UdEwEB/wQCMAAwDgYDVR0PAQH/BAQDAgeAMA0GCSqGSIb3DQEBBQUAA4IB
|
||||
AQAx6WHwikVFAH0TRYCznwO6He+0t2pnlyfrI+24N28tzupMSrRPs086UbLgHLz1
|
||||
lbkYdheeOkLPzjWi5vfymL1Oua3E2iAXWEpMb4Sg7E5SVHp9yt6gZ0DTVwR+Gcu7
|
||||
uooroidAG3OFeOXL5ivU5J5ipaoEAiLprpKxtPzo4z/TxIqw3kJISC56qw9VTJNQ
|
||||
TQZvneUecykdIZuH61ih0cJLe5WRkEs/63Dgl8TBYiVDbvBSGRbsXoAXcspVlc2x
|
||||
XOLey5IVJ4/TH5ZBobShC6J1KrjZTNYvUgc44CocOgrc0ePPiQzB7JXxR1H8ATGl
|
||||
yKjWqT2PkrfHmjdcmsi2GIVt
|
||||
-----END CERTIFICATE-----
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIEADCCAuigAwIBAgIJALOPTrQGpeshMA0GCSqGSIb3DQEBBQUAMIGHMQswCQYD
|
||||
VQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTESMBAGA1UEBwwJQ3VwZXJ0aW5v
|
||||
MRMwEQYDVQQKDApBcHBsZSBJbmMuMREwDwYDVQQLDAhGREIgVGVhbTEnMCUGA1UE
|
||||
AwweRkRCIExpYlRMUyBQbHVnaW4gVGVzdCBSb290IENBMB4XDTE4MDQwNzE0MTYw
|
||||
MVoXDTI4MDQwNDE0MTYwMVowgZExCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxp
|
||||
Zm9ybmlhMRIwEAYDVQQHDAlDdXBlcnRpbm8xEzARBgNVBAoMCkFwcGxlIEluYy4x
|
||||
ETAPBgNVBAsMCEZEQiBUZWFtMTEwLwYDVQQDDChGREIgTGliVExTIFBsdWdpbiBU
|
||||
ZXN0IEludGVybWVkaWF0ZSBDQSAxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
|
||||
CgKCAQEAyOwdOcYcH3wYou13CchsXh3lLWA85E550tT6/WwDnslQjiMZHFrKvUT2
|
||||
B8CUOR3Fr+4RG+cdw80rgojYEUuHKwmIGyjo5IotdaYbWzf6mvYThlIPPudCCkSU
|
||||
CTtqPv8Oq4QdIpCxHdix0MINKu7c+qt1rUwnDFQSv/gHhVnNxT4r8pwVp6T4hwka
|
||||
2YQaRNjzUuuFinMub0UtxnUX0rH8X5STlOSVn4Ksjo0OhQzsGEYDx86jVAXjgGcb
|
||||
2CgGGctgq04hVrngP5ahT1Xeh9YycMlQJXsckJJBxfUJebIjANSRyzxI5fYt+ZkY
|
||||
qoG5VLPREUQknxcpbT7Rsj0n+k0RhwIDAQABo2MwYTAdBgNVHQ4EFgQUJdMXt/zc
|
||||
d3vGb2BH47hCu+M2jxAwHwYDVR0jBBgwFoAUnqtGja3O5jGlh5vHgp3Tf8NCPKkw
|
||||
DwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQEFBQAD
|
||||
ggEBAGwW7bRqB7aYUGsD1MOE9d5slp6Iw6wKyNLdg+mzoV+iCV2ZM7ejNRButiAy
|
||||
vPOxSQwXcibLm/g599e+LY1TiI1XXPbL2bFnTcnThqpHHFe+eRrDgqxO8qJyrcBp
|
||||
EfyMCJWq7jFg4bWoYTpLeC/RAKyi9fxlqY1NzQCp1bG3LiaDJ5VJd4uwkgX2a0yN
|
||||
3e0XEFNi7r4u4IHejwFjKWrDg8sstjbY+XOYC4EVQyUsbzeKZKSqnOdR2Jv1QZHH
|
||||
5O24G/efIFpsA6MVUOfRk0eq0RfKX7CdHn2a5p8aC6E6YMDhXL6xo146n49t9sYD
|
||||
HMUnfG6AEboTBa/l+zwCG/u4f/Y=
|
||||
-----END CERTIFICATE-----
|
||||
-----BEGIN PRIVATE KEY-----
|
||||
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCadukAJpTLrDuw
|
||||
vD8vyNde695B7wfjMuZCK4/IPbCqZLcE85rCRqbyVBGiiEhHQbCRyxp2SYcCIa//
|
||||
jBuFgxDOKBTQrQUGc51d8IyEFqtcOCDvP39/pwT6Vn9eH47NRPddVKP2Ti/W8b4d
|
||||
UiB5EuorYCYvrYFT8ewt7N1t5guZ1N6JrBPkceAw5ilKtZMjdRCwSAHHkOME5kOQ
|
||||
fHb+jElu87fCXa4X4YNhiSDzwel1GSdsiDr4LueRliebDD2tLjQ3wrFid+38xZvl
|
||||
yfw/ere8fCOPSMn82yIHFPSWBZXKpK8ryoeSKUBhph/yOmnSFmucVqTIQdjwOpIL
|
||||
Qw9Ox7trAgMBAAECggEAOZAMvsCh/NDfobpVddJL6JTPzBRvBQ1H3+rp9z5+ItHL
|
||||
nq3Fw5aeynnn5IETJnLlgT+GSgSWqoWxV/N3oia40YsATs/bqo7VW1e0ldj43TIR
|
||||
m/c25XRxl3U6m/H4vqhv4rkTLUvv6hNGvRiI/3W8DJQVRvlK0+S5FlhKIJV1R0sH
|
||||
tp5vmaPp09Ln+NVno3u3iaYkVgVME4Ukul2i03sQ9OgvZSBCaVr//fMpiPdBeeN6
|
||||
QY6XHjeGQRnP/UdzMYJ4Qz1yovL1ntneaTMdz/GkKuAFoNNh8Vr2kiEskW17OWPB
|
||||
ZGcIT6YpBEPo34xXUhUQt7ylFPxGH+zZyHZ3vb8j6QKBgQDJPeu/iPg+M5nz5gO5
|
||||
ge9gzYrhxK/1mwbFlD7qt1NjOSm6xWxUcss3STjuG7jB0c+NopIUoq/egsUnxrRm
|
||||
4l17uOCYNLbhTJ2ynfv6QnUMxW5Xkve3DkLa2bze/fhMUywTy8N4A7z0+y35qzm3
|
||||
lY4rLmQOQKPkmqWRnxU1u8fjFQKBgQDEfpOZ0fp2D/1gTG+D+/zrMEbjnNn3ZO8I
|
||||
wrjoXwRxcRggt7lJhxgQpwtDr98IqYkDzX7bvyMFJuyTii3NM6NYycpA1pHX70B/
|
||||
xMvOcrgJnIUAoJ7nl43Or7s8bFTPDLaD9PNGHjrlkF3JOXqSKEbw367jHVOa4SYr
|
||||
OjrogjrEfwKBgQDHU2a7ax5+9btqggx0ZQfGOTBzmM60lZ3qe4CqGXUl1YvIrB01
|
||||
tBImq4cRCTJB/9/1qO3KNK2/1oUTddRgB5ySnDcRaz0tASc9sQ/Q/JxVTwSRB0gG
|
||||
78A2Zu6VbLbQWp1Q6kWtDP7PJC+QmRFtDlwn1yZRm6L6HlcaWpi2hU1iVQKBgCEu
|
||||
ashv8Aad3qCzZ6V3GReyOFZZd2lSjxcAou8ClKJ/gZ6Mx+pFuOee/cT5XwV8c5nD
|
||||
yuda2JQXJZ4omGFtlej5coEOeuRnD5JD7lK3hqKA3ujjNtJPAnBjto+Wj5/DOtL/
|
||||
u1Ec6782aNABN9SUnp4wd7z8h9DAsoxcMfRvgXMLAoGBAJ9gGttfqZbuPz9V0rAo
|
||||
p05SPPado1i5+2dUOScIbNB6+vQij9IlR2Tzu1T9DwzrBqTDPPmSggeA/JXeTvh6
|
||||
Skb9fDukizeDfwPYUN2gljhiJEqFdpRBr5vP0lFi291+a0jMW1zldrumxCcGKMyU
|
||||
D5ReKLp/zSQSQi/Wt4FF1II7
|
||||
-----END PRIVATE KEY-----
|
|
@ -0,0 +1,80 @@
|
|||
subject= C = AU, ST = New South Wales, L = Sydney, O = Apple Pty Limited, OU = FDB Team, CN = "FDB LibTLS Plugin Test Client 2, \C2\80 <\01+\02=\03>"
|
||||
issuer= C = US, ST = California, L = Cupertino, O = Apple Inc., OU = FDB Team, CN = FDB LibTLS Plugin Test Intermediate CA 2
|
||||
subject= C = US, ST = California, L = Cupertino, O = Apple Inc., OU = FDB Team, CN = FDB LibTLS Plugin Test Intermediate CA 2
|
||||
issuer= C = US, ST = California, L = Cupertino, O = Apple Inc., OU = FDB Team, CN = FDB LibTLS Plugin Test Root CA
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIEEzCCAvugAwIBAgIJALOPTrQGpesmMA0GCSqGSIb3DQEBBQUAMIGRMQswCQYD
|
||||
VQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTESMBAGA1UEBwwJQ3VwZXJ0aW5v
|
||||
MRMwEQYDVQQKDApBcHBsZSBJbmMuMREwDwYDVQQLDAhGREIgVGVhbTExMC8GA1UE
|
||||
AwwoRkRCIExpYlRMUyBQbHVnaW4gVGVzdCBJbnRlcm1lZGlhdGUgQ0EgMjAeFw0x
|
||||
ODA0MDcxNDE2MDJaFw0yODA0MDQxNDE2MDJaMIGdMQswCQYDVQQGEwJBVTEYMBYG
|
||||
A1UECAwPTmV3IFNvdXRoIFdhbGVzMQ8wDQYDVQQHDAZTeWRuZXkxGjAYBgNVBAoM
|
||||
EUFwcGxlIFB0eSBMaW1pdGVkMREwDwYDVQQLDAhGREIgVGVhbTE0MDIGA1UEAwwr
|
||||
RkRCIExpYlRMUyBQbHVnaW4gVGVzdCBDbGllbnQgMiwgwoAgPAErAj0DPjCCASIw
|
||||
DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALanLExQi/yK2PRyu6Mvdw2MRxUs
|
||||
26kJftYuK7KtYyltTO3vtj4kNKg1vZI1eezhqr2Ta/1DzE76eLVs8EOW0LAb5oWM
|
||||
zXdYBXBX4vG+K7pYfjuvZUd6jfX2bHW10xC96HgDTfRn6dof8GR0fILJ6DoEcyI3
|
||||
82xnKKxTsgAuXU4uvcsl0g0F78nXuIbk8ZktTV3LIdbOCIcLQfG7DdDyAfEA0T7Q
|
||||
Vg6eeLknIUvPePxyWkUdYeSCDP2d+3NIlHMxNPmH1q3+fCsEsy/kqdVO9e6KrZla
|
||||
CKqnc6yYTXvTffpPepC3Igz678iGg3dv9rLj0i4fyTr4tEOTJebO9Ka3TbMCAwEA
|
||||
AaNgMF4wHQYDVR0OBBYEFKO2/D1IhG8KWFwR6OdyoFqEzIWAMB8GA1UdIwQYMBaA
|
||||
FJFP+HFpDrD0BRU0yE606s6xkqFBMAwGA1UdEwEB/wQCMAAwDgYDVR0PAQH/BAQD
|
||||
AgeAMA0GCSqGSIb3DQEBBQUAA4IBAQAQV3FjsvZvwi5Oi/oSc7Du/BQS9nQ/D4j6
|
||||
IeYpd3M0y50awZB83BReYrhdC907xKkLRD0R8oEPDEg5SaSj3vRML4kaUUqnEINW
|
||||
4JQtv4wNO9CagYriGg8ygQa0xd683svHeXDet3ov11XN/Ms8lfDiOUp2291HgeTW
|
||||
8hqn1DaNfZrCb3EkdoNThwVKIUzQtEPBuPkLE+XT8kZP5d8KHmv8/9L39NdZY32d
|
||||
fzKGBeCxZ34pQS0cTap3rZ02nDfV2vNevODRyuqdhs7EQps2Oe1IfPB9GSE0OFUQ
|
||||
tdphxSjsv1BcHpTwBDpIITKarnceMIKxQjcZU3yPv5ibIaGCgZOt
|
||||
-----END CERTIFICATE-----
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIEADCCAuigAwIBAgIJALOPTrQGpesiMA0GCSqGSIb3DQEBBQUAMIGHMQswCQYD
|
||||
VQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTESMBAGA1UEBwwJQ3VwZXJ0aW5v
|
||||
MRMwEQYDVQQKDApBcHBsZSBJbmMuMREwDwYDVQQLDAhGREIgVGVhbTEnMCUGA1UE
|
||||
AwweRkRCIExpYlRMUyBQbHVnaW4gVGVzdCBSb290IENBMB4XDTE4MDQwNzE0MTYw
|
||||
MVoXDTI4MDQwNDE0MTYwMVowgZExCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxp
|
||||
Zm9ybmlhMRIwEAYDVQQHDAlDdXBlcnRpbm8xEzARBgNVBAoMCkFwcGxlIEluYy4x
|
||||
ETAPBgNVBAsMCEZEQiBUZWFtMTEwLwYDVQQDDChGREIgTGliVExTIFBsdWdpbiBU
|
||||
ZXN0IEludGVybWVkaWF0ZSBDQSAyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
|
||||
CgKCAQEApTSBCiUb0amf+QRV2WY6b3bK93D/PSrm4KR/2m2V0lciU1DAk00/kZ52
|
||||
ZIZmq8g9EaE2+CaDtU0fMvDZpaZD+vTFRwsx4varehq0ZwX9Wt25i/3G/eGLNlD3
|
||||
9E4tDNruK5UQjum4nJ0SV+AdFEGkSfeU3ZJEHYH0NrcbyAUbh0KeWCSwHiYiFJJf
|
||||
gBYwRq/HdKNoS/4YvLXzTLR7BSm3YcqWlO5tdkJ2lcT/7Th/Hq1TCW/FKwdQJJBq
|
||||
JrbOYGlMrf1pLO7Drei/xhsYkwTQ899MhSjkBRhc+401p41Mky0n8wLkuPJGhoY3
|
||||
9QUOjT+Rmvq5yryg0eWGiFquk6Ru5QIDAQABo2MwYTAdBgNVHQ4EFgQUkU/4cWkO
|
||||
sPQFFTTITrTqzrGSoUEwHwYDVR0jBBgwFoAUnqtGja3O5jGlh5vHgp3Tf8NCPKkw
|
||||
DwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQEFBQAD
|
||||
ggEBAJfCHU7dm2/2ASyt3wyxivQLxlV6FsEZcF7HcpbbxuB73frGOL4kEoOxvr2X
|
||||
fBGyjlPMotbc1MeAalAv+hVHdcAcBFPF7lxtYiV6D7YI5T5yVbWSASG3+DMAiW6S
|
||||
GdQi2eyeh00nH7Y1IkW+yaky0enBtWLzrw+XzHl6xT6DIEJnir//PNxvgXTJ5sjk
|
||||
6eFAm8HJIqkNQmgfChMQfUH6nm66WwULW6I117RCSkXhIgxZ7wzDq8bXcEdXCrZk
|
||||
yy5ket9OiVpbd38JgdYirBLmCQVq0uDOOPLz4ZJmNCzQzEt+38AAK2azAk/eb8W9
|
||||
JaKWH+5V8lhlyGw1zQKdNEP/wg8=
|
||||
-----END CERTIFICATE-----
|
||||
-----BEGIN PRIVATE KEY-----
|
||||
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC2pyxMUIv8itj0
|
||||
crujL3cNjEcVLNupCX7WLiuyrWMpbUzt77Y+JDSoNb2SNXns4aq9k2v9Q8xO+ni1
|
||||
bPBDltCwG+aFjM13WAVwV+Lxviu6WH47r2VHeo319mx1tdMQveh4A030Z+naH/Bk
|
||||
dHyCyeg6BHMiN/NsZyisU7IALl1OLr3LJdINBe/J17iG5PGZLU1dyyHWzgiHC0Hx
|
||||
uw3Q8gHxANE+0FYOnni5JyFLz3j8clpFHWHkggz9nftzSJRzMTT5h9at/nwrBLMv
|
||||
5KnVTvXuiq2ZWgiqp3OsmE170336T3qQtyIM+u/IhoN3b/ay49IuH8k6+LRDkyXm
|
||||
zvSmt02zAgMBAAECggEAU2sYHSZwOH+FRGcd8RJdcg+N60rYa2QNzG27wVfUwPfN
|
||||
OaHP/qN0dRpOIPdRXvFVlE0+9aVAKxXTiTBers+zMascZgP/VrEZksxgtn1e5TVD
|
||||
OakKPVHogdvwfvXylmPVRvJjaOsIb3lExew5bVYfPFgJ6Sfagbi/Z6y1z8VdEbYb
|
||||
mI34KSZA4bBAMAHPZLa9TGEx/vbPsBlqpU6k8lcoy3cTkO5fCZW4ZZIpwBwef4uJ
|
||||
UozhRgtTtRBiUpk0F9IoOXonZY1Dtpg+HcDMti/FYgahBVe1hadJ+lbVTxH6GxyI
|
||||
NJYvptdq5S99UOoJDmCCih0v0ZCUNYWoO0I0vzNncQKBgQDemN7es2fIBstiPjOf
|
||||
p103DF5j9Uxq5YH9B3wli0CXf6Z2w5uosONoJWgJZKsHJ6f+YSuHsoE/eCrFF3U9
|
||||
lxT9Nie/wYYIGedly/VR143aCdiTXI44m5gxXgwaUcjvY1DpWyEAAmr5XNdoyZ5n
|
||||
LNTvOTb4vVo9SgDU7II7rdpRmwKBgQDSD9aBtIy/650suQK/9RiXRU0Kg7LXXVM5
|
||||
lavPgLvH55lufJeGSa8+ofCNeo31N4AaVuU4lkGeny9tLNBQbYAoyAz0lf51qK7B
|
||||
1u5JqBDyRrIpdkqwbT0FT1pu1LA3+Qg0KQBrTCnOx+YyyVSivR4YMZzJjmwZGKMg
|
||||
BWOi0PzhyQKBgGR44dfpaIWbs39zjf+ZHnTza0N4+/YgA60/DKUxloULRArFPeRF
|
||||
e0+N2siqnJvNJYGnQGuugbIxPjTZ4rxbDklAgW6HHkVX099Z0TAQuGFbIltZYoRg
|
||||
jrBxv8q9cZHD5Uh/LoT/kmNdqYkNwCbX0IDt9UcOyMVzOq7g1eO0FB/TAoGBAMaG
|
||||
tWIsMwGHOip0SAcHKtB8bI1NXo5v4yH/NDuOHOqXFcj383S02uzEu8XaV6Ozalx6
|
||||
V3SdfTLem0IBIneApajlOGlIAQ9N9qu358ixECMJcYQCCiCnfQ4xqvQoCss7judN
|
||||
ANpnRvPotMS2xkhvl6uh594NvlgRksnGjh3oibcRAoGBAJKiu5ajmIkelzAhFMEC
|
||||
Slxhg/E+djJ1/SG/FaF8zIyTOxre/QUvmTwFKtHe6A5EfKQo9GCTuHuAcJ1U7eQP
|
||||
l2BoY0POqJFpw3s/QOt4g/pOz0YjD9GD6awL5WDfO++s4mnI1Snc3wcu99N4Klax
|
||||
htsaEUECJBUF0ZpIFad73s2f
|
||||
-----END PRIVATE KEY-----
|
|
@ -0,0 +1,80 @@
|
|||
subject= C = AU, ST = New South Wales, L = Sydney, O = Apple Pty Limited, OU = FDB Team, CN = "FDB LibTLS Plugin Test Server 2, \C2\80 <\01+\02=\03>"
|
||||
issuer= C = US, ST = California, L = Cupertino, O = Apple Inc., OU = FDB Team, CN = FDB LibTLS Plugin Test Intermediate CA 2
|
||||
subject= C = US, ST = California, L = Cupertino, O = Apple Inc., OU = FDB Team, CN = FDB LibTLS Plugin Test Intermediate CA 2
|
||||
issuer= C = US, ST = California, L = Cupertino, O = Apple Inc., OU = FDB Team, CN = FDB LibTLS Plugin Test Root CA
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIEEzCCAvugAwIBAgIJALOPTrQGpeskMA0GCSqGSIb3DQEBBQUAMIGRMQswCQYD
|
||||
VQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTESMBAGA1UEBwwJQ3VwZXJ0aW5v
|
||||
MRMwEQYDVQQKDApBcHBsZSBJbmMuMREwDwYDVQQLDAhGREIgVGVhbTExMC8GA1UE
|
||||
AwwoRkRCIExpYlRMUyBQbHVnaW4gVGVzdCBJbnRlcm1lZGlhdGUgQ0EgMjAeFw0x
|
||||
ODA0MDcxNDE2MDJaFw0yODA0MDQxNDE2MDJaMIGdMQswCQYDVQQGEwJBVTEYMBYG
|
||||
A1UECAwPTmV3IFNvdXRoIFdhbGVzMQ8wDQYDVQQHDAZTeWRuZXkxGjAYBgNVBAoM
|
||||
EUFwcGxlIFB0eSBMaW1pdGVkMREwDwYDVQQLDAhGREIgVGVhbTE0MDIGA1UEAwwr
|
||||
RkRCIExpYlRMUyBQbHVnaW4gVGVzdCBTZXJ2ZXIgMiwgwoAgPAErAj0DPjCCASIw
|
||||
DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALAolQZIGMeL5w/Bu2X6lHWjO58u
|
||||
+HUDtBmr37So4jazhZBSFDBg+QlRMiYGLev9EhvCrUsVcRwtvtcuMI3wfKl7qgbi
|
||||
ZX8zmrzZ3YJo9U47NzCa05faOl8uSBvuXuXUBLU342WFP8XDB1W8yOBQMK73xoFv
|
||||
DkcxURx9ZtOhdC3EgYKrFqOB1Azl1DB4gLV3h9rHW5QpQ8SqD9CyggcDBpDeZQIP
|
||||
+4l5YFE9Nb4kEUTscz2wGn4TdHMmcnVpfUxp1Y2o8Umvh4llXHIPhximGb3JJ4QQ
|
||||
Sir4ZXeeoooWoJG0sdlqVLroKav/VMGtEu9LyfbrNdKnTJq3ceVQ+HJ2hlMCAwEA
|
||||
AaNgMF4wHQYDVR0OBBYEFH61Z8O9vFsVdhM4MBU3poX2UMTEMB8GA1UdIwQYMBaA
|
||||
FJFP+HFpDrD0BRU0yE606s6xkqFBMAwGA1UdEwEB/wQCMAAwDgYDVR0PAQH/BAQD
|
||||
AgeAMA0GCSqGSIb3DQEBBQUAA4IBAQCVbxlLGIBCo6/XXjqoMyZc7uQZJj7pGnwh
|
||||
nIMs2izCLfax8j+QrThO2Qjn03zT/WF8eG6ibPbjgnw3VFwCkV6oQ+BXG6Yt0xqP
|
||||
4rz1LzxSio6HSm26gSk4SQUsVoAtz3OImoTCFVfz+Mixe87pyVXXEEtCYvfU74H9
|
||||
I1WGyNkWAxiJbqeIxF5PKoc3EdnT5mfdC6sdeGm7t2neeS8PDFQtJ4UfVIEK5z1C
|
||||
MOfQILNkLX2nBYxNqKpV66zf68VZNN9002ZH2FITGqImpj74BEws3sheiuZySdoI
|
||||
wnAwRnymIMfAmkf9C7Q2ugId0YMMyesaWrIwSlXlJOHGsA1VrBRD
|
||||
-----END CERTIFICATE-----
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIEADCCAuigAwIBAgIJALOPTrQGpesiMA0GCSqGSIb3DQEBBQUAMIGHMQswCQYD
|
||||
VQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTESMBAGA1UEBwwJQ3VwZXJ0aW5v
|
||||
MRMwEQYDVQQKDApBcHBsZSBJbmMuMREwDwYDVQQLDAhGREIgVGVhbTEnMCUGA1UE
|
||||
AwweRkRCIExpYlRMUyBQbHVnaW4gVGVzdCBSb290IENBMB4XDTE4MDQwNzE0MTYw
|
||||
MVoXDTI4MDQwNDE0MTYwMVowgZExCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxp
|
||||
Zm9ybmlhMRIwEAYDVQQHDAlDdXBlcnRpbm8xEzARBgNVBAoMCkFwcGxlIEluYy4x
|
||||
ETAPBgNVBAsMCEZEQiBUZWFtMTEwLwYDVQQDDChGREIgTGliVExTIFBsdWdpbiBU
|
||||
ZXN0IEludGVybWVkaWF0ZSBDQSAyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
|
||||
CgKCAQEApTSBCiUb0amf+QRV2WY6b3bK93D/PSrm4KR/2m2V0lciU1DAk00/kZ52
|
||||
ZIZmq8g9EaE2+CaDtU0fMvDZpaZD+vTFRwsx4varehq0ZwX9Wt25i/3G/eGLNlD3
|
||||
9E4tDNruK5UQjum4nJ0SV+AdFEGkSfeU3ZJEHYH0NrcbyAUbh0KeWCSwHiYiFJJf
|
||||
gBYwRq/HdKNoS/4YvLXzTLR7BSm3YcqWlO5tdkJ2lcT/7Th/Hq1TCW/FKwdQJJBq
|
||||
JrbOYGlMrf1pLO7Drei/xhsYkwTQ899MhSjkBRhc+401p41Mky0n8wLkuPJGhoY3
|
||||
9QUOjT+Rmvq5yryg0eWGiFquk6Ru5QIDAQABo2MwYTAdBgNVHQ4EFgQUkU/4cWkO
|
||||
sPQFFTTITrTqzrGSoUEwHwYDVR0jBBgwFoAUnqtGja3O5jGlh5vHgp3Tf8NCPKkw
|
||||
DwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQEFBQAD
|
||||
ggEBAJfCHU7dm2/2ASyt3wyxivQLxlV6FsEZcF7HcpbbxuB73frGOL4kEoOxvr2X
|
||||
fBGyjlPMotbc1MeAalAv+hVHdcAcBFPF7lxtYiV6D7YI5T5yVbWSASG3+DMAiW6S
|
||||
GdQi2eyeh00nH7Y1IkW+yaky0enBtWLzrw+XzHl6xT6DIEJnir//PNxvgXTJ5sjk
|
||||
6eFAm8HJIqkNQmgfChMQfUH6nm66WwULW6I117RCSkXhIgxZ7wzDq8bXcEdXCrZk
|
||||
yy5ket9OiVpbd38JgdYirBLmCQVq0uDOOPLz4ZJmNCzQzEt+38AAK2azAk/eb8W9
|
||||
JaKWH+5V8lhlyGw1zQKdNEP/wg8=
|
||||
-----END CERTIFICATE-----
|
||||
-----BEGIN PRIVATE KEY-----
|
||||
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCwKJUGSBjHi+cP
|
||||
wbtl+pR1ozufLvh1A7QZq9+0qOI2s4WQUhQwYPkJUTImBi3r/RIbwq1LFXEcLb7X
|
||||
LjCN8Hype6oG4mV/M5q82d2CaPVOOzcwmtOX2jpfLkgb7l7l1AS1N+NlhT/FwwdV
|
||||
vMjgUDCu98aBbw5HMVEcfWbToXQtxIGCqxajgdQM5dQweIC1d4fax1uUKUPEqg/Q
|
||||
soIHAwaQ3mUCD/uJeWBRPTW+JBFE7HM9sBp+E3RzJnJ1aX1MadWNqPFJr4eJZVxy
|
||||
D4cYphm9ySeEEEoq+GV3nqKKFqCRtLHZalS66Cmr/1TBrRLvS8n26zXSp0yat3Hl
|
||||
UPhydoZTAgMBAAECggEAVD60NlLYduXzVNfDtVuHEFNGOjSOYfepc/V8gLubo6lr
|
||||
IMAAI7rcnpYUM5cU8x0OQfRyR8wzUdSWxfWzBs6R78PSZoRzIcgeIl7Wzn0/g3BS
|
||||
To5czuxwqgBKQAFZpPQmZDwcJfr5qqxAn8IvFweCoMqiRlhELcvqDIP0XxWBqDjc
|
||||
TNJ988XzZXQmJbjjpWOkUBy2Uqz8lZt8MmxKFpW7SW4tBJwPphnorgjWfjCV/VEh
|
||||
ORio0rG74NHFo4f1TSrdU2BcB2cbVJ4B+bcUYRdvYmS5bmokhGF8vir0l43gUEdz
|
||||
Fyk6MaPrTI6cinqzenm3q/0eRvNhBE56U0tiGLn14QKBgQDkCkt1Y4LEboSwsVYl
|
||||
IXriStqj9p9MOizihh0enhzRXTTQuLX82fNi+bh1LAluwv290Q57pvKa+hB/YciB
|
||||
o4s7QfSojxQY9DxqvXN7CvxPWXHTyFY5sL4Rm807+C/a9rd39MxBynz9u/7YRvsA
|
||||
s8v8Y/01qIHnTo+mpDvu6HttWwKBgQDFwdRkgstuE+dXZZe8g1ivh3RNPa968TE3
|
||||
b8rzF9/nOJV7f6B/n6YEmHD/cHF5mm1bR+zt/jtf1NCRMpazchw3vT3JzQZYMDnM
|
||||
SD6vxTs5rG47QLiNyTIRmmD4gsEWBpyvoyP8E/9QdfDT1bWI5zZnky9CquRlN+cu
|
||||
J1bTsefEaQKBgGJsRxFNd91MThztDV9NSfptkFyAT1TZLxI+DEdwusNqVSdY8cNG
|
||||
VpP7cC+yaAfURSwuFPAtqDxXfdNc4uuBKNDUsMInrubuUz1Gs5cBsNCWrFhZ+U1B
|
||||
CWgUNMqTXiRFo/40PAyRVs003NOAH0m4UGyIw3rrVdX9xGaKMAv3b35NAoGATkkl
|
||||
I4UDs1f9xQNaxi3Y9ePRjqJUzX6d1SxUU1eoM4ia5IDpsJwqxLb0RKrmwRT5JaGb
|
||||
kbuLFazRxCkar38E3Kv1weWAFXlB6DTRXBPgFjzEhoBgjwCO6ZkLulVIysdjT8Rt
|
||||
gmUINXn7FGENtFyTlP0XQHUWZVt0ETlRjgxni8ECgYBYv6MoSr0iPjQpxeKvwFDz
|
||||
d9zE+ZXN+3GwtkI340lKRSc/f0Uq1TlC2w+DzjyyXcrBwubMQKTKcQQSH9f3YbMu
|
||||
DuxVE9AXdlQ1gSQHGjS0qUWwsS/8Xcjk8ZuduAXPGr/MsvsW+FbbZqG8qdZTeMHu
|
||||
MSTpOxu9HXC8SHML+y0cpw==
|
||||
-----END PRIVATE KEY-----
|
|
@ -0,0 +1,157 @@
|
|||
/*
|
||||
* verify-test.cpp
|
||||
*
|
||||
* This source file is part of the FoundationDB open source project
|
||||
*
|
||||
* Copyright 2013-2018 Apple Inc. and the FoundationDB project authors
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <openssl/obj_mac.h>
|
||||
|
||||
#include "ITLSPlugin.h"
|
||||
#include "ReferenceCounted.h"
|
||||
|
||||
#include "FDBLibTLSPlugin.h"
|
||||
#include "FDBLibTLSPolicy.h"
|
||||
|
||||
struct FDBLibTLSVerifyTest {
|
||||
FDBLibTLSVerifyTest(std::string input):
|
||||
input(input), valid(false), verify_cert(true), verify_time(true), subject_criteria({}), issuer_criteria({}) {};
|
||||
FDBLibTLSVerifyTest(std::string input, bool verify_cert, bool verify_time, std::map<int, std::string> subject, std::map<int, std::string> issuer):
|
||||
input(input), valid(true), verify_cert(verify_cert), verify_time(verify_time), subject_criteria(subject), issuer_criteria(issuer) {};
|
||||
~FDBLibTLSVerifyTest() {};
|
||||
|
||||
int run();
|
||||
|
||||
std::string input;
|
||||
|
||||
bool valid;
|
||||
bool verify_cert;
|
||||
bool verify_time;
|
||||
|
||||
std::map<int, std::string> subject_criteria;
|
||||
std::map<int, std::string> issuer_criteria;
|
||||
};
|
||||
|
||||
static std::string printable( std::string const& val ) {
|
||||
static char const digits[] = "0123456789ABCDEF";
|
||||
std::string s;
|
||||
|
||||
for ( int i = 0; i < val.size(); i++ ) {
|
||||
uint8_t b = val[i];
|
||||
if (b >= 32 && b < 127 && b != '\\')
|
||||
s += (char)b;
|
||||
else if (b == '\\')
|
||||
s += "\\\\";
|
||||
else {
|
||||
s += "\\x";
|
||||
s += digits[(b >> 4) & 15];
|
||||
s += digits[b & 15];
|
||||
}
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
static std::string criteriaToString(std::map<int, std::string> const& criteria) {
|
||||
std::string s;
|
||||
for (auto &pair: criteria) {
|
||||
s += "{" + std::to_string(pair.first) + ":" + printable(pair.second) + "}";
|
||||
}
|
||||
return "{" + s + "}";
|
||||
}
|
||||
|
||||
static void logf(const char* event, void* uid, int is_error, ...) {
|
||||
}
|
||||
|
||||
int FDBLibTLSVerifyTest::run() {
|
||||
FDBLibTLSPlugin *plugin = new FDBLibTLSPlugin();
|
||||
FDBLibTLSPolicy *policy = new FDBLibTLSPolicy(Reference<FDBLibTLSPlugin>::addRef(plugin), (ITLSLogFunc)logf);
|
||||
|
||||
bool rc = policy->set_verify_peers((const uint8_t *)input.c_str(), input.size());
|
||||
if (rc != valid) {
|
||||
if (valid) {
|
||||
std::cerr << "FAIL: Verify test failed, but should have succeeded - '" << input << "'\n";
|
||||
return 1;
|
||||
} else {
|
||||
std::cerr << "FAIL: Verify test should have failed, but succeeded - '" << input << "'\n";
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
if (policy->verify_cert != verify_cert) {
|
||||
std::cerr << "FAIL: Got verify cert " << policy->verify_cert << ", want " << verify_cert << "\n";
|
||||
return 1;
|
||||
}
|
||||
if (policy->verify_time != verify_time) {
|
||||
std::cerr << "FAIL: Got verify time " << policy->verify_time << ", want " << verify_time << "\n";
|
||||
return 1;
|
||||
}
|
||||
if (policy->subject_criteria != subject_criteria) {
|
||||
std::cerr << "FAIL: Got subject criteria " << criteriaToString(policy->subject_criteria) << ", want " << criteriaToString(subject_criteria) << "\n";
|
||||
return 1;
|
||||
}
|
||||
if (policy->issuer_criteria != issuer_criteria) {
|
||||
std::cerr << "FAIL: Got issuer criteria " << criteriaToString(policy->issuer_criteria) << ", want " << criteriaToString(issuer_criteria) << "\n";
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int failed = 0;
|
||||
|
||||
std::vector<FDBLibTLSVerifyTest> tests = {
|
||||
FDBLibTLSVerifyTest("", true, true, {}, {}),
|
||||
FDBLibTLSVerifyTest("Check.Valid=1", true, true, {}, {}),
|
||||
FDBLibTLSVerifyTest("Check.Valid=0", false, true, {}, {}),
|
||||
FDBLibTLSVerifyTest("Check.Unexpired=1", true, true, {}, {}),
|
||||
FDBLibTLSVerifyTest("Check.Unexpired=0", true, false, {}, {}),
|
||||
FDBLibTLSVerifyTest("Check.Valid=1,Check.Unexpired=0", true, false, {}, {}),
|
||||
FDBLibTLSVerifyTest("Check.Unexpired=0,Check.Valid=0", false, false, {}, {}),
|
||||
FDBLibTLSVerifyTest("Check.Unexpired=0,I.C=US,C=US,S.O=XYZCorp\\, LLC", true, false,
|
||||
{{NID_countryName, "US"}, {NID_organizationName, "XYZCorp, LLC"}}, {{NID_countryName, "US"}}),
|
||||
FDBLibTLSVerifyTest("Check.Unexpired=0,I.C=US,C=US,S.O=XYZCorp\\= LLC", true, false,
|
||||
{{NID_countryName, "US"}, {NID_organizationName, "XYZCorp= LLC"}}, {{NID_countryName, "US"}}),
|
||||
FDBLibTLSVerifyTest("Check.Unexpired=0,I.C=US,C=US,S.O=XYZCorp=LLC", true, false,
|
||||
{{NID_countryName, "US"}, {NID_organizationName, "XYZCorp=LLC"}}, {{NID_countryName, "US"}}),
|
||||
FDBLibTLSVerifyTest("I.C=US,C=US,Check.Unexpired=0,S.O=XYZCorp=LLC", true, false,
|
||||
{{NID_countryName, "US"}, {NID_organizationName, "XYZCorp=LLC"}}, {{NID_countryName, "US"}}),
|
||||
FDBLibTLSVerifyTest("I.C=US,C=US,S.O=XYZCorp\\, LLC", true, true,
|
||||
{{NID_countryName, "US"}, {NID_organizationName, "XYZCorp, LLC"}}, {{NID_countryName, "US"}}),
|
||||
FDBLibTLSVerifyTest("C=\\,S=abc", true, true, {{NID_countryName, ",S=abc"}}, {}),
|
||||
FDBLibTLSVerifyTest("CN=\\61\\62\\63", true, true, {{NID_commonName, "abc"}}, {}),
|
||||
FDBLibTLSVerifyTest("CN=a\\62c", true, true, {{NID_commonName, "abc"}}, {}),
|
||||
FDBLibTLSVerifyTest("CN=a\\01c", true, true, {{NID_commonName, "a\001c"}}, {}),
|
||||
|
||||
// Invalid cases.
|
||||
FDBLibTLSVerifyTest("Check.Invalid=0"),
|
||||
FDBLibTLSVerifyTest("Valid=1"),
|
||||
FDBLibTLSVerifyTest("C= US,S=abc"),
|
||||
FDBLibTLSVerifyTest("C=#US,S=abc"),
|
||||
FDBLibTLSVerifyTest("C=abc,S=\\"),
|
||||
FDBLibTLSVerifyTest("XYZ=abc"),
|
||||
FDBLibTLSVerifyTest("GN=abc"),
|
||||
FDBLibTLSVerifyTest("CN=abc,Check.Expired=1"),
|
||||
};
|
||||
|
||||
for (auto &test: tests)
|
||||
failed |= test.run();
|
||||
|
||||
return (failed);
|
||||
}
|
29
Makefile
29
Makefile
|
@ -92,8 +92,8 @@ STATIC_LIBS :=
|
|||
VPATH += $(addprefix :,$(filter-out lib,$(patsubst -L%,%,$(filter -L%,$(LDFLAGS)))))
|
||||
|
||||
CS_PROJECTS := flow/actorcompiler flow/coveragetool fdbclient/vexillographer
|
||||
CPP_PROJECTS := flow fdbrpc fdbclient fdbbackup fdbserver fdbcli bindings/c bindings/java fdbmonitor bindings/flow/tester bindings/flow
|
||||
OTHER_PROJECTS := bindings/python bindings/ruby bindings/nodejs bindings/go
|
||||
CPP_PROJECTS := flow fdbrpc fdbclient fdbbackup fdbserver fdbcli bindings/c bindings/java fdbmonitor bindings/flow/tester bindings/flow FDBLibTLS
|
||||
OTHER_PROJECTS := bindings/python bindings/ruby bindings/go
|
||||
|
||||
CS_MK_GENERATED := $(CS_PROJECTS:=/generated.mk)
|
||||
CPP_MK_GENERATED := $(CPP_PROJECTS:=/generated.mk)
|
||||
|
@ -127,7 +127,7 @@ else
|
|||
endif
|
||||
@echo "#define FDB_VT_PACKAGE_NAME \"$(PACKAGE_NAME)\"" >> $@
|
||||
|
||||
bindings: fdb_c fdb_python fdb_ruby fdb_java fdb_node fdb_flow fdb_flow_tester fdb_go fdb_go_tester
|
||||
bindings: fdb_c fdb_python fdb_ruby fdb_java fdb_flow fdb_flow_tester fdb_go fdb_go_tester
|
||||
|
||||
Makefiles: $(MK_GENERATED)
|
||||
|
||||
|
@ -144,11 +144,11 @@ OBJDIR := .objs
|
|||
|
||||
include $(MK_INCLUDE)
|
||||
|
||||
clean: $(CLEAN_TARGETS)
|
||||
clean: $(CLEAN_TARGETS) docpreview_clean
|
||||
@echo "Cleaning toplevel"
|
||||
@rm -rf $(OBJDIR)
|
||||
@rm -rf $(DEPSDIR)
|
||||
@rm -rf lib/libstdc++.a
|
||||
@rm -rf lib/
|
||||
@rm -rf bin/coverage.*.xml
|
||||
|
||||
targets:
|
||||
|
@ -174,12 +174,21 @@ lib/libstdc++.a: $(shell $(CC) -print-file-name=libstdc++_pic.a)
|
|||
@ar rcs $@ .libstdc++/*.o
|
||||
@rm -r .libstdc++
|
||||
|
||||
docpreview: javadoc
|
||||
TARGETS= $(MAKE) -C documentation docpreview
|
||||
|
||||
ifeq ($(PLATFORM),osx)
|
||||
MD5SUM=md5
|
||||
else
|
||||
MD5SUM=md5sum
|
||||
endif
|
||||
docpreview_clean:
|
||||
CLEAN_TARGETS= $(MAKE) -C documentation docpreview_clean
|
||||
|
||||
packages/foundationdb-docs-$(VERSION).tar.gz: FORCE javadoc
|
||||
TARGETS= $(MAKE) -C documentation docpackage
|
||||
@mkdir -p packages
|
||||
@rm -f packages/foundationdb-docs-$(VERSION).tar.gz
|
||||
@cp documentation/sphinx/.dist/foundationdb-docs-$(VERSION).tar.gz packages/foundationdb-docs-$(VERSION).tar.gz
|
||||
|
||||
docpackage: packages/foundationdb-docs-$(VERSION).tar.gz
|
||||
|
||||
FORCE:
|
||||
|
||||
.SECONDEXPANSION:
|
||||
|
||||
|
|
51
README.md
51
README.md
|
@ -1,3 +1,52 @@
|
|||
# FoundationDB
|
||||
<img alt="FoundationDB logo" src="documentation/FDB_logo.png?raw=true" width="400">
|
||||
|
||||
FoundationDB is a distributed database designed to handle large volumes of structured data across clusters of commodity servers. It organizes data as an ordered key-value store and employs ACID transactions for all operations. It is especially well-suited for read/write workloads but also has excellent performance for write-intensive workloads. Users interact with the database using API language binding.
|
||||
|
||||
To learn more about FoundationDB, visit [foundationdb.org](https://www.foundationdb.org/)
|
||||
|
||||
## Documentation
|
||||
|
||||
Documentation can be found online at <https://apple.github.io/foundationdb/>. The documentation covers details of API usage, background information on design philosophy, and extensive usage examples. Docs are built from the [source in this repo](documentation/sphinx/source).
|
||||
|
||||
## Forums
|
||||
|
||||
[The FoundationDB Forums](https://forums.foundationdb.org/) are the home for most of the discussion and communication about the FoundationDB project. We welcome your participation! We want FoundationDB to be a great project to be a part of and, as part of that, have established a [Code of Conduct](CODE_OF_CONDUCT.md) to establish what constitutes permissible modes of interaction.
|
||||
|
||||
## Contributing
|
||||
|
||||
Contributing to FoundationDB can be in contributions to the code base, sharing your experience and insights in the community on the Forums, or contributing to projects that make use of FoundationDB. Please see the [contributing guide](CONTRIBUTING.md) for more specifics.
|
||||
|
||||
## Getting Started
|
||||
|
||||
### Binary downloads
|
||||
|
||||
Developers interested in using the FoundationDB store for an application can get started easily by downloading and installing a binary package. Please see the [downloads page](https://www.foundationdb.org/download/) for a list of available packages.
|
||||
|
||||
|
||||
### Compiling from source
|
||||
|
||||
Developers on a OS for which there is no binary package, or who would like to start hacking on the code can get started by compiling from source.
|
||||
|
||||
#### macOS
|
||||
|
||||
1. Check out this repo on your Mac.
|
||||
1. Install the Xcode command-line tools.
|
||||
1. Download version 1.52 of [Boost](https://sourceforge.net/projects/boost/files/boost/1.52.0/).
|
||||
1. Set the `BOOSTDIR` environment variable to the location containing this boost installation.
|
||||
1. Install [Mono](http://www.mono-project.com/download/stable/).
|
||||
1. Install a [JDK](http://www.oracle.com/technetwork/java/javase/downloads/index.html). FoundationDB currently builds with Java 8.
|
||||
1. Navigate to the directory where you checked out the foundationdb repo.
|
||||
1. Run `make`.
|
||||
|
||||
#### Linux
|
||||
|
||||
1. Install [Docker](https://www.docker.com/).
|
||||
1. Check out the foundationdb repo.
|
||||
1. Build Linux docker image using the file `Dockerfile` located in the `build` source directory.
|
||||
1. Run the docker image interactively [Docker Run](https://docs.docker.com/engine/reference/run/#general-form) with the directory containing the foundationdb repo mounted [Docker Mounts](https://docs.docker.com/storage/volumes/).
|
||||
`docker run -it -v '/local/dir/path/foundationdb:/docker/dir/path/foundationdb' /bin/bash`
|
||||
1. Navigate to the mounted directory containing the foundationdb repo.
|
||||
`cd /docker/dir/path/foundationdb`
|
||||
1. Run `make`.
|
||||
|
||||
This will build the fdbserver binary and the python bindings. If you want to build our other bindings, you will need to install a runtime for the language whose binding you want to build. Each binding has an `.mk` file which provides specific targets for that binding.
|
||||
|
|
|
@ -25,7 +25,7 @@ sys.path[:0] = [os.path.join(os.path.dirname(__file__), '..', '..', 'bindings',
|
|||
|
||||
import util
|
||||
|
||||
FDB_API_VERSION = 510
|
||||
FDB_API_VERSION = 520
|
||||
|
||||
LOGGING = {
|
||||
'version': 1,
|
||||
|
|
|
@ -141,7 +141,7 @@ def choose_api_version(selected_api_version, tester_min_version, tester_max_vers
|
|||
api_version = min_version
|
||||
elif random.random() < 0.9:
|
||||
api_version = random.choice([v for v in [13, 14, 16, 21, 22, 23, 100, 200, 300, 400, 410, 420, 430,
|
||||
440, 450, 460, 500, 510] if v >= min_version and v <= max_version])
|
||||
440, 450, 460, 500, 510, 520] if v >= min_version and v <= max_version])
|
||||
else:
|
||||
api_version = random.randint(min_version, max_version)
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
|
||||
import os
|
||||
|
||||
MAX_API_VERSION = 510
|
||||
MAX_API_VERSION = 520
|
||||
COMMON_TYPES = ['null', 'bytes', 'string', 'int', 'uuid', 'bool', 'float', 'double', 'tuple']
|
||||
ALL_TYPES = COMMON_TYPES + ['versionstamp']
|
||||
|
||||
|
@ -58,8 +58,6 @@ _java_cmd = 'java -ea -cp %s:%s com.apple.foundationdb.test.' % (
|
|||
testers = {
|
||||
'python': Tester('python', 'python ' + _absolute_path('python/tests/tester.py'), 2040, 23, MAX_API_VERSION, types=ALL_TYPES),
|
||||
'python3': Tester('python3', 'python3 ' + _absolute_path('python/tests/tester.py'), 2040, 23, MAX_API_VERSION, types=ALL_TYPES),
|
||||
'node': Tester('node', _absolute_path('nodejs/tests/tester.js'), 53, 500, MAX_API_VERSION),
|
||||
'streamline': Tester('streamline', _absolute_path('nodejs/tests/streamline_tester._js'), 53, 500, MAX_API_VERSION),
|
||||
'ruby': Tester('ruby', _absolute_path('ruby/tests/tester.rb'), 64, 23, MAX_API_VERSION),
|
||||
'java': Tester('java', _java_cmd + 'StackTester', 2040, 510, MAX_API_VERSION, types=ALL_TYPES),
|
||||
'java_async': Tester('java', _java_cmd + 'AsyncStackTester', 2040, 510, MAX_API_VERSION, types=ALL_TYPES),
|
||||
|
|
|
@ -25,7 +25,7 @@ BREAKONERROR="${BREAKONERROR:-0}"
|
|||
RUNSCRIPTS="${RUNSCRIPTS:-1}"
|
||||
RUNTESTS="${RUNTESTS:-1}"
|
||||
RANDOMTEST="${RANDOMTEST:-0}"
|
||||
BINDINGTESTS="${BINDINGTESTS:-python python3 java java_async ruby node go flow}"
|
||||
BINDINGTESTS="${BINDINGTESTS:-python python3 java java_async ruby go flow}"
|
||||
LOGLEVEL="${LOGLEVEL:-INFO}"
|
||||
_BINDINGTESTS=(${BINDINGTESTS})
|
||||
DISABLEDTESTS=()
|
||||
|
|
|
@ -24,7 +24,6 @@ function run_scripted() {
|
|||
scripted ruby
|
||||
scripted java
|
||||
scripted java_async
|
||||
scripted node
|
||||
scripted go
|
||||
scripted flow
|
||||
}
|
||||
|
@ -40,8 +39,6 @@ while `true`; do
|
|||
run ruby
|
||||
run java
|
||||
run java_async
|
||||
run node
|
||||
#run streamline
|
||||
run go
|
||||
run flow
|
||||
done
|
||||
|
|
|
@ -5,9 +5,9 @@ Your API test program must implement a simple stack machine that exercises the
|
|||
FoundationDB API. The program is invoked with two or three arguments. The first
|
||||
argument is a prefix that is the first element of a tuple, the second is the
|
||||
API version, and the third argument is the path to a cluster file. If the
|
||||
third argument is not specified, your program may assume that fdb.open() will
|
||||
succeed with no arguments (an fdb.cluster file will exist in the current
|
||||
directory). Otherwise, your program should connect to the cluster specified
|
||||
third argument is not specified, your program may assume that `fdb.open()` will
|
||||
succeed with no arguments (an fdb.cluster file will exist in the current
|
||||
directory). Otherwise, your program should connect to the cluster specified
|
||||
by the given cluster file.
|
||||
|
||||
Your stack machine should begin reading the range returned by the tuple range
|
||||
|
@ -38,7 +38,7 @@ instructions:
|
|||
and a peek operation. The stack is initialized to be empty.
|
||||
|
||||
- A current FDB transaction name (stored as a byte string). The transaction
|
||||
name should be initialized to the prefix that instructions are being read
|
||||
name should be initialized to the prefix that instructions are being read
|
||||
from.
|
||||
|
||||
- A last seen FDB version, which is a 64-bit integer.
|
||||
|
@ -47,44 +47,44 @@ instructions:
|
|||
Data Operations
|
||||
---------------
|
||||
|
||||
PUSH <item>
|
||||
#### PUSH <item>
|
||||
|
||||
Pushes the provided item onto the stack.
|
||||
|
||||
DUP
|
||||
#### DUP
|
||||
|
||||
Duplicates the top item on the stack. The instruction number for the
|
||||
duplicate item should be the same as the original.
|
||||
|
||||
EMPTY_STACK
|
||||
#### EMPTY_STACK
|
||||
|
||||
Discards all items in the stack.
|
||||
|
||||
SWAP
|
||||
#### SWAP
|
||||
|
||||
Pops the top item off of the stack as INDEX. Swaps the items in the stack at
|
||||
depth 0 and depth INDEX. Does not modify the instruction numbers of the
|
||||
swapped items.
|
||||
|
||||
POP
|
||||
#### POP
|
||||
|
||||
Pops and discards the top item on the stack.
|
||||
|
||||
SUB
|
||||
#### SUB
|
||||
|
||||
Pops the top two items off of the stack as A and B and then pushes the
|
||||
difference (A-B) onto the stack. A and B may be assumed to be integers.
|
||||
|
||||
CONCAT
|
||||
#### CONCAT
|
||||
|
||||
Pops the top two items off the stack as A and B and then pushes the
|
||||
Pops the top two items off the stack as A and B and then pushes the
|
||||
concatenation of A and B onto the stack. A and B can be assumed to
|
||||
be of the same type and will be either byte strings or unicode strings.
|
||||
|
||||
LOG_STACK
|
||||
#### LOG_STACK
|
||||
|
||||
Pops the top item off the stack as PREFIX. Using a new transaction with normal
|
||||
retry logic, inserts a key-value pair into the database for each item in the
|
||||
retry logic, inserts a key-value pair into the database for each item in the
|
||||
stack of the form:
|
||||
|
||||
PREFIX + tuple.pack((stackIndex, instructionNumber)) = tuple.pack((item,))
|
||||
|
@ -96,8 +96,8 @@ LOG_STACK
|
|||
then the value should be truncated to the first 40000 bytes of the packed
|
||||
tuple.
|
||||
|
||||
When finished, the stack should be empty. Note that because the stack may be
|
||||
large, it may be necessary to commit the transaction every so often (e.g.
|
||||
When finished, the stack should be empty. Note that because the stack may be
|
||||
large, it may be necessary to commit the transaction every so often (e.g.
|
||||
after every 100 sets) to avoid past_version errors.
|
||||
|
||||
FoundationDB Operations
|
||||
|
@ -117,7 +117,7 @@ should simulate it using an anonymous transaction. Remember that set and clear
|
|||
operations must immediately commit (with appropriate retry behavior!).
|
||||
|
||||
Any error that bubbles out of these operations must be caught. In the event of
|
||||
an error, you must push the packed tuple of the string "ERROR" and the error
|
||||
an error, you must push the packed tuple of the string `"ERROR"` and the error
|
||||
code (as a string, not an integer).
|
||||
|
||||
Some operations may allow you to push future values onto the stack. When popping
|
||||
|
@ -132,25 +132,25 @@ futures must apply the following rules to the result:
|
|||
|
||||
- If the result is void (i.e. the future was just a signal of
|
||||
completion), then its value should be the byte string
|
||||
"RESULT_NOT_PRESENT"
|
||||
`"RESULT_NOT_PRESENT"`
|
||||
|
||||
- If the result is from a GET operation in which no result was
|
||||
returned, then its value is to be converted to the byte string
|
||||
"RESULT_NOT_PRESENT"
|
||||
`"RESULT_NOT_PRESENT"`
|
||||
|
||||
NEW_TRANSACTION
|
||||
#### NEW_TRANSACTION
|
||||
|
||||
Creates a new transaction and stores it in the global transaction map
|
||||
under the currently used transaction name.
|
||||
|
||||
USE_TRANSACTION
|
||||
#### USE_TRANSACTION
|
||||
|
||||
Pop the top item off of the stack as TRANSACTION_NAME. Begin using the
|
||||
transaction stored at TRANSACTION_NAME in the transaction map for future
|
||||
operations. If no entry exists in the map for the given name, a new
|
||||
transaction should be inserted.
|
||||
|
||||
ON_ERROR
|
||||
#### ON_ERROR
|
||||
|
||||
Pops the top item off of the stack as ERROR_CODE. Passes ERROR_CODE in a
|
||||
language-appropriate way to the on_error method of current transaction
|
||||
|
@ -158,22 +158,22 @@ ON_ERROR
|
|||
the error out as indicated above. May optionally push a future onto the
|
||||
stack.
|
||||
|
||||
GET (_SNAPSHOT, _DATABASE)
|
||||
#### GET (_SNAPSHOT, _DATABASE)
|
||||
|
||||
Pops the top item off of the stack as KEY and then looks up KEY in the
|
||||
database using the get() method. May optionally push a future onto the
|
||||
stack.
|
||||
|
||||
GET_KEY (_SNAPSHOT, _DATABASE)
|
||||
#### GET_KEY (_SNAPSHOT, _DATABASE)
|
||||
|
||||
Pops the top four items off of the stack as KEY, OR_EQUAL, OFFSET, PREFIX
|
||||
and then constructs a key selector. This key selector is then resolved
|
||||
using the get_key() method to yield RESULT. If RESULT starts with PREFIX,
|
||||
then RESULT is pushed onto the stack. Otherwise, if RESULT < PREFIX, PREFIX
|
||||
and then constructs a key selector. This key selector is then resolved
|
||||
using the get_key() method to yield RESULT. If RESULT starts with PREFIX,
|
||||
then RESULT is pushed onto the stack. Otherwise, if RESULT < PREFIX, PREFIX
|
||||
is pushed onto the stack. If RESULT > PREFIX, then strinc(PREFIX) is pushed
|
||||
onto the stack. May optionally push a future onto the stack.
|
||||
|
||||
GET_RANGE (_SNAPSHOT, _DATABASE)
|
||||
#### GET_RANGE (_SNAPSHOT, _DATABASE)
|
||||
|
||||
Pops the top five items off of the stack as BEGIN_KEY, END_KEY, LIMIT,
|
||||
REVERSE and STREAMING_MODE. Performs a range read in a language-appropriate
|
||||
|
@ -181,103 +181,103 @@ GET_RANGE (_SNAPSHOT, _DATABASE)
|
|||
packed into a tuple as [k1,v1,k2,v2,...,kn,vn], and this single packed value
|
||||
is pushed onto the stack.
|
||||
|
||||
GET_RANGE_STARTS_WITH (_SNAPSHOT, _DATABASE)
|
||||
#### GET_RANGE_STARTS_WITH (_SNAPSHOT, _DATABASE)
|
||||
|
||||
Pops the top four items off of the stack as PREFIX, LIMIT, REVERSE and
|
||||
STREAMING_MODE. Performs a prefix range read in a language-appropriate way
|
||||
using these parameters. Output is pushed onto the stack as with GET_RANGE.
|
||||
|
||||
GET_RANGE_SELECTOR (_SNAPSHOT, _DATABASE)
|
||||
#### GET_RANGE_SELECTOR (_SNAPSHOT, _DATABASE)
|
||||
|
||||
Pops the top ten items off of the stack as BEGIN_KEY, BEGIN_OR_EQUAL,
|
||||
BEGIN_OFFSET, END_KEY, END_OR_EQUAL, END_OFFSET, LIMIT, REVERSE,
|
||||
STREAMING_MODE, and PREFIX. Constructs key selectors BEGIN and END from
|
||||
STREAMING_MODE, and PREFIX. Constructs key selectors BEGIN and END from
|
||||
the first six parameters, and then performs a range read in a language-
|
||||
appropriate way using BEGIN, END, LIMIT, REVERSE and STREAMING_MODE. Output
|
||||
is pushed onto the stack as with GET_RANGE, excluding any keys that do not
|
||||
appropriate way using BEGIN, END, LIMIT, REVERSE and STREAMING_MODE. Output
|
||||
is pushed onto the stack as with GET_RANGE, excluding any keys that do not
|
||||
begin with PREFIX.
|
||||
|
||||
GET_READ_VERSION (_SNAPSHOT)
|
||||
#### GET_READ_VERSION (_SNAPSHOT)
|
||||
|
||||
Gets the current read version and stores it in the internal stack machine
|
||||
state as the last seen version. Pushed the string "GOT_READ_VERSION" onto
|
||||
the stack.
|
||||
|
||||
GET_VERSIONSTAMP
|
||||
#### GET_VERSIONSTAMP
|
||||
|
||||
Calls get_versionstamp and pushes the resulting future onto the stack.
|
||||
|
||||
SET (_DATABASE)
|
||||
#### SET (_DATABASE)
|
||||
|
||||
Pops the top two items off of the stack as KEY and VALUE. Sets KEY to have
|
||||
the value VALUE. A SET_DATABASE call may optionally push a future onto the
|
||||
stack.
|
||||
|
||||
SET_READ_VERSION
|
||||
#### SET_READ_VERSION
|
||||
|
||||
Sets the current transaction read version to the internal state machine last
|
||||
seen version.
|
||||
|
||||
CLEAR (_DATABASE)
|
||||
#### CLEAR (_DATABASE)
|
||||
|
||||
Pops the top item off of the stack as KEY and then clears KEY from the
|
||||
database. A CLEAR_DATABASE call may optionally push a future onto the stack.
|
||||
|
||||
CLEAR_RANGE (_DATABASE)
|
||||
#### CLEAR_RANGE (_DATABASE)
|
||||
|
||||
Pops the top two items off of the stack as BEGIN_KEY and END_KEY. Clears the
|
||||
range of keys from BEGIN_KEY to END_KEY in the database. A
|
||||
CLEAR_RANGE_DATABASE call may optionally push a future onto the stack.
|
||||
|
||||
CLEAR_RANGE_STARTS_WITH (_DATABASE)
|
||||
#### CLEAR_RANGE_STARTS_WITH (_DATABASE)
|
||||
|
||||
Pops the top item off of the stack as PREFIX and then clears all keys from
|
||||
the database that begin with PREFIX. A CLEAR_RANGE_STARTS_WITH_DATABASE call
|
||||
may optionally push a future onto the stack.
|
||||
|
||||
ATOMIC_OP (_DATABASE)
|
||||
#### ATOMIC_OP (_DATABASE)
|
||||
|
||||
Pops the top three items off of the stack as OPTYPE, KEY, and VALUE.
|
||||
Performs the atomic operation described by OPTYPE upon KEY with VALUE. An
|
||||
ATOMIC_OP_DATABASE call may optionally push a future onto the stack.
|
||||
|
||||
READ_CONFLICT_RANGE and WRITE_CONFLICT_RANGE
|
||||
#### READ_CONFLICT_RANGE and WRITE_CONFLICT_RANGE
|
||||
|
||||
Pops the top two items off of the stack as BEGIN_KEY and END_KEY. Adds a
|
||||
read conflict range or write conflict range from BEGIN_KEY to END_KEY.
|
||||
Pushes the byte string "SET_CONFLICT_RANGE" onto the stack.
|
||||
|
||||
READ_CONFLICT_KEY and WRITE_CONFLICT_KEY
|
||||
#### READ_CONFLICT_KEY and WRITE_CONFLICT_KEY
|
||||
|
||||
Pops the top item off of the stack as KEY. Adds KEY as a read conflict key
|
||||
or write conflict key. Pushes the byte string "SET_CONFLICT_KEY" onto the
|
||||
stack.
|
||||
|
||||
DISABLE_WRITE_CONFLICT
|
||||
#### DISABLE_WRITE_CONFLICT
|
||||
|
||||
Sets the NEXT_WRITE_NO_WRITE_CONFLICT_RANGE transaction option on the
|
||||
current transaction. Does not modify the stack.
|
||||
|
||||
COMMIT
|
||||
#### COMMIT
|
||||
|
||||
Commits the current transaction (with no retry behavior). May optionally
|
||||
push a future onto the stack.
|
||||
|
||||
RESET
|
||||
#### RESET
|
||||
|
||||
Resets the current transaction.
|
||||
|
||||
CANCEL
|
||||
#### CANCEL
|
||||
|
||||
Cancels the current transaction.
|
||||
|
||||
GET_COMMITTED_VERSION
|
||||
#### GET_COMMITTED_VERSION
|
||||
|
||||
Gets the committed version from the current transaction and stores it in the
|
||||
internal stack machine state as the last seen version. Pushes the byte
|
||||
string "GOT_COMMITTED_VERSION" onto the stack.
|
||||
|
||||
WAIT_FUTURE
|
||||
#### WAIT_FUTURE
|
||||
|
||||
Pops the top item off the stack and pushes it back on. If the top item on
|
||||
the stack is a future, this will have the side effect of waiting on the
|
||||
|
@ -287,13 +287,13 @@ WAIT_FUTURE
|
|||
Tuple Operations
|
||||
----------------
|
||||
|
||||
TUPLE_PACK
|
||||
#### TUPLE_PACK
|
||||
|
||||
Pops the top item off of the stack as N. Pops the next N items off of the
|
||||
stack and packs them as the tuple [item0,item1,...,itemN], and then pushes
|
||||
this single packed value onto the stack.
|
||||
|
||||
TUPLE_PACK_WITH_VERSIONSTAMP
|
||||
#### TUPLE_PACK_WITH_VERSIONSTAMP
|
||||
|
||||
Pops the top item off of the stack as a byte string prefix. Pops the next item
|
||||
off of the stack as N. Pops the next N items off of the stack and packs them
|
||||
|
@ -307,20 +307,20 @@ TUPLE_PACK_WITH_VERSIONSTAMP
|
|||
do not contain a 'Versionstamp' tuple-type do not have to implement this
|
||||
operation.)
|
||||
|
||||
TUPLE_UNPACK
|
||||
#### TUPLE_UNPACK
|
||||
|
||||
Pops the top item off of the stack as PACKED, and then unpacks PACKED into a
|
||||
tuple. For each element of the tuple, packs it as a new tuple and pushes it
|
||||
onto the stack.
|
||||
|
||||
TUPLE_RANGE
|
||||
#### TUPLE_RANGE
|
||||
|
||||
Pops the top item off of the stack as N. Pops the next N items off of the
|
||||
stack, and passes these items as a tuple (or array, or language-appropriate
|
||||
structure) to the tuple range method. Pushes the begin and end elements of
|
||||
the returned range onto the stack.
|
||||
|
||||
TUPLE_SORT
|
||||
#### TUPLE_SORT
|
||||
|
||||
Pops the top item off of the stack as N. Pops the next N items off of the
|
||||
stack as packed tuples (i.e., byte strings), unpacks them, sorts the tuples,
|
||||
|
@ -330,25 +330,25 @@ TUPLE_SORT
|
|||
use that to sort. Otherwise, it should sort them lexicographically by
|
||||
their byte representation. The choice of function should not affect final sort order.
|
||||
|
||||
ENCODE_FLOAT
|
||||
#### ENCODE_FLOAT
|
||||
|
||||
Pops the top item off of the stack. This will be a byte-string of length 4
|
||||
containing the IEEE 754 encoding of a float in big-endian order.
|
||||
This is then converted into a float and pushed onto the stack.
|
||||
|
||||
ENCODE_DOUBLE
|
||||
#### ENCODE_DOUBLE
|
||||
|
||||
Pops the top item off of the stack. This will be a byte-string of length 8
|
||||
containing the IEEE 754 encoding of a double in big-endian order.
|
||||
This is then converted into a double and pushed onto the stack.
|
||||
|
||||
DECODE_FLOAT
|
||||
#### DECODE_FLOAT
|
||||
|
||||
Pops the top item off of the stack. This will be a single-precision float.
|
||||
This is converted into a (4 byte) byte-string of its IEEE 754 representation
|
||||
in big-endian order, and pushed onto the stack.
|
||||
|
||||
DECODE_DOUBLE
|
||||
#### DECODE_DOUBLE
|
||||
|
||||
Pops the top item off of the stack. This will be a double-precision float.
|
||||
This is converted into a (8 byte) byte-string its IEEE 754 representation
|
||||
|
@ -358,7 +358,7 @@ DECODE_DOUBLE
|
|||
Thread Operations
|
||||
-----------------
|
||||
|
||||
START_THREAD
|
||||
#### START_THREAD
|
||||
|
||||
Pops the top item off of the stack as PREFIX. Creates a new stack machine
|
||||
instance operating on the same database as the current stack machine, but
|
||||
|
@ -366,7 +366,7 @@ START_THREAD
|
|||
state. The new stack machine should begin executing instructions concurrent
|
||||
with the current stack machine through a language-appropriate mechanism.
|
||||
|
||||
WAIT_EMPTY
|
||||
#### WAIT_EMPTY
|
||||
|
||||
Pops the top item off of the stack as PREFIX. Blocks execution until the
|
||||
range with prefix PREFIX is not present in the database. This should be
|
||||
|
@ -378,7 +378,7 @@ WAIT_EMPTY
|
|||
Miscellaneous
|
||||
-------------
|
||||
|
||||
UNIT_TESTS
|
||||
#### UNIT_TESTS
|
||||
|
||||
This is called during the scripted test to allow bindings to test features
|
||||
which aren't supported by the stack tester. Things currently tested in the
|
|
@ -8,19 +8,19 @@ directory testing state.
|
|||
Additional State and Initialization
|
||||
-----------------------------------
|
||||
|
||||
Your tester should store three additional pieces of state.
|
||||
Your tester should store three additional pieces of state.
|
||||
|
||||
directory list - The items in this list should be accessible by index. The list
|
||||
should support an append operation. It will be required to store Subspaces,
|
||||
* directory list - The items in this list should be accessible by index. The list
|
||||
should support an append operation. It will be required to store Subspaces,
|
||||
DirectorySubspaces, and DirectoryLayers.
|
||||
|
||||
directory list index - an index into the directory list of the currently active
|
||||
* directory list index - an index into the directory list of the currently active
|
||||
directory.
|
||||
|
||||
error index - the index to use when the directory at directory list index is not
|
||||
* error index - the index to use when the directory at directory list index is not
|
||||
present
|
||||
|
||||
At the beginning of the test, the list should contain just the default directory
|
||||
At the beginning of the test, the list should contain just the default directory
|
||||
layer. The directory index and error index should both be set to 0.
|
||||
|
||||
Popping Tuples
|
||||
|
@ -29,14 +29,14 @@ Popping Tuples
|
|||
Some instructions will require you to pop N tuples. To do this, repeat the
|
||||
following procedure N times:
|
||||
|
||||
Pop 1 item off the stack as M. Pop M items off the stack as
|
||||
Pop 1 item off the stack as M. Pop M items off the stack as
|
||||
tuple = [item1, ..., itemM].
|
||||
|
||||
Errors
|
||||
------
|
||||
|
||||
In the even that you encounter an error when performing a directory layer
|
||||
operation, you should push the byte string: "DIRECTORY_ERROR" onto the stack. If
|
||||
operation, you should push the byte string: `"DIRECTORY_ERROR"` onto the stack. If
|
||||
the operation being performed was supposed to append an item to the directory
|
||||
list, then a null entry should be appended instead.
|
||||
|
||||
|
@ -46,65 +46,65 @@ New Instructions
|
|||
Below are the new instructions that must be implemented to test the directory
|
||||
layer. Some instructions specify that the current directory should be used
|
||||
for the operation. In that case, use the object in the directory list specified
|
||||
by the current directory list index. Operations that are not defined for a
|
||||
by the current directory list index. Operations that are not defined for a
|
||||
particular object will not be called (e.g. a DirectoryLayer will never be asked
|
||||
to pack a key).
|
||||
|
||||
Directory/Subspace/Layer Creation
|
||||
---------------------------------
|
||||
|
||||
DIRECTORY_CREATE_SUBSPACE
|
||||
#### DIRECTORY_CREATE_SUBSPACE
|
||||
|
||||
Pop 1 tuple off the stack as [path]. Pop 1 additional item as [raw_prefix].
|
||||
Create a subspace with path as the prefix tuple and the specified
|
||||
Create a subspace with path as the prefix tuple and the specified
|
||||
raw_prefix. Append it to the directory list.
|
||||
|
||||
DIRECTORY_CREATE_LAYER
|
||||
#### DIRECTORY_CREATE_LAYER
|
||||
|
||||
Pop 3 items off the stack as [index1, index2, allow_manual_prefixes]. Let
|
||||
node_subspace be the object in the directory list at index1 and
|
||||
content_subspace be the object in the directory list at index2. Create a new
|
||||
directory layer with the specified node_subspace and content_subspace. If
|
||||
Pop 3 items off the stack as [index1, index2, allow_manual_prefixes]. Let
|
||||
node_subspace be the object in the directory list at index1 and
|
||||
content_subspace be the object in the directory list at index2. Create a new
|
||||
directory layer with the specified node_subspace and content_subspace. If
|
||||
allow_manual_prefixes is 1, then enable manual prefixes on the directory
|
||||
layer. Append the resulting directory layer to the directory list.
|
||||
|
||||
If either of the two specified subspaces are null, then do not create a
|
||||
If either of the two specified subspaces are null, then do not create a
|
||||
directory layer and instead push null onto the directory list.
|
||||
|
||||
DIRECTORY_CREATE_OR_OPEN[_DATABASE]
|
||||
#### DIRECTORY_CREATE_OR_OPEN[_DATABASE]
|
||||
|
||||
Use the current directory for this operation.
|
||||
|
||||
Pop 1 tuple off the stack as [path]. Pop 1 additional item as [layer].
|
||||
create_or_open a directory with the specified path and layer. If layer is
|
||||
Pop 1 tuple off the stack as [path]. Pop 1 additional item as [layer].
|
||||
create_or_open a directory with the specified path and layer. If layer is
|
||||
null, use the default value for that parameter.
|
||||
|
||||
DIRECTORY_CREATE[_DATABASE]
|
||||
#### DIRECTORY_CREATE[_DATABASE]
|
||||
|
||||
Pop 1 tuple off the stack as [path]. Pop 2 additional items as
|
||||
[layer, prefix]. create a directory with the specified path, layer,
|
||||
and prefix. If either of layer or prefix is null, use the default value for
|
||||
Pop 1 tuple off the stack as [path]. Pop 2 additional items as
|
||||
[layer, prefix]. create a directory with the specified path, layer,
|
||||
and prefix. If either of layer or prefix is null, use the default value for
|
||||
that parameter (layer='', prefix=null).
|
||||
|
||||
DIRECTORY_OPEN[_DATABASE|_SNAPSHOT]
|
||||
#### DIRECTORY_OPEN[_DATABASE|_SNAPSHOT]
|
||||
|
||||
Use the current directory for this operation.
|
||||
|
||||
Pop 1 tuple off the stack as [path]. Pop 1 additional item as [layer]. Open
|
||||
a directory with the specified path and layer. If layer is null, use the
|
||||
Pop 1 tuple off the stack as [path]. Pop 1 additional item as [layer]. Open
|
||||
a directory with the specified path and layer. If layer is null, use the
|
||||
default value (layer='').
|
||||
|
||||
Directory Management
|
||||
--------------------
|
||||
|
||||
DIRECTORY_CHANGE
|
||||
#### DIRECTORY_CHANGE
|
||||
|
||||
Pop the top item off the stack as [index]. Set the current directory list
|
||||
index to index. In the event that the directory at this new index is null
|
||||
(as the result of a previous error), set the directory list index to the
|
||||
(as the result of a previous error), set the directory list index to the
|
||||
error index.
|
||||
|
||||
DIRECTORY_SET_ERROR_INDEX
|
||||
#### DIRECTORY_SET_ERROR_INDEX
|
||||
|
||||
Pop the top item off the stack as [error_index]. Set the current error index
|
||||
to error_index.
|
||||
|
@ -112,130 +112,130 @@ DIRECTORY_SET_ERROR_INDEX
|
|||
Directory Operations
|
||||
--------------------
|
||||
|
||||
DIRECTORY_MOVE[_DATABASE]
|
||||
#### DIRECTORY_MOVE[_DATABASE]
|
||||
|
||||
Use the current directory for this operation.
|
||||
|
||||
Pop 2 tuples off the stack as [old_path, new_path]. Call move with the
|
||||
Pop 2 tuples off the stack as [old_path, new_path]. Call move with the
|
||||
specified old_path and new_path. Append the result onto the directory list.
|
||||
|
||||
DIRECTORY_MOVE_TO[_DATABASE]
|
||||
#### DIRECTORY_MOVE_TO[_DATABASE]
|
||||
|
||||
Use the current directory for this operation.
|
||||
|
||||
Pop 1 tuple off the stack as [new_absolute_path]. Call moveTo with the
|
||||
Pop 1 tuple off the stack as [new_absolute_path]. Call moveTo with the
|
||||
specified new_absolute_path. Append the result onto the directory list.
|
||||
|
||||
DIRECTORY_REMOVE[_DATABASE]
|
||||
#### DIRECTORY_REMOVE[_DATABASE]
|
||||
|
||||
Use the current directory for this operation.
|
||||
|
||||
Pop 1 item off the stack as [count] (either 0 or 1). If count is 1, pop 1
|
||||
tuple off the stack as [path]. Call remove, passing it path if one was
|
||||
tuple off the stack as [path]. Call remove, passing it path if one was
|
||||
popped.
|
||||
|
||||
DIRECTORY_REMOVE_IF_EXISTS[_DATABASE]
|
||||
#### DIRECTORY_REMOVE_IF_EXISTS[_DATABASE]
|
||||
|
||||
Use the current directory for this operation.
|
||||
|
||||
Pop 1 item off the stack as [count] (either 0 or 1). If count is 1, pop 1
|
||||
tuple off the stack as [path]. Call remove_if_exits, passing it path if one
|
||||
tuple off the stack as [path]. Call remove_if_exits, passing it path if one
|
||||
was popped.
|
||||
|
||||
DIRECTORY_LIST[_DATABASE|_SNAPSHOT]
|
||||
#### DIRECTORY_LIST[_DATABASE|_SNAPSHOT]
|
||||
|
||||
Use the current directory for this operation.
|
||||
|
||||
Pop 1 item off the stack as [count] (either 0 or 1). If count is 1, pop 1
|
||||
tuple off the stack as [path]. Call list, passing it path if one was popped.
|
||||
Pack the resulting list of directories using the tuple layer and push the
|
||||
tuple off the stack as [path]. Call list, passing it path if one was popped.
|
||||
Pack the resulting list of directories using the tuple layer and push the
|
||||
packed string onto the stack.
|
||||
|
||||
DIRECTORY_EXISTS[_DATABASE|_SNAPSHOT]
|
||||
#### DIRECTORY_EXISTS[_DATABASE|_SNAPSHOT]
|
||||
|
||||
Use the current directory for this operation.
|
||||
|
||||
Pop 1 item off the stack as [count] (either 0 or 1). If count is 1, pop 1
|
||||
tuple off the stack as [path]. Call exists, passing it path if one
|
||||
tuple off the stack as [path]. Call exists, passing it path if one
|
||||
was popped. Push 1 onto the stack if the path exists and 0 if it does not.
|
||||
|
||||
Subspace Operations
|
||||
-------------------
|
||||
|
||||
DIRECTORY_PACK_KEY
|
||||
#### DIRECTORY_PACK_KEY
|
||||
|
||||
Use the current directory for this operation.
|
||||
|
||||
Pop 1 tuple off the stack as [key_tuple]. Pack key_tuple and push the result
|
||||
onto the stack.
|
||||
|
||||
DIRECTORY_UNPACK_KEY
|
||||
#### DIRECTORY_UNPACK_KEY
|
||||
|
||||
Use the current directory for this operation.
|
||||
|
||||
Pop 1 item off the stack as [key]. Unpack key and push the resulting tuple
|
||||
onto the stack one item at a time.
|
||||
|
||||
DIRECTORY_RANGE
|
||||
#### DIRECTORY_RANGE
|
||||
|
||||
Use the current directory for this operation.
|
||||
|
||||
Pop 1 tuple off the stack as [tuple]. Create a range using tuple and push
|
||||
Pop 1 tuple off the stack as [tuple]. Create a range using tuple and push
|
||||
range.begin and range.end onto the stack.
|
||||
|
||||
DIRECTORY_CONTAINS
|
||||
#### DIRECTORY_CONTAINS
|
||||
|
||||
Use the current directory for this operation.
|
||||
|
||||
Pop 1 item off the stack as [key]. Check if the current directory contains
|
||||
the specified key. Push 1 if it does and 0 if it doesn't.
|
||||
|
||||
DIRECTORY_OPEN_SUBSPACE
|
||||
#### DIRECTORY_OPEN_SUBSPACE
|
||||
|
||||
Use the current directory for this operation.
|
||||
|
||||
Pop 1 tuple off the stack as [tuple]. Open the subspace of the current
|
||||
Pop 1 tuple off the stack as [tuple]. Open the subspace of the current
|
||||
directory specified by tuple and push it onto the directory list.
|
||||
|
||||
Directory Logging
|
||||
--------------------
|
||||
|
||||
DIRECTORY_LOG_SUBSPACE
|
||||
#### DIRECTORY_LOG_SUBSPACE
|
||||
|
||||
Use the current directory for this operation.
|
||||
|
||||
Pop 1 item off the stack as [prefix]. Let key equal
|
||||
Pop 1 item off the stack as [prefix]. Let key equal
|
||||
prefix + tuple.pack([dir_index]). Set key to be the result of calling
|
||||
directory.key() in the current transaction.
|
||||
directory.key() in the current transaction.
|
||||
|
||||
DIRECTORY_LOG_DIRECTORY
|
||||
#### DIRECTORY_LOG_DIRECTORY
|
||||
|
||||
Use the current directory for this operation.
|
||||
|
||||
Pop 1 item off the stack as [raw_prefix]. Create a subspace log_subspace
|
||||
Pop 1 item off the stack as [raw_prefix]. Create a subspace log_subspace
|
||||
with path (dir_index) and the specified raw_prefix. Set:
|
||||
|
||||
tr[log_subspace[u'path']] = the tuple packed path of the directory.
|
||||
|
||||
tr[log_subspace[u'layer']] = the tuple packed layer of the directory.
|
||||
|
||||
tr[log_subspace[u'exists']] = the packed tuple containing a 1 if the
|
||||
tr[log_subspace[u'exists']] = the packed tuple containing a 1 if the
|
||||
directory exists and 0 if it doesn't.
|
||||
|
||||
tr[log_subspace[u'children']] the tuple packed list of children of the
|
||||
tr[log_subspace[u'children']] the tuple packed list of children of the
|
||||
directory.
|
||||
|
||||
Where log_subspace[u<str>] is the subspace packed tuple containing only the
|
||||
Where log_subspace[u<str>] is the subspace packed tuple containing only the
|
||||
single specified unicode string <str>.
|
||||
|
||||
Other
|
||||
-----
|
||||
|
||||
DIRECTORY_STRIP_PREFIX
|
||||
#### DIRECTORY_STRIP_PREFIX
|
||||
|
||||
Use the current directory for this operation.
|
||||
|
||||
Pop 1 item off the stack as [byte_array]. Call .key() on the current
|
||||
subspace and store the result as [prefix]. Throw an error if the popped
|
||||
array does not start with prefix. Otherwise, remove the prefix from the
|
||||
Pop 1 item off the stack as [byte_array]. Call .key() on the current
|
||||
subspace and store the result as [prefix]. Throw an error if the popped
|
||||
array does not start with prefix. Otherwise, remove the prefix from the
|
||||
popped array and push the result onto the stack.
|
|
@ -340,9 +340,9 @@ class DirectoryTest(Test):
|
|||
# errors += directory_util.check_for_duplicate_prefixes(db, self.prefix_log)
|
||||
return errors
|
||||
|
||||
def get_result_specfications(self):
|
||||
def get_result_specifications(self):
|
||||
return [
|
||||
ResultSpecification(self.stack, key_start_index=1, ordering_index=1),
|
||||
ResultSpecification(self.stack_subspace, key_start_index=1, ordering_index=1),
|
||||
ResultSpecification(self.directory_log, ordering_index=0),
|
||||
ResultSpecification(self.subspace_log, ordering_index=0)
|
||||
]
|
||||
|
|
|
@ -34,7 +34,7 @@ fdb.api_version(FDB_API_VERSION)
|
|||
|
||||
|
||||
class ScriptedTest(Test):
|
||||
TEST_API_VERSION = 510
|
||||
TEST_API_VERSION = 520
|
||||
|
||||
def __init__(self, subspace):
|
||||
super(ScriptedTest, self).__init__(subspace, ScriptedTest.TEST_API_VERSION, ScriptedTest.TEST_API_VERSION)
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#define FDB_API_VERSION 510
|
||||
#define FDB_API_VERSION 520
|
||||
|
||||
#include "fdbclient/MultiVersionTransaction.h"
|
||||
#include "foundationdb/fdb_c.h"
|
||||
|
|
|
@ -28,10 +28,10 @@
|
|||
#endif
|
||||
|
||||
#if !defined(FDB_API_VERSION)
|
||||
#error You must #define FDB_API_VERSION prior to including fdb_c.h (current version is 510)
|
||||
#error You must #define FDB_API_VERSION prior to including fdb_c.h (current version is 520)
|
||||
#elif FDB_API_VERSION < 13
|
||||
#error API version no longer supported (upgrade to 13)
|
||||
#elif FDB_API_VERSION > 510
|
||||
#elif FDB_API_VERSION > 520
|
||||
#error Requested API version requires a newer version of this header
|
||||
#endif
|
||||
|
||||
|
@ -241,7 +241,7 @@ extern "C" {
|
|||
fdb_transaction_get_committed_version( FDBTransaction* tr,
|
||||
int64_t* out_version );
|
||||
|
||||
DLLEXPORT WARN_UNUSED_RESULT FDBFuture* fdb_transaction_get_versionstamp( FDBTransaction* tr );
|
||||
DLLEXPORT WARN_UNUSED_RESULT FDBFuture* fdb_transaction_get_versionstamp( FDBTransaction* tr );
|
||||
|
||||
DLLEXPORT WARN_UNUSED_RESULT FDBFuture*
|
||||
fdb_transaction_on_error( FDBTransaction* tr, fdb_error_t error );
|
||||
|
@ -276,7 +276,7 @@ extern "C" {
|
|||
|
||||
DLLEXPORT fdb_bool_t fdb_future_is_error( FDBFuture* f );
|
||||
#else
|
||||
#define fdb_future_is_error(x) FDB_REMOVED_FUNCTION
|
||||
#define fdb_future_is_error(x) FDB_REMOVED_FUNCTION
|
||||
#endif
|
||||
|
||||
#if FDB_API_VERSION < 14
|
||||
|
@ -307,7 +307,7 @@ extern "C" {
|
|||
int end_key_name_length, fdb_bool_t end_or_equal, int end_offset,
|
||||
int limit );
|
||||
#else
|
||||
#define fdb_transaction_get_range_selector(tr,bkn,bknl,boe,bo,ekn,eknl,eoe,eo,lim) FDB_REMOVED_FUNCTION
|
||||
#define fdb_transaction_get_range_selector(tr,bkn,bknl,boe,bo,ekn,eknl,eoe,eo,lim) FDB_REMOVED_FUNCTION
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -26,6 +26,8 @@ fdb_c_LIBS := lib/libfdbclient.a lib/libfdbrpc.a lib/libflow.a
|
|||
fdb_c_tests_LIBS := -Llib -lfdb_c
|
||||
fdb_c_tests_HEADERS := -Ibindings/c
|
||||
|
||||
CLEAN_TARGETS += fdb_c_tests_clean
|
||||
|
||||
ifeq ($(PLATFORM),linux)
|
||||
fdb_c_LIBS += lib/libstdc++.a -lm -lpthread -lrt -ldl
|
||||
fdb_c_LDFLAGS += -Wl,--version-script=bindings/c/fdb_c.map -static-libgcc -Wl,-z,nodelete
|
||||
|
@ -98,4 +100,5 @@ packages/fdb-c-tests-$(VERSION)-$(PLATFORM).tar.gz: bin/fdb_c_performance_test b
|
|||
|
||||
fdb_c_tests: packages/fdb-c-tests-$(VERSION)-$(PLATFORM).tar.gz
|
||||
|
||||
packages: fdb_c_tests
|
||||
fdb_c_tests_clean:
|
||||
@rm -f packages/fdb-c-tests-$(VERSION)-$(PLATFORM).tar.gz
|
||||
|
|
|
@ -602,7 +602,7 @@ void runTests(struct ResultSet *rs) {
|
|||
int main(int argc, char **argv) {
|
||||
srand(time(NULL));
|
||||
struct ResultSet *rs = newResultSet();
|
||||
checkError(fdb_select_api_version(510), "select API version", rs);
|
||||
checkError(fdb_select_api_version(520), "select API version", rs);
|
||||
printf("Running performance test at client version: %s\n", fdb_get_client_version());
|
||||
|
||||
valueStr = (uint8_t*)malloc((sizeof(uint8_t))*valueSize);
|
||||
|
|
|
@ -243,7 +243,7 @@ void runTests(struct ResultSet *rs) {
|
|||
int main(int argc, char **argv) {
|
||||
srand(time(NULL));
|
||||
struct ResultSet *rs = newResultSet();
|
||||
checkError(fdb_select_api_version(510), "select API version", rs);
|
||||
checkError(fdb_select_api_version(520), "select API version", rs);
|
||||
printf("Running RYW Benchmark test at client version: %s\n", fdb_get_client_version());
|
||||
|
||||
keys = generateKeys(numKeys, keySize);
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
#include <pthread.h>
|
||||
|
||||
#ifndef FDB_API_VERSION
|
||||
#define FDB_API_VERSION 510
|
||||
#define FDB_API_VERSION 520
|
||||
#endif
|
||||
|
||||
#include <foundationdb/fdb_c.h>
|
||||
|
|
|
@ -140,8 +140,13 @@ namespace FDB {
|
|||
API::API(int version) : version(version) {}
|
||||
|
||||
API* API::selectAPIVersion(int apiVersion) {
|
||||
if(API::instance && apiVersion != API::instance->version) {
|
||||
throw api_version_already_set();
|
||||
if(API::instance) {
|
||||
if(apiVersion != API::instance->version) {
|
||||
throw api_version_already_set();
|
||||
}
|
||||
else {
|
||||
return API::instance;
|
||||
}
|
||||
}
|
||||
|
||||
if(apiVersion < 500 || apiVersion > FDB_API_VERSION) {
|
||||
|
@ -150,13 +155,23 @@ namespace FDB {
|
|||
|
||||
throw_on_error( fdb_select_api_version_impl(apiVersion, FDB_API_VERSION) );
|
||||
|
||||
if(!API::instance) {
|
||||
API::instance = new API(apiVersion);
|
||||
}
|
||||
|
||||
API::instance = new API(apiVersion);
|
||||
return API::instance;
|
||||
}
|
||||
|
||||
bool API::isAPIVersionSelected() {
|
||||
return API::instance != NULL;
|
||||
}
|
||||
|
||||
API* API::getInstance() {
|
||||
if(API::instance == NULL) {
|
||||
throw api_version_unset();
|
||||
}
|
||||
else {
|
||||
return API::instance;
|
||||
}
|
||||
}
|
||||
|
||||
void API::setupNetwork() {
|
||||
throw_on_error( fdb_setup_network() );
|
||||
}
|
||||
|
@ -183,6 +198,10 @@ namespace FDB {
|
|||
return Reference<Cluster>( new Cluster(c) );
|
||||
}
|
||||
|
||||
int API::getAPIVersion() const {
|
||||
return version;
|
||||
}
|
||||
|
||||
Reference<DatabaseContext> Cluster::createDatabase() {
|
||||
const char *dbName = "DB";
|
||||
CFuture f( fdb_cluster_create_database( c, (uint8_t*)dbName, (int)strlen(dbName) ) );
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
|
||||
#include <flow/flow.h>
|
||||
|
||||
#define FDB_API_VERSION 510
|
||||
#define FDB_API_VERSION 520
|
||||
#include <bindings/c/foundationdb/fdb_c.h>
|
||||
#undef DLLEXPORT
|
||||
|
||||
|
@ -64,6 +64,8 @@ namespace FDB {
|
|||
class API {
|
||||
public:
|
||||
static API* selectAPIVersion(int apiVersion);
|
||||
static API* getInstance();
|
||||
static bool isAPIVersionSelected();
|
||||
|
||||
void setNetworkOption(FDBNetworkOption option, Optional<StringRef> value = Optional<StringRef>());
|
||||
|
||||
|
@ -74,6 +76,7 @@ namespace FDB {
|
|||
Reference<Cluster> createCluster( std::string const& connFilename );
|
||||
|
||||
bool evaluatePredicate(FDBErrorPredicate pred, Error const& e);
|
||||
int getAPIVersion() const;
|
||||
|
||||
private:
|
||||
static API* instance;
|
||||
|
|
|
@ -1510,6 +1510,25 @@ struct UnitTestsFunc : InstructionFunc {
|
|||
ASSERT(data->api->evaluatePredicate(FDBErrorPredicate::FDB_ERROR_PREDICATE_RETRYABLE, Error(1020)));
|
||||
ASSERT(!data->api->evaluatePredicate(FDBErrorPredicate::FDB_ERROR_PREDICATE_RETRYABLE, Error(10)));
|
||||
|
||||
ASSERT(API::isAPIVersionSelected());
|
||||
state API *fdb = API::getInstance();
|
||||
ASSERT(fdb->getAPIVersion() <= FDB_API_VERSION);
|
||||
try {
|
||||
API::selectAPIVersion(fdb->getAPIVersion() + 1);
|
||||
ASSERT(false);
|
||||
}
|
||||
catch(Error &e) {
|
||||
ASSERT(e.code() == error_code_api_version_already_set);
|
||||
}
|
||||
try {
|
||||
API::selectAPIVersion(fdb->getAPIVersion() - 1);
|
||||
ASSERT(false);
|
||||
}
|
||||
catch(Error &e) {
|
||||
ASSERT(e.code() == error_code_api_version_already_set);
|
||||
}
|
||||
API::selectAPIVersion(fdb->getAPIVersion());
|
||||
|
||||
state Reference<Transaction> tr(new Transaction(data->db));
|
||||
tr->setOption(FDBTransactionOption::FDB_TR_OPTION_PRIORITY_SYSTEM_IMMEDIATE);
|
||||
tr->setOption(FDBTransactionOption::FDB_TR_OPTION_PRIORITY_SYSTEM_IMMEDIATE);
|
||||
|
@ -1517,10 +1536,8 @@ struct UnitTestsFunc : InstructionFunc {
|
|||
tr->setOption(FDBTransactionOption::FDB_TR_OPTION_CAUSAL_READ_RISKY);
|
||||
tr->setOption(FDBTransactionOption::FDB_TR_OPTION_CAUSAL_WRITE_RISKY);
|
||||
tr->setOption(FDBTransactionOption::FDB_TR_OPTION_READ_YOUR_WRITES_DISABLE);
|
||||
tr->setOption(FDBTransactionOption::FDB_TR_OPTION_READ_AHEAD_DISABLE);
|
||||
tr->setOption(FDBTransactionOption::FDB_TR_OPTION_READ_SYSTEM_KEYS);
|
||||
tr->setOption(FDBTransactionOption::FDB_TR_OPTION_ACCESS_SYSTEM_KEYS);
|
||||
tr->setOption(FDBTransactionOption::FDB_TR_OPTION_DURABILITY_DEV_NULL_IS_WEB_SCALE);
|
||||
const uint64_t timeout = 60*1000;
|
||||
tr->setOption(FDBTransactionOption::FDB_TR_OPTION_TIMEOUT, Optional<StringRef>(StringRef((const uint8_t*)&timeout, 8)));
|
||||
const uint64_t retryLimit = 50;
|
||||
|
@ -1574,7 +1591,7 @@ ACTOR static Future<Void> doInstructions(Reference<FlowTesterData> data) {
|
|||
try {
|
||||
if(LOG_INSTRUCTIONS) {
|
||||
if(op != LiteralStringRef("SWAP") && op != LiteralStringRef("PUSH")) {
|
||||
printf("%lu. %s\n", idx, tupleToString(opTuple).c_str());
|
||||
printf("%zu. %s\n", idx, tupleToString(opTuple).c_str());
|
||||
fflush(stdout);
|
||||
}
|
||||
}
|
||||
|
@ -1682,7 +1699,18 @@ ACTOR void startTest(std::string clusterFilename, StringRef prefix, int apiVersi
|
|||
// This is "our" network
|
||||
g_network = newNet2(NetworkAddress(), false);
|
||||
|
||||
ASSERT(!API::isAPIVersionSelected());
|
||||
try {
|
||||
API::getInstance();
|
||||
ASSERT(false);
|
||||
}
|
||||
catch(Error& e) {
|
||||
ASSERT(e.code() == error_code_api_version_unset);
|
||||
}
|
||||
|
||||
API *fdb = API::selectAPIVersion(apiVersion);
|
||||
ASSERT(API::isAPIVersionSelected());
|
||||
ASSERT(fdb->getAPIVersion() == apiVersion);
|
||||
//fdb->setNetworkOption(FDBNetworkOption::FDB_NET_OPTION_TRACE_ENABLE);
|
||||
|
||||
// We have to start the fdb_flow network and thread separately!
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
fdb-go
|
||||
======
|
||||
|
||||
[Go language](http://golang.org) bindings for [FoundationDB](http://foundationdb.org/documentation/), a distributed key-value store with ACID transactions.
|
||||
[Go language](http://golang.org) bindings for [FoundationDB](https://apple.github.io/foundationdb/index.html#documentation), a distributed key-value store with ACID transactions.
|
||||
|
||||
This package requires:
|
||||
|
||||
- Go 1.1+ with CGO enabled
|
||||
- FoundationDB C API 2.0.x, 3.0.x, or 4.x.y (part of the [FoundationDB clients package](https://files.foundationdb.org/fdb-c/))
|
||||
- FoundationDB C API 2.0.x, 3.0.x, or 4.x.y (part of the [FoundationDB clients package](https://apple.github.io/foundationdb/downloads.html#c))
|
||||
|
||||
Use of this package requires the selection of a FoundationDB API version at runtime. This package currently supports FoundationDB API versions 200-510.
|
||||
Use of this package requires the selection of a FoundationDB API version at runtime. This package currently supports FoundationDB API versions 200-520.
|
||||
|
||||
To build this package, in the top level of this repository run:
|
||||
|
||||
|
@ -27,5 +27,5 @@ of downloading from the remote repository.
|
|||
Documentation
|
||||
-------------
|
||||
|
||||
* [API documentation](https://foundationdb.org/documentation/godoc/fdb.html)
|
||||
* [Tutorial](https://foundationdb.org/documentation/class-scheduling-go.html)
|
||||
* [API documentation](https://godoc.org/github.com/apple/foundationdb/bindings/go/src/fdb)
|
||||
* [Tutorial](https://apple.github.io/foundationdb/class-scheduling.html)
|
||||
|
|
|
@ -167,7 +167,7 @@ else
|
|||
|
||||
if [[ "${status}" -eq 0 ]] ; then
|
||||
destdir=$( cd "${destdir}" && pwd ) # Get absolute path of destination dir.
|
||||
fdbdir="${destdir}/foundation"
|
||||
fdbdir="${destdir}/foundationdb"
|
||||
|
||||
if [[ ! -d "${destdir}" ]] ; then
|
||||
cmd=("mkdir" "-p" "${destdir}")
|
||||
|
|
|
@ -25,7 +25,7 @@ GOPATH := $(CURDIR)/bindings/go/build
|
|||
GO_IMPORT_PATH := github.com/apple/foundationdb/bindings/go/src
|
||||
GO_DEST := $(GOPATH)/src/$(GO_IMPORT_PATH)
|
||||
|
||||
.PHONY: fdb_go fdb_go_path fdb_go_tester fdb_go_tester_clean godoc godoc_clean
|
||||
.PHONY: fdb_go fdb_go_path fdb_go_fmt fdb_go_fmt_check fdb_go_tester fdb_go_tester_clean
|
||||
|
||||
# We only override if the environment didn't set it (this is used by
|
||||
# the fdbwebsite documentation build process)
|
||||
|
@ -47,9 +47,10 @@ GO_PACKAGE_OUTDIR := $(GOPATH)/pkg/$(GOPLATFORM)/$(GO_IMPORT_PATH)
|
|||
GO_PACKAGES := fdb fdb/tuple fdb/subspace fdb/directory
|
||||
GO_PACKAGE_OBJECTS := $(addprefix $(GO_PACKAGE_OUTDIR)/,$(GO_PACKAGES:=.a))
|
||||
|
||||
GO_SRC := $(shell find $(CURDIR)/bindings/go/src -name '*.go')
|
||||
GO_GEN := $(CURDIR)/bindings/go/src/fdb/generated.go
|
||||
GO_SRC := $(shell find $(CURDIR)/bindings/go/src -name '*.go') $(GO_GEN)
|
||||
|
||||
fdb_go: $(GO_PACKAGE_OBJECTS) $(GO_SRC)
|
||||
fdb_go: $(GO_PACKAGE_OBJECTS) $(GO_SRC) fdb_go_fmt_check
|
||||
|
||||
fdb_go_fmt: $(GO_SRC)
|
||||
@echo "Formatting fdb_go"
|
||||
|
@ -59,10 +60,13 @@ fdb_go_fmt_check: $(GO_SRC)
|
|||
@echo "Checking fdb_go"
|
||||
@bash -c 'fmtoutstr=$$(gofmt -l $(GO_SRC)) ; if [[ -n "$${fmtoutstr}" ]] ; then echo "Detected go formatting violations for the following files:" ; echo "$${fmtoutstr}" ; echo "Try running: make fdb_go_fmt"; exit 1 ; fi'
|
||||
|
||||
fdb_go_path: $(GO_SRC)
|
||||
$(GO_DEST)/.stamp: $(GO_SRC)
|
||||
@echo "Creating fdb_go_path"
|
||||
@mkdir -p $(GO_DEST)
|
||||
@cp -r bindings/go/src/* $(GO_DEST)
|
||||
@touch $(GO_DEST)/.stamp
|
||||
|
||||
fdb_go_path: $(GO_DEST)/.stamp
|
||||
|
||||
fdb_go_clean:
|
||||
@echo "Cleaning fdb_go"
|
||||
|
@ -74,47 +78,26 @@ fdb_go_tester_clean:
|
|||
@echo "Cleaning fdb_go_tester"
|
||||
@rm -rf $(GOPATH)/bin
|
||||
|
||||
$(GOPATH)/bin/_stacktester: fdb_go_path fdb_go_fmt_check $(GO_SRC) $(GO_PACKAGE_OBJECTS) $(GO_DEST)/fdb/generated.go
|
||||
$(GOPATH)/bin/_stacktester: $(GO_DEST)/.stamp $(GO_SRC) $(GO_PACKAGE_OBJECTS)
|
||||
@echo "Compiling $(basename $(notdir $@))"
|
||||
@go install $(GO_IMPORT_PATH)/_stacktester
|
||||
|
||||
$(GO_PACKAGE_OUTDIR)/fdb/tuple.a: fdb_go_path fdb_go_fmt_check $(GO_SRC) $(GO_PACKAGE_OUTDIR)/fdb.a $(GO_DEST)/fdb/generated.go
|
||||
$(GO_PACKAGE_OUTDIR)/fdb/tuple.a: $(GO_DEST)/.stamp $(GO_SRC) $(GO_PACKAGE_OUTDIR)/fdb.a
|
||||
@echo "Compiling fdb/tuple"
|
||||
@go install $(GO_IMPORT_PATH)/fdb/tuple
|
||||
|
||||
$(GO_PACKAGE_OUTDIR)/fdb/subspace.a: fdb_go_path fdb_go_fmt_check $(GO_SRC) $(GO_PACKAGE_OUTDIR)/fdb.a $(GO_PACKAGE_OUTDIR)/fdb/tuple.a $(GO_DEST)/fdb/generated.go
|
||||
$(GO_PACKAGE_OUTDIR)/fdb/subspace.a: $(GO_DEST)/.stamp $(GO_SRC) $(GO_PACKAGE_OUTDIR)/fdb.a $(GO_PACKAGE_OUTDIR)/fdb/tuple.a
|
||||
@echo "Compiling fdb/subspace"
|
||||
@go install $(GO_IMPORT_PATH)/fdb/subspace
|
||||
|
||||
$(GO_PACKAGE_OUTDIR)/fdb/directory.a: fdb_go_path fdb_go_fmt_check $(GO_SRC) $(GO_PACKAGE_OUTDIR)/fdb.a $(GO_PACKAGE_OUTDIR)/fdb/tuple.a $(GO_PACKAGE_OUTDIR)/fdb/subspace.a $(GO_DEST)/fdb/generated.go
|
||||
$(GO_PACKAGE_OUTDIR)/fdb/directory.a: $(GO_DEST)/.stamp $(GO_SRC) $(GO_PACKAGE_OUTDIR)/fdb.a $(GO_PACKAGE_OUTDIR)/fdb/tuple.a $(GO_PACKAGE_OUTDIR)/fdb/subspace.a
|
||||
@echo "Compiling fdb/directory"
|
||||
@go install $(GO_IMPORT_PATH)/fdb/directory
|
||||
|
||||
$(GO_PACKAGE_OUTDIR)/fdb.a: fdb_go_path fdb_go_fmt_check $(GO_SRC) $(GO_DEST)/fdb/generated.go
|
||||
$(GO_PACKAGE_OUTDIR)/fdb.a: $(GO_DEST)/.stamp lib/libfdb_c.$(DLEXT) $(GO_SRC)
|
||||
@echo "Compiling fdb"
|
||||
@go install $(GO_IMPORT_PATH)/fdb
|
||||
|
||||
$(GO_DEST)/fdb/generated.go: fdb_go_path fdb_go_fmt_check lib/libfdb_c.$(DLEXT) bindings/go/src/_util/translate_fdb_options.go fdbclient/vexillographer/fdb.options
|
||||
$(GO_GEN): bindings/go/src/_util/translate_fdb_options.go fdbclient/vexillographer/fdb.options
|
||||
@echo "Building $@"
|
||||
@go run bindings/go/src/_util/translate_fdb_options.go < fdbclient/vexillographer/fdb.options > $@
|
||||
|
||||
godoc: fdb_go_path $(GO_SRC)
|
||||
@echo "Generating Go Documentation"
|
||||
@rm -rf $(GODOC_DIR)/godoc
|
||||
@mkdir -p $(GODOC_DIR)/godoc
|
||||
@mkdir -p $(GODOC_DIR)/godoc/lib/godoc
|
||||
@godoc -url "pkg/$(GO_IMPORT_PATH)/fdb" > $(GODOC_DIR)/godoc/fdb.html
|
||||
@godoc -url "pkg/$(GO_IMPORT_PATH)/fdb/tuple" > $(GODOC_DIR)/godoc/fdb.tuple.html
|
||||
@godoc -url "pkg/$(GO_IMPORT_PATH)/fdb/subspace" > $(GODOC_DIR)/godoc/fdb.subspace.html
|
||||
@godoc -url "pkg/$(GO_IMPORT_PATH)/fdb/directory" > $(GODOC_DIR)/godoc/fdb.directory.html
|
||||
@cp $(CURDIR)/bindings/go/godoc-resources/* $(GODOC_DIR)/godoc/lib/godoc
|
||||
@echo "Mangling paths in Go Documentation"
|
||||
@(find $(GODOC_DIR)/godoc/ -name *.html -exec sed -i '' -e 's_/lib_lib_' {} \;)
|
||||
@(sed -i -e 's_a href="tuple/"_a href="fdb.tuple.html"_' $(GODOC_DIR)/godoc/fdb.html)
|
||||
@(sed -i -e 's_a href="subspace/"_a href="fdb.subspace.html"_' $(GODOC_DIR)/godoc/fdb.html)
|
||||
@(sed -i -e 's_a href="directory/"_a href="fdb.directory.html"_' $(GODOC_DIR)/godoc/fdb.html)
|
||||
|
||||
godoc_clean:
|
||||
@echo "Cleaning Go Documentation"
|
||||
@rm -rf $(GODOC_DIR)/godoc
|
||||
|
||||
|
|
|
@ -752,16 +752,41 @@ func (sm *StackMachine) processInst(idx int, inst tuple.Tuple) {
|
|||
db.Options().SetLocationCacheSize(100001)
|
||||
db.Options().SetMaxWatches(10001)
|
||||
|
||||
if !fdb.IsAPIVersionSelected() {
|
||||
log.Fatal("API version should be selected")
|
||||
}
|
||||
apiVersion := fdb.MustGetAPIVersion()
|
||||
if apiVersion == 0 {
|
||||
log.Fatal("API version is 0")
|
||||
}
|
||||
e1 := fdb.APIVersion(apiVersion + 1)
|
||||
if e1 != nil {
|
||||
fdbE := e1.(fdb.Error)
|
||||
if fdbE.Code != 2201 {
|
||||
panic(e1)
|
||||
}
|
||||
} else {
|
||||
log.Fatal("Was not stopped from selecting two API versions")
|
||||
}
|
||||
e2 := fdb.APIVersion(apiVersion - 1)
|
||||
if e2 != nil {
|
||||
fdbE := e2.(fdb.Error)
|
||||
if fdbE.Code != 2201 {
|
||||
panic(e2)
|
||||
}
|
||||
} else {
|
||||
log.Fatal("Was not stopped from selecting two API versions")
|
||||
}
|
||||
fdb.MustAPIVersion(apiVersion)
|
||||
|
||||
_, e := db.Transact(func(tr fdb.Transaction) (interface{}, error) {
|
||||
tr.Options().SetPrioritySystemImmediate()
|
||||
tr.Options().SetPriorityBatch()
|
||||
tr.Options().SetCausalReadRisky()
|
||||
tr.Options().SetCausalWriteRisky()
|
||||
tr.Options().SetReadYourWritesDisable()
|
||||
tr.Options().SetReadAheadDisable()
|
||||
tr.Options().SetReadSystemKeys()
|
||||
tr.Options().SetAccessSystemKeys()
|
||||
tr.Options().SetDurabilityDevNullIsWebScale()
|
||||
tr.Options().SetTimeout(60 * 1000)
|
||||
tr.Options().SetRetryLimit(50)
|
||||
tr.Options().SetMaxRetryDelay(100)
|
||||
|
@ -835,10 +860,17 @@ func main() {
|
|||
log.Fatal(e)
|
||||
}
|
||||
|
||||
if fdb.IsAPIVersionSelected() {
|
||||
log.Fatal("API version already selected")
|
||||
}
|
||||
|
||||
e = fdb.APIVersion(apiVersion)
|
||||
if e != nil {
|
||||
log.Fatal(e)
|
||||
}
|
||||
if fdb.MustGetAPIVersion() != apiVersion {
|
||||
log.Fatal("API version not equal to value selected")
|
||||
}
|
||||
|
||||
db, e = fdb.Open(clusterFile, []byte("DB"))
|
||||
if e != nil {
|
||||
|
|
|
@ -136,7 +136,7 @@ func (t Transaction) %s(key KeyConvertible, param []byte) {
|
|||
func writeEnum(scope Scope, opt Option, delta int) {
|
||||
fmt.Println()
|
||||
if opt.Description != "" {
|
||||
doc.ToText(os.Stdout, opt.Description, " // ", "", 73)
|
||||
doc.ToText(os.Stdout, opt.Description, "\t// ", "", 73)
|
||||
// fmt.Printf(" // %s\n", opt.Description)
|
||||
}
|
||||
fmt.Printf(" %s %s = %d\n", scope.Name+translateName(opt.Name), scope.Name, opt.Code+delta)
|
||||
|
@ -157,14 +157,34 @@ func main() {
|
|||
log.Fatal(err)
|
||||
}
|
||||
|
||||
fmt.Print(`// DO NOT EDIT THIS FILE BY HAND. This file was generated using
|
||||
// translate_fdb_options.go, part of the fdb-go repository, and a copy of the
|
||||
// fdb.options file (installed as part of the FoundationDB client, typically
|
||||
fmt.Print(`/*
|
||||
* generated.go
|
||||
*
|
||||
* This source file is part of the FoundationDB open source project
|
||||
*
|
||||
* Copyright 2013-2018 Apple Inc. and the FoundationDB project authors
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
// DO NOT EDIT THIS FILE BY HAND. This file was generated using
|
||||
// translate_fdb_options.go, part of the FoundationDB repository, and a copy of
|
||||
// the fdb.options file (installed as part of the FoundationDB client, typically
|
||||
// found as /usr/include/foundationdb/fdb.options).
|
||||
|
||||
// To regenerate this file, from the top level of an fdb-go repository checkout,
|
||||
// run:
|
||||
// $ go run _util/translate_fdb_options.go < /usr/include/foundationdb/fdb.options > fdb/generated.go
|
||||
// To regenerate this file, from the top level of a FoundationDB repository
|
||||
// checkout, run:
|
||||
// $ go run bindings/go/src/_util/translate_fdb_options.go < fdbclient/vexillographer/fdb.options > bindings/go/src/fdb/generated.go
|
||||
|
||||
package fdb
|
||||
|
||||
|
@ -216,6 +236,7 @@ func int64ToBytes(i int64) ([]byte, error) {
|
|||
|
||||
fmt.Printf(`
|
||||
type %s int
|
||||
|
||||
const (
|
||||
`, scope.Name)
|
||||
for _, opt := range scope.Option {
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
package fdb
|
||||
|
||||
/*
|
||||
#define FDB_API_VERSION 510
|
||||
#define FDB_API_VERSION 520
|
||||
#include <foundationdb/fdb_c.h>
|
||||
*/
|
||||
import "C"
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
package fdb
|
||||
|
||||
/*
|
||||
#define FDB_API_VERSION 510
|
||||
#define FDB_API_VERSION 520
|
||||
#include <foundationdb/fdb_c.h>
|
||||
*/
|
||||
import "C"
|
||||
|
@ -111,7 +111,7 @@ func retryable(wrapped func() (interface{}, error), onError func(Error) FutureNi
|
|||
// retried or, if fatal, return the error to the caller.
|
||||
//
|
||||
// When working with Future objects in a transactional function, you may either
|
||||
// explicity check and return error values using Get, or call MustGet. Transact
|
||||
// explicitly check and return error values using Get, or call MustGet. Transact
|
||||
// will recover a panicked Error and either retry the transaction or return the
|
||||
// error.
|
||||
//
|
||||
|
@ -151,7 +151,7 @@ func (d Database) Transact(f func(Transaction) (interface{}, error)) (interface{
|
|||
// retried or, if fatal, return the error to the caller.
|
||||
//
|
||||
// When working with Future objects in a read-only transactional function, you
|
||||
// may either explicity check and return error values using Get, or call
|
||||
// may either explicitly check and return error values using Get, or call
|
||||
// MustGet. ReadTransact will recover a panicked Error and either retry the
|
||||
// transaction or return the error.
|
||||
//
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
//
|
||||
// For general guidance on directory usage, see the Directories section of the
|
||||
// Developer Guide
|
||||
// (https://foundationdb.org/documentation/developer-guide.html#developer-guide-directories).
|
||||
// (https://apple.github.io/foundationdb/developer-guide.html#directories).
|
||||
//
|
||||
// Directories are identified by hierarchical paths analogous to the paths in a
|
||||
// Unix-like file system. A path is represented as a slice of strings. Each
|
||||
|
|
|
@ -27,6 +27,7 @@ import (
|
|||
"encoding/binary"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/apple/foundationdb/bindings/go/src/fdb"
|
||||
"github.com/apple/foundationdb/bindings/go/src/fdb/subspace"
|
||||
"github.com/apple/foundationdb/bindings/go/src/fdb/tuple"
|
||||
|
@ -78,9 +79,8 @@ func (dl directoryLayer) createOrOpen(rtr fdb.ReadTransaction, tr *fdb.Transacti
|
|||
if prefix != nil && !dl.allowManualPrefixes {
|
||||
if len(dl.path) == 0 {
|
||||
return nil, errors.New("cannot specify a prefix unless manual prefixes are enabled")
|
||||
} else {
|
||||
return nil, errors.New("cannot specify a prefix in a partition")
|
||||
}
|
||||
return nil, errors.New("cannot specify a prefix in a partition")
|
||||
}
|
||||
|
||||
if len(path) == 0 {
|
||||
|
@ -562,9 +562,8 @@ func (dl directoryLayer) contentsOfNode(node subspace.Subspace, path []string, l
|
|||
ndl := NewDirectoryLayer(subspace.FromBytes(nssb), ss, false).(directoryLayer)
|
||||
ndl.path = newPath
|
||||
return directoryPartition{ndl, dl}, nil
|
||||
} else {
|
||||
return directorySubspace{ss, dl, newPath, layer}, nil
|
||||
}
|
||||
return directorySubspace{ss, dl, newPath, layer}, nil
|
||||
}
|
||||
|
||||
func (dl directoryLayer) nodeWithPrefix(prefix []byte) subspace.Subspace {
|
||||
|
|
|
@ -72,9 +72,8 @@ func (dp directoryPartition) GetLayer() []byte {
|
|||
func (dp directoryPartition) getLayerForPath(path []string) directoryLayer {
|
||||
if len(path) == 0 {
|
||||
return dp.parentDirectoryLayer
|
||||
} else {
|
||||
return dp.directoryLayer
|
||||
}
|
||||
return dp.directoryLayer
|
||||
}
|
||||
|
||||
func (dp directoryPartition) MoveTo(t fdb.Transactor, newAbsolutePath []string) (DirectorySubspace, error) {
|
||||
|
|
|
@ -25,12 +25,12 @@ Package fdb provides an interface to FoundationDB databases (version 2.0 or high
|
|||
|
||||
To build and run programs using this package, you must have an installed copy of
|
||||
the FoundationDB client libraries (version 2.0.0 or later), available for Linux,
|
||||
Windows and OS X at https://files.foundationdb.org/fdb-c/.
|
||||
Windows and OS X at https://www.foundationdb.org/downloads/fdb-c/.
|
||||
|
||||
This documentation specifically applies to the FoundationDB Go binding. For more
|
||||
extensive guidance to programming with FoundationDB, as well as API
|
||||
documentation for the other FoundationDB interfaces, please see
|
||||
https://foundationdb.org/documentation/index.html.
|
||||
https://apple.github.io/foundationdb/index.html.
|
||||
|
||||
Basic Usage
|
||||
|
||||
|
@ -198,7 +198,7 @@ operations perform different transformations. Like other database operations, an
|
|||
atomic operation is used within a transaction.
|
||||
|
||||
For more information on atomic operations in FoundationDB, please see
|
||||
https://foundationdb.org/documentation/developer-guide.html#atomic-operations. The
|
||||
https://apple.github.io/foundationdb/developer-guide.html#atomic-operations. The
|
||||
operands to atomic operations in this API must be provided as appropriately
|
||||
encoded byte slices. To convert a Go type to a byte slice, see the binary
|
||||
package.
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
package fdb
|
||||
|
||||
/*
|
||||
#define FDB_API_VERSION 510
|
||||
#define FDB_API_VERSION 520
|
||||
#include <foundationdb/fdb_c.h>
|
||||
*/
|
||||
import "C"
|
||||
|
@ -37,7 +37,7 @@ import (
|
|||
// as a panic from any FoundationDB API function whose name ends with OrPanic.
|
||||
//
|
||||
// You may compare the Code field of an Error against the list of FoundationDB
|
||||
// error codes at https://foundationdb.org/documentation/api-error-codes.html,
|
||||
// error codes at https://apple.github.io/foundationdb/api-error-codes.html,
|
||||
// but generally an Error should be passed to (Transaction).OnError. When using
|
||||
// (Database).Transact, non-fatal errors will be retried automatically.
|
||||
type Error struct {
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
package fdb
|
||||
|
||||
/*
|
||||
#define FDB_API_VERSION 510
|
||||
#define FDB_API_VERSION 520
|
||||
#include <foundationdb/fdb_c.h>
|
||||
#include <stdlib.h>
|
||||
*/
|
||||
|
@ -109,7 +109,7 @@ func (opt NetworkOptions) setOpt(code int, param []byte) error {
|
|||
// library, an error will be returned. APIVersion must be called prior to any
|
||||
// other functions in the fdb package.
|
||||
//
|
||||
// Currently, this package supports API versions 200 through 510.
|
||||
// Currently, this package supports API versions 200 through 520.
|
||||
//
|
||||
// Warning: When using the multi-version client API, setting an API version that
|
||||
// is not supported by a particular client library will prevent that client from
|
||||
|
@ -117,7 +117,7 @@ func (opt NetworkOptions) setOpt(code int, param []byte) error {
|
|||
// the API version of your application after upgrading your client until the
|
||||
// cluster has also been upgraded.
|
||||
func APIVersion(version int) error {
|
||||
headerVersion := 510
|
||||
headerVersion := 520
|
||||
|
||||
networkMutex.Lock()
|
||||
defer networkMutex.Unlock()
|
||||
|
@ -129,7 +129,7 @@ func APIVersion(version int) error {
|
|||
return errAPIVersionAlreadySet
|
||||
}
|
||||
|
||||
if version < 200 || version > 510 {
|
||||
if version < 200 || version > 520 {
|
||||
return errAPIVersionNotSupported
|
||||
}
|
||||
|
||||
|
@ -139,9 +139,8 @@ func APIVersion(version int) error {
|
|||
maxSupportedVersion := C.fdb_get_max_api_version()
|
||||
if headerVersion > int(maxSupportedVersion) {
|
||||
return fmt.Errorf("This version of the FoundationDB Go binding is not supported by the installed FoundationDB C library. The binding requires a library that supports API version %d, but the installed library supports a maximum version of %d.", version, maxSupportedVersion)
|
||||
} else {
|
||||
return fmt.Errorf("API version %d is not supported by the installed FoundationDB C library.", version)
|
||||
}
|
||||
return fmt.Errorf("API version %d is not supported by the installed FoundationDB C library.", version)
|
||||
}
|
||||
return Error{int(e)}
|
||||
}
|
||||
|
@ -152,6 +151,24 @@ func APIVersion(version int) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// Determines if an API version has already been selected, i.e., if
|
||||
// APIVersion or MustAPIVersion have already been called.
|
||||
func IsAPIVersionSelected() bool {
|
||||
return apiVersion != 0
|
||||
}
|
||||
|
||||
// Returns the API version that has been selected through APIVersion
|
||||
// or MustAPIVersion. If the version has already been selected, then
|
||||
// the first value returned is the API version and the error is
|
||||
// nil. If the API version has not yet been set, then the error
|
||||
// will be non-nil.
|
||||
func GetAPIVersion() (int, error) {
|
||||
if IsAPIVersionSelected() {
|
||||
return apiVersion, nil
|
||||
}
|
||||
return 0, errAPIVersionUnset
|
||||
}
|
||||
|
||||
// MustAPIVersion is like APIVersion but panics if the API version is not
|
||||
// supported.
|
||||
func MustAPIVersion(version int) {
|
||||
|
@ -161,6 +178,16 @@ func MustAPIVersion(version int) {
|
|||
}
|
||||
}
|
||||
|
||||
// MustGetAPIVersion is like GetAPIVersion but panics if the API version
|
||||
// has not yet been set.
|
||||
func MustGetAPIVersion() int {
|
||||
apiVersion, err := GetAPIVersion()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return apiVersion
|
||||
}
|
||||
|
||||
var apiVersion int
|
||||
var networkStarted bool
|
||||
var networkMutex sync.Mutex
|
||||
|
@ -326,9 +353,8 @@ func CreateCluster(clusterFile string) (Cluster, error) {
|
|||
func byteSliceToPtr(b []byte) *C.uint8_t {
|
||||
if len(b) > 0 {
|
||||
return (*C.uint8_t)(unsafe.Pointer(&b[0]))
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// A KeyConvertible can be converted to a FoundationDB Key. All functions in the
|
||||
|
|
|
@ -24,7 +24,7 @@ package fdb
|
|||
|
||||
/*
|
||||
#cgo LDFLAGS: -lfdb_c -lm
|
||||
#define FDB_API_VERSION 510
|
||||
#define FDB_API_VERSION 520
|
||||
#include <foundationdb/fdb_c.h>
|
||||
#include <string.h>
|
||||
|
||||
|
|
|
@ -0,0 +1,499 @@
|
|||
/*
|
||||
* generated.go
|
||||
*
|
||||
* This source file is part of the FoundationDB open source project
|
||||
*
|
||||
* Copyright 2013-2018 Apple Inc. and the FoundationDB project authors
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
// DO NOT EDIT THIS FILE BY HAND. This file was generated using
|
||||
// translate_fdb_options.go, part of the FoundationDB repository, and a copy of
|
||||
// the fdb.options file (installed as part of the FoundationDB client, typically
|
||||
// found as /usr/include/foundationdb/fdb.options).
|
||||
|
||||
// To regenerate this file, from the top level of a FoundationDB repository
|
||||
// checkout, run:
|
||||
// $ go run bindings/go/src/_util/translate_fdb_options.go < fdbclient/vexillographer/fdb.options > bindings/go/src/fdb/generated.go
|
||||
|
||||
package fdb
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
)
|
||||
|
||||
func int64ToBytes(i int64) ([]byte, error) {
|
||||
buf := new(bytes.Buffer)
|
||||
if e := binary.Write(buf, binary.LittleEndian, i); e != nil {
|
||||
return nil, e
|
||||
}
|
||||
return buf.Bytes(), nil
|
||||
}
|
||||
|
||||
// Enables trace output to a file in a directory of the clients choosing
|
||||
//
|
||||
// Parameter: path to output directory (or NULL for current working directory)
|
||||
func (o NetworkOptions) SetTraceEnable(param string) error {
|
||||
return o.setOpt(30, []byte(param))
|
||||
}
|
||||
|
||||
// Sets the maximum size in bytes of a single trace output file. This value should be in the range ``[0, INT64_MAX]``. If the value is set to 0, there is no limit on individual file size. The default is a maximum size of 10,485,760 bytes.
|
||||
//
|
||||
// Parameter: max size of a single trace output file
|
||||
func (o NetworkOptions) SetTraceRollSize(param int64) error {
|
||||
b, e := int64ToBytes(param)
|
||||
if e != nil {
|
||||
return e
|
||||
}
|
||||
return o.setOpt(31, b)
|
||||
}
|
||||
|
||||
// Sets the maximum size of all the trace output files put together. This value should be in the range ``[0, INT64_MAX]``. If the value is set to 0, there is no limit on the total size of the files. The default is a maximum size of 104,857,600 bytes. If the default roll size is used, this means that a maximum of 10 trace files will be written at a time.
|
||||
//
|
||||
// Parameter: max total size of trace files
|
||||
func (o NetworkOptions) SetTraceMaxLogsSize(param int64) error {
|
||||
b, e := int64ToBytes(param)
|
||||
if e != nil {
|
||||
return e
|
||||
}
|
||||
return o.setOpt(32, b)
|
||||
}
|
||||
|
||||
// Sets the 'logGroup' attribute with the specified value for all events in the trace output files. The default log group is 'default'.
|
||||
//
|
||||
// Parameter: value of the logGroup attribute
|
||||
func (o NetworkOptions) SetTraceLogGroup(param string) error {
|
||||
return o.setOpt(33, []byte(param))
|
||||
}
|
||||
|
||||
// Set internal tuning or debugging knobs
|
||||
//
|
||||
// Parameter: knob_name=knob_value
|
||||
func (o NetworkOptions) SetKnob(param string) error {
|
||||
return o.setOpt(40, []byte(param))
|
||||
}
|
||||
|
||||
// Set the TLS plugin to load. This option, if used, must be set before any other TLS options
|
||||
//
|
||||
// Parameter: file path or linker-resolved name
|
||||
func (o NetworkOptions) SetTLSPlugin(param string) error {
|
||||
return o.setOpt(41, []byte(param))
|
||||
}
|
||||
|
||||
// Set the certificate chain
|
||||
//
|
||||
// Parameter: certificates
|
||||
func (o NetworkOptions) SetTLSCertBytes(param []byte) error {
|
||||
return o.setOpt(42, param)
|
||||
}
|
||||
|
||||
// Set the file from which to load the certificate chain
|
||||
//
|
||||
// Parameter: file path
|
||||
func (o NetworkOptions) SetTLSCertPath(param string) error {
|
||||
return o.setOpt(43, []byte(param))
|
||||
}
|
||||
|
||||
// Set the private key corresponding to your own certificate
|
||||
//
|
||||
// Parameter: key
|
||||
func (o NetworkOptions) SetTLSKeyBytes(param []byte) error {
|
||||
return o.setOpt(45, param)
|
||||
}
|
||||
|
||||
// Set the file from which to load the private key corresponding to your own certificate
|
||||
//
|
||||
// Parameter: file path
|
||||
func (o NetworkOptions) SetTLSKeyPath(param string) error {
|
||||
return o.setOpt(46, []byte(param))
|
||||
}
|
||||
|
||||
// Set the peer certificate field verification criteria
|
||||
//
|
||||
// Parameter: verification pattern
|
||||
func (o NetworkOptions) SetTLSVerifyPeers(param []byte) error {
|
||||
return o.setOpt(47, param)
|
||||
}
|
||||
|
||||
// Not yet implemented.
|
||||
func (o NetworkOptions) SetBuggifyEnable() error {
|
||||
return o.setOpt(48, nil)
|
||||
}
|
||||
|
||||
// Not yet implemented.
|
||||
func (o NetworkOptions) SetBuggifyDisable() error {
|
||||
return o.setOpt(49, nil)
|
||||
}
|
||||
|
||||
// Set the probability of a BUGGIFY section being active for the current execution. Only applies to code paths first traversed AFTER this option is changed.
|
||||
//
|
||||
// Parameter: probability expressed as a percentage between 0 and 100
|
||||
func (o NetworkOptions) SetBuggifySectionActivatedProbability(param int64) error {
|
||||
b, e := int64ToBytes(param)
|
||||
if e != nil {
|
||||
return e
|
||||
}
|
||||
return o.setOpt(50, b)
|
||||
}
|
||||
|
||||
// Set the probability of an active BUGGIFY section being fired
|
||||
//
|
||||
// Parameter: probability expressed as a percentage between 0 and 100
|
||||
func (o NetworkOptions) SetBuggifySectionFiredProbability(param int64) error {
|
||||
b, e := int64ToBytes(param)
|
||||
if e != nil {
|
||||
return e
|
||||
}
|
||||
return o.setOpt(51, b)
|
||||
}
|
||||
|
||||
// Disables the multi-version client API and instead uses the local client directly. Must be set before setting up the network.
|
||||
func (o NetworkOptions) SetDisableMultiVersionClientApi() error {
|
||||
return o.setOpt(60, nil)
|
||||
}
|
||||
|
||||
// If set, callbacks from external client libraries can be called from threads created by the FoundationDB client library. Otherwise, callbacks will be called from either the thread used to add the callback or the network thread. Setting this option can improve performance when connected using an external client, but may not be safe to use in all environments. Must be set before setting up the network. WARNING: This feature is considered experimental at this time.
|
||||
func (o NetworkOptions) SetCallbacksOnExternalThreads() error {
|
||||
return o.setOpt(61, nil)
|
||||
}
|
||||
|
||||
// Adds an external client library for use by the multi-version client API. Must be set before setting up the network.
|
||||
//
|
||||
// Parameter: path to client library
|
||||
func (o NetworkOptions) SetExternalClientLibrary(param string) error {
|
||||
return o.setOpt(62, []byte(param))
|
||||
}
|
||||
|
||||
// Searches the specified path for dynamic libraries and adds them to the list of client libraries for use by the multi-version client API. Must be set before setting up the network.
|
||||
//
|
||||
// Parameter: path to directory containing client libraries
|
||||
func (o NetworkOptions) SetExternalClientDirectory(param string) error {
|
||||
return o.setOpt(63, []byte(param))
|
||||
}
|
||||
|
||||
// Prevents connections through the local client, allowing only connections through externally loaded client libraries. Intended primarily for testing.
|
||||
func (o NetworkOptions) SetDisableLocalClient() error {
|
||||
return o.setOpt(64, nil)
|
||||
}
|
||||
|
||||
// Disables logging of client statistics, such as sampled transaction activity.
|
||||
func (o NetworkOptions) SetDisableClientStatisticsLogging() error {
|
||||
return o.setOpt(70, nil)
|
||||
}
|
||||
|
||||
// Enables debugging feature to perform slow task profiling. Requires trace logging to be enabled. WARNING: this feature is not recommended for use in production.
|
||||
func (o NetworkOptions) SetEnableSlowTaskProfiling() error {
|
||||
return o.setOpt(71, nil)
|
||||
}
|
||||
|
||||
// Set the size of the client location cache. Raising this value can boost performance in very large databases where clients access data in a near-random pattern. Defaults to 100000.
|
||||
//
|
||||
// Parameter: Max location cache entries
|
||||
func (o DatabaseOptions) SetLocationCacheSize(param int64) error {
|
||||
b, e := int64ToBytes(param)
|
||||
if e != nil {
|
||||
return e
|
||||
}
|
||||
return o.setOpt(10, b)
|
||||
}
|
||||
|
||||
// Set the maximum number of watches allowed to be outstanding on a database connection. Increasing this number could result in increased resource usage. Reducing this number will not cancel any outstanding watches. Defaults to 10000 and cannot be larger than 1000000.
|
||||
//
|
||||
// Parameter: Max outstanding watches
|
||||
func (o DatabaseOptions) SetMaxWatches(param int64) error {
|
||||
b, e := int64ToBytes(param)
|
||||
if e != nil {
|
||||
return e
|
||||
}
|
||||
return o.setOpt(20, b)
|
||||
}
|
||||
|
||||
// Specify the machine ID that was passed to fdbserver processes running on the same machine as this client, for better location-aware load balancing.
|
||||
//
|
||||
// Parameter: Hexadecimal ID
|
||||
func (o DatabaseOptions) SetMachineId(param string) error {
|
||||
return o.setOpt(21, []byte(param))
|
||||
}
|
||||
|
||||
// Specify the datacenter ID that was passed to fdbserver processes running in the same datacenter as this client, for better location-aware load balancing.
|
||||
//
|
||||
// Parameter: Hexadecimal ID
|
||||
func (o DatabaseOptions) SetDatacenterId(param string) error {
|
||||
return o.setOpt(22, []byte(param))
|
||||
}
|
||||
|
||||
// The transaction, if not self-conflicting, may be committed a second time after commit succeeds, in the event of a fault
|
||||
func (o TransactionOptions) SetCausalWriteRisky() error {
|
||||
return o.setOpt(10, nil)
|
||||
}
|
||||
|
||||
// The read version will be committed, and usually will be the latest committed, but might not be the latest committed in the event of a fault or partition
|
||||
func (o TransactionOptions) SetCausalReadRisky() error {
|
||||
return o.setOpt(20, nil)
|
||||
}
|
||||
|
||||
// Not yet implemented.
|
||||
func (o TransactionOptions) SetCausalReadDisable() error {
|
||||
return o.setOpt(21, nil)
|
||||
}
|
||||
|
||||
// The next write performed on this transaction will not generate a write conflict range. As a result, other transactions which read the key(s) being modified by the next write will not conflict with this transaction. Care needs to be taken when using this option on a transaction that is shared between multiple threads. When setting this option, write conflict ranges will be disabled on the next write operation, regardless of what thread it is on.
|
||||
func (o TransactionOptions) SetNextWriteNoWriteConflictRange() error {
|
||||
return o.setOpt(30, nil)
|
||||
}
|
||||
|
||||
// Reads performed by a transaction will not see any prior mutations that occured in that transaction, instead seeing the value which was in the database at the transaction's read version. This option may provide a small performance benefit for the client, but also disables a number of client-side optimizations which are beneficial for transactions which tend to read and write the same keys within a single transaction.
|
||||
func (o TransactionOptions) SetReadYourWritesDisable() error {
|
||||
return o.setOpt(51, nil)
|
||||
}
|
||||
|
||||
// Not yet implemented.
|
||||
func (o TransactionOptions) SetDurabilityDatacenter() error {
|
||||
return o.setOpt(110, nil)
|
||||
}
|
||||
|
||||
// Not yet implemented.
|
||||
func (o TransactionOptions) SetDurabilityRisky() error {
|
||||
return o.setOpt(120, nil)
|
||||
}
|
||||
|
||||
// Specifies that this transaction should be treated as highest priority and that lower priority transactions should block behind this one. Use is discouraged outside of low-level tools
|
||||
func (o TransactionOptions) SetPrioritySystemImmediate() error {
|
||||
return o.setOpt(200, nil)
|
||||
}
|
||||
|
||||
// Specifies that this transaction should be treated as low priority and that default priority transactions should be processed first. Useful for doing batch work simultaneously with latency-sensitive work
|
||||
func (o TransactionOptions) SetPriorityBatch() error {
|
||||
return o.setOpt(201, nil)
|
||||
}
|
||||
|
||||
// This is a write-only transaction which sets the initial configuration. This option is designed for use by database system tools only.
|
||||
func (o TransactionOptions) SetInitializeNewDatabase() error {
|
||||
return o.setOpt(300, nil)
|
||||
}
|
||||
|
||||
// Allows this transaction to read and modify system keys (those that start with the byte 0xFF)
|
||||
func (o TransactionOptions) SetAccessSystemKeys() error {
|
||||
return o.setOpt(301, nil)
|
||||
}
|
||||
|
||||
// Allows this transaction to read system keys (those that start with the byte 0xFF)
|
||||
func (o TransactionOptions) SetReadSystemKeys() error {
|
||||
return o.setOpt(302, nil)
|
||||
}
|
||||
|
||||
// Not yet implemented.
|
||||
func (o TransactionOptions) SetDebugRetryLogging(param string) error {
|
||||
return o.setOpt(401, []byte(param))
|
||||
}
|
||||
|
||||
// Enables tracing for this transaction and logs results to the client trace logs. Client trace logging must be enabled to get log output.
|
||||
//
|
||||
// Parameter: String identifier to be used in the logs when tracing this transaction. The identifier must not exceed 100 characters.
|
||||
func (o TransactionOptions) SetTransactionLoggingEnable(param string) error {
|
||||
return o.setOpt(402, []byte(param))
|
||||
}
|
||||
|
||||
// Set a timeout in milliseconds which, when elapsed, will cause the transaction automatically to be cancelled. Valid parameter values are ``[0, INT_MAX]``. If set to 0, will disable all timeouts. All pending and any future uses of the transaction will throw an exception. The transaction can be used again after it is reset. Like all transaction options, a timeout must be reset after a call to onError. This behavior allows the user to make the timeout dynamic.
|
||||
//
|
||||
// Parameter: value in milliseconds of timeout
|
||||
func (o TransactionOptions) SetTimeout(param int64) error {
|
||||
b, e := int64ToBytes(param)
|
||||
if e != nil {
|
||||
return e
|
||||
}
|
||||
return o.setOpt(500, b)
|
||||
}
|
||||
|
||||
// Set a maximum number of retries after which additional calls to onError will throw the most recently seen error code. Valid parameter values are ``[-1, INT_MAX]``. If set to -1, will disable the retry limit. Like all transaction options, the retry limit must be reset after a call to onError. This behavior allows the user to make the retry limit dynamic.
|
||||
//
|
||||
// Parameter: number of times to retry
|
||||
func (o TransactionOptions) SetRetryLimit(param int64) error {
|
||||
b, e := int64ToBytes(param)
|
||||
if e != nil {
|
||||
return e
|
||||
}
|
||||
return o.setOpt(501, b)
|
||||
}
|
||||
|
||||
// Set the maximum amount of backoff delay incurred in the call to onError if the error is retryable. Defaults to 1000 ms. Valid parameter values are ``[0, INT_MAX]``. Like all transaction options, the maximum retry delay must be reset after a call to onError. If the maximum retry delay is less than the current retry delay of the transaction, then the current retry delay will be clamped to the maximum retry delay.
|
||||
//
|
||||
// Parameter: value in milliseconds of maximum delay
|
||||
func (o TransactionOptions) SetMaxRetryDelay(param int64) error {
|
||||
b, e := int64ToBytes(param)
|
||||
if e != nil {
|
||||
return e
|
||||
}
|
||||
return o.setOpt(502, b)
|
||||
}
|
||||
|
||||
// Snapshot read operations will see the results of writes done in the same transaction.
|
||||
func (o TransactionOptions) SetSnapshotRywEnable() error {
|
||||
return o.setOpt(600, nil)
|
||||
}
|
||||
|
||||
// Snapshot read operations will not see the results of writes done in the same transaction.
|
||||
func (o TransactionOptions) SetSnapshotRywDisable() error {
|
||||
return o.setOpt(601, nil)
|
||||
}
|
||||
|
||||
// The transaction can read and write to locked databases, and is resposible for checking that it took the lock.
|
||||
func (o TransactionOptions) SetLockAware() error {
|
||||
return o.setOpt(700, nil)
|
||||
}
|
||||
|
||||
// By default, operations that are performed on a transaction while it is being committed will not only fail themselves, but they will attempt to fail other in-flight operations (such as the commit) as well. This behavior is intended to help developers discover situations where operations could be unintentionally executed after the transaction has been reset. Setting this option removes that protection, causing only the offending operation to fail.
|
||||
func (o TransactionOptions) SetUsedDuringCommitProtectionDisable() error {
|
||||
return o.setOpt(701, nil)
|
||||
}
|
||||
|
||||
// The transaction can read from locked databases.
|
||||
func (o TransactionOptions) SetReadLockAware() error {
|
||||
return o.setOpt(702, nil)
|
||||
}
|
||||
|
||||
// No other transactions will be applied before this transaction within the same commit version.
|
||||
func (o TransactionOptions) SetFirstInBatch() error {
|
||||
return o.setOpt(710, nil)
|
||||
}
|
||||
|
||||
type StreamingMode int
|
||||
|
||||
const (
|
||||
|
||||
// Client intends to consume the entire range and would like it all
|
||||
// transferred as early as possible.
|
||||
StreamingModeWantAll StreamingMode = -1
|
||||
|
||||
// The default. The client doesn't know how much of the range it is likely
|
||||
// to used and wants different performance concerns to be balanced. Only a
|
||||
// small portion of data is transferred to the client initially (in order to
|
||||
// minimize costs if the client doesn't read the entire range), and as the
|
||||
// caller iterates over more items in the range larger batches will be
|
||||
// transferred in order to minimize latency.
|
||||
StreamingModeIterator StreamingMode = 0
|
||||
|
||||
// Infrequently used. The client has passed a specific row limit and wants
|
||||
// that many rows delivered in a single batch. Because of iterator operation
|
||||
// in client drivers make request batches transparent to the user, consider
|
||||
// ``WANT_ALL`` StreamingMode instead. A row limit must be specified if this
|
||||
// mode is used.
|
||||
StreamingModeExact StreamingMode = 1
|
||||
|
||||
// Infrequently used. Transfer data in batches small enough to not be much
|
||||
// more expensive than reading individual rows, to minimize cost if
|
||||
// iteration stops early.
|
||||
StreamingModeSmall StreamingMode = 2
|
||||
|
||||
// Infrequently used. Transfer data in batches sized in between small and
|
||||
// large.
|
||||
StreamingModeMedium StreamingMode = 3
|
||||
|
||||
// Infrequently used. Transfer data in batches large enough to be, in a
|
||||
// high-concurrency environment, nearly as efficient as possible. If the
|
||||
// client stops iteration early, some disk and network bandwidth may be
|
||||
// wasted. The batch size may still be too small to allow a single client to
|
||||
// get high throughput from the database, so if that is what you need
|
||||
// consider the SERIAL StreamingMode.
|
||||
StreamingModeLarge StreamingMode = 4
|
||||
|
||||
// Transfer data in batches large enough that an individual client can get
|
||||
// reasonable read bandwidth from the database. If the client stops
|
||||
// iteration early, considerable disk and network bandwidth may be wasted.
|
||||
StreamingModeSerial StreamingMode = 5
|
||||
)
|
||||
|
||||
// Add performs an addition of little-endian integers. If the existing value in the database is not present or shorter than ``param``, it is first extended to the length of ``param`` with zero bytes. If ``param`` is shorter than the existing value in the database, the existing value is truncated to match the length of ``param``. The integers to be added must be stored in a little-endian representation. They can be signed in two's complement representation or unsigned. You can add to an integer at a known offset in the value by prepending the appropriate number of zero bytes to ``param`` and padding with zero bytes to match the length of the value. However, this offset technique requires that you know the addition will not cause the integer field within the value to overflow.
|
||||
func (t Transaction) Add(key KeyConvertible, param []byte) {
|
||||
t.atomicOp(key.FDBKey(), param, 2)
|
||||
}
|
||||
|
||||
// BitAnd performs a bitwise ``and`` operation. If the existing value in the database is not present, then ``param`` is stored in the database. If the existing value in the database is shorter than ``param``, it is first extended to the length of ``param`` with zero bytes. If ``param`` is shorter than the existing value in the database, the existing value is truncated to match the length of ``param``.
|
||||
func (t Transaction) BitAnd(key KeyConvertible, param []byte) {
|
||||
t.atomicOp(key.FDBKey(), param, 6)
|
||||
}
|
||||
|
||||
// BitOr performs a bitwise ``or`` operation. If the existing value in the database is not present or shorter than ``param``, it is first extended to the length of ``param`` with zero bytes. If ``param`` is shorter than the existing value in the database, the existing value is truncated to match the length of ``param``.
|
||||
func (t Transaction) BitOr(key KeyConvertible, param []byte) {
|
||||
t.atomicOp(key.FDBKey(), param, 7)
|
||||
}
|
||||
|
||||
// BitXor performs a bitwise ``xor`` operation. If the existing value in the database is not present or shorter than ``param``, it is first extended to the length of ``param`` with zero bytes. If ``param`` is shorter than the existing value in the database, the existing value is truncated to match the length of ``param``.
|
||||
func (t Transaction) BitXor(key KeyConvertible, param []byte) {
|
||||
t.atomicOp(key.FDBKey(), param, 8)
|
||||
}
|
||||
|
||||
// AppendIfFits appends ``param`` to the end of the existing value already in the database at the given key (or creates the key and sets the value to ``param`` if the key is empty). This will only append the value if the final concatenated value size is less than or equal to the maximum value size (i.e., if it fits). WARNING: No error is surfaced back to the user if the final value is too large because the mutation will not be applied until after the transaction has been committed. Therefore, it is only safe to use this mutation type if one can guarantee that one will keep the total value size under the maximum size.
|
||||
func (t Transaction) AppendIfFits(key KeyConvertible, param []byte) {
|
||||
t.atomicOp(key.FDBKey(), param, 9)
|
||||
}
|
||||
|
||||
// Max performs a little-endian comparison of byte strings. If the existing value in the database is not present or shorter than ``param``, it is first extended to the length of ``param`` with zero bytes. If ``param`` is shorter than the existing value in the database, the existing value is truncated to match the length of ``param``. The larger of the two values is then stored in the database.
|
||||
func (t Transaction) Max(key KeyConvertible, param []byte) {
|
||||
t.atomicOp(key.FDBKey(), param, 12)
|
||||
}
|
||||
|
||||
// Min performs a little-endian comparison of byte strings. If the existing value in the database is not present, then ``param`` is stored in the database. If the existing value in the database is shorter than ``param``, it is first extended to the length of ``param`` with zero bytes. If ``param`` is shorter than the existing value in the database, the existing value is truncated to match the length of ``param``. The smaller of the two values is then stored in the database.
|
||||
func (t Transaction) Min(key KeyConvertible, param []byte) {
|
||||
t.atomicOp(key.FDBKey(), param, 13)
|
||||
}
|
||||
|
||||
// SetVersionstampedKey transforms ``key`` using a versionstamp for the transaction. Sets the transformed key in the database to ``param``. A versionstamp is a 10 byte, unique, monotonically (but not sequentially) increasing value for each committed transaction. The first 8 bytes are the committed version of the database. The last 2 bytes are monotonic in the serialization order for transactions. WARNING: At this time versionstamps are compatible with the Tuple layer only in the Java and Python bindings. Note that this implies versionstamped keys may not be used with the Subspace and Directory layers except in those languages.
|
||||
func (t Transaction) SetVersionstampedKey(key KeyConvertible, param []byte) {
|
||||
t.atomicOp(key.FDBKey(), param, 14)
|
||||
}
|
||||
|
||||
// SetVersionstampedValue transforms ``param`` using a versionstamp for the transaction. Sets ``key`` in the database to the transformed parameter. A versionstamp is a 10 byte, unique, monotonically (but not sequentially) increasing value for each committed transaction. The first 8 bytes are the committed version of the database. The last 2 bytes are monotonic in the serialization order for transactions. WARNING: At this time versionstamped values are not compatible with the Tuple layer.
|
||||
func (t Transaction) SetVersionstampedValue(key KeyConvertible, param []byte) {
|
||||
t.atomicOp(key.FDBKey(), param, 15)
|
||||
}
|
||||
|
||||
// ByteMin performs lexicographic comparison of byte strings. If the existing value in the database is not present, then ``param`` is stored. Otherwise the smaller of the two values is then stored in the database.
|
||||
func (t Transaction) ByteMin(key KeyConvertible, param []byte) {
|
||||
t.atomicOp(key.FDBKey(), param, 16)
|
||||
}
|
||||
|
||||
// ByteMax performs lexicographic comparison of byte strings. If the existing value in the database is not present, then ``param`` is stored. Otherwise the larger of the two values is then stored in the database.
|
||||
func (t Transaction) ByteMax(key KeyConvertible, param []byte) {
|
||||
t.atomicOp(key.FDBKey(), param, 17)
|
||||
}
|
||||
|
||||
type conflictRangeType int
|
||||
|
||||
const (
|
||||
|
||||
// Used to add a read conflict range
|
||||
conflictRangeTypeRead conflictRangeType = 0
|
||||
|
||||
// Used to add a write conflict range
|
||||
conflictRangeTypeWrite conflictRangeType = 1
|
||||
)
|
||||
|
||||
type ErrorPredicate int
|
||||
|
||||
const (
|
||||
|
||||
// Returns ``true`` if the error indicates the operations in the
|
||||
// transactions should be retried because of transient error.
|
||||
ErrorPredicateRetryable ErrorPredicate = 50000
|
||||
|
||||
// Returns ``true`` if the error indicates the transaction may have
|
||||
// succeeded, though not in a way the system can verify.
|
||||
ErrorPredicateMaybeCommitted ErrorPredicate = 50001
|
||||
|
||||
// Returns ``true`` if the error indicates the transaction has not
|
||||
// committed, though in a way that can be retried.
|
||||
ErrorPredicateRetryableNotCommitted ErrorPredicate = 50002
|
||||
)
|
|
@ -34,7 +34,7 @@ type Selectable interface {
|
|||
//
|
||||
// The most common key selectors are constructed with the functions documented
|
||||
// below. For details of how KeySelectors are specified and resolved, see
|
||||
// https://foundationdb.org/documentation/developer-guide.html#key-selectors.
|
||||
// https://apple.github.io/foundationdb/developer-guide.html#key-selectors.
|
||||
type KeySelector struct {
|
||||
Key KeyConvertible
|
||||
OrEqual bool
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
package fdb
|
||||
|
||||
/*
|
||||
#define FDB_API_VERSION 510
|
||||
#define FDB_API_VERSION 520
|
||||
#include <foundationdb/fdb_c.h>
|
||||
*/
|
||||
import "C"
|
||||
|
@ -247,7 +247,7 @@ func (ri *RangeIterator) fetchNextBatch() {
|
|||
ri.sr.Begin = FirstGreaterThan(ri.kvs[ri.index-1].Key)
|
||||
}
|
||||
|
||||
ri.iteration += 1
|
||||
ri.iteration++
|
||||
|
||||
f := ri.t.doGetRange(ri.sr, ri.options, ri.snapshot, ri.iteration)
|
||||
ri.f = &f
|
||||
|
@ -265,7 +265,7 @@ func (ri *RangeIterator) Get() (kv KeyValue, e error) {
|
|||
|
||||
kv = ri.kvs[ri.index]
|
||||
|
||||
ri.index += 1
|
||||
ri.index++
|
||||
|
||||
if ri.index == len(ri.kvs) {
|
||||
ri.fetchNextBatch()
|
||||
|
@ -291,7 +291,7 @@ func Strinc(prefix []byte) ([]byte, error) {
|
|||
if prefix[i] != 0xFF {
|
||||
ret := make([]byte, i+1)
|
||||
copy(ret, prefix[:i+1])
|
||||
ret[i] += 1
|
||||
ret[i]++
|
||||
return ret, nil
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,7 +28,7 @@ package fdb
|
|||
// transaction conflicts but making it harder to reason about concurrency.
|
||||
//
|
||||
// For more information on snapshot reads, see
|
||||
// https://foundationdb.org/documentation/developer-guide.html#snapshot-reads.
|
||||
// https://apple.github.io/foundationdb/developer-guide.html#snapshot-reads.
|
||||
type Snapshot struct {
|
||||
*transaction
|
||||
}
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
// As a best practice, API clients should use at least one subspace for
|
||||
// application data. For general guidance on subspace usage, see the Subspaces
|
||||
// section of the Developer Guide
|
||||
// (https://foundationdb.org/documentation/developer-guide.html#developer-guide-sub-keyspaces).
|
||||
// (https://apple.github.io/foundationdb/developer-guide.html#subspaces).
|
||||
package subspace
|
||||
|
||||
import (
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
package fdb
|
||||
|
||||
/*
|
||||
#define FDB_API_VERSION 510
|
||||
#define FDB_API_VERSION 520
|
||||
#include <foundationdb/fdb_c.h>
|
||||
*/
|
||||
import "C"
|
||||
|
@ -171,7 +171,7 @@ func (t Transaction) SetReadVersion(version int64) {
|
|||
// but making it harder to reason about concurrency.
|
||||
//
|
||||
// For more information on snapshot reads, see
|
||||
// https://foundationdb.org/documentation/developer-guide.html#using-snapshot-reads.
|
||||
// https://apple.github.io/foundationdb/developer-guide.html#snapshot-reads.
|
||||
func (t Transaction) Snapshot() Snapshot {
|
||||
return Snapshot{t.transaction}
|
||||
}
|
||||
|
@ -196,7 +196,7 @@ func (t Transaction) OnError(e Error) FutureNil {
|
|||
// As with other client/server databases, in some failure scenarios a client may
|
||||
// be unable to determine whether a transaction succeeded. For more information,
|
||||
// see
|
||||
// https://foundationdb.org/documentation/developer-guide.html#developer-guide-unknown-results.
|
||||
// https://apple.github.io/foundationdb/developer-guide.html#transactions-with-unknown-results.
|
||||
func (t Transaction) Commit() FutureNil {
|
||||
return &futureNil{newFuture(C.fdb_transaction_commit(t.ptr))}
|
||||
}
|
||||
|
@ -352,9 +352,8 @@ func (t Transaction) Reset() {
|
|||
func boolToInt(b bool) int {
|
||||
if b {
|
||||
return 1
|
||||
} else {
|
||||
return 0
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (t *transaction) getKey(sel KeySelector, snapshot int) FutureKey {
|
||||
|
@ -396,7 +395,7 @@ func addConflictRange(t *transaction, er ExactRange, crtype conflictRangeType) e
|
|||
// conflict.
|
||||
//
|
||||
// For more information on conflict ranges, see
|
||||
// https://foundationdb.org/documentation/developer-guide.html#conflict-ranges.
|
||||
// https://apple.github.io/foundationdb/developer-guide.html#conflict-ranges.
|
||||
func (t Transaction) AddReadConflictRange(er ExactRange) error {
|
||||
return addConflictRange(t.transaction, er, conflictRangeTypeRead)
|
||||
}
|
||||
|
@ -413,7 +412,7 @@ func copyAndAppend(orig []byte, b byte) []byte {
|
|||
// this key could cause the transaction to fail with a conflict.
|
||||
//
|
||||
// For more information on conflict ranges, see
|
||||
// https://foundationdb.org/documentation/developer-guide.html#conflict-ranges.
|
||||
// https://apple.github.io/foundationdb/developer-guide.html#conflict-ranges.
|
||||
func (t Transaction) AddReadConflictKey(key KeyConvertible) error {
|
||||
return addConflictRange(t.transaction, KeyRange{key, Key(copyAndAppend(key.FDBKey(), 0x00))}, conflictRangeTypeRead)
|
||||
}
|
||||
|
@ -424,7 +423,7 @@ func (t Transaction) AddReadConflictKey(key KeyConvertible) error {
|
|||
// conflict.
|
||||
//
|
||||
// For more information on conflict ranges, see
|
||||
// https://foundationdb.org/documentation/developer-guide.html#conflict-ranges.
|
||||
// https://apple.github.io/foundationdb/developer-guide.html#conflict-ranges.
|
||||
func (t Transaction) AddWriteConflictRange(er ExactRange) error {
|
||||
return addConflictRange(t.transaction, er, conflictRangeTypeWrite)
|
||||
}
|
||||
|
@ -434,7 +433,7 @@ func (t Transaction) AddWriteConflictRange(er ExactRange) error {
|
|||
// read this key could fail with a conflict.
|
||||
//
|
||||
// For more information on conflict ranges, see
|
||||
// https://foundationdb.org/documentation/developer-guide.html#conflict-ranges.
|
||||
// https://apple.github.io/foundationdb/developer-guide.html#conflict-ranges.
|
||||
func (t Transaction) AddWriteConflictKey(key KeyConvertible) error {
|
||||
return addConflictRange(t.transaction, KeyRange{key, Key(copyAndAppend(key.FDBKey(), 0x00))}, conflictRangeTypeWrite)
|
||||
}
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
// of higher-level data models.
|
||||
//
|
||||
// For general guidance on tuple usage, see the Tuple section of Data Modeling
|
||||
// (https://foundationdb.org/documentation/data-modeling.html#data-modeling-tuples).
|
||||
// (https://apple.github.io/foundationdb/data-modeling.html#tuples).
|
||||
//
|
||||
// FoundationDB tuples can currently encode byte and unicode strings, integers
|
||||
// and NULL values. In Go these are represented as []byte, string, int64 and
|
||||
|
@ -38,6 +38,7 @@ import (
|
|||
"bytes"
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
|
||||
"github.com/apple/foundationdb/bindings/go/src/fdb"
|
||||
)
|
||||
|
||||
|
@ -114,7 +115,7 @@ func encodeBytes(buf *bytes.Buffer, code byte, b []byte) {
|
|||
func bisectLeft(u uint64) int {
|
||||
var n int
|
||||
for sizeLimits[n] < u {
|
||||
n += 1
|
||||
n++
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
@ -356,7 +357,7 @@ func decodeTuple(b []byte, nested bool) (Tuple, int, error) {
|
|||
if err != nil {
|
||||
return nil, i, err
|
||||
}
|
||||
off += 1
|
||||
off++
|
||||
default:
|
||||
return nil, i, fmt.Errorf("unable to decode tuple element with unknown typecode %02x", b[i])
|
||||
}
|
||||
|
|
|
@ -30,11 +30,6 @@
|
|||
<property name="option" value="eol"/>
|
||||
<property name="ignoreEnums" value="false"/>
|
||||
</module>
|
||||
<!-- We have about 76 errors with value = "alone" and 27 with value = "same". We should pick one.
|
||||
<module name="RightCurly">
|
||||
<property name="option" value="same"/>
|
||||
</module>
|
||||
-->
|
||||
|
||||
<!-- Design -->
|
||||
<!-- We might get some helpful errors if we turned this on, but not right now.
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
#include <jni.h>
|
||||
#include <string.h>
|
||||
|
||||
#define FDB_API_VERSION 510
|
||||
#define FDB_API_VERSION 520
|
||||
|
||||
#include <foundationdb/fdb_c.h>
|
||||
|
||||
|
|
|
@ -38,13 +38,14 @@ else
|
|||
endif
|
||||
|
||||
ifeq ($(PLATFORM),linux)
|
||||
fdb_java_CFLAGS += -I/usr/lib/jvm/java-8-openjdk-amd64/include -I/usr/lib/jvm/java-8-openjdk-amd64/include/linux
|
||||
JAVA_HOME ?= /usr/lib/jvm/java-8-openjdk-amd64
|
||||
fdb_java_CFLAGS += -I$(JAVA_HOME)/include -I$(JAVA_HOME)/include/linux
|
||||
fdb_java_LDFLAGS += -static-libgcc
|
||||
|
||||
java_ARCH := amd64
|
||||
else ifeq ($(PLATFORM),osx)
|
||||
# FIXME: Surely there is a better way to grab the JNI headers on any version of macOS.
|
||||
fdb_java_CFLAGS += -I/System/Library/Frameworks/JavaVM.framework/Versions/A/Headers -I/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.11.sdk/System/Library/Frameworks/JavaVM.framework/Versions/A/Headers
|
||||
JAVA_HOME ?= $(shell /usr/libexec/java_home)
|
||||
fdb_java_CFLAGS += -I$(JAVA_HOME)/include -I$(JAVA_HOME)/include/darwin
|
||||
|
||||
java_ARCH := x86_64
|
||||
endif
|
||||
|
|
|
@ -10,13 +10,13 @@
|
|||
<packaging>jar</packaging>
|
||||
|
||||
<name>foundationdb-java</name>
|
||||
<description>Java bindings for the FoundationDB database. These bindings require the FoundationDB client, which is under a different license. The client can be obtained from https://files.foundationdb.org/fdb-c/.</description>
|
||||
<description>Java bindings for the FoundationDB database. These bindings require the FoundationDB client, which is under a different license. The client can be obtained from https://www.foundationdb.org/downloads/fdb-c/.</description>
|
||||
<inceptionYear>2010</inceptionYear>
|
||||
<url>http://foundationdb.org</url>
|
||||
<url>https://www.foundationdb.org</url>
|
||||
|
||||
<organization>
|
||||
<name>FoundationDB</name>
|
||||
<url>http://foundationdb.org</url>
|
||||
<url>https://www.foundationdb.org</url>
|
||||
</organization>
|
||||
|
||||
<developers>
|
||||
|
|
|
@ -83,6 +83,8 @@ public class Cluster extends NativeObjectWrapper {
|
|||
/**
|
||||
* Creates a connection to a specific database on an <i>FDB</i> cluster.
|
||||
*
|
||||
* @param e the {@link Executor} to use when executing asynchronous callbacks for the database
|
||||
*
|
||||
* @return a {@code Future} that will be set to a {@code Database} upon
|
||||
* successful connection.
|
||||
*/
|
||||
|
|
|
@ -80,6 +80,9 @@ public interface Database extends AutoCloseable, TransactionContext {
|
|||
*
|
||||
* @param retryable the block of logic to execute in a {@link Transaction} against
|
||||
* this database
|
||||
* @param <T> the return type of {@code retryable}
|
||||
*
|
||||
* @return the result of the last run of {@code retryable}
|
||||
*/
|
||||
@Override
|
||||
default <T> T read(Function<? super ReadTransaction, T> retryable) {
|
||||
|
@ -94,6 +97,8 @@ public interface Database extends AutoCloseable, TransactionContext {
|
|||
* @param retryable the block of logic to execute in a {@link Transaction} against
|
||||
* this database
|
||||
* @param e the {@link Executor} to use for asynchronous callbacks
|
||||
* @param <T> the return type of {@code retryable}
|
||||
* @return the result of the last run of {@code retryable}
|
||||
*
|
||||
* @see #read(Function)
|
||||
*/
|
||||
|
@ -113,6 +118,10 @@ public interface Database extends AutoCloseable, TransactionContext {
|
|||
*
|
||||
* @param retryable the block of logic to execute in a {@link ReadTransaction} against
|
||||
* this database
|
||||
* @param <T> the return type of {@code retryable}
|
||||
*
|
||||
* @return a {@code CompletableFuture} that will be set to the value returned by the last call
|
||||
* to {@code retryable}
|
||||
*/
|
||||
@Override
|
||||
default <T> CompletableFuture<T> readAsync(
|
||||
|
@ -128,7 +137,11 @@ public interface Database extends AutoCloseable, TransactionContext {
|
|||
* @param retryable the block of logic to execute in a {@link ReadTransaction} against
|
||||
* this database
|
||||
* @param e the {@link Executor} to use for asynchronous callbacks
|
||||
*
|
||||
* @param <T> the return type of {@code retryable}
|
||||
*
|
||||
* @return a {@code CompletableFuture} that will be set to the value returned by the last call
|
||||
* to {@code retryable}
|
||||
*
|
||||
* @see #readAsync(Function)
|
||||
*/
|
||||
<T> CompletableFuture<T> readAsync(
|
||||
|
@ -152,6 +165,9 @@ public interface Database extends AutoCloseable, TransactionContext {
|
|||
*
|
||||
* @param retryable the block of logic to execute in a {@link Transaction} against
|
||||
* this database
|
||||
* @param <T> the return type of {@code retryable}
|
||||
*
|
||||
* @return the result of the last run of {@code retryable}
|
||||
*/
|
||||
@Override
|
||||
default <T> T run(Function<? super Transaction, T> retryable) {
|
||||
|
@ -166,6 +182,9 @@ public interface Database extends AutoCloseable, TransactionContext {
|
|||
* @param retryable the block of logic to execute in a {@link Transaction} against
|
||||
* this database
|
||||
* @param e the {@link Executor} to use for asynchronous callbacks
|
||||
* @param <T> the return type of {@code retryable}
|
||||
*
|
||||
* @return the result of the last run of {@code retryable}
|
||||
*/
|
||||
<T> T run(Function<? super Transaction, T> retryable, Executor e);
|
||||
|
||||
|
@ -191,6 +210,10 @@ public interface Database extends AutoCloseable, TransactionContext {
|
|||
*
|
||||
* @param retryable the block of logic to execute in a {@link Transaction} against
|
||||
* this database
|
||||
* @param <T> the return type of {@code retryable}
|
||||
*
|
||||
* @return a {@code CompletableFuture} that will be set to the value returned by the last call
|
||||
* to {@code retryable}
|
||||
*/
|
||||
@Override
|
||||
default <T> CompletableFuture<T> runAsync(
|
||||
|
@ -206,6 +229,10 @@ public interface Database extends AutoCloseable, TransactionContext {
|
|||
* @param retryable the block of logic to execute in a {@link Transaction} against
|
||||
* this database
|
||||
* @param e the {@link Executor} to use for asynchronous callbacks
|
||||
* @param <T> the return type of {@code retryable}
|
||||
*
|
||||
* @return a {@code CompletableFuture} that will be set to the value returned by the last call
|
||||
* to {@code retryable}
|
||||
*
|
||||
* @see #run(Function)
|
||||
*/
|
||||
|
|
|
@ -35,7 +35,7 @@ import java.util.concurrent.atomic.AtomicInteger;
|
|||
* This call is required before using any other part of the API. The call allows
|
||||
* an error to be thrown at this point to prevent client code from accessing a later library
|
||||
* with incorrect assumptions from the current version. The API version documented here is version
|
||||
* {@code 510}.<br><br>
|
||||
* {@code 520}.<br><br>
|
||||
* FoundationDB encapsulates multiple versions of its interface by requiring
|
||||
* the client to explicitly specify the version of the API it uses. The purpose
|
||||
* of this design is to allow you to upgrade the server, client libraries, or
|
||||
|
@ -81,7 +81,7 @@ public class FDB {
|
|||
|
||||
public static final ExecutorService DEFAULT_EXECUTOR;
|
||||
|
||||
final int apiVersion;
|
||||
private final int apiVersion;
|
||||
private volatile boolean netStarted = false;
|
||||
private volatile boolean netStopped = false;
|
||||
volatile boolean warnOnUnclosed = true;
|
||||
|
@ -123,6 +123,37 @@ public class FDB {
|
|||
return options;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if the API version has already been selected. That is, this
|
||||
* will return {@code true} if the user has already called
|
||||
* {@link #selectAPIVersion(int) selectAPIVersion()} and that call
|
||||
* has completed successfully.
|
||||
*
|
||||
* @return {@code true} if an API version has been selected and {@code false} otherwise
|
||||
*/
|
||||
public static boolean isAPIVersionSelected() {
|
||||
return singleton != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the instance of the FDB API singleton. This method will always return
|
||||
* a non-{@code null} value for the singleton, but if the
|
||||
* {@link #selectAPIVersion(int) selectAPIVersion()} method has not yet been
|
||||
* called, it will throw an {@link FDBException} indicating that an API
|
||||
* version has not yet been set.
|
||||
*
|
||||
* @return the FoundationDB API object
|
||||
* @throws FDBException if {@link #selectAPIVersion(int) selectAPIVersion()} has not been called
|
||||
*/
|
||||
public static FDB instance() throws FDBException {
|
||||
if(singleton != null) {
|
||||
return singleton;
|
||||
}
|
||||
else {
|
||||
throw new FDBException("API version is not set", 2200);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Select the version for the client API. An exception will be thrown if the
|
||||
* requested version is not supported by this implementation of the API. As
|
||||
|
@ -142,7 +173,7 @@ public class FDB {
|
|||
*/
|
||||
public static synchronized FDB selectAPIVersion(final int version) throws FDBException {
|
||||
if(singleton != null) {
|
||||
if(version != singleton.apiVersion) {
|
||||
if(version != singleton.getAPIVersion()) {
|
||||
throw new IllegalArgumentException(
|
||||
"FoundationDB API already started at different version");
|
||||
}
|
||||
|
@ -150,8 +181,8 @@ public class FDB {
|
|||
}
|
||||
if(version < 510)
|
||||
throw new IllegalArgumentException("API version not supported (minimum 510)");
|
||||
if(version > 510)
|
||||
throw new IllegalArgumentException("API version not supported (maximum 510)");
|
||||
if(version > 520)
|
||||
throw new IllegalArgumentException("API version not supported (maximum 520)");
|
||||
|
||||
Select_API_version(version);
|
||||
FDB fdb = new FDB(version);
|
||||
|
@ -169,18 +200,21 @@ public class FDB {
|
|||
this.warnOnUnclosed = warnOnUnclosed;
|
||||
}
|
||||
|
||||
// Singleton is initialized to null and only set once by a call to selectAPIVersion
|
||||
static FDB getInstance() {
|
||||
if(singleton != null) {
|
||||
return singleton;
|
||||
}
|
||||
|
||||
throw new IllegalStateException("API version has not been selected");
|
||||
/**
|
||||
* Returns the API version that was selected by the {@link #selectAPIVersion(int) selectAPIVersion()}
|
||||
* call. This can be used to guard different parts of client code against different versions
|
||||
* of the FoundationDB API to allow for libraries using FoundationDB to be compatible across
|
||||
* several versions.
|
||||
*
|
||||
* @return the FoundationDB API version that has been loaded
|
||||
*/
|
||||
public int getAPIVersion() {
|
||||
return apiVersion;
|
||||
}
|
||||
|
||||
/**
|
||||
* Connects to the cluster specified by the
|
||||
* <a href="/foundationdb/api-general.html#default-cluster-file" target="_blank">default fdb.cluster file</a>.
|
||||
* <a href="/foundationdb/administration.html#default-cluster-file" target="_blank">default fdb.cluster file</a>.
|
||||
* If the FoundationDB network has not been started, it will be started in the course of this call
|
||||
* as if {@link FDB#startNetwork()} had been called.
|
||||
*
|
||||
|
@ -199,9 +233,9 @@ public class FDB {
|
|||
* {@link #startNetwork()} had been called.
|
||||
*
|
||||
* @param clusterFilePath the
|
||||
* <a href="/foundationdb/api-general.html#foundationdb-cluster-file" target="_blank">cluster file</a>
|
||||
* <a href="/foundationdb/administration.html#foundationdb-cluster-file" target="_blank">cluster file</a>
|
||||
* defining the FoundationDB cluster. This can be {@code null} if the
|
||||
* <a href="/foundationdb/api-general.html#default-cluster-file" target="_blank">default fdb.cluster file</a>
|
||||
* <a href="/foundationdb/administration.html#default-cluster-file" target="_blank">default fdb.cluster file</a>
|
||||
* is to be used.
|
||||
*
|
||||
* @return a {@code CompletableFuture} that will be set to a FoundationDB {@code Cluster}.
|
||||
|
@ -220,9 +254,9 @@ public class FDB {
|
|||
* are produced from using the resulting {@link Cluster}.
|
||||
*
|
||||
* @param clusterFilePath the
|
||||
* <a href="/foundationdb/api-general.html#foundationdb-cluster-file" target="_blank">cluster file</a>
|
||||
* <a href="/foundationdb/administration.html#foundationdb-cluster-file" target="_blank">cluster file</a>
|
||||
* defining the FoundationDB cluster. This can be {@code null} if the
|
||||
* <a href="/foundationdb/api-general.html#default-cluster-file" target="_blank">default fdb.cluster file</a>
|
||||
* <a href="/foundationdb/administration.html#default-cluster-file" target="_blank">default fdb.cluster file</a>
|
||||
* is to be used.
|
||||
* @param e used to run the FDB network thread
|
||||
*
|
||||
|
@ -245,7 +279,7 @@ public class FDB {
|
|||
|
||||
/**
|
||||
* Initializes networking, connects with the
|
||||
* <a href="/foundationdb/api-general.html#default-cluster-file" target="_blank">default fdb.cluster file</a>,
|
||||
* <a href="/foundationdb/administration.html#default-cluster-file" target="_blank">default fdb.cluster file</a>,
|
||||
* and opens the database.
|
||||
*
|
||||
* @return a {@code CompletableFuture} that will be set to a FoundationDB {@link Database}
|
||||
|
@ -259,9 +293,9 @@ public class FDB {
|
|||
* and opens the database.
|
||||
*
|
||||
* @param clusterFilePath the
|
||||
* <a href="/foundationdb/api-general.html#foundationdb-cluster-file" target="_blank">cluster file</a>
|
||||
* <a href="/foundationdb/administration.html#foundationdb-cluster-file" target="_blank">cluster file</a>
|
||||
* defining the FoundationDB cluster. This can be {@code null} if the
|
||||
* <a href="/foundationdb/api-general.html#default-cluster-file" target="_blank">default fdb.cluster file</a>
|
||||
* <a href="/foundationdb/administration.html#default-cluster-file" target="_blank">default fdb.cluster file</a>
|
||||
* is to be used.
|
||||
*
|
||||
* @return a {@code CompletableFuture} that will be set to a FoundationDB {@link Database}
|
||||
|
@ -275,9 +309,9 @@ public class FDB {
|
|||
* and opens the database.
|
||||
*
|
||||
* @param clusterFilePath the
|
||||
* <a href="/foundationdb/api-general.html#foundationdb-cluster-file" target="_blank">cluster file</a>
|
||||
* <a href="/foundationdb/administration.html#foundationdb-cluster-file" target="_blank">cluster file</a>
|
||||
* defining the FoundationDB cluster. This can be {@code null} if the
|
||||
* <a href="/foundationdb/api-general.html#default-cluster-file" target="_blank">default fdb.cluster file</a>
|
||||
* <a href="/foundationdb/administration.html#default-cluster-file" target="_blank">default fdb.cluster file</a>
|
||||
* is to be used.
|
||||
* @param e the {@link Executor} to use to execute asynchronous callbacks
|
||||
*
|
||||
|
@ -329,12 +363,14 @@ public class FDB {
|
|||
* event loop is a blocking operation that is not
|
||||
* expected to terminate until the program is complete. This will therefore consume an
|
||||
* entire thread from {@code e} if {@code e} is a thread pool or will completely block
|
||||
* operation of a single threaded {@code Executor}.<br>
|
||||
* the single thread of a single-threaded {@code Executor}.<br>
|
||||
* <br>
|
||||
* Manual configuration of the networking engine can be achieved through calls on
|
||||
* {@link NetworkOptions}. These options should be set before a call
|
||||
* to this method.
|
||||
*
|
||||
* @param e the {@link Executor} to use to execute network operations on
|
||||
*
|
||||
* @see NetworkOptions
|
||||
*
|
||||
* @throws IllegalStateException if the network has already been stopped
|
||||
|
|
|
@ -42,12 +42,12 @@ class JNIUtil {
|
|||
OSX("osx", "x86_64", true);
|
||||
|
||||
private final String name;
|
||||
private final String arch;
|
||||
private final String arch;
|
||||
private final boolean canDeleteEager;
|
||||
|
||||
OS(String name, String arch, boolean canDeleteEager) {
|
||||
this.name = name;
|
||||
this.arch = arch;
|
||||
this.arch = arch;
|
||||
this.canDeleteEager = canDeleteEager;
|
||||
}
|
||||
|
||||
|
@ -55,9 +55,9 @@ class JNIUtil {
|
|||
return this.name;
|
||||
}
|
||||
|
||||
public String getArch() {
|
||||
return this.arch;
|
||||
}
|
||||
public String getArch() {
|
||||
return this.arch;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -89,18 +89,18 @@ class JNIUtil {
|
|||
OS os = getRunningOS();
|
||||
String path = getPath(os, libName);
|
||||
|
||||
if ((os.getName().equals("linux") && !path.endsWith(".so")) || (os.getName().equals("windows") && !path.endsWith(".dll")) || (os.getName().equals("osx") && !path.endsWith(".jnilib") && !path.endsWith(".dylib"))) {
|
||||
throw new IllegalStateException("OS sanity check failed. System property os.name reports " + os.getName()+" but System.mapLibraryName is looking for " + getLibName(libName));
|
||||
}
|
||||
if ((os.getName().equals("linux") && !path.endsWith(".so")) || (os.getName().equals("windows") && !path.endsWith(".dll")) || (os.getName().equals("osx") && !path.endsWith(".jnilib") && !path.endsWith(".dylib"))) {
|
||||
throw new IllegalStateException("OS sanity check failed. System property os.name reports " + os.getName()+" but System.mapLibraryName is looking for " + getLibName(libName));
|
||||
}
|
||||
|
||||
File exported;
|
||||
File exported;
|
||||
|
||||
try {
|
||||
exported = exportResource(path);
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new UnsatisfiedLinkError(e.getMessage());
|
||||
}
|
||||
try {
|
||||
exported = exportResource(path);
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new UnsatisfiedLinkError(e.getMessage());
|
||||
}
|
||||
String filename = exported.getAbsolutePath();
|
||||
|
||||
System.load(filename);
|
||||
|
|
|
@ -33,6 +33,9 @@ import com.apple.foundationdb.tuple.ByteArrayUtil;
|
|||
* <br>
|
||||
* For more about how key selectors work in practice, see
|
||||
* <a href="/foundationdb/developer-guide.html#key-selectors" target="_blank">the KeySelector documentation</a>.
|
||||
* Note that the way the key selectors are resolved is somewhat non-intuitive, so
|
||||
* users who wish to use a key selector other than the default ones described below should
|
||||
* probably consult that documentation before proceeding.
|
||||
* <br>
|
||||
* <br>
|
||||
* Generally one of the following static methods should be used to construct a {@code KeySelector}:
|
||||
|
@ -52,13 +55,25 @@ public class KeySelector {
|
|||
|
||||
/**
|
||||
* Constructs a new {@code KeySelector} from the given parameters. Client code
|
||||
* will not generally call this constructor.
|
||||
* will not generally call this constructor. A key selector can be used to
|
||||
* specify a key that will be resolved at runtime based on a starting key and
|
||||
* an offset. When this is passed as an argument to a {@link Transaction}'s
|
||||
* {@link Transaction#getKey(KeySelector) getKey()} or
|
||||
* {@link Transaction#getRange(KeySelector, KeySelector) getRange()}
|
||||
* methods, the key selector will be resolved to a key within the
|
||||
* database. This is done in a manner equivalent to finding the last key that is
|
||||
* less than (or less than or equal to, if {@code orEqual} is
|
||||
* {@code true}) the base {@code key} specified here and then
|
||||
* returning the key that is {@code offset} keys greater than that
|
||||
* key.
|
||||
*
|
||||
* @param key the base key to reference
|
||||
* @param orEqual <code>true</code> if the key should be considered for equality
|
||||
* @param offset the number of keys to offset from once the key is found
|
||||
* @param orEqual {@code true} if the key selector should resolve to
|
||||
* {@code key} (if {@code key} is present) before accounting for the offset
|
||||
* @param offset the offset (in number of keys) that the selector will advance after
|
||||
* resolving to a key based on the {@code key} and {@code orEqual} parameters
|
||||
*/
|
||||
public KeySelector(byte[] key, boolean orEqual,int offset) {
|
||||
public KeySelector(byte[] key, boolean orEqual, int offset) {
|
||||
this.key = key;
|
||||
this.orEqual = orEqual;
|
||||
this.offset = offset;
|
||||
|
@ -157,7 +172,11 @@ public class KeySelector {
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns the key offset for this {@code KeySelector}. For internal use.
|
||||
* Returns the key offset parameter for this {@code KeySelector}. See
|
||||
* the {@link #KeySelector(byte[], boolean, int) KeySelector constructor}
|
||||
* for more details.
|
||||
*
|
||||
* @return the key offset for this {@code KeySelector}
|
||||
*/
|
||||
public int getOffset() {
|
||||
return offset;
|
||||
|
|
|
@ -221,7 +221,7 @@ public class LocalityUtil {
|
|||
@Override
|
||||
protected void finalize() throws Throwable {
|
||||
try {
|
||||
if(FDB.getInstance().warnOnUnclosed && !closed) {
|
||||
if(FDB.instance().warnOnUnclosed && !closed) {
|
||||
System.err.println("CloseableAsyncIterator not closed (getBoundaryKeys)");
|
||||
}
|
||||
if(!closed) {
|
||||
|
|
|
@ -47,7 +47,7 @@ abstract class NativeObjectWrapper implements AutoCloseable {
|
|||
|
||||
public void checkUnclosed(String context) {
|
||||
try {
|
||||
if(FDB.getInstance().warnOnUnclosed && !closed) {
|
||||
if(FDB.instance().warnOnUnclosed && !closed) {
|
||||
System.err.println(context + " not closed");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,17 +21,17 @@
|
|||
package com.apple.foundationdb;
|
||||
|
||||
class RangeResultInfo {
|
||||
RangeResultSummary getSummary() {
|
||||
return f.getSummary();
|
||||
}
|
||||
RangeResultSummary getSummary() {
|
||||
return f.getSummary();
|
||||
}
|
||||
|
||||
RangeResult get() {
|
||||
return f.getResults();
|
||||
}
|
||||
RangeResult get() {
|
||||
return f.getResults();
|
||||
}
|
||||
|
||||
RangeResultInfo(FutureResults f) {
|
||||
this.f = f;
|
||||
}
|
||||
RangeResultInfo(FutureResults f) {
|
||||
this.f = f;
|
||||
}
|
||||
|
||||
private FutureResults f;
|
||||
private FutureResults f;
|
||||
}
|
||||
|
|
|
@ -43,6 +43,7 @@ public interface ReadTransactionContext {
|
|||
*
|
||||
* @param retryable the block of logic to execute against a {@link ReadTransaction}
|
||||
* in this context
|
||||
* @param <T> the return type of {@code retryable}
|
||||
*
|
||||
* @return a result of the last call to {@code retryable}
|
||||
*/
|
||||
|
@ -56,6 +57,7 @@ public interface ReadTransactionContext {
|
|||
*
|
||||
* @param retryable the block of logic to execute against a {@link ReadTransaction}
|
||||
* in this context
|
||||
* @param <T> the return type of {@code retryable}
|
||||
*
|
||||
* @return a {@code CompletableFuture} that will be set to the value returned by the last call
|
||||
* to {@code retryable}
|
||||
|
|
|
@ -34,7 +34,7 @@ import com.apple.foundationdb.tuple.Tuple;
|
|||
* the underlying database if and when the transaction is committed. Read operations do see the
|
||||
* effects of previous write operations on the same transaction. Committing a transaction usually
|
||||
* succeeds in the absence of
|
||||
* <a href="/foundationdb/developer-guide.html#transaction-conflicts" target="_blank">conflicts</a>.<br>
|
||||
* <a href="/foundationdb/developer-guide.html#developer-guide-transaction-conflicts" target="_blank">conflicts</a>.<br>
|
||||
* <br>
|
||||
* Transactions group operations into a unit with the properties of atomicity, isolation, and
|
||||
* durability. Transactions also provide the ability to maintain an application's invariants or
|
||||
|
@ -49,7 +49,7 @@ import com.apple.foundationdb.tuple.Tuple;
|
|||
* <br>
|
||||
* Keys and values in FoundationDB are byte arrays. To encode other data types, see the
|
||||
* {@link Tuple Tuple API} and
|
||||
* <a href="/foundationdb/data-modeling.html#tuples" target="_blank">tuple layer documentation</a>.<br>
|
||||
* <a href="/foundationdb/data-modeling.html#data-modeling-tuples" target="_blank">tuple layer documentation</a>.<br>
|
||||
* <br>
|
||||
* When used as a {@link TransactionContext}, the methods {@code run()} and
|
||||
* {@code runAsync()} on a {@code Transaction} will simply attempt the operations
|
||||
|
@ -84,6 +84,8 @@ public interface Transaction extends AutoCloseable, ReadTransaction, Transaction
|
|||
* <br>
|
||||
* For more information about how to use snapshot reads correctly, see
|
||||
* <a href="/foundationdb/developer-guide.html#using-snapshot-reads" target="_blank">Using snapshot reads</a>.
|
||||
*
|
||||
* @return a read-only view of this {@code Transaction} with relaxed isolation properties
|
||||
*/
|
||||
ReadTransaction snapshot();
|
||||
|
||||
|
@ -143,8 +145,9 @@ public interface Transaction extends AutoCloseable, ReadTransaction, Transaction
|
|||
*
|
||||
* @param key the key whose value is to be set
|
||||
* @param value the value to set in the database
|
||||
* @throws IllegalArgumentException
|
||||
* @throws FDBException
|
||||
*
|
||||
* @throws IllegalArgumentException if {@code key} or {@code value} is {@code null}
|
||||
* @throws FDBException if the set operation otherwise fails
|
||||
*/
|
||||
void set(byte[] key, byte[] value);
|
||||
|
||||
|
@ -153,8 +156,9 @@ public interface Transaction extends AutoCloseable, ReadTransaction, Transaction
|
|||
* database until {@link #commit} is called.
|
||||
*
|
||||
* @param key the key whose value is to be cleared
|
||||
* @throws IllegalArgumentException
|
||||
* @throws FDBException
|
||||
*
|
||||
* @throws IllegalArgumentException if {@code key} is {@code null}
|
||||
* @throws FDBException if clear operation otherwise fails
|
||||
*/
|
||||
void clear(byte[] key);
|
||||
|
||||
|
@ -167,8 +171,9 @@ public interface Transaction extends AutoCloseable, ReadTransaction, Transaction
|
|||
*
|
||||
* @param beginKey the first clear
|
||||
* @param endKey the key one past the last key to clear
|
||||
* @throws IllegalArgumentException
|
||||
* @throws FDBException
|
||||
*
|
||||
* @throws IllegalArgumentException if {@code beginKey} or {@code endKey} is {@code null}
|
||||
* @throws FDBException if the clear operation otherwise fails
|
||||
*/
|
||||
void clear(byte[] beginKey, byte[] endKey);
|
||||
|
||||
|
@ -181,7 +186,7 @@ public interface Transaction extends AutoCloseable, ReadTransaction, Transaction
|
|||
*
|
||||
* @param range the range of keys to clear
|
||||
*
|
||||
* @throws FDBException
|
||||
* @throws FDBException if the clear operation fails
|
||||
*/
|
||||
void clear(Range range);
|
||||
|
||||
|
@ -191,7 +196,7 @@ public interface Transaction extends AutoCloseable, ReadTransaction, Transaction
|
|||
*
|
||||
* @param prefix the starting bytes from the keys to be cleared.
|
||||
*
|
||||
* @throws FDBException
|
||||
* @throws FDBException if the clear-range operation fails
|
||||
*/
|
||||
@Deprecated
|
||||
void clearRangeStartsWith(byte[] prefix);
|
||||
|
@ -209,15 +214,15 @@ public interface Transaction extends AutoCloseable, ReadTransaction, Transaction
|
|||
* read. It can only cause other transactions performing reads of the key
|
||||
* to conflict.<br>
|
||||
* <br>
|
||||
* By combining these logical steps into a single, read-free operation,
|
||||
* FoundationDB can guarantee that the transaction will not conflict due to
|
||||
* the operation. This makes atomic operations ideal for operating on keys
|
||||
* that are frequently modified. A common example is the use of a key-value
|
||||
* pair as a counter.<br>
|
||||
* <br>
|
||||
* <b>Note:</b> If a transaction uses both an atomic operation and a serializable
|
||||
* read on the same key, the benefits of using the atomic operation (for both
|
||||
* conflict checking and performance) are lost.
|
||||
* By combining these logical steps into a single, read-free operation,
|
||||
* FoundationDB can guarantee that the transaction will not conflict due to
|
||||
* the operation. This makes atomic operations ideal for operating on keys
|
||||
* that are frequently modified. A common example is the use of a key-value
|
||||
* pair as a counter.<br>
|
||||
* <br>
|
||||
* <b>Note:</b> If a transaction uses both an atomic operation and a serializable
|
||||
* read on the same key, the benefits of using the atomic operation (for both
|
||||
* conflict checking and performance) are lost.
|
||||
*
|
||||
* The behavior of each {@link MutationType} is documented at its definition.
|
||||
*
|
||||
|
@ -232,10 +237,7 @@ public interface Transaction extends AutoCloseable, ReadTransaction, Transaction
|
|||
* {@code Database}'s {@link Database#run(Function) run()} calls for managing
|
||||
* transactional access to FoundationDB.
|
||||
*
|
||||
* @return a {@code CompletableFuture} that, when set without error, guarantees the
|
||||
* {@code Transaction}'s modifications committed durably to the
|
||||
* database. If the commit failed, it will throw an {@link FDBException}.
|
||||
* <br><br>
|
||||
* <p>
|
||||
* As with other client/server databases, in some failure scenarios a client may
|
||||
* be unable to determine whether a transaction succeeded. In these cases, an
|
||||
* {@link FDBException} will be thrown with error code {@code commit_unknown_result} (1021).
|
||||
|
@ -243,11 +245,18 @@ public interface Transaction extends AutoCloseable, ReadTransaction, Transaction
|
|||
* retry loops that don't specifically detect {@code commit_unknown_result} could end
|
||||
* up executing a transaction twice. For more information, see the FoundationDB
|
||||
* Developer Guide documentation.
|
||||
* </p>
|
||||
*
|
||||
* If any operation is performed on a transaction after a commit has been
|
||||
* <p>
|
||||
* If any operation is performed on a transaction after a commit has been
|
||||
* issued but before it has returned, both the commit and the operation will
|
||||
* throw an error code {@code used_during_commit}(2017). In this case, all
|
||||
* throw an error code {@code used_during_commit} (2017). In this case, all
|
||||
* subsequent operations on this transaction will throw this error.
|
||||
* </p>
|
||||
*
|
||||
* @return a {@code CompletableFuture} that, when set without error, guarantees the
|
||||
* {@code Transaction}'s modifications committed durably to the
|
||||
* database. If the commit failed, it will throw an {@link FDBException}.
|
||||
*/
|
||||
CompletableFuture<Void> commit();
|
||||
|
||||
|
@ -355,7 +364,10 @@ public interface Transaction extends AutoCloseable, ReadTransaction, Transaction
|
|||
* Run a function once against this {@code Transaction}. This call blocks while
|
||||
* user code is executing, returning the result of that code on completion.
|
||||
*
|
||||
* @return the return value of {@code retryable}
|
||||
* @param retryable the block of logic to execute against this {@code Transaction}
|
||||
* @param <T> the return type of {@code retryable}
|
||||
*
|
||||
* @return a result of the single call to {@code retryable}
|
||||
*/
|
||||
@Override
|
||||
<T> T run(Function<? super Transaction, T> retryable);
|
||||
|
@ -364,6 +376,9 @@ public interface Transaction extends AutoCloseable, ReadTransaction, Transaction
|
|||
* Run a function once against this {@code Transaction}. This call returns
|
||||
* immediately with a {@code CompletableFuture} handle to the result.
|
||||
*
|
||||
* @param retryable the block of logic to execute against this {@code Transaction}
|
||||
* @param <T> the return type of {@code retryable}
|
||||
*
|
||||
* @return a {@code CompletableFuture} that will be set to the return value of {@code retryable}
|
||||
*/
|
||||
@Override
|
||||
|
|
|
@ -42,6 +42,7 @@ public interface TransactionContext extends ReadTransactionContext {
|
|||
*
|
||||
* @param retryable the block of logic to execute against a {@link Transaction}
|
||||
* in this context
|
||||
* @param <T> the return type of {@code retryable}
|
||||
*
|
||||
* @return a result of the last call to {@code retryable}
|
||||
*/
|
||||
|
@ -55,6 +56,7 @@ public interface TransactionContext extends ReadTransactionContext {
|
|||
*
|
||||
* @param retryable the block of logic to execute against a {@link Transaction}
|
||||
* in this context
|
||||
* @param <T> the return type of {@code retryable}
|
||||
*
|
||||
* @return a {@code CompletableFuture} that will be set to the value returned by the last call
|
||||
* to {@code retryable}
|
||||
|
|
|
@ -63,6 +63,8 @@ public class AsyncUtil {
|
|||
*
|
||||
* @param func the {@code Function} to run
|
||||
* @param value the input to pass to {@code func}
|
||||
* @param <I> type of input to {@code func}
|
||||
* @param <O> type of output of {@code func}
|
||||
*
|
||||
* @return the output of {@code func}, or a {@code CompletableFuture} carrying any exception
|
||||
* caught in the process.
|
||||
|
@ -159,9 +161,10 @@ public class AsyncUtil {
|
|||
}
|
||||
|
||||
/**
|
||||
* Iterates over a set of items and returns the result as a list.
|
||||
* Iterates over a stream of items and returns the result as a list.
|
||||
*
|
||||
* @param iterable the source of data over which to iterate
|
||||
* @param <V> type of the items returned by the iterable
|
||||
*
|
||||
* @return a {@code CompletableFuture} which will be set to the amalgamation of results
|
||||
* from iteration.
|
||||
|
@ -174,6 +177,7 @@ public class AsyncUtil {
|
|||
* Iterates over a set of items and returns the remaining results as a list.
|
||||
*
|
||||
* @param iterator the source of data over which to iterate. This function will exhaust the iterator.
|
||||
* @param <V> type of the items returned by the iterator
|
||||
*
|
||||
* @return a {@code CompletableFuture} which will be set to the amalgamation of results
|
||||
* from iteration.
|
||||
|
@ -187,6 +191,7 @@ public class AsyncUtil {
|
|||
*
|
||||
* @param iterable the source of data over which to iterate
|
||||
* @param executor the {@link Executor} to use for asynchronous operations
|
||||
* @param <V> type of the items returned by the iterable
|
||||
*
|
||||
* @return a {@code CompletableFuture} which will be set to the amalgamation of results
|
||||
* from iteration.
|
||||
|
@ -200,6 +205,7 @@ public class AsyncUtil {
|
|||
*
|
||||
* @param iterator the source of data over which to iterate. This function will exhaust the iterator.
|
||||
* @param executor the {@link Executor} to use for asynchronous operations
|
||||
* @param <V> type of the items returned by the iterator
|
||||
*
|
||||
* @return a {@code CompletableFuture} which will be set to the amalgamation of results
|
||||
* from iteration.
|
||||
|
@ -215,6 +221,9 @@ public class AsyncUtil {
|
|||
*
|
||||
* @param iterable input
|
||||
* @param func mapping function applied to each element
|
||||
* @param <V> type of the items returned by the original iterable
|
||||
* @param <T> type of the items returned by the final iterable
|
||||
*
|
||||
* @return a new iterable with each element mapped to a different value
|
||||
*/
|
||||
public static <V, T> AsyncIterable<T> mapIterable(final AsyncIterable<V> iterable,
|
||||
|
@ -239,6 +248,9 @@ public class AsyncUtil {
|
|||
*
|
||||
* @param iterator input
|
||||
* @param func mapping function applied to each element
|
||||
* @param <V> type of the items returned by the original iterator
|
||||
* @param <T> type of the items returned by the final iterator
|
||||
*
|
||||
* @return a new iterator with each element mapped to a different value
|
||||
*/
|
||||
public static <V, T> AsyncIterator<T> mapIterator(final AsyncIterator<V> iterator,
|
||||
|
@ -277,6 +289,9 @@ public class AsyncUtil {
|
|||
*
|
||||
* @param iterator input
|
||||
* @param func mapping function applied to each element
|
||||
* @param <V> type of the items returned by the original iterator
|
||||
* @param <T> type of the items returned by the final iterator
|
||||
*
|
||||
* @return a new iterator with each element mapped to a different value
|
||||
*/
|
||||
public static <V, T> CloseableAsyncIterator<T> mapIterator(final CloseableAsyncIterator<V> iterator,
|
||||
|
@ -423,6 +438,7 @@ public class AsyncUtil {
|
|||
* All errors from {@code task} will be passed to the resulting {@code CompletableFuture}.
|
||||
*
|
||||
* @param task the asynchronous process for which to signal completion
|
||||
* @param <V> type of element returned by {@code task}
|
||||
*
|
||||
* @return a newly created {@code CompletableFuture} that is set when {@code task} completes
|
||||
*/
|
||||
|
@ -432,11 +448,12 @@ public class AsyncUtil {
|
|||
|
||||
/**
|
||||
* Maps the readiness of a {@link CompletableFuture} into a completion signal. When
|
||||
* the given {@link CompletableFuture} is set to a value or an error, the returned {@link CompletableFuture}
|
||||
* will be set to null. The returned {@link CompletableFuture} will never be set to an error unless
|
||||
* it is explicitly cancelled.
|
||||
* the given {@link CompletableFuture} is set to a value or an error, the returned {@link CompletableFuture}
|
||||
* will be set to null. The returned {@link CompletableFuture} will never be set to an error unless
|
||||
* it is explicitly cancelled.
|
||||
*
|
||||
* @param task the asynchronous process to monitor the readiness of
|
||||
* @param <V> return type of the asynchronous task
|
||||
*
|
||||
* @return a new {@link CompletableFuture} that is set when {@code task} is ready.
|
||||
*/
|
||||
|
@ -444,6 +461,22 @@ public class AsyncUtil {
|
|||
return task.handle((v, t) -> null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Composes an asynchronous task with an exception-handler that returns a {@link CompletableFuture}
|
||||
* of the same type. If {@code task} completes normally, this will return a {@link CompletableFuture}
|
||||
* with the same value as {@code task}. If {@code task} completes exceptionally,
|
||||
* this will call {@code fn} with the exception returned by {@code task} and return
|
||||
* the result of the {@link CompletableFuture} returned by that function.
|
||||
*
|
||||
* @param task the asynchronous process to handle exceptions from
|
||||
* @param fn a function mapping exceptions from {@code task} to a {@link CompletableFuture} of the same
|
||||
* type as {@code task}
|
||||
* @param <V> return type of the asynchronous task
|
||||
*
|
||||
* @return a {@link CompletableFuture} that contains the value returned by {@code task}
|
||||
* if {@code task} completes normally and the result of {@code fn} if {@code task}
|
||||
* completes exceptionally
|
||||
*/
|
||||
public static <V> CompletableFuture<V> composeExceptionally(CompletableFuture<V> task, Function<Throwable, CompletableFuture<V>> fn) {
|
||||
return task.handle((v,e) -> e)
|
||||
.thenCompose(e -> {
|
||||
|
@ -521,6 +554,7 @@ public class AsyncUtil {
|
|||
* any of the tasks returns an error, the output is set to that error.
|
||||
*
|
||||
* @param tasks the tasks whose output is to be added to the output
|
||||
* @param <V> return type of the asynchronous tasks
|
||||
*
|
||||
* @return a {@code CompletableFuture} that will be set to the collective result of the tasks
|
||||
*/
|
||||
|
@ -539,8 +573,9 @@ public class AsyncUtil {
|
|||
* Replaces the output of an asynchronous task with a predetermined value.
|
||||
*
|
||||
* @param task the asynchronous process whose output is to be replaced
|
||||
*
|
||||
* @param value the predetermined value to be returned on success of {@code task}
|
||||
* @param <V> return type of original future
|
||||
* @param <T> return type of final future
|
||||
*
|
||||
* @return a {@code CompletableFuture} that will be set to {@code value} on completion of {@code task}
|
||||
*/
|
||||
|
@ -554,6 +589,7 @@ public class AsyncUtil {
|
|||
*
|
||||
* @param input the list of {@link CompletableFuture}s to monitor. This list
|
||||
* <b>must not</b> be modified during the execution of this call.
|
||||
* @param <V> return type of the asynchronous tasks
|
||||
*
|
||||
* @return a signal that will be set when any of the {@code CompletableFuture}s are done
|
||||
*/
|
||||
|
@ -569,6 +605,7 @@ public class AsyncUtil {
|
|||
*
|
||||
* @param input the list of {@link CompletableFuture}s to monitor. This list
|
||||
* <b>must not</b> be modified during the execution of this call.
|
||||
* @param <V> return type of the asynchronous tasks
|
||||
*
|
||||
* @return a signal that will be set when all of the {@code CompletableFuture}s are done
|
||||
*/
|
||||
|
|
|
@ -526,7 +526,7 @@ public class DirectoryLayer implements Directory {
|
|||
|
||||
return AsyncUtil.collect(
|
||||
AsyncUtil.mapIterable(tr.getRange(subdir.range()),
|
||||
kv -> subdir.unpack(kv.getKey()).getString(0)
|
||||
kv -> subdir.unpack(kv.getKey()).getString(0)
|
||||
),
|
||||
tr.getExecutor()
|
||||
);
|
||||
|
|
|
@ -37,8 +37,8 @@ import com.apple.foundationdb.tuple.Tuple;
|
|||
* content.
|
||||
* </p>
|
||||
*
|
||||
* For general guidance on partition usage, see
|
||||
* <a href="/foundationdb/developer-guide.html#directory-partitions" target="_blank">The Developer Guide</a>.
|
||||
* For general guidance on partition usage, see the
|
||||
* <a href="/foundationdb/developer-guide.html#directory-partitions" target="_blank">Developer Guide</a>.
|
||||
*/
|
||||
class DirectoryPartition extends DirectorySubspace {
|
||||
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
* assure that {@link com.apple.foundationdb.Transaction#commit()} has returned successfully
|
||||
* before itself returning. If you are not able to use these functions for some reason
|
||||
* please closely read and understand the other
|
||||
* <a href="/foundationdb/data-modeling.html#tuples">developer
|
||||
* <a href="/foundationdb/data-modeling.html#data-modeling-tuples">developer
|
||||
* documentation on FoundationDB transactions</a>.
|
||||
*/
|
||||
package com.apple.foundationdb;
|
||||
|
|
|
@ -38,7 +38,7 @@ import com.apple.foundationdb.tuple.Versionstamp;
|
|||
*
|
||||
* <p>
|
||||
* For general guidance on subspace usage, see the discussion in
|
||||
* <a href="/foundationdb/developer-guide.html#subspaces-of-keys" target="_blank">Developer Guide</a>.
|
||||
* <a href="/foundationdb/developer-guide.html#developer-guide-sub-keyspaces" target="_blank">Developer Guide</a>.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
|
@ -46,231 +46,231 @@ import com.apple.foundationdb.tuple.Versionstamp;
|
|||
* </p>
|
||||
*/
|
||||
public class Subspace {
|
||||
static final Tuple EMPTY_TUPLE = Tuple.from();
|
||||
static final byte[] EMPTY_BYTES = new byte[0];
|
||||
static final Tuple EMPTY_TUPLE = Tuple.from();
|
||||
static final byte[] EMPTY_BYTES = new byte[0];
|
||||
|
||||
private final byte[] rawPrefix;
|
||||
private final byte[] rawPrefix;
|
||||
|
||||
/**
|
||||
* Constructor for a subspace formed with an empty prefix {@link Tuple}.
|
||||
*/
|
||||
public Subspace() {
|
||||
this(EMPTY_TUPLE, EMPTY_BYTES);
|
||||
}
|
||||
/**
|
||||
* Constructor for a subspace formed with an empty prefix {@link Tuple}.
|
||||
*/
|
||||
public Subspace() {
|
||||
this(EMPTY_TUPLE, EMPTY_BYTES);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor for a subspace formed with the specified prefix {@link Tuple}.
|
||||
* Note that the {@link Tuple} {@code prefix} should not contain any incomplete
|
||||
* {@link Versionstamp}s as any of its entries.
|
||||
*
|
||||
* @param prefix a {@link Tuple} used to form the subspace
|
||||
* @throws IllegalArgumentException if {@code prefix} contains any incomplete {@link Versionstamp}s
|
||||
*/
|
||||
public Subspace(Tuple prefix) {
|
||||
this(prefix, EMPTY_BYTES);
|
||||
}
|
||||
/**
|
||||
* Constructor for a subspace formed with the specified prefix {@link Tuple}.
|
||||
* Note that the {@link Tuple} {@code prefix} should not contain any incomplete
|
||||
* {@link Versionstamp}s as any of its entries.
|
||||
*
|
||||
* @param prefix a {@link Tuple} used to form the subspace
|
||||
* @throws IllegalArgumentException if {@code prefix} contains any incomplete {@link Versionstamp}s
|
||||
*/
|
||||
public Subspace(Tuple prefix) {
|
||||
this(prefix, EMPTY_BYTES);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor for a subspace formed with the specified byte string, which will
|
||||
* be prepended to all packed keys.
|
||||
*
|
||||
* @param rawPrefix a byte array used as the prefix for all packed keys
|
||||
*/
|
||||
public Subspace(byte[] rawPrefix) {
|
||||
this(EMPTY_TUPLE, rawPrefix);
|
||||
}
|
||||
/**
|
||||
* Constructor for a subspace formed with the specified byte string, which will
|
||||
* be prepended to all packed keys.
|
||||
*
|
||||
* @param rawPrefix a byte array used as the prefix for all packed keys
|
||||
*/
|
||||
public Subspace(byte[] rawPrefix) {
|
||||
this(EMPTY_TUPLE, rawPrefix);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor for a subspace formed with both a prefix {@link Tuple} and a
|
||||
* prefix byte string. The prefix {@code Tuple} will be prepended to all
|
||||
* {@code Tuples} packed by the {@code Subspace}, and the byte string prefix
|
||||
* will be prepended to the packed result. Note that the {@link Tuple} {@code prefix}
|
||||
* should not contain any incomplete {@link Versionstamp}s as any of its entries.
|
||||
*
|
||||
* @param prefix a {@code Tuple} used to form the subspace
|
||||
* @param rawPrefix a byte array used as the prefix for all packed keys
|
||||
* @throws IllegalArgumentException if {@code prefix} contains any incomplete {@link Versionstamp}s
|
||||
*/
|
||||
public Subspace(Tuple prefix, byte[] rawPrefix) {
|
||||
this.rawPrefix = join(rawPrefix, prefix.pack());
|
||||
}
|
||||
/**
|
||||
* Constructor for a subspace formed with both a prefix {@link Tuple} and a
|
||||
* prefix byte string. The prefix {@code Tuple} will be prepended to all
|
||||
* {@code Tuples} packed by the {@code Subspace}, and the byte string prefix
|
||||
* will be prepended to the packed result. Note that the {@link Tuple} {@code prefix}
|
||||
* should not contain any incomplete {@link Versionstamp}s as any of its entries.
|
||||
*
|
||||
* @param prefix a {@code Tuple} used to form the subspace
|
||||
* @param rawPrefix a byte array used as the prefix for all packed keys
|
||||
* @throws IllegalArgumentException if {@code prefix} contains any incomplete {@link Versionstamp}s
|
||||
*/
|
||||
public Subspace(Tuple prefix, byte[] rawPrefix) {
|
||||
this.rawPrefix = join(rawPrefix, prefix.pack());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this {@code Subspace} is equal to {@code rhs}.
|
||||
* Two {@code Subspace}s are equal if they have the same prefix.
|
||||
*
|
||||
* @param rhs the object to check for equality
|
||||
* @return {@code true} if this {@code Subspace} and {@code rhs} have equal prefixes
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object rhs) {
|
||||
if(this == rhs) {
|
||||
return true;
|
||||
}
|
||||
if(rhs == null || getClass() != rhs.getClass()) {
|
||||
return false;
|
||||
}
|
||||
Subspace other = (Subspace)rhs;
|
||||
return Arrays.equals(rawPrefix, other.rawPrefix);
|
||||
}
|
||||
/**
|
||||
* Returns true if this {@code Subspace} is equal to {@code rhs}.
|
||||
* Two {@code Subspace}s are equal if they have the same prefix.
|
||||
*
|
||||
* @param rhs the object to check for equality
|
||||
* @return {@code true} if this {@code Subspace} and {@code rhs} have equal prefixes
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object rhs) {
|
||||
if(this == rhs) {
|
||||
return true;
|
||||
}
|
||||
if(rhs == null || getClass() != rhs.getClass()) {
|
||||
return false;
|
||||
}
|
||||
Subspace other = (Subspace)rhs;
|
||||
return Arrays.equals(rawPrefix, other.rawPrefix);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a human-readable string representation of this subspace. This is
|
||||
* really only useful for debugging purposes, but it includes information
|
||||
* on what raw prefix the subspace is using.
|
||||
* @return a printable representation of the subspace
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Subspace(rawPrefix=" + printable(rawPrefix) + ")";
|
||||
}
|
||||
/**
|
||||
* Create a human-readable string representation of this subspace. This is
|
||||
* really only useful for debugging purposes, but it includes information
|
||||
* on what raw prefix the subspace is using.
|
||||
* @return a printable representation of the subspace
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Subspace(rawPrefix=" + printable(rawPrefix) + ")";
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a hash-table compatible hash of this subspace. This is based off
|
||||
* of the hash of the underlying byte-array prefix.
|
||||
* @return a hash of this subspace
|
||||
*/
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Arrays.hashCode(rawPrefix);
|
||||
}
|
||||
/**
|
||||
* Returns a hash-table compatible hash of this subspace. This is based off
|
||||
* of the hash of the underlying byte-array prefix.
|
||||
* @return a hash of this subspace
|
||||
*/
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Arrays.hashCode(rawPrefix);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a new subspace which is equivalent to this subspace with its prefix {@link Tuple} extended by
|
||||
* the specified {@code Object}. The object will be inserted into a {@link Tuple} and passed to {@link #get(Tuple)}.
|
||||
*
|
||||
* @param obj an {@code Object} compatible with {@code Tuple}s
|
||||
* @return a new subspace formed by joining this {@code Subspace}'s prefix to {@code obj}
|
||||
*/
|
||||
public Subspace get(Object obj) {
|
||||
return get(Tuple.from(obj));
|
||||
}
|
||||
/**
|
||||
* Gets a new subspace which is equivalent to this subspace with its prefix {@link Tuple} extended by
|
||||
* the specified {@code Object}. The object will be inserted into a {@link Tuple} and passed to {@link #get(Tuple)}.
|
||||
*
|
||||
* @param obj an {@code Object} compatible with {@code Tuple}s
|
||||
* @return a new subspace formed by joining this {@code Subspace}'s prefix to {@code obj}
|
||||
*/
|
||||
public Subspace get(Object obj) {
|
||||
return get(Tuple.from(obj));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a new subspace which is equivalent to this subspace with its prefix {@link Tuple} extended by
|
||||
* the specified {@link Tuple}.
|
||||
*
|
||||
* @param tuple the {@link Tuple} used to form the new {@code Subspace}
|
||||
* @return a new subspace formed by joining this {@code Subspace}'s prefix to {@code tuple}
|
||||
*/
|
||||
public Subspace get(Tuple tuple) {
|
||||
return subspace(tuple);
|
||||
}
|
||||
/**
|
||||
* Gets a new subspace which is equivalent to this subspace with its prefix {@link Tuple} extended by
|
||||
* the specified {@link Tuple}.
|
||||
*
|
||||
* @param tuple the {@link Tuple} used to form the new {@code Subspace}
|
||||
* @return a new subspace formed by joining this {@code Subspace}'s prefix to {@code tuple}
|
||||
*/
|
||||
public Subspace get(Tuple tuple) {
|
||||
return subspace(tuple);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the key encoding the prefix used for this {@code Subspace}. This is equivalent to
|
||||
* {@link #pack}ing the empty {@link Tuple}.
|
||||
*
|
||||
* @return the key encoding the prefix used for this {@code Subspace}
|
||||
*/
|
||||
public byte[] getKey() {
|
||||
return pack();
|
||||
}
|
||||
/**
|
||||
* Gets the key encoding the prefix used for this {@code Subspace}. This is equivalent to
|
||||
* {@link #pack}ing the empty {@link Tuple}.
|
||||
*
|
||||
* @return the key encoding the prefix used for this {@code Subspace}
|
||||
*/
|
||||
public byte[] getKey() {
|
||||
return pack();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the key encoding the prefix used for this {@code Subspace}.
|
||||
*
|
||||
* @return the key encoding the prefix used for this {@code Subspace}
|
||||
*/
|
||||
public byte[] pack() {
|
||||
return Arrays.copyOf(rawPrefix, rawPrefix.length);
|
||||
}
|
||||
/**
|
||||
* Gets the key encoding the prefix used for this {@code Subspace}.
|
||||
*
|
||||
* @return the key encoding the prefix used for this {@code Subspace}
|
||||
*/
|
||||
public byte[] pack() {
|
||||
return Arrays.copyOf(rawPrefix, rawPrefix.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the key encoding the specified {@code Object} in this {@code Subspace}. {@code obj} is
|
||||
* inserted into a {@link Tuple} and packed with {@link #pack(Tuple)}.
|
||||
*
|
||||
* @param obj an {@code Object} to be packed that is compatible with {@link Tuple}s
|
||||
* @return the key encoding the tuple derived from {@code obj}
|
||||
*/
|
||||
public byte[] pack(Object obj) {
|
||||
return pack(Tuple.from(obj));
|
||||
}
|
||||
/**
|
||||
* Gets the key encoding the specified {@code Object} in this {@code Subspace}. {@code obj} is
|
||||
* inserted into a {@link Tuple} and packed with {@link #pack(Tuple)}.
|
||||
*
|
||||
* @param obj an {@code Object} to be packed that is compatible with {@link Tuple}s
|
||||
* @return the key encoding the tuple derived from {@code obj}
|
||||
*/
|
||||
public byte[] pack(Object obj) {
|
||||
return pack(Tuple.from(obj));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the key encoding the specified tuple in this {@code Subspace}. For example, if you have a {@code Subspace}
|
||||
* with prefix {@link Tuple} {@code ("users")} and you use it to pack the {@link Tuple} {@code ("Smith")},
|
||||
* the result is the same as if you packed the {@link Tuple} {@code ("users", "Smith")}.
|
||||
*
|
||||
* @param tuple the {@code Tuple} to be packed
|
||||
* @return the key encoding the specified tuple in this {@code Subspace}
|
||||
*/
|
||||
public byte[] pack(Tuple tuple) {
|
||||
return tuple.pack(rawPrefix);
|
||||
}
|
||||
/**
|
||||
* Gets the key encoding the specified tuple in this {@code Subspace}. For example, if you have a {@code Subspace}
|
||||
* with prefix {@link Tuple} {@code ("users")} and you use it to pack the {@link Tuple} {@code ("Smith")},
|
||||
* the result is the same as if you packed the {@link Tuple} {@code ("users", "Smith")}.
|
||||
*
|
||||
* @param tuple the {@code Tuple} to be packed
|
||||
* @return the key encoding the specified tuple in this {@code Subspace}
|
||||
*/
|
||||
public byte[] pack(Tuple tuple) {
|
||||
return tuple.pack(rawPrefix);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the key encoding the specified tuple in this {@code Subspace} for use with
|
||||
* {@link com.apple.foundationdb.MutationType#SET_VERSIONSTAMPED_KEY MutationType.SET_VERSIONSTAMPED_KEY}.
|
||||
* There must be exactly one incomplete {@link Versionstamp} included in the given {@link Tuple}. It will
|
||||
* create a key that is within this {@code Subspace} that can be provided as the {@code key} argument to
|
||||
* {@link com.apple.foundationdb.Transaction#mutate(com.apple.foundationdb.MutationType, byte[], byte[]) Transaction.mutate()}
|
||||
* with the {@link com.apple.foundationdb.MutationType#SET_VERSIONSTAMPED_KEY SET_VERSIONSTAMPED_KEY}
|
||||
* mutation. This will throw an {@link IllegalArgumentException} if the {@link Tuple} does not
|
||||
* contain an incomplete {@link Versionstamp} or if it contains multiple.
|
||||
*
|
||||
* @param tuple the {@code Tuple} to be packed
|
||||
* @return the key encoding the specified tuple in this {@code Subspace}
|
||||
* @throws IllegalArgumentException if {@code tuple} does not contain exactly one incomplete {@link Versionstamp}
|
||||
*/
|
||||
public byte[] packWithVersionstamp(Tuple tuple) {
|
||||
return tuple.packWithVersionstamp(rawPrefix);
|
||||
}
|
||||
/**
|
||||
* Gets the key encoding the specified tuple in this {@code Subspace} for use with
|
||||
* {@link com.apple.foundationdb.MutationType#SET_VERSIONSTAMPED_KEY MutationType.SET_VERSIONSTAMPED_KEY}.
|
||||
* There must be exactly one incomplete {@link Versionstamp} included in the given {@link Tuple}. It will
|
||||
* create a key that is within this {@code Subspace} that can be provided as the {@code key} argument to
|
||||
* {@link com.apple.foundationdb.Transaction#mutate(com.apple.foundationdb.MutationType, byte[], byte[]) Transaction.mutate()}
|
||||
* with the {@link com.apple.foundationdb.MutationType#SET_VERSIONSTAMPED_KEY SET_VERSIONSTAMPED_KEY}
|
||||
* mutation. This will throw an {@link IllegalArgumentException} if the {@link Tuple} does not
|
||||
* contain an incomplete {@link Versionstamp} or if it contains multiple.
|
||||
*
|
||||
* @param tuple the {@code Tuple} to be packed
|
||||
* @return the key encoding the specified tuple in this {@code Subspace}
|
||||
* @throws IllegalArgumentException if {@code tuple} does not contain exactly one incomplete {@link Versionstamp}
|
||||
*/
|
||||
public byte[] packWithVersionstamp(Tuple tuple) {
|
||||
return tuple.packWithVersionstamp(rawPrefix);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the {@link Tuple} encoded by the given key, with this {@code Subspace}'s prefix {@link Tuple} and
|
||||
* {@code raw prefix} removed.
|
||||
*
|
||||
* @param key The key being decoded
|
||||
* @return the {@link Tuple} encoded by {@code key} with the prefix removed
|
||||
*/
|
||||
public Tuple unpack(byte[] key) {
|
||||
if(!contains(key))
|
||||
throw new IllegalArgumentException("Cannot unpack key that is not contained in subspace.");
|
||||
/**
|
||||
* Gets the {@link Tuple} encoded by the given key, with this {@code Subspace}'s prefix {@link Tuple} and
|
||||
* {@code raw prefix} removed.
|
||||
*
|
||||
* @param key The key being decoded
|
||||
* @return the {@link Tuple} encoded by {@code key} with the prefix removed
|
||||
*/
|
||||
public Tuple unpack(byte[] key) {
|
||||
if(!contains(key))
|
||||
throw new IllegalArgumentException("Cannot unpack key that is not contained in subspace.");
|
||||
|
||||
return Tuple.fromBytes(Arrays.copyOfRange(key, rawPrefix.length, key.length));
|
||||
}
|
||||
return Tuple.fromBytes(Arrays.copyOfRange(key, rawPrefix.length, key.length));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a {@link Range} respresenting all keys strictly in the {@code Subspace}.
|
||||
*
|
||||
* @return the {@link Range} of keyspace corresponding to this {@code Subspace}
|
||||
*/
|
||||
public Range range() {
|
||||
return range(EMPTY_TUPLE);
|
||||
}
|
||||
/**
|
||||
* Gets a {@link Range} respresenting all keys strictly in the {@code Subspace}.
|
||||
*
|
||||
* @return the {@link Range} of keyspace corresponding to this {@code Subspace}
|
||||
*/
|
||||
public Range range() {
|
||||
return range(EMPTY_TUPLE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a {@link Range} representing all keys in the {@code Subspace} strictly starting with
|
||||
* the specified {@link Tuple}.
|
||||
*
|
||||
* @param tuple the {@code Tuple} whose sub-keys we are searching for
|
||||
* @return the {@link Range} of keyspace corresponding to {@code tuple}
|
||||
*/
|
||||
public Range range(Tuple tuple) {
|
||||
Range p = tuple.range();
|
||||
return new Range(join(rawPrefix, p.begin), join(rawPrefix, p.end));
|
||||
}
|
||||
/**
|
||||
* Gets a {@link Range} representing all keys in the {@code Subspace} strictly starting with
|
||||
* the specified {@link Tuple}.
|
||||
*
|
||||
* @param tuple the {@code Tuple} whose sub-keys we are searching for
|
||||
* @return the {@link Range} of keyspace corresponding to {@code tuple}
|
||||
*/
|
||||
public Range range(Tuple tuple) {
|
||||
Range p = tuple.range();
|
||||
return new Range(join(rawPrefix, p.begin), join(rawPrefix, p.end));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests whether the specified key starts with this {@code Subspace}'s prefix, indicating that
|
||||
* the {@code Subspace} logically contains key.
|
||||
*
|
||||
* @param key the key to be tested
|
||||
* @return {@code true} if {@code key} starts with {@code Subspace.key()}
|
||||
*/
|
||||
public boolean contains(byte[] key) {
|
||||
return ByteArrayUtil.startsWith(key, rawPrefix);
|
||||
}
|
||||
/**
|
||||
* Tests whether the specified key starts with this {@code Subspace}'s prefix, indicating that
|
||||
* the {@code Subspace} logically contains key.
|
||||
*
|
||||
* @param key the key to be tested
|
||||
* @return {@code true} if {@code key} starts with {@code Subspace.key()}
|
||||
*/
|
||||
public boolean contains(byte[] key) {
|
||||
return ByteArrayUtil.startsWith(key, rawPrefix);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a new subspace which is equivalent to this subspace with its prefix {@link Tuple} extended by
|
||||
* the specified {@link Tuple}.
|
||||
*
|
||||
* @param tuple the {@link Tuple} used to form the new {@code Subspace}
|
||||
* @return a new subspace formed by joining this {@code Subspace}'s prefix to {@code tuple}
|
||||
*/
|
||||
public Subspace subspace(Tuple tuple) {
|
||||
return new Subspace(tuple, rawPrefix);
|
||||
}
|
||||
/**
|
||||
* Gets a new subspace which is equivalent to this subspace with its prefix {@link Tuple} extended by
|
||||
* the specified {@link Tuple}.
|
||||
*
|
||||
* @param tuple the {@link Tuple} used to form the new {@code Subspace}
|
||||
* @return a new subspace formed by joining this {@code Subspace}'s prefix to {@code tuple}
|
||||
*/
|
||||
public Subspace subspace(Tuple tuple) {
|
||||
return new Subspace(tuple, rawPrefix);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -236,8 +236,11 @@ public class ByteArrayUtil {
|
|||
/**
|
||||
* Compare byte arrays for equality and ordering purposes. Elements in the array
|
||||
* are interpreted and compared as unsigned bytes. Neither parameter
|
||||
* may be {@code null}
|
||||
|
||||
* may be {@code null}.
|
||||
*
|
||||
* @param l byte array on the left-hand side of the inequality
|
||||
* @param r byte array on the right-hand side of the inequality
|
||||
*
|
||||
* @return return -1, 0, or 1 if {@code l} is less than, equal to, or greater than
|
||||
* {@code r}.
|
||||
*/
|
||||
|
@ -252,27 +255,27 @@ public class ByteArrayUtil {
|
|||
return l.length < r.length ? -1 : 1;
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Check if a byte array starts with another byte array.
|
||||
*
|
||||
* @param array the source byte array
|
||||
*
|
||||
* @param prefix the byte array that we are checking if {@code src}
|
||||
* @param array the source byte array
|
||||
*
|
||||
* @param prefix the byte array that we are checking if {@code src}
|
||||
* starts with.
|
||||
*
|
||||
* @return {@code true} if {@code array} starts with {@code prefix}
|
||||
*/
|
||||
public static boolean startsWith(byte[] array, byte[] prefix) {
|
||||
if(array.length < prefix.length) {
|
||||
return false;
|
||||
}
|
||||
for(int i = 0; i < prefix.length; ++i) {
|
||||
if(prefix[i] != array[i]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
*
|
||||
* @return {@code true} if {@code array} starts with {@code prefix}
|
||||
*/
|
||||
public static boolean startsWith(byte[] array, byte[] prefix) {
|
||||
if(array.length < prefix.length) {
|
||||
return false;
|
||||
}
|
||||
for(int i = 0; i < prefix.length; ++i) {
|
||||
if(prefix[i] != array[i]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Scan through an array of bytes to find the first occurrence of a specific value.
|
||||
|
@ -320,12 +323,12 @@ public class ByteArrayUtil {
|
|||
static int findTerminator(byte[] v, byte n, byte m, int start, int end) {
|
||||
int pos = start;
|
||||
while(true) {
|
||||
pos = findNext(v, n, pos, end);
|
||||
if(pos < 0)
|
||||
return end;
|
||||
if(pos + 1 == end || v[pos+1] != m)
|
||||
return pos;
|
||||
pos += 2;
|
||||
pos = findNext(v, n, pos, end);
|
||||
if(pos < 0)
|
||||
return end;
|
||||
if(pos + 1 == end || v[pos+1] != m)
|
||||
return pos;
|
||||
pos += 2;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -63,45 +63,45 @@ import java.util.Iterator;
|
|||
* </ul>
|
||||
*/
|
||||
public class IterableComparator implements Comparator<Iterable<?>> {
|
||||
/**
|
||||
* Creates a new {@code IterableComparator}. This {@link Comparator} has
|
||||
* no internal state.
|
||||
*/
|
||||
public IterableComparator() {}
|
||||
/**
|
||||
* Creates a new {@code IterableComparator}. This {@link Comparator} has
|
||||
* no internal state.
|
||||
*/
|
||||
public IterableComparator() {}
|
||||
|
||||
/**
|
||||
* Compare two {@link Iterable}s in a way consistent with their
|
||||
* byte representation. This is done element-wise and is consistent
|
||||
* with a number of other ways of sorting {@link Tuple}s. This will
|
||||
* raise an {@link IllegalArgumentException} if any of the items
|
||||
* of either {@link Iterable} cannot be serialized by a {@link Tuple}.
|
||||
*
|
||||
* @param iterable1 the first {@link Iterable} of items
|
||||
* @param iterable2 the second {@link Iterable} of items
|
||||
* @return a negative number if the first iterable would sort before the second
|
||||
* when serialized, a positive number if the opposite is true, and zero
|
||||
* if the two are equal
|
||||
*/
|
||||
@Override
|
||||
public int compare(Iterable<?> iterable1, Iterable<?> iterable2) {
|
||||
Iterator<?> i1 = iterable1.iterator();
|
||||
Iterator<?> i2 = iterable2.iterator();
|
||||
/**
|
||||
* Compare two {@link Iterable}s in a way consistent with their
|
||||
* byte representation. This is done element-wise and is consistent
|
||||
* with a number of other ways of sorting {@link Tuple}s. This will
|
||||
* raise an {@link IllegalArgumentException} if any of the items
|
||||
* of either {@link Iterable} cannot be serialized by a {@link Tuple}.
|
||||
*
|
||||
* @param iterable1 the first {@link Iterable} of items
|
||||
* @param iterable2 the second {@link Iterable} of items
|
||||
* @return a negative number if the first iterable would sort before the second
|
||||
* when serialized, a positive number if the opposite is true, and zero
|
||||
* if the two are equal
|
||||
*/
|
||||
@Override
|
||||
public int compare(Iterable<?> iterable1, Iterable<?> iterable2) {
|
||||
Iterator<?> i1 = iterable1.iterator();
|
||||
Iterator<?> i2 = iterable2.iterator();
|
||||
|
||||
while(i1.hasNext() && i2.hasNext()) {
|
||||
int itemComp = TupleUtil.compareItems(i1.next(), i2.next());
|
||||
if(itemComp != 0) {
|
||||
return itemComp;
|
||||
}
|
||||
}
|
||||
while(i1.hasNext() && i2.hasNext()) {
|
||||
int itemComp = TupleUtil.compareItems(i1.next(), i2.next());
|
||||
if(itemComp != 0) {
|
||||
return itemComp;
|
||||
}
|
||||
}
|
||||
|
||||
if(i1.hasNext()) {
|
||||
// iterable2 is a prefix of iterable1.
|
||||
return 1;
|
||||
}
|
||||
if(i2.hasNext()) {
|
||||
// iterable1 is a prefix of iterable2.
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
if(i1.hasNext()) {
|
||||
// iterable2 is a prefix of iterable1.
|
||||
return 1;
|
||||
}
|
||||
if(i2.hasNext()) {
|
||||
// iterable1 is a prefix of iterable2.
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -73,12 +73,12 @@ public class Tuple implements Comparable<Tuple>, Iterable<Object> {
|
|||
private List<Object> elements;
|
||||
|
||||
private Tuple(List<? extends Object> elements, Object newItem) {
|
||||
this(new LinkedList<Object>(elements));
|
||||
this(elements);
|
||||
this.elements.add(newItem);
|
||||
}
|
||||
|
||||
private Tuple(List<? extends Object> elements) {
|
||||
this.elements = new ArrayList<Object>(elements);
|
||||
this.elements = new ArrayList<>(elements);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -389,10 +389,11 @@ public class Tuple implements Comparable<Tuple>, Iterable<Object> {
|
|||
|
||||
/**
|
||||
* Construct a new {@code Tuple} with elements decoded from a supplied {@code byte} array.
|
||||
* The passed byte array must not be {@code null}.
|
||||
*
|
||||
* @param bytes encoded {@code Tuple} source. Must not be {@code null}
|
||||
* @param bytes encoded {@code Tuple} source
|
||||
*
|
||||
* @return a newly constructed object.
|
||||
* @return a new {@code Tuple} constructed by deserializing the provided {@code byte} array
|
||||
*/
|
||||
public static Tuple fromBytes(byte[] bytes) {
|
||||
return fromBytes(bytes, 0, bytes.length);
|
||||
|
@ -400,10 +401,13 @@ public class Tuple implements Comparable<Tuple>, Iterable<Object> {
|
|||
|
||||
/**
|
||||
* Construct a new {@code Tuple} with elements decoded from a supplied {@code byte} array.
|
||||
* The passed byte array must not be {@code null}.
|
||||
*
|
||||
* @param bytes encoded {@code Tuple} source. Must not be {@code null}
|
||||
* @param bytes encoded {@code Tuple} source
|
||||
* @param offset starting offset of byte array of encoded data
|
||||
* @param length length of encoded data within the source
|
||||
*
|
||||
* @return a newly constructed object.
|
||||
* @return a new {@code Tuple} constructed by deserializing the specified slice of the provided {@code byte} array
|
||||
*/
|
||||
public static Tuple fromBytes(byte[] bytes, int offset, int length) {
|
||||
Tuple t = new Tuple();
|
||||
|
@ -414,7 +418,7 @@ public class Tuple implements Comparable<Tuple>, Iterable<Object> {
|
|||
/**
|
||||
* Gets the number of elements in this {@code Tuple}.
|
||||
*
|
||||
* @return the count of elements
|
||||
* @return the number of elements in this {@code Tuple}
|
||||
*/
|
||||
public int size() {
|
||||
return this.elements.size();
|
||||
|
@ -437,6 +441,9 @@ public class Tuple implements Comparable<Tuple>, Iterable<Object> {
|
|||
* @param index the location of the item to return
|
||||
*
|
||||
* @return the item at {@code index} as a {@code long}
|
||||
*
|
||||
* @throws ClassCastException if the element at {@code index} is not a {@link Number}
|
||||
* @throws NullPointerException if the element at {@code index} is {@code null}
|
||||
*/
|
||||
public long getLong(int index) {
|
||||
Object o = this.elements.get(index);
|
||||
|
@ -453,6 +460,8 @@ public class Tuple implements Comparable<Tuple>, Iterable<Object> {
|
|||
* @param index the location of the element to return
|
||||
*
|
||||
* @return the item at {@code index} as a {@code byte[]}
|
||||
*
|
||||
* @throws ClassCastException if the element at {@code index} is not a {@link Number}
|
||||
*/
|
||||
public byte[] getBytes(int index) {
|
||||
Object o = this.elements.get(index);
|
||||
|
@ -470,6 +479,8 @@ public class Tuple implements Comparable<Tuple>, Iterable<Object> {
|
|||
* @param index the location of the element to return
|
||||
*
|
||||
* @return the item at {@code index} as a {@code String}
|
||||
*
|
||||
* @throws ClassCastException if the element at {@code index} is not a {@link String}
|
||||
*/
|
||||
public String getString(int index) {
|
||||
Object o = this.elements.get(index);
|
||||
|
@ -489,6 +500,8 @@ public class Tuple implements Comparable<Tuple>, Iterable<Object> {
|
|||
* @param index the location of the element to return
|
||||
*
|
||||
* @return the item at {@code index} as a {@link BigInteger}
|
||||
*
|
||||
* @throws ClassCastException if the element at {@code index} is not a {@link Number}
|
||||
*/
|
||||
public BigInteger getBigInteger(int index) {
|
||||
Object o = this.elements.get(index);
|
||||
|
@ -509,6 +522,8 @@ public class Tuple implements Comparable<Tuple>, Iterable<Object> {
|
|||
* @param index the location of the item to return
|
||||
*
|
||||
* @return the item at {@code index} as a {@code float}
|
||||
*
|
||||
* @throws ClassCastException if the element at {@code index} is not a {@link Number}
|
||||
*/
|
||||
public float getFloat(int index) {
|
||||
Object o = this.elements.get(index);
|
||||
|
@ -525,6 +540,8 @@ public class Tuple implements Comparable<Tuple>, Iterable<Object> {
|
|||
* @param index the location of the item to return
|
||||
*
|
||||
* @return the item at {@code index} as a {@code double}
|
||||
*
|
||||
* @throws ClassCastException if the element at {@code index} is not a {@link Number}
|
||||
*/
|
||||
public double getDouble(int index) {
|
||||
Object o = this.elements.get(index);
|
||||
|
@ -541,6 +558,9 @@ public class Tuple implements Comparable<Tuple>, Iterable<Object> {
|
|||
* @param index the location of the item to return
|
||||
*
|
||||
* @return the item at {@code index} as a {@code boolean}
|
||||
*
|
||||
* @throws ClassCastException if the element at {@code index} is not a {@link Boolean}
|
||||
* @throws NullPointerException if the element at {@code index} is {@code null}
|
||||
*/
|
||||
public boolean getBoolean(int index) {
|
||||
Object o = this.elements.get(index);
|
||||
|
@ -558,6 +578,8 @@ public class Tuple implements Comparable<Tuple>, Iterable<Object> {
|
|||
* @param index the location of the item to return
|
||||
*
|
||||
* @return the item at {@code index} as a {@link UUID}
|
||||
*
|
||||
* @throws ClassCastException if the element at {@code index} is not a {@link UUID}
|
||||
*/
|
||||
public UUID getUUID(int index) {
|
||||
Object o = this.elements.get(index);
|
||||
|
@ -573,7 +595,9 @@ public class Tuple implements Comparable<Tuple>, Iterable<Object> {
|
|||
*
|
||||
* @param index the location of the item to return
|
||||
*
|
||||
* @return the item at {@code index} as a {@link UUID}
|
||||
* @return the item at {@code index} as a {@link Versionstamp}
|
||||
*
|
||||
* @throws ClassCastException if the element at {@code index} is not a {@link Versionstamp}
|
||||
*/
|
||||
public Versionstamp getVersionstamp(int index) {
|
||||
Object o = this.elements.get(index);
|
||||
|
@ -590,6 +614,9 @@ public class Tuple implements Comparable<Tuple>, Iterable<Object> {
|
|||
* @param index the location of the item to return
|
||||
*
|
||||
* @return the item at {@code index} as a {@link List}
|
||||
*
|
||||
* @throws ClassCastException if the element at {@code index} is not a {@link List}
|
||||
* or a {@code Tuple}
|
||||
*/
|
||||
public List<Object> getNestedList(int index) {
|
||||
Object o = this.elements.get(index);
|
||||
|
@ -614,6 +641,9 @@ public class Tuple implements Comparable<Tuple>, Iterable<Object> {
|
|||
* @param index the location of the item to return
|
||||
*
|
||||
* @return the item at {@code index} as a {@link List}
|
||||
*
|
||||
* @throws ClassCastException if the element at {@code index} is not a {@code Tuple}
|
||||
* or a {@link List}
|
||||
*/
|
||||
public Tuple getNestedTuple(int index) {
|
||||
Object o = this.elements.get(index);
|
||||
|
@ -642,7 +672,9 @@ public class Tuple implements Comparable<Tuple>, Iterable<Object> {
|
|||
/**
|
||||
* Creates a new {@code Tuple} with the first item of this {@code Tuple} removed.
|
||||
*
|
||||
* @return a newly created {@code Tuple}
|
||||
* @return a newly created {@code Tuple} without the first item of this {@code Tuple}
|
||||
*
|
||||
* @throws IllegalStateException if this {@code Tuple} is empty
|
||||
*/
|
||||
public Tuple popFront() {
|
||||
if(elements.size() == 0)
|
||||
|
@ -659,7 +691,9 @@ public class Tuple implements Comparable<Tuple>, Iterable<Object> {
|
|||
/**
|
||||
* Creates a new {@code Tuple} with the last item of this {@code Tuple} removed.
|
||||
*
|
||||
* @return a newly created {@code Tuple}
|
||||
* @return a newly created {@code Tuple} without the last item of this {@code Tuple}
|
||||
*
|
||||
* @throws IllegalStateException if this {@code Tuple} is empty
|
||||
*/
|
||||
public Tuple popBack() {
|
||||
if(elements.size() == 0)
|
||||
|
@ -684,8 +718,8 @@ public class Tuple implements Comparable<Tuple>, Iterable<Object> {
|
|||
* Range r = t.range();</pre>
|
||||
* {@code r} includes all tuples ("a", "b", ...)
|
||||
*
|
||||
* @return the keyspace range containing all {@code Tuple}s that have this {@code Tuple}
|
||||
* as a prefix.
|
||||
* @return the range of keys containing all {@code Tuple}s that have this {@code Tuple}
|
||||
* as a prefix
|
||||
*/
|
||||
public Range range() {
|
||||
byte[] p = pack();
|
||||
|
@ -728,7 +762,7 @@ public class Tuple implements Comparable<Tuple>, Iterable<Object> {
|
|||
* Returns a hash code value for this {@code Tuple}.
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @return a hashcode
|
||||
* @return a hash code for this {@code Tuple} that can be used by hash tables
|
||||
*/
|
||||
@Override
|
||||
public int hashCode() {
|
||||
|
@ -741,7 +775,7 @@ public class Tuple implements Comparable<Tuple>, Iterable<Object> {
|
|||
* {@link Tuple#compareTo(Tuple) compareTo()} would return {@code 0}.
|
||||
*
|
||||
* @return {@code true} if {@code obj} is a {@code Tuple} and their binary representation
|
||||
* is identical.
|
||||
* is identical
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
|
@ -754,9 +788,14 @@ public class Tuple implements Comparable<Tuple>, Iterable<Object> {
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns a string representing this {@code Tuple}.
|
||||
* Returns a string representing this {@code Tuple}. This contains human-readable
|
||||
* representations of all of the elements of this {@code Tuple}. For most elements,
|
||||
* this means using that object's default string representation. For byte-arrays,
|
||||
* this means using {@link ByteArrayUtil#printable(byte[]) ByteArrayUtil.printable()}
|
||||
* to produce a byte-string where most printable ASCII code points have been
|
||||
* rendered as characters.
|
||||
*
|
||||
* @return a string
|
||||
* @return a human-readable {@link String} representation of this {@code Tuple}
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
|
@ -797,9 +836,9 @@ public class Tuple implements Comparable<Tuple>, Iterable<Object> {
|
|||
* can only be {@link String}s, {@code byte[]}s, {@link Number}s, {@link UUID}s,
|
||||
* {@link Boolean}s, {@link List}s, {@code Tuple}s, or {@code null}s.
|
||||
*
|
||||
* @param items the elements from which to create the {@code Tuple}.
|
||||
* @param items the elements from which to create the {@code Tuple}
|
||||
*
|
||||
* @return a newly created {@code Tuple}
|
||||
* @return a new {@code Tuple} with the given items as its elements
|
||||
*/
|
||||
public static Tuple fromItems(Iterable<? extends Object> items) {
|
||||
Tuple t = new Tuple();
|
||||
|
@ -817,7 +856,7 @@ public class Tuple implements Comparable<Tuple>, Iterable<Object> {
|
|||
*
|
||||
* @param items the elements from which to create the {@code Tuple}.
|
||||
*
|
||||
* @return a newly created {@code Tuple}
|
||||
* @return a new {@code Tuple} with the given items as its elements
|
||||
*/
|
||||
public static Tuple fromList(List<? extends Object> items) {
|
||||
return new Tuple(items);
|
||||
|
@ -827,11 +866,12 @@ public class Tuple implements Comparable<Tuple>, Iterable<Object> {
|
|||
* Efficiently creates a new {@code Tuple} from a {@link Stream} of objects. The
|
||||
* elements must follow the type guidelines from {@link Tuple#addObject(Object) add},
|
||||
* and so can only be {@link String}s, {@code byte[]}s, {@link Number}s, {@link UUID}s,
|
||||
* {@link Boolean}s, {@link List}s, {@code Tuple}s, or {@code null}s.
|
||||
* {@link Boolean}s, {@link List}s, {@code Tuple}s, or {@code null}s. Note that this
|
||||
* class will consume all elements from the {@link Stream}.
|
||||
*
|
||||
* @param items the {@link Stream} of items from which to create the {@code Tuple}.
|
||||
* @param items the {@link Stream} of items from which to create the {@code Tuple}
|
||||
*
|
||||
* @return a newly created {@code Tuple}
|
||||
* @return a new {@code Tuple} with the given items as its elements
|
||||
*/
|
||||
public static Tuple fromStream(Stream<? extends Object> items) {
|
||||
Tuple t = new Tuple();
|
||||
|
@ -845,9 +885,9 @@ public class Tuple implements Comparable<Tuple>, Iterable<Object> {
|
|||
* can only be {@link String}s, {@code byte[]}s, {@link Number}s, {@link UUID}s,
|
||||
* {@link Boolean}s, {@link List}s, {@code Tuple}s, or {@code null}s.
|
||||
*
|
||||
* @param items the elements from which to create the {@code Tuple}.
|
||||
* @param items the elements from which to create the {@code Tuple}
|
||||
*
|
||||
* @return a newly created {@code Tuple}
|
||||
* @return a new {@code Tuple} with the given items as its elements
|
||||
*/
|
||||
public static Tuple from(Object... items) {
|
||||
return fromList(Arrays.asList(items));
|
||||
|
|
|
@ -57,7 +57,7 @@ import java.util.Arrays;
|
|||
*
|
||||
* <pre>
|
||||
* <code>
|
||||
* {@code CompletableFuture<byte[]>} trVersionFuture = db.run((Transaction tr) -> {
|
||||
* CompletableFuture<byte[]> trVersionFuture = db.run((Transaction tr) -> {
|
||||
* // The incomplete Versionstamp will be overwritten with tr's version information when committed.
|
||||
* Tuple t = Tuple.from("prefix", Versionstamp.incomplete());
|
||||
* tr.mutate(MutationType.SET_VERSIONSTAMPED_KEY, t.packWithVersionstamp(), new byte[0]);
|
||||
|
@ -66,7 +66,7 @@ import java.util.Arrays;
|
|||
*
|
||||
* byte[] trVersion = trVersionFuture.get();
|
||||
*
|
||||
* Versionstamp v = db.run((Transaction tr) -> {
|
||||
* Versionstamp v = db.run((Transaction tr) -> {
|
||||
* Subspace subspace = new Subspace(Tuple.from("prefix"));
|
||||
* byte[] serialized = tr.getRange(subspace.range(), 1).iterator().next().getKey();
|
||||
* Tuple t = subspace.unpack(serialized);
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
* Provides a set of utilities for serializing and deserializing typed data
|
||||
* for use in FoundationDB. When packed together into a {@link com.apple.foundationdb.tuple.Tuple}
|
||||
* this data is suitable for use as an index or organizational structure within FoundationDB
|
||||
* keyspace. See <a href="/foundationdb/data-modeling.html#tuples">general Tuple
|
||||
* keyspace. See <a href="/foundationdb/data-modeling.html#data-modeling-tuples">general Tuple
|
||||
* documentation</a> for information about how Tuples sort and can be used to efficiently
|
||||
* model data.
|
||||
*/
|
||||
|
|
|
@ -6,31 +6,19 @@ This documents the client API for using FoundationDB from Java.<br>
|
|||
FoundationDB's Java bindings rely on native libraries that are installed as part of the
|
||||
FoundationDB client binaries installation (see
|
||||
<a href="/foundationdb/api-general.html#installing-client-binaries" target="_blank">
|
||||
Installing FoundationDB client binaries</a>). The FoundationDB Java bindings are available
|
||||
through Artifactory. To use them in your Maven-enabled project, add a dependency to your
|
||||
pom.xml like: <br>
|
||||
<pre>
|
||||
{@code
|
||||
<dependency>
|
||||
<groupId>com.apple.cie.foundationdb</groupId>
|
||||
<artifactId>fdb-java</artifactId>
|
||||
<version>VERSION</version>
|
||||
</dependency>
|
||||
}
|
||||
</pre>
|
||||
Alternatively, simply download the JAR from
|
||||
<a href="https://files.foundationdb.org/fdb-java/">Artifactory</a>
|
||||
and add it to your classpath.<br>
|
||||
Installing FoundationDB client binaries</a>). The JAR can be downloaded from
|
||||
<a href="https://www.foundationdb.org/download/">our website</a>
|
||||
and then added to your classpath.<br>
|
||||
<br>
|
||||
<h3>Getting started</h3>
|
||||
To start using FoundationDB from Java, create an instance of the
|
||||
{@link com.apple.foundationdb.FDB FoundationDB API interface} with the version of the
|
||||
API that you want to use (this release of the FoundationDB Java API supports only version {@code 510}).
|
||||
API that you want to use (this release of the FoundationDB Java API supports versions between {@code 510} and {@code 520}).
|
||||
With this API object you can then open {@link com.apple.foundationdb.Cluster Cluster}s and
|
||||
{@link com.apple.foundationdb.Database Database}s and start using
|
||||
{@link com.apple.foundationdb.Transaction Transaction}s.
|
||||
Here we give an example. The example relies on a cluster file at the
|
||||
<a href="/foundationdb/api-general.html#default-cluster-file">default location</a>
|
||||
<a href="/foundationdb/administration.html#default-cluster-file">default location</a>
|
||||
for your platform and a running server.<br>
|
||||
<br>
|
||||
<pre>
|
||||
|
@ -41,7 +29,7 @@ import com.apple.foundationdb.tuple.Tuple;
|
|||
|
||||
public class Example {
|
||||
public static void main(String[] args) {
|
||||
FDB fdb = FDB.selectAPIVersion(510);
|
||||
FDB fdb = FDB.selectAPIVersion(520);
|
||||
|
||||
try(Database db = fdb.open()) {
|
||||
// Run an operation on the database
|
||||
|
@ -69,7 +57,7 @@ cross-language support for storing and retrieving typed data from the
|
|||
binary data that FoundationDB supports. And, just as importantly, data packed into
|
||||
{@code Tuple}s and used as keys sort in predictable and useful ways. See the
|
||||
{@link com.apple.foundationdb.tuple Tuple class documentation} for information about use in Java
|
||||
and <a href="/foundationdb/data-modeling.html#tuples">general Tuple documentation</a>
|
||||
and <a href="/foundationdb/data-modeling.html#data-modeling-tuples">general Tuple documentation</a>
|
||||
for information about how Tuples sort and can be used to efficiently model data.
|
||||
<br>
|
||||
<h3>FoundationDB {@link com.apple.foundationdb.directory Directory API}</h3>
|
||||
|
|
|
@ -27,89 +27,89 @@ import com.apple.foundationdb.Database;
|
|||
import com.apple.foundationdb.FDB;
|
||||
|
||||
public abstract class AbstractTester {
|
||||
public static final int API_VERSION = 510;
|
||||
protected static final int NUM_RUNS = 25;
|
||||
protected static final Charset ASCII = Charset.forName("ASCII");
|
||||
public static final int API_VERSION = 520;
|
||||
protected static final int NUM_RUNS = 25;
|
||||
protected static final Charset ASCII = Charset.forName("ASCII");
|
||||
|
||||
protected TesterArgs args;
|
||||
protected Random random;
|
||||
protected TestResult result;
|
||||
protected FDB fdb;
|
||||
protected TesterArgs args;
|
||||
protected Random random;
|
||||
protected TestResult result;
|
||||
protected FDB fdb;
|
||||
|
||||
public AbstractTester() {
|
||||
args = null;
|
||||
random = new Random();
|
||||
result = new TestResult(random);
|
||||
}
|
||||
public AbstractTester() {
|
||||
args = null;
|
||||
random = new Random();
|
||||
result = new TestResult(random);
|
||||
}
|
||||
|
||||
public void runTest() {
|
||||
try(Database db = fdb.open()) {
|
||||
try {
|
||||
testPerformance(db);
|
||||
}
|
||||
catch (Exception e) {
|
||||
result.addError(wrapAndPrintError(e, "Failed to complete all tests"));
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
result.addError(wrapAndPrintError(e, "fdb.open failed"));
|
||||
return;
|
||||
}
|
||||
}
|
||||
public void runTest() {
|
||||
try(Database db = fdb.open()) {
|
||||
try {
|
||||
testPerformance(db);
|
||||
}
|
||||
catch (Exception e) {
|
||||
result.addError(wrapAndPrintError(e, "Failed to complete all tests"));
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
result.addError(wrapAndPrintError(e, "fdb.open failed"));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
public abstract void testPerformance(Database db);
|
||||
public abstract void testPerformance(Database db);
|
||||
|
||||
public String multiVersionDescription() {
|
||||
if (args == null) return "";
|
||||
public String multiVersionDescription() {
|
||||
if (args == null) return "";
|
||||
|
||||
if (!args.useMultiversionApi()) {
|
||||
return "multi-version API disabled";
|
||||
} else if (args.useExternalClient()) {
|
||||
if (args.putCallbacksOnExternalThread()) {
|
||||
return "external client on external thread";
|
||||
} else {
|
||||
return "external client on main thread";
|
||||
}
|
||||
} else {
|
||||
return "local client";
|
||||
}
|
||||
}
|
||||
if (!args.useMultiversionApi()) {
|
||||
return "multi-version API disabled";
|
||||
} else if (args.useExternalClient()) {
|
||||
if (args.putCallbacksOnExternalThread()) {
|
||||
return "external client on external thread";
|
||||
} else {
|
||||
return "external client on main thread";
|
||||
}
|
||||
} else {
|
||||
return "local client";
|
||||
}
|
||||
}
|
||||
|
||||
public void run(String[] argStrings) {
|
||||
args = TesterArgs.parseArgs(argStrings);
|
||||
if (args == null) return;
|
||||
public void run(String[] argStrings) {
|
||||
args = TesterArgs.parseArgs(argStrings);
|
||||
if (args == null) return;
|
||||
|
||||
fdb = FDB.selectAPIVersion(API_VERSION);
|
||||
fdb = FDB.selectAPIVersion(API_VERSION);
|
||||
|
||||
// Validate argument combinations and set options.
|
||||
if (!args.useMultiversionApi()) {
|
||||
if (args.putCallbacksOnExternalThread() || args.useExternalClient()) {
|
||||
throw new IllegalArgumentException("Invalid multi-version API argument combination");
|
||||
}
|
||||
fdb.options().setDisableMultiVersionClientApi();
|
||||
}
|
||||
if (args.putCallbacksOnExternalThread()) {
|
||||
if (!args.useExternalClient()) {
|
||||
throw new IllegalArgumentException("Cannot enable callbacks on external thread without using external client");
|
||||
}
|
||||
fdb.options().setCallbacksOnExternalThreads();
|
||||
}
|
||||
if (args.useExternalClient()) {
|
||||
fdb.options().setDisableLocalClient();
|
||||
}
|
||||
// Validate argument combinations and set options.
|
||||
if (!args.useMultiversionApi()) {
|
||||
if (args.putCallbacksOnExternalThread() || args.useExternalClient()) {
|
||||
throw new IllegalArgumentException("Invalid multi-version API argument combination");
|
||||
}
|
||||
fdb.options().setDisableMultiVersionClientApi();
|
||||
}
|
||||
if (args.putCallbacksOnExternalThread()) {
|
||||
if (!args.useExternalClient()) {
|
||||
throw new IllegalArgumentException("Cannot enable callbacks on external thread without using external client");
|
||||
}
|
||||
fdb.options().setCallbacksOnExternalThreads();
|
||||
}
|
||||
if (args.useExternalClient()) {
|
||||
fdb.options().setDisableLocalClient();
|
||||
}
|
||||
|
||||
try {
|
||||
runTest();
|
||||
} catch (Exception e) {
|
||||
result.addError(e);
|
||||
}
|
||||
try {
|
||||
runTest();
|
||||
} catch (Exception e) {
|
||||
result.addError(e);
|
||||
}
|
||||
|
||||
result.save(args.getOutputDirectory());
|
||||
}
|
||||
result.save(args.getOutputDirectory());
|
||||
}
|
||||
|
||||
public RuntimeException wrapAndPrintError(Throwable t, String message) {
|
||||
String errorMessage = message + ": " + t.getClass() + ": " + t.getMessage() + "\n";
|
||||
t.printStackTrace();
|
||||
return new RuntimeException(errorMessage, t);
|
||||
}
|
||||
public RuntimeException wrapAndPrintError(Throwable t, String message) {
|
||||
String errorMessage = message + ": " + t.getClass() + ": " + t.getMessage() + "\n";
|
||||
t.printStackTrace();
|
||||
return new RuntimeException(errorMessage, t);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -451,15 +451,34 @@ public class AsyncStackTester {
|
|||
else if(op == StackOperation.UNIT_TESTS) {
|
||||
inst.context.db.options().setLocationCacheSize(100001);
|
||||
return inst.context.db.runAsync(tr -> {
|
||||
FDB fdb = FDB.instance();
|
||||
|
||||
String alreadyStartedMessage = "FoundationDB API already started at different version";
|
||||
try {
|
||||
FDB.selectAPIVersion(fdb.getAPIVersion() + 1);
|
||||
throw new IllegalStateException("Was not stopped from selecting two API versions");
|
||||
}
|
||||
catch(IllegalArgumentException e) {
|
||||
if(!e.getMessage().equals(alreadyStartedMessage)) {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
try {
|
||||
FDB.selectAPIVersion(fdb.getAPIVersion() - 1);
|
||||
throw new IllegalStateException("Was not stopped from selecting two API versions");
|
||||
}
|
||||
catch(IllegalArgumentException e) {
|
||||
if(!e.getMessage().equals(alreadyStartedMessage)) {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
tr.options().setPrioritySystemImmediate();
|
||||
tr.options().setPriorityBatch();
|
||||
tr.options().setCausalReadRisky();
|
||||
tr.options().setCausalWriteRisky();
|
||||
tr.options().setReadYourWritesDisable();
|
||||
tr.options().setReadAheadDisable();
|
||||
tr.options().setReadSystemKeys();
|
||||
tr.options().setAccessSystemKeys();
|
||||
tr.options().setDurabilityDevNullIsWebScale();
|
||||
tr.options().setTimeout(60*1000);
|
||||
tr.options().setRetryLimit(50);
|
||||
tr.options().setMaxRetryDelay(100);
|
||||
|
@ -686,7 +705,23 @@ public class AsyncStackTester {
|
|||
|
||||
byte[] prefix = args[0].getBytes();
|
||||
|
||||
FDB fdb = FDB.selectAPIVersion(Integer.parseInt(args[1]));
|
||||
if(FDB.isAPIVersionSelected()) {
|
||||
throw new IllegalStateException("API version already set to " + FDB.instance().getAPIVersion());
|
||||
}
|
||||
try {
|
||||
FDB.instance();
|
||||
throw new IllegalStateException("Able to get API instance before selecting API version");
|
||||
}
|
||||
catch(FDBException e) {
|
||||
if(e.getCode() != 2200) {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
int apiVersion = Integer.parseInt(args[1]);
|
||||
FDB fdb = FDB.selectAPIVersion(apiVersion);
|
||||
if(FDB.instance().getAPIVersion() != apiVersion) {
|
||||
throw new IllegalStateException("API version not correctly set to " + apiVersion);
|
||||
}
|
||||
//ExecutorService executor = Executors.newFixedThreadPool(2);
|
||||
Cluster cl = fdb.createCluster(args.length > 2 ? args[2] : null);
|
||||
|
||||
|
|
|
@ -33,7 +33,7 @@ public class BlockingBenchmark {
|
|||
private static final int PARALLEL = 100;
|
||||
|
||||
public static void main(String[] args) throws InterruptedException {
|
||||
FDB fdb = FDB.selectAPIVersion(510);
|
||||
FDB fdb = FDB.selectAPIVersion(520);
|
||||
|
||||
// The cluster file DOES NOT need to be valid, although it must exist.
|
||||
// This is because the database is never really contacted in this test.
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue