forked from hugegraph/hugegraph-sync
Compare commits
No commits in common. "master" and "release-1.2.0" have entirely different histories.
master
...
release-1.
|
|
@ -34,15 +34,15 @@ github:
|
|||
protected_branches:
|
||||
master:
|
||||
required_status_checks:
|
||||
# strict means "Require PR to be up-to-date before merging". (enable when branch unstable)
|
||||
# strict means "Require branches to be up-to-date before merging".
|
||||
strict: false
|
||||
# contexts are the names of checks that must pass (now only enable the basic check)
|
||||
contexts:
|
||||
- Analyze (java)
|
||||
- CodeQL
|
||||
- check-license
|
||||
- build-server (memory, 11)
|
||||
- build-commons (11)
|
||||
- build (memory, 8)
|
||||
- build (memory, 11)
|
||||
required_pull_request_reviews:
|
||||
dismiss_stale_reviews: true
|
||||
require_code_owner_reviews: false
|
||||
|
|
|
|||
|
|
@ -21,79 +21,7 @@ root = true
|
|||
charset = utf-8
|
||||
end_of_line = lf
|
||||
insert_final_newline = true
|
||||
max_line_length = 100
|
||||
ij_wrap_on_typing = true
|
||||
ij_visual_guides = 100
|
||||
|
||||
|
||||
[*.{java,xml,py}]
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
|
||||
[*.{java,xml}]
|
||||
# Ignore the IDEA unsupported warning & it works well (indeed)
|
||||
continuation_indent_size = 8
|
||||
|
||||
[*.md]
|
||||
max_line_length = off
|
||||
|
||||
[*.java]
|
||||
ij_java_doc_add_p_tag_on_empty_lines = true
|
||||
ij_java_doc_do_not_wrap_if_one_line = true
|
||||
ij_java_annotation_parameter_wrap = normal
|
||||
ij_java_align_multiline_annotation_parameters = true
|
||||
ij_java_class_count_to_use_import_on_demand = 100
|
||||
ij_java_names_count_to_use_import_on_demand = 100
|
||||
ij_java_imports_layout = $*, |, java.**, |, javax.**, |, org.**, |, com.**, |, *
|
||||
|
||||
ij_java_line_comment_at_first_column = false
|
||||
ij_java_align_multiline_chained_methods = true
|
||||
ij_java_align_multiline_parameters_in_calls = true
|
||||
ij_java_align_multiline_binary_operation = true
|
||||
ij_java_align_multiline_assignment = true
|
||||
ij_java_align_multiline_ternary_operation = true
|
||||
ij_java_align_multiline_throws_list = true
|
||||
ij_java_align_multiline_extends_list = true
|
||||
ij_java_align_multiline_array_initializer_expression = true
|
||||
|
||||
ij_java_call_parameters_wrap = normal
|
||||
ij_java_method_parameters_wrap = normal
|
||||
ij_java_resource_list_wrap = normal
|
||||
ij_java_extends_list_wrap = normal
|
||||
ij_java_throws_list_wrap = normal
|
||||
ij_java_method_call_chain_wrap = normal
|
||||
ij_java_binary_operation_wrap = normal
|
||||
ij_java_ternary_operation_wrap = normal
|
||||
ij_java_for_statement_wrap = normal
|
||||
ij_java_array_initializer_wrap = normal
|
||||
ij_java_assignment_wrap = normal
|
||||
ij_java_assert_statement_wrap = normal
|
||||
ij_java_if_brace_force = if_multiline
|
||||
ij_java_do_while_brace_force = always
|
||||
ij_java_while_brace_force = if_multiline
|
||||
ij_java_for_brace_force = if_multiline
|
||||
ij_java_wrap_long_lines = true
|
||||
ij_java_parameter_annotation_wrap = normal
|
||||
ij_java_enum_constants_wrap = split_into_lines
|
||||
|
||||
ij_java_keep_blank_lines_in_declarations = 1
|
||||
ij_java_keep_blank_lines_in_code = 1
|
||||
ij_java_keep_blank_lines_between_package_declaration_and_header = 1
|
||||
ij_java_keep_blank_lines_before_right_brace = 1
|
||||
ij_java_blank_lines_around_class = 1
|
||||
ij_java_blank_lines_after_class_header = 1
|
||||
|
||||
ij_smart_tabs = true
|
||||
|
||||
[*.xml]
|
||||
max_line_length = 120
|
||||
ij_visual_guides = 120
|
||||
ij_xml_text_wrap = off
|
||||
ij_xml_space_inside_empty_tag = true
|
||||
|
||||
[.yaml]
|
||||
ij_yaml_spaces_within_braces = false
|
||||
ij_yaml_spaces_within_brackets = false
|
||||
|
||||
[.properties]
|
||||
ij_properties_keep_blank_lines = true
|
||||
|
|
|
|||
|
|
@ -5,12 +5,8 @@
|
|||
apache-release.sh export-ignore
|
||||
.licenserc.yaml export-ignore
|
||||
.editorconfig export-ignore
|
||||
hugegraph-store/hg-store-dist/src/assembly/static/bin/libjemalloc.so export-ignore
|
||||
hugegraph-store/hg-store-dist/src/assembly/static/bin/libjemalloc_aarch64.so export-ignore
|
||||
|
||||
# ignored directory
|
||||
.github/ export-ignore
|
||||
.idea/ export-ignore
|
||||
install-dist/scripts/ export-ignore
|
||||
hugegraph-commons/hugegraph-dist/ export-ignore
|
||||
docker/ export-ignore
|
||||
hugegraph-dist/scripts/ export-ignore
|
||||
#assembly/ export-ignore
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ published)
|
|||
|
||||
## Purpose of the PR
|
||||
|
||||
- close #xxx <!-- or use "fix #xxx", "xxx" is the ID-link of related issue, e.g: close #1024 -->
|
||||
- close #xxx <!-- or use "fix #xxx", "xxx" is the ID-link of related issue, e.g: close #1024 -->
|
||||
|
||||
<!--
|
||||
Please explain more context in this section, clarify why the changes are needed.
|
||||
|
|
@ -30,7 +30,7 @@ e.g:
|
|||
|
||||
## Main Changes
|
||||
|
||||
<!-- Please clarify what changes you are proposing. The purpose of this section is to outline the changes and how this PR fixes the issue. These change logs are helpful for better and faster reviews.)
|
||||
<!-- Please clarify what changes you are proposing. The purpose of this section is to outline the changes and how this PR fixes the issue. These change logs are helpful for better ant faster reviews.)
|
||||
|
||||
For example:
|
||||
|
||||
|
|
@ -51,12 +51,11 @@ For example:
|
|||
|
||||
<!-- DO NOT REMOVE THIS SECTION. CHECK THE PROPER BOX ONLY. -->
|
||||
|
||||
- [ ] Dependencies ([add/update license](https://hugegraph.apache.org/docs/contribution-guidelines/contribute/#321-check-licenses) info & [regenerate_dependencies](../hugegraph-server/hugegraph-dist/scripts/dependency/regenerate_known_dependencies.sh)) <!-- Don't forget to add/update the info in "LICENSE" & "NOTICE" files (both in root & dist module) -->
|
||||
- [ ] Nope
|
||||
- [ ] Dependencies (add/update license info) <!-- Don't forget to add/update the info in "LICENSE" & "NOTICE" files (both in root & dist module) -->
|
||||
- [ ] Modify configurations
|
||||
- [ ] The public API
|
||||
- [ ] Other affects (typed here)
|
||||
- [ ] Nope
|
||||
|
||||
|
||||
## Documentation Status
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1,20 @@
|
|||
<!--
|
||||
Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
contributor license agreements. See the NOTICE file distributed with
|
||||
this work for additional information regarding copyright ownership.
|
||||
The ASF licenses this file to You 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.
|
||||
-->
|
||||
|
||||
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 https://maven.apache.org/xsd/settings-1.0.0.xsd">
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ jobs:
|
|||
runs-on: ubuntu-latest
|
||||
env:
|
||||
USE_STAGE: 'true' # Whether to include the stage repository.
|
||||
SCRIPT_DEPENDENCY: install-dist/scripts/dependency
|
||||
SCRIPT_DEPENDENCY: hugegraph-server/hugegraph-dist/scripts/dependency
|
||||
steps:
|
||||
- name: Checkout source
|
||||
uses: actions/checkout@v4
|
||||
|
|
@ -32,7 +32,7 @@ jobs:
|
|||
|
||||
- name: mvn install
|
||||
run: |
|
||||
mvn install -Dmaven.test.skip=true -ntp
|
||||
mvn install -DskipTests=true -ntp
|
||||
- name: generate current dependencies
|
||||
run: |
|
||||
bash $SCRIPT_DEPENDENCY/regenerate_known_dependencies.sh current-dependencies.txt
|
||||
|
|
@ -49,8 +49,7 @@ jobs:
|
|||
uses: actions/dependency-review-action@v3
|
||||
# Refer: https://github.com/actions/dependency-review-action
|
||||
with:
|
||||
# TODO: reset critical to low before releasing
|
||||
fail-on-severity: critical
|
||||
fail-on-severity: low
|
||||
# Action will fail if dependencies don't match the list
|
||||
#allow-licenses: Apache-2.0, MIT
|
||||
#deny-licenses: GPL-3.0, AGPL-1.0, AGPL-3.0, LGPL-2.0, CC-BY-3.0
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
name: "HugeGraph-Server CI"
|
||||
name: "hugegraph-ci"
|
||||
|
||||
on:
|
||||
push:
|
||||
|
|
@ -9,11 +9,9 @@ on:
|
|||
pull_request:
|
||||
|
||||
jobs:
|
||||
build-server:
|
||||
# TODO: we need test & replace it to ubuntu-24.04 or ubuntu-latest
|
||||
build:
|
||||
runs-on: ubuntu-20.04
|
||||
env:
|
||||
# TODO: reset use stage to false later
|
||||
USE_STAGE: 'true' # Whether to include the stage repository.
|
||||
TRAVIS_DIR: hugegraph-server/hugegraph-dist/src/assembly/travis
|
||||
REPORT_DIR: target/site/jacoco
|
||||
|
|
@ -29,13 +27,13 @@ jobs:
|
|||
fail-fast: false
|
||||
matrix:
|
||||
BACKEND: [ memory, rocksdb, hbase, cassandra, mysql, postgresql, scylladb ]
|
||||
JAVA_VERSION: [ '11' ]
|
||||
JAVA_VERSION: [ '8', '11' ]
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 5
|
||||
fetch-depth: 2
|
||||
|
||||
# TODO: Remove this step after install-backend.sh updated
|
||||
- name: Install Java8 for backend
|
||||
|
|
@ -1,64 +0,0 @@
|
|||
name: "HugeGraph-Commons CI"
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
- /^release-.*$/
|
||||
- /^test-.*$/
|
||||
pull_request:
|
||||
|
||||
jobs:
|
||||
build-commons:
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
# TODO: reset use stage to false later
|
||||
USE_STAGE: 'true' # Whether to include the stage repository.
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
JAVA_VERSION: ['11']
|
||||
|
||||
steps:
|
||||
- name: Install JDK ${{ matrix.JAVA_VERSION }}
|
||||
uses: actions/setup-java@v3
|
||||
with:
|
||||
java-version: ${{ matrix.JAVA_VERSION }}
|
||||
distribution: 'zulu'
|
||||
|
||||
- name: Cache Maven packages
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: ~/.m2
|
||||
key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }}
|
||||
restore-keys: ${{ runner.os }}-m2
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 2
|
||||
|
||||
- name: Use staged maven repo settings
|
||||
if: ${{ env.USE_STAGE == 'true' }}
|
||||
run: |
|
||||
cp $HOME/.m2/settings.xml /tmp/settings.xml
|
||||
cp -vf .github/configs/settings.xml $HOME/.m2/settings.xml && cat $HOME/.m2/settings.xml
|
||||
|
||||
- name: Compile
|
||||
run: |
|
||||
mvn compile -Dmaven.javadoc.skip=true -ntp
|
||||
|
||||
- name: Run common test
|
||||
run: |
|
||||
mvn test -pl hugegraph-commons/hugegraph-common -Dtest=UnitTestSuite
|
||||
|
||||
- name: Run rpc test
|
||||
run: |
|
||||
mvn test -pl hugegraph-commons/hugegraph-rpc -Dtest=UnitTestSuite
|
||||
|
||||
- name: Upload coverage to Codecov
|
||||
uses: codecov/codecov-action@v3.0.0
|
||||
with:
|
||||
file: target/jacoco.xml
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
name: "License Checker"
|
||||
name: "License checker"
|
||||
|
||||
on:
|
||||
push:
|
||||
|
|
@ -24,7 +24,7 @@ jobs:
|
|||
token: ${{ github.token }}
|
||||
config: .licenserc.yaml
|
||||
|
||||
- name: License Check (RAT)
|
||||
- name: License check(RAT)
|
||||
run: |
|
||||
mvn apache-rat:check -ntp
|
||||
find ./ -name rat.txt -print0 | xargs -0 -I file cat file > merged-rat.txt
|
||||
|
|
|
|||
|
|
@ -1,219 +0,0 @@
|
|||
name: "HugeGraph-PD & Store & Hstore CI"
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
- 'release-*'
|
||||
- 'test-*'
|
||||
pull_request:
|
||||
|
||||
# TODO: consider merge to one ci.yml file
|
||||
jobs:
|
||||
pd:
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
# TODO: avoid duplicated env setup in pd & store
|
||||
# TODO: reset use stage to false later
|
||||
USE_STAGE: 'true' # Whether to include the stage repository.
|
||||
# TODO: remove outdated env
|
||||
TRAVIS_DIR: hugegraph-server/hugegraph-dist/src/assembly/travis
|
||||
REPORT_DIR: target/site/jacoco
|
||||
|
||||
steps:
|
||||
- name: Install JDK 11
|
||||
uses: actions/setup-java@v3
|
||||
with:
|
||||
java-version: '11'
|
||||
distribution: 'zulu'
|
||||
|
||||
- name: Cache Maven packages
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: ~/.m2
|
||||
key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }}
|
||||
restore-keys: ${{ runner.os }}-m2
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 5
|
||||
|
||||
- name: use staged maven repo settings
|
||||
if: ${{ env.USE_STAGE == 'true' }}
|
||||
run: |
|
||||
cp $HOME/.m2/settings.xml /tmp/settings.xml
|
||||
mv -vf .github/configs/settings.xml $HOME/.m2/settings.xml
|
||||
|
||||
- name: Run common test
|
||||
run: |
|
||||
mvn test -pl hugegraph-pd/hg-pd-test -am -P pd-common-test -DskipCommonsTests=true
|
||||
|
||||
- name: Run core test
|
||||
run: |
|
||||
mvn test -pl hugegraph-pd/hg-pd-test -am -P pd-core-test -DskipCommonsTests=true
|
||||
|
||||
# The above tests do not require starting a PD instance.
|
||||
|
||||
- name: Package
|
||||
run: |
|
||||
mvn clean package -U -Dmaven.javadoc.skip=true -Dmaven.test.skip=true -ntp
|
||||
|
||||
- name: Prepare env and service
|
||||
run: |
|
||||
$TRAVIS_DIR/start-pd.sh
|
||||
|
||||
- name: Run client test
|
||||
run: |
|
||||
mvn test -pl hugegraph-pd/hg-pd-test -am -P pd-client-test -DskipCommonsTests=true
|
||||
|
||||
- name: Run rest test
|
||||
run: |
|
||||
mvn test -pl hugegraph-pd/hg-pd-test -am -P pd-rest-test -DskipCommonsTests=true
|
||||
|
||||
- name: Upload coverage to Codecov
|
||||
uses: codecov/codecov-action@v3.0.0
|
||||
with:
|
||||
file: ${{ env.REPORT_DIR }}/*.xml
|
||||
|
||||
store:
|
||||
# TODO: avoid duplicated env setup
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
USE_STAGE: 'true' # Whether to include the stage repository.
|
||||
# TODO: remove outdated env
|
||||
TRAVIS_DIR: hugegraph-server/hugegraph-dist/src/assembly/travis
|
||||
REPORT_DIR: target/site/jacoco
|
||||
|
||||
steps:
|
||||
- name: Install JDK 11
|
||||
uses: actions/setup-java@v3
|
||||
with:
|
||||
java-version: '11'
|
||||
distribution: 'zulu'
|
||||
|
||||
- name: Cache Maven packages
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: ~/.m2
|
||||
key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }}
|
||||
restore-keys: ${{ runner.os }}-m2
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 5
|
||||
|
||||
- name: use staged maven repo settings
|
||||
if: ${{ env.USE_STAGE == 'true' }}
|
||||
run: |
|
||||
cp $HOME/.m2/settings.xml /tmp/settings.xml
|
||||
mv -vf .github/configs/settings.xml $HOME/.m2/settings.xml
|
||||
|
||||
- name: Package
|
||||
run: |
|
||||
mvn clean package -U -Dmaven.javadoc.skip=true -Dmaven.test.skip=true -ntp
|
||||
|
||||
- name: Prepare env and service
|
||||
run: |
|
||||
$TRAVIS_DIR/start-pd.sh
|
||||
$TRAVIS_DIR/start-store.sh
|
||||
|
||||
- name: Run common test
|
||||
run: |
|
||||
mvn test -pl hugegraph-store/hg-store-test -am -P store-common-test -DskipCommonsTests=true
|
||||
|
||||
- name: Run client test
|
||||
run: |
|
||||
mvn test -pl hugegraph-store/hg-store-test -am -P store-client-test -DskipCommonsTests=true
|
||||
|
||||
- name: Run core test
|
||||
run: |
|
||||
mvn test -pl hugegraph-store/hg-store-test -am -P store-core-test -DskipCommonsTests=true
|
||||
|
||||
- name: Run rocksdb test
|
||||
run: |
|
||||
mvn test -pl hugegraph-store/hg-store-test -am -P store-rocksdb-test -DskipCommonsTests=true
|
||||
|
||||
- name: Run server test
|
||||
run: |
|
||||
mvn test -pl hugegraph-store/hg-store-test -am -P store-server-test -DskipCommonsTests=true
|
||||
|
||||
- name: Run raft-core test
|
||||
run: |
|
||||
mvn test -pl hugegraph-store/hg-store-test -am -P store-raftcore-test -DskipCommonsTests=true
|
||||
|
||||
- name: Upload coverage to Codecov
|
||||
uses: codecov/codecov-action@v3.0.0
|
||||
with:
|
||||
file: ${{ env.REPORT_DIR }}/*.xml
|
||||
|
||||
hstore:
|
||||
# TODO: avoid duplicated env setup
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
USE_STAGE: 'true' # Whether to include the stage repository.
|
||||
TRAVIS_DIR: hugegraph-server/hugegraph-dist/src/assembly/travis
|
||||
REPORT_DIR: target/site/jacoco
|
||||
BACKEND: hstore
|
||||
RELEASE_BRANCH: ${{ startsWith(github.ref_name, 'release-') || startsWith(github.ref_name, 'test-') || startsWith(github.base_ref, 'release-') }}
|
||||
|
||||
steps:
|
||||
- name: Install JDK 11
|
||||
uses: actions/setup-java@v3
|
||||
with:
|
||||
java-version: '11'
|
||||
distribution: 'zulu'
|
||||
|
||||
- name: Cache Maven packages
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: ~/.m2
|
||||
key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }}
|
||||
restore-keys: ${{ runner.os }}-m2
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 2
|
||||
|
||||
- name: use staged maven repo settings
|
||||
if: ${{ env.USE_STAGE == 'true' }}
|
||||
run: |
|
||||
cp $HOME/.m2/settings.xml /tmp/settings.xml
|
||||
mv -vf .github/configs/settings.xml $HOME/.m2/settings.xml
|
||||
|
||||
- name: Package
|
||||
run: |
|
||||
mvn clean package -U -Dmaven.javadoc.skip=true -Dmaven.test.skip=true -ntp
|
||||
|
||||
- name: Prepare env and service
|
||||
run: |
|
||||
$TRAVIS_DIR/install-backend.sh $BACKEND
|
||||
|
||||
- name: Run unit test
|
||||
run: |
|
||||
$TRAVIS_DIR/run-unit-test.sh $BACKEND
|
||||
|
||||
- name: Run core test
|
||||
run: |
|
||||
$TRAVIS_DIR/run-core-test.sh $BACKEND
|
||||
|
||||
- name: Run api test
|
||||
run: |
|
||||
$TRAVIS_DIR/run-api-test.sh $BACKEND $REPORT_DIR
|
||||
|
||||
- name: Run raft test
|
||||
if: ${{ env.BACKEND == 'rocksdb' }}
|
||||
run: |
|
||||
$TRAVIS_DIR/run-api-test-for-raft.sh $BACKEND $REPORT_DIR
|
||||
|
||||
- name: Run TinkerPop test
|
||||
if: ${{ env.RELEASE_BRANCH == 'true' }}
|
||||
run: |
|
||||
$TRAVIS_DIR/run-tinkerpop-test.sh $BACKEND tinkerpop
|
||||
|
||||
- name: Upload coverage to Codecov
|
||||
uses: codecov/codecov-action@v3.0.0
|
||||
with:
|
||||
file: ${{ env.REPORT_DIR }}/*.xml
|
||||
|
|
@ -29,7 +29,7 @@ jobs:
|
|||
days-before-pr-stale: 30
|
||||
days-before-pr-close: 180
|
||||
operations-per-run: 10
|
||||
start-date: '2016-10-01T00:00:00Z'
|
||||
start-date: '2017-10-01T00:00:00Z'
|
||||
|
||||
exempt-all-assignees: true
|
||||
remove-stale-when-updated: true
|
||||
|
|
|
|||
|
|
@ -19,9 +19,8 @@ gen-java
|
|||
.svn
|
||||
|
||||
### IntelliJ IDEA ###
|
||||
.idea/*
|
||||
!.idea/vcs.xml
|
||||
!.idea/icon.png
|
||||
.idea
|
||||
.idea/
|
||||
*.iws
|
||||
*.iml
|
||||
*.ipr
|
||||
|
|
@ -57,7 +56,7 @@ build/
|
|||
*.pyc
|
||||
|
||||
# maven ignore
|
||||
apache-hugegraph-*/
|
||||
apache-hugegraph-incubating-*/
|
||||
output/
|
||||
*.war
|
||||
*.zip
|
||||
|
|
@ -84,6 +83,3 @@ hs_err_pid*
|
|||
.mtj.tmp/
|
||||
# blueJ files
|
||||
*.ctxt
|
||||
|
||||
# docker volumes ignore
|
||||
hugegraph-server/hugegraph-dist/docker/data/
|
||||
|
|
|
|||
BIN
.idea/icon.png
BIN
.idea/icon.png
Binary file not shown.
|
Before Width: | Height: | Size: 8.3 KiB |
|
|
@ -1,37 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
contributor license agreements. See the NOTICE file distributed with
|
||||
this work for additional information regarding copyright ownership.
|
||||
The ASF licenses this file to You 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.
|
||||
-->
|
||||
|
||||
<project version="4">
|
||||
<component name="IssueNavigationConfiguration">
|
||||
<option name="links">
|
||||
<list>
|
||||
<IssueNavigationLink>
|
||||
<option name="issueRegexp" value="#(\d+)" />
|
||||
<!--
|
||||
GitHub share the sequence number of issues and pull requests, and it will redirect to
|
||||
the right place when the the sequence number not match kind.
|
||||
-->
|
||||
<option name="linkRegexp" value="https://github.com/apache/hugegraph/pull/$1" />
|
||||
</IssueNavigationLink>
|
||||
</list>
|
||||
</option>
|
||||
</component>
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
||||
|
|
@ -26,9 +26,7 @@ header: # `header` section is configurations for source codes license header.
|
|||
The ASF licenses this file to You 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.
|
||||
|
|
@ -36,20 +34,20 @@ header: # `header` section is configurations for source codes license header.
|
|||
limitations under the License.
|
||||
# `pattern` is optional regexp if all the file headers are the same as `license` or the license of `spdx-id` and `copyright-owner`.
|
||||
pattern: |
|
||||
Licensed to the Apache Software Foundation \(ASF\) under one or more
|
||||
contributor license agreements. See the NOTICE file distributed with
|
||||
this work for additional information regarding copyright ownership.
|
||||
The ASF licenses this file to You 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
|
||||
|
||||
Licensed to the Apache Software Foundation under one or more contributor
|
||||
license agreements. See the NOTICE file distributed with
|
||||
this work for additional information regarding copyright
|
||||
ownership. The Apache Software Foundation licenses this file to you 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.
|
||||
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.
|
||||
paths: # `paths` are the path list that will be checked (and fixed) by license-eye, default is ['**'].
|
||||
- '**'
|
||||
|
||||
|
|
@ -92,14 +90,13 @@ header: # `header` section is configurations for source codes license header.
|
|||
- '.repository/**'
|
||||
- '**/.flattened-pom.xml'
|
||||
- 'hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/id/SnowflakeIdGenerator.java'
|
||||
- 'hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/optimize/HugeScriptTraversal.java'
|
||||
- 'hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/type/Nameable.java'
|
||||
- 'hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/type/define/Cardinality.java'
|
||||
- 'hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/util/StringEncoding.java'
|
||||
- 'hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/tinkerpop/ProcessBasicSuite.java'
|
||||
- 'hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/tinkerpop/StructureBasicSuite.java'
|
||||
- '**/optimize/HugeScriptTraversal.java'
|
||||
- '**/type/Nameable.java'
|
||||
- '**/define/Cardinality.java'
|
||||
- '**/util/StringEncoding.java'
|
||||
- 'hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/opencypher/CypherOpProcessor.java'
|
||||
- 'hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/opencypher/CypherPlugin.java'
|
||||
- 'hugegraph-server/hugegraph-dist/src/assembly/static/bin/wait-storage.sh'
|
||||
comment: on-failure # on what condition license-eye will comment on the pull request, `on-failure`, `always`, `never`.
|
||||
|
||||
# license-location-threshold specifies the index threshold where the license header can be located,
|
||||
|
|
|
|||
37
BUILDING.md
37
BUILDING.md
|
|
@ -1,35 +1,28 @@
|
|||
Building HugeGraph
|
||||
Building hugegraph
|
||||
--------------
|
||||
|
||||
Required:
|
||||
|
||||
* Java 11
|
||||
* Maven 3.5+
|
||||
|
||||
To build without executing tests: `mvn clean package -Dmaven.test.skip=true`
|
||||
|
||||
## Building in IDEA
|
||||
* Java 8/11
|
||||
* Maven
|
||||
|
||||
To build without executing tests:
|
||||
|
||||
1. Click on "File" -> "Open", choose your project location.
|
||||
2. Open maven view by click "View" -> "Tool Windows" -> "Maven Projects".
|
||||
3. Choose root module "hugegraph: Distributed Graph Database", unfold the menu of "Lifecycle".
|
||||
4. Click the "Toggle 'Skip Tests' Mode" button which is located on the top navibar of "Maven Projects" window to skip tests.
|
||||
5. Double click "package" or "install" to build a project.
|
||||
```
|
||||
mvn clean
|
||||
mvn package -DskipTests
|
||||
```
|
||||
|
||||
Could also refer [Dev-In-IDEA](https://hugegraph.apache.org/docs/contribution-guidelines/hugegraph-server-idea-setup/) for more details.
|
||||
## Building on Eclipse IDE
|
||||
Note that this has only been tested on Eclipse Neon.2 Release (4.6.2) with m2e (1.7.0.20160603-1933) and m2e-wtp (1.3.1.20160831-1005) plugin.
|
||||
|
||||
## Building in Eclipse
|
||||
|
||||
> Note: this has only been tested on Eclipse Neon.2 Release (4.6.2) with m2e (1.7.0.20160603-1933) and m2e-wtp (1.3.1.20160831-1005) plugin.
|
||||
|
||||
To build without executing tests:
|
||||
|
||||
1. Right-click on your project -> "Run As..." -> "Run Configurations..."
|
||||
2. On "Goals", populate with `install`
|
||||
3. Select the options `Update Snapshots` and `Skip Tests`
|
||||
4. Before clicking "Run", make sure that Eclipse knows where `JAVA_HOME` is. In the same window, go to "Environment" tab and click "New".
|
||||
4. Before clicking "Run", make sure that Eclipse knows where `JAVA_HOME` is. On same window, go to "Environment" tab and click "New".
|
||||
5. Under "Name:", add `JAVA_HOME`
|
||||
6. Under "Value:", add the path where `java` is located
|
||||
7. Click "OK"
|
||||
|
|
@ -39,3 +32,13 @@ To find the Java binary in your environment, run the appropriate command for you
|
|||
* Linux/macOS: `which java`
|
||||
* Windows: `for %i in (java.exe) do @echo. %~$PATH:i`
|
||||
|
||||
## Building on IDEA
|
||||
|
||||
To build without executing tests:
|
||||
|
||||
1. Click on "File" -> "Open", choose your project location.
|
||||
2. Open maven view by click "View" -> "Tool Windows" -> "Maven Projects".
|
||||
3. Choose root module "hugegraph: Distributed Graph Database", unfold the menu of "Lifecycle".
|
||||
4. Click the "Toggle 'Skip Tests' Mode" button which is located on the top
|
||||
navibar of "Maven Projects" window to skip tests.
|
||||
5. Double click "package" or "install" to build project.
|
||||
|
|
|
|||
|
|
@ -1,9 +1,7 @@
|
|||
# How to Contribute to HugeGraph
|
||||
|
||||
> Refer [website-doc](https://hugegraph.apache.org/docs/contribution-guidelines/) for the latest information.
|
||||
|
||||
Thanks for taking the time to contribute!
|
||||
As an open source project, HugeGraph is looking forward to being contributed from everyone, and we are also grateful to all the contributors.
|
||||
Thanks for taking the time to contribute! As an open source project, HugeGraph is looking forward to be contributed from everyone,
|
||||
and we are also grateful to all the contributors.
|
||||
|
||||
The following is a contribution guide for HugeGraph:
|
||||
|
||||
|
|
@ -17,7 +15,7 @@ We can contribute by reporting issues, submitting code patches or any other feed
|
|||
|
||||
Before submitting the code, we need to do some preparation:
|
||||
|
||||
1. Sign up or login to GitHub: [https://github.com](https://github.com)
|
||||
1. Sign up or login to GitHub: [https://github.com](https://github.com)
|
||||
|
||||
2. Fork HugeGraph repo from GitHub: [https://github.com/apache/incubator-hugegraph/fork](https://github.com/apache/incubator-hugegraph/fork)
|
||||
|
||||
|
|
@ -66,26 +64,26 @@ Assume that we need to modify some files like "HugeGraph.java" and "HugeFactory.
|
|||
|
||||
```shell
|
||||
# modify code to fix a bug
|
||||
vim hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/HugeGraph.java
|
||||
vim hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/HugeFactory.java
|
||||
vim hugegraph-core/src/main/java/org/apache/hugegraph/HugeGraph.java
|
||||
vim hugegraph-core/src/main/java/org/apache/hugegraph/HugeFactory.java
|
||||
# run test locally (optional)
|
||||
mvn test -Pcore-test,memory
|
||||
```
|
||||
Note: To be consistent with the code style easily, if you use [IDEA](https://www.jetbrains.com/idea/) as your IDE, you can directly [import](https://www.jetbrains.com/help/idea/configuring-code-style.html) our code style [configuration file](./hugegraph-style.xml).
|
||||
Note: In order to be consistent with the code style easily, if you use [IDEA](https://www.jetbrains.com/idea/) as your IDE, you can directly [import](https://www.jetbrains.com/help/idea/configuring-code-style.html) our code style [configuration file](./hugegraph-style.xml).
|
||||
|
||||
##### 3.2.1 Check licenses
|
||||
If we want to add new third-party dependencies to the `HugeGraph` project, we need to do the following things:
|
||||
1. Find the third-party dependent repository, put the dependent `license` file into [./hugegraph-dist/release-docs/licenses/](https://github.com/apache/incubator-hugegraph/tree/master/hugegraph-dist/release-docs/licenses) path.
|
||||
2. Declare the dependency in [./hugegraph-server/hugegraph-dist/release-docs/LICENSE](https://github.com/apache/incubator-hugegraph/blob/master/hugegraph-server/hugegraph-dist/release-docs/LICENSE) `LICENSE` information.
|
||||
3. Find the NOTICE file in the repository and append it to [./hugegraph-server/hugegraph-dist/release-docs/NOTICE](https://github.com/apache/incubator-hugegraph/blob/master/hugegraph-server/hugegraph-dist/release-docs/NOTICE) file (skip this step if there is no NOTICE file).
|
||||
4. Execute locally [./hugegraph-server/hugegraph-dist/scripts/dependency/regenerate_known_dependencies.sh](https://github.com/apache/incubator-hugegraph/blob/master/hugegraph-server/hugegraph-dist/scripts/dependency/regenerate_known_dependencies.sh) to update the dependency list [known-dependencies.txt](https://github.com/apache/incubator-hugegraph/blob/master/hugegraph-server/hugegraph-dist/scripts/dependency/known-dependencies.txt) (or manually update).
|
||||
2. Declare the dependency in [./hugegraph-dist/release-docs/LICENSE](https://github.com/apache/incubator-hugegraph/blob/master/hugegraph-dist/release-docs/LICENSE) `LICENSE` information.
|
||||
3. Find the NOTICE file in the repository and append it to [./hugegraph-dist/release-docs/NOTICE](https://github.com/apache/incubator-hugegraph/blob/master/hugegraph-dist/release-docs/NOTICE) file (skip this step if there is no NOTICE file).
|
||||
4. Execute locally [./hugegraph-dist/scripts/dependency/regenerate_known_dependencies.sh](https://github.com/apache/incubator-hugegraph/blob/master/hugegraph-dist/scripts/dependency/regenerate_known_dependencies.sh) to update the dependency list [known-dependencies.txt](https://github.com/apache/incubator-hugegraph/blob/master/hugegraph-dist/scripts/dependency/known-dependencies.txt) (or manually update) .
|
||||
|
||||
**Example**: A new third-party dependency is introduced into the project -> `ant-1.9.1.jar`
|
||||
- The project source code is located at: https://github.com/apache/ant/tree/rel/1.9.1
|
||||
- LICENSE file: https://github.com/apache/ant/blob/rel/1.9.1/LICENSE
|
||||
- NOTICE file: https://github.com/apache/ant/blob/rel/1.9.1/NOTICE
|
||||
|
||||
The license information of `ant-1.9.1.jar` needs to be specified in the LICENSE file, and the notice information needs to be specified in the NOTICE file. The detailed LICENSE file corresponding to ant-1.9.1.jar needs to be copied to our licenses/ directory. Finally, update the known-dependencies.txt file.
|
||||
The license information of `ant-1.9.1.jar` needs to be specified in the LICENSE file, and the notice information needs to be specified in the NOTICE file. The detailed LICENSE file corresponding to ant-1.9.1.jar needs to be copied to our licenses/ directory. Finally update the known-dependencies.txt file.
|
||||
|
||||
#### 3.3 Commit changes to git repo
|
||||
|
||||
|
|
@ -93,8 +91,8 @@ After the code has been completed, we submit them to the local git repo:
|
|||
|
||||
```shell
|
||||
# add files to local git index
|
||||
git add hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/HugeGraph.java
|
||||
git add hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/HugeFactory.java
|
||||
git add hugegraph-core/src/main/java/org/apache/hugegraph/HugeGraph.java
|
||||
git add hugegraph-core/src/main/java/org/apache/hugegraph/HugeFactory.java
|
||||
# commit to local git repo
|
||||
git commit
|
||||
```
|
||||
|
|
@ -107,7 +105,7 @@ Fix bug: run deploy multiple times
|
|||
fix #ISSUE_ID
|
||||
```
|
||||
|
||||
> Please remember to fill in the issue id, which GitHub generated after issue creation.
|
||||
> Please remember to fill in the issue id, which was generated by GitHub after issue creation.
|
||||
|
||||
#### 3.4 Push commit to GitHub fork repo
|
||||
|
||||
|
|
@ -123,7 +121,7 @@ Note that since GitHub requires submitting code through `username + token` (inst
|
|||
|
||||
## 4. Create a Pull Request
|
||||
|
||||
Go to the web page of GitHub fork repo, there would be a chance to create a Pull Request after pushing to a new branch, click the button "Compare & pull request" to do it. Then edit the description for proposed changes, which can just be copied from the commit message.
|
||||
Go to the web page of GitHub fork repo, there would be a chance to create a Pull Request after pushing to a new branch, just click button "Compare & pull request" to do it. Then edit the description for proposed changes, which can just be copied from the commit message.
|
||||
|
||||
Note: please make sure the email address you used to submit the code is bound to the GitHub account. For how to bind the email address, please refer to https://github.com/settings/emails:
|
||||
<img width="1280" alt="image" src="https://user-images.githubusercontent.com/9625821/163522445-2a50a72a-dea2-434f-9868-3a0d40d0d037.png">
|
||||
|
|
@ -133,7 +131,7 @@ Note: please make sure the email address you used to submit the code is bound to
|
|||
Maintainers will start the code review after all the **automatic** checks are passed:
|
||||
|
||||
- Check: Contributor License Agreement is signed
|
||||
- Check: Travis CI builds are passed (automatically Test and Deploy)
|
||||
- Check: Travis CI builds is passed (automatically Test and Deploy)
|
||||
|
||||
The commit will be accepted and merged if there is no problem after review.
|
||||
|
||||
|
|
@ -173,8 +171,8 @@ And push it to GitHub fork repo again:
|
|||
git push -f origin bugfix-branch:bugfix-branch
|
||||
```
|
||||
|
||||
GitHub will automatically update the Pull Request after we push it, wait for code review.
|
||||
GitHub will automatically update the Pull Request after we push it, just wait for code review.
|
||||
|
||||
For Any question, please contact us through [dev@hugegraph.apache.org](mailto:dev@hugegraph.apache.org) ([subscriber](https://hugegraph.apache.org/docs/contribution-guidelines/subscribe/) only)
|
||||
Any question please contact to us through [hugegraph@googlegroups.com](mailto:hugegraph@googlegroups.com) or [other contact information](https://hugegraph.github.io/hugegraph-doc/).
|
||||
|
||||
|
||||
|
|
|
|||
19
LICENSE
19
LICENSE
|
|
@ -207,12 +207,13 @@ Apache 2.0 licenses
|
|||
The following components are provided under the Apache License. See project link for details.
|
||||
The text of each license is the standard Apache 2.0 license.
|
||||
|
||||
hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/tinkerpop/StructureBasicSuite.java from https://github.com/apache/tinkerpop
|
||||
hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/tinkerpop/ProcessBasicSuite.java from https://github.com/apache/tinkerpop
|
||||
hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/id/SnowflakeIdGenerator.java from https://github.com/twitter-archive/snowflake
|
||||
hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/optimize/HugeScriptTraversal.java from https://github.com/apache/tinkerpop
|
||||
hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/type/Nameable.java from https://github.com/JanusGraph/janusgraph
|
||||
hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/type/define/Cardinality.java from https://github.com/JanusGraph/janusgraph
|
||||
hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/util/StringEncoding.java from https://github.com/JanusGraph/janusgraph
|
||||
hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/opencypher/CypherOpProcessor.java from https://github.com/opencypher/cypher-for-gremlin
|
||||
hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/opencypher/CypherPlugin.java from https://github.com/opencypher/cypher-for-gremlin
|
||||
hugegraph-test/src/main/java/org/apache/hugegraph/tinkerpop/StructureBasicSuite.java from https://github.com/apache/tinkerpop
|
||||
hugegraph-test/src/main/java/org/apache/hugegraph/tinkerpop/ProcessBasicSuite.java from https://github.com/apache/tinkerpop
|
||||
hugegraph-core/src/main/java/org/apache/hugegraph/backend/id/SnowflakeIdGenerator.java from https://github.com/twitter-archive/snowflake
|
||||
hugegraph-core/src/main/java/org/apache/hugegraph/traversal/optimize/HugeScriptTraversal.java from https://github.com/apache/tinkerpop
|
||||
hugegraph-core/src/main/java/org/apache/hugegraph/type/Nameable.java from https://github.com/JanusGraph/janusgraph
|
||||
hugegraph-core/src/main/java/org/apache/hugegraph/type/define/Cardinality.java from https://github.com/JanusGraph/janusgraph
|
||||
hugegraph-core/src/main/java/org/apache/hugegraph/util/StringEncoding.java from https://github.com/JanusGraph/janusgraph
|
||||
hugegraph-dist/src/assembly/static/bin/wait-storage.sh from https://github.com/JanusGraph/janusgraph
|
||||
hugegraph-api/src/main/java/org/apache/hugegraph/opencypher/CypherOpProcessor.java from https://github.com/opencypher/cypher-for-gremlin
|
||||
hugegraph-api/src/main/java/org/apache/hugegraph/opencypher/CypherPlugin.java from https://github.com/opencypher/cypher-for-gremlin
|
||||
|
|
|
|||
40
NOTICE
40
NOTICE
|
|
@ -1,5 +1,5 @@
|
|||
Apache HugeGraph(incubating)
|
||||
Copyright 2022-2024 The Apache Software Foundation
|
||||
Copyright 2022-2023 The Apache Software Foundation
|
||||
|
||||
This product includes software developed at
|
||||
The Apache Software Foundation (http://www.apache.org/).
|
||||
|
|
@ -13,6 +13,9 @@ This product contains code form the Apache TinkerPop Project:
|
|||
Apache TinkerPop
|
||||
Copyright 2015-2022 The Apache Software Foundation.
|
||||
|
||||
This product includes software developed at
|
||||
The Apache Software Foundation (http://www.apache.org/).
|
||||
|
||||
------------------------------------------------------------------------
|
||||
Activiti
|
||||
------------------------------------------------------------------------
|
||||
|
|
@ -39,7 +42,7 @@ This product contains code form the JanusGraph Project:
|
|||
-----------------------------------------------------------------------
|
||||
==============================================================
|
||||
JanusGraph: Distributed Graph Database
|
||||
Copyright 2012 with JanusGraph Authors
|
||||
Copyright 2012 and onwards JanusGraph Authors
|
||||
==============================================================
|
||||
|
||||
This product includes software developed by JanusGraph contributors listed
|
||||
|
|
@ -53,3 +56,36 @@ DataStax) and the following individuals:
|
|||
* Marko A. Rodriguez
|
||||
* Stephen Mallette
|
||||
* Pavel Yaskevich
|
||||
|
||||
It also includes software from other open source projects including, but not limited to (check pom.xml for complete listing):
|
||||
|
||||
* Apache Cassandra [https://cassandra.apache.org/]
|
||||
* Apache Commons [https://commons.apache.org/]
|
||||
* Apache Groovy [http://groovy-lang.org/]
|
||||
* Apache HBase [https://hbase.apache.org/]
|
||||
* Apache Hadoop [https://hadoop.apache.org/]
|
||||
* Apache Kerby [https://github.com/apache/directory-kerby]
|
||||
* Apache Log4j [https://logging.apache.org/log4j]
|
||||
* Apache Lucene [https://lucene.apache.org/]
|
||||
* Apache Solr [https://lucene.apache.org/solr/]
|
||||
* Apache TinkerPop [https://tinkerpop.apache.org/]
|
||||
* Astyanax [https://github.com/Netflix/astyanax]
|
||||
* DataStax Driver for Apache Cassandra [https://github.com/datastax/java-driver]
|
||||
* EasyMock [http://easymock.org/]
|
||||
* Elasticsearch [https://www.elastic.co/]
|
||||
* Google Cloud Bigtable [https://github.com/googlecloudplatform/cloud-bigtable-client]
|
||||
* Google Guava [https://github.com/google/guava]
|
||||
* HPPC [https://labs.carrotsearch.com/hppc.html]
|
||||
* JUnit [https://www.junit.org/]
|
||||
* Jackson [https://github.com/FasterXML/jackson]
|
||||
* Kryo [https://github.com/EsotericSoftware/kryo]
|
||||
* Metrics [https://metrics.dropwizard.io]
|
||||
* Mockito [https://site.mockito.org/]
|
||||
* Noggit [https://github.com/yonik/noggit]
|
||||
* OpenRDF [http://rdf4j.org/]
|
||||
* Oracle BerkeleyDB Java Edition [https://www.oracle.com/technetwork/products/berkeleydb/] (see license below)
|
||||
* Project Lombok [https://projectlombok.org/]
|
||||
* Reflections8 [https://github.com/aschoerk/reflections8]
|
||||
* SLF4J [https://www.slf4j.org/]
|
||||
* Spatial4j [https://github.com/locationtech/spatial4j]
|
||||
* Vavr [https://www.vavr.io/]
|
||||
|
|
|
|||
44
README.md
44
README.md
|
|
@ -16,9 +16,7 @@
|
|||
## What is Apache HugeGraph?
|
||||
|
||||
[HugeGraph](https://hugegraph.apache.org/) is a fast-speed and highly-scalable [graph database](https://en.wikipedia.org/wiki/Graph_database).
|
||||
Billions of vertices and edges can be easily stored into and queried from HugeGraph due to its excellent OLTP ability.
|
||||
As compliance to [Apache TinkerPop 3](https://tinkerpop.apache.org/) framework, various complicated graph queries can be
|
||||
achieved through [Gremlin](https://tinkerpop.apache.org/gremlin.html)(a powerful graph traversal language).
|
||||
Billions of vertices and edges can be easily stored into and queried from HugeGraph due to its excellent OLTP ability. As compliance to [Apache TinkerPop 3](https://tinkerpop.apache.org/) framework, various complicated graph queries can be accomplished through [Gremlin](https://tinkerpop.apache.org/gremlin.html)(a powerful graph traversal language).
|
||||
|
||||
|
||||
## Features
|
||||
|
|
@ -32,25 +30,12 @@ achieved through [Gremlin](https://tinkerpop.apache.org/gremlin.html)(a powerful
|
|||
|
||||
## Quick Start
|
||||
|
||||
### 1. Docker Way (Convenient for Test)
|
||||
|
||||
We can use `docker run -itd --name=graph -p 8080:8080 hugegraph/hugegraph` to quickly start an inner
|
||||
HugeGraph server with `RocksDB` (in backgrounds) for **test/dev**.
|
||||
You can visit [doc page](https://hugegraph.apache.org/docs/quickstart/hugegraph-server/#3-deploy) or
|
||||
the [README](hugegraph-server/hugegraph-dist/docker/README.md) for more details. ([Docker Compose](./hugegraph-server/hugegraph-dist/docker/example))
|
||||
|
||||
> Note:
|
||||
>
|
||||
> 1. The docker image of hugegraph is a convenience release, but not **official distribution** artifacts. You can find more details from [ASF Release Distribution Policy](https://infra.apache.org/release-distribution.html#dockerhub).
|
||||
>
|
||||
> 2. Recommend to use `release tag`(like `1.2.0`) for the stable version. Use `latest` tag to experience the newest functions in development.
|
||||
|
||||
### 2. Download Way
|
||||
### 1. Download Way
|
||||
|
||||
Visit [Download Page](https://hugegraph.apache.org/docs/download/download/) and refer the [doc](https://hugegraph.apache.org/docs/quickstart/hugegraph-server/#32-download-the-binary-tar-tarball)
|
||||
to download the latest release package and start the server.
|
||||
|
||||
### 3. Source Building Way
|
||||
### 2. Source Building Way
|
||||
|
||||
Visit [Source Building Page](https://hugegraph.apache.org/docs/quickstart/hugegraph-server/#33-source-code-compilation) and follow the
|
||||
steps to build the source code and start the server.
|
||||
|
|
@ -59,15 +44,26 @@ The project [doc page](https://hugegraph.apache.org/docs/) contains more informa
|
|||
and provides detailed documentation for users. (Structure / Usage / API / Configs...)
|
||||
|
||||
And here are links of other **HugeGraph** component/repositories:
|
||||
1. [hugegraph-toolchain](https://github.com/apache/hugegraph-toolchain) (graph tools **[loader](https://github.com/apache/incubator-hugegraph-toolchain/tree/master/hugegraph-loader)/[dashboard](https://github.com/apache/incubator-hugegraph-toolchain/tree/master/hugegraph-hubble)/[tool](https://github.com/apache/incubator-hugegraph-toolchain/tree/master/hugegraph-tools)/[client](https://github.com/apache/incubator-hugegraph-toolchain/tree/master/hugegraph-client)**)
|
||||
2. [hugegraph-computer](https://github.com/apache/hugegraph-computer) (integrated **graph computing** system)
|
||||
3. [hugegraph-commons](https://github.com/apache/hugegraph-commons) (**common & rpc** libs)
|
||||
4. [hugegraph-website](https://github.com/apache/hugegraph-doc) (**doc & website** code)
|
||||
5. [hugegraph-ai](https://github.com/apache/incubator-hugegraph-ai) (integrated **Graph AI/LLM/KG** system)
|
||||
1. [hugegraph-toolchain](https://github.com/apache/incubator-hugegraph-toolchain) (graph tools **[loader](https://github.com/apache/incubator-hugegraph-toolchain/tree/master/hugegraph-loader)/[dashboard](https://github.com/apache/incubator-hugegraph-toolchain/tree/master/hugegraph-hubble)/[tool](https://github.com/apache/incubator-hugegraph-toolchain/tree/master/hugegraph-tools)/[client](https://github.com/apache/incubator-hugegraph-toolchain/tree/master/hugegraph-client)**)
|
||||
2. [hugegraph-computer](https://github.com/apache/incubator-hugegraph-computer) (integrated **graph computing** system)
|
||||
3. [hugegraph-commons](https://github.com/apache/incubator-hugegraph-commons) (**common & rpc** libs)
|
||||
4. [hugegraph-website](https://github.com/apache/incubator-hugegraph-doc) (**doc & website** code)
|
||||
|
||||
### 3. Docker Way (Convenient for Test)
|
||||
|
||||
We can use `docker run -itd --name=graph -p 8080:8080 hugegraph/hugegraph` to quickly start an inner
|
||||
HugeGraph server with `RocksDB` (in backgrounds) for **test/dev**.
|
||||
You can visit [doc page](https://hugegraph.apache.org/docs/quickstart/hugegraph-server/#3-deploy) or the [README](hugegraph-server/hugegraph-dist/docker/READEME.md) for more details.
|
||||
|
||||
> Note:
|
||||
>
|
||||
> 1. The docker image of hugegraph is a convenience release, but not **official distribution** artifacts. You can find more details from [ASF Release Distribution Policy](https://infra.apache.org/release-distribution.html#dockerhub).
|
||||
>
|
||||
> 2. Recommand to use `release tag`(like `1.0.0`) for the stable version. Use `latest` tag to experience the newest functions in development.
|
||||
|
||||
## License
|
||||
|
||||
HugeGraph is licensed under [Apache 2.0 License](LICENSE).
|
||||
HugeGraph is licensed under Apache 2.0 License.
|
||||
|
||||
|
||||
## Contributing
|
||||
|
|
|
|||
|
|
@ -1,63 +0,0 @@
|
|||
#
|
||||
# Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
# contributor license agreements. See the NOTICE file distributed with
|
||||
# this work for additional information regarding copyright ownership.
|
||||
# The ASF licenses this file to You 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.
|
||||
#
|
||||
|
||||
spring:
|
||||
application:
|
||||
name: hugegraph-pd
|
||||
|
||||
management:
|
||||
metrics:
|
||||
export:
|
||||
prometheus:
|
||||
enabled: true
|
||||
endpoints:
|
||||
web:
|
||||
exposure:
|
||||
include: "*"
|
||||
|
||||
logging:
|
||||
config: 'file:./conf/log4j2.xml'
|
||||
license:
|
||||
verify-path: ./conf/verify-license.json
|
||||
license-path: ./conf/hugegraph.license
|
||||
grpc:
|
||||
port: 8686
|
||||
host: 127.0.0.1
|
||||
|
||||
server:
|
||||
port: 8620
|
||||
|
||||
pd:
|
||||
data-path: ./pd_data
|
||||
patrol-interval: 1800
|
||||
initial-store-count: 3
|
||||
initial-store-list: 127.0.0.1:8500,127.0.0.1:8501,127.0.0.1:8502
|
||||
|
||||
raft:
|
||||
address: 127.0.0.1:8610
|
||||
peers-list: 127.0.0.1:8610,127.0.0.1:8611,127.0.0.1:8612
|
||||
|
||||
store:
|
||||
max-down-time: 172800
|
||||
monitor_data_enabled: true
|
||||
monitor_data_interval: 1 minute
|
||||
monitor_data_retention: 1 day
|
||||
initial-store-count: 1
|
||||
|
||||
partition:
|
||||
default-shard-count: 1
|
||||
store-max-shard-count: 12
|
||||
|
|
@ -1,63 +0,0 @@
|
|||
#
|
||||
# Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
# contributor license agreements. See the NOTICE file distributed with
|
||||
# this work for additional information regarding copyright ownership.
|
||||
# The ASF licenses this file to You 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.
|
||||
#
|
||||
|
||||
spring:
|
||||
application:
|
||||
name: hugegraph-pd
|
||||
|
||||
management:
|
||||
metrics:
|
||||
export:
|
||||
prometheus:
|
||||
enabled: true
|
||||
endpoints:
|
||||
web:
|
||||
exposure:
|
||||
include: "*"
|
||||
|
||||
logging:
|
||||
config: 'file:./conf/log4j2.xml'
|
||||
license:
|
||||
verify-path: ./conf/verify-license.json
|
||||
license-path: ./conf/hugegraph.license
|
||||
grpc:
|
||||
port: 8687
|
||||
host: 127.0.0.1
|
||||
|
||||
server:
|
||||
port: 8621
|
||||
|
||||
pd:
|
||||
data-path: ./pd_data
|
||||
patrol-interval: 1800
|
||||
initial-store-count: 3
|
||||
initial-store-list: 127.0.0.1:8500,127.0.0.1:8501,127.0.0.1:8502
|
||||
|
||||
raft:
|
||||
address: 127.0.0.1:8611
|
||||
peers-list: 127.0.0.1:8610,127.0.0.1:8611,127.0.0.1:8612
|
||||
|
||||
store:
|
||||
max-down-time: 172800
|
||||
monitor_data_enabled: true
|
||||
monitor_data_interval: 1 minute
|
||||
monitor_data_retention: 1 day
|
||||
initial-store-count: 1
|
||||
|
||||
partition:
|
||||
default-shard-count: 1
|
||||
store-max-shard-count: 12
|
||||
|
|
@ -1,63 +0,0 @@
|
|||
#
|
||||
# Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
# contributor license agreements. See the NOTICE file distributed with
|
||||
# this work for additional information regarding copyright ownership.
|
||||
# The ASF licenses this file to You 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.
|
||||
#
|
||||
|
||||
spring:
|
||||
application:
|
||||
name: hugegraph-pd
|
||||
|
||||
management:
|
||||
metrics:
|
||||
export:
|
||||
prometheus:
|
||||
enabled: true
|
||||
endpoints:
|
||||
web:
|
||||
exposure:
|
||||
include: "*"
|
||||
|
||||
logging:
|
||||
config: 'file:./conf/log4j2.xml'
|
||||
license:
|
||||
verify-path: ./conf/verify-license.json
|
||||
license-path: ./conf/hugegraph.license
|
||||
grpc:
|
||||
port: 8688
|
||||
host: 127.0.0.1
|
||||
|
||||
server:
|
||||
port: 8622
|
||||
|
||||
pd:
|
||||
data-path: ./pd_data
|
||||
patrol-interval: 1800
|
||||
initial-store-count: 3
|
||||
initial-store-list: 127.0.0.1:8500,127.0.0.1:8501,127.0.0.1:8502
|
||||
|
||||
raft:
|
||||
address: 127.0.0.1:8612
|
||||
peers-list: 127.0.0.1:8610,127.0.0.1:8611,127.0.0.1:8612
|
||||
|
||||
store:
|
||||
max-down-time: 172800
|
||||
monitor_data_enabled: true
|
||||
monitor_data_interval: 1 minute
|
||||
monitor_data_retention: 1 day
|
||||
initial-store-count: 1
|
||||
|
||||
partition:
|
||||
default-shard-count: 1
|
||||
store-max-shard-count: 12
|
||||
|
|
@ -1,57 +0,0 @@
|
|||
#
|
||||
# Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
# contributor license agreements. See the NOTICE file distributed with
|
||||
# this work for additional information regarding copyright ownership.
|
||||
# The ASF licenses this file to You 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.
|
||||
#
|
||||
|
||||
pdserver:
|
||||
address: 127.0.0.1:8686,127.0.0.1:8687,127.0.0.1:8688
|
||||
|
||||
management:
|
||||
metrics:
|
||||
export:
|
||||
prometheus:
|
||||
enabled: true
|
||||
endpoints:
|
||||
web:
|
||||
exposure:
|
||||
include: "*"
|
||||
|
||||
grpc:
|
||||
host: 127.0.0.1
|
||||
port: 8500
|
||||
netty-server:
|
||||
max-inbound-message-size: 1000MB
|
||||
raft:
|
||||
disruptorBufferSize: 1024
|
||||
address: 127.0.0.1:8510
|
||||
max-log-file-size: 600000000000
|
||||
snapshotInterval: 1800
|
||||
server:
|
||||
port: 8520
|
||||
|
||||
app:
|
||||
data-path: ./storage
|
||||
|
||||
spring:
|
||||
application:
|
||||
name: store-node-grpc-server
|
||||
profiles:
|
||||
active: default
|
||||
include: pd
|
||||
|
||||
logging:
|
||||
config: 'file:./conf/log4j2.xml'
|
||||
level:
|
||||
root: info
|
||||
|
|
@ -1,57 +0,0 @@
|
|||
#
|
||||
# Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
# contributor license agreements. See the NOTICE file distributed with
|
||||
# this work for additional information regarding copyright ownership.
|
||||
# The ASF licenses this file to You 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.
|
||||
#
|
||||
|
||||
pdserver:
|
||||
address: 127.0.0.1:8686,127.0.0.1:8687,127.0.0.1:8688
|
||||
|
||||
management:
|
||||
metrics:
|
||||
export:
|
||||
prometheus:
|
||||
enabled: true
|
||||
endpoints:
|
||||
web:
|
||||
exposure:
|
||||
include: "*"
|
||||
|
||||
grpc:
|
||||
host: 127.0.0.1
|
||||
port: 8501
|
||||
netty-server:
|
||||
max-inbound-message-size: 1000MB
|
||||
raft:
|
||||
disruptorBufferSize: 1024
|
||||
address: 127.0.0.1:8511
|
||||
max-log-file-size: 600000000000
|
||||
snapshotInterval: 1800
|
||||
server:
|
||||
port: 8521
|
||||
|
||||
app:
|
||||
data-path: ./storage
|
||||
|
||||
spring:
|
||||
application:
|
||||
name: store-node-grpc-server
|
||||
profiles:
|
||||
active: default
|
||||
include: pd
|
||||
|
||||
logging:
|
||||
config: 'file:./conf/log4j2.xml'
|
||||
level:
|
||||
root: info
|
||||
|
|
@ -1,57 +0,0 @@
|
|||
#
|
||||
# Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
# contributor license agreements. See the NOTICE file distributed with
|
||||
# this work for additional information regarding copyright ownership.
|
||||
# The ASF licenses this file to You 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.
|
||||
#
|
||||
|
||||
pdserver:
|
||||
address: 127.0.0.1:8686,127.0.0.1:8687,127.0.0.1:8688
|
||||
|
||||
management:
|
||||
metrics:
|
||||
export:
|
||||
prometheus:
|
||||
enabled: true
|
||||
endpoints:
|
||||
web:
|
||||
exposure:
|
||||
include: "*"
|
||||
|
||||
grpc:
|
||||
host: 127.0.0.1
|
||||
port: 8502
|
||||
netty-server:
|
||||
max-inbound-message-size: 1000MB
|
||||
raft:
|
||||
disruptorBufferSize: 1024
|
||||
address: 127.0.0.1:8512
|
||||
max-log-file-size: 600000000000
|
||||
snapshotInterval: 1800
|
||||
server:
|
||||
port: 8522
|
||||
|
||||
app:
|
||||
data-path: ./storage
|
||||
|
||||
spring:
|
||||
application:
|
||||
name: store-node-grpc-server
|
||||
profiles:
|
||||
active: default
|
||||
include: pd
|
||||
|
||||
logging:
|
||||
config: 'file:./conf/log4j2.xml'
|
||||
level:
|
||||
root: info
|
||||
|
|
@ -1,19 +0,0 @@
|
|||
# auth config: org.apache.hugegraph.auth.HugeFactoryAuthProxy
|
||||
gremlin.graph=org.apache.hugegraph.HugeFactory
|
||||
|
||||
# cache config
|
||||
vertex.cache_type=l2
|
||||
edge.cache_type=l2
|
||||
|
||||
store=hugegraph
|
||||
backend=hstore
|
||||
serializer=binary
|
||||
|
||||
# pd config
|
||||
pd.peers=127.0.0.1:8686,127.0.0.1:8687,127.0.0.1:8688
|
||||
|
||||
# task config
|
||||
task.scheduler_type=local
|
||||
task.schedule_period=10
|
||||
task.retry=0
|
||||
task.wait_timeout=10
|
||||
|
|
@ -1,25 +0,0 @@
|
|||
#
|
||||
# Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
# contributor license agreements. See the NOTICE file distributed with
|
||||
# this work for additional information regarding copyright ownership.
|
||||
# The ASF licenses this file to You 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.
|
||||
#
|
||||
hosts: [localhost]
|
||||
port: 8181
|
||||
serializer: {
|
||||
className: org.apache.tinkerpop.gremlin.driver.ser.GraphSONMessageSerializerV1d0,
|
||||
config: {
|
||||
serializeResultToString: false,
|
||||
ioRegistries: [org.apache.hugegraph.io.HugeGraphIoRegistry]
|
||||
}
|
||||
}
|
||||
|
|
@ -1,127 +0,0 @@
|
|||
#
|
||||
# Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
# contributor license agreements. See the NOTICE file distributed with
|
||||
# this work for additional information regarding copyright ownership.
|
||||
# The ASF licenses this file to You 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.
|
||||
#
|
||||
# host and port of gremlin server, need to be consistent with host and port in rest-server.properties
|
||||
host: 127.0.0.1
|
||||
port: 8181
|
||||
|
||||
# timeout in ms of gremlin query
|
||||
evaluationTimeout: 30000
|
||||
|
||||
channelizer: org.apache.tinkerpop.gremlin.server.channel.WsAndHttpChannelizer
|
||||
# don't set graph at here, this happens after support for dynamically adding graph
|
||||
graphs: {
|
||||
}
|
||||
scriptEngines: {
|
||||
gremlin-groovy: {
|
||||
staticImports: [
|
||||
org.opencypher.gremlin.process.traversal.CustomPredicates.*',
|
||||
org.opencypher.gremlin.traversal.CustomFunctions.*
|
||||
],
|
||||
plugins: {
|
||||
org.apache.hugegraph.plugin.HugeGraphGremlinPlugin: {},
|
||||
org.apache.tinkerpop.gremlin.server.jsr223.GremlinServerGremlinPlugin: {},
|
||||
org.apache.tinkerpop.gremlin.jsr223.ImportGremlinPlugin: {
|
||||
classImports: [
|
||||
java.lang.Math,
|
||||
org.apache.hugegraph.backend.id.IdGenerator,
|
||||
org.apache.hugegraph.type.define.Directions,
|
||||
org.apache.hugegraph.type.define.NodeRole,
|
||||
org.apache.hugegraph.masterelection.GlobalMasterInfo,
|
||||
org.apache.hugegraph.util.DateUtil,
|
||||
org.apache.hugegraph.traversal.algorithm.CollectionPathsTraverser,
|
||||
org.apache.hugegraph.traversal.algorithm.CountTraverser,
|
||||
org.apache.hugegraph.traversal.algorithm.CustomizedCrosspointsTraverser,
|
||||
org.apache.hugegraph.traversal.algorithm.CustomizePathsTraverser,
|
||||
org.apache.hugegraph.traversal.algorithm.FusiformSimilarityTraverser,
|
||||
org.apache.hugegraph.traversal.algorithm.HugeTraverser,
|
||||
org.apache.hugegraph.traversal.algorithm.JaccardSimilarTraverser,
|
||||
org.apache.hugegraph.traversal.algorithm.KneighborTraverser,
|
||||
org.apache.hugegraph.traversal.algorithm.KoutTraverser,
|
||||
org.apache.hugegraph.traversal.algorithm.MultiNodeShortestPathTraverser,
|
||||
org.apache.hugegraph.traversal.algorithm.NeighborRankTraverser,
|
||||
org.apache.hugegraph.traversal.algorithm.PathsTraverser,
|
||||
org.apache.hugegraph.traversal.algorithm.PersonalRankTraverser,
|
||||
org.apache.hugegraph.traversal.algorithm.SameNeighborTraverser,
|
||||
org.apache.hugegraph.traversal.algorithm.ShortestPathTraverser,
|
||||
org.apache.hugegraph.traversal.algorithm.SingleSourceShortestPathTraverser,
|
||||
org.apache.hugegraph.traversal.algorithm.SubGraphTraverser,
|
||||
org.apache.hugegraph.traversal.algorithm.TemplatePathsTraverser,
|
||||
org.apache.hugegraph.traversal.algorithm.steps.EdgeStep,
|
||||
org.apache.hugegraph.traversal.algorithm.steps.RepeatEdgeStep,
|
||||
org.apache.hugegraph.traversal.algorithm.steps.WeightedEdgeStep,
|
||||
org.apache.hugegraph.traversal.optimize.ConditionP,
|
||||
org.apache.hugegraph.traversal.optimize.Text,
|
||||
org.apache.hugegraph.traversal.optimize.TraversalUtil,
|
||||
org.opencypher.gremlin.traversal.CustomFunctions,
|
||||
org.opencypher.gremlin.traversal.CustomPredicate
|
||||
],
|
||||
methodImports: [
|
||||
java.lang.Math#*,
|
||||
org.opencypher.gremlin.traversal.CustomPredicate#*,
|
||||
org.opencypher.gremlin.traversal.CustomFunctions#*
|
||||
]
|
||||
},
|
||||
org.apache.tinkerpop.gremlin.jsr223.ScriptFileGremlinPlugin: {
|
||||
files: [scripts/empty-sample.groovy]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
serializers:
|
||||
- {className: org.apache.tinkerpop.gremlin.driver.ser.GraphBinaryMessageSerializerV1,
|
||||
config: {
|
||||
serializeResultToString: false,
|
||||
ioRegistries: [org.apache.hugegraph.io.HugeGraphIoRegistry]
|
||||
}
|
||||
}
|
||||
- {className: org.apache.tinkerpop.gremlin.driver.ser.GraphSONMessageSerializerV1d0,
|
||||
config: {
|
||||
serializeResultToString: false,
|
||||
ioRegistries: [org.apache.hugegraph.io.HugeGraphIoRegistry]
|
||||
}
|
||||
}
|
||||
- {className: org.apache.tinkerpop.gremlin.driver.ser.GraphSONMessageSerializerV2d0,
|
||||
config: {
|
||||
serializeResultToString: false,
|
||||
ioRegistries: [org.apache.hugegraph.io.HugeGraphIoRegistry]
|
||||
}
|
||||
}
|
||||
- {className: org.apache.tinkerpop.gremlin.driver.ser.GraphSONMessageSerializerV3d0,
|
||||
config: {
|
||||
serializeResultToString: false,
|
||||
ioRegistries: [org.apache.hugegraph.io.HugeGraphIoRegistry]
|
||||
}
|
||||
}
|
||||
metrics: {
|
||||
consoleReporter: {enabled: false, interval: 180000},
|
||||
csvReporter: {enabled: false, interval: 180000, fileName: ./metrics/gremlin-server-metrics.csv},
|
||||
jmxReporter: {enabled: false},
|
||||
slf4jReporter: {enabled: false, interval: 180000},
|
||||
gangliaReporter: {enabled: false, interval: 180000, addressingMode: MULTICAST},
|
||||
graphiteReporter: {enabled: false, interval: 180000}
|
||||
}
|
||||
maxInitialLineLength: 4096
|
||||
maxHeaderSize: 8192
|
||||
maxChunkSize: 8192
|
||||
maxContentLength: 65536
|
||||
maxAccumulationBufferComponents: 1024
|
||||
resultIterationBatchSize: 64
|
||||
writeBufferLowWaterMark: 32768
|
||||
writeBufferHighWaterMark: 65536
|
||||
ssl: {
|
||||
enabled: false
|
||||
}
|
||||
|
|
@ -1,144 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
contributor license agreements. See the NOTICE file distributed with
|
||||
this work for additional information regarding copyright ownership.
|
||||
The ASF licenses this file to You 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.
|
||||
-->
|
||||
<!-- Config will be auto loaded every 60s -->
|
||||
<configuration status="error" monitorInterval="60">
|
||||
<properties>
|
||||
<property name="LOG_PATH">logs</property>
|
||||
<property name="FILE_NAME">hugegraph-server</property>
|
||||
</properties>
|
||||
|
||||
<appenders>
|
||||
<Console name="console" target="SYSTEM_OUT">
|
||||
<ThresholdFilter level="DEBUG" onMatch="ACCEPT" onMismatch="DENY"/>
|
||||
<PatternLayout pattern="%-d{yyyy-MM-dd HH:mm:ss} [%t] [%p] %c{1.} - %m%n"/>
|
||||
</Console>
|
||||
|
||||
<!-- Normal server log config -->
|
||||
<RollingRandomAccessFile name="file" fileName="${LOG_PATH}/${FILE_NAME}.log"
|
||||
filePattern="${LOG_PATH}/$${date:yyyy-MM}/${FILE_NAME}-%d{yyyy-MM-dd}-%i.log"
|
||||
immediateFlush="false">
|
||||
<ThresholdFilter level="TRACE" onMatch="ACCEPT" onMismatch="DENY"/>
|
||||
<PatternLayout pattern="%-d{yyyy-MM-dd HH:mm:ss} [%t] [%p] %c{1.} - %m%n"/>
|
||||
<!-- Trigger after exceeding 1day or 50MB -->
|
||||
<Policies>
|
||||
<SizeBasedTriggeringPolicy size="50MB"/>
|
||||
<TimeBasedTriggeringPolicy interval="1" modulate="true"/>
|
||||
</Policies>
|
||||
<!-- Keep 5 files per day & auto delete after over 2GB or 100 files -->
|
||||
<DefaultRolloverStrategy max="5">
|
||||
<Delete basePath="${LOG_PATH}" maxDepth="2">
|
||||
<IfFileName glob="*/*.log"/>
|
||||
<!-- Limit log amount & size -->
|
||||
<IfAny>
|
||||
<IfAccumulatedFileSize exceeds="2GB"/>
|
||||
<IfAccumulatedFileCount exceeds="100"/>
|
||||
</IfAny>
|
||||
</Delete>
|
||||
</DefaultRolloverStrategy>
|
||||
</RollingRandomAccessFile>
|
||||
|
||||
<!-- Separate & compress audit log, buffer size is 512KB -->
|
||||
<RollingRandomAccessFile name="audit" fileName="${LOG_PATH}/audit-${FILE_NAME}.log"
|
||||
filePattern="${LOG_PATH}/$${date:yyyy-MM}/audit-${FILE_NAME}-%d{yyyy-MM-dd-HH}-%i.gz"
|
||||
bufferSize="524288" immediateFlush="false">
|
||||
<ThresholdFilter level="TRACE" onMatch="ACCEPT" onMismatch="DENY"/>
|
||||
<!-- Use simple format for audit log to speed up -->
|
||||
<PatternLayout pattern="%-d{yyyy-MM-dd HH:mm:ss} - %m%n"/>
|
||||
<!-- Trigger after exceeding 1hour or 500MB -->
|
||||
<Policies>
|
||||
<SizeBasedTriggeringPolicy size="500MB"/>
|
||||
<TimeBasedTriggeringPolicy interval="1" modulate="true"/>
|
||||
</Policies>
|
||||
<!-- Keep 2 files per hour & auto delete [after 60 days] or [over 5GB or 500 files] -->
|
||||
<DefaultRolloverStrategy max="2">
|
||||
<Delete basePath="${LOG_PATH}" maxDepth="2">
|
||||
<IfFileName glob="*/*.gz"/>
|
||||
<IfLastModified age="60d"/>
|
||||
<IfAny>
|
||||
<IfAccumulatedFileSize exceeds="5GB"/>
|
||||
<IfAccumulatedFileCount exceeds="500"/>
|
||||
</IfAny>
|
||||
</Delete>
|
||||
</DefaultRolloverStrategy>
|
||||
</RollingRandomAccessFile>
|
||||
|
||||
<!-- Slow query log config -->
|
||||
<RollingRandomAccessFile name="slowQueryLog" fileName="${LOG_PATH}/slow_query.log"
|
||||
filePattern="${LOG_PATH}/$${date:yyyy-MM}/slow_query_log-%d{yyyy-MM-dd}-%i.log"
|
||||
immediateFlush="false">
|
||||
<ThresholdFilter level="TRACE" onMatch="ACCEPT" onMismatch="DENY"/>
|
||||
<PatternLayout pattern="%-d{yyyy-MM-dd HH:mm:ss} [%t] [%p] %c{1.} - %m%n"/>
|
||||
<!-- Trigger after exceeding 1day or 50MB -->
|
||||
<Policies>
|
||||
<SizeBasedTriggeringPolicy size="50MB"/>
|
||||
<TimeBasedTriggeringPolicy interval="1" modulate="true"/>
|
||||
</Policies>
|
||||
<!-- Keep 5 files per day & auto delete after over 2GB or 100 files -->
|
||||
<DefaultRolloverStrategy max="5">
|
||||
<Delete basePath="${LOG_PATH}" maxDepth="2">
|
||||
<IfFileName glob="*/*.log"/>
|
||||
<!-- Limit log amount & size -->
|
||||
<IfAny>
|
||||
<IfAccumulatedFileSize exceeds="2GB"/>
|
||||
<IfAccumulatedFileCount exceeds="100"/>
|
||||
</IfAny>
|
||||
</Delete>
|
||||
</DefaultRolloverStrategy>
|
||||
</RollingRandomAccessFile>
|
||||
</appenders>
|
||||
|
||||
<loggers>
|
||||
<root level="INFO">
|
||||
<appender-ref ref="file"/>
|
||||
</root>
|
||||
<logger name="org.apache.cassandra" level="INFO" additivity="false">
|
||||
<appender-ref ref="file"/>
|
||||
</logger>
|
||||
<logger name="org.apache.hadoop" level="INFO" additivity="false">
|
||||
<appender-ref ref="file"/>
|
||||
</logger>
|
||||
<logger name="org.apache.zookeeper" level="WARN" additivity="false">
|
||||
<appender-ref ref="file"/>
|
||||
</logger>
|
||||
<logger name="com.datastax.driver" level="WARN" additivity="false">
|
||||
<appender-ref ref="file"/>
|
||||
</logger>
|
||||
<logger name="com.alipay.sofa" level="WARN" additivity="false">
|
||||
<appender-ref ref="file"/>
|
||||
</logger>
|
||||
<logger name="io.netty" level="INFO" additivity="false">
|
||||
<appender-ref ref="file"/>
|
||||
</logger>
|
||||
<logger name="org.apache.commons" level="INFO" additivity="false">
|
||||
<appender-ref ref="file"/>
|
||||
</logger>
|
||||
<!-- Use mixed async way to output logs -->
|
||||
<AsyncLogger name="org.apache.hugegraph" level="INFO" additivity="false">
|
||||
<appender-ref ref="file"/>
|
||||
</AsyncLogger>
|
||||
<AsyncLogger name="org.apache.hugegraph.auth" level="INFO" additivity="false">
|
||||
<appender-ref ref="audit"/>
|
||||
</AsyncLogger>
|
||||
<AsyncLogger name="org.apache.hugegraph.api.filter.AuthenticationFilter" level="INFO" additivity="false">
|
||||
<appender-ref ref="audit"/>
|
||||
</AsyncLogger>
|
||||
<AsyncLogger name="org.apache.hugegraph.api.filter.AccessLogFilter" level="INFO" additivity="false">
|
||||
<appender-ref ref="slowQueryLog"/>
|
||||
</AsyncLogger>
|
||||
</loggers>
|
||||
</configuration>
|
||||
|
|
@ -1,30 +0,0 @@
|
|||
#
|
||||
# Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
# contributor license agreements. See the NOTICE file distributed with
|
||||
# this work for additional information regarding copyright ownership.
|
||||
# The ASF licenses this file to You 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.
|
||||
#
|
||||
hosts: [localhost]
|
||||
port: 8181
|
||||
serializer: {
|
||||
className: org.apache.tinkerpop.gremlin.driver.ser.GraphSONMessageSerializerV1d0,
|
||||
config: {
|
||||
serializeResultToString: false,
|
||||
# The duplication of HugeGraphIoRegistry is meant to fix a bug in the
|
||||
# 'org.apache.tinkerpop.gremlin.driver.Settings:from(Configuration)' method.
|
||||
ioRegistries: [
|
||||
org.apache.hugegraph.io.HugeGraphIoRegistry,
|
||||
org.apache.hugegraph.io.HugeGraphIoRegistry
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
@ -1,25 +0,0 @@
|
|||
#
|
||||
# Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
# contributor license agreements. See the NOTICE file distributed with
|
||||
# this work for additional information regarding copyright ownership.
|
||||
# The ASF licenses this file to You 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.
|
||||
#
|
||||
hosts: [localhost]
|
||||
port: 8181
|
||||
serializer: {
|
||||
className: org.apache.tinkerpop.gremlin.driver.ser.GraphSONMessageSerializerV1d0,
|
||||
config: {
|
||||
serializeResultToString: false,
|
||||
ioRegistries: [org.apache.hugegraph.io.HugeGraphIoRegistry]
|
||||
}
|
||||
}
|
||||
|
|
@ -1,28 +0,0 @@
|
|||
# bind url
|
||||
restserver.url=http://127.0.0.1:8081
|
||||
# gremlin server url, need to be consistent with host and port in gremlin-server.yaml
|
||||
gremlinserver.url=http://127.0.0.1:8181
|
||||
|
||||
graphs=./conf/graphs
|
||||
|
||||
# configuration of arthas
|
||||
arthas.telnet_port=8562
|
||||
arthas.http_port=8561
|
||||
arthas.ip=127.0.0.1
|
||||
arthas.disabled_commands=jad
|
||||
|
||||
# authentication configs
|
||||
# choose 'org.apache.hugegraph.auth.StandardAuthenticator' or
|
||||
# 'org.apache.hugegraph.auth.ConfigAuthenticator'
|
||||
#auth.authenticator=
|
||||
|
||||
# rpc server configs for multi graph-servers or raft-servers
|
||||
rpc.server_host=127.0.0.1
|
||||
rpc.server_port=8091
|
||||
|
||||
# lightweight load balancing (beta)
|
||||
server.id=server-1
|
||||
server.role=master
|
||||
|
||||
# slow query log
|
||||
log.slow_query_threshold=1000
|
||||
|
|
@ -1,19 +0,0 @@
|
|||
# auth config: org.apache.hugegraph.auth.HugeFactoryAuthProxy
|
||||
gremlin.graph=org.apache.hugegraph.HugeFactory
|
||||
|
||||
# cache config
|
||||
vertex.cache_type=l2
|
||||
edge.cache_type=l2
|
||||
|
||||
store=hugegraph
|
||||
backend=hstore
|
||||
serializer=binary
|
||||
|
||||
# pd config
|
||||
pd.peers=127.0.0.1:8686,127.0.0.1:8687,127.0.0.1:8688
|
||||
|
||||
# task config
|
||||
task.scheduler_type=local
|
||||
task.schedule_period=10
|
||||
task.retry=0
|
||||
task.wait_timeout=10
|
||||
|
|
@ -1,25 +0,0 @@
|
|||
#
|
||||
# Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
# contributor license agreements. See the NOTICE file distributed with
|
||||
# this work for additional information regarding copyright ownership.
|
||||
# The ASF licenses this file to You 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.
|
||||
#
|
||||
hosts: [localhost]
|
||||
port: 8182
|
||||
serializer: {
|
||||
className: org.apache.tinkerpop.gremlin.driver.ser.GraphSONMessageSerializerV1d0,
|
||||
config: {
|
||||
serializeResultToString: false,
|
||||
ioRegistries: [org.apache.hugegraph.io.HugeGraphIoRegistry]
|
||||
}
|
||||
}
|
||||
|
|
@ -1,127 +0,0 @@
|
|||
#
|
||||
# Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
# contributor license agreements. See the NOTICE file distributed with
|
||||
# this work for additional information regarding copyright ownership.
|
||||
# The ASF licenses this file to You 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.
|
||||
#
|
||||
# host and port of gremlin server, need to be consistent with host and port in rest-server.properties
|
||||
host: 127.0.0.1
|
||||
port: 8182
|
||||
|
||||
# timeout in ms of gremlin query
|
||||
evaluationTimeout: 30000
|
||||
|
||||
channelizer: org.apache.tinkerpop.gremlin.server.channel.WsAndHttpChannelizer
|
||||
# don't set graph at here, this happens after support for dynamically adding graph
|
||||
graphs: {
|
||||
}
|
||||
scriptEngines: {
|
||||
gremlin-groovy: {
|
||||
staticImports: [
|
||||
org.opencypher.gremlin.process.traversal.CustomPredicates.*',
|
||||
org.opencypher.gremlin.traversal.CustomFunctions.*
|
||||
],
|
||||
plugins: {
|
||||
org.apache.hugegraph.plugin.HugeGraphGremlinPlugin: {},
|
||||
org.apache.tinkerpop.gremlin.server.jsr223.GremlinServerGremlinPlugin: {},
|
||||
org.apache.tinkerpop.gremlin.jsr223.ImportGremlinPlugin: {
|
||||
classImports: [
|
||||
java.lang.Math,
|
||||
org.apache.hugegraph.backend.id.IdGenerator,
|
||||
org.apache.hugegraph.type.define.Directions,
|
||||
org.apache.hugegraph.type.define.NodeRole,
|
||||
org.apache.hugegraph.masterelection.GlobalMasterInfo,
|
||||
org.apache.hugegraph.util.DateUtil,
|
||||
org.apache.hugegraph.traversal.algorithm.CollectionPathsTraverser,
|
||||
org.apache.hugegraph.traversal.algorithm.CountTraverser,
|
||||
org.apache.hugegraph.traversal.algorithm.CustomizedCrosspointsTraverser,
|
||||
org.apache.hugegraph.traversal.algorithm.CustomizePathsTraverser,
|
||||
org.apache.hugegraph.traversal.algorithm.FusiformSimilarityTraverser,
|
||||
org.apache.hugegraph.traversal.algorithm.HugeTraverser,
|
||||
org.apache.hugegraph.traversal.algorithm.JaccardSimilarTraverser,
|
||||
org.apache.hugegraph.traversal.algorithm.KneighborTraverser,
|
||||
org.apache.hugegraph.traversal.algorithm.KoutTraverser,
|
||||
org.apache.hugegraph.traversal.algorithm.MultiNodeShortestPathTraverser,
|
||||
org.apache.hugegraph.traversal.algorithm.NeighborRankTraverser,
|
||||
org.apache.hugegraph.traversal.algorithm.PathsTraverser,
|
||||
org.apache.hugegraph.traversal.algorithm.PersonalRankTraverser,
|
||||
org.apache.hugegraph.traversal.algorithm.SameNeighborTraverser,
|
||||
org.apache.hugegraph.traversal.algorithm.ShortestPathTraverser,
|
||||
org.apache.hugegraph.traversal.algorithm.SingleSourceShortestPathTraverser,
|
||||
org.apache.hugegraph.traversal.algorithm.SubGraphTraverser,
|
||||
org.apache.hugegraph.traversal.algorithm.TemplatePathsTraverser,
|
||||
org.apache.hugegraph.traversal.algorithm.steps.EdgeStep,
|
||||
org.apache.hugegraph.traversal.algorithm.steps.RepeatEdgeStep,
|
||||
org.apache.hugegraph.traversal.algorithm.steps.WeightedEdgeStep,
|
||||
org.apache.hugegraph.traversal.optimize.ConditionP,
|
||||
org.apache.hugegraph.traversal.optimize.Text,
|
||||
org.apache.hugegraph.traversal.optimize.TraversalUtil,
|
||||
org.opencypher.gremlin.traversal.CustomFunctions,
|
||||
org.opencypher.gremlin.traversal.CustomPredicate
|
||||
],
|
||||
methodImports: [
|
||||
java.lang.Math#*,
|
||||
org.opencypher.gremlin.traversal.CustomPredicate#*,
|
||||
org.opencypher.gremlin.traversal.CustomFunctions#*
|
||||
]
|
||||
},
|
||||
org.apache.tinkerpop.gremlin.jsr223.ScriptFileGremlinPlugin: {
|
||||
files: [scripts/empty-sample.groovy]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
serializers:
|
||||
- {className: org.apache.tinkerpop.gremlin.driver.ser.GraphBinaryMessageSerializerV1,
|
||||
config: {
|
||||
serializeResultToString: false,
|
||||
ioRegistries: [org.apache.hugegraph.io.HugeGraphIoRegistry]
|
||||
}
|
||||
}
|
||||
- {className: org.apache.tinkerpop.gremlin.driver.ser.GraphSONMessageSerializerV1d0,
|
||||
config: {
|
||||
serializeResultToString: false,
|
||||
ioRegistries: [org.apache.hugegraph.io.HugeGraphIoRegistry]
|
||||
}
|
||||
}
|
||||
- {className: org.apache.tinkerpop.gremlin.driver.ser.GraphSONMessageSerializerV2d0,
|
||||
config: {
|
||||
serializeResultToString: false,
|
||||
ioRegistries: [org.apache.hugegraph.io.HugeGraphIoRegistry]
|
||||
}
|
||||
}
|
||||
- {className: org.apache.tinkerpop.gremlin.driver.ser.GraphSONMessageSerializerV3d0,
|
||||
config: {
|
||||
serializeResultToString: false,
|
||||
ioRegistries: [org.apache.hugegraph.io.HugeGraphIoRegistry]
|
||||
}
|
||||
}
|
||||
metrics: {
|
||||
consoleReporter: {enabled: false, interval: 180000},
|
||||
csvReporter: {enabled: false, interval: 180000, fileName: ./metrics/gremlin-server-metrics.csv},
|
||||
jmxReporter: {enabled: false},
|
||||
slf4jReporter: {enabled: false, interval: 180000},
|
||||
gangliaReporter: {enabled: false, interval: 180000, addressingMode: MULTICAST},
|
||||
graphiteReporter: {enabled: false, interval: 180000}
|
||||
}
|
||||
maxInitialLineLength: 4096
|
||||
maxHeaderSize: 8192
|
||||
maxChunkSize: 8192
|
||||
maxContentLength: 65536
|
||||
maxAccumulationBufferComponents: 1024
|
||||
resultIterationBatchSize: 64
|
||||
writeBufferLowWaterMark: 32768
|
||||
writeBufferHighWaterMark: 65536
|
||||
ssl: {
|
||||
enabled: false
|
||||
}
|
||||
|
|
@ -1,144 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
contributor license agreements. See the NOTICE file distributed with
|
||||
this work for additional information regarding copyright ownership.
|
||||
The ASF licenses this file to You 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.
|
||||
-->
|
||||
<!-- Config will be auto loaded every 60s -->
|
||||
<configuration status="error" monitorInterval="60">
|
||||
<properties>
|
||||
<property name="LOG_PATH">logs</property>
|
||||
<property name="FILE_NAME">hugegraph-server</property>
|
||||
</properties>
|
||||
|
||||
<appenders>
|
||||
<Console name="console" target="SYSTEM_OUT">
|
||||
<ThresholdFilter level="DEBUG" onMatch="ACCEPT" onMismatch="DENY"/>
|
||||
<PatternLayout pattern="%-d{yyyy-MM-dd HH:mm:ss} [%t] [%p] %c{1.} - %m%n"/>
|
||||
</Console>
|
||||
|
||||
<!-- Normal server log config -->
|
||||
<RollingRandomAccessFile name="file" fileName="${LOG_PATH}/${FILE_NAME}.log"
|
||||
filePattern="${LOG_PATH}/$${date:yyyy-MM}/${FILE_NAME}-%d{yyyy-MM-dd}-%i.log"
|
||||
immediateFlush="false">
|
||||
<ThresholdFilter level="TRACE" onMatch="ACCEPT" onMismatch="DENY"/>
|
||||
<PatternLayout pattern="%-d{yyyy-MM-dd HH:mm:ss} [%t] [%p] %c{1.} - %m%n"/>
|
||||
<!-- Trigger after exceeding 1day or 50MB -->
|
||||
<Policies>
|
||||
<SizeBasedTriggeringPolicy size="50MB"/>
|
||||
<TimeBasedTriggeringPolicy interval="1" modulate="true"/>
|
||||
</Policies>
|
||||
<!-- Keep 5 files per day & auto delete after over 2GB or 100 files -->
|
||||
<DefaultRolloverStrategy max="5">
|
||||
<Delete basePath="${LOG_PATH}" maxDepth="2">
|
||||
<IfFileName glob="*/*.log"/>
|
||||
<!-- Limit log amount & size -->
|
||||
<IfAny>
|
||||
<IfAccumulatedFileSize exceeds="2GB"/>
|
||||
<IfAccumulatedFileCount exceeds="100"/>
|
||||
</IfAny>
|
||||
</Delete>
|
||||
</DefaultRolloverStrategy>
|
||||
</RollingRandomAccessFile>
|
||||
|
||||
<!-- Separate & compress audit log, buffer size is 512KB -->
|
||||
<RollingRandomAccessFile name="audit" fileName="${LOG_PATH}/audit-${FILE_NAME}.log"
|
||||
filePattern="${LOG_PATH}/$${date:yyyy-MM}/audit-${FILE_NAME}-%d{yyyy-MM-dd-HH}-%i.gz"
|
||||
bufferSize="524288" immediateFlush="false">
|
||||
<ThresholdFilter level="TRACE" onMatch="ACCEPT" onMismatch="DENY"/>
|
||||
<!-- Use simple format for audit log to speed up -->
|
||||
<PatternLayout pattern="%-d{yyyy-MM-dd HH:mm:ss} - %m%n"/>
|
||||
<!-- Trigger after exceeding 1hour or 500MB -->
|
||||
<Policies>
|
||||
<SizeBasedTriggeringPolicy size="500MB"/>
|
||||
<TimeBasedTriggeringPolicy interval="1" modulate="true"/>
|
||||
</Policies>
|
||||
<!-- Keep 2 files per hour & auto delete [after 60 days] or [over 5GB or 500 files] -->
|
||||
<DefaultRolloverStrategy max="2">
|
||||
<Delete basePath="${LOG_PATH}" maxDepth="2">
|
||||
<IfFileName glob="*/*.gz"/>
|
||||
<IfLastModified age="60d"/>
|
||||
<IfAny>
|
||||
<IfAccumulatedFileSize exceeds="5GB"/>
|
||||
<IfAccumulatedFileCount exceeds="500"/>
|
||||
</IfAny>
|
||||
</Delete>
|
||||
</DefaultRolloverStrategy>
|
||||
</RollingRandomAccessFile>
|
||||
|
||||
<!-- Slow query log config -->
|
||||
<RollingRandomAccessFile name="slowQueryLog" fileName="${LOG_PATH}/slow_query.log"
|
||||
filePattern="${LOG_PATH}/$${date:yyyy-MM}/slow_query_log-%d{yyyy-MM-dd}-%i.log"
|
||||
immediateFlush="false">
|
||||
<ThresholdFilter level="TRACE" onMatch="ACCEPT" onMismatch="DENY"/>
|
||||
<PatternLayout pattern="%-d{yyyy-MM-dd HH:mm:ss} [%t] [%p] %c{1.} - %m%n"/>
|
||||
<!-- Trigger after exceeding 1day or 50MB -->
|
||||
<Policies>
|
||||
<SizeBasedTriggeringPolicy size="50MB"/>
|
||||
<TimeBasedTriggeringPolicy interval="1" modulate="true"/>
|
||||
</Policies>
|
||||
<!-- Keep 5 files per day & auto delete after over 2GB or 100 files -->
|
||||
<DefaultRolloverStrategy max="5">
|
||||
<Delete basePath="${LOG_PATH}" maxDepth="2">
|
||||
<IfFileName glob="*/*.log"/>
|
||||
<!-- Limit log amount & size -->
|
||||
<IfAny>
|
||||
<IfAccumulatedFileSize exceeds="2GB"/>
|
||||
<IfAccumulatedFileCount exceeds="100"/>
|
||||
</IfAny>
|
||||
</Delete>
|
||||
</DefaultRolloverStrategy>
|
||||
</RollingRandomAccessFile>
|
||||
</appenders>
|
||||
|
||||
<loggers>
|
||||
<root level="INFO">
|
||||
<appender-ref ref="file"/>
|
||||
</root>
|
||||
<logger name="org.apache.cassandra" level="INFO" additivity="false">
|
||||
<appender-ref ref="file"/>
|
||||
</logger>
|
||||
<logger name="org.apache.hadoop" level="INFO" additivity="false">
|
||||
<appender-ref ref="file"/>
|
||||
</logger>
|
||||
<logger name="org.apache.zookeeper" level="WARN" additivity="false">
|
||||
<appender-ref ref="file"/>
|
||||
</logger>
|
||||
<logger name="com.datastax.driver" level="WARN" additivity="false">
|
||||
<appender-ref ref="file"/>
|
||||
</logger>
|
||||
<logger name="com.alipay.sofa" level="WARN" additivity="false">
|
||||
<appender-ref ref="file"/>
|
||||
</logger>
|
||||
<logger name="io.netty" level="INFO" additivity="false">
|
||||
<appender-ref ref="file"/>
|
||||
</logger>
|
||||
<logger name="org.apache.commons" level="INFO" additivity="false">
|
||||
<appender-ref ref="file"/>
|
||||
</logger>
|
||||
<!-- Use mixed async way to output logs -->
|
||||
<AsyncLogger name="org.apache.hugegraph" level="INFO" additivity="false">
|
||||
<appender-ref ref="file"/>
|
||||
</AsyncLogger>
|
||||
<AsyncLogger name="org.apache.hugegraph.auth" level="INFO" additivity="false">
|
||||
<appender-ref ref="audit"/>
|
||||
</AsyncLogger>
|
||||
<AsyncLogger name="org.apache.hugegraph.api.filter.AuthenticationFilter" level="INFO" additivity="false">
|
||||
<appender-ref ref="audit"/>
|
||||
</AsyncLogger>
|
||||
<AsyncLogger name="org.apache.hugegraph.api.filter.AccessLogFilter" level="INFO" additivity="false">
|
||||
<appender-ref ref="slowQueryLog"/>
|
||||
</AsyncLogger>
|
||||
</loggers>
|
||||
</configuration>
|
||||
|
|
@ -1,30 +0,0 @@
|
|||
#
|
||||
# Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
# contributor license agreements. See the NOTICE file distributed with
|
||||
# this work for additional information regarding copyright ownership.
|
||||
# The ASF licenses this file to You 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.
|
||||
#
|
||||
hosts: [localhost]
|
||||
port: 8182
|
||||
serializer: {
|
||||
className: org.apache.tinkerpop.gremlin.driver.ser.GraphSONMessageSerializerV1d0,
|
||||
config: {
|
||||
serializeResultToString: false,
|
||||
# The duplication of HugeGraphIoRegistry is meant to fix a bug in the
|
||||
# 'org.apache.tinkerpop.gremlin.driver.Settings:from(Configuration)' method.
|
||||
ioRegistries: [
|
||||
org.apache.hugegraph.io.HugeGraphIoRegistry,
|
||||
org.apache.hugegraph.io.HugeGraphIoRegistry
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
@ -1,25 +0,0 @@
|
|||
#
|
||||
# Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
# contributor license agreements. See the NOTICE file distributed with
|
||||
# this work for additional information regarding copyright ownership.
|
||||
# The ASF licenses this file to You 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.
|
||||
#
|
||||
hosts: [localhost]
|
||||
port: 8182
|
||||
serializer: {
|
||||
className: org.apache.tinkerpop.gremlin.driver.ser.GraphSONMessageSerializerV1d0,
|
||||
config: {
|
||||
serializeResultToString: false,
|
||||
ioRegistries: [org.apache.hugegraph.io.HugeGraphIoRegistry]
|
||||
}
|
||||
}
|
||||
|
|
@ -1,26 +0,0 @@
|
|||
# bind url
|
||||
restserver.url=http://127.0.0.1:8082
|
||||
# gremlin server url, need to be consistent with host and port in gremlin-server.yaml
|
||||
gremlinserver.url=http://127.0.0.1:8182
|
||||
|
||||
graphs=./conf/graphs
|
||||
|
||||
# configuration of arthas
|
||||
arthas.telnet_port=8572
|
||||
arthas.http_port=8571
|
||||
arthas.ip=127.0.0.1
|
||||
arthas.disabled_commands=jad
|
||||
|
||||
# authentication configs
|
||||
# choose 'org.apache.hugegraph.auth.StandardAuthenticator' or
|
||||
# 'org.apache.hugegraph.auth.ConfigAuthenticator'
|
||||
#auth.authenticator=
|
||||
|
||||
# rpc server configs for multi graph-servers or raft-servers
|
||||
rpc.server_host=127.0.0.1
|
||||
rpc.server_port=8092
|
||||
#rpc.server_timeout=30
|
||||
|
||||
# lightweight load balancing (beta)
|
||||
server.id=server-2
|
||||
server.role=worker
|
||||
|
|
@ -1,19 +0,0 @@
|
|||
# auth config: org.apache.hugegraph.auth.HugeFactoryAuthProxy
|
||||
gremlin.graph=org.apache.hugegraph.HugeFactory
|
||||
|
||||
# cache config
|
||||
vertex.cache_type=l2
|
||||
edge.cache_type=l2
|
||||
|
||||
store=hugegraph
|
||||
backend=hstore
|
||||
serializer=binary
|
||||
|
||||
# pd config
|
||||
pd.peers=127.0.0.1:8686,127.0.0.1:8687,127.0.0.1:8688
|
||||
|
||||
# task config
|
||||
task.scheduler_type=local
|
||||
task.schedule_period=10
|
||||
task.retry=0
|
||||
task.wait_timeout=10
|
||||
|
|
@ -1,25 +0,0 @@
|
|||
#
|
||||
# Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
# contributor license agreements. See the NOTICE file distributed with
|
||||
# this work for additional information regarding copyright ownership.
|
||||
# The ASF licenses this file to You 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.
|
||||
#
|
||||
hosts: [localhost]
|
||||
port: 8183
|
||||
serializer: {
|
||||
className: org.apache.tinkerpop.gremlin.driver.ser.GraphSONMessageSerializerV1d0,
|
||||
config: {
|
||||
serializeResultToString: false,
|
||||
ioRegistries: [org.apache.hugegraph.io.HugeGraphIoRegistry]
|
||||
}
|
||||
}
|
||||
|
|
@ -1,127 +0,0 @@
|
|||
#
|
||||
# Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
# contributor license agreements. See the NOTICE file distributed with
|
||||
# this work for additional information regarding copyright ownership.
|
||||
# The ASF licenses this file to You 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.
|
||||
#
|
||||
# host and port of gremlin server, need to be consistent with host and port in rest-server.properties
|
||||
host: 127.0.0.1
|
||||
port: 8183
|
||||
|
||||
# timeout in ms of gremlin query
|
||||
evaluationTimeout: 30000
|
||||
|
||||
channelizer: org.apache.tinkerpop.gremlin.server.channel.WsAndHttpChannelizer
|
||||
# don't set graph at here, this happens after support for dynamically adding graph
|
||||
graphs: {
|
||||
}
|
||||
scriptEngines: {
|
||||
gremlin-groovy: {
|
||||
staticImports: [
|
||||
org.opencypher.gremlin.process.traversal.CustomPredicates.*',
|
||||
org.opencypher.gremlin.traversal.CustomFunctions.*
|
||||
],
|
||||
plugins: {
|
||||
org.apache.hugegraph.plugin.HugeGraphGremlinPlugin: {},
|
||||
org.apache.tinkerpop.gremlin.server.jsr223.GremlinServerGremlinPlugin: {},
|
||||
org.apache.tinkerpop.gremlin.jsr223.ImportGremlinPlugin: {
|
||||
classImports: [
|
||||
java.lang.Math,
|
||||
org.apache.hugegraph.backend.id.IdGenerator,
|
||||
org.apache.hugegraph.type.define.Directions,
|
||||
org.apache.hugegraph.type.define.NodeRole,
|
||||
org.apache.hugegraph.masterelection.GlobalMasterInfo,
|
||||
org.apache.hugegraph.util.DateUtil,
|
||||
org.apache.hugegraph.traversal.algorithm.CollectionPathsTraverser,
|
||||
org.apache.hugegraph.traversal.algorithm.CountTraverser,
|
||||
org.apache.hugegraph.traversal.algorithm.CustomizedCrosspointsTraverser,
|
||||
org.apache.hugegraph.traversal.algorithm.CustomizePathsTraverser,
|
||||
org.apache.hugegraph.traversal.algorithm.FusiformSimilarityTraverser,
|
||||
org.apache.hugegraph.traversal.algorithm.HugeTraverser,
|
||||
org.apache.hugegraph.traversal.algorithm.JaccardSimilarTraverser,
|
||||
org.apache.hugegraph.traversal.algorithm.KneighborTraverser,
|
||||
org.apache.hugegraph.traversal.algorithm.KoutTraverser,
|
||||
org.apache.hugegraph.traversal.algorithm.MultiNodeShortestPathTraverser,
|
||||
org.apache.hugegraph.traversal.algorithm.NeighborRankTraverser,
|
||||
org.apache.hugegraph.traversal.algorithm.PathsTraverser,
|
||||
org.apache.hugegraph.traversal.algorithm.PersonalRankTraverser,
|
||||
org.apache.hugegraph.traversal.algorithm.SameNeighborTraverser,
|
||||
org.apache.hugegraph.traversal.algorithm.ShortestPathTraverser,
|
||||
org.apache.hugegraph.traversal.algorithm.SingleSourceShortestPathTraverser,
|
||||
org.apache.hugegraph.traversal.algorithm.SubGraphTraverser,
|
||||
org.apache.hugegraph.traversal.algorithm.TemplatePathsTraverser,
|
||||
org.apache.hugegraph.traversal.algorithm.steps.EdgeStep,
|
||||
org.apache.hugegraph.traversal.algorithm.steps.RepeatEdgeStep,
|
||||
org.apache.hugegraph.traversal.algorithm.steps.WeightedEdgeStep,
|
||||
org.apache.hugegraph.traversal.optimize.ConditionP,
|
||||
org.apache.hugegraph.traversal.optimize.Text,
|
||||
org.apache.hugegraph.traversal.optimize.TraversalUtil,
|
||||
org.opencypher.gremlin.traversal.CustomFunctions,
|
||||
org.opencypher.gremlin.traversal.CustomPredicate
|
||||
],
|
||||
methodImports: [
|
||||
java.lang.Math#*,
|
||||
org.opencypher.gremlin.traversal.CustomPredicate#*,
|
||||
org.opencypher.gremlin.traversal.CustomFunctions#*
|
||||
]
|
||||
},
|
||||
org.apache.tinkerpop.gremlin.jsr223.ScriptFileGremlinPlugin: {
|
||||
files: [scripts/empty-sample.groovy]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
serializers:
|
||||
- {className: org.apache.tinkerpop.gremlin.driver.ser.GraphBinaryMessageSerializerV1,
|
||||
config: {
|
||||
serializeResultToString: false,
|
||||
ioRegistries: [org.apache.hugegraph.io.HugeGraphIoRegistry]
|
||||
}
|
||||
}
|
||||
- {className: org.apache.tinkerpop.gremlin.driver.ser.GraphSONMessageSerializerV1d0,
|
||||
config: {
|
||||
serializeResultToString: false,
|
||||
ioRegistries: [org.apache.hugegraph.io.HugeGraphIoRegistry]
|
||||
}
|
||||
}
|
||||
- {className: org.apache.tinkerpop.gremlin.driver.ser.GraphSONMessageSerializerV2d0,
|
||||
config: {
|
||||
serializeResultToString: false,
|
||||
ioRegistries: [org.apache.hugegraph.io.HugeGraphIoRegistry]
|
||||
}
|
||||
}
|
||||
- {className: org.apache.tinkerpop.gremlin.driver.ser.GraphSONMessageSerializerV3d0,
|
||||
config: {
|
||||
serializeResultToString: false,
|
||||
ioRegistries: [org.apache.hugegraph.io.HugeGraphIoRegistry]
|
||||
}
|
||||
}
|
||||
metrics: {
|
||||
consoleReporter: {enabled: false, interval: 180000},
|
||||
csvReporter: {enabled: false, interval: 180000, fileName: ./metrics/gremlin-server-metrics.csv},
|
||||
jmxReporter: {enabled: false},
|
||||
slf4jReporter: {enabled: false, interval: 180000},
|
||||
gangliaReporter: {enabled: false, interval: 180000, addressingMode: MULTICAST},
|
||||
graphiteReporter: {enabled: false, interval: 180000}
|
||||
}
|
||||
maxInitialLineLength: 4096
|
||||
maxHeaderSize: 8192
|
||||
maxChunkSize: 8192
|
||||
maxContentLength: 65536
|
||||
maxAccumulationBufferComponents: 1024
|
||||
resultIterationBatchSize: 64
|
||||
writeBufferLowWaterMark: 32768
|
||||
writeBufferHighWaterMark: 65536
|
||||
ssl: {
|
||||
enabled: false
|
||||
}
|
||||
|
|
@ -1,144 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
contributor license agreements. See the NOTICE file distributed with
|
||||
this work for additional information regarding copyright ownership.
|
||||
The ASF licenses this file to You 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.
|
||||
-->
|
||||
<!-- Config will be auto loaded every 60s -->
|
||||
<configuration status="error" monitorInterval="60">
|
||||
<properties>
|
||||
<property name="LOG_PATH">logs</property>
|
||||
<property name="FILE_NAME">hugegraph-server</property>
|
||||
</properties>
|
||||
|
||||
<appenders>
|
||||
<Console name="console" target="SYSTEM_OUT">
|
||||
<ThresholdFilter level="DEBUG" onMatch="ACCEPT" onMismatch="DENY"/>
|
||||
<PatternLayout pattern="%-d{yyyy-MM-dd HH:mm:ss} [%t] [%p] %c{1.} - %m%n"/>
|
||||
</Console>
|
||||
|
||||
<!-- Normal server log config -->
|
||||
<RollingRandomAccessFile name="file" fileName="${LOG_PATH}/${FILE_NAME}.log"
|
||||
filePattern="${LOG_PATH}/$${date:yyyy-MM}/${FILE_NAME}-%d{yyyy-MM-dd}-%i.log"
|
||||
immediateFlush="false">
|
||||
<ThresholdFilter level="TRACE" onMatch="ACCEPT" onMismatch="DENY"/>
|
||||
<PatternLayout pattern="%-d{yyyy-MM-dd HH:mm:ss} [%t] [%p] %c{1.} - %m%n"/>
|
||||
<!-- Trigger after exceeding 1day or 50MB -->
|
||||
<Policies>
|
||||
<SizeBasedTriggeringPolicy size="50MB"/>
|
||||
<TimeBasedTriggeringPolicy interval="1" modulate="true"/>
|
||||
</Policies>
|
||||
<!-- Keep 5 files per day & auto delete after over 2GB or 100 files -->
|
||||
<DefaultRolloverStrategy max="5">
|
||||
<Delete basePath="${LOG_PATH}" maxDepth="2">
|
||||
<IfFileName glob="*/*.log"/>
|
||||
<!-- Limit log amount & size -->
|
||||
<IfAny>
|
||||
<IfAccumulatedFileSize exceeds="2GB"/>
|
||||
<IfAccumulatedFileCount exceeds="100"/>
|
||||
</IfAny>
|
||||
</Delete>
|
||||
</DefaultRolloverStrategy>
|
||||
</RollingRandomAccessFile>
|
||||
|
||||
<!-- Separate & compress audit log, buffer size is 512KB -->
|
||||
<RollingRandomAccessFile name="audit" fileName="${LOG_PATH}/audit-${FILE_NAME}.log"
|
||||
filePattern="${LOG_PATH}/$${date:yyyy-MM}/audit-${FILE_NAME}-%d{yyyy-MM-dd-HH}-%i.gz"
|
||||
bufferSize="524288" immediateFlush="false">
|
||||
<ThresholdFilter level="TRACE" onMatch="ACCEPT" onMismatch="DENY"/>
|
||||
<!-- Use simple format for audit log to speed up -->
|
||||
<PatternLayout pattern="%-d{yyyy-MM-dd HH:mm:ss} - %m%n"/>
|
||||
<!-- Trigger after exceeding 1hour or 500MB -->
|
||||
<Policies>
|
||||
<SizeBasedTriggeringPolicy size="500MB"/>
|
||||
<TimeBasedTriggeringPolicy interval="1" modulate="true"/>
|
||||
</Policies>
|
||||
<!-- Keep 2 files per hour & auto delete [after 60 days] or [over 5GB or 500 files] -->
|
||||
<DefaultRolloverStrategy max="2">
|
||||
<Delete basePath="${LOG_PATH}" maxDepth="2">
|
||||
<IfFileName glob="*/*.gz"/>
|
||||
<IfLastModified age="60d"/>
|
||||
<IfAny>
|
||||
<IfAccumulatedFileSize exceeds="5GB"/>
|
||||
<IfAccumulatedFileCount exceeds="500"/>
|
||||
</IfAny>
|
||||
</Delete>
|
||||
</DefaultRolloverStrategy>
|
||||
</RollingRandomAccessFile>
|
||||
|
||||
<!-- Slow query log config -->
|
||||
<RollingRandomAccessFile name="slowQueryLog" fileName="${LOG_PATH}/slow_query.log"
|
||||
filePattern="${LOG_PATH}/$${date:yyyy-MM}/slow_query_log-%d{yyyy-MM-dd}-%i.log"
|
||||
immediateFlush="false">
|
||||
<ThresholdFilter level="TRACE" onMatch="ACCEPT" onMismatch="DENY"/>
|
||||
<PatternLayout pattern="%-d{yyyy-MM-dd HH:mm:ss} [%t] [%p] %c{1.} - %m%n"/>
|
||||
<!-- Trigger after exceeding 1day or 50MB -->
|
||||
<Policies>
|
||||
<SizeBasedTriggeringPolicy size="50MB"/>
|
||||
<TimeBasedTriggeringPolicy interval="1" modulate="true"/>
|
||||
</Policies>
|
||||
<!-- Keep 5 files per day & auto delete after over 2GB or 100 files -->
|
||||
<DefaultRolloverStrategy max="5">
|
||||
<Delete basePath="${LOG_PATH}" maxDepth="2">
|
||||
<IfFileName glob="*/*.log"/>
|
||||
<!-- Limit log amount & size -->
|
||||
<IfAny>
|
||||
<IfAccumulatedFileSize exceeds="2GB"/>
|
||||
<IfAccumulatedFileCount exceeds="100"/>
|
||||
</IfAny>
|
||||
</Delete>
|
||||
</DefaultRolloverStrategy>
|
||||
</RollingRandomAccessFile>
|
||||
</appenders>
|
||||
|
||||
<loggers>
|
||||
<root level="INFO">
|
||||
<appender-ref ref="file"/>
|
||||
</root>
|
||||
<logger name="org.apache.cassandra" level="INFO" additivity="false">
|
||||
<appender-ref ref="file"/>
|
||||
</logger>
|
||||
<logger name="org.apache.hadoop" level="INFO" additivity="false">
|
||||
<appender-ref ref="file"/>
|
||||
</logger>
|
||||
<logger name="org.apache.zookeeper" level="WARN" additivity="false">
|
||||
<appender-ref ref="file"/>
|
||||
</logger>
|
||||
<logger name="com.datastax.driver" level="WARN" additivity="false">
|
||||
<appender-ref ref="file"/>
|
||||
</logger>
|
||||
<logger name="com.alipay.sofa" level="WARN" additivity="false">
|
||||
<appender-ref ref="file"/>
|
||||
</logger>
|
||||
<logger name="io.netty" level="INFO" additivity="false">
|
||||
<appender-ref ref="file"/>
|
||||
</logger>
|
||||
<logger name="org.apache.commons" level="INFO" additivity="false">
|
||||
<appender-ref ref="file"/>
|
||||
</logger>
|
||||
<!-- Use mixed async way to output logs -->
|
||||
<AsyncLogger name="org.apache.hugegraph" level="INFO" additivity="false">
|
||||
<appender-ref ref="file"/>
|
||||
</AsyncLogger>
|
||||
<AsyncLogger name="org.apache.hugegraph.auth" level="INFO" additivity="false">
|
||||
<appender-ref ref="audit"/>
|
||||
</AsyncLogger>
|
||||
<AsyncLogger name="org.apache.hugegraph.api.filter.AuthenticationFilter" level="INFO" additivity="false">
|
||||
<appender-ref ref="audit"/>
|
||||
</AsyncLogger>
|
||||
<AsyncLogger name="org.apache.hugegraph.api.filter.AccessLogFilter" level="INFO" additivity="false">
|
||||
<appender-ref ref="slowQueryLog"/>
|
||||
</AsyncLogger>
|
||||
</loggers>
|
||||
</configuration>
|
||||
|
|
@ -1,30 +0,0 @@
|
|||
#
|
||||
# Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
# contributor license agreements. See the NOTICE file distributed with
|
||||
# this work for additional information regarding copyright ownership.
|
||||
# The ASF licenses this file to You 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.
|
||||
#
|
||||
hosts: [localhost]
|
||||
port: 8183
|
||||
serializer: {
|
||||
className: org.apache.tinkerpop.gremlin.driver.ser.GraphSONMessageSerializerV1d0,
|
||||
config: {
|
||||
serializeResultToString: false,
|
||||
# The duplication of HugeGraphIoRegistry is meant to fix a bug in the
|
||||
# 'org.apache.tinkerpop.gremlin.driver.Settings:from(Configuration)' method.
|
||||
ioRegistries: [
|
||||
org.apache.hugegraph.io.HugeGraphIoRegistry,
|
||||
org.apache.hugegraph.io.HugeGraphIoRegistry
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
@ -1,25 +0,0 @@
|
|||
#
|
||||
# Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
# contributor license agreements. See the NOTICE file distributed with
|
||||
# this work for additional information regarding copyright ownership.
|
||||
# The ASF licenses this file to You 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.
|
||||
#
|
||||
hosts: [localhost]
|
||||
port: 8183
|
||||
serializer: {
|
||||
className: org.apache.tinkerpop.gremlin.driver.ser.GraphSONMessageSerializerV1d0,
|
||||
config: {
|
||||
serializeResultToString: false,
|
||||
ioRegistries: [org.apache.hugegraph.io.HugeGraphIoRegistry]
|
||||
}
|
||||
}
|
||||
|
|
@ -1,25 +0,0 @@
|
|||
# bind url
|
||||
restserver.url=http://127.0.0.1:8083
|
||||
# gremlin server url, need to be consistent with host and port in gremlin-server.yaml
|
||||
gremlinserver.url=http://127.0.0.1:8183
|
||||
|
||||
graphs=./conf/graphs
|
||||
|
||||
# configuration of arthas
|
||||
arthas.telnet_port=8582
|
||||
arthas.http_port=8581
|
||||
arthas.ip=127.0.0.1
|
||||
arthas.disabled_commands=jad
|
||||
|
||||
# authentication configs
|
||||
# choose 'org.apache.hugegraph.auth.StandardAuthenticator' or
|
||||
# 'org.apache.hugegraph.auth.ConfigAuthenticator'
|
||||
#auth.authenticator=
|
||||
|
||||
# rpc server configs for multi graph-servers or raft-servers
|
||||
rpc.server_host=127.0.0.1
|
||||
rpc.server_port=8093
|
||||
|
||||
# lightweight load balancing (beta)
|
||||
server.id=server-3
|
||||
server.role=worker
|
||||
|
|
@ -1,180 +0,0 @@
|
|||
#
|
||||
# Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
# contributor license agreements. See the NOTICE file distributed with
|
||||
# this work for additional information regarding copyright ownership.
|
||||
# The ASF licenses this file to You 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.
|
||||
#
|
||||
|
||||
# TODO: reuse the configs for same type containers
|
||||
# User could modify the node nums and the port by themselves
|
||||
version: "3"
|
||||
|
||||
services:
|
||||
pd0:
|
||||
image: hugegraph/pd
|
||||
container_name: pd0
|
||||
hostname: pd0
|
||||
network_mode: host
|
||||
healthcheck:
|
||||
test: ["CMD", "curl", "-f", "http://localhost:8620"]
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 3
|
||||
volumes:
|
||||
- ./configs/application-pd0.yml:/hugegraph-pd/conf/application.yml
|
||||
|
||||
pd1:
|
||||
image: hugegraph/pd
|
||||
container_name: pd1
|
||||
hostname: pd1
|
||||
network_mode: host
|
||||
healthcheck:
|
||||
test: ["CMD", "curl", "-f", "http://localhost:8621"]
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 3
|
||||
volumes:
|
||||
- ./configs/application-pd1.yml:/hugegraph-pd/conf/application.yml
|
||||
|
||||
pd2:
|
||||
image: hugegraph/pd
|
||||
container_name: pd2
|
||||
hostname: pd2
|
||||
network_mode: host
|
||||
healthcheck:
|
||||
test: ["CMD", "curl", "-f", "http://localhost:8622"]
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 3
|
||||
volumes:
|
||||
- ./configs/application-pd2.yml:/hugegraph-pd/conf/application.yml
|
||||
|
||||
store0:
|
||||
image: hugegraph/store
|
||||
container_name: store0
|
||||
hostname: store0
|
||||
network_mode: host
|
||||
depends_on:
|
||||
pd0:
|
||||
condition: service_healthy
|
||||
pd1:
|
||||
condition: service_healthy
|
||||
pd2:
|
||||
condition: service_healthy
|
||||
healthcheck:
|
||||
test: ["CMD", "curl", "-f", "http://localhost:8520"]
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 3
|
||||
volumes:
|
||||
- ./configs/application-store0.yml:/hugegraph-store/conf/application.yml
|
||||
|
||||
store1:
|
||||
image: hugegraph/store
|
||||
container_name: store1
|
||||
hostname: store1
|
||||
network_mode: host
|
||||
depends_on:
|
||||
pd0:
|
||||
condition: service_healthy
|
||||
pd1:
|
||||
condition: service_healthy
|
||||
pd2:
|
||||
condition: service_healthy
|
||||
healthcheck:
|
||||
test: ["CMD", "curl", "-f", "http://localhost:8521"]
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 3
|
||||
volumes:
|
||||
- ./configs/application-store1.yml:/hugegraph-store/conf/application.yml
|
||||
|
||||
store2:
|
||||
image: hugegraph/store
|
||||
container_name: store2
|
||||
hostname: store2
|
||||
network_mode: host
|
||||
depends_on:
|
||||
pd0:
|
||||
condition: service_healthy
|
||||
pd1:
|
||||
condition: service_healthy
|
||||
pd2:
|
||||
condition: service_healthy
|
||||
healthcheck:
|
||||
test: ["CMD", "curl", "-f", "http://localhost:8522"]
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 3
|
||||
volumes:
|
||||
- ./configs/application-store2.yml:/hugegraph-store/conf/application.yml
|
||||
|
||||
server1:
|
||||
image: hugegraph/server
|
||||
container_name: server1
|
||||
hostname: server1
|
||||
network_mode: host
|
||||
depends_on:
|
||||
store0:
|
||||
condition: service_healthy
|
||||
store1:
|
||||
condition: service_healthy
|
||||
store2:
|
||||
condition: service_healthy
|
||||
healthcheck:
|
||||
test: ["CMD", "curl", "-f", "http://localhost:8081"]
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 3
|
||||
volumes:
|
||||
- ./configs/server1-conf:/hugegraph-server/conf
|
||||
|
||||
server2:
|
||||
image: hugegraph/server
|
||||
container_name: server2
|
||||
hostname: server2
|
||||
network_mode: host
|
||||
depends_on:
|
||||
store0:
|
||||
condition: service_healthy
|
||||
store1:
|
||||
condition: service_healthy
|
||||
store2:
|
||||
condition: service_healthy
|
||||
healthcheck:
|
||||
test: ["CMD", "curl", "-f", "http://localhost:8082"]
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 3
|
||||
volumes:
|
||||
- ./configs/server2-conf:/hugegraph-server/conf
|
||||
|
||||
server3:
|
||||
image: hugegraph/server
|
||||
container_name: server3
|
||||
hostname: server3
|
||||
network_mode: host
|
||||
depends_on:
|
||||
store0:
|
||||
condition: service_healthy
|
||||
store1:
|
||||
condition: service_healthy
|
||||
store2:
|
||||
condition: service_healthy
|
||||
healthcheck:
|
||||
test: ["CMD", "curl", "-f", "http://localhost:8083"]
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 3
|
||||
volumes:
|
||||
- ./configs/server3-conf:/hugegraph-server/conf
|
||||
|
|
@ -1,58 +0,0 @@
|
|||
#
|
||||
# Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
# contributor license agreements. See the NOTICE file distributed with
|
||||
# this work for additional information regarding copyright ownership.
|
||||
# The ASF licenses this file to You 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.
|
||||
#
|
||||
|
||||
version: "3"
|
||||
|
||||
services:
|
||||
pd:
|
||||
image: hugegraph/pd
|
||||
container_name: pd
|
||||
hostname: pd
|
||||
network_mode: host
|
||||
healthcheck:
|
||||
test: ["CMD", "curl", "-f", "http://localhost:8620"]
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 3
|
||||
|
||||
store:
|
||||
image: hugegraph/store
|
||||
container_name: store
|
||||
hostname: store
|
||||
network_mode: host
|
||||
depends_on:
|
||||
pd:
|
||||
condition: service_healthy
|
||||
healthcheck:
|
||||
test: ["CMD", "curl", "-f", "http://localhost:8520"]
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 3
|
||||
|
||||
server:
|
||||
image: hugegraph/server
|
||||
container_name: server
|
||||
hostname: server
|
||||
network_mode: host
|
||||
depends_on:
|
||||
store:
|
||||
condition: service_healthy
|
||||
healthcheck:
|
||||
test: ["CMD", "curl", "-f", "http://localhost:8080"]
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 3
|
||||
|
|
@ -1,66 +0,0 @@
|
|||
# hugegraph-commons
|
||||
|
||||
[](https://www.apache.org/licenses/LICENSE-2.0.html)
|
||||
[](https://codecov.io/gh/hugegraph/hugegraph-common)
|
||||
[](https://mvnrepository.com/artifact/org.apache.hugegraph/hugegraph-common)
|
||||
[](https://github.com/apache/incubator-hugegraph-commons/actions/workflows/codeql-analysis.yml)
|
||||
[](https://github.com/apache/incubator-hugegraph-commons/actions/workflows/ci.yml)
|
||||
|
||||
|
||||
hugegraph-commons is a common module for [HugeGraph](https://github.com/apache/hugegraph) and its peripheral components.
|
||||
hugegraph-commons encapsulates locks, configurations, events, iterators, rest and some
|
||||
numeric or collection util classes to simplify the development of HugeGraph and its components.
|
||||
|
||||
## Components
|
||||
|
||||
- Lock: atomic lock, key lock, lock group and lock manger
|
||||
- Config: register and load config option with security check
|
||||
- Event: listening and notification, do something asynchronously
|
||||
- Iterator: some iterators with extra functions, map, filter, extend, etc.
|
||||
- Rest: RESTful client implemented on OkHttp, POST, PUT, GET and DELETE
|
||||
- Util: performance analyzer, version checker, numeric and Collection utils, log and exception utils, etc.
|
||||
- Rpc: rpc component for inner module communication, currently it's based on [Sofa-RPC](https://github.com/sofastack/sofa-rpc)
|
||||
|
||||
You could use import the dependencies in `maven` like this:
|
||||
|
||||
```xml
|
||||
<dependency>
|
||||
<groupId>org.apache.hugegraph</groupId>
|
||||
<artifactId>hugegraph-common</artifactId>
|
||||
<version>1.2.0</version>
|
||||
</dependency>
|
||||
```
|
||||
|
||||
## Learn More
|
||||
|
||||
The [doc page](https://hugegraph.apache.org/docs/) contains more information about hugegraph modules.
|
||||
|
||||
And here are links of other repositories:
|
||||
1. [hugegraph-server](https://github.com/apache/hugegraph) (graph's core component - OLTP server)
|
||||
2. [hugegraph-toolchain](https://github.com/apache/hugegraph-toolchain) (include loader/dashboard/tool/client)
|
||||
3. [hugegraph-computer](https://github.com/apache/hugegraph-computer) (graph processing system - OLAP)
|
||||
4. [hugegraph-website/doc](https://github.com/apache/hugegraph-doc) (include doc & website code)
|
||||
|
||||
|
||||
|
||||
## Contributing
|
||||
|
||||
- Welcome to contribute to HugeGraph, please see [How to Contribute](https://hugegraph.apache.org/docs/contribution-guidelines/contribute/) for more information.
|
||||
- Note: It's recommended to use [GitHub Desktop](https://desktop.github.com/) to greatly simplify the PR and commit process.
|
||||
- Thank you to all the people who already contributed to HugeGraph!
|
||||
|
||||
[](https://github.com/apache/incubator-hugegraph-commons/graphs/contributors)
|
||||
|
||||
## Licence
|
||||
|
||||
Same as HugeGraph, hugegraph-commons are also licensed under [Apache 2.0](./LICENSE) License.
|
||||
|
||||
### Contact Us
|
||||
|
||||
---
|
||||
|
||||
- [GitHub Issues](https://github.com/apache/incubator-hugegraph-commons/issues): Feedback on usage issues and functional requirements (quick response)
|
||||
- Feedback Email: [dev@hugegraph.apache.org](mailto:dev@hugegraph.apache.org) ([subscriber](https://hugegraph.apache.org/docs/contribution-guidelines/subscribe/) only)
|
||||
- WeChat public account: Apache HugeGraph, welcome to scan this QR code to follow us.
|
||||
|
||||
<img src="https://raw.githubusercontent.com/apache/incubator-hugegraph-doc/master/assets/images/wechat.png" alt="QR png" width="350"/>
|
||||
|
|
@ -1,23 +0,0 @@
|
|||
# hugegraph-common
|
||||
|
||||
[](https://www.apache.org/licenses/LICENSE-2.0.html)
|
||||
[](https://travis-ci.org/hugegraph/hugegraph-common)
|
||||
[](https://codecov.io/gh/hugegraph/hugegraph-common)
|
||||
[](https://mvnrepository.com/artifact/org.apache.hugegraph/hugegraph-common)
|
||||
|
||||
hugegraph-common is a common module for [HugeGraph](https://github.com/hugegraph/hugegraph) and its peripheral components.
|
||||
hugegraph-common encapsulates locks, configurations, events, iterators, rest and some
|
||||
numeric or collection util classes to simplify the development of HugeGraph and
|
||||
its components.
|
||||
|
||||
## Components
|
||||
|
||||
- Lock: atomic lock, key lock, lock group and lock manger
|
||||
- Config: register and load config option with security check
|
||||
- Event: listening and notification, do something asynchronously
|
||||
- Iterator: some iterators with extra functions, map, filter, extend, etc.
|
||||
- Rest: RESTful client implemented on Jersey, POST, PUT, GET and DELETE
|
||||
- Util: Performance analyzer, version checker, numeric and Collection utils, log and exception utils, etc.
|
||||
|
||||
## Licence
|
||||
The same as HugeGraph, hugegraph-common is also licensed under Apache 2.0 License.
|
||||
|
|
@ -1,23 +0,0 @@
|
|||
#!/usr/bin/env bash
|
||||
#
|
||||
# Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
# contributor license agreements. See the NOTICE file distributed with
|
||||
# this work for additional information regarding copyright ownership.
|
||||
# The ASF licenses this file to You 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.
|
||||
#
|
||||
|
||||
export MAVEN_HOME=/home/scmtools/buildkit/maven/apache-maven-3.3.9/
|
||||
export JAVA_HOME=/home/scmtools/buildkit/java/jdk1.8.0_25/
|
||||
export PATH=$JAVA_HOME/bin:$MAVEN_HOME/bin:$PATH
|
||||
|
||||
mvn clean test -Dtest=UnitTestSuite
|
||||
|
|
@ -1,302 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
contributor license agreements. See the NOTICE file distributed with
|
||||
this work for additional information regarding copyright ownership.
|
||||
The ASF licenses this file to You 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.
|
||||
-->
|
||||
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.apache.hugegraph</groupId>
|
||||
<artifactId>hugegraph-commons</artifactId>
|
||||
<version>${revision}</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
<artifactId>hugegraph-common</artifactId>
|
||||
<name>${project.artifactId}</name>
|
||||
<url>https://github.com/apache/incubator-hugegraph-commons/tree/master/hugegraph-common</url>
|
||||
<description>
|
||||
hugegraph-common is a common module for HugeGraph and its peripheral components.
|
||||
hugegraph-common encapsulates locks, configurations, events, iterators, rest and some
|
||||
numeric or collection util classes to simplify the development of HugeGraph and its
|
||||
components.
|
||||
</description>
|
||||
|
||||
<properties>
|
||||
<!-- Use parent params -->
|
||||
<lombok.version>1.18.8</lombok.version>
|
||||
<okhttp.version>4.10.0</okhttp.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<!-- Test -->
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>${junit.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mockito</groupId>
|
||||
<artifactId>mockito-core</artifactId>
|
||||
<version>${mockito.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- Logging -->
|
||||
<dependency>
|
||||
<groupId>org.apache.logging.log4j</groupId>
|
||||
<artifactId>log4j-api</artifactId>
|
||||
<version>${log4j2.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.logging.log4j</groupId>
|
||||
<artifactId>log4j-core</artifactId>
|
||||
<version>${log4j2.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.logging.log4j</groupId>
|
||||
<artifactId>log4j-slf4j-impl</artifactId>
|
||||
<version>${log4j2.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Utility -->
|
||||
<dependency>
|
||||
<groupId>org.glassfish</groupId>
|
||||
<artifactId>javax.json</artifactId>
|
||||
<version>${javax.json.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-configuration</groupId>
|
||||
<artifactId>commons-configuration</artifactId>
|
||||
<version>${commons.configuration.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-configuration2</artifactId>
|
||||
<version>${commons.configuration2.version}</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>commons-logging</artifactId>
|
||||
<groupId>commons-logging</groupId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
<version>${commons.lang3.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-beanutils</groupId>
|
||||
<artifactId>commons-beanutils</artifactId>
|
||||
<version>${commons.beanutils.version}</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>commons-logging</artifactId>
|
||||
<groupId>commons-logging</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-io</groupId>
|
||||
<artifactId>commons-io</artifactId>
|
||||
<version>${commons.io.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-collections</groupId>
|
||||
<artifactId>commons-collections</artifactId>
|
||||
<version>${commons.collections.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-codec</groupId>
|
||||
<artifactId>commons-codec</artifactId>
|
||||
<version>${commons.codec.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
<version>${guava.version}</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>jsr305</artifactId>
|
||||
<groupId>com.google.code.findbugs</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.google.code.findbugs</groupId>
|
||||
<artifactId>jsr305</artifactId>
|
||||
<version>${jsr305.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>joda-time</groupId>
|
||||
<artifactId>joda-time</artifactId>
|
||||
<version>2.10.8</version>
|
||||
</dependency>
|
||||
|
||||
<!-- javassist -->
|
||||
<dependency>
|
||||
<groupId>org.javassist</groupId>
|
||||
<artifactId>javassist</artifactId>
|
||||
<version>${javassist.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- jackson -->
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-annotations</artifactId>
|
||||
<version>${jackson.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-core</artifactId>
|
||||
<version>${jackson.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-databind</artifactId>
|
||||
<version>${jackson.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.module</groupId>
|
||||
<artifactId>jackson-module-jaxb-annotations</artifactId>
|
||||
<version>${jackson.version}</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>jakarta.xml.bind-api</artifactId>
|
||||
<groupId>jakarta.xml.bind</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.jaxrs</groupId>
|
||||
<artifactId>jackson-jaxrs-base</artifactId>
|
||||
<version>${jackson.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.jaxrs</groupId>
|
||||
<artifactId>jackson-jaxrs-json-provider</artifactId>
|
||||
<version>${jackson.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.sun.xml.bind</groupId>
|
||||
<artifactId>jaxb-impl</artifactId>
|
||||
<version>${sun.xml.version}</version>
|
||||
<scope>runtime</scope>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>jakarta.xml.bind-api</artifactId>
|
||||
<groupId>jakarta.xml.bind</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.squareup.okhttp3</groupId>
|
||||
<artifactId>okhttp</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.squareup.okhttp3</groupId>
|
||||
<artifactId>logging-interceptor</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<version>${lombok.version}</version>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.squareup.okhttp3</groupId>
|
||||
<artifactId>okhttp-bom</artifactId>
|
||||
<version>${okhttp.version}</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-jar-plugin</artifactId>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>org.jacoco</groupId>
|
||||
<artifactId>jacoco-maven-plugin</artifactId>
|
||||
<version>0.8.2</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>pre-unit-test</id>
|
||||
<goals>
|
||||
<goal>prepare-agent</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>post-unit-test</id>
|
||||
<phase>test</phase>
|
||||
<goals>
|
||||
<goal>report</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<outputDirectory>${project.parent.build.directory}</outputDirectory>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>apache-release</id>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-source-plugin</artifactId>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-javadoc-plugin</artifactId>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-gpg-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</profile>
|
||||
</profiles>
|
||||
</project>
|
||||
|
|
@ -1,82 +0,0 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with this
|
||||
* work for additional information regarding copyright ownership. The ASF
|
||||
* licenses this file to You under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.apache.hugegraph.concurrent;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import org.apache.hugegraph.util.Log;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
public class AtomicLock {
|
||||
|
||||
private static final Logger LOG = Log.logger(LockManager.class);
|
||||
|
||||
private String name;
|
||||
private AtomicReference<Thread> sign;
|
||||
|
||||
public AtomicLock(String name) {
|
||||
this.name = name;
|
||||
this.sign = new AtomicReference<>();
|
||||
}
|
||||
|
||||
public boolean tryLock() {
|
||||
Thread current = Thread.currentThread();
|
||||
return this.sign.compareAndSet(null, current);
|
||||
}
|
||||
|
||||
public void unlock() {
|
||||
if (this.sign.get() == null) {
|
||||
return;
|
||||
}
|
||||
Thread current = Thread.currentThread();
|
||||
if (!this.sign.compareAndSet(current, null)) {
|
||||
throw new RuntimeException(String.format(
|
||||
"Thread '%s' trying to unlock '%s' " +
|
||||
"which is held by other threads now.",
|
||||
current.getName(), this.name));
|
||||
}
|
||||
}
|
||||
|
||||
public boolean lock(int retries) {
|
||||
// The interval between retries is exponential growth, most wait
|
||||
// interval is 2^(retries-1)s. If retries=0, don't retry.
|
||||
if (retries < 0 || retries > 10) {
|
||||
throw new IllegalArgumentException(String.format(
|
||||
"Locking retry times should be in [0, 10], but got %d",
|
||||
retries));
|
||||
}
|
||||
|
||||
boolean isLocked = false;
|
||||
try {
|
||||
for (int i = 0; !(isLocked = this.tryLock()) && i < retries; i++) {
|
||||
Thread.sleep(1000 * (1L << i));
|
||||
}
|
||||
} catch (InterruptedException ignored) {
|
||||
LOG.info("Thread sleep is interrupted.");
|
||||
}
|
||||
return isLocked;
|
||||
}
|
||||
|
||||
public String name() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public void name(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,104 +0,0 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with this
|
||||
* work for additional information regarding copyright ownership. The ASF
|
||||
* licenses this file to You under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.apache.hugegraph.concurrent;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.locks.Condition;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
import org.apache.hugegraph.util.E;
|
||||
|
||||
public class BarrierEvent {
|
||||
|
||||
private final Lock lock = new ReentrantLock();
|
||||
private final Condition cond = lock.newCondition();
|
||||
private volatile boolean signaled = false;
|
||||
|
||||
/**
|
||||
* Wait forever until the signal is received.
|
||||
* @throws InterruptedException if interrupted.
|
||||
*/
|
||||
public void await() throws InterruptedException {
|
||||
this.lock.lock();
|
||||
try {
|
||||
while (!this.signaled) {
|
||||
this.cond.await();
|
||||
}
|
||||
} finally {
|
||||
this.lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Wait specified time in milliseconds.
|
||||
* @param timeout: the time in millisecond to wait.
|
||||
* @return true if signal is received, false if time out.
|
||||
* @throws InterruptedException if interrupted.
|
||||
*/
|
||||
public boolean await(long timeout) throws InterruptedException {
|
||||
E.checkArgument(timeout >= 0L,
|
||||
"The time must be >= 0, but got '%d'.",
|
||||
timeout);
|
||||
long deadline = System.currentTimeMillis() + timeout;
|
||||
this.lock.lock();
|
||||
try {
|
||||
while (!this.signaled) {
|
||||
timeout = deadline - System.currentTimeMillis();
|
||||
if (timeout > 0) {
|
||||
this.cond.await(timeout, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
if (System.currentTimeMillis() >= deadline) {
|
||||
return this.signaled;
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
this.lock.unlock();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
this.lock.lock();
|
||||
try {
|
||||
this.signaled = false;
|
||||
} finally {
|
||||
this.lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
public void signal() {
|
||||
this.lock.lock();
|
||||
try {
|
||||
this.signaled = true;
|
||||
this.cond.signal();
|
||||
} finally {
|
||||
this.lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
public void signalAll() {
|
||||
this.lock.lock();
|
||||
try {
|
||||
this.signaled = true;
|
||||
this.cond.signalAll();
|
||||
} finally {
|
||||
this.lock.unlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,144 +0,0 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with this
|
||||
* work for additional information regarding copyright ownership. The ASF
|
||||
* licenses this file to You under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.apache.hugegraph.concurrent;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
|
||||
import org.apache.hugegraph.util.E;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.util.concurrent.Striped;
|
||||
|
||||
/**
|
||||
* KeyLock provide an interface of segment lock
|
||||
*/
|
||||
public class KeyLock {
|
||||
|
||||
private Striped<Lock> locks;
|
||||
|
||||
public KeyLock() {
|
||||
// The default size is availableProcessors() * 4
|
||||
this(Runtime.getRuntime().availableProcessors() << 2);
|
||||
}
|
||||
|
||||
public KeyLock(int size) {
|
||||
this.locks = Striped.lock(size);
|
||||
}
|
||||
|
||||
private int indexOf(Lock lock) {
|
||||
for (int i = 0; i < this.locks.size(); i++) {
|
||||
if (this.locks.getAt(i) == lock) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Lock an object
|
||||
* @param key The object to lock
|
||||
* @return The lock(locked) of passed key
|
||||
*/
|
||||
public final Lock lock(Object key) {
|
||||
E.checkArgument(key != null, "Lock key can't be null");
|
||||
Lock lock = this.locks.get(key);
|
||||
lock.lock();
|
||||
return lock;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unlock an object
|
||||
* @param key The object to unlock
|
||||
*/
|
||||
public final void unlock(Object key) {
|
||||
E.checkArgument(key != null, "Unlock key can't be null");
|
||||
this.locks.get(key).unlock();
|
||||
}
|
||||
|
||||
/**
|
||||
* Lock a list of object with sorted order
|
||||
* @param keys The objects to lock
|
||||
* @return The locks(locked) of keys
|
||||
*/
|
||||
public final List<Lock> lockAll(Object... keys) {
|
||||
E.checkArgument(keys != null && keys.length > 0,
|
||||
"Lock keys can't be null or empty");
|
||||
List<Lock> locks = new ArrayList<>(keys.length);
|
||||
for (Object key : keys) {
|
||||
E.checkArgument(key != null, "Lock key can't be null");
|
||||
Lock lock = this.locks.get(key);
|
||||
locks.add(lock);
|
||||
}
|
||||
locks.sort((a, b) -> {
|
||||
int diff = a.hashCode() - b.hashCode();
|
||||
if (diff == 0 && a != b) {
|
||||
diff = this.indexOf(a) - this.indexOf(b);
|
||||
assert diff != 0;
|
||||
}
|
||||
return diff;
|
||||
});
|
||||
for (Lock lock : locks) {
|
||||
lock.lock();
|
||||
}
|
||||
return Collections.unmodifiableList(locks);
|
||||
}
|
||||
|
||||
/**
|
||||
* Lock two objects with sorted order
|
||||
* NOTE: This is to optimize the performance of lockAll(keys)
|
||||
* @param key1 The first object
|
||||
* @param key2 The second object
|
||||
* @return locks for the two objects
|
||||
*/
|
||||
public List<Lock> lockAll(Object key1, Object key2) {
|
||||
E.checkArgument(key1 != null, "Lock key can't be null");
|
||||
E.checkArgument(key2 != null, "Lock key can't be null");
|
||||
Lock lock1 = this.locks.get(key1);
|
||||
Lock lock2 = this.locks.get(key2);
|
||||
|
||||
int diff = lock1.hashCode() - lock2.hashCode();
|
||||
if (diff == 0 && lock1 != lock2) {
|
||||
diff = this.indexOf(lock1) - this.indexOf(lock2);
|
||||
assert diff != 0;
|
||||
}
|
||||
|
||||
List<Lock> locks = diff > 0 ?
|
||||
ImmutableList.of(lock2, lock1) :
|
||||
ImmutableList.of(lock1, lock2);
|
||||
|
||||
for (Lock lock : locks) {
|
||||
lock.lock();
|
||||
}
|
||||
|
||||
return locks;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unlock a list of object
|
||||
* @param locks The locks to unlock
|
||||
*/
|
||||
public final void unlockAll(List<Lock> locks) {
|
||||
E.checkArgument(locks != null, "Unlock locks can't be null");
|
||||
for (int i = locks.size(); i > 0; i--) {
|
||||
assert this.indexOf(locks.get(i - 1)) != -1;
|
||||
locks.get(i - 1).unlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,85 +0,0 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with this
|
||||
* work for additional information regarding copyright ownership. The ASF
|
||||
* licenses this file to You under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.apache.hugegraph.concurrent;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
import java.util.concurrent.locks.ReadWriteLock;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||
|
||||
public class LockGroup {
|
||||
|
||||
private final String name;
|
||||
private final Map<String, Object> locksMap;
|
||||
|
||||
public LockGroup(String lockGroup) {
|
||||
this.name = lockGroup;
|
||||
this.locksMap = new ConcurrentHashMap<>();
|
||||
}
|
||||
|
||||
public Lock lock(String lockName) {
|
||||
if (!this.locksMap.containsKey(lockName)) {
|
||||
this.locksMap.putIfAbsent(lockName, new ReentrantLock());
|
||||
}
|
||||
return (Lock) this.locksMap.get(lockName);
|
||||
}
|
||||
|
||||
public AtomicLock atomicLock(String lockName) {
|
||||
if (!this.locksMap.containsKey(lockName)) {
|
||||
this.locksMap.putIfAbsent(lockName, new AtomicLock(lockName));
|
||||
}
|
||||
return (AtomicLock) this.locksMap.get(lockName);
|
||||
}
|
||||
|
||||
public ReadWriteLock readWriteLock(String lockName) {
|
||||
if (!this.locksMap.containsKey(lockName)) {
|
||||
this.locksMap.putIfAbsent(lockName, new ReentrantReadWriteLock());
|
||||
}
|
||||
return (ReadWriteLock) this.locksMap.get(lockName);
|
||||
}
|
||||
|
||||
public KeyLock keyLock(String lockName) {
|
||||
if (!this.locksMap.containsKey(lockName)) {
|
||||
this.locksMap.putIfAbsent(lockName, new KeyLock());
|
||||
}
|
||||
return (KeyLock) this.locksMap.get(lockName);
|
||||
}
|
||||
|
||||
public KeyLock keyLock(String lockName, int size) {
|
||||
if (!this.locksMap.containsKey(lockName)) {
|
||||
this.locksMap.putIfAbsent(lockName, new KeyLock(size));
|
||||
}
|
||||
return (KeyLock) this.locksMap.get(lockName);
|
||||
}
|
||||
|
||||
public <K extends Comparable<K>> RowLock<K> rowLock(String lockName) {
|
||||
if (!this.locksMap.containsKey(lockName)) {
|
||||
this.locksMap.putIfAbsent(lockName, new RowLock<>());
|
||||
}
|
||||
Object value = this.locksMap.get(lockName);
|
||||
@SuppressWarnings("unchecked")
|
||||
RowLock<K> lock = (RowLock<K>) value;
|
||||
return lock;
|
||||
}
|
||||
|
||||
public String name() {
|
||||
return this.name;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,71 +0,0 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with this
|
||||
* work for additional information regarding copyright ownership. The ASF
|
||||
* licenses this file to You under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.apache.hugegraph.concurrent;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
public class LockManager {
|
||||
|
||||
private static final LockManager INSTANCE = new LockManager();
|
||||
|
||||
public static LockManager instance() {
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
private Map<String, LockGroup> lockGroupMap;
|
||||
|
||||
private LockManager() {
|
||||
this.lockGroupMap = new ConcurrentHashMap<>();
|
||||
}
|
||||
|
||||
public boolean exists(String group) {
|
||||
return this.lockGroupMap.containsKey(group);
|
||||
}
|
||||
|
||||
public LockGroup create(String group) {
|
||||
if (exists(group)) {
|
||||
throw new RuntimeException(String.format(
|
||||
"LockGroup '%s' already exists", group));
|
||||
}
|
||||
LockGroup lockGroup = new LockGroup(group);
|
||||
LockGroup previous = this.lockGroupMap.putIfAbsent(group, lockGroup);
|
||||
if (previous != null) {
|
||||
return previous;
|
||||
}
|
||||
return lockGroup;
|
||||
}
|
||||
|
||||
public LockGroup get(String group) {
|
||||
LockGroup lockGroup = this.lockGroupMap.get(group);
|
||||
if (lockGroup == null) {
|
||||
throw new RuntimeException(String.format(
|
||||
"LockGroup '%s' does not exists", group));
|
||||
}
|
||||
return lockGroup;
|
||||
}
|
||||
|
||||
public void destroy(String group) {
|
||||
if (this.exists(group)) {
|
||||
this.lockGroupMap.remove(group);
|
||||
} else {
|
||||
throw new RuntimeException(String.format(
|
||||
"LockGroup '%s' does not exists", group));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,78 +0,0 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with this
|
||||
* work for additional information regarding copyright ownership. The ASF
|
||||
* licenses this file to You under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.apache.hugegraph.concurrent;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ScheduledThreadPoolExecutor;
|
||||
import java.util.concurrent.ThreadFactory;
|
||||
|
||||
import org.apache.hugegraph.util.Log;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
public class PausableScheduledThreadPool extends ScheduledThreadPoolExecutor {
|
||||
|
||||
private static final Logger LOG = Log.logger(PausableScheduledThreadPool.class);
|
||||
|
||||
private volatile boolean paused = false;
|
||||
|
||||
public PausableScheduledThreadPool(int corePoolSize,
|
||||
ThreadFactory factory) {
|
||||
super(corePoolSize, factory);
|
||||
}
|
||||
|
||||
public synchronized void pauseSchedule() {
|
||||
this.paused = true;
|
||||
LOG.info("PausableScheduledThreadPool was paused");
|
||||
}
|
||||
|
||||
public synchronized void resumeSchedule() {
|
||||
this.paused = false;
|
||||
this.notifyAll();
|
||||
LOG.info("PausableScheduledThreadPool was resumed");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void beforeExecute(Thread t, Runnable r) {
|
||||
synchronized (this) {
|
||||
while (this.paused) {
|
||||
try {
|
||||
this.wait();
|
||||
} catch (InterruptedException e) {
|
||||
LOG.warn("PausableScheduledThreadPool was interrupted");
|
||||
}
|
||||
}
|
||||
}
|
||||
super.beforeExecute(t, r);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void shutdown() {
|
||||
if (this.paused) {
|
||||
this.resumeSchedule();
|
||||
}
|
||||
super.shutdown();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Runnable> shutdownNow() {
|
||||
if (this.paused) {
|
||||
this.resumeSchedule();
|
||||
}
|
||||
return super.shutdownNow();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,98 +0,0 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with this
|
||||
* work for additional information regarding copyright ownership. The ASF
|
||||
* licenses this file to You under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.apache.hugegraph.concurrent;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
import org.apache.hugegraph.util.E;
|
||||
|
||||
public class RowLock<K extends Comparable<K>> {
|
||||
|
||||
private final Map<K, Lock> locks = new ConcurrentHashMap<>();
|
||||
private final ThreadLocal<Map<K, LocalLock>> localLocks =
|
||||
ThreadLocal.withInitial(HashMap::new);
|
||||
|
||||
public void lock(K key) {
|
||||
E.checkArgument(key != null, "Lock key can't be null");
|
||||
LocalLock localLock = this.localLocks.get().get(key);
|
||||
if (localLock != null) {
|
||||
localLock.lockCount++;
|
||||
} else {
|
||||
Lock current = new ReentrantLock();
|
||||
Lock previous = this.locks.putIfAbsent(key, current);
|
||||
if (previous != null) {
|
||||
current = previous;
|
||||
}
|
||||
current.lock();
|
||||
this.localLocks.get().put(key, new LocalLock(current));
|
||||
}
|
||||
}
|
||||
|
||||
public void unlock(K key) {
|
||||
E.checkArgument(key != null, "Unlock key can't be null");
|
||||
LocalLock localLock = this.localLocks.get().get(key);
|
||||
if (localLock == null) {
|
||||
return;
|
||||
}
|
||||
if (--localLock.lockCount == 0) {
|
||||
this.locks.remove(key, localLock.current);
|
||||
this.localLocks.get().remove(key);
|
||||
localLock.current.unlock();
|
||||
}
|
||||
E.checkState(localLock.lockCount >= 0,
|
||||
"The lock count must be >= 0, but got %s",
|
||||
localLock.lockCount);
|
||||
}
|
||||
|
||||
public void lockAll(Set<K> keys) {
|
||||
E.checkArgument(keys != null && keys.size() > 0,
|
||||
"Lock keys can't be null or empty");
|
||||
List<K> list = new ArrayList<>(keys);
|
||||
Collections.sort(list);
|
||||
for (K key : list) {
|
||||
this.lock(key);
|
||||
}
|
||||
}
|
||||
|
||||
public void unlockAll(Set<K> keys) {
|
||||
E.checkArgument(keys != null && keys.size() > 0,
|
||||
"Unlock keys can't be null or empty");
|
||||
for (K key : keys) {
|
||||
this.unlock(key);
|
||||
}
|
||||
}
|
||||
|
||||
private static class LocalLock {
|
||||
|
||||
private final Lock current;
|
||||
private int lockCount;
|
||||
|
||||
private LocalLock(Lock current) {
|
||||
this.current = current;
|
||||
this.lockCount = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,47 +0,0 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with this
|
||||
* work for additional information regarding copyright ownership. The ASF
|
||||
* licenses this file to You under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.apache.hugegraph.config;
|
||||
|
||||
import java.util.function.Function;
|
||||
|
||||
import org.apache.hugegraph.util.E;
|
||||
import com.google.common.base.Predicate;
|
||||
|
||||
public class ConfigConvOption<T, R> extends TypedOption<T, R> {
|
||||
|
||||
private final Function<T, R> converter;
|
||||
|
||||
public ConfigConvOption(String name, String desc, Predicate<T> pred,
|
||||
Function<T, R> convert, T value) {
|
||||
this(name, false, desc, pred, convert, value);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public ConfigConvOption(String name, boolean required, String desc,
|
||||
Predicate<T> pred, Function<T, R> convert,
|
||||
T value) {
|
||||
super(name, required, desc, pred, (Class<T>) value.getClass(), value);
|
||||
E.checkNotNull(convert, "convert");
|
||||
this.converter = convert;
|
||||
}
|
||||
|
||||
@Override
|
||||
public R convert(T value) {
|
||||
return this.converter.apply(value);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,39 +0,0 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with this
|
||||
* work for additional information regarding copyright ownership. The ASF
|
||||
* licenses this file to You under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.apache.hugegraph.config;
|
||||
|
||||
public class ConfigException extends RuntimeException {
|
||||
|
||||
private static final long serialVersionUID = -8711375282196157058L;
|
||||
|
||||
public ConfigException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public ConfigException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
public ConfigException(String message, Object... args) {
|
||||
super(String.format(message, args));
|
||||
}
|
||||
|
||||
public ConfigException(String message, Throwable cause, Object... args) {
|
||||
super(String.format(message, args), cause);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,75 +0,0 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with this
|
||||
* work for additional information regarding copyright ownership. The ASF
|
||||
* licenses this file to You under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.apache.hugegraph.config;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.function.Function;
|
||||
|
||||
import org.apache.hugegraph.util.E;
|
||||
import com.google.common.base.Predicate;
|
||||
|
||||
public class ConfigListConvOption<T, R> extends TypedOption<List<T>, List<R>> {
|
||||
|
||||
private final Class<T> elemClass;
|
||||
private final Function<T, R> converter;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public ConfigListConvOption(String name, String desc,
|
||||
Predicate<List<T>> pred, Function<T, R> convert,
|
||||
T... values) {
|
||||
this(name, false, desc, pred, convert, null, Arrays.asList(values));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public ConfigListConvOption(String name, boolean required, String desc,
|
||||
Predicate<List<T>> pred, Function<T, R> convert,
|
||||
Class<T> clazz, List<T> values) {
|
||||
super(name, required, desc, pred,
|
||||
(Class<List<T>>) values.getClass(), values);
|
||||
E.checkNotNull(convert, "convert");
|
||||
if (clazz == null && values.size() > 0) {
|
||||
clazz = (Class<T>) values.get(0).getClass();
|
||||
}
|
||||
E.checkArgumentNotNull(clazz, "Element class can't be null");
|
||||
this.elemClass = clazz;
|
||||
this.converter = convert;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean forList() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<T> parse(String value) {
|
||||
return ConfigListOption.convert(value, part -> {
|
||||
return this.parse(part, this.elemClass);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<R> convert(List<T> values) {
|
||||
List<R> results = new ArrayList<>(values.size());
|
||||
for (T value : values) {
|
||||
results.add(this.converter.apply(value));
|
||||
}
|
||||
return results;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,79 +0,0 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with this
|
||||
* work for additional information regarding copyright ownership. The ASF
|
||||
* licenses this file to You under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.apache.hugegraph.config;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.function.Function;
|
||||
|
||||
import org.apache.hugegraph.util.E;
|
||||
import com.google.common.base.Predicate;
|
||||
|
||||
public class ConfigListOption<T> extends ConfigOption<List<T>> {
|
||||
|
||||
private final Class<T> elemClass;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public ConfigListOption(String name, String desc,
|
||||
Predicate<List<T>> pred, T... values) {
|
||||
this(name, false, desc, pred, null, Arrays.asList(values));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public ConfigListOption(String name, boolean required, String desc,
|
||||
Predicate<List<T>> pred, Class<T> clazz,
|
||||
List<T> values) {
|
||||
super(name, required, desc, pred,
|
||||
(Class<List<T>>) values.getClass(), values);
|
||||
if (clazz == null && values.size() > 0) {
|
||||
clazz = (Class<T>) values.get(0).getClass();
|
||||
}
|
||||
E.checkArgumentNotNull(clazz, "Element class can't be null");
|
||||
this.elemClass = clazz;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean forList() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<T> parse(String value) {
|
||||
return convert(value, part -> this.parse(part, this.elemClass));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T> List<T> convert(Object value, Function<String, ?> conv) {
|
||||
if (value instanceof List) {
|
||||
return (List<T>) value;
|
||||
}
|
||||
// If target data type is List, parse it as a list
|
||||
String str = (String) value;
|
||||
if (str.startsWith("[") && str.endsWith("]")) {
|
||||
str = str.substring(1, str.length() - 1);
|
||||
}
|
||||
|
||||
String[] parts = str.split(",");
|
||||
List<T> results = new ArrayList<>(parts.length);
|
||||
for (String part : parts) {
|
||||
results.add((T) conv.apply(part.trim()));
|
||||
}
|
||||
return results;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,37 +0,0 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with this
|
||||
* work for additional information regarding copyright ownership. The ASF
|
||||
* licenses this file to You under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.apache.hugegraph.config;
|
||||
|
||||
import com.google.common.base.Predicate;
|
||||
|
||||
public class ConfigOption<T> extends TypedOption<T, T> {
|
||||
|
||||
public ConfigOption(String name, String desc, T value) {
|
||||
this(name, desc, null, value);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public ConfigOption(String name, String desc, Predicate<T> pred, T value) {
|
||||
this(name, false, desc, pred, (Class<T>) value.getClass(), value);
|
||||
}
|
||||
|
||||
public ConfigOption(String name, boolean required, String desc,
|
||||
Predicate<T> pred, Class<T> type, T value) {
|
||||
super(name, required, desc, pred, type, value);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,216 +0,0 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with this
|
||||
* work for additional information regarding copyright ownership. The ASF
|
||||
* licenses this file to You under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.apache.hugegraph.config;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import org.apache.commons.configuration2.Configuration;
|
||||
import org.apache.commons.configuration2.FileBasedConfiguration;
|
||||
import org.apache.commons.configuration2.PropertiesConfiguration;
|
||||
import org.apache.commons.configuration2.YAMLConfiguration;
|
||||
import org.apache.commons.configuration2.builder.FileBasedConfigurationBuilder;
|
||||
import org.apache.commons.configuration2.builder.fluent.Configurations;
|
||||
import org.apache.commons.configuration2.builder.fluent.Parameters;
|
||||
import org.apache.commons.configuration2.ex.ConfigurationException;
|
||||
import org.apache.commons.configuration2.io.FileHandler;
|
||||
import org.apache.commons.io.FilenameUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.hugegraph.util.E;
|
||||
import org.apache.hugegraph.util.Log;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
public class HugeConfig extends PropertiesConfiguration {
|
||||
|
||||
private static final Logger LOG = Log.logger(HugeConfig.class);
|
||||
|
||||
private String configPath;
|
||||
|
||||
public HugeConfig(Configuration config) {
|
||||
loadConfig(config);
|
||||
this.configPath = null;
|
||||
}
|
||||
|
||||
public HugeConfig(String configFile) {
|
||||
loadConfig(loadConfigFile(configFile));
|
||||
this.configPath = configFile;
|
||||
}
|
||||
|
||||
public HugeConfig(Map<String, Object> propertyMap) {
|
||||
if (propertyMap == null) {
|
||||
throw new ConfigException("The property map is null");
|
||||
}
|
||||
|
||||
for (Map.Entry<String, Object> kv : propertyMap.entrySet()) {
|
||||
this.addProperty(kv.getKey(), kv.getValue());
|
||||
}
|
||||
this.checkRequiredOptions();
|
||||
}
|
||||
|
||||
private void loadConfig(Configuration config) {
|
||||
if (config == null) {
|
||||
throw new ConfigException("The config object is null");
|
||||
}
|
||||
this.setLayoutIfNeeded(config);
|
||||
|
||||
this.append(config);
|
||||
this.checkRequiredOptions();
|
||||
}
|
||||
|
||||
private void setLayoutIfNeeded(Configuration conf) {
|
||||
if (!(conf instanceof PropertiesConfiguration)) {
|
||||
return;
|
||||
}
|
||||
PropertiesConfiguration propConf = (PropertiesConfiguration) conf;
|
||||
this.setLayout(propConf.getLayout());
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T, R> R get(TypedOption<T, R> option) {
|
||||
Object value = this.getProperty(option.name());
|
||||
if (value == null) {
|
||||
return option.defaultValue();
|
||||
}
|
||||
return (R) value;
|
||||
}
|
||||
|
||||
public Map<String, String> getMap(ConfigListOption<String> option) {
|
||||
List<String> values = this.get(option);
|
||||
Map<String, String> result = new HashMap<>();
|
||||
for (String value : values) {
|
||||
String[] pair = value.split(":", 2);
|
||||
E.checkState(pair.length == 2,
|
||||
"Invalid option format for '%s': %s(expect KEY:VALUE)",
|
||||
option.name(), value);
|
||||
result.put(pair[0].trim(), pair[1].trim());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addPropertyDirect(String key, Object value) {
|
||||
TypedOption<?, ?> option = OptionSpace.get(key);
|
||||
if (option == null) {
|
||||
LOG.warn("The config option '{}' is redundant, " +
|
||||
"please ensure it has been registered", key);
|
||||
} else {
|
||||
// The input value is String(parsed by PropertiesConfiguration)
|
||||
value = this.validateOption(key, value);
|
||||
}
|
||||
if (this.containsKey(key) && value instanceof List) {
|
||||
for (Object item : (List<?>) value) {
|
||||
super.addPropertyDirect(key, item);
|
||||
}
|
||||
} else {
|
||||
super.addPropertyDirect(key, value);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void addPropertyInternal(String key, Object value) {
|
||||
this.addPropertyDirect(key, value);
|
||||
}
|
||||
|
||||
private Object validateOption(String key, Object value) {
|
||||
TypedOption<?, ?> option = OptionSpace.get(key);
|
||||
|
||||
if (value instanceof String) {
|
||||
return option.parseConvert((String) value);
|
||||
}
|
||||
|
||||
Class<?> dataType = option.dataType();
|
||||
if (dataType.isInstance(value)) {
|
||||
return value;
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException(
|
||||
String.format("Invalid value for key '%s': '%s'", key, value));
|
||||
}
|
||||
|
||||
private void checkRequiredOptions() {
|
||||
// TODO: Check required options must be contained in this map
|
||||
}
|
||||
|
||||
public void save(File copiedFile) throws ConfigurationException {
|
||||
FileHandler fileHandler = new FileHandler(this);
|
||||
fileHandler.save(copiedFile);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public File file() {
|
||||
if (StringUtils.isEmpty(this.configPath)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return new File(this.configPath);
|
||||
}
|
||||
|
||||
public void file(String path) {
|
||||
this.configPath = path;
|
||||
}
|
||||
|
||||
private static Configuration loadConfigFile(String path) {
|
||||
E.checkNotNull(path, "config path");
|
||||
E.checkArgument(!path.isEmpty(),
|
||||
"The config path can't be empty");
|
||||
|
||||
File file = new File(path);
|
||||
return loadConfigFile(file);
|
||||
}
|
||||
|
||||
private static Configuration loadConfigFile(File configFile) {
|
||||
E.checkArgument(configFile.exists() &&
|
||||
configFile.isFile() &&
|
||||
configFile.canRead(),
|
||||
"Please specify a proper config file rather than: '%s'",
|
||||
configFile.toString());
|
||||
|
||||
try {
|
||||
String fileName = configFile.getName();
|
||||
String fileExtension = FilenameUtils.getExtension(fileName);
|
||||
|
||||
Configuration config;
|
||||
Configurations configs = new Configurations();
|
||||
|
||||
switch (fileExtension) {
|
||||
case "yml":
|
||||
case "yaml":
|
||||
Parameters params = new Parameters();
|
||||
FileBasedConfigurationBuilder<FileBasedConfiguration> builder =
|
||||
new FileBasedConfigurationBuilder(YAMLConfiguration.class)
|
||||
.configure(params.fileBased().setFile(configFile));
|
||||
config = builder.getConfiguration();
|
||||
break;
|
||||
case "xml":
|
||||
config = configs.xml(configFile);
|
||||
break;
|
||||
default:
|
||||
config = configs.properties(configFile);
|
||||
break;
|
||||
}
|
||||
return config;
|
||||
} catch (ConfigurationException e) {
|
||||
throw new ConfigException("Unable to load config: '%s'",
|
||||
e, configFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,83 +0,0 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with this
|
||||
* work for additional information regarding copyright ownership. The ASF
|
||||
* licenses this file to You under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.apache.hugegraph.config;
|
||||
|
||||
import java.lang.reflect.Array;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import com.google.common.base.Predicate;
|
||||
|
||||
public final class OptionChecker {
|
||||
|
||||
public static <O> Predicate<O> disallowEmpty() {
|
||||
return o -> {
|
||||
if (o == null) {
|
||||
return false;
|
||||
}
|
||||
if (o instanceof String) {
|
||||
return StringUtils.isNotBlank((String) o);
|
||||
}
|
||||
if (o.getClass().isArray() && (Array.getLength(o) == 0)) {
|
||||
return false;
|
||||
}
|
||||
return !(o instanceof Iterable) || ((Iterable<?>) o).iterator().hasNext();
|
||||
};
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <O> Predicate<O> allowValues(O... values) {
|
||||
return o -> o != null && Arrays.asList(values).contains(o);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <O> Predicate<List<O>> inValues(O... values) {
|
||||
return o -> o != null && new HashSet<>(Arrays.asList(values)).containsAll(o);
|
||||
}
|
||||
|
||||
public static <N extends Number> Predicate<N> positiveInt() {
|
||||
return number -> number != null && number.longValue() > 0;
|
||||
}
|
||||
|
||||
public static <N extends Number> Predicate<N> nonNegativeInt() {
|
||||
return number -> number != null && number.longValue() >= 0;
|
||||
}
|
||||
|
||||
public static <N extends Number> Predicate<N> rangeInt(N min, N max) {
|
||||
return number -> {
|
||||
if (number == null) {
|
||||
return false;
|
||||
}
|
||||
long value = number.longValue();
|
||||
return value >= min.longValue() && value <= max.longValue();
|
||||
};
|
||||
}
|
||||
|
||||
public static <N extends Number> Predicate<N> rangeDouble(N min, N max) {
|
||||
return number -> {
|
||||
if (number == null) {
|
||||
return false;
|
||||
}
|
||||
double value = number.doubleValue();
|
||||
return value >= min.doubleValue() && value <= max.doubleValue();
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
@ -1,59 +0,0 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with this
|
||||
* work for additional information regarding copyright ownership. The ASF
|
||||
* licenses this file to You under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.apache.hugegraph.config;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.hugegraph.util.Log;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
public class OptionHolder {
|
||||
|
||||
private static final Logger LOG = Log.logger(HugeConfig.class);
|
||||
|
||||
protected Map<String, TypedOption<?, ?>> options;
|
||||
|
||||
public OptionHolder() {
|
||||
this.options = new HashMap<>();
|
||||
}
|
||||
|
||||
protected void registerOptions() {
|
||||
for (Field field : this.getClass().getFields()) {
|
||||
if (!TypedOption.class.isAssignableFrom(field.getType())) {
|
||||
// Skip if not option
|
||||
continue;
|
||||
}
|
||||
try {
|
||||
TypedOption<?, ?> option = (TypedOption<?, ?>) field.get(this);
|
||||
// Fields of subclass first, don't overwrite by superclass
|
||||
this.options.putIfAbsent(option.name(), option);
|
||||
} catch (Exception e) {
|
||||
LOG.error("Failed to register option: {}", field, e);
|
||||
throw new ConfigException(
|
||||
"Failed to register option: %s", field);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Map<String, TypedOption<?, ?>> options() {
|
||||
return Collections.unmodifiableMap(this.options);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,120 +0,0 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with this
|
||||
* work for additional information regarding copyright ownership. The ASF
|
||||
* licenses this file to You under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.apache.hugegraph.config;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import org.apache.hugegraph.util.E;
|
||||
import org.apache.hugegraph.util.Log;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
public final class OptionSpace {
|
||||
|
||||
private static final Logger LOG = Log.logger(OptionSpace.class);
|
||||
|
||||
private static final Map<String, Class<? extends OptionHolder>> HOLDERS;
|
||||
private static final Map<String, TypedOption<?, ?>> OPTIONS;
|
||||
private static final String INSTANCE_METHOD = "instance";
|
||||
|
||||
static {
|
||||
HOLDERS = new ConcurrentHashMap<>();
|
||||
OPTIONS = new ConcurrentHashMap<>();
|
||||
}
|
||||
|
||||
public static void register(String module, String holder) {
|
||||
ClassLoader classLoader = OptionSpace.class.getClassLoader();
|
||||
Class<?> clazz;
|
||||
try {
|
||||
clazz = classLoader.loadClass(holder);
|
||||
} catch (ClassNotFoundException e) {
|
||||
throw new ConfigException(
|
||||
"Failed to load class of option holder '%s'", e, holder);
|
||||
}
|
||||
|
||||
// Check subclass
|
||||
if (!OptionHolder.class.isAssignableFrom(clazz)) {
|
||||
throw new ConfigException(
|
||||
"Class '%s' is not a subclass of OptionHolder", holder);
|
||||
}
|
||||
|
||||
OptionHolder instance = null;
|
||||
Exception exception = null;
|
||||
try {
|
||||
Method method = clazz.getMethod(INSTANCE_METHOD);
|
||||
if (!Modifier.isStatic(method.getModifiers())) {
|
||||
throw new NoSuchMethodException(INSTANCE_METHOD);
|
||||
}
|
||||
instance = (OptionHolder) method.invoke(null);
|
||||
if (instance == null) {
|
||||
exception = new ConfigException(
|
||||
"Returned null from %s() method",
|
||||
INSTANCE_METHOD);
|
||||
}
|
||||
} catch (NoSuchMethodException e) {
|
||||
LOG.warn("Class {} does not has static method {}.",
|
||||
holder, INSTANCE_METHOD);
|
||||
exception = e;
|
||||
} catch (InvocationTargetException e) {
|
||||
LOG.warn("Can't call static method {} from class {}.",
|
||||
INSTANCE_METHOD, holder);
|
||||
exception = e;
|
||||
} catch (IllegalAccessException e) {
|
||||
LOG.warn("Illegal access while calling method {} from class {}.",
|
||||
INSTANCE_METHOD, holder);
|
||||
exception = e;
|
||||
}
|
||||
|
||||
if (exception != null) {
|
||||
throw new ConfigException("Failed to instantiate option holder: %s",
|
||||
exception, holder);
|
||||
}
|
||||
|
||||
register(module, instance);
|
||||
}
|
||||
|
||||
public static void register(String module, OptionHolder holder) {
|
||||
// Check exists
|
||||
if (HOLDERS.containsKey(module)) {
|
||||
LOG.warn("Already registered option holder: {} ({})",
|
||||
module, HOLDERS.get(module));
|
||||
}
|
||||
E.checkArgumentNotNull(holder, "OptionHolder can't be null");
|
||||
HOLDERS.put(module, holder.getClass());
|
||||
OPTIONS.putAll(holder.options());
|
||||
LOG.debug("Registered options for OptionHolder: {}",
|
||||
holder.getClass().getSimpleName());
|
||||
}
|
||||
|
||||
public static Set<String> keys() {
|
||||
return Collections.unmodifiableSet(OPTIONS.keySet());
|
||||
}
|
||||
|
||||
public static boolean containKey(String key) {
|
||||
return OPTIONS.containsKey(key);
|
||||
}
|
||||
|
||||
public static TypedOption<?, ?> get(String key) {
|
||||
return OPTIONS.get(key);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,194 +0,0 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with this
|
||||
* work for additional information regarding copyright ownership. The ASF
|
||||
* licenses this file to You under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.apache.hugegraph.config;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.hugegraph.util.E;
|
||||
import org.apache.hugegraph.util.Log;
|
||||
import org.apache.commons.configuration.PropertyConverter;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
import com.google.common.base.Joiner;
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
|
||||
public class TypedOption<T, R> {
|
||||
|
||||
private static final Logger LOG = Log.logger(TypedOption.class);
|
||||
|
||||
private static final Set<Class<?>> ACCEPTED_DATA_TYPES;
|
||||
private static final String ACCEPTED_DATA_TYPES_STRING;
|
||||
|
||||
static {
|
||||
ACCEPTED_DATA_TYPES = ImmutableSet.of(
|
||||
Boolean.class,
|
||||
Short.class,
|
||||
Integer.class,
|
||||
Byte.class,
|
||||
Long.class,
|
||||
Float.class,
|
||||
Double.class,
|
||||
String.class,
|
||||
String[].class,
|
||||
Class.class,
|
||||
List.class
|
||||
);
|
||||
|
||||
ACCEPTED_DATA_TYPES_STRING = Joiner.on(", ").join(ACCEPTED_DATA_TYPES);
|
||||
}
|
||||
|
||||
private final String name;
|
||||
private final String desc;
|
||||
private final boolean required;
|
||||
private final Class<T> dataType;
|
||||
private final T defaultValue;
|
||||
private final Predicate<T> checkFunc;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public TypedOption(String name, boolean required, String desc,
|
||||
Predicate<T> pred, Class<T> type, T value) {
|
||||
E.checkNotNull(name, "name");
|
||||
E.checkNotNull(type, "dataType");
|
||||
|
||||
this.name = name;
|
||||
this.dataType = (Class<T>) this.checkAndAssignDataType(type);
|
||||
this.defaultValue = value;
|
||||
this.required = required;
|
||||
this.desc = desc;
|
||||
this.checkFunc = pred;
|
||||
|
||||
this.check(this.defaultValue);
|
||||
}
|
||||
|
||||
private Class<?> checkAndAssignDataType(Class<T> dataType) {
|
||||
for (Class<?> clazz : ACCEPTED_DATA_TYPES) {
|
||||
if (clazz.isAssignableFrom(dataType)) {
|
||||
return clazz;
|
||||
}
|
||||
}
|
||||
|
||||
String msg = String.format("Input data type '%s' doesn't belong " +
|
||||
"to acceptable type set: [%s]",
|
||||
dataType, ACCEPTED_DATA_TYPES_STRING);
|
||||
throw new IllegalArgumentException(msg);
|
||||
}
|
||||
|
||||
public String name() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public Class<T> dataType() {
|
||||
return this.dataType;
|
||||
}
|
||||
|
||||
public String desc() {
|
||||
return this.desc;
|
||||
}
|
||||
|
||||
public boolean required() {
|
||||
return this.required;
|
||||
}
|
||||
|
||||
public R defaultValue() {
|
||||
return this.convert(this.defaultValue);
|
||||
}
|
||||
|
||||
public R parseConvert(String value) {
|
||||
T parsed = this.parse(value);
|
||||
this.check(parsed);
|
||||
return this.convert(parsed);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
protected T parse(String value) {
|
||||
return (T) this.parse(value, this.dataType);
|
||||
}
|
||||
|
||||
protected Object parse(String value, Class<?> dataType) {
|
||||
if (dataType.equals(String.class)) {
|
||||
return value;
|
||||
} else if (dataType.equals(Class.class)) {
|
||||
try {
|
||||
if (value.startsWith("class")) {
|
||||
value = value.substring("class".length()).trim();
|
||||
}
|
||||
return Class.forName(value);
|
||||
} catch (ClassNotFoundException e) {
|
||||
throw new ConfigException(
|
||||
"Failed to parse Class from String '%s'", e, value);
|
||||
}
|
||||
} else if (List.class.isAssignableFrom(dataType)) {
|
||||
E.checkState(this.forList(),
|
||||
"List option can't be registered with class %s",
|
||||
this.getClass().getSimpleName());
|
||||
}
|
||||
|
||||
// Use PropertyConverter method `toXXX` convert value
|
||||
String methodTo = "to" + dataType.getSimpleName();
|
||||
try {
|
||||
Method method = PropertyConverter.class.getMethod(
|
||||
methodTo, Object.class);
|
||||
return method.invoke(null, value);
|
||||
} catch (ReflectiveOperationException e) {
|
||||
LOG.error("Invalid type of value '{}' for option '{}'",
|
||||
value, this.name, e);
|
||||
throw new ConfigException(
|
||||
"Invalid type of value '%s' for option '%s', " +
|
||||
"expect '%s' type",
|
||||
value, this.name, dataType.getSimpleName());
|
||||
}
|
||||
}
|
||||
|
||||
protected void check(Object value) {
|
||||
E.checkNotNull(value, "value", this.name);
|
||||
if (!this.dataType.isInstance(value)) {
|
||||
throw new ConfigException(
|
||||
"Invalid type of value '%s' for option '%s', " +
|
||||
"expect type %s but got %s", value, this.name,
|
||||
this.dataType.getSimpleName(),
|
||||
value.getClass().getSimpleName());
|
||||
}
|
||||
|
||||
if (this.checkFunc != null) {
|
||||
@SuppressWarnings("unchecked")
|
||||
T result = (T) value;
|
||||
if (!this.checkFunc.apply(result)) {
|
||||
throw new ConfigException("Invalid option value for '%s': %s",
|
||||
this.name, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
protected R convert(T value) {
|
||||
return (R) value;
|
||||
}
|
||||
|
||||
protected boolean forList() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("[%s]%s=%s", this.dataType.getSimpleName(),
|
||||
this.name, this.defaultValue);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,64 +0,0 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with this
|
||||
* work for additional information regarding copyright ownership. The ASF
|
||||
* licenses this file to You under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.apache.hugegraph.date;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.TimeZone;
|
||||
|
||||
import org.joda.time.DateTimeZone;
|
||||
import org.joda.time.format.DateTimeFormat;
|
||||
import org.joda.time.format.DateTimeFormatter;
|
||||
|
||||
/**
|
||||
* The SafeDateFormat actually is a proxy for joda DateTimeFormatter
|
||||
*/
|
||||
public class SafeDateFormat {
|
||||
|
||||
private static final int ONE_HOUR_MS = 3600 * 1000;
|
||||
|
||||
private final String pattern;
|
||||
private DateTimeFormatter formatter;
|
||||
|
||||
public SafeDateFormat(String pattern) {
|
||||
this.pattern = pattern;
|
||||
this.formatter = DateTimeFormat.forPattern(pattern);
|
||||
}
|
||||
|
||||
public synchronized void setTimeZone(String zoneId) {
|
||||
int hoursOffset = TimeZone.getTimeZone(zoneId).getRawOffset() /
|
||||
ONE_HOUR_MS;
|
||||
DateTimeZone zone = DateTimeZone.forOffsetHours(hoursOffset);
|
||||
this.formatter = this.formatter.withZone(zone);
|
||||
}
|
||||
|
||||
public TimeZone getTimeZone() {
|
||||
return this.formatter.getZone().toTimeZone();
|
||||
}
|
||||
|
||||
public Date parse(String source) {
|
||||
return this.formatter.parseDateTime(source).toDate();
|
||||
}
|
||||
|
||||
public String format(Date date) {
|
||||
return this.formatter.print(date.getTime());
|
||||
}
|
||||
|
||||
public Object toPattern() {
|
||||
return this.pattern;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,71 +0,0 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with this
|
||||
* work for additional information regarding copyright ownership. The ASF
|
||||
* licenses this file to You under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.apache.hugegraph.event;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
|
||||
import org.apache.hugegraph.util.E;
|
||||
|
||||
public class Event extends java.util.EventObject {
|
||||
|
||||
private static final long serialVersionUID = 1625973849208342813L;
|
||||
|
||||
private String name;
|
||||
private Object[] args;
|
||||
|
||||
public Event(Object source, String event) {
|
||||
this(source, event, Collections.emptyList().toArray());
|
||||
}
|
||||
|
||||
public Event(Object source, String event, Object... args) {
|
||||
super(source);
|
||||
this.name = event;
|
||||
this.args = args;
|
||||
}
|
||||
|
||||
public String name() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public Object[] args() {
|
||||
return this.args;
|
||||
}
|
||||
|
||||
public void checkArgs(Class<?>... classes) throws IllegalArgumentException {
|
||||
E.checkArgument(this.args.length == classes.length,
|
||||
"The args count of event '%s' should be %s(actual %s)",
|
||||
this.name, classes.length, this.args.length);
|
||||
int i = 0;
|
||||
for (Class<?> c : classes) {
|
||||
Object arg = this.args[i++];
|
||||
if (arg == null) {
|
||||
continue;
|
||||
}
|
||||
E.checkArgument(c.isAssignableFrom(arg.getClass()),
|
||||
"The arg '%s'(%s) can't match %s",
|
||||
arg, arg.getClass(), c);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("Event{name='%s', args=%s}",
|
||||
this.name, Arrays.asList(this.args));
|
||||
}
|
||||
}
|
||||
|
|
@ -1,197 +0,0 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with this
|
||||
* work for additional information regarding copyright ownership. The ASF
|
||||
* licenses this file to You under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.apache.hugegraph.event;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import org.apache.hugegraph.util.E;
|
||||
import org.apache.hugegraph.util.ExecutorUtil;
|
||||
import org.apache.hugegraph.util.Log;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
import org.apache.hugegraph.iterator.ExtendableIterator;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
|
||||
public class EventHub {
|
||||
|
||||
private static final Logger LOG = Log.logger(EventHub.class);
|
||||
|
||||
public static final String EVENT_WORKER = "event-worker-%d";
|
||||
public static final String ANY_EVENT = "*";
|
||||
|
||||
private static final List<EventListener> EMPTY = ImmutableList.of();
|
||||
|
||||
// Event executor
|
||||
private static ExecutorService executor = null;
|
||||
|
||||
private String name;
|
||||
private Map<String, List<EventListener>> listeners;
|
||||
|
||||
public EventHub() {
|
||||
this("hub");
|
||||
}
|
||||
|
||||
public EventHub(String name) {
|
||||
this(name, 1, Runtime.getRuntime().availableProcessors() << 2);
|
||||
}
|
||||
|
||||
public EventHub(String name, int threadSize) {
|
||||
LOG.debug("Create new EventHub {},threadSize {}", name, threadSize);
|
||||
this.name = name;
|
||||
this.listeners = new ConcurrentHashMap<>();
|
||||
EventHub.init(threadSize);
|
||||
}
|
||||
|
||||
public EventHub(String name, int corePoolSize, int maximumPoolSize) {
|
||||
LOG.debug("Create new EventHub {},corePoolSize {}, maximumPoolSize {}", name, corePoolSize, maximumPoolSize);
|
||||
this.name = name;
|
||||
this.listeners = new ConcurrentHashMap<>();
|
||||
EventHub.init(corePoolSize, maximumPoolSize);
|
||||
}
|
||||
|
||||
public static synchronized void init(int poolSize) {
|
||||
if (executor != null) {
|
||||
return;
|
||||
}
|
||||
LOG.debug("Init pool(size {}) for EventHub", poolSize);
|
||||
executor = ExecutorUtil.newFixedThreadPool(poolSize, EVENT_WORKER);
|
||||
}
|
||||
|
||||
public static synchronized void init(int corePoolSize, int maximumPoolSize) {
|
||||
LOG.debug("Init corePoolSize {}, maximumPoolSize {} for EventHub", corePoolSize, maximumPoolSize);
|
||||
if (executor != null) {
|
||||
LOG.debug("EventHub executor already initialized");
|
||||
return;
|
||||
}
|
||||
executor = ExecutorUtil.newDynamicThreadExecutor(EVENT_WORKER, corePoolSize, maximumPoolSize);
|
||||
}
|
||||
|
||||
public static synchronized boolean destroy(long timeout)
|
||||
throws InterruptedException {
|
||||
E.checkState(executor != null, "EventHub has not been initialized");
|
||||
LOG.debug("Destroy pool for EventHub");
|
||||
executor.shutdown();
|
||||
return executor.awaitTermination(timeout, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
private static ExecutorService executor() {
|
||||
ExecutorService e = executor;
|
||||
E.checkState(e != null, "The event executor has been destroyed");
|
||||
return e;
|
||||
}
|
||||
|
||||
public String name() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public boolean containsListener(String event) {
|
||||
List<EventListener> ls = this.listeners.get(event);
|
||||
return ls != null && ls.size() > 0;
|
||||
}
|
||||
|
||||
public List<EventListener> listeners(String event) {
|
||||
List<EventListener> ls = this.listeners.get(event);
|
||||
return ls == null ? EMPTY : Collections.unmodifiableList(ls);
|
||||
}
|
||||
|
||||
public void listen(String event, EventListener listener) {
|
||||
E.checkNotNull(event, "event");
|
||||
E.checkNotNull(listener, "event listener");
|
||||
|
||||
if (!this.listeners.containsKey(event)) {
|
||||
this.listeners.putIfAbsent(event, new CopyOnWriteArrayList<>());
|
||||
}
|
||||
List<EventListener> ls = this.listeners.get(event);
|
||||
assert ls != null : this.listeners;
|
||||
ls.add(listener);
|
||||
}
|
||||
|
||||
public List<EventListener> unlisten(String event) {
|
||||
List<EventListener> ls = this.listeners.remove(event);
|
||||
return ls == null ? EMPTY : Collections.unmodifiableList(ls);
|
||||
}
|
||||
|
||||
public int unlisten(String event, EventListener listener) {
|
||||
List<EventListener> ls = this.listeners.get(event);
|
||||
if (ls == null) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int count = 0;
|
||||
while (ls.remove(listener)) {
|
||||
count++;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
public Future<Integer> notify(String event, @Nullable Object... args) {
|
||||
@SuppressWarnings("resource")
|
||||
ExtendableIterator<EventListener> all = new ExtendableIterator<>();
|
||||
|
||||
List<EventListener> ls = this.listeners.get(event);
|
||||
if (ls != null && !ls.isEmpty()) {
|
||||
all.extend(ls.iterator());
|
||||
}
|
||||
List<EventListener> lsAny = this.listeners.get(ANY_EVENT);
|
||||
if (lsAny != null && !lsAny.isEmpty()) {
|
||||
all.extend(lsAny.iterator());
|
||||
}
|
||||
|
||||
if (!all.hasNext()) {
|
||||
return CompletableFuture.completedFuture(0);
|
||||
}
|
||||
|
||||
Event ev = new Event(this, event, args);
|
||||
|
||||
// The submit will catch params: `all`(Listeners) and `ev`(Event)
|
||||
return executor().submit(() -> {
|
||||
int count = 0;
|
||||
// Notify all listeners, and ignore the results
|
||||
while (all.hasNext()) {
|
||||
try {
|
||||
all.next().event(ev);
|
||||
count++;
|
||||
} catch (Throwable e) {
|
||||
LOG.warn("Failed to handle event: {}", ev, e);
|
||||
}
|
||||
}
|
||||
return count;
|
||||
});
|
||||
}
|
||||
|
||||
public Object call(String event, @Nullable Object... args) {
|
||||
List<EventListener> ls = this.listeners.get(event);
|
||||
if (ls == null) {
|
||||
throw new RuntimeException("Not found listener for: " + event);
|
||||
} else if (ls.size() != 1) {
|
||||
throw new RuntimeException("Too many listeners for: " + event);
|
||||
}
|
||||
EventListener listener = ls.get(0);
|
||||
return listener.event(new Event(this, event, args));
|
||||
}
|
||||
}
|
||||
|
|
@ -1,27 +0,0 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with this
|
||||
* work for additional information regarding copyright ownership. The ASF
|
||||
* licenses this file to You under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.apache.hugegraph.event;
|
||||
|
||||
public interface EventListener extends java.util.EventListener {
|
||||
/**
|
||||
* The event callback
|
||||
* @param event object
|
||||
* @return event result
|
||||
*/
|
||||
Object event(Event event);
|
||||
}
|
||||
|
|
@ -1,23 +0,0 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with this
|
||||
* work for additional information regarding copyright ownership. The ASF
|
||||
* licenses this file to You under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.apache.hugegraph.func;
|
||||
|
||||
public interface TriFunction<T1, T2, T3, R> {
|
||||
|
||||
R apply(T1 v1, T2 v2, T3 v3);
|
||||
}
|
||||
|
|
@ -1,104 +0,0 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with this
|
||||
* work for additional information regarding copyright ownership. The ASF
|
||||
* licenses this file to You under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.apache.hugegraph.iterator;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.function.Function;
|
||||
|
||||
import org.apache.hugegraph.util.E;
|
||||
import org.apache.hugegraph.util.InsertionOrderUtil;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
|
||||
public class BatchMapperIterator<T, R> extends WrappedIterator<R> {
|
||||
|
||||
private final int batch;
|
||||
private final Iterator<T> originIterator;
|
||||
private final Function<List<T>, Iterator<R>> mapperCallback;
|
||||
|
||||
private Iterator<R> batchIterator;
|
||||
|
||||
public BatchMapperIterator(int batch, Iterator<T> origin,
|
||||
Function<List<T>, Iterator<R>> mapper) {
|
||||
E.checkArgument(batch > 0, "Expect batch > 0, but got %s", batch);
|
||||
this.batch = batch;
|
||||
this.originIterator = origin;
|
||||
this.mapperCallback = mapper;
|
||||
this.batchIterator = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Iterator<T> originIterator() {
|
||||
return this.originIterator;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected final boolean fetch() {
|
||||
if (this.batchIterator != null && this.fetchFromBatch()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
List<T> batch = this.nextBatch();
|
||||
assert this.batchIterator == null;
|
||||
while (!batch.isEmpty()) {
|
||||
// Do fetch
|
||||
this.batchIterator = this.mapperCallback.apply(batch);
|
||||
if (this.batchIterator != null && this.fetchFromBatch()) {
|
||||
return true;
|
||||
}
|
||||
// Try next batch
|
||||
batch = this.nextBatch();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
protected final List<T> nextBatch() {
|
||||
if (!this.originIterator.hasNext()) {
|
||||
return ImmutableList.of();
|
||||
}
|
||||
List<T> list = InsertionOrderUtil.newList();
|
||||
for (int i = 0; i < this.batch && this.originIterator.hasNext(); i++) {
|
||||
T next = this.originIterator.next();
|
||||
list.add(next);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
protected final boolean fetchFromBatch() {
|
||||
E.checkNotNull(this.batchIterator, "mapper results");
|
||||
while (this.batchIterator.hasNext()) {
|
||||
R result = this.batchIterator.next();
|
||||
if (result != null) {
|
||||
assert this.current == none();
|
||||
this.current = result;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
this.resetBatchIterator();
|
||||
return false;
|
||||
}
|
||||
|
||||
protected final void resetBatchIterator() {
|
||||
if (this.batchIterator == null) {
|
||||
return;
|
||||
}
|
||||
close(this.batchIterator);
|
||||
this.batchIterator = null;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,23 +0,0 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with this
|
||||
* work for additional information regarding copyright ownership. The ASF
|
||||
* licenses this file to You under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.apache.hugegraph.iterator;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
public interface CIter<R> extends Iterator<R>, AutoCloseable, Metadatable {
|
||||
}
|
||||
|
|
@ -1,98 +0,0 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with this
|
||||
* work for additional information regarding copyright ownership. The ASF
|
||||
* licenses this file to You under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.apache.hugegraph.iterator;
|
||||
|
||||
import java.util.Deque;
|
||||
import java.util.Iterator;
|
||||
import java.util.concurrent.ConcurrentLinkedDeque;
|
||||
|
||||
import org.apache.hugegraph.util.E;
|
||||
|
||||
public class ExtendableIterator<T> extends WrappedIterator<T> {
|
||||
|
||||
private final Deque<Iterator<T>> itors;
|
||||
|
||||
private Iterator<T> currentIterator;
|
||||
|
||||
public ExtendableIterator() {
|
||||
this.itors = new ConcurrentLinkedDeque<>();
|
||||
this.currentIterator = null;
|
||||
}
|
||||
|
||||
public ExtendableIterator(Iterator<T> iter) {
|
||||
this();
|
||||
this.extend(iter);
|
||||
}
|
||||
|
||||
public ExtendableIterator(Iterator<T> itor1, Iterator<T> itor2) {
|
||||
this();
|
||||
this.extend(itor1);
|
||||
this.extend(itor2);
|
||||
}
|
||||
|
||||
public ExtendableIterator<T> extend(Iterator<T> iter) {
|
||||
E.checkState(this.currentIterator == null,
|
||||
"Can't extend iterator after iterating");
|
||||
if (iter != null) {
|
||||
this.itors.addLast(iter);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws Exception {
|
||||
for (Iterator<T> iter : this.itors) {
|
||||
if (iter instanceof AutoCloseable) {
|
||||
((AutoCloseable) iter).close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Iterator<T> originIterator() {
|
||||
return this.currentIterator;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean fetch() {
|
||||
assert this.current == none();
|
||||
if (this.itors.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (this.currentIterator != null && this.currentIterator.hasNext()) {
|
||||
this.current = this.currentIterator.next();
|
||||
return true;
|
||||
}
|
||||
|
||||
Iterator<T> first;
|
||||
while ((first = this.itors.peekFirst()) != null && !first.hasNext()) {
|
||||
if (first == this.itors.peekLast() && this.itors.size() == 1) {
|
||||
this.currentIterator = first;
|
||||
// The last one
|
||||
return false;
|
||||
}
|
||||
close(this.itors.removeFirst());
|
||||
}
|
||||
|
||||
assert first != null && first.hasNext();
|
||||
this.currentIterator = first;
|
||||
this.current = this.currentIterator.next();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,51 +0,0 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with this
|
||||
* work for additional information regarding copyright ownership. The ASF
|
||||
* licenses this file to You under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.apache.hugegraph.iterator;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.function.Function;
|
||||
|
||||
public class FilterIterator<T> extends WrappedIterator<T> {
|
||||
|
||||
private final Iterator<T> originIterator;
|
||||
private final Function<T, Boolean> filterCallback;
|
||||
|
||||
public FilterIterator(Iterator<T> origin, Function<T, Boolean> filter) {
|
||||
this.originIterator = origin;
|
||||
this.filterCallback = filter;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Iterator<T> originIterator() {
|
||||
return this.originIterator;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected final boolean fetch() {
|
||||
while (this.originIterator.hasNext()) {
|
||||
T next = this.originIterator.next();
|
||||
// Do filter
|
||||
if (next != null && this.filterCallback.apply(next)) {
|
||||
assert this.current == none();
|
||||
this.current = next;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,50 +0,0 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with this
|
||||
* work for additional information regarding copyright ownership. The ASF
|
||||
* licenses this file to You under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.apache.hugegraph.iterator;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.function.Function;
|
||||
|
||||
import org.apache.hugegraph.util.E;
|
||||
|
||||
public class FlatMapperFilterIterator<T, R> extends FlatMapperIterator<T, R> {
|
||||
|
||||
private final Function<R, Boolean> filterCallback;
|
||||
|
||||
public FlatMapperFilterIterator(Iterator<T> origin,
|
||||
Function<T, Iterator<R>> mapper,
|
||||
Function<R, Boolean> filter) {
|
||||
super(origin, mapper);
|
||||
this.filterCallback = filter;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected final boolean fetchFromBatch() {
|
||||
E.checkNotNull(this.batchIterator, "mapper results");
|
||||
while (this.batchIterator.hasNext()) {
|
||||
R result = this.batchIterator.next();
|
||||
if (result != null && this.filterCallback.apply(result)) {
|
||||
assert this.current == none();
|
||||
this.current = result;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
this.resetBatchIterator();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,89 +0,0 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with this
|
||||
* work for additional information regarding copyright ownership. The ASF
|
||||
* licenses this file to You under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.apache.hugegraph.iterator;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.function.Function;
|
||||
|
||||
import org.apache.hugegraph.util.E;
|
||||
|
||||
public class FlatMapperIterator<T, R> extends WrappedIterator<R> {
|
||||
|
||||
private final Iterator<T> originIterator;
|
||||
private final Function<T, Iterator<R>> mapperCallback;
|
||||
|
||||
protected Iterator<R> batchIterator;
|
||||
|
||||
public FlatMapperIterator(Iterator<T> origin,
|
||||
Function<T, Iterator<R>> mapper) {
|
||||
this.originIterator = origin;
|
||||
this.mapperCallback = mapper;
|
||||
this.batchIterator = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws Exception {
|
||||
this.resetBatchIterator();
|
||||
super.close();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Iterator<T> originIterator() {
|
||||
return this.originIterator;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected final boolean fetch() {
|
||||
if (this.batchIterator != null && this.fetchFromBatch()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
while (this.originIterator.hasNext()) {
|
||||
T next = this.originIterator.next();
|
||||
assert this.batchIterator == null;
|
||||
// Do fetch
|
||||
this.batchIterator = this.mapperCallback.apply(next);
|
||||
if (this.batchIterator != null && this.fetchFromBatch()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
protected boolean fetchFromBatch() {
|
||||
E.checkNotNull(this.batchIterator, "mapper results");
|
||||
while (this.batchIterator.hasNext()) {
|
||||
R result = this.batchIterator.next();
|
||||
if (result != null) {
|
||||
assert this.current == none();
|
||||
this.current = result;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
this.resetBatchIterator();
|
||||
return false;
|
||||
}
|
||||
|
||||
protected final void resetBatchIterator() {
|
||||
if (this.batchIterator == null) {
|
||||
return;
|
||||
}
|
||||
close(this.batchIterator);
|
||||
this.batchIterator = null;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,64 +0,0 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with this
|
||||
* work for additional information regarding copyright ownership. The ASF
|
||||
* licenses this file to You under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.apache.hugegraph.iterator;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.function.Function;
|
||||
|
||||
public class LimitIterator<T> extends WrappedIterator<T> {
|
||||
|
||||
private final Iterator<T> originIterator;
|
||||
private final Function<T, Boolean> filterCallback;
|
||||
|
||||
public LimitIterator(Iterator<T> origin, Function<T, Boolean> filter) {
|
||||
this.originIterator = origin;
|
||||
this.filterCallback = filter;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Iterator<T> originIterator() {
|
||||
return this.originIterator;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected final boolean fetch() {
|
||||
while (this.originIterator.hasNext()) {
|
||||
T next = this.originIterator.next();
|
||||
if (next == null) {
|
||||
continue;
|
||||
}
|
||||
// Do filter
|
||||
boolean reachLimit = this.filterCallback.apply(next);
|
||||
if (reachLimit) {
|
||||
this.closeOriginIterator();
|
||||
return false;
|
||||
}
|
||||
assert this.current == none();
|
||||
this.current = next;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
protected final void closeOriginIterator() {
|
||||
if (this.originIterator == null) {
|
||||
return;
|
||||
}
|
||||
close(this.originIterator);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,78 +0,0 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with this
|
||||
* work for additional information regarding copyright ownership. The ASF
|
||||
* licenses this file to You under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.apache.hugegraph.iterator;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.hugegraph.util.InsertionOrderUtil;
|
||||
|
||||
public class ListIterator<T> extends WrappedIterator<T> {
|
||||
|
||||
private final Iterator<T> originIterator;
|
||||
private final Iterator<T> resultsIterator;
|
||||
private final Collection<T> results;
|
||||
|
||||
public ListIterator(long capacity, Iterator<T> origin) {
|
||||
List<T> results = InsertionOrderUtil.newList();
|
||||
while (origin.hasNext()) {
|
||||
if (capacity >= 0L && results.size() >= capacity) {
|
||||
throw new IllegalArgumentException(
|
||||
"The iterator exceeded capacity " + capacity);
|
||||
}
|
||||
results.add(origin.next());
|
||||
}
|
||||
this.originIterator = origin;
|
||||
this.results = Collections.unmodifiableList(results);
|
||||
this.resultsIterator = this.results.iterator();
|
||||
}
|
||||
|
||||
public ListIterator(Collection<T> origin) {
|
||||
this.originIterator = origin.iterator();
|
||||
this.results = origin instanceof List ?
|
||||
Collections.unmodifiableList((List<T>) origin) :
|
||||
Collections.unmodifiableCollection(origin);
|
||||
this.resultsIterator = this.results.iterator();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
this.resultsIterator.remove();
|
||||
}
|
||||
|
||||
public Collection<T> list() {
|
||||
return this.results;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean fetch() {
|
||||
assert this.current == none();
|
||||
if (!this.resultsIterator.hasNext()) {
|
||||
return false;
|
||||
}
|
||||
this.current = this.resultsIterator.next();
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Iterator<T> originIterator() {
|
||||
return this.originIterator;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,51 +0,0 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with this
|
||||
* work for additional information regarding copyright ownership. The ASF
|
||||
* licenses this file to You under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.apache.hugegraph.iterator;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.function.Function;
|
||||
|
||||
public class MapperIterator<T, R> extends WrappedIterator<R> {
|
||||
|
||||
private final Iterator<T> originIterator;
|
||||
private final Function<T, R> mapperCallback;
|
||||
|
||||
public MapperIterator(Iterator<T> origin, Function<T, R> mapper) {
|
||||
this.originIterator = origin;
|
||||
this.mapperCallback = mapper;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Iterator<T> originIterator() {
|
||||
return this.originIterator;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected final boolean fetch() {
|
||||
while (this.originIterator.hasNext()) {
|
||||
T next = this.originIterator.next();
|
||||
R result = this.mapperCallback.apply(next);
|
||||
if (result != null) {
|
||||
assert this.current == none();
|
||||
this.current = result;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,23 +0,0 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with this
|
||||
* work for additional information regarding copyright ownership. The ASF
|
||||
* licenses this file to You under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.apache.hugegraph.iterator;
|
||||
|
||||
public interface Metadatable {
|
||||
|
||||
Object metadata(String meta, Object... args);
|
||||
}
|
||||
|
|
@ -1,99 +0,0 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with this
|
||||
* work for additional information regarding copyright ownership. The ASF
|
||||
* licenses this file to You under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.apache.hugegraph.iterator;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.NoSuchElementException;
|
||||
|
||||
public abstract class WrappedIterator<R> implements CIter<R> {
|
||||
|
||||
private static final Object NONE = new Object();
|
||||
|
||||
protected R current;
|
||||
|
||||
public WrappedIterator() {
|
||||
this.current = none();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
if (this.current != none()) {
|
||||
return true;
|
||||
}
|
||||
return this.fetch();
|
||||
}
|
||||
|
||||
@Override
|
||||
public R next() {
|
||||
if (this.current == none()) {
|
||||
this.fetch();
|
||||
if (this.current == none()) {
|
||||
throw new NoSuchElementException();
|
||||
}
|
||||
}
|
||||
R current = this.current;
|
||||
this.current = none();
|
||||
return current;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
Iterator<?> iterator = this.originIterator();
|
||||
if (iterator == null) {
|
||||
throw new NoSuchElementException(
|
||||
"The origin iterator can't be null for removing");
|
||||
}
|
||||
iterator.remove();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws Exception {
|
||||
Iterator<?> iterator = this.originIterator();
|
||||
if (iterator instanceof AutoCloseable) {
|
||||
((AutoCloseable) iterator).close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object metadata(String meta, Object... args) {
|
||||
Iterator<?> iterator = this.originIterator();
|
||||
if (iterator instanceof Metadatable) {
|
||||
return ((Metadatable) iterator).metadata(meta, args);
|
||||
}
|
||||
throw new IllegalStateException("Original iterator is not Metadatable");
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
protected static final <R> R none() {
|
||||
return (R) NONE;
|
||||
}
|
||||
|
||||
public static void close(Iterator<?> iterator) {
|
||||
if (iterator instanceof AutoCloseable) {
|
||||
try {
|
||||
((AutoCloseable) iterator).close();
|
||||
} catch (Exception e) {
|
||||
throw new IllegalStateException("Failed to close iterator");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract Iterator<?> originIterator();
|
||||
|
||||
protected abstract boolean fetch();
|
||||
}
|
||||
|
|
@ -1,106 +0,0 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with this
|
||||
* work for additional information regarding copyright ownership. The ASF
|
||||
* licenses this file to You under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.apache.hugegraph.license;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.lang3.time.DateUtils;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
|
||||
public class LicenseCommonParam {
|
||||
|
||||
@JsonProperty("subject")
|
||||
private String subject;
|
||||
|
||||
@JsonProperty("issued_time")
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
|
||||
private Date issuedTime = new Date();
|
||||
|
||||
@JsonProperty("not_before")
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
|
||||
private Date notBefore = this.issuedTime;
|
||||
|
||||
@JsonProperty("not_after")
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
|
||||
private Date notAfter = DateUtils.addDays(this.notBefore, 30);
|
||||
|
||||
@JsonProperty("consumer_type")
|
||||
private String consumerType = "user";
|
||||
|
||||
@JsonProperty("consumer_amount")
|
||||
private Integer consumerAmount = 1;
|
||||
|
||||
@JsonProperty("description")
|
||||
private String description = "";
|
||||
|
||||
@JsonProperty("extra_params")
|
||||
private List<LicenseExtraParam> extraParams;
|
||||
|
||||
public LicenseCommonParam() {
|
||||
// pass
|
||||
}
|
||||
|
||||
public LicenseCommonParam(String subject, String description,
|
||||
Date issued, Date notBefore, Date notAfter,
|
||||
String consumerType, int consumerAmount,
|
||||
List<LicenseExtraParam> extraParams) {
|
||||
this.subject = subject;
|
||||
this.description = description;
|
||||
this.issuedTime = issued;
|
||||
this.notBefore = notBefore;
|
||||
this.notAfter = notAfter;
|
||||
this.consumerType = consumerType;
|
||||
this.consumerAmount = consumerAmount;
|
||||
this.extraParams = extraParams;
|
||||
}
|
||||
|
||||
public String subject() {
|
||||
return this.subject;
|
||||
}
|
||||
|
||||
public Date issuedTime() {
|
||||
return this.issuedTime;
|
||||
}
|
||||
|
||||
public Date notBefore() {
|
||||
return this.notBefore;
|
||||
}
|
||||
|
||||
public Date notAfter() {
|
||||
return this.notAfter;
|
||||
}
|
||||
|
||||
public String consumerType() {
|
||||
return this.consumerType;
|
||||
}
|
||||
|
||||
public Integer consumerAmount() {
|
||||
return this.consumerAmount;
|
||||
}
|
||||
|
||||
public String description() {
|
||||
return this.description;
|
||||
}
|
||||
|
||||
public List<LicenseExtraParam> extraParams() {
|
||||
return this.extraParams;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,61 +0,0 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with this
|
||||
* work for additional information regarding copyright ownership. The ASF
|
||||
* licenses this file to You under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.apache.hugegraph.license;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonAlias;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
|
||||
public class LicenseCreateParam extends LicenseCommonParam {
|
||||
|
||||
@JsonProperty("private_alias")
|
||||
private String privateAlias;
|
||||
|
||||
@JsonAlias("key_ticket")
|
||||
@JsonProperty("key_password")
|
||||
private String keyPassword;
|
||||
|
||||
@JsonAlias("store_ticket")
|
||||
@JsonProperty("store_password")
|
||||
private String storePassword;
|
||||
|
||||
@JsonProperty("privatekey_path")
|
||||
private String privateKeyPath;
|
||||
|
||||
@JsonProperty("license_path")
|
||||
private String licensePath;
|
||||
|
||||
public String privateAlias() {
|
||||
return this.privateAlias;
|
||||
}
|
||||
|
||||
public String keyPassword() {
|
||||
return this.keyPassword;
|
||||
}
|
||||
|
||||
public String storePassword() {
|
||||
return this.storePassword;
|
||||
}
|
||||
|
||||
public String privateKeyPath() {
|
||||
return this.privateKeyPath;
|
||||
}
|
||||
|
||||
public String licensePath() {
|
||||
return this.licensePath;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,119 +0,0 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with this
|
||||
* work for additional information regarding copyright ownership. The ASF
|
||||
* licenses this file to You under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.apache.hugegraph.license;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
|
||||
public class LicenseExtraParam {
|
||||
|
||||
public static final int NO_LIMIT = -1;
|
||||
|
||||
@JsonProperty("id")
|
||||
private String id;
|
||||
|
||||
@JsonProperty("version")
|
||||
private String version;
|
||||
|
||||
@JsonProperty("graphs")
|
||||
private int graphs;
|
||||
|
||||
@JsonProperty("ip")
|
||||
private String ip;
|
||||
|
||||
@JsonProperty("mac")
|
||||
private String mac;
|
||||
|
||||
@JsonProperty("cpus")
|
||||
private int cpus;
|
||||
|
||||
// The unit is MB
|
||||
@JsonProperty("ram")
|
||||
private int ram;
|
||||
|
||||
@JsonProperty("threads")
|
||||
private int threads;
|
||||
|
||||
// The unit is MB
|
||||
@JsonProperty("memory")
|
||||
private int memory;
|
||||
|
||||
@JsonProperty("nodes")
|
||||
private int nodes;
|
||||
|
||||
// The unit is MB
|
||||
@JsonProperty("data_size")
|
||||
private long dataSize;
|
||||
|
||||
@JsonProperty("vertices")
|
||||
private long vertices;
|
||||
|
||||
@JsonProperty("edges")
|
||||
private long edges;
|
||||
|
||||
public String id() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
public String version() {
|
||||
return this.version;
|
||||
}
|
||||
|
||||
public int graphs() {
|
||||
return this.graphs;
|
||||
}
|
||||
|
||||
public String ip() {
|
||||
return this.ip;
|
||||
}
|
||||
|
||||
public String mac() {
|
||||
return this.mac;
|
||||
}
|
||||
|
||||
public int cpus() {
|
||||
return this.cpus;
|
||||
}
|
||||
|
||||
public int ram() {
|
||||
return this.ram;
|
||||
}
|
||||
|
||||
public int threads() {
|
||||
return this.threads;
|
||||
}
|
||||
|
||||
public int memory() {
|
||||
return this.memory;
|
||||
}
|
||||
|
||||
public int nodes() {
|
||||
return this.nodes;
|
||||
}
|
||||
|
||||
public long dataSize() {
|
||||
return this.dataSize;
|
||||
}
|
||||
|
||||
public long vertices() {
|
||||
return this.vertices;
|
||||
}
|
||||
|
||||
public long edges() {
|
||||
return this.edges;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,60 +0,0 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with this
|
||||
* work for additional information regarding copyright ownership. The ASF
|
||||
* licenses this file to You under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.apache.hugegraph.license;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonAlias;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
|
||||
public class LicenseInstallParam {
|
||||
|
||||
@JsonProperty("subject")
|
||||
private String subject;
|
||||
|
||||
@JsonProperty("public_alias")
|
||||
private String publicAlias;
|
||||
|
||||
@JsonAlias("store_ticket")
|
||||
@JsonProperty("store_password")
|
||||
private String storePassword;
|
||||
|
||||
@JsonProperty("publickey_path")
|
||||
private String publicKeyPath;
|
||||
|
||||
@JsonProperty("license_path")
|
||||
private String licensePath;
|
||||
|
||||
public String subject() {
|
||||
return this.subject;
|
||||
}
|
||||
|
||||
public String publicAlias() {
|
||||
return this.publicAlias;
|
||||
}
|
||||
|
||||
public String storePassword() {
|
||||
return this.storePassword;
|
||||
}
|
||||
|
||||
public String licensePath() {
|
||||
return this.licensePath;
|
||||
}
|
||||
|
||||
public String publicKeyPath() {
|
||||
return this.publicKeyPath;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,32 +0,0 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with this
|
||||
* work for additional information regarding copyright ownership. The ASF
|
||||
* licenses this file to You under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.apache.hugegraph.license;
|
||||
|
||||
public interface LicenseManager {
|
||||
|
||||
LicenseParams installLicense() throws Exception;
|
||||
|
||||
void uninstallLicense() throws Exception;
|
||||
|
||||
LicenseParams verifyLicense() throws Exception;
|
||||
|
||||
interface VerifyCallback {
|
||||
|
||||
void onVerifyLicense(LicenseParams params) throws Exception;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,30 +0,0 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with this
|
||||
* work for additional information regarding copyright ownership. The ASF
|
||||
* licenses this file to You under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.apache.hugegraph.license;
|
||||
|
||||
import org.apache.commons.lang.NotImplementedException;
|
||||
|
||||
import org.apache.hugegraph.license.LicenseManager.VerifyCallback;
|
||||
|
||||
public class LicenseManagerFactory {
|
||||
|
||||
public static LicenseManager create(LicenseInstallParam param,
|
||||
VerifyCallback veryfyCallback) {
|
||||
throw new NotImplementedException("No LicenseManager available");
|
||||
}
|
||||
}
|
||||
|
|
@ -1,45 +0,0 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with this
|
||||
* work for additional information regarding copyright ownership. The ASF
|
||||
* licenses this file to You under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.apache.hugegraph.license;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
public class LicenseParams extends LicenseCommonParam {
|
||||
|
||||
public LicenseParams() {
|
||||
super();
|
||||
}
|
||||
|
||||
public LicenseParams(String subject, String description,
|
||||
Date issued, Date notBefore, Date notAfter,
|
||||
String consumerType, int consumerAmount,
|
||||
List<LicenseExtraParam> extraParams) {
|
||||
super(subject, description, issued, notBefore, notAfter,
|
||||
consumerType, consumerAmount, extraParams);
|
||||
}
|
||||
|
||||
public LicenseExtraParam matchParam(String id) {
|
||||
for (LicenseExtraParam param : this.extraParams()) {
|
||||
if (param.id().equals(id)) {
|
||||
return param;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,126 +0,0 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with this
|
||||
* work for additional information regarding copyright ownership. The ASF
|
||||
* licenses this file to You under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.apache.hugegraph.license;
|
||||
|
||||
import java.net.InetAddress;
|
||||
import java.net.NetworkInterface;
|
||||
import java.net.SocketException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Enumeration;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class MachineInfo {
|
||||
|
||||
private List<String> ipAddressList;
|
||||
private List<String> macAddressList;
|
||||
|
||||
public MachineInfo() {
|
||||
this.ipAddressList = null;
|
||||
this.macAddressList = null;
|
||||
}
|
||||
|
||||
public List<String> getIpAddress() {
|
||||
if (this.ipAddressList != null) {
|
||||
return this.ipAddressList;
|
||||
}
|
||||
this.ipAddressList = new ArrayList<>();
|
||||
List<InetAddress> inetAddresses = this.getLocalAllInetAddress();
|
||||
if (inetAddresses != null && !inetAddresses.isEmpty()) {
|
||||
this.ipAddressList = inetAddresses.stream()
|
||||
.map(InetAddress::getHostAddress)
|
||||
.distinct()
|
||||
.map(String::toLowerCase)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
return this.ipAddressList;
|
||||
}
|
||||
|
||||
public List<String> getMacAddress() {
|
||||
if (this.macAddressList != null) {
|
||||
return this.macAddressList;
|
||||
}
|
||||
this.macAddressList = new ArrayList<>();
|
||||
List<InetAddress> inetAddresses = this.getLocalAllInetAddress();
|
||||
if (inetAddresses != null && !inetAddresses.isEmpty()) {
|
||||
// Get the Mac address of all network interfaces
|
||||
List<String> list = new ArrayList<>();
|
||||
Set<String> uniqueValues = new HashSet<>();
|
||||
for (InetAddress inetAddress : inetAddresses) {
|
||||
String macByInetAddress = this.getMacByInetAddress(inetAddress);
|
||||
if (uniqueValues.add(macByInetAddress)) {
|
||||
list.add(macByInetAddress);
|
||||
}
|
||||
}
|
||||
this.macAddressList = list;
|
||||
}
|
||||
return this.macAddressList;
|
||||
}
|
||||
|
||||
public List<InetAddress> getLocalAllInetAddress() {
|
||||
Enumeration<NetworkInterface> interfaces;
|
||||
try {
|
||||
interfaces = NetworkInterface.getNetworkInterfaces();
|
||||
} catch (SocketException e) {
|
||||
throw new RuntimeException("Failed to get network interfaces");
|
||||
}
|
||||
|
||||
List<InetAddress> result = new ArrayList<>();
|
||||
while (interfaces.hasMoreElements()) {
|
||||
NetworkInterface nw = interfaces.nextElement();
|
||||
for (Enumeration<InetAddress> inetAddresses = nw.getInetAddresses();
|
||||
inetAddresses.hasMoreElements(); ) {
|
||||
InetAddress inetAddr = inetAddresses.nextElement();
|
||||
if (!inetAddr.isLoopbackAddress() &&
|
||||
!inetAddr.isLinkLocalAddress() &&
|
||||
!inetAddr.isMulticastAddress()) {
|
||||
result.add(inetAddr);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public String getMacByInetAddress(InetAddress inetAddr) {
|
||||
byte[] mac;
|
||||
try {
|
||||
mac = NetworkInterface.getByInetAddress(inetAddr)
|
||||
.getHardwareAddress();
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(String.format(
|
||||
"Failed to get mac address for inet address '%s'",
|
||||
inetAddr));
|
||||
}
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (int i = 0; i < mac.length; i++) {
|
||||
if (i != 0) {
|
||||
sb.append("-");
|
||||
}
|
||||
String temp = Integer.toHexString(mac[i] & 0xff);
|
||||
if (temp.length() == 1) {
|
||||
sb.append("0").append(temp);
|
||||
} else {
|
||||
sb.append(temp);
|
||||
}
|
||||
}
|
||||
return sb.toString().toUpperCase();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,185 +0,0 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with this
|
||||
* work for additional information regarding copyright ownership. The ASF
|
||||
* licenses this file to You under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.apache.hugegraph.perf;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.hugegraph.perf.PerfUtil.FastMap;
|
||||
|
||||
public final class LightStopwatch implements Stopwatch {
|
||||
|
||||
private long lastStartTime = -1L;
|
||||
|
||||
private long times = 0L;
|
||||
private long totalCost = 0L;
|
||||
private long totalChildrenTimes = -1L;
|
||||
|
||||
private final String name;
|
||||
private final Path parent;
|
||||
private final Path id;
|
||||
private final FastMap<String, Stopwatch> children;
|
||||
|
||||
public LightStopwatch(String name, Stopwatch parent) {
|
||||
this(name, parent.id());
|
||||
parent.child(name, this);
|
||||
}
|
||||
|
||||
public LightStopwatch(String name, Path parent) {
|
||||
this.name = name;
|
||||
this.parent = parent;
|
||||
this.id = Stopwatch.id(parent, name);
|
||||
this.children = new FastMap<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Path id() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String name() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Path parent() {
|
||||
return this.parent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void lastStartTime(long startTime) {
|
||||
this.lastStartTime = startTime;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startTime(long startTime) {
|
||||
this.times++;
|
||||
this.lastStartTime = startTime;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endTime(long startTime) {
|
||||
this.totalCost += PerfUtil.now() - this.lastStartTime;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long times() {
|
||||
return this.times;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long totalTimes() {
|
||||
if (this.totalChildrenTimes > 0L) {
|
||||
return this.times + this.totalChildrenTimes;
|
||||
}
|
||||
return this.times;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long totalChildrenTimes() {
|
||||
return this.totalChildrenTimes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long totalCost() {
|
||||
return this.totalCost;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void totalCost(long totalCost) {
|
||||
this.totalCost = totalCost;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long minCost() {
|
||||
return -1L;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long maxCost() {
|
||||
return -1L;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long totalWasted() {
|
||||
return 0L;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long totalSelfWasted() {
|
||||
return 0L;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long totalChildrenWasted() {
|
||||
return -1L;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fillChildrenTotal(List<Stopwatch> children) {
|
||||
// Fill total times of children
|
||||
this.totalChildrenTimes = children.stream().mapToLong(Stopwatch::totalTimes).sum();
|
||||
}
|
||||
|
||||
@Override
|
||||
public LightStopwatch copy() {
|
||||
try {
|
||||
return (LightStopwatch) super.clone();
|
||||
} catch (CloneNotSupportedException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Stopwatch child(String name) {
|
||||
return this.children.get(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Stopwatch child(String name, Stopwatch watch) {
|
||||
if (watch == null) {
|
||||
return this.children.remove(name);
|
||||
}
|
||||
return this.children.put(name, watch);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean empty() {
|
||||
return this.children.size() == 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear() {
|
||||
this.lastStartTime = -1L;
|
||||
|
||||
this.times = 0L;
|
||||
this.totalCost = 0L;
|
||||
this.totalChildrenTimes = -1L;
|
||||
|
||||
this.children.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("{parent:%s,name:%s," +
|
||||
"times:%s,totalChildrenTimes:%s,totalCost:%s}",
|
||||
this.parent, this.name,
|
||||
this.times, this.totalChildrenTimes,
|
||||
this.totalCost);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,302 +0,0 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with this
|
||||
* work for additional information regarding copyright ownership. The ASF
|
||||
* licenses this file to You under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.apache.hugegraph.perf;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.function.BiFunction;
|
||||
|
||||
import org.apache.hugegraph.util.Log;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
import org.apache.hugegraph.testutil.Whitebox;
|
||||
|
||||
public final class NormalStopwatch implements Stopwatch {
|
||||
|
||||
private static final Logger LOG = Log.logger(Stopwatch.class);
|
||||
|
||||
private static final String MULTI_THREAD_ACCESS_ERROR =
|
||||
"There may be multi-threaded access, ensure " +
|
||||
"not call PerfUtil.profileSingleThread(true) when " +
|
||||
"multithreading.";
|
||||
|
||||
private long lastStartTime = -1L;
|
||||
|
||||
private long times = 0L;
|
||||
private long totalCost = 0L;
|
||||
private long minCost = Long.MAX_VALUE;
|
||||
private long maxCost = 0L;
|
||||
private long totalSelfWasted = 0L;
|
||||
private long totalChildrenWasted = -1L;
|
||||
private long totalChildrenTimes = -1L;
|
||||
|
||||
private final String name;
|
||||
private final Path parent;
|
||||
private final Path id;
|
||||
private final PerfUtil.FastMap<String, Stopwatch> children;
|
||||
|
||||
public NormalStopwatch(String name, Stopwatch parent) {
|
||||
this(name, parent.id());
|
||||
parent.child(name, this);
|
||||
}
|
||||
|
||||
public NormalStopwatch(String name, Path parent) {
|
||||
this.name = name;
|
||||
this.parent = parent;
|
||||
this.id = Stopwatch.id(parent, name);
|
||||
this.children = new PerfUtil.FastMap<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Path id() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String name() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Path parent() {
|
||||
return this.parent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void lastStartTime(long startTime) {
|
||||
this.lastStartTime = startTime;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startTime(long startTime) {
|
||||
assert this.lastStartTime == -1L : MULTI_THREAD_ACCESS_ERROR;
|
||||
|
||||
this.times++;
|
||||
this.lastStartTime = startTime;
|
||||
|
||||
long endTime = PerfUtil.now();
|
||||
long wastedTime = endTime - startTime;
|
||||
if (wastedTime <= 0L) {
|
||||
wastedTime += eachStartWastedLost;
|
||||
}
|
||||
|
||||
this.totalSelfWasted += wastedTime;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endTime(long startTime) {
|
||||
assert startTime >= this.lastStartTime && this.lastStartTime != -1L :
|
||||
MULTI_THREAD_ACCESS_ERROR;
|
||||
|
||||
long endTime = PerfUtil.now();
|
||||
// The following code cost about 3ns~4ns
|
||||
long wastedTime = endTime - startTime;
|
||||
if (wastedTime <= 0L) {
|
||||
wastedTime += eachEndWastedLost;
|
||||
}
|
||||
|
||||
long cost = endTime - this.lastStartTime;
|
||||
|
||||
if (this.minCost > cost) {
|
||||
this.minCost = cost;
|
||||
}
|
||||
if (this.maxCost < cost) {
|
||||
this.maxCost = cost;
|
||||
}
|
||||
|
||||
this.totalCost += cost;
|
||||
this.totalSelfWasted += wastedTime;
|
||||
this.lastStartTime = -1L;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long times() {
|
||||
return this.times;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long totalCost() {
|
||||
return this.totalCost;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void totalCost(long totalCost) {
|
||||
this.totalCost = totalCost;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long minCost() {
|
||||
return this.minCost;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long maxCost() {
|
||||
return this.maxCost;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long totalTimes() {
|
||||
if (this.totalChildrenTimes > 0L) {
|
||||
return this.times + this.totalChildrenTimes;
|
||||
}
|
||||
return this.times;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long totalChildrenTimes() {
|
||||
return this.totalChildrenTimes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long totalWasted() {
|
||||
if (this.totalChildrenWasted > 0L) {
|
||||
return this.totalSelfWasted + this.totalChildrenWasted;
|
||||
}
|
||||
return this.totalSelfWasted;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long totalSelfWasted() {
|
||||
return this.totalSelfWasted;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long totalChildrenWasted() {
|
||||
return this.totalChildrenWasted;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fillChildrenTotal(List<Stopwatch> children) {
|
||||
// Fill total wasted cost of children
|
||||
this.totalChildrenWasted = children.stream().mapToLong(Stopwatch::totalWasted).sum();
|
||||
// Fill total times of children
|
||||
this.totalChildrenTimes = children.stream().mapToLong(Stopwatch::totalTimes).sum();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Stopwatch copy() {
|
||||
try {
|
||||
return (Stopwatch) super.clone();
|
||||
} catch (CloneNotSupportedException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Stopwatch child(String name) {
|
||||
return this.children.get(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Stopwatch child(String name, Stopwatch watch) {
|
||||
if (watch == null) {
|
||||
return this.children.remove(name);
|
||||
}
|
||||
return this.children.put(name, watch);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean empty() {
|
||||
return this.children.size() == 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear() {
|
||||
this.lastStartTime = -1L;
|
||||
|
||||
this.times = 0L;
|
||||
this.totalCost = 0L;
|
||||
|
||||
this.minCost = Long.MAX_VALUE;
|
||||
this.maxCost = 0L;
|
||||
this.totalSelfWasted = 0L;
|
||||
this.totalChildrenWasted = -1L;
|
||||
this.totalChildrenTimes = -1L;
|
||||
|
||||
this.children.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("{parent:%s,name:%s," +
|
||||
"times:%s,totalChildrenTimes:%s," +
|
||||
"totalCost:%s,minCost:%s,maxCost:%s," +
|
||||
"totalSelfWasted:%s,totalChildrenWasted:%s}",
|
||||
this.parent, this.name,
|
||||
this.times, this.totalChildrenTimes,
|
||||
this.totalCost, this.minCost, this.maxCost,
|
||||
this.totalSelfWasted, this.totalChildrenWasted);
|
||||
}
|
||||
|
||||
private static long eachStartWastedLost = 0L;
|
||||
private static long eachEndWastedLost = 0L;
|
||||
|
||||
protected static void initEachWastedLost() {
|
||||
int times = 100000000;
|
||||
|
||||
PerfUtil.LocalStack<Stopwatch> callStack = Whitebox.getInternalState(
|
||||
PerfUtil.instance(), "callStack");
|
||||
|
||||
long baseStart = PerfUtil.now();
|
||||
for (int i = 0; i < times; i++) {
|
||||
PerfUtil.instance();
|
||||
}
|
||||
long baseCost = PerfUtil.now() - baseStart;
|
||||
|
||||
BiFunction<String, Runnable, Long> testEachCost = (name, test) -> {
|
||||
long start = PerfUtil.now();
|
||||
test.run();
|
||||
long end = PerfUtil.now();
|
||||
long cost = end - start - baseCost;
|
||||
if (cost < 0L) {
|
||||
cost = 0L;
|
||||
}
|
||||
long eachCost = cost / times;
|
||||
|
||||
LOG.info("Wasted time test: cost={}ms, base_cost={}ms, {}={}ns",
|
||||
cost / 1000000.0, baseCost / 1000000.0, name, eachCost);
|
||||
return eachCost;
|
||||
};
|
||||
|
||||
String startName = "each_start_cost";
|
||||
eachStartWastedLost = testEachCost.apply(startName, () -> {
|
||||
Stopwatch watch = PerfUtil.instance().start(startName);
|
||||
PerfUtil.instance().end(startName);
|
||||
for (int i = 0; i < times; i++) {
|
||||
// Test call start()
|
||||
PerfUtil.instance().start(startName);
|
||||
// Mock end()
|
||||
watch.lastStartTime(-1L);
|
||||
callStack.pop();
|
||||
}
|
||||
});
|
||||
|
||||
String endName = "each_end_cost";
|
||||
eachEndWastedLost = testEachCost.apply(endName, () -> {
|
||||
Stopwatch watch = PerfUtil.instance().start(endName);
|
||||
PerfUtil.instance().end(endName);
|
||||
for (int i = 0; i < times; i++) {
|
||||
// Mock start()
|
||||
callStack.push(watch);
|
||||
watch.lastStartTime(0L);
|
||||
// Test call start()
|
||||
PerfUtil.instance().end(endName);
|
||||
watch.totalCost(0L);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -1,687 +0,0 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with this
|
||||
* work for additional information regarding copyright ownership. The ASF
|
||||
* licenses this file to You under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.apache.hugegraph.perf;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
import java.util.EmptyStackException;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
|
||||
import org.apache.hugegraph.util.E;
|
||||
import org.apache.hugegraph.util.Log;
|
||||
import org.apache.hugegraph.util.ReflectionUtil;
|
||||
import org.apache.hugegraph.func.TriFunction;
|
||||
import org.apache.hugegraph.testutil.Assert.ThrowableConsumer;
|
||||
import org.apache.hugegraph.perf.Stopwatch.Path;
|
||||
import com.google.common.reflect.ClassPath.ClassInfo;
|
||||
|
||||
import javassist.CannotCompileException;
|
||||
import javassist.ClassPool;
|
||||
import javassist.CtClass;
|
||||
import javassist.CtMethod;
|
||||
|
||||
public final class PerfUtil {
|
||||
|
||||
private static final Logger LOG = Log.logger(PerfUtil.class);
|
||||
private static final int DEFAULT_CAPACITY = 1024;
|
||||
|
||||
private static final ThreadLocal<PerfUtil> INSTANCE = new ThreadLocal<>();
|
||||
|
||||
private static PerfUtil SINGLE_INSTANCE = null;
|
||||
private static Thread SINGLE_THREAD = null;
|
||||
private static LocalTimer LOCAL_TIMER = null;
|
||||
private static boolean LIGHT_WATCH = false;
|
||||
|
||||
private final Map<Path, Stopwatch> stopwatches;
|
||||
private final LocalStack<Stopwatch> callStack;
|
||||
private final Stopwatch root;
|
||||
|
||||
private PerfUtil() {
|
||||
this.stopwatches = new HashMap<>(DEFAULT_CAPACITY);
|
||||
this.callStack = new LocalStack<>(DEFAULT_CAPACITY);
|
||||
this.root = newStopwatch(Path.ROOT_NAME, Path.EMPTY);
|
||||
}
|
||||
|
||||
public static PerfUtil instance() {
|
||||
if (SINGLE_INSTANCE != null &&
|
||||
SINGLE_THREAD == Thread.currentThread()) {
|
||||
// Return the only one instance for single thread, for performance
|
||||
return SINGLE_INSTANCE;
|
||||
}
|
||||
|
||||
PerfUtil p = INSTANCE.get();
|
||||
if (p == null) {
|
||||
p = new PerfUtil();
|
||||
INSTANCE.set(p);
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
public static void profileSingleThread(boolean yes) {
|
||||
SINGLE_INSTANCE = yes ? PerfUtil.instance() : null;
|
||||
SINGLE_THREAD = yes ? Thread.currentThread() : null;
|
||||
}
|
||||
|
||||
public static void useLocalTimer(boolean yes) {
|
||||
if (yes) {
|
||||
if (LOCAL_TIMER != null) {
|
||||
return;
|
||||
}
|
||||
LOCAL_TIMER = new LocalTimer();
|
||||
try {
|
||||
LOCAL_TIMER.startTimeUpdateLoop();
|
||||
} catch (InterruptedException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
if (!LIGHT_WATCH) {
|
||||
NormalStopwatch.initEachWastedLost();
|
||||
}
|
||||
} else {
|
||||
if (LOCAL_TIMER == null) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
LOCAL_TIMER.stop();
|
||||
} catch (InterruptedException e) {
|
||||
throw new RuntimeException(e);
|
||||
} finally {
|
||||
LOCAL_TIMER = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void useLightStopwatch(boolean yes) {
|
||||
if (yes != LIGHT_WATCH) {
|
||||
PerfUtil instance = INSTANCE.get();
|
||||
boolean empty = instance == null || instance.empty();
|
||||
String message = "Please call clear() before switching " +
|
||||
"light-stopwatch due to there is dirty watch";
|
||||
E.checkArgument(empty, message);
|
||||
}
|
||||
LIGHT_WATCH = yes;
|
||||
}
|
||||
|
||||
protected static long now() {
|
||||
if (LOCAL_TIMER != null) {
|
||||
return LOCAL_TIMER.now();
|
||||
}
|
||||
// System.nanoTime() cost about 40 ns each call
|
||||
return System.nanoTime();
|
||||
}
|
||||
|
||||
protected static Stopwatch newStopwatch(String name, Path parent) {
|
||||
return LIGHT_WATCH ? new LightStopwatch(name, parent) :
|
||||
new NormalStopwatch(name, parent);
|
||||
}
|
||||
|
||||
protected static Stopwatch newStopwatch(String name, Stopwatch parent) {
|
||||
return LIGHT_WATCH ? new LightStopwatch(name, parent) :
|
||||
new NormalStopwatch(name, parent);
|
||||
}
|
||||
|
||||
public Stopwatch start(String name) {
|
||||
long start = now();
|
||||
|
||||
Stopwatch parent = this.callStack.empty() ?
|
||||
this.root : this.callStack.peek();
|
||||
|
||||
// Get watch by name from local tree
|
||||
Stopwatch watch = parent.child(name);
|
||||
if (watch == null) {
|
||||
watch = newStopwatch(name, parent);
|
||||
assert !this.stopwatches.containsKey(watch.id()) : watch;
|
||||
this.stopwatches.put(watch.id(), watch);
|
||||
}
|
||||
this.callStack.push(watch);
|
||||
|
||||
watch.startTime(start);
|
||||
|
||||
return watch;
|
||||
}
|
||||
|
||||
public Stopwatch start2(String name) {
|
||||
long start = now(); // cost 70 ns with System.nanoTime()
|
||||
|
||||
Path parent = this.callStack.empty() ?
|
||||
Path.EMPTY : this.callStack.peek().id();
|
||||
Path id = Stopwatch.id(parent, name); // cost 130
|
||||
// Get watch by id from global map
|
||||
Stopwatch watch = this.stopwatches.get(id); // cost 170
|
||||
if (watch == null) {
|
||||
watch = newStopwatch(name, parent);
|
||||
this.stopwatches.put(watch.id(), watch); // cost 180
|
||||
}
|
||||
this.callStack.push(watch); // cost 190
|
||||
|
||||
watch.startTime(start);
|
||||
|
||||
return watch;
|
||||
}
|
||||
|
||||
public void end(String name) {
|
||||
long start = LIGHT_WATCH ? 0L : now();
|
||||
|
||||
Stopwatch watch = this.callStack.pop();
|
||||
if (watch == null || watch.name() != name) {
|
||||
throw new IllegalArgumentException("Invalid watch name: " + name);
|
||||
}
|
||||
|
||||
watch.endTime(start);
|
||||
}
|
||||
|
||||
public boolean empty() {
|
||||
return this.stopwatches.isEmpty() && this.root.empty();
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
String error = "Can't be cleared when the call has not ended yet";
|
||||
E.checkState(this.callStack.empty(), error);
|
||||
|
||||
this.stopwatches.clear();
|
||||
this.root.clear();
|
||||
}
|
||||
|
||||
public void profilePackage(String... packages) throws Throwable {
|
||||
Set<String> loadedClasses = new HashSet<>();
|
||||
|
||||
Function<String, Boolean> inPackage = (cls) -> {
|
||||
for (String pkg : packages) {
|
||||
if (cls.startsWith(pkg)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
ThrowableConsumer<String> profileClassIfPresent = (cls) -> {
|
||||
if (!loadedClasses.contains(cls)) {
|
||||
// Profile super class
|
||||
for (String s : ReflectionUtil.superClasses(cls)) {
|
||||
if (!loadedClasses.contains(s) && inPackage.apply(s)) {
|
||||
profileClass(s);
|
||||
loadedClasses.add(s);
|
||||
}
|
||||
}
|
||||
// Profile self class
|
||||
profileClass(cls);
|
||||
loadedClasses.add(cls);
|
||||
}
|
||||
};
|
||||
|
||||
Iterator<ClassInfo> classes = ReflectionUtil.classes(packages);
|
||||
while (classes.hasNext()) {
|
||||
String cls = classes.next().getName();
|
||||
// Profile self class
|
||||
profileClassIfPresent.accept(cls);
|
||||
// Profile nested class
|
||||
for (String s : ReflectionUtil.nestedClasses(cls)) {
|
||||
profileClassIfPresent.accept(s);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void profileClass(String... classes) throws Throwable {
|
||||
ClassPool classPool = ClassPool.getDefault();
|
||||
|
||||
for (String cls : classes) {
|
||||
CtClass ctClass = classPool.get(cls);
|
||||
List<CtMethod> methods = ReflectionUtil.getMethodsAnnotatedWith(
|
||||
ctClass, Watched.class, false);
|
||||
for (CtMethod method : methods) {
|
||||
profile(method);
|
||||
}
|
||||
|
||||
// Load class and make it effective
|
||||
if (!methods.isEmpty()) {
|
||||
ctClass.toClass();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void profile(CtMethod ctMethod)
|
||||
throws CannotCompileException, ClassNotFoundException {
|
||||
final String START =
|
||||
"org.apache.hugegraph.perf.PerfUtil.instance().start(\"%s\");";
|
||||
final String END =
|
||||
"org.apache.hugegraph.perf.PerfUtil.instance().end(\"%s\");";
|
||||
|
||||
Watched annotation = (Watched) ctMethod.getAnnotation(Watched.class);
|
||||
|
||||
String name = annotation.value();
|
||||
if (name.isEmpty()) {
|
||||
name = ctMethod.getName();
|
||||
}
|
||||
if (!annotation.prefix().isEmpty()) {
|
||||
name = annotation.prefix() + "." + name;
|
||||
}
|
||||
|
||||
ctMethod.insertBefore(String.format(START, name));
|
||||
// Insert as a finally-statement
|
||||
ctMethod.insertAfter(String.format(END, name), true);
|
||||
|
||||
LOG.debug("Profiled for: '{}' [{}]", name, ctMethod.getLongName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return this.stopwatches.toString();
|
||||
}
|
||||
|
||||
public String toJson() {
|
||||
StringBuilder sb = new StringBuilder(8 + this.stopwatches.size() * 96);
|
||||
sb.append('{');
|
||||
for (Map.Entry<Path, Stopwatch> w : this.stopwatches.entrySet()) {
|
||||
sb.append('"');
|
||||
sb.append(w.getKey());
|
||||
sb.append('"');
|
||||
|
||||
sb.append(':');
|
||||
|
||||
sb.append(w.getValue().toJson());
|
||||
|
||||
sb.append(',');
|
||||
}
|
||||
if (!this.stopwatches.isEmpty()) {
|
||||
sb.deleteCharAt(sb.length() - 1);
|
||||
}
|
||||
sb.append('}');
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
// TODO: move toECharts() method out of this class
|
||||
public String toECharts() {
|
||||
TriFunction<Integer, Integer, List<Stopwatch>, String> formatLevel = (
|
||||
totalDepth, depth, items) -> {
|
||||
float factor = 100.0f / (totalDepth + 1);
|
||||
float showFactor = 1 + (totalDepth - depth) / (float) depth;
|
||||
|
||||
float radiusFrom = depth * factor;
|
||||
float radiusTo = depth * factor + factor;
|
||||
if (depth == 1) {
|
||||
radiusFrom = 0;
|
||||
}
|
||||
|
||||
StringBuilder sb = new StringBuilder(8 + items.size() * 128);
|
||||
sb.append('{');
|
||||
sb.append("name: 'Total Cost',");
|
||||
sb.append("type: 'pie',");
|
||||
sb.append(String.format("radius: ['%s%%', '%s%%'],",
|
||||
radiusFrom, radiusTo));
|
||||
sb.append(String.format(
|
||||
"label: {normal: {position: 'inner', formatter:" +
|
||||
"function(params) {" +
|
||||
" if (params.percent > %s) return params.data.name;" +
|
||||
" else return '';" +
|
||||
"}}},", showFactor));
|
||||
sb.append("data: [");
|
||||
|
||||
items.sort((i, j) -> i.id().compareTo(j.id()));
|
||||
for (Stopwatch w : items) {
|
||||
sb.append('{');
|
||||
|
||||
sb.append("id:'");
|
||||
sb.append(w.id());
|
||||
sb.append("',");
|
||||
|
||||
sb.append("name:'");
|
||||
sb.append(w.name());
|
||||
sb.append("',");
|
||||
|
||||
sb.append("value:");
|
||||
// w.totalCost() - w.totalWasted() ?
|
||||
sb.append(w.totalCost());
|
||||
sb.append(',');
|
||||
|
||||
sb.append("cost:");
|
||||
sb.append(w.totalCost() / 1000000.0);
|
||||
sb.append(',');
|
||||
|
||||
sb.append("minCost:");
|
||||
sb.append(w.minCost());
|
||||
sb.append(',');
|
||||
|
||||
sb.append("maxCost:");
|
||||
sb.append(w.maxCost());
|
||||
sb.append(',');
|
||||
|
||||
sb.append("wasted:");
|
||||
sb.append(w.totalWasted() / 1000000.0);
|
||||
sb.append(',');
|
||||
|
||||
sb.append("selfWasted:");
|
||||
sb.append(w.totalSelfWasted() / 1000000.0);
|
||||
sb.append(',');
|
||||
|
||||
sb.append("times:");
|
||||
sb.append(w.times());
|
||||
sb.append(',');
|
||||
|
||||
sb.append("totalTimes:");
|
||||
sb.append(w.totalTimes());
|
||||
|
||||
sb.append('}');
|
||||
sb.append(',');
|
||||
}
|
||||
if (!items.isEmpty()) {
|
||||
sb.deleteCharAt(sb.length() - 1);
|
||||
}
|
||||
sb.append("]}");
|
||||
return sb.toString();
|
||||
};
|
||||
|
||||
BiConsumer<List<Stopwatch>, List<Stopwatch>> fillChildrenTotal =
|
||||
(itemsOfLn, itemsOfLnParent) -> {
|
||||
for (Stopwatch parent : itemsOfLnParent) {
|
||||
List<Stopwatch> children = itemsOfLn.stream().filter(c -> {
|
||||
return c.parent().equals(parent.id());
|
||||
}).collect(Collectors.toList());
|
||||
|
||||
parent.fillChildrenTotal(children);
|
||||
}
|
||||
};
|
||||
|
||||
BiConsumer<List<Stopwatch>, List<Stopwatch>> fillOther =
|
||||
(itemsOfLn, itemsOfLnParent) -> {
|
||||
for (Stopwatch parent : itemsOfLnParent) {
|
||||
Stream<Stopwatch> children = itemsOfLn.stream().filter(c -> {
|
||||
return c.parent().equals(parent.id());
|
||||
});
|
||||
// Fill other cost
|
||||
long sumCost = children.mapToLong(Stopwatch::totalCost).sum();
|
||||
long otherCost = parent.totalCost() - sumCost;
|
||||
if (otherCost > 0L) {
|
||||
Stopwatch other = newStopwatch("~", parent.id());
|
||||
other.totalCost(otherCost);
|
||||
itemsOfLn.add(other);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Map<Path, Stopwatch> items = this.stopwatches;
|
||||
Map<Integer, List<Stopwatch>> levelItems = new HashMap<>();
|
||||
int maxDepth = 0;
|
||||
for (Map.Entry<Path, Stopwatch> e : items.entrySet()) {
|
||||
int depth = e.getKey().toString().split("/").length;
|
||||
List<Stopwatch> levelItem = levelItems.get(depth);
|
||||
if (levelItem == null) {
|
||||
levelItem = new LinkedList<>();
|
||||
levelItems.putIfAbsent(depth, levelItem);
|
||||
}
|
||||
levelItem.add(e.getValue().copy());
|
||||
if (depth > maxDepth) {
|
||||
maxDepth = depth;
|
||||
}
|
||||
}
|
||||
|
||||
// Fill wasted cost from the outermost to innermost
|
||||
for (int i = maxDepth; i > 0; i--) {
|
||||
assert levelItems.containsKey(i) : i;
|
||||
List<Stopwatch> itemsOfI = levelItems.get(i);
|
||||
List<Stopwatch> itemsOfParent = levelItems.get(i - 1);
|
||||
if (itemsOfParent != null) {
|
||||
// Fill total value of children
|
||||
fillChildrenTotal.accept(itemsOfI, itemsOfParent);
|
||||
}
|
||||
}
|
||||
|
||||
StringBuilder sb = new StringBuilder(8 + items.size() * 128);
|
||||
// Output results header
|
||||
sb.append("{");
|
||||
sb.append("tooltip: {trigger: 'item', " +
|
||||
"formatter: function(params) {" +
|
||||
" return params.data.name + ' ' + params.percent + '% <br/>'" +
|
||||
" + 'cost: ' + params.data.cost + ' (ms) <br/>'" +
|
||||
" + 'min cost: ' + params.data.minCost + ' (ns) <br/>'" +
|
||||
" + 'max cost: ' + params.data.maxCost + ' (ns) <br/>'" +
|
||||
" + 'wasted: ' + params.data.wasted + ' (ms) <br/>'" +
|
||||
" + 'self wasted: ' + params.data.selfWasted + ' (ms) <br/>'" +
|
||||
" + 'times: ' + params.data.times + '<br/>'" +
|
||||
" + 'total times: ' + params.data.totalTimes + '<br/>'" +
|
||||
" + 'path: ' + params.data.id + '<br/>';" +
|
||||
"}");
|
||||
sb.append("},");
|
||||
sb.append("series: [");
|
||||
// Output results data
|
||||
for (int i = 1; i <= maxDepth; i++) {
|
||||
assert levelItems.containsKey(i) : i;
|
||||
List<Stopwatch> itemsOfI = levelItems.get(i);
|
||||
List<Stopwatch> itemsOfParent = levelItems.get(i - 1);
|
||||
if (itemsOfParent != null) {
|
||||
// Fill other cost for non-root level, ignore root level (i=1)
|
||||
fillOther.accept(itemsOfI, itemsOfParent);
|
||||
}
|
||||
// Output items of level I
|
||||
sb.append(formatLevel.apply(maxDepth, i, itemsOfI));
|
||||
sb.append(',');
|
||||
}
|
||||
if (!items.isEmpty()) {
|
||||
sb.deleteCharAt(sb.length() - 1);
|
||||
}
|
||||
sb.append("]}");
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public static final class LocalTimer {
|
||||
|
||||
// Header: 4 bytes classptr + 8 bytes markword
|
||||
private volatile long padding11 = 0L;
|
||||
private volatile long padding12 = 0L;
|
||||
private volatile long padding13 = 0L;
|
||||
private volatile long padding14 = 0L;
|
||||
private volatile long padding15 = 0L;
|
||||
private volatile long padding16 = 0L; // the 1st 64 bytes
|
||||
|
||||
private volatile long time = 0L;
|
||||
|
||||
private volatile long padding21 = 0L;
|
||||
private volatile long padding22 = 0L;
|
||||
private volatile long padding23 = 0L;
|
||||
private volatile long padding24 = 0L;
|
||||
private volatile long padding25 = 0L;
|
||||
private volatile long padding26 = 0L;
|
||||
private volatile long padding27 = 0L; // the 2nd 64 bytes
|
||||
|
||||
private volatile boolean running = false;
|
||||
private Thread thread = null;
|
||||
|
||||
public long now() {
|
||||
// Read current ns time (be called frequently)
|
||||
return this.time;
|
||||
}
|
||||
|
||||
public void startTimeUpdateLoop() throws InterruptedException {
|
||||
assert this.thread == null;
|
||||
assert this.preventOptimizePadding() == 0L;
|
||||
this.running = true;
|
||||
CountDownLatch started = new CountDownLatch(1);
|
||||
this.thread = new Thread(() -> {
|
||||
started.countDown();
|
||||
while (this.running) {
|
||||
this.time = System.nanoTime();
|
||||
// Prevent frequent updates for perf (5.2s => 3.6s for 8kw)
|
||||
Thread.yield();
|
||||
}
|
||||
}, "LocalTimer");
|
||||
this.thread.setDaemon(true);
|
||||
this.thread.start();
|
||||
started.await();
|
||||
}
|
||||
|
||||
public void stop() throws InterruptedException {
|
||||
this.running = false;
|
||||
if (this.thread != null) {
|
||||
this.thread.join();
|
||||
}
|
||||
}
|
||||
|
||||
public long preventOptimizePadding() {
|
||||
long p1 = this.padding11 + this.padding12 + this.padding13 +
|
||||
this.padding14 + this.padding15 + this.padding16;
|
||||
long p2 = this.padding21 + this.padding22 + this.padding23 +
|
||||
this.padding24 + this.padding25 + this.padding26 +
|
||||
this.padding27;
|
||||
return p1 + p2;
|
||||
}
|
||||
}
|
||||
|
||||
public static final class LocalStack<T> {
|
||||
|
||||
private final Object[] elementData;
|
||||
private int elementCount;
|
||||
|
||||
public LocalStack(int capacity) {
|
||||
this.elementData = new Object[capacity];
|
||||
this.elementCount = 0;
|
||||
}
|
||||
|
||||
int size() {
|
||||
return this.elementCount;
|
||||
}
|
||||
|
||||
boolean empty() {
|
||||
return this.elementCount == 0;
|
||||
}
|
||||
|
||||
public void push(T elem) {
|
||||
this.elementData[this.elementCount++] = elem;
|
||||
}
|
||||
|
||||
public T pop() {
|
||||
if (this.elementCount == 0) {
|
||||
throw new EmptyStackException();
|
||||
}
|
||||
this.elementCount--;
|
||||
@SuppressWarnings("unchecked")
|
||||
T elem = (T) this.elementData[this.elementCount];
|
||||
this.elementData[this.elementCount] = null;
|
||||
return elem;
|
||||
}
|
||||
|
||||
public T peek() {
|
||||
if (this.elementCount == 0) {
|
||||
throw new EmptyStackException();
|
||||
}
|
||||
@SuppressWarnings("unchecked")
|
||||
T elem = (T) this.elementData[this.elementCount - 1];
|
||||
return elem;
|
||||
}
|
||||
}
|
||||
|
||||
public static final class FastMap<K, V> {
|
||||
|
||||
private final Map<K, V> hashMap;
|
||||
|
||||
private K key1;
|
||||
private K key2;
|
||||
private K key3;
|
||||
|
||||
private V val1;
|
||||
private V val2;
|
||||
private V val3;
|
||||
|
||||
public FastMap() {
|
||||
this.hashMap = new HashMap<>();
|
||||
}
|
||||
|
||||
public int size() {
|
||||
return this.hashMap.size();
|
||||
}
|
||||
|
||||
public boolean containsKey(Object key) {
|
||||
return this.hashMap.containsKey(key);
|
||||
}
|
||||
|
||||
public V get(Object key) {
|
||||
if (key == this.key1) {
|
||||
return this.val1;
|
||||
} else if (key == this.key2) {
|
||||
return this.val2;
|
||||
} else if (key == this.key3) {
|
||||
return this.val3;
|
||||
}
|
||||
|
||||
return this.hashMap.get(key);
|
||||
}
|
||||
|
||||
public V put(K key, V value) {
|
||||
if (this.key1 == null) {
|
||||
this.key1 = key;
|
||||
this.val1 = value;
|
||||
} else if (this.key2 == null) {
|
||||
this.key2 = key;
|
||||
this.val2 = value;
|
||||
} else if (this.key3 == null) {
|
||||
this.key3 = key;
|
||||
this.val3 = value;
|
||||
}
|
||||
|
||||
return this.hashMap.put(key, value);
|
||||
}
|
||||
|
||||
public V remove(Object key) {
|
||||
if (key == this.key1) {
|
||||
this.key1 = null;
|
||||
this.val1 = null;
|
||||
} else if (key == this.key2) {
|
||||
this.key2 = null;
|
||||
this.val2 = null;
|
||||
} else if (key == this.key3) {
|
||||
this.key3 = null;
|
||||
this.val3 = null;
|
||||
}
|
||||
|
||||
return this.hashMap.remove(key);
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
this.key1 = null;
|
||||
this.key2 = null;
|
||||
this.key3 = null;
|
||||
|
||||
this.val1 = null;
|
||||
this.val2 = null;
|
||||
this.val3 = null;
|
||||
|
||||
this.hashMap.clear();
|
||||
}
|
||||
}
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({ ElementType.METHOD, ElementType.CONSTRUCTOR })
|
||||
public @interface Watched {
|
||||
String value() default "";
|
||||
String prefix() default "";
|
||||
}
|
||||
}
|
||||
|
|
@ -1,148 +0,0 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with this
|
||||
* work for additional information regarding copyright ownership. The ASF
|
||||
* licenses this file to You under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.apache.hugegraph.perf;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface Stopwatch extends Cloneable {
|
||||
|
||||
Path id();
|
||||
|
||||
String name();
|
||||
|
||||
Path parent();
|
||||
|
||||
void startTime(long startTime);
|
||||
|
||||
void endTime(long startTime);
|
||||
|
||||
void lastStartTime(long startTime);
|
||||
|
||||
long times();
|
||||
|
||||
long totalTimes();
|
||||
|
||||
long totalChildrenTimes();
|
||||
|
||||
long totalCost();
|
||||
|
||||
void totalCost(long otherCost);
|
||||
|
||||
long minCost();
|
||||
|
||||
long maxCost();
|
||||
|
||||
long totalWasted();
|
||||
|
||||
long totalSelfWasted();
|
||||
|
||||
long totalChildrenWasted();
|
||||
|
||||
void fillChildrenTotal(List<Stopwatch> children);
|
||||
|
||||
Stopwatch copy();
|
||||
|
||||
Stopwatch child(String name);
|
||||
|
||||
Stopwatch child(String name, Stopwatch watch);
|
||||
|
||||
boolean empty();
|
||||
|
||||
void clear();
|
||||
|
||||
default String toJson() {
|
||||
int len = 200 + this.name().length() + this.parent().length();
|
||||
StringBuilder sb = new StringBuilder(len);
|
||||
sb.append("{");
|
||||
sb.append("\"parent\":\"").append(this.parent()).append("\"");
|
||||
sb.append(",\"name\":\"").append(this.name()).append("\"");
|
||||
sb.append(",\"times\":").append(this.times());
|
||||
sb.append(",\"total_cost\":").append(this.totalCost());
|
||||
sb.append(",\"min_cost\":").append(this.minCost());
|
||||
sb.append(",\"max_cost\":").append(this.maxCost());
|
||||
sb.append(",\"total_self_wasted\":").append(this.totalSelfWasted());
|
||||
sb.append(",\"total_children_wasted\":").append(
|
||||
this.totalChildrenWasted());
|
||||
sb.append(",\"total_children_times\":").append(
|
||||
this.totalChildrenTimes());
|
||||
sb.append("}");
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
static Path id(Path parent, String name) {
|
||||
if (parent == Path.EMPTY && name == Path.ROOT_NAME) {
|
||||
return Path.EMPTY;
|
||||
}
|
||||
return new Path(parent, name);
|
||||
}
|
||||
|
||||
final class Path implements Comparable<Path> {
|
||||
|
||||
public static final String ROOT_NAME = "root";
|
||||
public static final Path EMPTY = new Path("");
|
||||
|
||||
private final String path;
|
||||
|
||||
public Path(String self) {
|
||||
this.path = self;
|
||||
}
|
||||
|
||||
public Path(Path parent, String name) {
|
||||
if (parent == EMPTY) {
|
||||
this.path = name;
|
||||
} else {
|
||||
this.path = parent.path + '/' + name;
|
||||
}
|
||||
}
|
||||
|
||||
public int length() {
|
||||
return this.path.length();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return this.path.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this.hashCode() != obj.hashCode()) {
|
||||
return false;
|
||||
}
|
||||
if (!(obj instanceof Path)) {
|
||||
return false;
|
||||
}
|
||||
Path other = (Path) obj;
|
||||
return this.path.equals(other.path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(Path other) {
|
||||
return this.path.compareTo(other.path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return this.path;
|
||||
}
|
||||
|
||||
public boolean endsWith(String name) {
|
||||
return this.path.endsWith(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,490 +0,0 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with this
|
||||
* work for additional information regarding copyright ownership. The ASF
|
||||
* licenses this file to You under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.apache.hugegraph.rest;
|
||||
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URI;
|
||||
import java.net.URLEncoder;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.security.KeyStore;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import javax.net.ssl.HostnameVerifier;
|
||||
import javax.net.ssl.HttpsURLConnection;
|
||||
import javax.net.ssl.SSLContext;
|
||||
import javax.net.ssl.SSLSession;
|
||||
import javax.net.ssl.SSLSocketFactory;
|
||||
import javax.net.ssl.TrustManager;
|
||||
import javax.net.ssl.TrustManagerFactory;
|
||||
import javax.net.ssl.X509TrustManager;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.hugegraph.util.JsonUtilCommon;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
|
||||
import lombok.SneakyThrows;
|
||||
import okhttp3.ConnectionPool;
|
||||
import okhttp3.HttpUrl;
|
||||
import okhttp3.MediaType;
|
||||
import okhttp3.OkHttpClient;
|
||||
import okhttp3.Request;
|
||||
import okhttp3.RequestBody;
|
||||
import okhttp3.Response;
|
||||
import okio.BufferedSink;
|
||||
import okio.GzipSink;
|
||||
import okio.Okio;
|
||||
|
||||
/**
|
||||
* This class provides an abstract implementation of the RestClient interface.
|
||||
* It provides methods for making HTTP requests (GET, POST, PUT, DELETE) to a REST API.
|
||||
* Note: It uses the OkHttp library to make these requests for now.
|
||||
*/
|
||||
public abstract class AbstractRestClient implements RestClient {
|
||||
|
||||
private final ThreadLocal<String> authContext;
|
||||
|
||||
private final OkHttpClient client;
|
||||
|
||||
private final String baseUrl;
|
||||
|
||||
public AbstractRestClient(String url, int timeout) {
|
||||
this(url, RestClientConfig.builder().timeout(timeout).build());
|
||||
}
|
||||
|
||||
public AbstractRestClient(String url, String user, String password, int timeout) {
|
||||
this(url, RestClientConfig.builder()
|
||||
.user(user)
|
||||
.password(password)
|
||||
.timeout(timeout)
|
||||
.build());
|
||||
}
|
||||
|
||||
public AbstractRestClient(String url, int timeout, int idleTime,
|
||||
int maxConns, int maxConnsPerRoute) {
|
||||
this(url, RestClientConfig.builder()
|
||||
.idleTime(idleTime)
|
||||
.timeout(timeout)
|
||||
.maxConns(maxConns)
|
||||
.maxConnsPerRoute(maxConnsPerRoute)
|
||||
.build());
|
||||
}
|
||||
|
||||
public AbstractRestClient(String url, String user, String password, int timeout,
|
||||
int maxConns, int maxConnsPerRoute,
|
||||
String trustStoreFile, String trustStorePassword) {
|
||||
this(url, RestClientConfig.builder()
|
||||
.user(user).password(password)
|
||||
.timeout(timeout)
|
||||
.maxConns(maxConns)
|
||||
.maxConnsPerRoute(maxConnsPerRoute)
|
||||
.trustStoreFile(trustStoreFile)
|
||||
.trustStorePassword(trustStorePassword)
|
||||
.build());
|
||||
}
|
||||
|
||||
public AbstractRestClient(String url, String token, int timeout,
|
||||
int maxConns, int maxConnsPerRoute,
|
||||
String trustStoreFile, String trustStorePassword) {
|
||||
this(url, RestClientConfig.builder()
|
||||
.token(token)
|
||||
.timeout(timeout)
|
||||
.maxConns(maxConns)
|
||||
.maxConnsPerRoute(maxConnsPerRoute)
|
||||
.trustStoreFile(trustStoreFile)
|
||||
.trustStorePassword(trustStorePassword)
|
||||
.build());
|
||||
}
|
||||
|
||||
public AbstractRestClient(String url, RestClientConfig config) {
|
||||
this.baseUrl = url;
|
||||
this.client = buildOkHttpClient(config);
|
||||
this.authContext = new InheritableThreadLocal<>();
|
||||
}
|
||||
|
||||
private static RequestBody buildRequestBody(Object body, RestHeaders headers) {
|
||||
String contentType = parseContentType(headers);
|
||||
String bodyContent;
|
||||
if (RestHeaders.APPLICATION_JSON.equals(contentType)) {
|
||||
if (body == null) {
|
||||
bodyContent = "{}";
|
||||
} else if (body instanceof String) {
|
||||
bodyContent = (String) body;
|
||||
} else {
|
||||
bodyContent = JsonUtilCommon.toJson(body);
|
||||
}
|
||||
} else {
|
||||
bodyContent = String.valueOf(body);
|
||||
}
|
||||
RequestBody requestBody = RequestBody.create(bodyContent.getBytes(),
|
||||
MediaType.parse(contentType));
|
||||
|
||||
if (headers != null &&
|
||||
"gzip".equals(headers.get(RestHeaders.CONTENT_ENCODING))) {
|
||||
requestBody = gzipBody(requestBody);
|
||||
}
|
||||
return requestBody;
|
||||
}
|
||||
|
||||
private static RequestBody gzipBody(final RequestBody body) {
|
||||
return new RequestBody() {
|
||||
@Override
|
||||
public MediaType contentType() {
|
||||
return body.contentType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long contentLength() {
|
||||
return -1; // We don't know the compressed length in advance!
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeTo(@NotNull BufferedSink sink) throws IOException {
|
||||
BufferedSink gzipSink = Okio.buffer(new GzipSink(sink));
|
||||
body.writeTo(gzipSink);
|
||||
gzipSink.close();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private static String parseContentType(RestHeaders headers) {
|
||||
if (headers != null) {
|
||||
String contentType = headers.get(RestHeaders.CONTENT_TYPE);
|
||||
if (contentType != null) {
|
||||
return contentType;
|
||||
}
|
||||
}
|
||||
return RestHeaders.APPLICATION_JSON;
|
||||
}
|
||||
|
||||
private OkHttpClient buildOkHttpClient(RestClientConfig config) {
|
||||
OkHttpClient.Builder builder = new OkHttpClient.Builder();
|
||||
|
||||
if (config.getTimeout() != null) {
|
||||
builder.connectTimeout(config.getTimeout(), TimeUnit.MILLISECONDS)
|
||||
.readTimeout(config.getTimeout(), TimeUnit.MILLISECONDS);
|
||||
}
|
||||
if (config.getConnectTimeout() != null) {
|
||||
builder.connectTimeout(config.getConnectTimeout(), TimeUnit.MILLISECONDS);
|
||||
}
|
||||
if (config.getReadTimeout() != null) {
|
||||
builder.readTimeout(config.getReadTimeout(), TimeUnit.MILLISECONDS);
|
||||
}
|
||||
|
||||
if (config.getMaxIdleConns() != null || config.getIdleTime() != null) {
|
||||
ConnectionPool connectionPool = new ConnectionPool(config.getMaxIdleConns(),
|
||||
config.getIdleTime(),
|
||||
TimeUnit.SECONDS);
|
||||
builder.connectionPool(connectionPool);
|
||||
}
|
||||
|
||||
// auth header interceptor
|
||||
if (StringUtils.isNotBlank(config.getUser()) &&
|
||||
StringUtils.isNotBlank(config.getPassword())) {
|
||||
builder.addInterceptor(new OkHttpBasicAuthInterceptor(config.getUser(),
|
||||
config.getPassword()));
|
||||
}
|
||||
if (StringUtils.isNotBlank(config.getToken())) {
|
||||
builder.addInterceptor(new OkHttpTokenInterceptor(config.getToken()));
|
||||
}
|
||||
|
||||
// ssl
|
||||
configSsl(builder, this.baseUrl, config.getTrustStoreFile(),
|
||||
config.getTrustStorePassword());
|
||||
|
||||
// Execute builder callback before builder.build() for user configs
|
||||
if (config.getBuilderCallback() != null) {
|
||||
config.getBuilderCallback().accept(builder);
|
||||
}
|
||||
|
||||
OkHttpClient okHttpClient = builder.build();
|
||||
|
||||
if (config.getMaxConns() != null) {
|
||||
okHttpClient.dispatcher().setMaxRequests(config.getMaxConns());
|
||||
}
|
||||
|
||||
if (config.getMaxConnsPerRoute() != null) {
|
||||
okHttpClient.dispatcher().setMaxRequestsPerHost(config.getMaxConnsPerRoute());
|
||||
}
|
||||
|
||||
return okHttpClient;
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
private void configSsl(OkHttpClient.Builder builder, String url, String trustStoreFile,
|
||||
String trustStorePass) {
|
||||
if (StringUtils.isBlank(trustStoreFile) || StringUtils.isBlank(trustStorePass)) {
|
||||
return;
|
||||
}
|
||||
|
||||
X509TrustManager trustManager = trustManagerForCertificates(trustStoreFile, trustStorePass);
|
||||
SSLContext sslContext = SSLContext.getInstance("TLS");
|
||||
sslContext.init(null, new TrustManager[]{trustManager}, null);
|
||||
SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
|
||||
|
||||
builder.sslSocketFactory(sslSocketFactory, trustManager)
|
||||
.hostnameVerifier(new HostNameVerifier(url));
|
||||
}
|
||||
|
||||
@Override
|
||||
public RestResult post(String path, Object object) {
|
||||
return this.post(path, object, null, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RestResult post(String path, Object object, RestHeaders headers) {
|
||||
return this.post(path, object, headers, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RestResult post(String path, Object object, Map<String, Object> params) {
|
||||
return this.post(path, object, null, params);
|
||||
}
|
||||
|
||||
private Request.Builder genRequestBuilder(String path, String id, RestHeaders headers,
|
||||
Map<String, Object> params) {
|
||||
HttpUrl.Builder urlBuilder = Objects.requireNonNull(HttpUrl.parse(this.baseUrl))
|
||||
.newBuilder()
|
||||
.addPathSegments(path);
|
||||
if (id != null) {
|
||||
urlBuilder.addPathSegment(id);
|
||||
}
|
||||
|
||||
if (params != null) {
|
||||
params.forEach((name, value) -> {
|
||||
if (value == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (value instanceof Collection) {
|
||||
for (Object i : (Collection<?>) value) {
|
||||
urlBuilder.addQueryParameter(name, String.valueOf(i));
|
||||
}
|
||||
} else {
|
||||
urlBuilder.addQueryParameter(name, String.valueOf(value));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Request.Builder builder = newRequestBuilder().url(urlBuilder.build());
|
||||
|
||||
if (headers != null) {
|
||||
builder.headers(headers.toOkHttpHeader());
|
||||
}
|
||||
|
||||
this.attachAuthToRequest(builder);
|
||||
|
||||
return builder;
|
||||
}
|
||||
|
||||
/**
|
||||
* In order to provide subclasses with overloading opportunities
|
||||
*/
|
||||
protected Request.Builder newRequestBuilder() {
|
||||
return new Request.Builder();
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
@Override
|
||||
public RestResult post(String path, Object object, RestHeaders headers,
|
||||
Map<String, Object> params) {
|
||||
Request.Builder requestBuilder = genRequestBuilder(path, null, headers, params);
|
||||
requestBuilder.post(buildRequestBody(object, headers));
|
||||
|
||||
try (Response response = request(requestBuilder)) {
|
||||
checkStatus(response, 200, 201, 202);
|
||||
return new RestResult(response);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public RestResult put(String path, String id, Object object) {
|
||||
return this.put(path, id, object, ImmutableMap.of());
|
||||
}
|
||||
|
||||
@Override
|
||||
public RestResult put(String path, String id, Object object, RestHeaders headers) {
|
||||
return this.put(path, id, object, headers, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RestResult put(String path, String id, Object object, Map<String, Object> params) {
|
||||
return this.put(path, id, object, null, params);
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
@Override
|
||||
public RestResult put(String path, String id, Object object,
|
||||
RestHeaders headers,
|
||||
Map<String, Object> params) {
|
||||
Request.Builder requestBuilder = genRequestBuilder(path, id, headers, params);
|
||||
requestBuilder.put(buildRequestBody(object, headers));
|
||||
|
||||
try (Response response = request(requestBuilder)) {
|
||||
checkStatus(response, 200, 202);
|
||||
return new RestResult(response);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public RestResult get(String path) {
|
||||
return this.get(path, null, ImmutableMap.of());
|
||||
}
|
||||
|
||||
@Override
|
||||
public RestResult get(String path, Map<String, Object> params) {
|
||||
return this.get(path, null, params);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RestResult get(String path, String id) {
|
||||
return this.get(path, id, ImmutableMap.of());
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
private RestResult get(String path, String id, Map<String, Object> params) {
|
||||
Request.Builder requestBuilder = genRequestBuilder(path, id, null, params);
|
||||
|
||||
try (Response response = request(requestBuilder)) {
|
||||
checkStatus(response, 200);
|
||||
return new RestResult(response);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public RestResult delete(String path, Map<String, Object> params) {
|
||||
return this.delete(path, null, params);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RestResult delete(String path, String id) {
|
||||
return this.delete(path, id, ImmutableMap.of());
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
private RestResult delete(String path, String id,
|
||||
Map<String, Object> params) {
|
||||
Request.Builder requestBuilder = genRequestBuilder(path, id, null, params);
|
||||
requestBuilder.delete();
|
||||
|
||||
try (Response response = request(requestBuilder)) {
|
||||
checkStatus(response, 204, 202);
|
||||
return new RestResult(response);
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract void checkStatus(Response response, int... statuses);
|
||||
|
||||
@SneakyThrows
|
||||
protected Response request(Request.Builder requestBuilder) {
|
||||
return this.client.newCall(requestBuilder.build()).execute();
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
@Override
|
||||
public void close() {
|
||||
if (this.client != null) {
|
||||
this.client.dispatcher().executorService().shutdown();
|
||||
this.client.connectionPool().evictAll();
|
||||
if (this.client.cache() != null) {
|
||||
this.client.cache().close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static String encode(String raw) {
|
||||
try {
|
||||
return URLEncoder.encode(raw, StandardCharsets.UTF_8.toString()).replace("+", "%2B");
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
throw new IllegalArgumentException("Failed to encode string: " + raw, e);
|
||||
}
|
||||
}
|
||||
|
||||
public void resetAuthContext() {
|
||||
this.authContext.remove();
|
||||
}
|
||||
|
||||
public String getAuthContext() {
|
||||
return this.authContext.get();
|
||||
}
|
||||
|
||||
public void setAuthContext(String auth) {
|
||||
this.authContext.set(auth);
|
||||
}
|
||||
|
||||
private void attachAuthToRequest(Request.Builder builder) {
|
||||
// Add auth header
|
||||
String auth = this.getAuthContext();
|
||||
if (StringUtils.isNotEmpty(auth)) {
|
||||
builder.addHeader(RestHeaders.AUTHORIZATION, auth);
|
||||
}
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
private X509TrustManager trustManagerForCertificates(String trustStoreFile,
|
||||
String trustStorePass) {
|
||||
char[] password = trustStorePass.toCharArray();
|
||||
|
||||
// load keyStore
|
||||
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
|
||||
try (FileInputStream in = new FileInputStream(trustStoreFile)) {
|
||||
keyStore.load(in, password);
|
||||
}
|
||||
|
||||
TrustManagerFactory trustManagerFactory =
|
||||
TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
|
||||
trustManagerFactory.init(keyStore);
|
||||
|
||||
TrustManager[] trustManagers = trustManagerFactory.getTrustManagers();
|
||||
if (trustManagers.length != 1 || !(trustManagers[0] instanceof X509TrustManager)) {
|
||||
throw new IllegalStateException("Unexpected default trust managers:" +
|
||||
Arrays.toString(trustManagers));
|
||||
}
|
||||
return (X509TrustManager) trustManagers[0];
|
||||
}
|
||||
|
||||
public static class HostNameVerifier implements HostnameVerifier {
|
||||
|
||||
private final String url;
|
||||
|
||||
public HostNameVerifier(String url) {
|
||||
if (!url.startsWith("http://") && !url.startsWith("https://")) {
|
||||
url = "http://" + url;
|
||||
}
|
||||
url = URI.create(url).getHost();
|
||||
this.url = url;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean verify(String hostname, SSLSession session) {
|
||||
if (!this.url.isEmpty() && this.url.endsWith(hostname)) {
|
||||
return true;
|
||||
} else {
|
||||
HostnameVerifier verifier = HttpsURLConnection.getDefaultHostnameVerifier();
|
||||
return verifier.verify(hostname, session);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,35 +0,0 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with this
|
||||
* work for additional information regarding copyright ownership. The ASF
|
||||
* licenses this file to You under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.apache.hugegraph.rest;
|
||||
|
||||
public class ClientException extends RuntimeException {
|
||||
|
||||
private static final long serialVersionUID = 814572040103754705L;
|
||||
|
||||
public ClientException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
public ClientException(String message, Object... args) {
|
||||
super(String.format(message, args));
|
||||
}
|
||||
|
||||
public ClientException(String message, Throwable cause, Object... args) {
|
||||
super(String.format(message, args), cause);
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue